diff --git a/src/internal.c b/src/internal.c index be2dd10bc..344e1c422 100644 --- a/src/internal.c +++ b/src/internal.c @@ -11477,6 +11477,10 @@ static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifndef WOLFSSL_NO_TLS12 #ifdef HAVE_AEAD + +#if ((defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))) || \ + (defined(HAVE_POLY1305) && defined(HAVE_CHACHA)) static WC_INLINE void AeadIncrementExpIV(WOLFSSL* ssl) { int i; @@ -11484,6 +11488,7 @@ static WC_INLINE void AeadIncrementExpIV(WOLFSSL* ssl) if (++ssl->keys.aead_exp_IV[i]) return; } } +#endif #if defined(HAVE_POLY1305) && defined(HAVE_CHACHA) @@ -11833,6 +11838,28 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, #endif /* HAVE_AEAD */ +#if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) + +#if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) +/* The following type is used to share code between AES-GCM and AES-CCM. */ + typedef int (*AesAuthEncryptFunc)(Aes* aes, byte* out, + const byte* in, word32 sz, + byte* iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte* authIn, word32 authInSz); + #define AES_AUTH_ENCRYPT_FUNC AesAuthEncryptFunc + #define AES_GCM_ENCRYPT wc_AesGcmEncrypt_ex + #define AES_CCM_ENCRYPT wc_AesCcmEncrypt_ex +#else + #define AES_AUTH_ENCRYPT_FUNC wc_AesAuthEncryptFunc + #define AES_GCM_ENCRYPT wc_AesGcmEncrypt + #define AES_CCM_ENCRYPT wc_AesCcmEncrypt +#endif + +#endif + + static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, word16 sz, int asyncOkay) { @@ -11897,7 +11924,7 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, case wolfssl_aes_gcm: case wolfssl_aes_ccm:/* GCM AEAD macros use same size as CCM */ { - wc_AesAuthEncryptFunc aes_auth_fn; + AES_AUTH_ENCRYPT_FUNC aes_auth_fn; const byte* additionalSrc; #ifdef WOLFSSL_ASYNC_CRYPT @@ -11910,11 +11937,11 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, #if defined(BUILD_AESGCM) && defined(HAVE_AESCCM) aes_auth_fn = (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) - ? wc_AesGcmEncrypt : wc_AesCcmEncrypt; + ? AES_GCM_ENCRYPT : AES_CCM_ENCRYPT; #elif defined(BUILD_AESGCM) - aes_auth_fn = wc_AesGcmEncrypt; + aes_auth_fn = AES_GCM_ENCRYPT; #else - aes_auth_fn = wc_AesCcmEncrypt; + aes_auth_fn = AES_CCM_ENCRYPT; #endif additionalSrc = input - 5; @@ -11937,10 +11964,13 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, * IV length minus the authentication tag size. */ c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, ssl->encrypt.additional + AEAD_LEN_OFFSET); +#if (defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) XMEMCPY(ssl->encrypt.nonce, ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ); XMEMCPY(ssl->encrypt.nonce + AESGCM_IMP_IV_SZ, ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ); +#endif ret = aes_auth_fn(ssl->encrypt.aes, out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ, sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, @@ -11953,6 +11983,11 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, ret = wolfSSL_AsyncPush(ssl, asyncDev); } #endif +#if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + XMEMCPY(out, + ssl->encrypt.nonce + AESGCM_IMP_IV_SZ, AESGCM_EXP_IV_SZ); +#endif } break; #endif /* BUILD_AESGCM || HAVE_AESCCM */ @@ -12081,8 +12116,10 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) { /* finalize authentication cipher */ +#if (defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) AeadIncrementExpIV(ssl); - +#endif if (ssl->encrypt.nonce) ForceZero(ssl->encrypt.nonce, AESGCM_NONCE_SZ); @@ -12102,6 +12139,7 @@ static WC_INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 return ret; } + static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) { @@ -14000,13 +14038,14 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, goto exit_buildmsg; } - - #ifdef HAVE_AEAD +#if (defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) && \ + defined(HAVE_AEAD) if (ssl->specs.cipher_type == aead) { if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) XMEMCPY(args->iv, ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ); } - #endif +#endif args->size = (word16)(args->sz - args->headerSz); /* include mac and digest */ AddRecordHeader(output, args->size, (byte)type, ssl); diff --git a/src/keys.c b/src/keys.c index 0bbaa53af..21a89c27e 100644 --- a/src/keys.c +++ b/src/keys.c @@ -2212,11 +2212,14 @@ static int SetPrefix(byte* sha_input, int idx) static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, - int side, void* heap, int devId) + int side, void* heap, int devId, WC_RNG* rng, int skipIv) { + (void)rng; + (void)skipIv; + #ifdef BUILD_ARC4 - word32 sz = specs->key_size; if (specs->bulk_cipher_algorithm == wolfssl_rc4) { + word32 sz = specs->key_size; if (enc && enc->arc4 == NULL) enc->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER); if (enc && enc->arc4 == NULL) @@ -2608,6 +2611,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, if (gcmRet != 0) return gcmRet; XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, AEAD_MAX_IMP_SZ); +#if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + if (!skipIv) { + gcmRet = wc_AesGcmSetIV(enc->aes, AESGCM_NONCE_SZ, + keys->client_write_IV, AESGCM_IMP_IV_SZ, rng); + if (gcmRet != 0) return gcmRet; + } +#endif } if (dec) { gcmRet = wc_AesGcmSetKey(dec->aes, keys->server_write_key, @@ -2624,6 +2635,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, if (gcmRet != 0) return gcmRet; XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, AEAD_MAX_IMP_SZ); +#if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + if (!skipIv) { + gcmRet = wc_AesGcmSetIV(enc->aes, AESGCM_NONCE_SZ, + keys->server_write_IV, AESGCM_IMP_IV_SZ, rng); + if (gcmRet != 0) return gcmRet; + } +#endif } if (dec) { gcmRet = wc_AesGcmSetKey(dec->aes, keys->client_write_key, @@ -2692,6 +2711,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, } XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, AEAD_MAX_IMP_SZ); +#if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + if (!skipIv) { + CcmRet = wc_AesCcmSetNonce(enc->aes, keys->client_write_IV, + AEAD_MAX_IMP_SZ); + if (CcmRet != 0) return CcmRet; + } +#endif } if (dec) { CcmRet = wc_AesCcmSetKey(dec->aes, keys->server_write_key, @@ -2712,6 +2739,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, } XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, AEAD_MAX_IMP_SZ); +#if (!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) + if (!skipIv) { + CcmRet = wc_AesCcmSetNonce(enc->aes, keys->server_write_IV, + AEAD_MAX_IMP_SZ); + if (CcmRet != 0) return CcmRet; + } +#endif } if (dec) { CcmRet = wc_AesCcmSetKey(dec->aes, keys->client_write_key, @@ -3006,7 +3041,7 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) #endif ret = SetKeys(wc_encrypt, wc_decrypt, keys, &ssl->specs, ssl->options.side, - ssl->heap, ssl->devId); + ssl->heap, ssl->devId, ssl->rng, ssl->options.tls1_3); #ifdef HAVE_SECURE_RENEGOTIATION if (copy) { diff --git a/src/tls13.c b/src/tls13.c index 73b2cc6e6..b2858a9fa 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1681,9 +1681,13 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, #endif nonceSz = AESGCM_NONCE_SZ; - ret = wc_AesGcmEncrypt(ssl->encrypt.aes, output, input, - dataSz, ssl->encrypt.nonce, nonceSz, - output + dataSz, macSz, aad, aadSz); + ret = wc_AesGcmSetExtIV(ssl->encrypt.aes, + ssl->encrypt.nonce, nonceSz); + if (ret == 0) { + ret = wc_AesGcmEncrypt_ex(ssl->encrypt.aes, output, + input, dataSz, ssl->encrypt.nonce, nonceSz, + output + dataSz, macSz, aad, aadSz); + } break; #endif @@ -1698,9 +1702,13 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input, #endif nonceSz = AESCCM_NONCE_SZ; - ret = wc_AesCcmEncrypt(ssl->encrypt.aes, output, input, - dataSz, ssl->encrypt.nonce, nonceSz, - output + dataSz, macSz, aad, aadSz); + ret = wc_AesCcmSetNonce(ssl->encrypt.aes, + ssl->encrypt.nonce, nonceSz); + if (ret == 0) { + ret = wc_AesCcmEncrypt_ex(ssl->encrypt.aes, output, + input, dataSz, ssl->encrypt.nonce, nonceSz, + output + dataSz, macSz, aad, aadSz); + } break; #endif