openssl中关于sha256算法最关键的代码文件有sha.h, sha256.c,md32_common.h,crypto.h等等。
1、sha256算法最关键的文件sha256.c。
查看这个文件可以看到openssl如何计算sha256值:
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
{
SHA256_CTX c;
static unsigned char m[SHA256_DIGEST_LENGTH];
if (md == NULL) md=m;
SHA256_Init(&c);
SHA256_Update(&c,d,n);
SHA256_Final(md,&c);
OPENSSL_cleanse(&c,sizeof(c));
return(md);
}
可见求sha256主要是执行三个函数:SHA256_Init,SHA256_Update,SHA256_Final。对于OPENSSL_cleanse函数(定义在crypto/mem_clr.c中),其实没有什么实际意义。
但是搜遍openssl源码,也找不到上面这三个函数的定义,只有sha.h文件中的函数声明。
1.1 SHA256_Init函数。
查看sha256.c文件,跟SHA256和Init有关的只有该文件前面的:
fips_md_init(SHA256)
{
memset (c,0,sizeof(*c));
c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL;
c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL;
c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL;
c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL;
c->md_len=SHA256_DIGEST_LENGTH;
return 1;
}
这不是巧合。查看crypto.h文件中有关该宏的定义:
#define fips_md_init(alg) fips_md_init_ctx(alg, alg)
再查看fips_md_init_ctx的定义:
#define fips_md_init_ctx(alg, cx) \
int alg##_Init(cx##_CTX *c)
根据上面两个宏定义,把上面的fips_md_init(SHA256)展开就得到:
int SHA256_Init(SHA256_CTX *c)
因此,sha256.c文件中定义的fips_md_init(SHA256)就是SHA256_Init(SHA256_CTX *c)。
所以SHA256_Init函数的定义如下:
int SHA256_Init(SHA256_CTX *c) {
memset (c,0,sizeof(*c));
c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL;
c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL;
c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL;
c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL;
c->md_len=SHA256_DIGEST_LENGTH;
return 1;
}
1.2 SHA256_Update函数。
sha256.c文件也没有该函数的定义,但是有一个宏:
#define HASH_UPDATE SHA256_Update
因此可猜测openssl别处应该还有一个HASH_UPDATE的宏定义。
这个定义在md32_common.h文件中:
int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
{
const unsigned char *data=data_;
unsigned char *p;
HASH_LONG l;
size_t n;
if (len==0) return 1;
l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
* Wei Dai <weidai@eskimo.com> for pointing it out. */
if (l < c->Nl) /* overflow */
c