]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic_tls: Add quic_tls_decrypt2() implementation
authorFrédéric Lécaille <flecaille@haproxy.com>
Mon, 16 May 2022 08:27:57 +0000 (10:27 +0200)
committerFrédéric Lécaille <flecaille@haproxy.com>
Fri, 20 May 2022 14:57:12 +0000 (16:57 +0200)
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.

include/haproxy/quic_tls.h
src/quic_tls.c

index 18a9a047560236babe7772b06e62b9bbf6df3a67..9435e9228a827870f0066db209b55007c4be50f8 100644 (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,
index 8f17b237158c9991da71a4db5d5543d38a4c917d..623f759be231958ff8475c00d109c488677b993a 100644 (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.