mirror of
https://abf.rosa.ru/djam/libressl.git
synced 2025-02-23 08:02:54 +00:00
244 lines
7.4 KiB
Diff
244 lines
7.4 KiB
Diff
![]() |
From 6da2bfbafdce6ef876fe8645a01da835831f1f2a Mon Sep 17 00:00:00 2001
|
||
|
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
|
||
|
Date: Sat, 18 Apr 2020 18:42:12 +0300
|
||
|
Subject: [PATCH 87/87] ssl: add support for TLSTREE rekeying
|
||
|
|
||
|
CTR-OMAC ciphersuites use TLSTREE rekeying to change keys regularly.
|
||
|
Handle TLSTREE rekeying for those ciphersuites.
|
||
|
|
||
|
Sponsored by ROSA Linux
|
||
|
|
||
|
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
|
||
|
---
|
||
|
src/lib/libssl/s3_lib.c | 18 +++++++++++++++--
|
||
|
src/lib/libssl/ssl.h | 6 ++++++
|
||
|
src/lib/libssl/ssl_lib.c | 14 +++++++++++++
|
||
|
src/lib/libssl/ssl_locl.h | 4 ++++
|
||
|
src/lib/libssl/t1_enc.c | 42 +++++++++++++++++++++++++++++++++++++++
|
||
|
5 files changed, 82 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
|
||
|
index ba87e9101..2636cfd4f 100644
|
||
|
--- a/src/lib/libssl/s3_lib.c
|
||
|
+++ b/src/lib/libssl/s3_lib.c
|
||
|
@@ -169,6 +169,18 @@
|
||
|
*/
|
||
|
#define FIXED_NONCE_LEN(x) (((x / 2) & 0xf) << 24)
|
||
|
|
||
|
+static const TLSTREE_CONST tlstree_magma_ctr_omac = {
|
||
|
+ .c1 = UINT64_C(0xFFFFFFC000000000),
|
||
|
+ .c2 = UINT64_C(0xFFFFFFFFFE000000),
|
||
|
+ .c3 = UINT64_C(0xFFFFFFFFFFFFF000),
|
||
|
+};
|
||
|
+
|
||
|
+static const TLSTREE_CONST tlstree_kuznyechik_ctr_omac = {
|
||
|
+ .c1 = UINT64_C(0xFFFFFFFF00000000),
|
||
|
+ .c2 = UINT64_C(0xFFFFFFFFFFF80000),
|
||
|
+ .c3 = UINT64_C(0xFFFFFFFFFFFFFFC0),
|
||
|
+};
|
||
|
+
|
||
|
/* list of available SSLv3 ciphers (sorted by id) */
|
||
|
SSL_CIPHER ssl3_ciphers[] = {
|
||
|
|
||
|
@@ -1318,7 +1330,8 @@ SSL_CIPHER ssl3_ciphers[] = {
|
||
|
.algo_strength = SSL_HIGH,
|
||
|
.algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256|TLS1_NONCE_ADD_SEQUENCE,
|
||
|
.strength_bits = 256,
|
||
|
- .alg_bits = 256
|
||
|
+ .alg_bits = 256,
|
||
|
+ .tlstree = &tlstree_kuznyechik_ctr_omac,
|
||
|
},
|
||
|
|
||
|
/* Cipher C101 */
|
||
|
@@ -1334,7 +1347,8 @@ SSL_CIPHER ssl3_ciphers[] = {
|
||
|
.algo_strength = SSL_HIGH,
|
||
|
.algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256|TLS1_NONCE_ADD_SEQUENCE,
|
||
|
.strength_bits = 256,
|
||
|
- .alg_bits = 256
|
||
|
+ .alg_bits = 256,
|
||
|
+ .tlstree = &tlstree_magma_ctr_omac,
|
||
|
},
|
||
|
|
||
|
/* Cipher C102 */
|
||
|
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
|
||
|
index 1c5e174b8..a9f414224 100644
|
||
|
--- a/src/lib/libssl/ssl.h
|
||
|
+++ b/src/lib/libssl/ssl.h
|
||
|
@@ -153,6 +153,8 @@
|
||
|
|
||
|
#include <openssl/bio.h>
|
||
|
|
||
|
+#include <openssl/kdftree.h>
|
||
|
+
|
||
|
#ifndef OPENSSL_NO_DEPRECATED
|
||
|
#include <openssl/buffer.h>
|
||
|
#include <openssl/crypto.h>
|
||
|
@@ -397,6 +399,10 @@ struct ssl_cipher_st {
|
||
|
unsigned long algorithm2; /* Extra flags */
|
||
|
int strength_bits; /* Number of bits really used */
|
||
|
int alg_bits; /* Number of bits for algorithm */
|
||
|
+
|
||
|
+#ifndef OPENSSL_NO_GOST
|
||
|
+ const TLSTREE_CONST *tlstree; /* TLSTREE parameters */
|
||
|
+#endif
|
||
|
};
|
||
|
|
||
|
|
||
|
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
|
||
|
index c989d802c..a54c01dc7 100644
|
||
|
--- a/src/lib/libssl/ssl_lib.c
|
||
|
+++ b/src/lib/libssl/ssl_lib.c
|
||
|
@@ -2545,6 +2545,13 @@ ssl_clear_cipher_read_state(SSL *s)
|
||
|
free(s->internal->aead_read_ctx);
|
||
|
s->internal->aead_read_ctx = NULL;
|
||
|
}
|
||
|
+
|
||
|
+#ifndef OPENSSL_NO_GOST
|
||
|
+ if (S3I(s)->read.tlstree_cipher != NULL)
|
||
|
+ TLSTREE_CTX_free(S3I(s)->read.tlstree_cipher);
|
||
|
+ if (S3I(s)->read.tlstree_mac != NULL)
|
||
|
+ TLSTREE_CTX_free(S3I(s)->read.tlstree_mac);
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
void
|
||
|
@@ -2561,6 +2568,13 @@ ssl_clear_cipher_write_state(SSL *s)
|
||
|
free(s->internal->aead_write_ctx);
|
||
|
s->internal->aead_write_ctx = NULL;
|
||
|
}
|
||
|
+
|
||
|
+#ifndef OPENSSL_NO_GOST
|
||
|
+ if (S3I(s)->write.tlstree_cipher != NULL)
|
||
|
+ TLSTREE_CTX_free(S3I(s)->write.tlstree_cipher);
|
||
|
+ if (S3I(s)->write.tlstree_mac != NULL)
|
||
|
+ TLSTREE_CTX_free(S3I(s)->write.tlstree_mac);
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
/* Fix this function so that it takes an optional type parameter */
|
||
|
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
|
||
|
index dc291ae4f..6871b01a9 100644
|
||
|
--- a/src/lib/libssl/ssl_locl.h
|
||
|
+++ b/src/lib/libssl/ssl_locl.h
|
||
|
@@ -811,6 +811,10 @@ typedef struct ssl3_rw_state_internal_st {
|
||
|
unsigned char mac_secret[EVP_MAX_MD_SIZE];
|
||
|
int cipher_iv_size;
|
||
|
unsigned char cipher_iv[EVP_MAX_IV_LENGTH];
|
||
|
+#ifndef OPENSSL_NO_GOST
|
||
|
+ TLSTREE_CTX *tlstree_cipher;
|
||
|
+ TLSTREE_CTX *tlstree_mac;
|
||
|
+#endif
|
||
|
} SSL3_RW_STATE_INTERNAL;
|
||
|
|
||
|
typedef struct ssl3_state_internal_st {
|
||
|
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
|
||
|
index 7ed6825a1..a4219599d 100644
|
||
|
--- a/src/lib/libssl/t1_enc.c
|
||
|
+++ b/src/lib/libssl/t1_enc.c
|
||
|
@@ -411,6 +411,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
|
||
|
const EVP_MD *mac;
|
||
|
const EVP_CIPHER *mac_cipher;
|
||
|
int mac_type;
|
||
|
+ SSL3_RW_STATE_INTERNAL *rws;
|
||
|
|
||
|
cipher = S3I(s)->tmp.new_sym_enc;
|
||
|
mac = S3I(s)->tmp.new_hash;
|
||
|
@@ -426,6 +427,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
|
||
|
if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
|
||
|
goto err;
|
||
|
s->read_hash = mac_ctx;
|
||
|
+ rws = &S3I(s)->read;
|
||
|
} else {
|
||
|
/*
|
||
|
* DTLS fragments retain a pointer to the compression, cipher
|
||
|
@@ -443,6 +445,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
|
||
|
if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
|
||
|
goto err;
|
||
|
s->internal->write_hash = mac_ctx;
|
||
|
+ rws = &S3I(s)->write;
|
||
|
}
|
||
|
|
||
|
EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read);
|
||
|
@@ -465,6 +468,24 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
|
||
|
else
|
||
|
s->internal->write_mac_size = mac_size;
|
||
|
|
||
|
+#ifndef OPENSSL_NO_GOST
|
||
|
+ if (s->session->cipher->tlstree) {
|
||
|
+ rws->tlstree_cipher = TLSTREE_CTX_new();
|
||
|
+ rws->tlstree_mac = TLSTREE_CTX_new();
|
||
|
+ if (rws->tlstree_cipher == NULL ||
|
||
|
+ rws->tlstree_mac == NULL ||
|
||
|
+ !TLSTREE_Init(rws->tlstree_cipher,
|
||
|
+ s->session->cipher->tlstree,
|
||
|
+ EVP_streebog256(), NULL,
|
||
|
+ key, key_len) ||
|
||
|
+ !TLSTREE_Init(rws->tlstree_mac,
|
||
|
+ s->session->cipher->tlstree,
|
||
|
+ EVP_streebog256(), NULL,
|
||
|
+ mac_secret, mac_secret_size))
|
||
|
+ goto err;
|
||
|
+ }
|
||
|
+#endif
|
||
|
+
|
||
|
if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) {
|
||
|
int nid;
|
||
|
if (S3I(s)->hs.new_cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94)
|
||
|
@@ -904,6 +925,14 @@ tls1_enc(SSL *s, int send)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+#ifndef OPENSSL_NO_GOST
|
||
|
+ if (rws->tlstree_cipher != NULL) {
|
||
|
+ unsigned char tmp[EVP_MAX_KEY_LENGTH];
|
||
|
+ if (!TLSTREE_GET(rws->tlstree_cipher, rws->sequence, tmp) ||
|
||
|
+ !EVP_CipherInit_ex(ds, NULL, NULL, tmp, NULL, -1))
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+#endif
|
||
|
if (add_nonce) {
|
||
|
unsigned char new_iv[EVP_MAX_IV_LENGTH];
|
||
|
int iv_size = rws->cipher_iv_size;
|
||
|
@@ -974,6 +1003,7 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
|
||
|
int stream_mac = ssl->session && ssl->session->cipher ?
|
||
|
ssl->session->cipher->algorithm2 & TLS1_STREAM_MAC :
|
||
|
0;
|
||
|
+ SSL3_RW_STATE_INTERNAL *rws;
|
||
|
int t;
|
||
|
|
||
|
if (send) {
|
||
|
@@ -981,11 +1011,13 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
|
||
|
seq = &(ssl->s3->internal->write.sequence[0]);
|
||
|
hash = ssl->internal->write_hash;
|
||
|
t = ssl->internal->write_mac_size;
|
||
|
+ rws = &S3I(ssl)->write;
|
||
|
} else {
|
||
|
rec = &(ssl->s3->internal->rrec);
|
||
|
seq = &(ssl->s3->internal->read.sequence[0]);
|
||
|
hash = ssl->read_hash;
|
||
|
t = ssl->read_mac_size;
|
||
|
+ rws = &S3I(ssl)->read;
|
||
|
}
|
||
|
|
||
|
OPENSSL_assert(t >= 0);
|
||
|
@@ -1028,6 +1060,16 @@ tls1_mac(SSL *ssl, unsigned char *md, int send)
|
||
|
ssl->s3->internal->read.mac_secret_size))
|
||
|
return -1;
|
||
|
} else {
|
||
|
+#ifndef OPENSSL_NO_GOST
|
||
|
+ if (rws->tlstree_mac != NULL) {
|
||
|
+ unsigned char tmp[EVP_MAX_KEY_LENGTH];
|
||
|
+ if (mac_ctx->pctx == NULL ||
|
||
|
+ !TLSTREE_GET(rws->tlstree_mac, seq, tmp) ||
|
||
|
+ EVP_PKEY_CTX_ctrl(mac_ctx->pctx, -1, EVP_PKEY_OP_SIGNCTX,
|
||
|
+ EVP_PKEY_CTRL_SET_MAC_KEY, rws->mac_secret_size, tmp) <= 0)
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+#endif
|
||
|
EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
|
||
|
EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
|
||
|
t = EVP_DigestSignFinal(mac_ctx, md, &md_size);
|
||
|
--
|
||
|
2.17.1
|
||
|
|