Start using the provider side TLS HMAC implementation
authorMatt Caswell <matt@openssl.org>
Thu, 30 Jul 2020 12:16:39 +0000 (13:16 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 3 Sep 2020 08:40:52 +0000 (09:40 +0100)
This commit just moves the TLS1 and above implementation to use the TLS
HMAC implementation in the providers.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12732)

providers/implementations/macs/hmac_prov.c
ssl/record/ssl3_record.c

index f32841152af87045354092d00b2df9875774df58..3376395a172fea0f2f4d5385ae889cacf5888c6e 100644 (file)
@@ -51,7 +51,7 @@ struct hmac_data_st {
     PROV_DIGEST digest;
     unsigned char *key;
     size_t keylen;
-    /* Length of TLS data including the MAC but excluding padding */
+    /* Length of full TLS record including the MAC and any padding */
     size_t tls_data_size;
     unsigned char tls_header[13];
     int tls_header_set;
@@ -166,8 +166,8 @@ static int hmac_update(void *vmacctx, const unsigned char *data,
             macctx->tls_header_set = 1;
             return 1;
         }
-        /* datalen is macctx->tls_data_size plus the padding length */
-        if (datalen < macctx->tls_data_size)
+        /* macctx->tls_data_size is datalen plus the padding length */
+        if (macctx->tls_data_size < datalen)
             return 0;
 
         return ssl3_cbc_digest_record(ossl_prov_digest_md(&macctx->digest),
@@ -175,8 +175,8 @@ static int hmac_update(void *vmacctx, const unsigned char *data,
                                       &macctx->tls_mac_out_size,
                                       macctx->tls_header,
                                       data,
-                                      macctx->tls_data_size,
                                       datalen,
+                                      macctx->tls_data_size,
                                       macctx->key,
                                       macctx->keylen,
                                       0);
index 70707da691acd7a16a056f8411045b2efad3a4f8..6708a832412a49b13640dc16437d225ca3c834f7 100644 (file)
@@ -1465,31 +1465,25 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
     header[12] = (unsigned char)(rec->length & 0xff);
 
     if (!sending && !SSL_READ_ETM(ssl) &&
-        EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
-        ssl3_cbc_record_digest_supported(mac_ctx)) {
-        /*
-         * This is a CBC-encrypted record. We must avoid leaking any
-         * timing-side channel information about how many blocks of data we
-         * are hashing because that gives an attacker a timing-oracle.
-         */
-        /* Final param == not SSLv3 */
-        if (ssl3_cbc_digest_record(EVP_MD_CTX_md(mac_ctx),
-                                   md, &md_size,
-                                   header, rec->input,
-                                   rec->length + md_size, rec->orig_len,
-                                   ssl->s3.read_mac_secret,
-                                   ssl->s3.read_mac_secret_size, 0) <= 0) {
-            EVP_MD_CTX_free(hmac);
-            return 0;
-        }
-    } else {
-        /* TODO(size_t): Convert these calls */
-        if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
-            || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
-            || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
-            EVP_MD_CTX_free(hmac);
+            EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+            ssl3_cbc_record_digest_supported(mac_ctx)) {
+        OSSL_PARAM tls_hmac_params[2], *p = tls_hmac_params;
+
+        *p++ = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_TLS_DATA_SIZE,
+                                           &rec->orig_len);
+        *p++ = OSSL_PARAM_construct_end();
+
+        if (!EVP_PKEY_CTX_set_params(EVP_MD_CTX_pkey_ctx(mac_ctx),
+                                     tls_hmac_params))
             return 0;
-        }
+    }
+
+    /* TODO(size_t): Convert these calls */
+    if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
+        || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
+        || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
+        EVP_MD_CTX_free(hmac);
+        return 0;
     }
 
     EVP_MD_CTX_free(hmac);