mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-19 11:23:38 +08:00
Update GHASH
This commit is contained in:
@@ -763,7 +763,7 @@ endif()
|
||||
#
|
||||
set(CPACK_PACKAGE_NAME "GmSSL")
|
||||
set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
|
||||
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1045")
|
||||
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1046")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
|
||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||
include(CPack)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,13 @@ extern "C" {
|
||||
|
||||
#define GHASH_SIZE (16)
|
||||
|
||||
/*
|
||||
* GHASH encodes aadlen and clen as 64-bit bit lengths.
|
||||
* Callers must ensure that each one-shot length, and the accumulated clen
|
||||
* passed to ghash_update(), is no greater than UINT64_MAX/8 bytes.
|
||||
* If aadlen or clen is non-zero, the corresponding input pointer must be
|
||||
* non-NULL.
|
||||
*/
|
||||
|
||||
// h = ENC_k(0^128)
|
||||
void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen,
|
||||
|
||||
@@ -19,7 +19,7 @@ extern "C" {
|
||||
|
||||
// Also update CPACK_PACKAGE_VERSION in CMakeLists.txt
|
||||
#define GMSSL_VERSION_NUM 30200
|
||||
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1045"
|
||||
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1046"
|
||||
|
||||
int gmssl_version_num(void);
|
||||
const char *gmssl_version_str(void);
|
||||
|
||||
30
src/ghash.c
30
src/ghash.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -36,13 +36,14 @@ void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t
|
||||
gf128_t H;
|
||||
gf128_t X;
|
||||
gf128_t L;
|
||||
uint8_t block[16];
|
||||
|
||||
gf128_from_bytes(H, h);
|
||||
gf128_set_zero(X);
|
||||
|
||||
PUTU64(out, (uint64_t)aadlen << 3);
|
||||
PUTU64(out + 8, (uint64_t)clen << 3);
|
||||
gf128_from_bytes(L, out);
|
||||
PUTU64(block, (uint64_t)aadlen << 3);
|
||||
PUTU64(block + 8, (uint64_t)clen << 3);
|
||||
gf128_from_bytes(L, block);
|
||||
|
||||
while (aadlen) {
|
||||
gf128_t A;
|
||||
@@ -51,9 +52,9 @@ void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t
|
||||
aad += 16;
|
||||
aadlen -= 16;
|
||||
} else {
|
||||
memset(out, 0, 16);
|
||||
memcpy(out, aad, aadlen);
|
||||
gf128_from_bytes(A, out);
|
||||
memset(block, 0, 16);
|
||||
memcpy(block, aad, aadlen);
|
||||
gf128_from_bytes(A, block);
|
||||
aadlen = 0;
|
||||
}
|
||||
gf128_add(X, X, A);
|
||||
@@ -67,9 +68,9 @@ void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t
|
||||
c += 16;
|
||||
clen -= 16;
|
||||
} else {
|
||||
memset(out, 0, 16);
|
||||
memcpy(out, c, clen);
|
||||
gf128_from_bytes(C, out);
|
||||
memset(block, 0, 16);
|
||||
memcpy(block, c, clen);
|
||||
gf128_from_bytes(C, block);
|
||||
clen = 0;
|
||||
}
|
||||
gf128_add(X, X, C);
|
||||
@@ -79,6 +80,11 @@ void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t
|
||||
gf128_add(X, X, L);
|
||||
gf128_mul(H, X, H); // clear secrets in H
|
||||
gf128_to_bytes(H, out);
|
||||
|
||||
gmssl_secure_clear(H, sizeof(H));
|
||||
gmssl_secure_clear(X, sizeof(X));
|
||||
gmssl_secure_clear(L, sizeof(L));
|
||||
gmssl_secure_clear(block, sizeof(block));
|
||||
}
|
||||
|
||||
void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t aadlen)
|
||||
@@ -113,6 +119,10 @@ void ghash_update(GHASH_CTX *ctx, const uint8_t *c, size_t clen)
|
||||
|
||||
assert(ctx->num < 16);
|
||||
|
||||
if (!clen) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->clen += clen;
|
||||
|
||||
if (ctx->num) {
|
||||
|
||||
@@ -108,6 +108,7 @@ int test_ghash(void)
|
||||
format_print(stderr, 0, 2, "C = %s\n", ghash_tests[i].C);
|
||||
format_bytes(stderr, 0, 2, "GHASH(H,A,C) = ", out, 16);
|
||||
format_print(stderr, 0, 2, " = %s\n\n", ghash_tests[i].T);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +116,43 @@ int test_ghash(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test_ghash_update(void)
|
||||
{
|
||||
uint8_t H[16];
|
||||
uint8_t A[32];
|
||||
uint8_t C[80];
|
||||
uint8_t C_alias[80];
|
||||
uint8_t T[16];
|
||||
uint8_t out[16];
|
||||
size_t Hlen, Alen, Clen, Tlen;
|
||||
GHASH_CTX ghash_ctx;
|
||||
|
||||
hex_to_bytes(ghash_tests[3].H, strlen(ghash_tests[3].H), H, &Hlen);
|
||||
hex_to_bytes(ghash_tests[3].A, strlen(ghash_tests[3].A), A, &Alen);
|
||||
hex_to_bytes(ghash_tests[3].C, strlen(ghash_tests[3].C), C, &Clen);
|
||||
hex_to_bytes(ghash_tests[3].T, strlen(ghash_tests[3].T), T, &Tlen);
|
||||
|
||||
ghash_init(&ghash_ctx, H, A, Alen);
|
||||
ghash_update(&ghash_ctx, C, 7);
|
||||
ghash_update(&ghash_ctx, NULL, 0);
|
||||
ghash_update(&ghash_ctx, C + 7, Clen - 7);
|
||||
ghash_finish(&ghash_ctx, out);
|
||||
if (memcmp(out, T, Tlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(C_alias, C, Clen);
|
||||
ghash(H, A, Alen, C_alias, Clen, C_alias);
|
||||
if (memcmp(C_alias, T, Tlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int speed_ghash(void)
|
||||
{
|
||||
GHASH_CTX ghash_ctx;
|
||||
@@ -148,6 +186,7 @@ static int speed_ghash(void)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (test_ghash() != 1) goto err;
|
||||
if (test_ghash_update() != 1) goto err;
|
||||
|
||||
#if ENABLE_TEST_SPEED
|
||||
speed_ghash();
|
||||
|
||||
Reference in New Issue
Block a user