From 621150042b45a60412ed44e3b00a3beca4295f05 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 18 May 2017 04:09:51 +0300 Subject: Support GOST cipher suite MAC calculation GOST ciphersuites require that MAC is calculated over _all_ packets, rather than just current packet. Add flag to auth_cipher_hd_st controlling this behaviour. Signed-off-by: Dmitry Eremin-Solenikov --- lib/cipher_int.c | 20 +++++++++++++++++--- lib/cipher_int.h | 6 ++++++ lib/constate.c | 6 ++++++ lib/gnutls_int.h | 5 +++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/cipher_int.c b/lib/cipher_int.c index bc5ba38dec..c1a670f2da 100644 --- a/lib/cipher_int.c +++ b/lib/cipher_int.c @@ -175,6 +175,9 @@ int _gnutls_auth_cipher_init(auth_cipher_hd_st * handle, unsigned etm, #ifdef ENABLE_SSL3 unsigned ssl_hmac, +#endif +#ifdef ENABLE_GOST + unsigned continuous_mac, #endif int enc) { @@ -217,6 +220,9 @@ int _gnutls_auth_cipher_init(auth_cipher_hd_st * handle, gnutls_assert(); goto cleanup; } +#ifdef ENABLE_GOST + handle->continuous_mac = continuous_mac; +#endif handle->tag_size = _gnutls_mac_get_algo_len(me); } else if (_gnutls_cipher_algo_is_aead(e)) { @@ -419,14 +425,22 @@ int _gnutls_auth_cipher_tag(auth_cipher_hd_st * handle, void *tag, { if (handle->is_mac) { #ifdef ENABLE_SSL3 - int ret; - if (handle->ssl_hmac) { - ret = + int ret = _gnutls_mac_output_ssl3(&handle->mac.dig, tag); if (ret < 0) return gnutls_assert_val(ret); } else +#endif +#ifdef ENABLE_GOST + /* draft-chudov-cryptopro-cptls-04 section-2.3 */ + if (handle->continuous_mac) { + mac_hd_st temp_mac; + int ret = _gnutls_mac_copy(&handle->mac.mac, &temp_mac); + if (ret < 0) + return gnutls_assert_val(ret); + _gnutls_mac_deinit(&temp_mac, tag); + } else #endif _gnutls_mac_output(&handle->mac.mac, tag); } else if (_gnutls_cipher_is_aead(&handle->cipher)) { diff --git a/lib/cipher_int.h b/lib/cipher_int.h index 26175dc3bd..9ea9bce23d 100644 --- a/lib/cipher_int.h +++ b/lib/cipher_int.h @@ -195,6 +195,9 @@ typedef struct { unsigned int is_mac:1; #ifdef ENABLE_SSL3 unsigned int ssl_hmac:1; +#endif +#ifdef ENABLE_GOST + unsigned int continuous_mac:1; #endif unsigned int non_null:1; unsigned int etm:1; @@ -210,6 +213,9 @@ int _gnutls_auth_cipher_init(auth_cipher_hd_st * handle, unsigned etm, #ifdef ENABLE_SSL3 unsigned ssl_hmac, +#endif +#ifdef ENABLE_GOST + unsigned continuous_mac, #endif int enc); diff --git a/lib/constate.c b/lib/constate.c index bcd996808b..e6c1011fe1 100644 --- a/lib/constate.c +++ b/lib/constate.c @@ -215,6 +215,9 @@ _gnutls_init_record_state(record_parameters_st * params, params->etm, #ifdef ENABLE_SSL3 (ver->id == GNUTLS_SSL3) ? 1 : 0, +#endif +#ifdef ENABLE_GOST + params->continuous_mac, #endif 1 - read /*1==encrypt */ ); if (ret < 0 && params->cipher->id != GNUTLS_CIPHER_NULL) @@ -259,6 +262,9 @@ _gnutls_set_cipher_suite2(gnutls_session_t session, session->security_parameters.cs = cs; params->cipher = cipher_algo; params->mac = mac_algo; +#ifdef ENABLE_GOST + params->continuous_mac = cs->flags & GNUTLS_CIPHER_SUITE_CONTINUOUS_MAC; +#endif return 0; } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index bb40364c23..6850cf0432 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -463,6 +463,7 @@ typedef struct cipher_entry_st { bool only_aead; /* When set, this cipher is only available through the new AEAD API */ } cipher_entry_st; +#define GNUTLS_CIPHER_SUITE_CONTINUOUS_MAC 1 typedef struct gnutls_cipher_suite_entry_st { const char *name; const uint8_t id[2]; @@ -474,6 +475,7 @@ typedef struct gnutls_cipher_suite_entry_st { */ gnutls_protocol_t min_dtls_version; /* DTLS min version */ gnutls_mac_algorithm_t prf; + unsigned flags; } gnutls_cipher_suite_entry_st; @@ -658,6 +660,9 @@ struct record_parameters_st { under this epoch's parameters. */ int usage_cnt; +#ifdef ENABLE_GOST + unsigned continuous_mac; +#endif }; typedef struct { -- cgit v1.2.1