openssl sha256演算法原始碼

2021-07-27 12:35:15 字數 3216 閱讀 4034

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主要是執行三個函式: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)

這不是巧合。檢視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)

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)

else

}n = len/hash_cblock;

if (n >

0)

if (len !=

0)

return

1;}

所以,openssl裡面是通過重定義巨集hash_update來實現sha256_update函式(這就是為什麼sha256.c檔案中要在重定義hash_update巨集這一行之後再包含md32_common.h檔案)。

openssl這麼做,是因為這裡的hash_update演算法是乙個通用演算法,其他的幾個演算法,如sha1,sha256,sha512等等都會用到這個update演算法。這幾個演算法只在update演算法中的某些地方有所區別,而這些區別,openssl也是通過巨集定義來達到目的的。

比如說,上面的hash_update演算法中有呼叫乙個hash_block_data_order的地方,但是其實幾個sha演算法會再次重定義這個巨集來實現自己的操作。在sha256.c檔案中,就有以下定義:

#define hash_block_data_order   sha256_block_data_order
並且,有以下函式的宣告:

void sha256_block_data_order (sha256_ctx *ctx, const

void *in, size_t num);

在sha256.c檔案中,隨後就實現了該函式:

static void sha256_block_data_order (sha256_ctx *ctx, const void *in, size_t num)

is_endian = ;

while (num--)

else

for (i=16;i<64;i+=8)

ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;

ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;

}}

再比如,上面的hash_update演算法中,還呼叫了乙個hash_make_string巨集函式。sha256.c檔案中,也重定義了這個巨集:

#define hash_make_string(c,s)   do   \

break; \

case

sha256_digest_length: \

for (nn=0;nn4;nn++) \

\break; \

default: \

if((c)->md_len > sha256_digest_length) \

return 0; \

for(nn=0;nn<(c)->md_len/4;nn++) \

\break; \

} \

} while (0)

以上是分析sha256_update函式的實現。

1.3 sha256_final函式

這個函式的實現跟上面的update函式一樣。

也是在md32_common.h檔案中定義了乙個通用的hash_final演算法。

通過上面的步驟,可以找到openssl實現sha256演算法的**模組組織。至於演算法內部的實現邏輯,留到下次慢慢研究。

SHA 256演算法流程

sha 256 輸入訊息 m 輸出訊息 256位 bit hash值 步驟 訊息填充 m的長度 mod 512 r,考慮r r為輸入訊息長度按512bit進行分組後,最後一組的長度 系統給出8個32位暫存器 a,b,c,d,e,f,g,h,其初始值分別取自8個素數 2,3,5,7,11,13,17,...

golang sha256 加密演算法

package main import fmt crypto sha256 io log os func main 對檔案加密 f,err os.open test.txt if err nil defer f.close h sha256.new if err io.copy h,f err ni...

SHA 256演算法實現過程

1.定義8個32位常量 h0 0x6a09e667 h1 0xbb67ae85 h2 0x3c6ef372 h3 0xa54ff53a h4 0x510e527f h5 0x9b05688c h6 0x1f83d9ab h7 0x5be0cd192.再定義乙個k的32位整形陣列,陣列大小為64 k ...