diff options
author | Matt Caswell <matt@openssl.org> | 2020-07-30 12:02:06 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2020-09-03 09:40:52 +0100 |
commit | 3fddbb264e87a8cef2903cbd7b02b8e1a39a2a99 (patch) | |
tree | c73b3bb141d21a739ae8faedcaf090e07a4fcba6 /ssl | |
parent | b48ca22a56553f285d91da0ac9399fd5efd54589 (diff) |
Add an HMAC implementation that is TLS aware
The TLS HMAC implementation should take care to calculate the MAC in
constant time in the case of MAC-Then-Encrypt where we have a variable
amount of padding.
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12732)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/build.info | 1 | ||||
-rw-r--r-- | ssl/record/ssl3_record.c | 4 | ||||
-rw-r--r-- | ssl/s3_cbc.c | 56 | ||||
-rw-r--r-- | ssl/ssl_local.h | 3 |
4 files changed, 50 insertions, 14 deletions
diff --git a/ssl/build.info b/ssl/build.info index cfcb2b1737..e5b7befbaa 100644 --- a/ssl/build.info +++ b/ssl/build.info @@ -37,3 +37,4 @@ SOURCE[../libssl]=\ DEFINE[../libssl]=$AESDEF SOURCE[../providers/libcommon.a]=record/tls_pad.c +SOURCE[../providers/libimplementations.a]=s3_cbc.c diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 634052d342..70707da691 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -1362,7 +1362,7 @@ int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) header[j++] = (unsigned char)(rec->length & 0xff); /* Final param == is SSLv3 */ - if (ssl3_cbc_digest_record(ssl, hash, + if (ssl3_cbc_digest_record(EVP_MD_CTX_md(hash), md, &md_size, header, rec->input, rec->length + md_size, rec->orig_len, @@ -1473,7 +1473,7 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) * are hashing because that gives an attacker a timing-oracle. */ /* Final param == not SSLv3 */ - if (ssl3_cbc_digest_record(ssl, mac_ctx, + if (ssl3_cbc_digest_record(EVP_MD_CTX_md(mac_ctx), md, &md_size, header, rec->input, rec->length + md_size, rec->orig_len, diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c index ec1f3cf83b..bffaebb0c2 100644 --- a/ssl/s3_cbc.c +++ b/ssl/s3_cbc.c @@ -8,18 +8,60 @@ */ /* + * This file has no dependencies on the rest of libssl because it is shared + * with the providers. It contains functions for low level MAC calculations. + * Responsibility for this lies with the HMAC implementation in the + * providers. However there are legacy code paths in libssl which also need to + * do this. In time those legacy code paths can be removed and this file can be + * moved out of libssl. + */ + + +/* * MD5 and SHA-1 low level APIs are deprecated for public use, but still ok for * internal use. */ #include "internal/deprecated.h" #include "internal/constant_time.h" -#include "ssl_local.h" #include "internal/cryptlib.h" +#include <openssl/evp.h> #include <openssl/md5.h> #include <openssl/sha.h> +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +int ssl3_cbc_digest_record(const EVP_MD *md, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + size_t mac_secret_length, char is_sslv3); + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + /* * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's * length field. (SHA-384/512 have 128-bit length.) @@ -131,8 +173,7 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) * padding too. ) * Returns 1 on success or 0 on error */ -int ssl3_cbc_digest_record(SSL *s, - const EVP_MD_CTX *ctx, +int ssl3_cbc_digest_record(const EVP_MD *md, unsigned char *md_out, size_t *md_out_size, const unsigned char header[13], @@ -168,7 +209,6 @@ int ssl3_cbc_digest_record(SSL *s, size_t md_length_size = 8; char length_is_big_endian = 1; int ret = 0; - const EVP_MD *md = NULL; /* * This is a, hopefully redundant, check that allows us to forget about @@ -177,7 +217,7 @@ int ssl3_cbc_digest_record(SSL *s, if (!ossl_assert(data_plus_mac_plus_padding_size < 1024 * 1024)) return 0; - switch (EVP_MD_CTX_type(ctx)) { + switch (EVP_MD_type(md)) { case NID_md5: if (MD5_Init((MD5_CTX *)md_state.c) <= 0) return 0; @@ -463,10 +503,7 @@ int ssl3_cbc_digest_record(SSL *s, md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) goto err; - md = ssl_evp_md_fetch(s->ctx->libctx, EVP_MD_type(EVP_MD_CTX_md(ctx)), - s->ctx->propq); - if (md == NULL) - goto err; + if (EVP_DigestInit_ex(md_ctx, md, NULL /* engine */ ) <= 0) goto err; if (is_sslv3) { @@ -494,6 +531,5 @@ int ssl3_cbc_digest_record(SSL *s, ret = 1; err: EVP_MD_CTX_free(md_ctx); - ssl_evp_md_free(md); return ret; } diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index f74f833312..c54ced6a1d 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2761,8 +2761,7 @@ int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, /* s3_cbc.c */ __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); -__owur int ssl3_cbc_digest_record(SSL *s, - const EVP_MD_CTX *ctx, +__owur int ssl3_cbc_digest_record(const EVP_MD *md, unsigned char *md_out, size_t *md_out_size, const unsigned char header[13], |