Add a prepare for encryption step
authorMatt Caswell <matt@openssl.org>
Tue, 27 Sep 2022 15:43:23 +0000 (16:43 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 12 Oct 2022 14:53:31 +0000 (15:53 +0100)
This applies any mac that might be necessary, ensures that we have
enough space in the WPACKET to perform the encryption and sets up the
SSL3_RECORD ready for that encryption.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19343)

ssl/record/methods/ktls_meth.c
ssl/record/methods/recmethod_local.h
ssl/record/methods/ssl3_meth.c
ssl/record/methods/tls13_meth.c
ssl/record/methods/tls1_meth.c
ssl/record/methods/tls_common.c
ssl/record/methods/tlsany_meth.c

index f73334604ad4cff7d64997fd4df3e6847db83420..bd694a894864f943c399aba53d8edd8caa7d9ae4 100644 (file)
@@ -492,6 +492,15 @@ static int ktls_prepare_record_header(OSSL_RECORD_LAYER *rl,
     return 1;
 }
 
+static int ktls_prepare_for_encryption(OSSL_RECORD_LAYER *rl,
+                                       size_t mac_size,
+                                       WPACKET *thispkt,
+                                       SSL3_RECORD *thiswr)
+{
+    /* No encryption, so nothing to do */
+    return 1;
+}
+
 static struct record_functions_st ossl_ktls_funcs = {
     ktls_set_crypto_state,
     ktls_cipher,
@@ -507,7 +516,8 @@ static struct record_functions_st ossl_ktls_funcs = {
     ktls_initialise_write_packets,
     NULL,
     ktls_prepare_record_header,
-    NULL
+    NULL,
+    ktls_prepare_for_encryption
 };
 
 const OSSL_RECORD_METHOD ossl_ktls_record_method = {
index 0a4c97a29d036b77f7a1250002b7b6f6bbdff5f2..2e30d2f13323beb4f348ff6c75c88306a8ce6220 100644 (file)
@@ -110,6 +110,16 @@ struct record_functions_st
                               OSSL_RECORD_TEMPLATE *thistempl,
                               WPACKET *thispkt,
                               SSL3_RECORD *thiswr);
+
+    /*
+     * This applies any mac that might be necessary, ensures that we have enough
+     * space in the WPACKET to perform the encryption and sets up the
+     * SSL3_RECORD ready for that encryption.
+     */
+    int (*prepare_for_encryption)(OSSL_RECORD_LAYER *rl,
+                                  size_t mac_size,
+                                  WPACKET *thispkt,
+                                  SSL3_RECORD *thiswr);
 };
 
 struct ossl_record_layer_st
@@ -407,6 +417,10 @@ int tls_prepare_record_header_default(OSSL_RECORD_LAYER *rl,
                                       OSSL_RECORD_TEMPLATE *templ,
                                       unsigned int rectype,
                                       unsigned char **recdata);
+int tls_prepare_for_encryption_default(OSSL_RECORD_LAYER *rl,
+                                       size_t mac_size,
+                                       WPACKET *thispkt,
+                                       SSL3_RECORD *thiswr);
 int tls_write_records_default(OSSL_RECORD_LAYER *rl,
                               OSSL_RECORD_TEMPLATE *templates,
                               size_t numtempl);
index 544d4d07e045b089cf42697cf74e9e5c381b2ad6..ef9a6ae49979878d14a0c6d3adfea216a3ae155d 100644 (file)
@@ -316,5 +316,6 @@ struct record_functions_st ssl_3_0_funcs = {
     tls1_initialise_write_packets,
     NULL,
     tls_prepare_record_header_default,
-    NULL
+    NULL,
+    tls_prepare_for_encryption_default
 };
index 4b0142391b6295565f8ef05c9b796b78ae9d4888..a9d90f6577e0edffaf267146a62d6ad2381248e1 100644 (file)
@@ -324,5 +324,6 @@ struct record_functions_st tls_1_3_funcs = {
     tls_initialise_write_packets_default,
     tls13_get_record_type,
     tls_prepare_record_header_default,
-    tls13_add_record_padding
+    tls13_add_record_padding,
+    tls_prepare_for_encryption_default
 };
