libressl/0081-ssl-fix-Finished-message-length-for-CTR-OMAC-ciphers.patch
Mikhail Novosyolov faac7d3eaa Add gost-new patches sponsored by ROSA Linux
TODO: add tests
2020-08-05 12:58:06 +03:00

150 lines
4.9 KiB
Diff

From 55d3c8d25a6bd5764dcafed8b899723b80fd5a92 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 1 Apr 2020 19:05:59 +0300
Subject: [PATCH 81/87] ssl: fix Finished message length for CTR-OMAC
ciphersuites
CTR-OMAC ciphersuites use 32-byte Finished messages. Generate them
properly.
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
---
src/lib/libssl/ssl_both.c | 18 ++++++++++--------
src/lib/libssl/ssl_locl.h | 5 +++--
src/lib/libssl/ssl_pkt.c | 2 +-
src/lib/libssl/t1_enc.c | 13 ++++++++++---
4 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/src/lib/libssl/ssl_both.c b/src/lib/libssl/ssl_both.c
index 488a5ff7c..8c71e580f 100644
--- a/src/lib/libssl/ssl_both.c
+++ b/src/lib/libssl/ssl_both.c
@@ -175,9 +175,12 @@ ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
md_len = TLS1_FINISH_MAC_LENGTH;
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
- if (tls1_final_finish_mac(s, sender, slen,
- S3I(s)->tmp.finish_md) != md_len)
+ md_len = tls1_final_finish_mac(s, sender, slen,
+ S3I(s)->tmp.finish_md, sizeof(S3I(s)->tmp.finish_md));
+ if (md_len == 0) {
+ SSLerror(s, ERR_R_INTERNAL_ERROR);
return (0);
+ }
S3I(s)->tmp.finish_md_len = md_len;
/* Copy finished so we can use it for renegotiation checks. */
@@ -237,7 +240,7 @@ ssl3_take_mac(SSL *s)
S3I(s)->tmp.peer_finish_md_len =
tls1_final_finish_mac(s, sender, slen,
- S3I(s)->tmp.peer_finish_md);
+ S3I(s)->tmp.peer_finish_md, sizeof(S3I(s)->tmp.peer_finish_md));
}
int
@@ -260,8 +263,6 @@ ssl3_get_finished(SSL *s, int a, int b)
}
S3I(s)->change_cipher_spec = 0;
- md_len = TLS1_FINISH_MAC_LENGTH;
-
if (n < 0) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
@@ -270,14 +271,15 @@ ssl3_get_finished(SSL *s, int a, int b)
CBS_init(&cbs, s->internal->init_msg, n);
- if (S3I(s)->tmp.peer_finish_md_len != md_len ||
- CBS_len(&cbs) != md_len) {
+ md_len = S3I(s)->tmp.peer_finish_md_len;
+
+ if (CBS_len(&cbs) != md_len) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
goto f_err;
}
- if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, CBS_len(&cbs))) {
+ if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, md_len)) {
al = SSL_AD_DECRYPT_ERROR;
SSLerror(s, SSL_R_DIGEST_CHECK_FAILED);
goto f_err;
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 87eb05999..f522abf96 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -874,7 +874,8 @@ typedef struct ssl3_state_internal_st {
/* actually only needs to be 16+20 */
unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
- /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+ /* actually only need to be 16+20 for SSLv3 and 12 for TLS
+ * 32 for GOST CTR-OMAC ciphersuites */
unsigned char finish_md[EVP_MAX_MD_SIZE*2];
int finish_md_len;
unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
@@ -1337,7 +1338,7 @@ void tls1_cleanup_key_block(SSL *s);
int tls1_change_cipher_state(SSL *s, int which);
int tls1_setup_key_block(SSL *s);
int tls1_enc(SSL *s, int snd);
-int tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *p);
+int tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out, unsigned int outlen);
int tls1_mac(SSL *ssl, unsigned char *md, int snd);
int tls1_generate_master_secret(SSL *s, unsigned char *out,
unsigned char *p, int len);
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 157dd9895..d4aebebe9 100644
--- a/src/lib/libssl/ssl_pkt.c
+++ b/src/lib/libssl/ssl_pkt.c
@@ -1388,7 +1388,7 @@ ssl3_do_change_cipher_spec(SSL *s)
}
i = tls1_final_finish_mac(s, sender, slen,
- S3I(s)->tmp.peer_finish_md);
+ S3I(s)->tmp.peer_finish_md, sizeof(S3I(s)->tmp.peer_finish_md));
if (i == 0) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
return 0;
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index a3814dd44..7e9422b51 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -926,23 +926,30 @@ tls1_enc(SSL *s, int send)
}
int
-tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out)
+tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out, unsigned int outlen)
{
unsigned char buf[EVP_MAX_MD_SIZE];
size_t hash_len;
+ int finished_len = TLS1_FINISH_MAC_LENGTH;
if (str_len < 0)
return 0;
+ if (S3I(s)->hs.new_cipher->algorithm_mkey == SSL_kGOST_KDF)
+ finished_len = 32;
+
+ if (finished_len > outlen)
+ return 0;
+
if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len))
return 0;
if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length,
str, str_len, buf, hash_len, NULL, 0, NULL, 0, NULL, 0,
- out, TLS1_FINISH_MAC_LENGTH))
+ out, finished_len))
return 0;
- return TLS1_FINISH_MAC_LENGTH;
+ return finished_len;
}
int
--
2.17.1