From: slontis Date: Fri, 17 Oct 2025 05:21:54 +0000 (+1100) Subject: SHA256: Document SHA256_CTX, HASH_UPDATE() and HASH_FINAL() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d66c748300c7650e36c4c720da950ad4ac70fc54;p=thirdparty%2Fopenssl.git SHA256: Document SHA256_CTX, HASH_UPDATE() and HASH_FINAL() Reviewed-by: Paul Dale Reviewed-by: Viktor Dukhovni (Merged from https://github.com/openssl/openssl/pull/28941) --- diff --git a/include/crypto/md32_common.h b/include/crypto/md32_common.h index 9d8f6beb1d4..7e928a3582a 100644 --- a/include/crypto/md32_common.h +++ b/include/crypto/md32_common.h @@ -181,9 +181,14 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) n = c->num; if (ossl_likely(n != 0)) { + /* Gets here if we already have buffered input data */ p = (unsigned char *)c->data; if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + /* + * If there is enough input to fill the buffer then fill the + * buffer and process a single chunk. + */ memcpy(p + n, data, HASH_CBLOCK - n); HASH_BLOCK_DATA_ORDER(c, p, 1); n = HASH_CBLOCK - n; @@ -198,20 +203,22 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) */ memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ } else { + /* Otherwise just keep filling the buffer */ memcpy(p + n, data, len); c->num += (unsigned int)len; return 1; } } - n = len / HASH_CBLOCK; + n = len / HASH_CBLOCK; /* Get number of input chunks (e.g. multiple of 512 bits for SHA256) */ if (n > 0) { + /* Process chunks */ HASH_BLOCK_DATA_ORDER(c, data, n); n *= HASH_CBLOCK; data += n; len -= n; } - + /* Buffer any left over data */ if (len != 0) { p = (unsigned char *)c->data; c->num = (unsigned int)len; @@ -222,7 +229,7 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data) { - HASH_BLOCK_DATA_ORDER(c, data, 1); + HASH_BLOCK_DATA_ORDER(c, data, 1); /* Process a single chunk */ } int HASH_FINAL(unsigned char *md, HASH_CTX *c) @@ -230,16 +237,26 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c) unsigned char *p = (unsigned char *)c->data; size_t n = c->num; - p[n] = 0x80; /* there is always room for one */ + /* + * Pad the input by adding a 1 bit + K zero bits + input length (L) + * as a 64 bit value. K must align the data to a chunk boundary. + */ + p[n] = 0x80; /* there is always room for one */ n++; if (n > (HASH_CBLOCK - 8)) { + /* + * If there is not enough room in the buffer to add L, then fill the + * current buffer with zeros, and process the chunk + */ memset(p + n, 0, HASH_CBLOCK - n); n = 0; HASH_BLOCK_DATA_ORDER(c, p, 1); } + /* Add zero padding - but leave enough room for L */ memset(p + n, 0, HASH_CBLOCK - 8 - n); + /* Add the 64 bit L value to the end of the buffer */ p += HASH_CBLOCK - 8; #if defined(DATA_ORDER_IS_BIG_ENDIAN) (void)HOST_l2c(c->Nh, p); @@ -249,6 +266,7 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c) (void)HOST_l2c(c->Nh, p); #endif p -= HASH_CBLOCK; + /* Process the final padded chunk */ HASH_BLOCK_DATA_ORDER(c, p, 1); c->num = 0; OPENSSL_cleanse(p, HASH_CBLOCK); diff --git a/include/openssl/sha.h b/include/openssl/sha.h index 7140d71043a..a7f1f6870cf 100644 --- a/include/openssl/sha.h +++ b/include/openssl/sha.h @@ -60,10 +60,11 @@ unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); * big-endian values. */ typedef struct SHA256state_st { - SHA_LONG h[8]; - SHA_LONG Nl, Nh; - SHA_LONG data[SHA_LBLOCK]; - unsigned int num, md_len; + SHA_LONG h[8]; /* Hash values (32 bytes) */ + SHA_LONG Nl, Nh; /* The length of the message in bits is stored into 64 bits */ + SHA_LONG data[SHA_LBLOCK]; /* Buffer used to store input less than 512 bits */ + unsigned int num; /* The size of the partial buffered input in data[] */ + unsigned int md_len; /* The output size (used for truncation) */ } SHA256_CTX; OSSL_DEPRECATEDIN_3_0 int SHA224_Init(SHA256_CTX *c);