From 2ecba704724de831e7150e7c6af532d4f33e9ff1 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Sat, 31 Jul 2021 22:07:25 +0800 Subject: [PATCH] remove old api --- include/gmssl/cipher.h | 109 --------- include/gmssl/gcm.h | 2 + include/gmssl/hex.h | 4 +- include/gmssl/hmac.h | 1 - include/gmssl/sm4.h | 15 +- include/gmssl/tls.h | 2 + src/gcm.c | 7 +- src/gf128.c | 2 +- src/hmac.c | 68 +++--- src/pbkdf2.c | 7 +- src/sm4_modes.c | 2 +- src/sm4_setkey.c | 4 +- src/tls.c | 224 +++++++++++++++++ src/tls13.c | 532 +++++++++++++++++++++++++---------------- src/tls_cipher.c | 347 --------------------------- tests/aestest.c | 226 ++++++++++++++++- tests/chacha20test.c | 1 + tests/gcmtest.c | 141 +++++++---- tests/gf128test.c | 46 ++-- tests/hash_drbgtest.c | 45 ++-- tests/md5test.c | 18 +- tests/pbkdf2test.c | 2 +- tests/pemtest.c | 0 tests/sha1test.c | 18 +- tests/sha224test.c | 18 +- tests/sha256test.c | 18 +- tests/sha384test.c | 18 +- tests/sha512test.c | 18 +- tests/sm3test.c | 21 +- tests/u128test.c | 62 ----- 30 files changed, 1025 insertions(+), 953 deletions(-) delete mode 100644 include/gmssl/cipher.h delete mode 100644 src/tls_cipher.c create mode 100644 tests/pemtest.c delete mode 100644 tests/u128test.c diff --git a/include/gmssl/cipher.h b/include/gmssl/cipher.h deleted file mode 100644 index 9daba8be..00000000 --- a/include/gmssl/cipher.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - - -#ifndef GMSSL_CIPHER_H -#define GMSSL_CIPHER_H - -#ifdef __cplusplus -extern "C" { -#endif - - - - - - -struct cipher_st { - int nid; - size_t block_size; - size_t key_size; - size_t iv_size; - unsigned long flags; - int (*init)(CIPHER_CTX *ctx, const uint8_t *key); - int (*encrypt)(CIPHER_CTX *ctx); -}; - -struct cipher_ctx_st { - CIPHER *cipher; - int is_encrypt; - uint8_t iv[16]; - uint8_t block[16]; -}; - -int cipher_encyrpt_init(CIPHER_CTX *ctx, const CIPHER *cipher, const uint8_t *key, const uint8_t *iv); -int cipher_encrypt_update(CIPHER_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int cipher_encrypt_finish(CIPHER_CTX *ctx, uint8_t *out, size_t *outlen); - -int cipher_decrypt_init(CIPHER_CTX *ctx, const CIPHER *cipher, const uint8_t *key, const uint8_t *iv); -int cipher_decrypt_update(CIPHER_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int cipher_decrypt_finish(CIPHER_CTX *ctx, uint8_t *out, size_t *outlen); - -int cipher_init(CIPHER_CTX *ctx, const CIPHER *cipher, const uint8_t *key, const uint8_t *iv, int enc); -int cipher_update(CIPHER_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int cipher_finish(CIPHER_CTX *ctx, uint8_t *out, size_t *outlen); - - -const CIPHER *CIPHER_sm4_ecb(void); -const CIPHER *CIPHER_sm4_cbc(void); -const CIPHER *CIPHER_sm4_ofb(void); -const CIPHER *CIPHER_sm4_cfb1(void); -const CIPHER *CIPHER_sm4_cfb8(void); -const CIPHER *CIPHER_sm4_cfb128(void); -const CIPHER *CIPHER_sm4_ctr(void); -const CIPHER *CIPHER_sm4_gcm(void); -const CIPHER *CIPHER_zuc(void); -const CIPHER *CIPHER_zuc256(void); - - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/gmssl/gcm.h b/include/gmssl/gcm.h index 792145ad..10e372e3 100644 --- a/include/gmssl/gcm.h +++ b/include/gmssl/gcm.h @@ -75,6 +75,8 @@ extern "C" { #define GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) +#define GHASH_SIZE (16) + #define GCM_IS_LITTLE_ENDIAN 1 diff --git a/include/gmssl/hex.h b/include/gmssl/hex.h index 2917cec6..a0214097 100644 --- a/include/gmssl/hex.h +++ b/include/gmssl/hex.h @@ -65,8 +65,8 @@ int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen); int hex2bin(const char *in, size_t inlen, uint8_t *out); -int OPENSSL_hexchar2int(unsigned char c); -unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len); +//int OPENSSL_hexchar2int(unsigned char c); +//unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len); #ifdef __cplusplus } diff --git a/include/gmssl/hmac.h b/include/gmssl/hmac.h index 40268cb5..ee34c1e9 100644 --- a/include/gmssl/hmac.h +++ b/include/gmssl/hmac.h @@ -73,7 +73,6 @@ size_t hmac_size(const HMAC_CTX *ctx); int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen); int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen); int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen); -int hmac_reset(HMAC_CTX *ctx); int hmac(const DIGEST *md, const unsigned char *key, size_t keylen, const unsigned char *data, size_t dlen, diff --git a/include/gmssl/sm4.h b/include/gmssl/sm4.h index ac2d5a7e..0153a209 100644 --- a/include/gmssl/sm4.h +++ b/include/gmssl/sm4.h @@ -60,11 +60,9 @@ extern "C" { #endif -#define SM4_KEY_SIZE 16 -#define SM4_KEY_LENGTH 16 -#define SM4_BLOCK_SIZE 16 -#define SM4_IV_LENGTH (SM4_BLOCK_SIZE) -#define SM4_NUM_ROUNDS 32 +#define SM4_KEY_SIZE (16) +#define SM4_BLOCK_SIZE (16) +#define SM4_NUM_ROUNDS (32) typedef struct { @@ -72,10 +70,9 @@ typedef struct { } SM4_KEY; -void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16]); -void sm4_set_decrypt_key(SM4_KEY *key, const unsigned char user_key[16]); -void sm4_encrypt(const SM4_KEY *key, const unsigned char in[16], unsigned char out[16]); -#define sm4_decrypt(key,in,out) sm4_encrypt(key,in,out) +void sm4_set_encrypt_key(SM4_KEY *sm4_key, const uint8_t key[16]); +void sm4_set_decrypt_key(SM4_KEY *sm4_key, const uint8_t key[16]); +void sm4_encrypt(const SM4_KEY *sm4_key, const uint8_t in[16], uint8_t out[16]); void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16], diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index 203b4f00..4ff5eb3a 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -92,6 +92,8 @@ int tls_uint24array_copy_from_bytes(uint8_t *data, size_t *datalen, size_t maxle typedef enum { + TLS_version_tls12_major = 3, + TLS_version_tls12_minor = 3, TLS_version_tlcp = 0x0101, TLS_version_ssl2 = 0x0200, TLS_version_ssl3 = 0x0300, diff --git a/src/gcm.c b/src/gcm.c index 4d08f960..6a5bf8b5 100644 --- a/src/gcm.c +++ b/src/gcm.c @@ -135,6 +135,11 @@ 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()) { + sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out); + } else if (key->cipher == BLOCK_CIPHER_aes128()) { + aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out); + } + error_print(); return -1; } - diff --git a/src/gf128.c b/src/gf128.c index 714dde9f..d27b99d1 100644 --- a/src/gf128.c +++ b/src/gf128.c @@ -85,7 +85,7 @@ void gf128_print_bits(gf128_t a) { int i; for (i = 0; i < 128; i++) { - printf("%d", (int)(a % 2)); + printf("%d", a % 2); a >>= 1; } printf("\n"); diff --git a/src/hmac.c b/src/hmac.c index 754f8b08..3fd064cd 100644 --- a/src/hmac.c +++ b/src/hmac.c @@ -48,23 +48,13 @@ #include #include +#include #define IPAD 0x36 #define OPAD 0x5C -int hmac_ctx_init(HMAC_CTX *ctx) -{ - memset(ctx, 0, sizeof(HMAC_CTX)); - return 1; -} - -void hmac_ctx_cleanup(HMAC_CTX *ctx) -{ - memset(ctx, 0, sizeof(HMAC_CTX)); -} - int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen) { uint8_t i_key[DIGEST_MAX_BLOCK_SIZE] = {0}; @@ -73,7 +63,8 @@ int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, siz int i; if (!ctx || !digest || !key || !keylen) { - return 0; + error_print(); + return -1; } ctx->digest = digest; @@ -107,34 +98,45 @@ int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, siz int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen) { if (!ctx || (!data && datalen != 0)) { - return 0; + error_print(); + return -1; } - return digest_update(&ctx->digest_ctx, data, datalen); + if (digest_update(&ctx->digest_ctx, data, datalen) != 1) { + error_print(); + return -1; + } + return 1; } int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen) { - int ret = 0; - size_t i; - size_t blocksize; - - if (!digest_finish(&ctx->digest_ctx, mac, maclen)) { + if (digest_finish(&ctx->digest_ctx, mac, maclen) != 1) { + error_print(); return -1; } memcpy(&ctx->digest_ctx, &ctx->o_ctx, sizeof(DIGEST_CTX)); - if (!digest_update(&ctx->digest_ctx, mac, *maclen) - || !digest_finish(&ctx->digest_ctx, mac, maclen)) { - goto end; + if (digest_update(&ctx->digest_ctx, mac, *maclen) != 1 + || digest_finish(&ctx->digest_ctx, mac, maclen) != 1) { + error_print(); + return -1; } - - ret = 1; -end: - return ret; + return 1; } -int hmac_reset(HMAC_CTX *ctx) +int hmac_finish_and_verify(HMAC_CTX *ctx, const uint8_t *mac, size_t maclen) { - memcpy(&ctx->digest_ctx, &ctx->i_ctx, sizeof(DIGEST_CTX)); + uint8_t hmac[64]; + size_t hmaclen; + + if (hmac_finish(ctx, hmac, &hmaclen) != 1) { + error_print(); + return -1; + } + if (maclen != hmaclen + || memcmp(hmac, mac, maclen) != 0) { + error_print(); + return -1; + } return 1; } @@ -145,14 +147,14 @@ int hmac(const DIGEST *digest, const unsigned char *key, size_t keylen, int ret = 0; HMAC_CTX ctx; - if (!hmac_ctx_init(&ctx) - || !hmac_init(&ctx, digest, key, keylen) - || !hmac_update(&ctx, data, datalen) - || !hmac_finish(&ctx, mac, maclen)) { + if (hmac_init(&ctx, digest, key, keylen) != 1 + || hmac_update(&ctx, data, datalen) != 1 + || hmac_finish(&ctx, mac, maclen) != 1) { goto end; } ret = 1; + end: - hmac_ctx_cleanup(&ctx); + memset(&ctx, 0, sizeof(ctx)); return ret; } diff --git a/src/pbkdf2.c b/src/pbkdf2.c index 7504acfc..febd26e7 100644 --- a/src/pbkdf2.c +++ b/src/pbkdf2.c @@ -129,13 +129,14 @@ int pbkdf2_genkey(const DIGEST *digest, size_t outlen, uint8_t *out) { HMAC_CTX ctx; + HMAC_CTX ctx_tmpl; uint32_t iter = 1; uint8_t iter_be[4]; uint8_t tmp_block[64]; uint8_t key_block[64]; size_t len; - hmac_init(&ctx, digest, (uint8_t *)pass, passlen); + hmac_init(&ctx_tmpl, digest, (uint8_t *)pass, passlen); while (outlen > 0) { int i; @@ -143,16 +144,16 @@ int pbkdf2_genkey(const DIGEST *digest, PUTU32(iter_be, iter); iter++; + ctx = ctx_tmpl; hmac_update(&ctx, salt, saltlen); hmac_update(&ctx, iter_be, sizeof(iter_be)); hmac_finish(&ctx, tmp_block, &len); - hmac_reset(&ctx); memcpy(key_block, tmp_block, len); for (i = 1; i < count; i++) { + ctx = ctx_tmpl; hmac_update(&ctx, tmp_block, len); hmac_finish(&ctx, tmp_block, &len); - hmac_reset(&ctx); memxor(key_block, tmp_block, len); } diff --git a/src/sm4_modes.c b/src/sm4_modes.c index 1b1115f2..5beeecb7 100644 --- a/src/sm4_modes.c +++ b/src/sm4_modes.c @@ -67,7 +67,7 @@ void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[16], const uint8_t *in, size_t nblocks, uint8_t *out) { while (nblocks--) { - sm4_decrypt(key, in, out); + sm4_encrypt(key, in, out); memxor(out, iv, 16); iv = in; in += 16; diff --git a/src/sm4_setkey.c b/src/sm4_setkey.c index 01664cf5..2c2bf029 100644 --- a/src/sm4_setkey.c +++ b/src/sm4_setkey.c @@ -83,7 +83,7 @@ static uint32_t CK[32] = { x4 = x0 ^ L32_(x4); \ *(rk + 31 - i) = x4 -void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16]) +void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t user_key[16]) { uint32_t *rk = key->rk; uint32_t x0, x1, x2, x3, x4; @@ -100,7 +100,7 @@ void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16]) x0 = x1 = x2 = x3 = x4 = 0; } -void sm4_set_decrypt_key(SM4_KEY *key, const unsigned char user_key[16]) +void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t user_key[16]) { uint32_t *rk = key->rk; uint32_t x0, x1, x2, x3, x4; diff --git a/src/tls.c b/src/tls.c index acb3c8cd..8cc3297f 100644 --- a/src/tls.c +++ b/src/tls.c @@ -322,7 +322,118 @@ int tls_record_length(const uint8_t *record) } +int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key, + const uint8_t seq_num[8], const uint8_t header[5], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM3_HMAC_CTX hmac_ctx; + uint8_t last_blocks[32 + 16] = {0}; + uint8_t *mac, *padding, *iv; + int rem, padding_len; + int i; + if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) { + error_print(); + return -1; + } + if (inlen > (1 << 14)) { + error_print("invalid tls record data length %zu\n", inlen); + return -1; + } + + rem = (inlen + 32) % 16; + memcpy(last_blocks, in + inlen - rem, rem); + mac = last_blocks + rem; + + memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, seq_num, 8); + sm3_hmac_update(&hmac_ctx, header, 5); + sm3_hmac_update(&hmac_ctx, in, inlen); + sm3_hmac_finish(&hmac_ctx, mac); + + padding = mac + 32; + padding_len = 16 - rem - 1; + for (i = 0; i <= padding_len; i++) { + padding[i] = padding_len; + } + + iv = out; + if (rand_bytes(iv, 16) != 1) { + error_print(); + return -1; + } + out += 16; + + if (inlen >= 16) { + sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out); + out += inlen - rem; + iv = out - 16; + } + sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out); + *outlen = 16 + inlen - rem + sizeof(last_blocks); + return 1; +} + +int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key, + const uint8_t seq_num[8], const uint8_t enced_header[5], + const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) +{ + SM3_HMAC_CTX hmac_ctx; + const uint8_t *iv; + const uint8_t *padding; + const uint8_t *mac; + uint8_t header[5]; + int padding_len; + int i; + + if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) { + error_print(); + return -1; + } + if (inlen % 16 + || inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding + || inlen > (16 + (1<<14) + 32 + 256)) { + error_print("invalid tls cbc ciphertext length %zu\n", inlen); + return -1; + } + + iv = in; + in += 16; + inlen -= 16; + + sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out); + + padding_len = out[inlen - 1]; + padding = out + inlen - padding_len - 1; + if (padding < out + 32) { + error_print(); + return -1; + } + for (i = 0; i < padding_len; i++) { + if (padding[i] != padding_len) { + error_print("tls ciphertext cbc-padding check failure"); + return -1; + } + } + + *outlen = inlen - 32 - padding_len - 1; + header[0] = enced_header[0]; + header[1] = enced_header[1]; + header[2] = enced_header[2]; + header[3] = (*outlen) >> 8; + header[4] = (*outlen); + mac = padding - 32; + + memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, seq_num, 8); + sm3_hmac_update(&hmac_ctx, header, 5); + sm3_hmac_update(&hmac_ctx, out, *outlen); + if (sm3_hmac_finish_and_verify(&hmac_ctx, mac) != 1) { + error_print("tls ciphertext mac check failure"); + return -1; + } + return 1; +} // 这个函数应该是处理的,这个函数是不应该用的,通常我们在加密的时候,header ,明文数据是分离的,但是输出的record是一个 int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, @@ -378,6 +489,62 @@ int tls_random_generate(uint8_t random[32]) return 1; } +int tls_prf(const uint8_t *secret, size_t secretlen, const char *label, + const uint8_t *seed, size_t seedlen, + const uint8_t *more, size_t morelen, + size_t outlen, uint8_t *out) +{ + SM3_HMAC_CTX inited_hmac_ctx; + SM3_HMAC_CTX hmac_ctx; + uint8_t A[32]; + uint8_t hmac[32]; + size_t len; + + if (!secret || !secretlen || !label || !seed || !seedlen + || (!more && morelen) || !outlen || !out) { + error_print(); + return -1; + } + + sm3_hmac_init(&inited_hmac_ctx, secret, secretlen); + + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); + sm3_hmac_update(&hmac_ctx, seed, seedlen); + sm3_hmac_update(&hmac_ctx, more, morelen); + sm3_hmac_finish(&hmac_ctx, A); + + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, A, sizeof(A)); + sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); + sm3_hmac_update(&hmac_ctx, seed, seedlen); + sm3_hmac_update(&hmac_ctx, more, morelen); + sm3_hmac_finish(&hmac_ctx, hmac); + + len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); + memcpy(out, hmac, len); + out += len; + outlen -= len; + + while (outlen) { + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, A, sizeof(A)); + sm3_hmac_finish(&hmac_ctx, A); + + memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); + sm3_hmac_update(&hmac_ctx, A, sizeof(A)); + sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); + sm3_hmac_update(&hmac_ctx, seed, seedlen); + sm3_hmac_update(&hmac_ctx, more, morelen); + sm3_hmac_finish(&hmac_ctx, hmac); + + len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); + memcpy(out, hmac, len); + out += len; + outlen -= len; + } + return 1; +} int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int version) { @@ -396,6 +563,63 @@ int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int version) +int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key, + const uint8_t client_random[32], const uint8_t server_random[32], + int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen) +{ + uint8_t server_ecdh_params[69]; + SM2_SIGN_CTX sign_ctx; + + if (!server_sign_key || !client_random || !server_random + || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) { + error_print(); + return -1; + } + server_ecdh_params[0] = TLS_curve_type_named_curve; + server_ecdh_params[1] = curve >> 8; + server_ecdh_params[2] = curve; + server_ecdh_params[3] = 65; + sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); + + sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID); + sm2_sign_update(&sign_ctx, client_random, 32); + sm2_sign_update(&sign_ctx, server_random, 32); + sm2_sign_update(&sign_ctx, server_ecdh_params, 69); + sm2_sign_finish(&sign_ctx, sig, siglen); + + return 1; +} + +int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key, + const uint8_t client_random[32], const uint8_t server_random[32], + int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen) +{ + int ret; + uint8_t server_ecdh_params[69]; + SM2_SIGN_CTX verify_ctx; + + if (!server_sign_key || !client_random || !server_random + || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen + || siglen > TLS_MAX_SIGNATURE_SIZE) { + error_print(); + return -1; + } + server_ecdh_params[0] = TLS_curve_type_named_curve; + server_ecdh_params[1] = curve >> 8; + server_ecdh_params[2] = curve; + server_ecdh_params[3] = 65; + sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); + + sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID); + sm2_verify_update(&verify_ctx, client_random, 32); + sm2_verify_update(&verify_ctx, server_random, 32); + sm2_verify_update(&verify_ctx, server_ecdh_params, 69); + ret = sm2_verify_finish(&verify_ctx, sig, siglen); + if (ret != 1) error_print(); + return ret; +} + + // handshakes diff --git a/src/tls13.c b/src/tls13.c index 6ebe583c..dc3ee2f8 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -65,45 +65,66 @@ #include #include #include -#include #include #include +#include #include "mem.h" -int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *enc_key, - const uint8_t iv[12], size_t padding_len, + +/* +struct { + opaque content[TLSPlaintext.length]; + ContentType type; + uint8 zeros[length_of_padding]; +} TLSInnerPlaintext; + +struct { + ContentType opaque_type = application_data; // 23 + ProtocolVersion legacy_record_version = 0x0303; // TLS v1.2 + uint16 length; + opaque encrypted_record[TLSCiphertext.length]; +} TLSCiphertext; +*/ +int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], const uint8_t seq_num[8], int record_type, - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) + const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content + uint8_t *out, size_t *outlen) // TLSCiphertext.encrypted_record { uint8_t nonce[12]; - uint8_t *mbuf = malloc(inlen + 256); uint8_t aad[5]; uint8_t *gmac; + uint8_t *mbuf = malloc(inlen + 256); // FIXME: update gcm_encrypt API size_t mlen, clen; + // nonce = (zeros|seq_num) xor (iv) nonce[0] = nonce[1] = nonce[2] = 0; memcpy(nonce + 3, seq_num, 8); gmssl_memxor(nonce, nonce, iv, 12); + // TLSInnerPlaintext memcpy(mbuf, in, inlen); mbuf[inlen] = record_type; memset(mbuf + inlen + 1, 0, padding_len); mlen = inlen + 1 + padding_len; - clen = mlen + 16; + clen = mlen + GHASH_SIZE; + // aad = TLSCiphertext header aad[0] = TLS_record_application_data; - aad[1] = 3; - aad[2] = 3; + aad[1] = TLS_version_tls12_major; + aad[2] = TLS_version_tls12_minor; aad[3] = clen >> 8; aad[4] = clen; gmac = out + mlen; - gcm_encrypt(enc_key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac); + if (gcm_encrypt(key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac) != 1) { + error_print(); + return -1; + } return 1; } -int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *sm4_key, const uint8_t iv[12], +int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], const uint8_t seq_num[8], const uint8_t *in, size_t inlen, int *record_type, uint8_t *out, size_t *outlen) { @@ -113,62 +134,335 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *sm4_key, const uint8_t iv[12], const uint8_t *gmac; size_t i; + // nonce = (zeros|seq_num) xor (iv) nonce[0] = nonce[1] = nonce[2] = 0; memcpy(nonce + 3, seq_num, 8); gmssl_memxor(nonce, nonce, iv, 12); + // aad = TLSCiphertext header aad[0] = TLS_record_application_data; - aad[1] = 3; - aad[2] = 3; + aad[1] = TLS_version_tls12_major; + aad[2] = TLS_version_tls12_minor; aad[3] = inlen >> 8; + aad[4] = inlen; - mlen = inlen - 16; - + if (inlen < GHASH_SIZE) { + error_print(); + return -1; + } + mlen = inlen - GHASH_SIZE; + gmac = in + mlen; - return -1; -} - -int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, size_t padding_len, - uint8_t *out, size_t *outlen) -{ - if (tls13_gcm_encrypt(key, iv, padding_len, - seq_num, in[0], in + 5, inlen - 5, out + 5, outlen) != 1) { + if (gcm_decrypt(key, iv, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) { error_print(); return -1; } - out[0] = TLS_record_application_data; - out[1] = in[1]; - out[2] = in[2]; - out[3] = (*outlen) >> 8; - out[4] = (*outlen); - (*outlen) += 5; + // remove padding, get record_type + *record_type = 0; + while (mlen--) { + if (out[mlen] != 0) { + *record_type = out[mlen]; + break; + } + } + if (!tls_record_type_name(*record_type)) { + error_print(); + return -1; + } + return 1; +} +int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], + const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len, + uint8_t *enced_record, size_t *enced_recordlen) +{ + if (tls13_gcm_encrypt(key, iv, + seq_num, record[0], record + 5, recordlen - 5, padding_len, + enced_record + 5, enced_recordlen) != 1) { + error_print(); + return -1; + } + + enced_record[0] = TLS_record_application_data; + enced_record[1] = TLS_version_tls12_major; + enced_record[2] = TLS_version_tls12_minor; + enced_record[3] = (*enced_recordlen) >> 8; + enced_record[4] = (*enced_recordlen); + + (*enced_recordlen) += 5; return 1; } int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], - const uint8_t seq_num[8], const uint8_t *in, size_t inlen, - uint8_t *out, size_t *outlen) + const uint8_t seq_num[8], const uint8_t *enced_record, size_t enced_recordlen, + uint8_t *record, size_t *recordlen) { int record_type; - if (tls13_gcm_decrypt(key, iv, seq_num, in + 5, inlen - 5, - &record_type, out + 5, outlen) != 1) { + if (tls13_gcm_decrypt(key, iv, + seq_num, enced_record + 5, enced_recordlen - 5, + &record_type, record + 5, recordlen) != 1) { + error_print(); + return -1; + } + record[0] = record_type; + record[1] = TLS_version_tls12_major; + record[2] = TLS_version_tls12_minor; + record[3] = (*recordlen) >> 8; + record[4] = (*recordlen); + + (*recordlen) += 5; + return 1; +} + +int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t padding_len) +{ + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + uint8_t *record = conn->record; + size_t recordlen; + + tls_trace("<<<< [ApplicationData]\n"); + + if (conn->is_client) { + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if (tls13_gcm_encrypt(key, iv, + seq_num, TLS_record_application_data, data, datalen, padding_len, + record + 5, &recordlen) != 1) { error_print(); return -1; } - out[0] = record_type; - out[1] = in[1]; - out[2] = in[2]; - out[3] = (*outlen) >> 8; - out[4] = (*outlen); + record[0] = TLS_record_application_data; + record[1] = TLS_version_tls12 >> 8; + record[2] = TLS_version_tls12 & 0xff; + record[3] = recordlen >> 8; + record[4] = recordlen; + recordlen += 5; + + tls_record_send(record, recordlen, conn->sock); + tls_seq_num_incr(seq_num); return 1; } +int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen) +{ + int record_type; + uint8_t *record = conn->record; + size_t recordlen; + const BLOCK_CIPHER_KEY *key; + const uint8_t *iv; + uint8_t *seq_num; + + + tls_trace(">>>> [ApplicationData]\n"); + + if (conn->is_client) { + key = &conn->client_write_key; + iv = conn->client_write_iv; + seq_num = conn->client_seq_num; + } else { + key = &conn->server_write_key; + iv = conn->server_write_iv; + seq_num = conn->server_seq_num; + } + + if (tls12_record_recv(record, &recordlen, conn->sock) != 1) { + error_print(); + return -1; + } + if (record[0] != TLS_record_application_data) { + error_print(); + return -1; + } + + if (tls13_gcm_decrypt(key, iv, + seq_num, record + 5, recordlen - 5, + &record_type, data, datalen) != 1) { + error_print(); + return -1; + } + tls_seq_num_incr(seq_num); + + if (record_type != TLS_record_application_data) { + error_print(); + return -1; + } + return 1; +} + + +/* +HKDF-Expand-Label(Secret, Label, Context, Length) = + HKDF-Expand(Secret, HkdfLabel, Length); + + HkdfLabel = struct { + uint16 length = Length; + opaque label<7..255> = "tls13 " + Label; + opaque context<0..255> = Context; } + +Derive-Secret(Secret, Label, Messages) = + HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length) + +*/ + +int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]) +{ + size_t dgstlen; + if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1 + || dgstlen != 32) { + error_print(); + return -1; + } + return 1; +} + +int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32], + const char *label, const uint8_t *context, size_t context_len, + size_t outlen, uint8_t *out) +{ + uint8_t label_len; + uint8_t hkdf_label[2 + 256 + 256]; + uint8_t *p = hkdf_label; + size_t hkdf_label_len = 0; + + label_len = strlen("tls13") + strlen(label); + tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len); + tls_uint8_to_bytes(label_len, &p, &hkdf_label_len); + tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len); + tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len); + tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len); + + hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out); + return 1; +} + +int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]) +{ + DIGEST_CTX ctx = *dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + + if (digest_finish(&ctx, dgst, &dgstlen) != 1 + || tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) { + error_print(); + return -1; + } + return 1; +} + + +/* +data to be signed in certificate_verify: + - A string that consists of octet 32 (0x20) repeated 64 times + - The context string + - A single 0 byte which serves as the separator + - The content to be signed +*/ +int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server) +{ + uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; + uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; + + SM2_SIGN_CTX sm2_ctx; + DIGEST_CTX temp_dgst_ctx; + uint8_t prefix[64]; + uint8_t *context_str = is_server ? server_context_str : client_context_str; + size_t context_str_len = sizeof(client_context_str); + uint8_t dgst[64]; + size_t dgstlen; + + memset(prefix, 0x20, 64); + temp_dgst_ctx = *dgst_ctx; + digest_finish(&temp_dgst_ctx, dgst, &dgstlen); + + sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID); + sm2_sign_update(&sm2_ctx, prefix, 64); + sm2_sign_update(&sm2_ctx, context_str, context_str_len); + sm2_sign_update(&sm2_ctx, dgst, dgstlen); + sm2_sign_finish(&sm2_ctx, sig, siglen); + + return 1; +} + +int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server) +{ + uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; + uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; + + int ret; + SM2_SIGN_CTX sm2_ctx; + DIGEST_CTX temp_dgst_ctx; + uint8_t prefix[64]; + uint8_t dgst[64]; + size_t dgstlen; + + memset(prefix, 0x20, 64); + temp_dgst_ctx = *dgst_ctx; + digest_finish(&temp_dgst_ctx, dgst, &dgstlen); + + sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID); + sm2_verify_update(&sm2_ctx, prefix, 64); + sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str)); + sm2_verify_update(&sm2_ctx, dgst, dgstlen); + ret = sm2_verify_finish(&sm2_ctx, sig, siglen); + + return ret; +} + +/* + verify_data in Finished + + finished_key = + HKDF-Expand-Label(BaseKey, "finished", "", Hash.length) + Structure of this message: + struct { + opaque verify_data[Hash.length]; + } Finished; + The verify_data value is computed as follows: + verify_data = + HMAC(finished_key, + Transcript-Hash(Handshake Context, + Certificate*, CertificateVerify*)) +*/ + +int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret, + const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len) +{ + DIGEST_CTX temp_dgst_ctx; + uint8_t dgst[64]; + size_t dgstlen; + uint8_t finished_key[64]; + size_t finished_key_len; + + temp_dgst_ctx = *dgst_ctx; + digest_finish(&temp_dgst_ctx, dgst, &dgstlen); + finished_key_len = dgstlen; + + tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret, + "finished", NULL, 0, finished_key_len, finished_key); + + hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len); + + return 1; +} + +/* +Handshakes + +*/ + int tls_ext_supported_versions_to_bytes(const int *versions, size_t versions_count, uint8_t **out, size_t *outlen) { @@ -597,56 +891,6 @@ int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record) return 1; } -int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server) -{ - uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; - uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; - - SM2_SIGN_CTX sm2_ctx; - DIGEST_CTX temp_dgst_ctx; - uint8_t prefix[64]; - uint8_t *context_str = is_server ? server_context_str : client_context_str; - size_t context_str_len = sizeof(client_context_str); - uint8_t dgst[64]; - size_t dgstlen; - - memset(prefix, 0x20, 64); - temp_dgst_ctx = *dgst_ctx; - digest_finish(&temp_dgst_ctx, dgst, &dgstlen); - - sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID); - sm2_sign_update(&sm2_ctx, prefix, 64); - sm2_sign_update(&sm2_ctx, context_str, context_str_len); - sm2_sign_update(&sm2_ctx, dgst, dgstlen); - sm2_sign_finish(&sm2_ctx, sig, siglen); - - return 1; -} - -int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server) -{ - uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify"; - uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify"; - - int ret; - SM2_SIGN_CTX sm2_ctx; - DIGEST_CTX temp_dgst_ctx; - uint8_t prefix[64]; - uint8_t dgst[64]; - size_t dgstlen; - - memset(prefix, 0x20, 64); - temp_dgst_ctx = *dgst_ctx; - digest_finish(&temp_dgst_ctx, dgst, &dgstlen); - - sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID); - sm2_verify_update(&sm2_ctx, prefix, 64); - sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str)); - sm2_verify_update(&sm2_ctx, dgst, dgstlen); - ret = sm2_verify_finish(&sm2_ctx, sig, siglen); - - return ret; -} /* ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法 @@ -814,26 +1058,6 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, uint8_t *data, } -int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret, - const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len) -{ - DIGEST_CTX temp_dgst_ctx; - uint8_t dgst[64]; - size_t dgstlen; - uint8_t finished_key[64]; - size_t finished_key_len; - - temp_dgst_ctx = *dgst_ctx; - digest_finish(&temp_dgst_ctx, dgst, &dgstlen); - finished_key_len = dgstlen; - - tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret, - "finished", NULL, 0, finished_key_len, finished_key); - - hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len); - - return 1; -} @@ -1839,95 +2063,3 @@ int tls13_accept(TLS_CONNECT *conn, int port, tls_trace("Connection Established!\n\n"); return 1; } - - -int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t padding_len) -{ - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; - uint8_t *record = conn->record; - size_t recordlen; - - tls_trace("<<<< [ApplicationData]\n"); - - if (conn->is_client) { - key = &conn->client_write_key; - iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } else { - key = &conn->server_write_key; - iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } - - if (tls13_gcm_encrypt(key, iv, padding_len, - seq_num, TLS_record_application_data, data, datalen, - record + 5, &recordlen) != 1) { - error_print(); - return -1; - } - - record[0] = TLS_record_application_data; - record[1] = TLS_version_tls12 >> 8; - record[2] = TLS_version_tls12 & 0xff; - record[3] = recordlen >> 8; - record[4] = recordlen; - recordlen += 5; - - tls_record_send(record, recordlen, conn->sock); - tls_seq_num_incr(seq_num); - - return 1; -} - -int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen) -{ - int record_type; - uint8_t *record = conn->record; - size_t recordlen; - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; - - - tls_trace(">>>> [ApplicationData]\n"); - - if (conn->is_client) { - key = &conn->client_write_key; - iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } else { - key = &conn->server_write_key; - iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } - - if (tls12_record_recv(record, &recordlen, conn->sock) != 1) { - error_print(); - return -1; - } - if (record[0] != TLS_record_application_data) { - error_print(); - return -1; - } - - if (tls13_gcm_decrypt(key, iv, - seq_num, record + 5, recordlen - 5, - &record_type, data, datalen) != 1) { - error_print(); - return -1; - } - tls_seq_num_incr(seq_num); - - - if (record_type != TLS_record_application_data) { - error_print(); - return -1; - } - return 1; -} - - - - diff --git a/src/tls_cipher.c b/src/tls_cipher.c deleted file mode 100644 index ed676940..00000000 --- a/src/tls_cipher.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "mem.h" - - - -int tls_prf(const uint8_t *secret, size_t secretlen, const char *label, - const uint8_t *seed, size_t seedlen, - const uint8_t *more, size_t morelen, - size_t outlen, uint8_t *out) -{ - SM3_HMAC_CTX inited_hmac_ctx; - SM3_HMAC_CTX hmac_ctx; - uint8_t A[32]; - uint8_t hmac[32]; - size_t len; - - if (!secret || !secretlen || !label || !seed || !seedlen - || (!more && morelen) || !outlen || !out) { - error_print(); - return -1; - } - - sm3_hmac_init(&inited_hmac_ctx, secret, secretlen); - - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); - sm3_hmac_update(&hmac_ctx, seed, seedlen); - sm3_hmac_update(&hmac_ctx, more, morelen); - sm3_hmac_finish(&hmac_ctx, A); - - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, A, sizeof(A)); - sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); - sm3_hmac_update(&hmac_ctx, seed, seedlen); - sm3_hmac_update(&hmac_ctx, more, morelen); - sm3_hmac_finish(&hmac_ctx, hmac); - - len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); - memcpy(out, hmac, len); - out += len; - outlen -= len; - - while (outlen) { - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, A, sizeof(A)); - sm3_hmac_finish(&hmac_ctx, A); - - memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, A, sizeof(A)); - sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label)); - sm3_hmac_update(&hmac_ctx, seed, seedlen); - sm3_hmac_update(&hmac_ctx, more, morelen); - sm3_hmac_finish(&hmac_ctx, hmac); - - len = outlen < sizeof(hmac) ? outlen : sizeof(hmac); - memcpy(out, hmac, len); - out += len; - outlen -= len; - } - return 1; -} - -/* -HKDF-Expand-Label(Secret, Label, Context, Length) = - HKDF-Expand(Secret, HkdfLabel, Length); - - HkdfLabel = struct { - uint16 length = Length; - opaque label<7..255> = "tls13 " + Label; - opaque context<0..255> = Context; } - -Derive-Secret(Secret, Label, Messages) = - HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length) - -*/ - -int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32]) -{ - size_t dgstlen; - if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1 - || dgstlen != 32) { - error_print(); - return -1; - } - return 1; -} - -int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32], - const char *label, const uint8_t *context, size_t context_len, - size_t outlen, uint8_t *out) -{ - uint8_t label_len; - uint8_t hkdf_label[2 + 256 + 256]; - uint8_t *p = hkdf_label; - size_t hkdf_label_len = 0; - - label_len = strlen("tls13") + strlen(label); - tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len); - tls_uint8_to_bytes(label_len, &p, &hkdf_label_len); - tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len); - tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len); - tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len); - - hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out); - return 1; -} - -int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32]) -{ - DIGEST_CTX ctx = *dgst_ctx; - uint8_t dgst[64]; - size_t dgstlen; - - if (digest_finish(&ctx, dgst, &dgstlen) != 1 - || tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) { - error_print(); - return -1; - } - return 1; -} - -int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key, - const uint8_t seq_num[8], const uint8_t header[5], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM3_HMAC_CTX hmac_ctx; - uint8_t last_blocks[32 + 16] = {0}; - uint8_t *mac, *padding, *iv; - int rem, padding_len; - int i; - - if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) { - error_print(); - return -1; - } - if (inlen > (1 << 14)) { - error_print("invalid tls record data length %zu\n", inlen); - return -1; - } - - rem = (inlen + 32) % 16; - memcpy(last_blocks, in + inlen - rem, rem); - mac = last_blocks + rem; - - memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, seq_num, 8); - sm3_hmac_update(&hmac_ctx, header, 5); - sm3_hmac_update(&hmac_ctx, in, inlen); - sm3_hmac_finish(&hmac_ctx, mac); - - padding = mac + 32; - padding_len = 16 - rem - 1; - for (i = 0; i <= padding_len; i++) { - padding[i] = padding_len; - } - - iv = out; - if (rand_bytes(iv, 16) != 1) { - error_print(); - return -1; - } - out += 16; - - if (inlen >= 16) { - sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out); - out += inlen - rem; - iv = out - 16; - } - sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out); - *outlen = 16 + inlen - rem + sizeof(last_blocks); - return 1; -} - -int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key, - const uint8_t seq_num[8], const uint8_t enced_header[5], - const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) -{ - SM3_HMAC_CTX hmac_ctx; - const uint8_t *iv; - const uint8_t *padding; - const uint8_t *mac; - uint8_t header[5]; - int padding_len; - int i; - - if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) { - error_print(); - return -1; - } - if (inlen % 16 - || inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding - || inlen > (16 + (1<<14) + 32 + 256)) { - error_print("invalid tls cbc ciphertext length %zu\n", inlen); - return -1; - } - - iv = in; - in += 16; - inlen -= 16; - - sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out); - - padding_len = out[inlen - 1]; - padding = out + inlen - padding_len - 1; - if (padding < out + 32) { - error_print(); - return -1; - } - for (i = 0; i < padding_len; i++) { - if (padding[i] != padding_len) { - error_print("tls ciphertext cbc-padding check failure"); - return -1; - } - } - - *outlen = inlen - 32 - padding_len - 1; - header[0] = enced_header[0]; - header[1] = enced_header[1]; - header[2] = enced_header[2]; - header[3] = (*outlen) >> 8; - header[4] = (*outlen); - mac = padding - 32; - - memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX)); - sm3_hmac_update(&hmac_ctx, seq_num, 8); - sm3_hmac_update(&hmac_ctx, header, 5); - sm3_hmac_update(&hmac_ctx, out, *outlen); - if (sm3_hmac_finish_and_verify(&hmac_ctx, mac) != 1) { - error_print("tls ciphertext mac check failure"); - return -1; - } - return 1; -} - -int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key, - const uint8_t client_random[32], const uint8_t server_random[32], - int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen) -{ - uint8_t server_ecdh_params[69]; - SM2_SIGN_CTX sign_ctx; - - if (!server_sign_key || !client_random || !server_random - || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) { - error_print(); - return -1; - } - server_ecdh_params[0] = TLS_curve_type_named_curve; - server_ecdh_params[1] = curve >> 8; - server_ecdh_params[2] = curve; - server_ecdh_params[3] = 65; - sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); - - sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID); - sm2_sign_update(&sign_ctx, client_random, 32); - sm2_sign_update(&sign_ctx, server_random, 32); - sm2_sign_update(&sign_ctx, server_ecdh_params, 69); - sm2_sign_finish(&sign_ctx, sig, siglen); - - return 1; -} - -int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key, - const uint8_t client_random[32], const uint8_t server_random[32], - int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen) -{ - int ret; - uint8_t server_ecdh_params[69]; - SM2_SIGN_CTX verify_ctx; - - if (!server_sign_key || !client_random || !server_random - || curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen - || siglen > TLS_MAX_SIGNATURE_SIZE) { - error_print(); - return -1; - } - server_ecdh_params[0] = TLS_curve_type_named_curve; - server_ecdh_params[1] = curve >> 8; - server_ecdh_params[2] = curve; - server_ecdh_params[3] = 65; - sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4); - - sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID); - sm2_verify_update(&verify_ctx, client_random, 32); - sm2_verify_update(&verify_ctx, server_random, 32); - sm2_verify_update(&verify_ctx, server_ecdh_params, 69); - ret = sm2_verify_finish(&verify_ctx, sig, siglen); - if (ret != 1) error_print(); - return ret; -} diff --git a/tests/aestest.c b/tests/aestest.c index 09992441..f7ae56c3 100644 --- a/tests/aestest.c +++ b/tests/aestest.c @@ -51,8 +51,55 @@ #include #include #include +#include +#include -int main(void) + +int test_aes_ctr(void) +{ + // NIST SP 800-38A F.5.1 + char *hex_key = "2b7e151628aed2a6abf7158809cf4f3c"; + char *hex_ctr = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; + char *hex_msg = "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"; + char *hex_out = "874d6191b620e3261bef6864990db6ce" + "9806f66b7970fdff8617187bb9fffdff" + "5ae4df3edbd5d35e5b4f09020db03eab" + "1e031dda2fbe03d1792170a0f3009cee"; + + int err = 0; + AES_KEY aes_key; + uint8_t key[32]; + uint8_t ctr[16]; + uint8_t msg[64]; + uint8_t out[64]; + uint8_t buf[64]; + size_t keylen, ctrlen, msglen, outlen, buflen; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen); + hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); + + aes_set_encrypt_key(&aes_key, key, keylen); + aes_ctr_encrypt(&aes_key, ctr, msg, msglen, buf); + buflen = msglen; + + format_bytes(stdout, 0, 0, "aes_ctr(msg) = ", buf, buflen); + format_bytes(stdout, 0, 0, " = ", out, outlen); + + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + aes_ctr_encrypt(&aes_key, ctr, buf, buflen, buf); + format_bytes(stdout, 0, 0, "msg = ", msg, msglen); + format_bytes(stdout, 0, 0, " = ", buf, buflen); + + return 1; +} + + +int test_aes(void) { int err = 0; AES_KEY aes_key; @@ -185,3 +232,180 @@ int main(void) return 0; } + + +struct { + char *K; + char *P; + char *A; + char *IV; + char *C; + char *T; +} aes_gcm_tests[] = { + // test 1 + { + "00000000000000000000000000000000", + "", + "", + "000000000000000000000000", + "", + "58e2fccefa7e3061367f1d57a4e7455a", + }, + // test 2 + { + "00000000000000000000000000000000", + "00000000000000000000000000000000", + "", + "000000000000000000000000", + "0388dace60b6a392f328c2b971b2fe78", + "ab6e47d42cec13bdf53a67b21257bddf", + }, + // test 3 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b391aafd255", + "", + "cafebabefacedbaddecaf888", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091473f5985", + "4d5c2af327cd64a62cf35abd2ba6fab4", + }, + // test 4 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "cafebabefacedbaddecaf888", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091", + "5bc94fbc3221a5db94fae95ae7121a47", + }, + // test 5 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "cafebabefacedbad", + "61353b4c2806934a777ff51fa22a4755" + "699b2a714fcdc6f83766e5f97b6c7423" + "73806900e49f24b22b097544d4896b42" + "4989b5e1ebac0f07c23f4598", + "3612d2e79e3b0785561be14aaca2fccb", + }, + // test 6 + { + "feffe9928665731c6d6a8f9467308308", + "d9313225f88406e5a55909c5aff5269a" + "86a7a9531534f7da2e4c303d8a318a72" + "1c3c0c95956809532fcf0e2449a6b525" + "b16aedf5aa0de657ba637b39", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "9313225df88406e555909c5aff5269aa" + "6a7a9538534f7da1e4c303d2a318a728" + "c3c0c95156809539fcf0e2429a6b5254" + "16aedbf5a0de6a57a637b39b", + "8ce24998625615b603a033aca13fb894" + "be9112a5c3a211a8ba262a3cca7e2ca7" + "01e4a9a4fba43c90ccdcb281d48c7c6f" + "d62875d2aca417034c34aee5", + "619cc5aefffe0bfa462af43c1699d050", + }, + // test 7 + { + "00000000000000000000000000000000" + "0000000000000000", + "", + "", + "000000000000000000000000", + "", + "cd33b28ac773f74ba00ed1f312572435", + }, +}; + +int test_aes_gcm(void) +{ + uint8_t K[32]; + uint8_t P[64]; + uint8_t A[32]; + uint8_t IV[64]; + uint8_t C[64]; + uint8_t T[16]; + size_t Klen, Plen, Alen, IVlen, Clen, Tlen; + + AES_KEY aes_key; + uint8_t out[64]; + uint8_t tag[16]; + uint8_t buf[64]; + int i; + + printf("%s\n", __FUNCTION__); + + for (i = 0; i < sizeof(aes_gcm_tests)/sizeof(aes_gcm_tests[0]); i++) { + int ok = 1; + + hex_to_bytes(aes_gcm_tests[i].K, strlen(aes_gcm_tests[i].K), K, &Klen); + hex_to_bytes(aes_gcm_tests[i].P, strlen(aes_gcm_tests[i].P), P, &Plen); + hex_to_bytes(aes_gcm_tests[i].A, strlen(aes_gcm_tests[i].A), A, &Alen); + hex_to_bytes(aes_gcm_tests[i].IV, strlen(aes_gcm_tests[i].IV), IV, &IVlen); + hex_to_bytes(aes_gcm_tests[i].C, strlen(aes_gcm_tests[i].C), C, &Clen); + hex_to_bytes(aes_gcm_tests[i].T, strlen(aes_gcm_tests[i].T), T, &Tlen); + + aes_set_encrypt_key(&aes_key, K, Klen); + aes_gcm_encrypt(&aes_key, IV, IVlen, A, Alen, P, Plen, out, Tlen, tag); + + if (aes_gcm_decrypt(&aes_key, IV, IVlen, A, Alen, out, Plen, tag, Tlen, buf) != 1) { + error_print(); + ok = 0; + } + if (memcmp(buf, P, Plen) != 0) { + error_print(); + ok = 0; + } + + printf(" test %d %s\n", i + 1, ok ? "ok" : "error"); + + /* + format_print(stdout, 0, 2, "K = %s\n", aes_gcm_tests[i].K); + format_print(stdout, 0, 2, "P = %s\n", aes_gcm_tests[i].P); + format_print(stdout, 0, 2, "A = %s\n", aes_gcm_tests[i].A); + format_print(stdout, 0, 2, "IV = %s\n", aes_gcm_tests[i].IV); + format_print(stdout, 0, 2, "C = %s\n", aes_gcm_tests[i].C); + format_bytes(stdout, 0, 2, " = ", out, Plen); + format_print(stdout, 0, 2, "T = %s\n", aes_gcm_tests[i].T); + format_bytes(stdout, 0, 2, " = ", tag, Tlen); + printf("\n"); + */ + } + + return 0; +} + + + + + + +int main(void) +{ + test_aes(); + test_aes_ctr(); + test_aes_gcm(); + return 0; +} + diff --git a/tests/chacha20test.c b/tests/chacha20test.c index 3a61a5fd..d6076d9c 100644 --- a/tests/chacha20test.c +++ b/tests/chacha20test.c @@ -85,6 +85,7 @@ int main(void) if (memcmp(buf, testdata, sizeof(testdata)) != 0) { printf("chacha20 test 1 failed\n"); + return -1; } else { printf("chacha20 test 1 ok\n"); } diff --git a/tests/gcmtest.c b/tests/gcmtest.c index 4f48f1e0..54e74ac1 100644 --- a/tests/gcmtest.c +++ b/tests/gcmtest.c @@ -50,69 +50,110 @@ #include #include #include +#include +#include struct { - char *K; - char *P; - char *IV; + char *H; + char *A; char *C; char *T; -} gcm_tests[] = { - /* test 1 */ +} ghash_tests[] = { + // test 1 { + "66e94bd4ef8a2c3b884cfa59ca342b2e", + "", + "", "00000000000000000000000000000000", - "", - "000000000000000000000000", - "", - "58e2fccefa7e3061367f1d57a4e7455a", }, - /* test 2 */ + // test 2 { - "00000000000000000000000000000000", - "00000000000000000000000000000000", - "000000000000000000000000", + "66e94bd4ef8a2c3b884cfa59ca342b2e", + "", "0388dace60b6a392f328c2b971b2fe78", - "ab6e47d42cec13bdf53a67b21257bddf", + "f38cbb1ad69223dcc3457ae5b6b0f885", + }, + // test 3 + { + "b83b533708bf535d0aa6e52980d53b78", + "", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091473f5985", + "7f1b32b81b820d02614f8895ac1d4eac", + }, + // test 4 + { + "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "42831ec2217774244b7221b784d0d49c" + "e3aa212f2c02a4e035c17e2329aca12e" + "21d514b25466931c7d8f6a5aac84aa05" + "1ba30b396a0aac973d58e091", + "698e57f70e6ecc7fd9463b7260a9ae5f", + }, + // test 5 + { + "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "61353b4c2806934a777ff51fa22a4755" + "699b2a714fcdc6f83766e5f97b6c7423" + "73806900e49f24b22b097544d4896b42" + "4989b5e1ebac0f07c23f4598", + "df586bb4c249b92cb6922877e444d37b", + }, + // test 6 + { + "b83b533708bf535d0aa6e52980d53b78", + "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2", + "8ce24998625615b603a033aca13fb894" + "be9112a5c3a211a8ba262a3cca7e2ca7" + "01e4a9a4fba43c90ccdcb281d48c7c6f" + "d62875d2aca417034c34aee5", + "1c5afe9760d3932f3c9a878aac3dc3de", + }, +}; + +int test_ghash(void) +{ + uint8_t H[16]; + uint8_t A[32]; + uint8_t C[64]; + uint8_t T[16]; + uint8_t out[16]; + size_t Hlen, Alen, Clen, Tlen; + int i; + + printf("%s\n", __FUNCTION__); + + for (i = 0; i < sizeof(ghash_tests)/sizeof(ghash_tests[0]); i++) { + hex_to_bytes(ghash_tests[i].H, strlen(ghash_tests[i].H), H, &Hlen); + hex_to_bytes(ghash_tests[i].A, strlen(ghash_tests[i].A), A, &Alen); + hex_to_bytes(ghash_tests[i].C, strlen(ghash_tests[i].C), C, &Clen); + hex_to_bytes(ghash_tests[i].T, strlen(ghash_tests[i].T), T, &Tlen); + ghash(H, A, Alen, C, Clen, out); + + printf(" test %d %s\n", i + 1, memcmp(out ,T, Tlen) == 0 ? "ok" : "error"); + /* + format_print(stdout, 0, 2, "H = %s\n", ghash_tests[i].H); + format_print(stdout, 0, 2, "A = %s\n", ghash_tests[i].A); + format_print(stdout, 0, 2, "C = %s\n", ghash_tests[i].C); + format_bytes(stdout, 0, 2, "GHASH(H,A,C) = ", out, 16); + format_print(stdout, 0, 2, " = %s\n\n", ghash_tests[i].T); + */ + } + return 1; } + int main(void) { - int err = 0; - GCM_CTX ctx; - uint8_t *key = NULL; - uint8_t *iv = NULL; - uint8_t *p = NULL; - uint8_t *c = NULL; - uint8_t *tag = NULL; - size_t keylen, ivlen, plen, clen, taglen, len, i; - - for (i = 0; i < sizeof(gcm_tests)/sizeof(gcm_tests[0]); i++) { - - key = OPENSSL_hexstr2buf(gcm_tests[i].K, &keylen); - iv = OPENSSL_hexstr2buf(gcm_tests[i].IV, &ivlen); - p = OPENSSL_hexstr2buf(gcm_tests[i].P, &plen); - c = OPENSSL_hexstr2buf(gcm_tests[i].C, &clen); - tag = OPENSSL_hexstr2buf(gcm_tests[i].T, &taglen); - buf = malloc(plen); - - gcm_init(&ctx, taglen, key, keylen, iv, ivlen, aad, aadlen); - gcm_update(&ctx, p, plen, buf, &len); - if (!gcm_finish_verify(&ctx, tag, taglen)) { - printf("gcm test %zu failed\n", i+1); - err++; - } else { - printf("gcm test %zu ok\n", i+1); - } - - free(key); - free(iv); - free(p); - free(c); - free(tag); - free(buf); - } - - return err; + test_ghash(); + return 1; } diff --git a/tests/gf128test.c b/tests/gf128test.c index c850737c..1a93dc82 100644 --- a/tests/gf128test.c +++ b/tests/gf128test.c @@ -51,26 +51,16 @@ #include #include #include -#include "internal/gf128.h" +#include - -static gf128_t gf128_from_hex(const char *s) -{ - uint8_t bin[16]; - assert(strlen(s) == 32); - hex2bin(s, strlen(s), bin); - return gf128_from_bytes(bin); -} - -static int gf128_equ_hex(gf128_t a, const char *s) -{ - uint8_t bin1[16]; - uint8_t bin2[16]; - assert(strlen(s) == 32); - hex2bin(s, strlen(s), bin1); - gf128_to_bytes(a, bin2); - return memcmp(bin1, bin2, sizeof(bin1)) == 0; -} +/* +a = de300f9301a499a965f8bf677e99e80d +b = 14b267838ec9ef1bb7b5ce8c19e34bc6 +a + b = ca8268108f6d76b2d24d71eb677aa3cb +a - b = ca8268108f6d76b2d24d71eb677aa3cb +a * b = 28e63413cd53b01a3b469375781942c6 +a * 2 = bc601f2603493352cbf17ecefd33d09d +*/ int main(void) { @@ -81,9 +71,25 @@ int main(void) gf128_t b = gf128_from_hex("14b267838ec9ef1bb7b5ce8c19e34bc6"); gf128_t r; + /* + r = gf128_add(a, b); + gf128_print("a + b = ", r); + + r = gf128_mul(a, b); + gf128_print("a * b = ", r); + + r = gf128_mul2(a); + gf128_print("a * 2 = ", r); + */ + + gf128_t H = gf128_from_hex("66e94bd4ef8a2c3b884cfa59ca342b2e"); + gf128_t C = gf128_from_hex("0388dace60b6a392f328c2b971b2fe78"); + gf128_t T = gf128_mul(C, H); - + gf128_print("C = ", C); + gf128_print("H = ", H); + gf128_print("C * H = ", T); diff --git a/tests/hash_drbgtest.c b/tests/hash_drbgtest.c index 6b50f966..3a303bd2 100644 --- a/tests/hash_drbgtest.c +++ b/tests/hash_drbgtest.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -66,31 +67,36 @@ #define V1 "f9afadfbbf2c3d1004f9baca38be247342e5fbb83281915d5de18beb963712a344e89bb0e6b925a7bbc32eadb8b441efc1fa0c649df42a" #define C1 "1d41cbbd634909e4761c232fcfd6a6c2edf0a7f4d3d3c164f74a88955f355efce2d86c1e9fa897b7005ef9d4d3a51bf4fc0b805ab896c9" +#define PR1 "2edb396eeb8960f77943c2a59075a786" +#define PR2 "30b565b63a5012676940d3ef17d9e996" + int main(void) { HASH_DRBG drbg; - unsigned char *entropy = NULL; - unsigned char *nonce = NULL; - unsigned char *personalstr = NULL; - unsigned char *v = NULL; - unsigned char *c = NULL; + uint8_t entropy[sizeof(EntropyInput)/2]; + uint8_t nonce[sizeof(Nonce)/2]; + uint8_t personalstr[sizeof(PersonalizationString)/2]; + uint8_t v[sizeof(V0)/2]; + uint8_t c[sizeof(C0)/2]; + uint8_t entropy_pr1[sizeof(EntropyInputPR1)/2]; + uint8_t pr1[sizeof(PR1)/2]; + uint8_t pr2[sizeof(PR2)/2]; size_t entropy_len, nonce_len, personalstr_len, vlen, clen; - - - unsigned char *entropy_pr1 = NULL; size_t entropy_pr1len; - + size_t pr1_len, pr2_len; unsigned char out[640/8]; + int i; - entropy = OPENSSL_hexstr2buf(EntropyInput, &entropy_len); - nonce = OPENSSL_hexstr2buf(Nonce, &nonce_len); - personalstr = OPENSSL_hexstr2buf(PersonalizationString, &personalstr_len); - v = OPENSSL_hexstr2buf(V0, &vlen); - c = OPENSSL_hexstr2buf(C0, &clen); - - entropy_pr1 = OPENSSL_hexstr2buf(EntropyInputPR1, &entropy_pr1len); + hex_to_bytes(EntropyInput, strlen(EntropyInput), entropy, &entropy_len); + hex_to_bytes(Nonce, strlen(Nonce), nonce, &nonce_len); + hex_to_bytes(PersonalizationString, strlen(PersonalizationString), personalstr, &personalstr_len); + hex_to_bytes(V0, strlen(V0), v, &vlen); + hex_to_bytes(C0, strlen(C0), c, &clen); + hex_to_bytes(EntropyInputPR1, strlen(EntropyInputPR1), entropy_pr1, &entropy_pr1len); + hex_to_bytes(PR1, strlen(PR1), pr1, &pr1_len); + hex_to_bytes(PR2, strlen(PR2), pr2, &pr2_len); hash_drbg_init(&drbg, DIGEST_sha1(), @@ -108,12 +114,6 @@ int main(void) printf("ok\n"); } - unsigned char *pr1 = NULL; - unsigned char *pr2 = NULL; - size_t pr1_len, pr2_len; - - pr1 = OPENSSL_hexstr2buf("2edb396eeb8960f77943c2a59075a786", &pr1_len); - pr2 = OPENSSL_hexstr2buf("30b565b63a5012676940d3ef17d9e996", &pr2_len); hash_drbg_reseed(&drbg, pr1, pr1_len, NULL, 0); hash_drbg_generate(&drbg, NULL, 0, 640/8, out); @@ -121,7 +121,6 @@ int main(void) hash_drbg_reseed(&drbg, pr2, pr2_len, NULL, 0); hash_drbg_generate(&drbg, NULL, 0, 640/8, out); - int i; for (i = 0; i < sizeof(out); i++) { printf("%02x", out[i]); } diff --git a/tests/md5test.c b/tests/md5test.c index 07171c39..d29ba0b8 100644 --- a/tests/md5test.c +++ b/tests/md5test.c @@ -50,9 +50,11 @@ #include #include #include +#include #include #include + static char *teststr[] = { "", "a", @@ -77,17 +79,14 @@ int main(int argc, char **argv) { int err = 0; char *p; - unsigned char *dgstbuf = NULL; + uint8_t dgst[16]; + uint8_t dgstbuf[16]; size_t dgstbuflen; - unsigned char dgst[16]; size_t i; for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { - if (!(dgstbuf = OPENSSL_hexstr2buf(dgsthex[i], &dgstbuflen))) { - goto end; - } - - md5_digest((unsigned char *)teststr[i], strlen(teststr[i]), dgst); + hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen); + md5_digest((uint8_t *)teststr[i], strlen(teststr[i]), dgst); if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { int n; @@ -102,12 +101,7 @@ int main(int argc, char **argv) } else { printf("md5 test %lu ok\n", i+1); } - - free(dgstbuf); - dgstbuf = NULL; } -end: - if (dgstbuf) free(dgstbuf); return err; } diff --git a/tests/pbkdf2test.c b/tests/pbkdf2test.c index aedcef63..63700eaa 100644 --- a/tests/pbkdf2test.c +++ b/tests/pbkdf2test.c @@ -156,5 +156,5 @@ int main(void) } } - return 0; + return 1; } diff --git a/tests/pemtest.c b/tests/pemtest.c new file mode 100644 index 00000000..e69de29b diff --git a/tests/sha1test.c b/tests/sha1test.c index b3fe25dd..71c26981 100644 --- a/tests/sha1test.c +++ b/tests/sha1test.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -78,19 +79,17 @@ int main(void) { int err = 0; SHA1_CTX ctx; - unsigned char dgst[20]; - unsigned char *dgstbuf = NULL; + uint8_t dgst[20]; + uint8_t dgstbuf[20]; + size_t dgstlen; size_t i, j; for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { - - if (!(dgstbuf = OPENSSL_hexstr2buf(dgsthex[i], NULL))) { - goto end; - } + hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstlen); sha1_init(&ctx); for (j = 0; j < testcnt[i]; j++) { - sha1_update(&ctx, (unsigned char *)teststr[i], strlen(teststr[i])); + sha1_update(&ctx, (uint8_t *)teststr[i], strlen(teststr[i])); } sha1_finish(&ctx, dgst); @@ -105,12 +104,7 @@ int main(void) } else { printf("sha1 test %lu ok\n", i+1); } - - free(dgstbuf); - dgstbuf = NULL; } -end: - if (dgstbuf) free(dgstbuf); return err; } diff --git a/tests/sha224test.c b/tests/sha224test.c index ff9c6c54..926c0502 100644 --- a/tests/sha224test.c +++ b/tests/sha224test.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -100,19 +101,17 @@ int main(int argc, char **argv) { int err = 0; SHA224_CTX ctx; - unsigned char dgst[SHA224_DIGEST_SIZE]; - unsigned char *dgstbuf = NULL; + uint8_t dgst[SHA224_DIGEST_SIZE]; + uint8_t dgstbuf[SHA224_DIGEST_SIZE]; + size_t dgstlen; size_t i, j; for (i = 0; i < 7; i++) { - - if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) { - goto end; - } + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); sha224_init(&ctx); for (j = 0; j < tests[i].count; j++) { - sha224_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); + sha224_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); } sha224_finish(&ctx, dgst); @@ -127,12 +126,7 @@ int main(int argc, char **argv) } else { printf("sha224 test %lu ok\n", i+1); } - - free(dgstbuf); - dgstbuf = NULL; } -end: - if (dgstbuf) free(dgstbuf); return err; } diff --git a/tests/sha256test.c b/tests/sha256test.c index 621b5136..a60aab61 100644 --- a/tests/sha256test.c +++ b/tests/sha256test.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -99,19 +100,17 @@ int main(int argc, char **argv) { int err = 0; SHA256_CTX ctx; - unsigned char dgst[SHA256_DIGEST_SIZE]; - unsigned char *dgstbuf = NULL; + uint8_t dgst[SHA256_DIGEST_SIZE]; + uint8_t dgstbuf[SHA256_DIGEST_SIZE]; + size_t dgstlen; size_t i, j; for (i = 0; i < 7; i++) { - - if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) { - goto end; - } + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); sha256_init(&ctx); for (j = 0; j < tests[i].count; j++) { - sha256_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); + sha256_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); } sha256_finish(&ctx, dgst); @@ -126,12 +125,7 @@ int main(int argc, char **argv) } else { printf("sha256 test %lu ok\n", i+1); } - - free(dgstbuf); - dgstbuf = NULL; } -end: - if (dgstbuf) free(dgstbuf); return err; } diff --git a/tests/sha384test.c b/tests/sha384test.c index 1f57954e..a7fe6131 100644 --- a/tests/sha384test.c +++ b/tests/sha384test.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -105,19 +106,17 @@ int main(void) { int err = 0; SHA384_CTX ctx; - unsigned char dgst[SHA384_DIGEST_SIZE]; - unsigned char *dgstbuf = NULL; + uint8_t dgst[SHA384_DIGEST_SIZE]; + uint8_t dgstbuf[SHA384_DIGEST_SIZE]; + size_t dgstlen; size_t i, j; for (i = 0; i < 7; i++) { - - if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) { - goto end; - } + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); sha384_init(&ctx); for (j = 0; j < tests[i].count; j++) { - sha384_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); + sha384_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); } sha384_finish(&ctx, dgst); @@ -132,12 +131,7 @@ int main(void) } else { printf("sha384 test %lu ok\n", i+1); } - - free(dgstbuf); - dgstbuf = NULL; } -end: - if (dgstbuf) free(dgstbuf); return err; } diff --git a/tests/sha512test.c b/tests/sha512test.c index c1767be4..8275452e 100644 --- a/tests/sha512test.c +++ b/tests/sha512test.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -106,19 +107,17 @@ int main(void) { int err = 0; SHA512_CTX ctx; - unsigned char dgst[SHA512_DIGEST_SIZE]; - unsigned char *dgstbuf = NULL; + uint8_t dgst[SHA512_DIGEST_SIZE]; + uint8_t dgstbuf[SHA512_DIGEST_SIZE]; + size_t dgstlen; size_t i, j; for (i = 0; i < 7; i++) { - - if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) { - goto end; - } + hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen); sha512_init(&ctx); for (j = 0; j < tests[i].count; j++) { - sha512_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); + sha512_update(&ctx, (uint8_t *)tests[i].data, tests[i].length); } sha512_finish(&ctx, dgst); @@ -133,12 +132,7 @@ int main(void) } else { printf("sha512 test %lu ok\n", i+1); } - - free(dgstbuf); - dgstbuf = NULL; } -end: - if (dgstbuf) free(dgstbuf); return err; } diff --git a/tests/sm3test.c b/tests/sm3test.c index a2785812..e5282ac4 100644 --- a/tests/sm3test.c +++ b/tests/sm3test.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -178,17 +179,15 @@ int main(int argc, char **argv) { int err = 0; char *p; - unsigned char *testbuf = NULL; - unsigned char *dgstbuf = NULL; + uint8_t testbuf[sizeof(testhex)/2]; + uint8_t dgstbuf[32]; size_t testbuflen, dgstbuflen; - unsigned char dgst[32]; + uint8_t dgst[32]; size_t i; for (i = 0; i < sizeof(testhex)/sizeof(testhex[0]); i++) { - if (!(testbuf = OPENSSL_hexstr2buf(testhex[i], &testbuflen)) - || !(dgstbuf = OPENSSL_hexstr2buf(dgsthex[i], &dgstbuflen))) { - goto end; - } + hex_to_bytes(testhex[i], strlen(testhex[i]), testbuf, &testbuflen); + hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen); sm3_digest(testbuf, testbuflen, dgst); @@ -205,15 +204,7 @@ int main(int argc, char **argv) } else { printf("sm3 test %lu ok\n", i+1); } - - free(testbuf); - free(dgstbuf); - testbuf = NULL; - dgstbuf = NULL; } -end: - if (testbuf) free(testbuf); - if (dgstbuf) free(dgstbuf); return err; } diff --git a/tests/u128test.c b/tests/u128test.c deleted file mode 100644 index fa2b22e9..00000000 --- a/tests/u128test.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the GmSSL Project. - * (http://gmssl.org/)" - * - * 4. The name "GmSSL Project" must not be used to endorse or promote - * products derived from this software without prior written - * permission. For written permission, please contact - * guanzhi1980@gmail.com. - * - * 5. Products derived from this software may not be called "GmSSL" - * nor may "GmSSL" appear in their names without prior written - * permission of the GmSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the GmSSL Project - * (http://gmssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -int main(void) -{ - __uint128_t a = 0; - uint64_t al = 1; - uint64_t ah = 1; - - a = ((__uint128_t)ah << 64) | al; - - return (int)a; -}