diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ee99af4..96a3d75c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,6 @@ set(src src/pbkdf2.c src/gf128.c src/ghash.c - src/gcm.c src/sm4_cbc_sm3_hmac.c src/sm4_ctr_sm3_hmac.c src/pkcs8.c @@ -137,6 +136,7 @@ set(tools set(tests sm4 sm3 + sm4_sm3_hmac # sm2 sm2_z256 sm2_sign @@ -151,8 +151,7 @@ set(tests hkdf pbkdf2 gf128 - gcm - aead + ghash pkcs8 ec asn1 diff --git a/include/gmssl/ghash.h b/include/gmssl/ghash.h index 27445f30..1b793cdc 100644 --- a/include/gmssl/ghash.h +++ b/include/gmssl/ghash.h @@ -25,7 +25,6 @@ extern "C" { #define GHASH_SIZE (16) - void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t *c, size_t clen, uint8_t out[16]); diff --git a/include/gmssl/aead.h b/include/gmssl/sm4_cbc_sm3_hmac.h similarity index 54% rename from include/gmssl/aead.h rename to include/gmssl/sm4_cbc_sm3_hmac.h index 2b76e663..11ae6e93 100644 --- a/include/gmssl/aead.h +++ b/include/gmssl/sm4_cbc_sm3_hmac.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2024 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. @@ -7,14 +7,13 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#ifndef GMSSL_AEAD_H -#define GMSSL_AEAD_H +#ifndef GMSSL_SM4_CBC_SM3_HMAC_H +#define GMSSL_SM4_CBC_SM3_HMAC_H #include #include -#include #include -#include +#include #include #ifdef __cplusplus @@ -48,35 +47,6 @@ _gmssl_export int sm4_cbc_sm3_hmac_decrypt_finish(SM4_CBC_SM3_HMAC_CTX *ctx, uint8_t *out, size_t *outlen); -typedef struct { - SM4_CTR_CTX enc_ctx; - SM3_HMAC_CTX mac_ctx; - uint8_t mac[SM3_HMAC_SIZE]; - size_t maclen; -} SM4_CTR_SM3_HMAC_CTX; - -#define SM4_CTR_SM3_HMAC_KEY_SIZE 48 -#define SM4_CTR_SM3_HMAC_IV_SIZE 16 - -_gmssl_export int sm4_ctr_sm3_hmac_encrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, - const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen); -_gmssl_export int sm4_ctr_sm3_hmac_encrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -_gmssl_export int sm4_ctr_sm3_hmac_encrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx, - uint8_t *out, size_t *outlen); -_gmssl_export int sm4_ctr_sm3_hmac_decrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, - const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, - const uint8_t *aad, size_t aadlen); -_gmssl_export int sm4_ctr_sm3_hmac_decrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -_gmssl_export int sm4_ctr_sm3_hmac_decrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx, - uint8_t *out, size_t *outlen); - - - - - #ifdef __cplusplus } #endif diff --git a/include/gmssl/sm4_ctr_sm3_hmac.h b/include/gmssl/sm4_ctr_sm3_hmac.h new file mode 100644 index 00000000..71ad6027 --- /dev/null +++ b/include/gmssl/sm4_ctr_sm3_hmac.h @@ -0,0 +1,53 @@ +/* + * Copyright 2014-2024 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. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +#ifndef GMSSL_SM4_CTR_SM3_HMAC_H +#define GMSSL_SM4_CTR_SM3_HMAC_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + SM4_CTR_CTX enc_ctx; + SM3_HMAC_CTX mac_ctx; + uint8_t mac[SM3_HMAC_SIZE]; + size_t maclen; +} SM4_CTR_SM3_HMAC_CTX; + +#define SM4_CTR_SM3_HMAC_KEY_SIZE 48 +#define SM4_CTR_SM3_HMAC_IV_SIZE 16 + +_gmssl_export int sm4_ctr_sm3_hmac_encrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, + const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen); +_gmssl_export int sm4_ctr_sm3_hmac_encrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +_gmssl_export int sm4_ctr_sm3_hmac_encrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx, + uint8_t *out, size_t *outlen); +_gmssl_export int sm4_ctr_sm3_hmac_decrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, + const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen); +_gmssl_export int sm4_ctr_sm3_hmac_decrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); +_gmssl_export int sm4_ctr_sm3_hmac_decrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx, + uint8_t *out, size_t *outlen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/gf128.c b/src/gf128.c index 515062e1..f61cf155 100644 --- a/src/gf128.c +++ b/src/gf128.c @@ -111,7 +111,6 @@ void gf128_mul(gf128_t r, const gf128_t a, const gf128_t b) uint64_t r1 = 0; int i; - for (i = 0; i < 64; i++) { if (r1 & mask) { r1 = r1 << 1 | r0 >> 63; diff --git a/src/ghash.c b/src/ghash.c index 51d4e8ce..f3d33558 100644 --- a/src/ghash.c +++ b/src/ghash.c @@ -13,9 +13,7 @@ #include #include #include -#include #include -#include #include #include @@ -79,11 +77,10 @@ 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, H, X); + gf128_mul(H, X, H); // clear secrets in H gf128_to_bytes(H, out); } - void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t aadlen) { gf128_t A; diff --git a/src/sm4_cbc_sm3_hmac.c b/src/sm4_cbc_sm3_hmac.c index 554e6ef0..5feed84b 100644 --- a/src/sm4_cbc_sm3_hmac.c +++ b/src/sm4_cbc_sm3_hmac.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2024 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. @@ -11,9 +11,8 @@ #include #include #include -#include +#include #include -#include #include diff --git a/src/sm4_ctr_sm3_hmac.c b/src/sm4_ctr_sm3_hmac.c index f5211baf..ea83b61d 100644 --- a/src/sm4_ctr_sm3_hmac.c +++ b/src/sm4_ctr_sm3_hmac.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2024 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. @@ -11,13 +11,11 @@ #include #include #include -#include +#include #include -#include #include - int sm4_ctr_sm3_hmac_encrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx, const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen, const uint8_t *aad, size_t aadlen) @@ -179,13 +177,3 @@ int sm4_ctr_sm3_hmac_decrypt_finish(SM4_CTR_SM3_HMAC_CTX *ctx, uint8_t *out, siz ctx->maclen = 0; return 1; } - -static void ctr_incr(uint8_t a[16]) -{ - int i; - for (i = 15; i >= 0; i--) { - a[i]++; - if (a[i]) break; - } -} - diff --git a/src/tls13.c b/src/tls13.c index a6c6c669..37c8bc18 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,53 @@ static int tls13_client_hello_exts[] = { TLS_extension_padding, }; +// FIXME: remove block_cipher.h +int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + uint8_t *out, size_t taglen, uint8_t *tag) +{ + if (key->cipher == BLOCK_CIPHER_sm4()) { + if (sm4_gcm_encrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { + error_print(); + return -1; + } +#ifdef ENABLE_AES + } else if (key->cipher == BLOCK_CIPHER_aes128()) { + if (aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag) != 1) { + error_print(); + return -1; + } +#endif + } else { + error_print(); + return -1; + } + return 1; +} + +int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen, + const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, + const uint8_t *tag, size_t taglen, uint8_t *out) +{ + if (key->cipher == BLOCK_CIPHER_sm4()) { + if (sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { + error_print(); + return -1; + } +#ifdef ENABLE_AES + } else if (key->cipher == BLOCK_CIPHER_aes128()) { + if (aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out) != 1) { + error_print(); + return -1; + } +#endif + } else { + error_print(); + return -1; + } + return 1; +} + /* struct { diff --git a/tests/gcmtest.c b/tests/ghashtest.c similarity index 96% rename from tests/gcmtest.c rename to tests/ghashtest.c index 6d69a61f..70991da4 100644 --- a/tests/gcmtest.c +++ b/tests/ghashtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2024 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. @@ -11,10 +11,9 @@ #include #include #include -#include +#include #include #include -#include #include @@ -115,6 +114,7 @@ int test_ghash(void) return 1; } +#if 0 int test_gcm(void) { BLOCK_CIPHER_KEY block_key; @@ -178,15 +178,12 @@ int test_gcm(void) printf("%s() ok\n", __FUNCTION__); return 1; } - - - +#endif int main(int argc, char **argv) { if (test_ghash() != 1) goto err; - if (test_gcm() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; err: diff --git a/tests/sm4_gcmtest.c b/tests/sm4_gcmtest.c new file mode 100644 index 00000000..429d682b --- /dev/null +++ b/tests/sm4_gcmtest.c @@ -0,0 +1,326 @@ +/* + * Copyright 2014-2022 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. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_sm4_gcm(void) +{ + // gcm test vectors from rfc 8998 A.1 + const char *hex_key = "0123456789ABCDEFFEDCBA9876543210"; + const char *hex_iv = "00001234567800000000ABCD"; + const char *hex_aad = "FEEDFACEDEADBEEFFEEDFACEDEADBEEF" + "ABADDAD2"; + const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" + "CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD" + "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF" + "EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"; + const char *hex_out = "17F399F08C67D5EE19D0DC9969C4BB7D" + "5FD46FD3756489069157B282BB200735" + "D82710CA5C22F0CCFA7CBF93D496AC15" + "A56834CBCF98C397B4024A2691233B8D"; + const char *hex_tag = "83DE3541E4C2B58177E065A9BF7B62EC"; + + SM4_KEY sm4_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t aad[20]; + uint8_t in[64]; + uint8_t out[64]; + uint8_t tag[16]; + size_t keylen, ivlen, aadlen, inlen, outlen, taglen; + + uint8_t buf[64]; + uint8_t mac[16]; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); + hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); + hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); + hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); + hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); + + memset(buf, 0, sizeof(buf)); + memset(mac, 0, sizeof(mac)); + + sm4_set_encrypt_key(&sm4_key, key); + + // test gcm encrypt + sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); + if (memcmp(buf, out, outlen) != 0) { + error_print(); + return -1; + } + if (memcmp(mac, tag, taglen) != 0) { + error_print(); + return -1; + } + + // test gcm decrypt + memset(buf, 0, sizeof(buf)); + sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); + if (memcmp(buf, in, inlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_gcm_gbt36624_1(void) +{ + // gcm test vectors from GB/T 36624-2018 C.5 + const char *hex_key = "00000000000000000000000000000000"; + const char *hex_iv = "000000000000000000000000"; + const char *hex_aad = ""; + const char *hex_in = ""; + const char *hex_out = ""; + const char *hex_tag = "232F0CFE308B49EA6FC88229B5DC858D"; + + SM4_KEY sm4_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t aad[20]; + uint8_t in[64]; + uint8_t out[64]; + uint8_t tag[16]; + size_t keylen, ivlen, aadlen, inlen, outlen, taglen; + + uint8_t buf[64]; + uint8_t mac[16]; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); + hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); + hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); + hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); + hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); + + memset(buf, 0, sizeof(buf)); + memset(mac, 0, sizeof(mac)); + + sm4_set_encrypt_key(&sm4_key, key); + + // test gcm encrypt + sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); + if (memcmp(buf, out, outlen) != 0) { + error_print(); + return -1; + } + if (memcmp(mac, tag, taglen) != 0) { + error_print(); + return -1; + } + + // test gcm decrypt + memset(buf, 0, sizeof(buf)); + sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); + if (memcmp(buf, in, inlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_gcm_gbt36624_2(void) +{ + // gcm test vectors from GB/T 36624-2018 C.5 + const char *hex_key = "00000000000000000000000000000000"; + const char *hex_iv = "000000000000000000000000"; + const char *hex_aad = ""; + const char *hex_in = "00000000000000000000000000000000"; + const char *hex_out = "7DE2AA7F1110188218063BE1BFEB6D89"; + const char *hex_tag = "B851B5F39493752BE508F1BB4482C557"; + + SM4_KEY sm4_key; + uint8_t key[16]; + uint8_t iv[12]; + uint8_t aad[20]; + uint8_t in[64]; + uint8_t out[64]; + uint8_t tag[16]; + size_t keylen, ivlen, aadlen, inlen, outlen, taglen; + + uint8_t buf[64]; + uint8_t mac[16]; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); + hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); + hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); + hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); + hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); + + memset(buf, 0, sizeof(buf)); + memset(mac, 0, sizeof(mac)); + + sm4_set_encrypt_key(&sm4_key, key); + + // test gcm encrypt + sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); + if (memcmp(buf, out, outlen) != 0) { + error_print(); + return -1; + } + if (memcmp(mac, tag, taglen) != 0) { + error_print(); + return -1; + } + + // test gcm decrypt + memset(buf, 0, sizeof(buf)); + sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); + if (memcmp(buf, in, inlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_gcm_update(void) +{ + SM4_GCM_CTX aead_ctx; + uint8_t key[16]; + uint8_t iv[16]; + uint8_t aad[29]; + uint8_t plain[71]; + size_t plainlen = sizeof(plain); + uint8_t cipher[256]; + size_t cipherlen = 0; + uint8_t buf[256]; + size_t buflen = 0; + + size_t lens[] = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; + uint8_t *in = plain; + uint8_t *out = cipher; + size_t inlen, outlen; + size_t i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + rand_bytes(aad, sizeof(aad)); + rand_bytes(plain, plainlen); + + if (sm4_gcm_encrypt_init(&aead_ctx, key, sizeof(key), iv, sizeof(iv), aad, sizeof(aad), GHASH_SIZE) != 1) { + error_print(); + return -1; + } + for (i = 0; plainlen; i++) { + assert(i < sizeof(lens)/sizeof(lens[0])); + + inlen = plainlen < lens[i] ? plainlen : lens[i]; + if (sm4_gcm_encrypt_update(&aead_ctx, in, inlen, out, &outlen) != 1) { + error_print(); + return -1; + } + in += inlen; + plainlen -= inlen; + out += outlen; + cipherlen += outlen; + } + if (sm4_gcm_encrypt_finish(&aead_ctx, out, &outlen) != 1) { + error_print(); + return -1; + } + out += outlen; + cipherlen += outlen; + + format_bytes(stdout, 0, 4, "plaintext ", plain, sizeof(plain)); + format_bytes(stdout, 0, 4, "ciphertext", cipher, cipherlen); + + { + SM4_KEY sm4_key; + uint8_t tmp[256]; + size_t tmplen; + + sm4_set_encrypt_key(&sm4_key, key); + + if (sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), plain, sizeof(plain), + tmp, GHASH_SIZE, tmp + sizeof(plain)) != 1) { + error_print(); + return -1; + } + tmplen = sizeof(plain) + GHASH_SIZE; + + format_bytes(stdout, 0, 4, "ciphertext", tmp, tmplen); + + if (cipherlen != tmplen + || memcmp(cipher, tmp, tmplen) != 0) { + error_print(); + return -1; + } + } + + in = cipher; + out = buf; + + if (sm4_gcm_decrypt_init(&aead_ctx, key, sizeof(key), iv, sizeof(iv), aad, sizeof(aad), GHASH_SIZE) != 1) { + error_print(); + return -1; + } + for (i = sizeof(lens)/sizeof(lens[0]) - 1; cipherlen; i--) { + inlen = cipherlen < lens[i] ? cipherlen : lens[i]; + + if (sm4_gcm_decrypt_update(&aead_ctx, in, inlen, out, &outlen) != 1) { + error_print(); + return -1; + } + in += inlen; + cipherlen -= inlen; + out += outlen; + buflen += outlen; + + } + if (sm4_gcm_decrypt_finish(&aead_ctx, out, &outlen) != 1) { + error_print(); + return -1; + } + out += outlen; + buflen += outlen; + + format_bytes(stdout, 0, 4, "plaintext ", buf, buflen); + + if (buflen != sizeof(plain)) { + error_print(); + return -1; + } + if (memcmp(buf, plain, sizeof(plain)) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_sm4_gcm() != 1) goto err; + if (test_sm4_gcm_gbt36624_1() != 1) goto err; + if (test_sm4_gcm_gbt36624_2() != 1) goto err; + if (test_sm4_gcm_update() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/aeadtest.c b/tests/sm4_sm3_hmactest.c similarity index 66% rename from tests/aeadtest.c rename to tests/sm4_sm3_hmactest.c index a7eb7a9b..8c5131a6 100644 --- a/tests/aeadtest.c +++ b/tests/sm4_sm3_hmactest.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2024 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. @@ -12,13 +12,14 @@ #include #include #include +#include +#include #include #include -#include #include -static int test_aead_sm4_cbc_sm3_hmac(void) +static int test_sm4_cbc_sm3_hmac(void) { SM4_CBC_SM3_HMAC_CTX aead_ctx; uint8_t key[16 + 32]; @@ -137,7 +138,7 @@ static int test_aead_sm4_cbc_sm3_hmac(void) return 1; } -static int test_aead_sm4_ctr_sm3_hmac(void) +static int test_sm4_ctr_sm3_hmac(void) { SM4_CTR_SM3_HMAC_CTX aead_ctx; uint8_t key[16 + 32]; @@ -259,127 +260,13 @@ static int test_aead_sm4_ctr_sm3_hmac(void) return 1; } -static int test_aead_sm4_gcm(void) -{ - SM4_GCM_CTX aead_ctx; - uint8_t key[16]; - uint8_t iv[16]; - uint8_t aad[29]; - uint8_t plain[71]; - size_t plainlen = sizeof(plain); - uint8_t cipher[256]; - size_t cipherlen = 0; - uint8_t buf[256]; - size_t buflen = 0; - - size_t lens[] = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 }; - uint8_t *in = plain; - uint8_t *out = cipher; - size_t inlen, outlen; - size_t i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - rand_bytes(aad, sizeof(aad)); - rand_bytes(plain, plainlen); - - if (sm4_gcm_encrypt_init(&aead_ctx, key, sizeof(key), iv, sizeof(iv), aad, sizeof(aad), GHASH_SIZE) != 1) { - error_print(); - return -1; - } - for (i = 0; plainlen; i++) { - assert(i < sizeof(lens)/sizeof(lens[0])); - - inlen = plainlen < lens[i] ? plainlen : lens[i]; - if (sm4_gcm_encrypt_update(&aead_ctx, in, inlen, out, &outlen) != 1) { - error_print(); - return -1; - } - in += inlen; - plainlen -= inlen; - out += outlen; - cipherlen += outlen; - } - if (sm4_gcm_encrypt_finish(&aead_ctx, out, &outlen) != 1) { - error_print(); - return -1; - } - out += outlen; - cipherlen += outlen; - - format_bytes(stdout, 0, 4, "plaintext ", plain, sizeof(plain)); - format_bytes(stdout, 0, 4, "ciphertext", cipher, cipherlen); - - { - SM4_KEY sm4_key; - uint8_t tmp[256]; - size_t tmplen; - - sm4_set_encrypt_key(&sm4_key, key); - - if (sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), plain, sizeof(plain), - tmp, GHASH_SIZE, tmp + sizeof(plain)) != 1) { - error_print(); - return -1; - } - tmplen = sizeof(plain) + GHASH_SIZE; - - format_bytes(stdout, 0, 4, "ciphertext", tmp, tmplen); - - if (cipherlen != tmplen - || memcmp(cipher, tmp, tmplen) != 0) { - error_print(); - return -1; - } - } - - in = cipher; - out = buf; - - if (sm4_gcm_decrypt_init(&aead_ctx, key, sizeof(key), iv, sizeof(iv), aad, sizeof(aad), GHASH_SIZE) != 1) { - error_print(); - return -1; - } - for (i = sizeof(lens)/sizeof(lens[0]) - 1; cipherlen; i--) { - inlen = cipherlen < lens[i] ? cipherlen : lens[i]; - - if (sm4_gcm_decrypt_update(&aead_ctx, in, inlen, out, &outlen) != 1) { - error_print(); - return -1; - } - in += inlen; - cipherlen -= inlen; - out += outlen; - buflen += outlen; - - } - if (sm4_gcm_decrypt_finish(&aead_ctx, out, &outlen) != 1) { - error_print(); - return -1; - } - out += outlen; - buflen += outlen; - - format_bytes(stdout, 0, 4, "plaintext ", buf, buflen); - - if (buflen != sizeof(plain)) { - error_print(); - return -1; - } - if (memcmp(buf, plain, sizeof(plain)) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - int main(void) { - if (test_aead_sm4_cbc_sm3_hmac() != 1) { error_print(); return -1; } - if (test_aead_sm4_ctr_sm3_hmac() != 1) { error_print(); return -1; } - if (test_aead_sm4_gcm() != 1) { error_print(); return -1; } - printf("%s all tests passed!\n", __FILE__); + if (test_sm4_cbc_sm3_hmac() != 1) goto err; + if (test_sm4_ctr_sm3_hmac() != 1) goto err; + printf("%s all tests passed\n", __FILE__); return 0; +err: + error_print(); + return 1; } diff --git a/tools/sm4.c b/tools/sm4.c index c6bd8470..a7116159 100755 --- a/tools/sm4.c +++ b/tools/sm4.c @@ -14,8 +14,9 @@ #include #include #include +#include +#include #include -#include #include