MINOR: quic_tls: Add quic_tls_decrypt2() implementation

This function does exactly the same thing as quic_tls_decrypt(), except that
it does reuse its input buffer as output buffer. This is needed
to decrypt the Retry token without modifying the packet buffer which
contains this token. Indeed, this would prevent us from decryption
the packet itself as the token belong to the AEAD AAD for the packet.
This commit is contained in:
Frédéric Lécaille 2022-05-16 10:27:57 +02:00
parent a9c5d8da58
commit 55367c8679
2 changed files with 42 additions and 0 deletions

View File

@ -64,6 +64,12 @@ int quic_tls_encrypt(unsigned char *buf, size_t len,
EVP_CIPHER_CTX *ctx, const EVP_CIPHER *aead,
const unsigned char *key, const unsigned char *iv);
int quic_tls_decrypt2(unsigned char *out,
unsigned char *in, size_t ilen,
unsigned char *aad, size_t aad_len,
EVP_CIPHER_CTX *ctx, const EVP_CIPHER *aead,
const unsigned char *key, const unsigned char *iv);
int quic_tls_decrypt(unsigned char *buf, size_t len,
unsigned char *aad, size_t aad_len,
EVP_CIPHER_CTX *tls_ctx, const EVP_CIPHER *aead,

View File

@ -490,6 +490,42 @@ int quic_tls_decrypt(unsigned char *buf, size_t len,
return 1;
}
/* Similar to quic_tls_decrypt(), except that this function does not decrypt
* in place its ciphertest if <out> output buffer ciphertest with <len> as length
* is different from <in> input buffer. This is the responbality of the caller
* to check that the output buffer has at least the same size as the input buffer.
* Note that for CCM mode, we must set the the ciphertext length if AAD data
* are provided from <aad> buffer with <aad_len> as length. This is always the
* case here. So the caller of this function must provide <aad>. Also note that
* there is no need to call EVP_DecryptFinal_ex for CCM mode.
*
* https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
*
* Return 1 if succeeded, 0 if not.
*/
int quic_tls_decrypt2(unsigned char *out,
unsigned char *in, size_t len,
unsigned char *aad, size_t aad_len,
EVP_CIPHER_CTX *ctx, const EVP_CIPHER *aead,
const unsigned char *key, const unsigned char *iv)
{
int outlen;
int aead_nid = EVP_CIPHER_nid(aead);
len -= QUIC_TLS_TAG_LEN;
if (!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) ||
!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, QUIC_TLS_TAG_LEN, in + len) ||
(aead_nid == NID_aes_128_ccm &&
!EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, len)) ||
!EVP_DecryptUpdate(ctx, NULL, &outlen, aad, aad_len) ||
!EVP_DecryptUpdate(ctx, out, &outlen, in, len) ||
(aead_nid != NID_aes_128_ccm &&
!EVP_DecryptFinal_ex(ctx, out + outlen, &outlen)))
return 0;
return 1;
}
/* Derive <key> and <iv> key and IV to be used to encrypt a retry token
* with <secret> which is not pseudo-random.
* Return 1 if succeeded, 0 if not.