From e9471890b62f0137cf6baf3e4d3cc7d5246e2bb1 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Mon, 1 Jun 2026 15:44:42 +0800 Subject: [PATCH] Fix SHA512-224, SHA512-256 IV --- include/gmssl/sha2.h | 9 ++++++ src/digest.c | 74 +++++++++++++++++++++++++------------------- src/sha512.c | 44 ++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 31 deletions(-) diff --git a/include/gmssl/sha2.h b/include/gmssl/sha2.h index fd2bcb94..0706413d 100644 --- a/include/gmssl/sha2.h +++ b/include/gmssl/sha2.h @@ -88,6 +88,15 @@ void sha512_update(SHA512_CTX *ctx, const uint8_t* data, size_t datalen); void sha512_finish(SHA512_CTX *ctx, uint8_t dgst[SHA512_DIGEST_SIZE]); +void sha512_256_init(SHA512_CTX *ctx); +#define sha512_256_update(ctx,data,datalen) sha512_update(ctx,data,datalen) +void sha512_256_finish(SHA512_CTX *ctx, uint8_t dgst[SHA256_DIGEST_SIZE]); + +void sha512_224_init(SHA512_CTX *ctx); +#define sha512_224_update(ctx,data,datalen) sha512_update(ctx,data,datalen) +void sha512_224_finish(SHA512_CTX *ctx, uint8_t dgst[SHA224_DIGEST_SIZE]); + + #define SHA256_HMAC_SIZE (SHA256_DIGEST_SIZE) typedef struct { diff --git a/src/digest.c b/src/digest.c index 87f147ed..4953133a 100644 --- a/src/digest.c +++ b/src/digest.c @@ -362,6 +362,26 @@ static int sha512_digest_init(DIGEST_CTX *ctx) return 1; } +static int sha512_224_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sha512_224_init(&ctx->u.sha512_ctx); + return 1; +} + +static int sha512_256_digest_init(DIGEST_CTX *ctx) +{ + if (!ctx) { + error_print(); + return -1; + } + sha512_256_init(&ctx->u.sha512_ctx); + return 1; +} + static int sha512_digest_update(DIGEST_CTX *ctx, const uint8_t *in, size_t inlen) { if (!ctx || (!in && inlen != 0)) { @@ -382,6 +402,27 @@ static int sha512_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) return 1; } +static int sha512_224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha512_224_finish(&ctx->u.sha512_ctx, dgst); + return 1; +} + +static int sha512_256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) +{ + if (!ctx || !dgst) { + error_print(); + return -1; + } + sha512_256_finish(&ctx->u.sha512_ctx, dgst); + return 1; +} + + static const DIGEST sha512_digest_object = { OID_sha512, SHA512_DIGEST_SIZE, @@ -397,26 +438,12 @@ const DIGEST *DIGEST_sha512(void) return &sha512_digest_object; } - -static int sha512_224_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - uint8_t buf[SHA512_DIGEST_SIZE]; - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha512_finish(&ctx->u.sha512_ctx, buf); - memcpy(dgst, buf, SHA224_DIGEST_SIZE); - memset(buf, 0, sizeof(buf)); - return 1; -} - static const DIGEST sha512_224_digest_object = { OID_sha512_224, SHA224_DIGEST_SIZE, SHA512_BLOCK_SIZE, sizeof(SHA512_CTX), - sha512_digest_init, + sha512_224_digest_init, sha512_digest_update, sha512_224_digest_finish, }; @@ -426,27 +453,12 @@ const DIGEST *DIGEST_sha512_224(void) return &sha512_224_digest_object; } - -static int sha512_256_digest_finish(DIGEST_CTX *ctx, uint8_t *dgst) -{ - uint8_t buf[SHA512_DIGEST_SIZE]; - if (!ctx || !dgst) { - error_print(); - return -1; - } - sha512_finish(&ctx->u.sha512_ctx, buf); - memcpy(dgst, buf, SHA256_DIGEST_SIZE); - memset(buf, 0, sizeof(buf)); - return 1; -} - - static const DIGEST sha512_256_digest_object = { OID_sha512_256, SHA256_DIGEST_SIZE, SHA512_BLOCK_SIZE, sizeof(SHA512_CTX), - sha512_digest_init, + sha512_256_digest_init, sha512_digest_update, sha512_256_digest_finish, }; diff --git a/src/sha512.c b/src/sha512.c index 37268d60..2cd78cfd 100644 --- a/src/sha512.c +++ b/src/sha512.c @@ -201,3 +201,47 @@ void sha384_finish(SHA384_CTX *ctx, unsigned char dgst[SHA384_DIGEST_SIZE]) memcpy(dgst, buf, SHA384_DIGEST_SIZE); memset(buf, 0, sizeof(buf)); } + + +void sha512_256_init(SHA512_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0x22312194fc2bf72c; + ctx->state[1] = 0x9f555fa3c84c64c2; + ctx->state[2] = 0x2393b86b6f53b151; + ctx->state[3] = 0x963877195940eabd; + ctx->state[4] = 0x96283ee2a88effe3; + ctx->state[5] = 0xbe5e1e2553863992; + ctx->state[6] = 0x2b0199fc2c85b8aa; + ctx->state[7] = 0x0eb72ddc81c52ca2; +} + +void sha512_256_finish(SHA512_CTX *ctx, unsigned char dgst[SHA256_DIGEST_SIZE]) +{ + unsigned char buf[SHA512_DIGEST_SIZE]; + sha512_finish(ctx, buf); + memcpy(dgst, buf, SHA256_DIGEST_SIZE); + memset(buf, 0, sizeof(buf)); +} + +void sha512_224_init(SHA512_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = 0x8c3d37c819544da2; + ctx->state[1] = 0x73e1996689dcd4d6; + ctx->state[2] = 0x1dfab7ae32ff9c82; + ctx->state[3] = 0x679dd514582f9fcf; + ctx->state[4] = 0x0f6d2b697bd44da8; + ctx->state[5] = 0x77e36f7304c48942; + ctx->state[6] = 0x3f9d85a86a1d36c8; + ctx->state[7] = 0x1112e6ad91d692a1; +} + +void sha512_224_finish(SHA512_CTX *ctx, unsigned char dgst[SHA224_DIGEST_SIZE]) +{ + unsigned char buf[SHA512_DIGEST_SIZE]; + sha512_finish(ctx, buf); + memcpy(dgst, buf, SHA224_DIGEST_SIZE); + memset(buf, 0, sizeof(buf)); +} +