mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +02:00
Merge pull request #2087 from ejohnstown/aesgcm
Update TLS for AES-GCM/CCM changes
This commit is contained in:
@@ -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);
|
||||
|
41
src/keys.c
41
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) {
|
||||
|
20
src/tls13.c
20
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
|
||||
|
||||
|
Reference in New Issue
Block a user