Chacha-Poly AEAD fix for SCR

Wrong cipher material was being used when using Chacha-Poly AEAD for DTLS 1.2 with secure renegotiation
pull/3904/head
Juliusz Sosinowicz 2021-03-22 22:42:49 +01:00
parent 24b67599c8
commit 3abcdf059a
2 changed files with 43 additions and 11 deletions

View File

@ -13786,14 +13786,34 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
#ifdef CHACHA_AEAD_TEST
int i;
#endif
Keys* keys = &ssl->keys;
XMEMSET(tag, 0, sizeof(tag));
XMEMSET(nonce, 0, sizeof(nonce));
XMEMSET(poly, 0, sizeof(poly));
XMEMSET(add, 0, sizeof(add));
#if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION)
/*
* For epochs 2+:
* * use ssl->secure_renegotiation when encrypting the current epoch as it
* has the current epoch cipher material
* * use PREV_ORDER if encrypting the epoch not in
* ssl->secure_renegotiation
*/
/* opaque SEQ number stored for AD */
WriteSEQ(ssl, CUR_ORDER, add);
if (ssl->options.dtls && DtlsSCRKeysSet(ssl)) {
if (ssl->keys.dtls_epoch ==
ssl->secure_renegotiation->tmp_keys.dtls_epoch) {
keys = &ssl->secure_renegotiation->tmp_keys;
WriteSEQ(ssl, CUR_ORDER, add);
}
else
WriteSEQ(ssl, PREV_ORDER, add);
}
else
#endif
WriteSEQ(ssl, CUR_ORDER, add);
if (ssl->options.oldPoly != 0) {
/* get nonce. SEQ should not be incremented again here */
@ -13832,7 +13852,7 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
if (ssl->options.oldPoly == 0) {
/* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
* record sequence number XORed with client_write_IV/server_write_IV */
XMEMCPY(nonce, ssl->keys.aead_enc_imp_IV, CHACHA20_IMP_IV_SZ);
XMEMCPY(nonce, keys->aead_enc_imp_IV, CHACHA20_IMP_IV_SZ);
nonce[4] ^= add[0];
nonce[5] ^= add[1];
nonce[6] ^= add[2];
@ -13940,6 +13960,7 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
int ret = 0;
int msgLen = (sz - ssl->specs.aead_mac_size);
Keys* keys = &ssl->keys;
#ifdef CHACHA_AEAD_TEST
int i;
@ -13957,6 +13978,17 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
XMEMSET(nonce, 0, sizeof(nonce));
XMEMSET(add, 0, sizeof(add));
#if defined(WOLFSSL_DTLS) && defined(HAVE_SECURE_RENEGOTIATION)
/*
* For epochs 2+:
* * use ssl->secure_renegotiation when decrypting the latest epoch as it
* has the latest epoch cipher material
*/
if (ssl->options.dtls && DtlsSCRKeysSet(ssl) &&
ssl->keys.curEpoch == ssl->secure_renegotiation->tmp_keys.dtls_epoch)
keys = &ssl->secure_renegotiation->tmp_keys;
#endif
/* sequence number field is 64-bits */
WriteSEQ(ssl, PEER_ORDER, add);
@ -13986,7 +14018,7 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
if (ssl->options.oldPoly == 0) {
/* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte
* record sequence number XORed with client_write_IV/server_write_IV */
XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, CHACHA20_IMP_IV_SZ);
XMEMCPY(nonce, keys->aead_dec_imp_IV, CHACHA20_IMP_IV_SZ);
nonce[4] ^= add[0];
nonce[5] ^= add[1];
nonce[6] ^= add[2];

View File

@ -3086,10 +3086,10 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Provisioning ENCRYPT key");
if (ssl->options.side == WOLFSSL_CLIENT_END) {
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->client_write_key, ssl->specs.key_size);
}
else {
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->server_write_key, ssl->specs.key_size);
}
#endif
wc_encrypt = &ssl->encrypt;
@ -3099,10 +3099,10 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Provisioning DECRYPT key");
if (ssl->options.side == WOLFSSL_CLIENT_END) {
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->server_write_key, ssl->specs.key_size);
}
else {
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->client_write_key, ssl->specs.key_size);
}
#endif
wc_decrypt = &ssl->decrypt;
@ -3112,17 +3112,17 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Provisioning ENCRYPT key");
if (ssl->options.side == WOLFSSL_CLIENT_END) {
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->client_write_key, ssl->specs.key_size);
}
else {
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->server_write_key, ssl->specs.key_size);
}
WOLFSSL_MSG("Provisioning DECRYPT key");
if (ssl->options.side == WOLFSSL_CLIENT_END) {
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->server_write_key, ssl->specs.key_size);
}
else {
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
WOLFSSL_BUFFER(keys->client_write_key, ssl->specs.key_size);
}
#endif
wc_encrypt = &ssl->encrypt;