From eb221238c2df11f0193539f7192298e653e544f4 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Mon, 14 Jan 2013 15:59:53 -0800 Subject: [PATCH] separated TLS-AEAD and AES-GCM so TLS-AEAD can also use AES-CCM --- ctaocrypt/benchmark/benchmark.c | 9 ++- ctaocrypt/src/aes.c | 114 ++++++++++---------------------- ctaocrypt/test/test.c | 37 ++++++----- cyassl/ctaocrypt/aes.h | 24 +++---- cyassl/internal.h | 10 +++ src/internal.c | 29 +++++++- src/keys.c | 37 ++++++----- 7 files changed, 126 insertions(+), 134 deletions(-) diff --git a/ctaocrypt/benchmark/benchmark.c b/ctaocrypt/benchmark/benchmark.c index cc02fdf44..bb58e3574 100644 --- a/ctaocrypt/benchmark/benchmark.c +++ b/ctaocrypt/benchmark/benchmark.c @@ -198,12 +198,11 @@ void bench_aesgcm(void) double start, total, persec; int i; - AesGcmSetKey(&enc, key, 16, iv); - AesGcmSetExpIV(&enc, iv+4); + AesGcmSetKey(&enc, key, 16); start = current_time(); for(i = 0; i < megs; i++) - AesGcmEncrypt(&enc, cipher, plain, sizeof(plain), + AesGcmEncrypt(&enc, cipher, plain, sizeof(plain), iv, 12, tag, 16, additional, 13); total = current_time() - start; @@ -222,11 +221,11 @@ void bench_aesccm(void) double start, total, persec; int i; - AesCcmSetKey(&enc, key, 16, iv, 12); + AesCcmSetKey(&enc, key, 16); start = current_time(); for(i = 0; i < megs; i++) - AesCcmEncrypt(&enc, cipher, plain, sizeof(plain), + AesCcmEncrypt(&enc, cipher, plain, sizeof(plain), iv, 12, tag, 16, additional, 13); total = current_time() - start; diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index de2bf488c..fb4149b09 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -1807,8 +1807,6 @@ void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) */ enum { - IMPLICIT_IV_SZ = 4, - EXPLICIT_IV_SZ = 8, CTR_SZ = 4 }; @@ -1834,36 +1832,6 @@ static INLINE void IncrementGcmCounter(byte* inOutCtr) } -/* - * The explicit IV is set by the caller. A common practice is to treat it as - * a sequence number seeded with a random number. The caller manages - * incrementing the explicit IV when appropriate. - */ - -void AesGcmSetExpIV(Aes* aes, const byte* iv) -{ - XMEMCPY((byte*)aes->reg + IMPLICIT_IV_SZ, iv, EXPLICIT_IV_SZ); -} - - -void AesGcmGetExpIV(Aes* aes, byte* iv) -{ - XMEMCPY(iv, (byte*)aes->reg + IMPLICIT_IV_SZ, EXPLICIT_IV_SZ); -} - - -void AesGcmIncExpIV(Aes* aes) -{ - int i; - byte* iv = (byte*)aes->reg + IMPLICIT_IV_SZ; - - for (i = EXPLICIT_IV_SZ - 1; i >= 0; i--) { - if (++iv[i]) - return; - } -} - - #if defined(GCM_SMALL) || defined(GCM_TABLE) static INLINE void FlattenSzInBits(byte* buf, word32 sz) @@ -1929,20 +1897,17 @@ static void GenerateM0(Aes* aes) #endif /* GCM_TABLE */ -void AesGcmSetKey(Aes* aes, const byte* key, word32 len, - const byte* implicitIV) +void AesGcmSetKey(Aes* aes, const byte* key, word32 len) { - byte fullIV[AES_BLOCK_SIZE]; + byte iv[AES_BLOCK_SIZE]; if (!((len == 16) || (len == 24) || (len == 32))) return; - XMEMSET(fullIV, 0, AES_BLOCK_SIZE); - XMEMCPY(fullIV, implicitIV, IMPLICIT_IV_SZ); - AesSetKeyLocal(aes, key, len, fullIV, AES_ENCRYPTION); + XMEMSET(iv, 0, AES_BLOCK_SIZE); + AesSetKeyLocal(aes, key, len, iv, AES_ENCRYPTION); - XMEMSET(fullIV, 0, AES_BLOCK_SIZE); - AesEncrypt(aes, fullIV, aes->H); + AesEncrypt(aes, iv, aes->H); #ifdef GCM_TABLE GenerateM0(aes); #endif /* GCM_TABLE */ @@ -2449,6 +2414,7 @@ static void GHASH(Aes* aes, const byte* a, word32 aSz, void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { @@ -2461,9 +2427,8 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, CYASSL_ENTER("AesGcmEncrypt"); - /* Initialize the counter with the MS 96 bits of IV, and the counter - * portion set to "1". */ - XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE); + XMEMSET(ctr, 0, AES_BLOCK_SIZE); + XMEMCPY(ctr, iv, ivSz); InitGcmCounter(ctr); while (blocks--) { @@ -2489,6 +2454,7 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { @@ -2501,9 +2467,8 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, CYASSL_ENTER("AesGcmDecrypt"); - /* Initialize the counter with the MS 96 bits of IV, and the counter - * portion set to "1". */ - XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE); + XMEMSET(ctr, 0, AES_BLOCK_SIZE); + XMEMCPY(ctr, iv, ivSz); InitGcmCounter(ctr); /* Calculate the authTag again using the received auth data and the @@ -2543,26 +2508,15 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, #ifdef HAVE_AESCCM -void AesCcmSetKey(Aes* aes, const byte* key, word32 keySz, - const byte* implicitIV, word32 ivSz) +void AesCcmSetKey(Aes* aes, const byte* key, word32 keySz) { - byte fullIV[AES_BLOCK_SIZE]; + byte nonce[AES_BLOCK_SIZE]; if (!((keySz == 16) || (keySz == 24) || (keySz == 32))) return; - if (ivSz > AES_BLOCK_SIZE - 2) { - CYASSL_MSG("AES-CCM IV is too long"); - return; - } - - XMEMSET(fullIV, 0, sizeof(fullIV)); - XMEMCPY(fullIV + 1, implicitIV, ivSz); - - AesSetKeyLocal(aes, key, keySz, fullIV, AES_ENCRYPTION); - aes->lenSz = AES_BLOCK_SIZE - 1 - ivSz; - - XMEMSET(fullIV, 0, sizeof(fullIV)); + XMEMSET(nonce, 0, sizeof(nonce)); + AesSetKeyLocal(aes, key, keySz, nonce, AES_ENCRYPTION); } @@ -2641,18 +2595,20 @@ static INLINE void AesCcmCtrInc(byte* B, word32 lenSz) void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { byte A[AES_BLOCK_SIZE]; byte B[AES_BLOCK_SIZE]; - word32 i; + word32 i, lenSz; - XMEMCPY(B, aes->reg, AES_BLOCK_SIZE); + XMEMCPY(B+1, nonce, nonceSz); + lenSz = AES_BLOCK_SIZE - 1 - nonceSz; B[0] = (authInSz > 0 ? 64 : 0) + (8 * ((authTagSz - 2) / 2)) - + (aes->lenSz - 1); - for (i = 0; i < aes->lenSz; i++) + + (lenSz - 1); + for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF; AesEncrypt(aes, B, A); @@ -2662,8 +2618,8 @@ void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, roll_x(aes, in, inSz, A); XMEMCPY(authTag, A, authTagSz); - B[0] = (aes->lenSz - 1); - for (i = 0; i < aes->lenSz; i++) + B[0] = (lenSz - 1); + for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; AesEncrypt(aes, B, A); xorbuf(authTag, A, authTagSz); @@ -2674,7 +2630,7 @@ void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, xorbuf(A, in, AES_BLOCK_SIZE); XMEMCPY(out, A, AES_BLOCK_SIZE); - AesCcmCtrInc(B, aes->lenSz); + AesCcmCtrInc(B, lenSz); inSz -= AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; @@ -2691,19 +2647,21 @@ void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, + const byte* nonce, word32 nonceSz, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { byte A[AES_BLOCK_SIZE]; byte B[AES_BLOCK_SIZE]; byte* o; - word32 i, oSz, result = 0; + word32 i, lenSz, oSz, result = 0; o = out; oSz = inSz; - XMEMCPY(B, aes->reg, AES_BLOCK_SIZE); - B[0] = (aes->lenSz - 1); - for (i = 0; i < aes->lenSz - 1; i++) + XMEMCPY(B+1, nonce, AES_BLOCK_SIZE); + lenSz = AES_BLOCK_SIZE - 1 - nonceSz; + B[0] = (lenSz - 1); + for (i = 0; i < lenSz - 1; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; B[15] = 1; while (oSz >= AES_BLOCK_SIZE) { @@ -2711,7 +2669,7 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, xorbuf(A, in, AES_BLOCK_SIZE); XMEMCPY(o, A, AES_BLOCK_SIZE); - AesCcmCtrInc(B, aes->lenSz); + AesCcmCtrInc(B, lenSz); oSz -= AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; o += AES_BLOCK_SIZE; @@ -2722,7 +2680,7 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, XMEMCPY(o, A, oSz); } - for (i = 0; i < aes->lenSz; i++) + for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; AesEncrypt(aes, B, A); @@ -2731,8 +2689,8 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, B[0] = (authInSz > 0 ? 64 : 0) + (8 * ((authTagSz - 2) / 2)) - + (aes->lenSz - 1); - for (i = 0; i < aes->lenSz; i++) + + (lenSz - 1); + for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = (inSz >> (8 * i)) & 0xFF; AesEncrypt(aes, B, A); @@ -2741,8 +2699,8 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, if (inSz > 0) roll_x(aes, o, oSz, A); - B[0] = (aes->lenSz - 1); - for (i = 0; i < aes->lenSz; i++) + B[0] = (lenSz - 1); + for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; AesEncrypt(aes, B, B); xorbuf(A, B, authTagSz); diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 74773d345..f9bff0550 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -1518,7 +1518,7 @@ int aesgcm_test(void) const byte iv[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88, 0x00, 0x00, 0x00, 0x00 + 0xde, 0xca, 0xf8, 0x88 }; const byte p[] = @@ -1558,27 +1558,27 @@ int aesgcm_test(void) 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }; - byte t2[16]; - byte p2[60]; - byte c2[60]; + byte t2[sizeof(t)]; + byte p2[sizeof(c)]; + byte c2[sizeof(p)]; int result; - memset(t2, 0, 16); - memset(c2, 0, 60); - memset(p2, 0, 60); + memset(t2, 0, sizeof(t2)); + memset(c2, 0, sizeof(c2)); + memset(p2, 0, sizeof(p2)); - AesGcmSetKey(&enc, k, sizeof(k), iv); - AesGcmSetExpIV(&enc, iv + /*AES_GCM_IMP_IV_SZ*/ 4); + AesGcmSetKey(&enc, k, sizeof(k)); /* AES-GCM encrypt and decrypt both use AES encrypt internally */ - AesGcmEncrypt(&enc, c2, p, sizeof(c2), t2, sizeof(t2), a, sizeof(a)); + AesGcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); if (memcmp(c, c2, sizeof(c2))) return -68; if (memcmp(t, t2, sizeof(t2))) return -69; - result = AesGcmDecrypt(&enc, - p2, c2, sizeof(p2), t2, sizeof(t2), a, sizeof(a)); + result = AesGcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); if (result != 0) return -70; if (memcmp(p, p2, sizeof(p2))) @@ -1642,16 +1642,17 @@ int aesccm_test(void) memset(c2, 0, sizeof(c2)); memset(p2, 0, sizeof(p2)); - AesCcmSetKey(&enc, k, sizeof(k), iv, sizeof(iv)); + AesCcmSetKey(&enc, k, sizeof(k)); /* AES-CCM encrypt and decrypt both use AES encrypt internally */ - AesCcmEncrypt(&enc, c2, p, sizeof(c2), t2, sizeof(t2), a, sizeof(a)); + AesCcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); if (memcmp(c, c2, sizeof(c2))) return -107; if (memcmp(t, t2, sizeof(t2))) return -108; - result = AesCcmDecrypt(&enc, - p2, c2, sizeof(p2), t2, sizeof(t2), a, sizeof(a)); + result = AesCcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); if (result != 0) return -109; if (memcmp(p, p2, sizeof(p2))) @@ -1659,8 +1660,8 @@ int aesccm_test(void) /* Test the authentication failure */ t2[0]++; /* Corrupt the authentication tag. */ - result = AesCcmDecrypt(&enc, - p2, c, sizeof(p2), t2, sizeof(t2), a, sizeof(a)); + result = AesCcmDecrypt(&enc, p2, c, sizeof(p2), iv, sizeof(iv), + t2, sizeof(t2), a, sizeof(a)); if (result == 0) return -111; diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index 1c5e93bf0..4272973da 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -76,9 +76,6 @@ typedef struct Aes { ALIGN16 byte M0[256][AES_BLOCK_SIZE]; #endif /* GCM_TABLE */ #endif /* HAVE_AESGCM */ -#ifdef HAVE_AESCCM - word32 lenSz; -#endif #ifdef CYASSL_AESNI byte use_aesni; #endif /* CYASSL_AESNI */ @@ -96,27 +93,26 @@ CYASSL_API void AesDecryptDirect(Aes* aes, byte* out, const byte* in); CYASSL_API int AesSetKeyDirect(Aes* aes, const byte* key, word32 len, const byte* iv, int dir); #ifdef HAVE_AESGCM -CYASSL_API void AesGcmSetKey(Aes* aes, const byte* key, word32 len, - const byte* implicitIV); -CYASSL_API void AesGcmSetExpIV(Aes* aes, const byte* iv); -CYASSL_API void AesGcmGetExpIV(Aes* aes, byte* iv); -CYASSL_API void AesGcmIncExpIV(Aes* aes); +CYASSL_API void AesGcmSetKey(Aes* aes, const byte* key, word32 len); CYASSL_API void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz); CYASSL_API int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* iv, word32 ivSz, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz); #endif /* HAVE_AESGCM */ #ifdef HAVE_AESCCM -CYASSL_API void AesCcmSetKey(Aes* aes, const byte* key, word32 keySz, - const byte* implicitIV, word32 ivSz); +CYASSL_API void AesCcmSetKey(Aes* aes, const byte* key, word32 keySz); CYASSL_API void AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, - byte* authTag, word32 authTagSz, - const byte* authIn, word32 authInSz); + const byte* nonce, word32 nonceSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); CYASSL_API int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, - const byte* authTag, word32 authTagSz, - const byte* authIn, word32 authInSz); + const byte* nonce, word32 nonceSz, + const byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); #endif /* HAVE_AESCCM */ diff --git a/cyassl/internal.h b/cyassl/internal.h index 557f476d8..d2cc3e61e 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -284,6 +284,10 @@ void c32to24(word32 in, word24 out); #define AES_BLOCK_SIZE 16 #endif +#if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) + #define HAVE_AEAD +#endif + /* actual cipher values, 2nd byte */ enum { @@ -471,6 +475,7 @@ enum Misc { AEAD_LEN_OFFSET = 11, /* Auth Data: Length */ AEAD_AUTH_TAG_SZ = 16, /* Size of the authentication tag */ AEAD_AUTH_DATA_SZ = 13, /* Size of the data to authenticate */ + AEAD_NONCE_SZ = AES_GCM_EXP_IV_SZ + AES_GCM_IMP_IV_SZ, HC_128_KEY_SIZE = 16, /* 128 bits */ HC_128_IV_SIZE = 16, /* also 128 bits */ @@ -1046,6 +1051,11 @@ typedef struct Keys { byte server_write_key[AES_256_KEY_SIZE]; byte client_write_IV[AES_IV_SIZE]; /* max sizes */ byte server_write_IV[AES_IV_SIZE]; +#ifdef HAVE_AEAD + byte aead_exp_IV[AES_GCM_EXP_IV_SZ]; + byte aead_enc_imp_IV[AES_GCM_IMP_IV_SZ]; + byte aead_dec_imp_IV[AES_GCM_IMP_IV_SZ]; +#endif word32 peer_sequence_number; word32 sequence_number; diff --git a/src/internal.c b/src/internal.c index 765ce75e7..c70e06941 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2930,6 +2930,17 @@ static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) } +#ifdef HAVE_AEAD +static INLINE void AeadIncrementExpIV(CYASSL* ssl) +{ + int i; + for (i = AES_GCM_EXP_IV_SZ-1; i >= 0; i--) { + if (++ssl->keys.aead_exp_IV[i]) return; + } +} +#endif + + static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) { (void)out; @@ -2976,6 +2987,7 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) case aes_gcm: { byte additional[AES_BLOCK_SIZE]; + byte nonce[AEAD_NONCE_SZ]; XMEMSET(additional, 0, AES_BLOCK_SIZE); @@ -2991,12 +3003,18 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) * IV length minus the authentication tag size. */ c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, additional + AEAD_LEN_OFFSET); + XMEMCPY(nonce, + ssl->keys.aead_enc_imp_IV, AES_GCM_IMP_IV_SZ); + XMEMCPY(nonce + AES_GCM_IMP_IV_SZ, + ssl->keys.aead_exp_IV, AES_GCM_EXP_IV_SZ); AesGcmEncrypt(ssl->encrypt.aes, out + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ, sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + nonce, AEAD_NONCE_SZ, out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ, additional, AEAD_AUTH_DATA_SZ); - AesGcmIncExpIV(ssl->encrypt.aes); + AeadIncrementExpIV(ssl); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); } break; #endif @@ -3089,8 +3107,8 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, case aes_gcm: { byte additional[AES_BLOCK_SIZE]; + byte nonce[AEAD_NONCE_SZ]; - AesGcmSetExpIV(ssl->decrypt.aes, input); XMEMSET(additional, 0, AES_BLOCK_SIZE); /* sequence number field is 64-bits, we only use 32-bits */ @@ -3102,15 +3120,20 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, additional + AEAD_LEN_OFFSET); + XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AES_GCM_IMP_IV_SZ); + XMEMCPY(nonce + AES_GCM_IMP_IV_SZ, input, AES_GCM_EXP_IV_SZ); if (AesGcmDecrypt(ssl->decrypt.aes, plain + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ, sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + nonce, AEAD_NONCE_SZ, input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ, additional, AEAD_AUTH_DATA_SZ) < 0) { SendAlert(ssl, alert_fatal, bad_record_mac); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); return VERIFY_MAC_ERROR; } + XMEMSET(nonce, 0, AEAD_NONCE_SZ); break; } #endif @@ -4149,7 +4172,7 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, if (ssl->specs.cipher_type == aead) { ivSz = AES_GCM_EXP_IV_SZ; sz += (ivSz + 16 - digestSz); - AesGcmGetExpIV(ssl->encrypt.aes, iv); + XMEMCPY(iv, ssl->keys.aead_exp_IV, AES_GCM_EXP_IV_SZ); } #endif size = (word16)(sz - headerSz); /* include mac and digest */ diff --git a/src/keys.c b/src/keys.c index cb5f845a4..db8147766 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1006,7 +1006,7 @@ static int SetPrefix(byte* sha_input, int idx) static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, - byte side, void* heap, RNG* rng) + byte side, void* heap) { #ifdef BUILD_ARC4 word32 sz = specs->key_size; @@ -1136,7 +1136,6 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #ifdef BUILD_AESGCM if (specs->bulk_cipher_algorithm == aes_gcm) { - byte iv[AES_GCM_EXP_IV_SZ]; enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); if (enc->aes == NULL) return MEMORY_E; @@ -1144,21 +1143,21 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, if (dec->aes == NULL) return MEMORY_E; - /* Initialize the AES-GCM explicit IV to a random number. */ - RNG_GenerateBlock(rng, iv, sizeof(iv)); - AesGcmSetExpIV(enc->aes, iv); - if (side == CLIENT_END) { - AesGcmSetKey(enc->aes, keys->client_write_key, specs->key_size, - keys->client_write_IV); - AesGcmSetKey(dec->aes, keys->server_write_key, specs->key_size, - keys->server_write_IV); + AesGcmSetKey(enc->aes, keys->client_write_key, specs->key_size); + XMEMCPY(keys->aead_enc_imp_IV, + keys->client_write_IV, AES_GCM_IMP_IV_SZ); + AesGcmSetKey(dec->aes, keys->server_write_key, specs->key_size); + XMEMCPY(keys->aead_dec_imp_IV, + keys->server_write_IV, AES_GCM_IMP_IV_SZ); } else { - AesGcmSetKey(enc->aes, keys->server_write_key, specs->key_size, - keys->server_write_IV); - AesGcmSetKey(dec->aes, keys->client_write_key, specs->key_size, - keys->client_write_IV); + AesGcmSetKey(enc->aes, keys->server_write_key, specs->key_size); + XMEMCPY(keys->aead_enc_imp_IV, + keys->server_write_IV, AES_GCM_IMP_IV_SZ); + AesGcmSetKey(dec->aes, keys->client_write_key, specs->key_size); + XMEMCPY(keys->aead_dec_imp_IV, + keys->client_write_IV, AES_GCM_IMP_IV_SZ); } enc->setup = 1; dec->setup = 1; @@ -1175,7 +1174,6 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, keys->sequence_number = 0; keys->peer_sequence_number = 0; keys->encryptionOn = 0; - (void)rng; (void)side; (void)heap; (void)enc; @@ -1209,8 +1207,15 @@ int StoreKeys(CYASSL* ssl, const byte* keyData) i += sz; XMEMCPY(ssl->keys.server_write_IV, &keyData[i], sz); +#ifdef HAVE_AEAD + if (ssl->specs.cipher_type == aead) { + /* Initialize the AES-GCM explicit IV to a random number. */ + RNG_GenerateBlock(ssl->rng, ssl->keys.aead_exp_IV, AES_GCM_EXP_IV_SZ); + } +#endif + return SetKeys(&ssl->encrypt, &ssl->decrypt, &ssl->keys, &ssl->specs, - ssl->options.side, ssl->heap, ssl->rng); + ssl->options.side, ssl->heap); } #ifndef NO_OLD_TLS