summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-07-30 12:02:06 +0100
committerMatt Caswell <matt@openssl.org>2020-09-03 09:40:52 +0100
commit3fddbb264e87a8cef2903cbd7b02b8e1a39a2a99 (patch)
treec73b3bb141d21a739ae8faedcaf090e07a4fcba6 /ssl
parentb48ca22a56553f285d91da0ac9399fd5efd54589 (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.info1
-rw-r--r--ssl/record/ssl3_record.c4
-rw-r--r--ssl/s3_cbc.c56
-rw-r--r--ssl/ssl_local.h3
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],