summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2019-10-23 15:31:05 +0000
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2019-10-23 15:31:05 +0000
commite4a7db34259295ebb32a0255215471323948efbb (patch)
tree8bf3f5d771be0e0a236db4e2b803c75aa78d3110
parent69390cc8a09fcb4167a995e570c7d2163264f4c2 (diff)
parent01942d357af587ad913154a2222e1a525501b468 (diff)
downloadgnutls-e4a7db34259295ebb32a0255215471323948efbb.tar.gz
Merge branch 'tls-continuous-mac' into 'master'
Support GOST cipher suite MAC calculation See merge request gnutls/gnutls!1098
-rw-r--r--lib/algorithms.h2
-rw-r--r--lib/algorithms/ciphers.c13
-rw-r--r--lib/algorithms/mac.c13
-rw-r--r--lib/cipher.c4
-rw-r--r--lib/cipher_int.c17
-rw-r--r--lib/cipher_int.h3
-rw-r--r--lib/crypto-api.c8
-rw-r--r--lib/gnutls_int.h12
-rw-r--r--lib/record.c2
9 files changed, 46 insertions, 28 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h
index 84271e53b8..a83fec07bb 100644
--- a/lib/algorithms.h
+++ b/lib/algorithms.h
@@ -183,7 +183,7 @@ inline static int _gnutls_digest_is_secure(const mac_entry_st * e)
if (unlikely(e == NULL))
return 0;
else
- return (e->preimage_insecure==0);
+ return !(e->flags & GNUTLS_MAC_FLAG_PREIMAGE_INSECURE);
}
/* Functions for cipher suites. */
diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c
index aab3708128..fd47c13b66 100644
--- a/lib/algorithms/ciphers.c
+++ b/lib/algorithms/ciphers.c
@@ -86,7 +86,7 @@ static const cipher_entry_st algorithms[] = {
.implicit_iv = 4,
.explicit_iv = 8,
.cipher_iv = 12,
- .only_aead = 1,
+ .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD,
.tagsize = 16},
{ .name = "AES-256-CCM",
.id = GNUTLS_CIPHER_AES_256_CCM,
@@ -96,7 +96,7 @@ static const cipher_entry_st algorithms[] = {
.implicit_iv = 4,
.explicit_iv = 8,
.cipher_iv = 12,
- .only_aead = 1,
+ .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD,
.tagsize = 16},
{ .name = "AES-128-CCM-8",
.id = GNUTLS_CIPHER_AES_128_CCM_8,
@@ -106,7 +106,7 @@ static const cipher_entry_st algorithms[] = {
.implicit_iv = 4,
.explicit_iv = 8,
.cipher_iv = 12,
- .only_aead = 1,
+ .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD,
.tagsize = 8},
{ .name = "AES-256-CCM-8",
.id = GNUTLS_CIPHER_AES_256_CCM_8,
@@ -116,7 +116,7 @@ static const cipher_entry_st algorithms[] = {
.implicit_iv = 4,
.explicit_iv = 8,
.cipher_iv = 12,
- .only_aead = 1,
+ .flags = GNUTLS_CIPHER_FLAG_ONLY_AEAD,
.tagsize = 8},
{ .name = "ARCFOUR-128",
.id = GNUTLS_CIPHER_ARCFOUR_128,
@@ -164,10 +164,9 @@ static const cipher_entry_st algorithms[] = {
.type = CIPHER_AEAD,
.implicit_iv = 12,
.explicit_iv = 0,
- .xor_nonce = 1,
- .cipher_iv = 12,
/* in chacha20 we don't need a rekey after 2^24 messages */
- .no_rekey = 1,
+ .flags = GNUTLS_CIPHER_FLAG_XOR_NONCE | GNUTLS_CIPHER_FLAG_NO_REKEY,
+ .cipher_iv = 12,
.tagsize = 16
},
{ .name = "CAMELLIA-128-GCM",
diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c
index fc2e99b186..376c76df06 100644
--- a/lib/algorithms/mac.c
+++ b/lib/algorithms/mac.c
@@ -49,7 +49,7 @@ mac_entry_st hash_algorithms[] = {
.id = GNUTLS_MAC_MD5_SHA1,
.output_size = 36,
.key_size = 36,
- .preimage_insecure = 1,
+ .flags = GNUTLS_MAC_FLAG_PREIMAGE_INSECURE,
.block_size = 64},
{.name = "SHA256",
.oid = HASH_OID_SHA256,
@@ -121,11 +121,11 @@ mac_entry_st hash_algorithms[] = {
.id = GNUTLS_MAC_MD5,
.output_size = 16,
.key_size = 16,
- .preimage_insecure = 1,
+ .flags = GNUTLS_MAC_FLAG_PREIMAGE_INSECURE,
.block_size = 64},
{.name = "MD2",
.oid = HASH_OID_MD2,
- .preimage_insecure = 1,
+ .flags = GNUTLS_MAC_FLAG_PREIMAGE_INSECURE,
.id = GNUTLS_MAC_MD2},
{.name = "RIPEMD160",
.oid = HASH_OID_RMD160,
@@ -181,7 +181,8 @@ mac_entry_st hash_algorithms[] = {
.id = GNUTLS_MAC_GOST28147_TC26Z_IMIT,
.output_size = 4,
.key_size = 32,
- .block_size = 8},
+ .block_size = 8,
+ .flags = GNUTLS_MAC_FLAG_CONTINUOUS_MAC},
{.name = "MAC-NULL",
.id = GNUTLS_MAC_NULL},
{0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -276,7 +277,7 @@ int _gnutls_digest_mark_insecure(const char *name)
for(p = hash_algorithms; p->name != NULL; p++) {
if (p->oid != NULL && c_strcasecmp(p->name, name) == 0) {
- p->preimage_insecure = 1;
+ p->flags |= GNUTLS_MAC_FLAG_PREIMAGE_INSECURE;
return 0;
}
}
@@ -291,7 +292,7 @@ unsigned _gnutls_digest_is_insecure(gnutls_digest_algorithm_t dig)
for(p = hash_algorithms; p->name != NULL; p++) {
if (p->oid != NULL && p->id == (gnutls_mac_algorithm_t)dig) {
- return p->preimage_insecure;
+ return p->flags & GNUTLS_MAC_FLAG_PREIMAGE_INSECURE;
}
}
diff --git a/lib/cipher.c b/lib/cipher.c
index 679a5807c1..b69a228db5 100644
--- a/lib/cipher.c
+++ b/lib/cipher.c
@@ -332,7 +332,7 @@ encrypt_packet(gnutls_session_t session,
cipher_data += blocksize;
}
} else { /* AEAD */
- if (params->cipher->xor_nonce == 0) {
+ if ((params->cipher->flags & GNUTLS_CIPHER_FLAG_XOR_NONCE) == 0) {
/* Values in AEAD are pretty fixed in TLS 1.2 for 128-bit block
*/
if (params->write.iv_size != imp_iv_size)
@@ -602,7 +602,7 @@ decrypt_packet(gnutls_session_t session,
if (unlikely(ciphertext->size < (tag_size + exp_iv_size)))
return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
- if (params->cipher->xor_nonce == 0) {
+ if ((params->cipher->flags & GNUTLS_CIPHER_FLAG_XOR_NONCE) == 0) {
/* Values in AEAD are pretty fixed in TLS 1.2 for 128-bit block
*/
if (unlikely(params->read.iv_size != 4))
diff --git a/lib/cipher_int.c b/lib/cipher_int.c
index 40bf64f8bc..b5308aa629 100644
--- a/lib/cipher_int.c
+++ b/lib/cipher_int.c
@@ -218,6 +218,9 @@ int _gnutls_auth_cipher_init(auth_cipher_hd_st * handle,
gnutls_assert();
goto cleanup;
}
+#ifdef ENABLE_GOST
+ handle->continuous_mac = !!(me->flags & GNUTLS_MAC_FLAG_CONTINUOUS_MAC);
+#endif
handle->tag_size = _gnutls_mac_get_algo_len(me);
} else if (_gnutls_cipher_algo_is_aead(e)) {
@@ -422,15 +425,23 @@ 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-smyshlyaev-tls12-gost-suites section 4.1.2 */
+ 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)) {
_gnutls_cipher_tag(&handle->cipher, tag, tag_size);
diff --git a/lib/cipher_int.h b/lib/cipher_int.h
index 36c9385fbf..b50a59c64a 100644
--- a/lib/cipher_int.h
+++ b/lib/cipher_int.h
@@ -211,6 +211,9 @@ typedef struct {
#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;
size_t tag_size;
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index 7308d7e7bb..d3e8094563 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -67,7 +67,7 @@ gnutls_cipher_init(gnutls_cipher_hd_t * handle,
return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
e = cipher_to_entry(cipher);
- if (e == NULL || e->only_aead)
+ if (e == NULL || (e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
*handle = gnutls_calloc(1, sizeof(api_cipher_hd_st));
@@ -1006,7 +1006,7 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- if (handle->ctx_enc.e->only_aead || handle->ctx_enc.encrypt == NULL) {
+ if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
/* ciphertext cannot be produced in a piecemeal approach */
struct iov_store_st auth;
struct iov_store_st ptext;
@@ -1130,7 +1130,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
* AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
* then this becomes a convenience function as it missed the lower-level primitives
* necessary for piecemeal encryption. */
- if (handle->ctx_enc.e->only_aead || handle->ctx_enc.encrypt == NULL) {
+ if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
/* ciphertext cannot be produced in a piecemeal approach */
struct iov_store_st auth;
struct iov_store_st ptext;
@@ -1274,7 +1274,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
* AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
* then this becomes a convenience function as it missed the lower-level primitives
* necessary for piecemeal encryption. */
- if (handle->ctx_enc.e->only_aead || handle->ctx_enc.encrypt == NULL) {
+ if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
/* ciphertext cannot be produced in a piecemeal approach */
struct iov_store_st auth;
struct iov_store_st ctext;
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 7f7b6a7c97..5f1a915a14 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -645,6 +645,10 @@ typedef struct record_state_st record_state_st;
struct record_parameters_st;
typedef struct record_parameters_st record_parameters_st;
+#define GNUTLS_CIPHER_FLAG_ONLY_AEAD (1 << 0) /* When set, this cipher is only available through the new AEAD API */
+#define GNUTLS_CIPHER_FLAG_XOR_NONCE (1 << 1) /* In this TLS AEAD cipher xor the implicit_iv with the nonce */
+#define GNUTLS_CIPHER_FLAG_NO_REKEY (1 << 2) /* whether this tls1.3 cipher doesn't need to rekey after 2^24 messages */
+
/* cipher and mac parameters */
typedef struct cipher_entry_st {
const char *name;
@@ -656,9 +660,7 @@ typedef struct cipher_entry_st {
uint16_t explicit_iv; /* the size of explicit IV - the IV stored in record */
uint16_t cipher_iv; /* the size of IV needed by the cipher */
uint16_t tagsize;
- bool xor_nonce; /* In this TLS AEAD cipher xor the implicit_iv with the nonce */
- bool only_aead; /* When set, this cipher is only available through the new AEAD API */
- bool no_rekey; /* whether this tls1.3 cipher doesn't need to rekey after 2^24 messages */
+ unsigned flags;
} cipher_entry_st;
typedef struct gnutls_cipher_suite_entry_st {
@@ -691,6 +693,8 @@ typedef struct gnutls_group_entry_st {
unsigned tls_id; /* The RFC4492 namedCurve ID or TLS 1.3 group ID */
} gnutls_group_entry_st;
+#define GNUTLS_MAC_FLAG_PREIMAGE_INSECURE 1 /* if this algorithm should not be trusted for pre-image attacks */
+#define GNUTLS_MAC_FLAG_CONTINUOUS_MAC (1 << 1) /* if this MAC should be used in a 'continuous' way in TLS */
/* This structure is used both for MACs and digests
*/
typedef struct mac_entry_st {
@@ -703,7 +707,7 @@ typedef struct mac_entry_st {
unsigned nonce_size;
unsigned placeholder; /* if set, then not a real MAC */
unsigned block_size; /* internal block size for HMAC */
- unsigned preimage_insecure; /* if this algorithm should not be trusted for pre-image attacks */
+ unsigned flags;
} mac_entry_st;
typedef struct {
diff --git a/lib/record.c b/lib/record.c
index 5105c13fdd..ced217c245 100644
--- a/lib/record.c
+++ b/lib/record.c
@@ -584,7 +584,7 @@ _gnutls_send_tlen_int(gnutls_session_t session, content_type_t type,
(int) cipher_size);
if (vers->tls13_sem && !(session->internals.flags & GNUTLS_NO_AUTO_REKEY) &&
- !(record_params->cipher->no_rekey)) {
+ !(record_params->cipher->flags & GNUTLS_CIPHER_FLAG_NO_REKEY)) {
if (unlikely(record_state->sequence_number.i[7] == 0xfd &&
record_state->sequence_number.i[6] == 0xff &&
record_state->sequence_number.i[5] == 0xff)) {