diff --git a/include/haproxy/quic_tls.h b/include/haproxy/quic_tls.h index 18a9a0475..9435e9228 100644 --- a/include/haproxy/quic_tls.h +++ b/include/haproxy/quic_tls.h @@ -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, diff --git a/src/quic_tls.c b/src/quic_tls.c index 8f17b2371..623f759be 100644 --- a/src/quic_tls.c +++ b/src/quic_tls.c @@ -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 output buffer ciphertest with as length + * is different from 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 buffer with as length. This is always the + * case here. So the caller of this function must provide . 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 and key and IV to be used to encrypt a retry token * with which is not pseudo-random. * Return 1 if succeeded, 0 if not.