From: Amaury Denoyelle Date: Tue, 11 Jan 2022 10:57:00 +0000 (+0100) Subject: MINOR: quic: implement Retry TLS AEAD tag generation X-Git-Tag: v2.6-dev1~141 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6efec292ef77ec87ffbbc2e3547e697170f2663f;p=thirdparty%2Fhaproxy.git MINOR: quic: implement Retry TLS AEAD tag generation Implement a new QUIC TLS related function quic_tls_generate_retry_integrity_tag(). This function can be used to calculate the AEAD tag of a Retry packet. --- diff --git a/include/haproxy/quic_tls.h b/include/haproxy/quic_tls.h index 2c3528d837..cc94b029a9 100644 --- a/include/haproxy/quic_tls.h +++ b/include/haproxy/quic_tls.h @@ -69,6 +69,9 @@ int quic_tls_decrypt(unsigned char *buf, size_t len, const EVP_CIPHER *aead, const unsigned char *key, const unsigned char *iv); +int quic_tls_generate_retry_integrity_tag(unsigned char *odcid, size_t odcid_len, + unsigned char *buf, size_t len); + int quic_tls_derive_keys(const EVP_CIPHER *aead, const EVP_CIPHER *hp, const EVP_MD *md, unsigned char *key, size_t keylen, diff --git a/src/quic_tls.c b/src/quic_tls.c index 8100d47590..d4314d7cb4 100644 --- a/src/quic_tls.c +++ b/src/quic_tls.c @@ -396,3 +396,59 @@ int quic_tls_decrypt(unsigned char *buf, size_t len, EVP_CIPHER_CTX_free(ctx); return ret; } + +/* Generate the AEAD tag for the Retry packet of bytes and + * write it to . The tag is written just after the area. It should + * be at least 16 bytes longs. is the CID of the Initial packet + * received which triggers the Retry. + * + * Returns non-zero on success else zero. + */ +int quic_tls_generate_retry_integrity_tag(unsigned char *odcid, + unsigned char odcid_len, + unsigned char *pkt, size_t pkt_len) +{ + const EVP_CIPHER *evp = EVP_aes_128_gcm(); + EVP_CIPHER_CTX *ctx; + + /* key/nonce from rfc9001 5.8. Retry Packet Integrity */ + const unsigned char key[] = { + 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, + 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e, + }; + const unsigned char nonce[] = { + 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb, + }; + + /* encryption buffer - not used as only AEAD tag generation is proceed */ + unsigned char *out = NULL; + /* address to store the AEAD tag */ + unsigned char *tag = pkt + pkt_len; + int outlen, ret = 0; + + ctx = EVP_CIPHER_CTX_new(); + if (!ctx) + return 0; + + /* rfc9001 5.8. Retry Packet Integrity + * + * AEAD is proceed over a pseudo-Retry packet used as AAD. It contains + * the ODCID len + data and the Retry packet itself. + */ + if (!EVP_EncryptInit_ex(ctx, evp, NULL, key, nonce) || + /* specify pseudo-Retry as AAD */ + !EVP_EncryptUpdate(ctx, NULL, &outlen, &odcid_len, sizeof(odcid_len)) || + !EVP_EncryptUpdate(ctx, NULL, &outlen, odcid, odcid_len) || + !EVP_EncryptUpdate(ctx, NULL, &outlen, pkt, pkt_len) || + /* finalize */ + !EVP_EncryptFinal_ex(ctx, out, &outlen) || + /* store the tag */ + !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, QUIC_TLS_TAG_LEN, tag)) { + goto out; + } + ret = 1; + + out: + EVP_CIPHER_CTX_free(ctx); + return ret; +}