index b02c53d6494f6e7c07ddb8af8e70994f1dabb857..71138abc28a98e7c25ef77c276fae46ae7d696cc 100644 (file)
@@ -657,7 +657,8 @@ struct record_functions_st tls_1_funcs = {
     tls1_initialise_write_packets,
     NULL,
     tls_prepare_record_header_default,
-    NULL
+    NULL,
+    tls_prepare_for_encryption_default
 };
 
 struct record_functions_st dtls_1_funcs = {
@@ -674,5 +675,6 @@ struct record_functions_st dtls_1_funcs = {
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 };
index e3be4303367355f1b516d95e0894fb4e48a9f1a4..97e2714042b5036348c77c2c70c4495b39fa5905 100644 (file)
@@ -1562,6 +1562,56 @@ int tls_prepare_record_header_default(OSSL_RECORD_LAYER *rl,
     return 1;
 }
 
+int tls_prepare_for_encryption_default(OSSL_RECORD_LAYER *rl,
+                                       size_t mac_size,
+                                       WPACKET *thispkt,
+                                       SSL3_RECORD *thiswr)
+{
+    size_t len;
+    unsigned char *recordstart;
+
+    /*
+     * we should still have the output to thiswr->data and the input from
+     * wr->input. Length should be thiswr->length. thiswr->data still points
+     * in the wb->buf
+     */
+
+    if (!rl->use_etm && mac_size != 0) {
+        unsigned char *mac;
+
+        if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+                || !rl->funcs->mac(rl, thiswr, mac, 1)) {
+            RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+
+    /*
+     * Reserve some bytes for any growth that may occur during encryption.
+     * This will be at most one cipher block or the tag length if using
+     * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
+     */
+    if (!WPACKET_reserve_bytes(thispkt,
+                               SSL_RT_MAX_CIPHER_BLOCK_SIZE,
+                               NULL)
+            /*
+             * We also need next the amount of bytes written to this
+             * sub-packet
+             */
+            || !WPACKET_get_length(thispkt, &len)) {
+        RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    /* Get a pointer to the start of this record excluding header */
+    recordstart = WPACKET_get_curr(thispkt) - len;
+    SSL3_RECORD_set_data(thiswr, recordstart);
+    SSL3_RECORD_reset_input(thiswr);
+    SSL3_RECORD_set_length(thiswr, len);
+
+    return 1;
+}
+
 int tls_write_records_default(OSSL_RECORD_LAYER *rl,
                               OSSL_RECORD_TEMPLATE *templates,
                               size_t numtempl)
@@ -1665,45 +1715,9 @@ int tls_write_records_default(OSSL_RECORD_LAYER *rl,
             goto err;
         }
 
-        /*
-         * we should still have the output to thiswr->data and the input from
-         * wr->input. Length should be thiswr->length. thiswr->data still points
-         * in the wb->buf
-         */
-
-        if (!using_ktls && !rl->use_etm && mac_size != 0) {
-            unsigned char *mac;
-
-            if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
-                    || !rl->funcs->mac(rl, thiswr, mac, 1)) {
-                RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-                goto err;
-            }
-        }
-
-        /*
-         * Reserve some bytes for any growth that may occur during encryption.
-         * This will be at most one cipher block or the tag length if using
-         * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
-         */
-        if (!using_ktls) {
-            if (!WPACKET_reserve_bytes(thispkt,
-                                        SSL_RT_MAX_CIPHER_BLOCK_SIZE,
-                                        NULL)
-                    /*
-                    * We also need next the amount of bytes written to this
-                    * sub-packet
-                    */
-                    || !WPACKET_get_length(thispkt, &len)) {
-                RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
-                goto err;
-            }
-
-            /* Get a pointer to the start of this record excluding header */
-            recordstart = WPACKET_get_curr(thispkt) - len;
-            SSL3_RECORD_set_data(thiswr, recordstart);
-            SSL3_RECORD_reset_input(thiswr);
-            SSL3_RECORD_set_length(thiswr, len);
+        if (!rl->funcs->prepare_for_encryption(rl, mac_size, thispkt, thiswr)) {
+            /* RLAYERfatal() already called */
+            goto err;
         }
     }
 
index 8d4486547c1f2ca2a3f80488c60367f95deef1bb..bf4fe6a31c9131f9e60264ceda3034cd80236508 100644 (file)
@@ -134,6 +134,15 @@ static int tls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
     return 1;
 }
 
+static int tls_any_prepare_for_encryption(OSSL_RECORD_LAYER *rl,
+                                          size_t mac_size,
+                                          WPACKET *thispkt,
+                                          SSL3_RECORD *thiswr)
+{
+    /* No encryption, so nothing to do */
+    return 1;
+}
+
 struct record_functions_st tls_any_funcs = {
     tls_any_set_crypto_state,
     tls_any_cipher,
@@ -149,7 +158,8 @@ struct record_functions_st tls_any_funcs = {
     tls_initialise_write_packets_default,
     NULL,
     tls_prepare_record_header_default,
-    NULL
+    NULL,
+    tls_any_prepare_for_encryption
 };
 
 static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
@@ -176,5 +186,6 @@ struct record_functions_st dtls_any_funcs = {
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 };