From 92daa9548dfd53490e6e463e4ce5185cdd766be0 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 30 Nov 2016 01:32:30 +0300 Subject: Add MAC api to support copying of instances GOST ciphersuites requires continuously computing MAC of all the previously sent or received data. The easies way to support that is to add support for copy function, that creates MAC instance with the same internal state. Signed-off-by: Dmitry Eremin-Solenikov --- lib/crypto-backend.h | 1 + lib/hash_int.c | 16 ++++++++++++++++ lib/hash_int.h | 4 ++++ lib/includes/gnutls/crypto.h | 1 + 4 files changed, 22 insertions(+) diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index f2fbba947d..f91a5387d1 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -55,6 +55,7 @@ typedef struct { gnutls_mac_output_func output; gnutls_mac_deinit_func deinit; gnutls_mac_fast_func fast; + gnutls_mac_copy_func copy; /* Not needed for registered on run-time. Only included * should define it. */ diff --git a/lib/hash_int.c b/lib/hash_int.c index fbc56b4333..61e24d5375 100644 --- a/lib/hash_int.c +++ b/lib/hash_int.c @@ -225,6 +225,7 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e, mac->setnonce = cc->setnonce; mac->output = cc->output; mac->deinit = cc->deinit; + mac->copy = cc->copy; return 0; } @@ -239,6 +240,7 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e, mac->setnonce = _gnutls_mac_ops.setnonce; mac->output = _gnutls_mac_ops.output; mac->deinit = _gnutls_mac_ops.deinit; + mac->copy = _gnutls_mac_ops.copy; if (_gnutls_mac_ops.setkey(mac->handle, key, keylen) < 0) { gnutls_assert(); @@ -249,6 +251,20 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e, return 0; } +int _gnutls_mac_copy(const mac_hd_st * handle, mac_hd_st * dst) +{ + if (handle->copy == NULL) + return gnutls_assert_val(GNUTLS_E_HASH_FAILED); + + *dst = *handle; /* copy data */ + dst->handle = handle->copy(handle->handle); + + if (dst->handle == NULL) + return GNUTLS_E_HASH_FAILED; + + return 0; +} + void _gnutls_mac_deinit(mac_hd_st * handle, void *digest) { if (handle->handle == NULL) { diff --git a/lib/hash_int.h b/lib/hash_int.h index 52fb2b01f0..8e3154daa6 100644 --- a/lib/hash_int.h +++ b/lib/hash_int.h @@ -41,6 +41,7 @@ typedef int (*nonce_func) (void *handle, const void *text, size_t size); typedef int (*output_func) (void *src_ctx, void *digest, size_t digestsize); typedef void (*hash_deinit_func) (void *handle); +typedef void *(*copy_func) (const void *handle); typedef struct { const mac_entry_st *e; @@ -62,6 +63,7 @@ typedef struct { nonce_func setnonce; output_func output; hash_deinit_func deinit; + copy_func copy; void *handle; } mac_hd_st; @@ -73,6 +75,8 @@ int _gnutls_mac_exists(gnutls_mac_algorithm_t algorithm); int _gnutls_mac_init(mac_hd_st *, const mac_entry_st * e, const void *key, int keylen); +int _gnutls_mac_copy(const mac_hd_st * handle, mac_hd_st * dst); + int _gnutls_mac_fast(gnutls_mac_algorithm_t algorithm, const void *key, int keylen, const void *text, size_t textlen, void *digest); diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h index 93a157857c..640924bed5 100644 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -208,6 +208,7 @@ typedef void (*gnutls_mac_deinit_func) (void *ctx); typedef int (*gnutls_mac_fast_func) (gnutls_mac_algorithm_t, const void *nonce, size_t nonce_size, const void *key, size_t keysize, const void *text, size_t textsize, void *digest); +typedef void *(*gnutls_mac_copy_func) (const void *ctx); int gnutls_crypto_register_mac(gnutls_mac_algorithm_t mac, -- cgit v1.2.1 From 4591181a6c06465393425e51c4c68a2a1126b8e8 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 30 Nov 2016 01:34:14 +0300 Subject: Add MAC copying support to nettle backend Signed-off-by: Dmitry Eremin-Solenikov --- lib/nettle/mac.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c index 249ff2e2d7..90789d876f 100644 --- a/lib/nettle/mac.c +++ b/lib/nettle/mac.c @@ -324,6 +324,22 @@ static int wrap_nettle_mac_init(gnutls_mac_algorithm_t algo, void **_ctx) return 0; } +static void *wrap_nettle_mac_copy(const void *_ctx) +{ + const struct nettle_mac_ctx *ctx = _ctx; + struct nettle_mac_ctx *new_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_calloc(1, sizeof(struct nettle_mac_ctx)); + if (new_ctx == NULL) + return NULL; + + memcpy(new_ctx, ctx, sizeof(*ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + static int wrap_nettle_mac_set_key(void *_ctx, const void *key, size_t keylen) { @@ -641,6 +657,7 @@ gnutls_crypto_mac_st _gnutls_mac_ops = { .deinit = wrap_nettle_mac_deinit, .fast = wrap_nettle_mac_fast, .exists = wrap_nettle_mac_exists, + .copy = wrap_nettle_mac_copy, }; gnutls_crypto_digest_st _gnutls_digest_ops = { -- cgit v1.2.1 From de42342c24ba0d4f745a4a4ba29176bb79b1a9da Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 24 Jun 2019 17:38:56 +0300 Subject: api: add gnutls_hmac_copy() function Add gnutls_hmac_copy() API to duplicate MAC handler state, which is necessary for SMB3 support. Resolves: #787 Signed-off-by: Dmitry Eremin-Solenikov --- devel/libgnutls-latest-x86_64.abi | 1 + devel/symbols.last | 1 + doc/Makefile.am | 2 ++ doc/manpages/Makefile.am | 1 + lib/crypto-api.c | 32 ++++++++++++++++++++++++++++++++ lib/includes/gnutls/crypto.h | 1 + lib/libgnutls.map | 1 + 7 files changed, 39 insertions(+) diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi index 11c4174508..c63a68d94e 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -309,6 +309,7 @@ + diff --git a/devel/symbols.last b/devel/symbols.last index c2287e0f53..e3d5fa22a5 100644 --- a/devel/symbols.last +++ b/devel/symbols.last @@ -279,6 +279,7 @@ gnutls_hex_decode@GNUTLS_3_4 gnutls_hex_encode2@GNUTLS_3_4 gnutls_hex_encode@GNUTLS_3_4 gnutls_hmac@GNUTLS_3_4 +gnutls_hmac_copy@GNUTLS_3_6_9 gnutls_hmac_deinit@GNUTLS_3_4 gnutls_hmac_fast@GNUTLS_3_4 gnutls_hmac_get_len@GNUTLS_3_4 diff --git a/doc/Makefile.am b/doc/Makefile.am index 3ab2ad0049..f5788e7618 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1113,6 +1113,8 @@ FUNCS += functions/gnutls_hex_encode2 FUNCS += functions/gnutls_hex_encode2.short FUNCS += functions/gnutls_hmac FUNCS += functions/gnutls_hmac.short +FUNCS += functions/gnutls_hmac_copy +FUNCS += functions/gnutls_hmac_copy.short FUNCS += functions/gnutls_hmac_deinit FUNCS += functions/gnutls_hmac_deinit.short FUNCS += functions/gnutls_hmac_fast diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am index 063ebcb659..d4d358ea5c 100644 --- a/doc/manpages/Makefile.am +++ b/doc/manpages/Makefile.am @@ -358,6 +358,7 @@ APIMANS += gnutls_hex_decode2.3 APIMANS += gnutls_hex_encode.3 APIMANS += gnutls_hex_encode2.3 APIMANS += gnutls_hmac.3 +APIMANS += gnutls_hmac_copy.3 APIMANS += gnutls_hmac_deinit.3 APIMANS += gnutls_hmac_fast.3 APIMANS += gnutls_hmac_get_len.3 diff --git a/lib/crypto-api.c b/lib/crypto-api.c index 0b6be4eed2..db7a08fd92 100644 --- a/lib/crypto-api.c +++ b/lib/crypto-api.c @@ -482,6 +482,38 @@ gnutls_hmac_fast(gnutls_mac_algorithm_t algorithm, digest); } +/** + * gnutls_hmac_copy: + * @handle: is a #gnutls_hmac_hd_t type + * + * This function will create a copy of MAC context, containing all its current + * state. Copying contexts for MACs registered using + * gnutls_crypto_register_mac() is not supported and will always result in an + * error. + * + * Returns: new MAC context or NULL in case of an error. + * + * Since: 3.6.9 + */ +gnutls_hmac_hd_t gnutls_hmac_copy(gnutls_hmac_hd_t handle) +{ + gnutls_hmac_hd_t dig; + + dig = gnutls_malloc(sizeof(mac_hd_st)); + if (dig == NULL) { + gnutls_assert(); + return NULL; + } + + if (_gnutls_mac_copy((const mac_hd_st *) handle, (mac_hd_st *)dig) != GNUTLS_E_SUCCESS) { + gnutls_assert(); + gnutls_free(dig); + return NULL; + } + + return dig; +} + /* HASH */ /** diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h index 640924bed5..1afadd8759 100644 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -112,6 +112,7 @@ unsigned gnutls_hmac_get_len(gnutls_mac_algorithm_t algorithm) __GNUTLS_CONST__; int gnutls_hmac_fast(gnutls_mac_algorithm_t algorithm, const void *key, size_t keylen, const void *text, size_t textlen, void *digest); +gnutls_hmac_hd_t gnutls_hmac_copy(gnutls_hmac_hd_t handle); int gnutls_hash_init(gnutls_hash_hd_t * dig, gnutls_digest_algorithm_t algorithm); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 338cae2b1b..8f504b70f0 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1290,6 +1290,7 @@ GNUTLS_3_6_9 { global: gnutls_get_system_config_file; + gnutls_hmac_copy; } GNUTLS_3_6_8; GNUTLS_FIPS140_3_4 { -- cgit v1.2.1 From 6b41d6ce9f18eac9673279db336f8c84bc839cac Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 24 Jun 2019 17:42:10 +0300 Subject: crypto-selftests: add test for gnutls_hmac_copy() Signed-off-by: Dmitry Eremin-Solenikov --- lib/crypto-selftests.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index 02e92849e9..200d98ee8d 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -1544,6 +1544,7 @@ static int test_mac(gnutls_mac_algorithm_t mac, int ret; size_t data_size; gnutls_hmac_hd_t hd; + gnutls_hmac_hd_t copy; for (i = 0; i < vectors_size; i++) { ret = gnutls_hmac_init(&hd, @@ -1560,6 +1561,14 @@ static int test_mac(gnutls_mac_algorithm_t mac, if (ret < 0) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + copy = gnutls_hmac_copy(hd); + /* Returning NULL is not an error here for the time being, but + * it might become one later */ +#if 0 + if (!copy) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); +#endif + ret = gnutls_hmac(hd, &vectors[i].plaintext[1], vectors[i].plaintext_size - 1); @@ -1582,6 +1591,25 @@ static int test_mac(gnutls_mac_algorithm_t mac, return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + + if (copy != NULL) { + ret = gnutls_hmac(copy, + &vectors[i].plaintext[1], + vectors[i].plaintext_size - 1); + if (ret < 0) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + + memset(data, 0xaa, data_size); + gnutls_hmac_deinit(copy, data); + + if (memcmp(data, vectors[i].output, + vectors[i].output_size) != 0) { + _gnutls_debug_log + ("MAC-%s copy test vector %d failed!\n", + gnutls_mac_get_name(mac), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } } _gnutls_debug_log -- cgit v1.2.1 From c034cf9f332de9f6ccb878e1b0f0355049489827 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 26 Jun 2019 11:00:39 +0300 Subject: lib: add support for gnutls_hash_copy() Add gnutls_hash_copy() function for copying message digest context. Signed-off-by: Dmitry Eremin-Solenikov --- devel/libgnutls-latest-x86_64.abi | 1 + devel/symbols.last | 1 + doc/Makefile.am | 2 ++ doc/manpages/Makefile.am | 1 + lib/crypto-api.c | 32 ++++++++++++++++++++++++++++++++ lib/crypto-backend.h | 1 + lib/crypto-selftests.c | 27 +++++++++++++++++++++++++++ lib/hash_int.c | 16 ++++++++++++++++ lib/hash_int.h | 3 +++ lib/includes/gnutls/crypto.h | 2 ++ lib/libgnutls.map | 1 + lib/nettle/mac.c | 17 +++++++++++++++++ 12 files changed, 104 insertions(+) diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi index c63a68d94e..3fa7f45238 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -292,6 +292,7 @@ + diff --git a/devel/symbols.last b/devel/symbols.last index e3d5fa22a5..e5ff89d5e4 100644 --- a/devel/symbols.last +++ b/devel/symbols.last @@ -262,6 +262,7 @@ gnutls_handshake_set_private_extensions@GNUTLS_3_4 gnutls_handshake_set_random@GNUTLS_3_4 gnutls_handshake_set_timeout@GNUTLS_3_4 gnutls_hash@GNUTLS_3_4 +gnutls_hash_copy@GNUTLS_3_6_9 gnutls_hash_deinit@GNUTLS_3_4 gnutls_hash_fast@GNUTLS_3_4 gnutls_hash_get_len@GNUTLS_3_4 diff --git a/doc/Makefile.am b/doc/Makefile.am index f5788e7618..6d21d74820 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1079,6 +1079,8 @@ FUNCS += functions/gnutls_handshake_set_timeout FUNCS += functions/gnutls_handshake_set_timeout.short FUNCS += functions/gnutls_hash FUNCS += functions/gnutls_hash.short +FUNCS += functions/gnutls_hash_copy +FUNCS += functions/gnutls_hash_copy.short FUNCS += functions/gnutls_hash_deinit FUNCS += functions/gnutls_hash_deinit.short FUNCS += functions/gnutls_hash_fast diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am index d4d358ea5c..d06c180138 100644 --- a/doc/manpages/Makefile.am +++ b/doc/manpages/Makefile.am @@ -341,6 +341,7 @@ APIMANS += gnutls_handshake_set_private_extensions.3 APIMANS += gnutls_handshake_set_random.3 APIMANS += gnutls_handshake_set_timeout.3 APIMANS += gnutls_hash.3 +APIMANS += gnutls_hash_copy.3 APIMANS += gnutls_hash_deinit.3 APIMANS += gnutls_hash_fast.3 APIMANS += gnutls_hash_get_len.3 diff --git a/lib/crypto-api.c b/lib/crypto-api.c index db7a08fd92..0cd3d21723 100644 --- a/lib/crypto-api.c +++ b/lib/crypto-api.c @@ -636,6 +636,38 @@ gnutls_hash_fast(gnutls_digest_algorithm_t algorithm, return _gnutls_hash_fast(algorithm, ptext, ptext_len, digest); } +/** + * gnutls_hash_copy: + * @handle: is a #gnutls_hash_hd_t type + * + * This function will create a copy of Message Digest context, containing all + * its current state. Copying contexts for Message Digests registered using + * gnutls_crypto_register_digest() is not supported and will always result in + * an error. + * + * Returns: new Message Digest context or NULL in case of an error. + * + * Since: 3.6.9 + */ +gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle) +{ + gnutls_hash_hd_t dig; + + dig = gnutls_malloc(sizeof(digest_hd_st)); + if (dig == NULL) { + gnutls_assert(); + return NULL; + } + + if (_gnutls_hash_copy((const digest_hd_st *) handle, (digest_hd_st *)dig) != GNUTLS_E_SUCCESS) { + gnutls_assert(); + gnutls_free(dig); + return NULL; + } + + return dig; +} + /** * gnutls_key_generate: * @key: is a pointer to a #gnutls_datum_t which will contain a newly diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index f91a5387d1..43124abafb 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -68,6 +68,7 @@ typedef struct { gnutls_digest_output_func output; gnutls_digest_deinit_func deinit; gnutls_digest_fast_func fast; + gnutls_digest_copy_func copy; /* Not needed for registered on run-time. Only included * should define it. */ diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index 200d98ee8d..5110593845 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -1355,6 +1355,7 @@ static int test_digest(gnutls_digest_algorithm_t dig, int ret; size_t data_size; gnutls_hash_hd_t hd; + gnutls_hash_hd_t copy; if (_gnutls_digest_exists(dig) == 0) return 0; @@ -1371,6 +1372,14 @@ static int test_digest(gnutls_digest_algorithm_t dig, if (ret < 0) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + copy = gnutls_hash_copy(hd); + /* Returning NULL is not an error here for the time being, but + * it might become one later */ +#if 0 + if (!copy) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); +#endif + ret = gnutls_hash(hd, &vectors[i].plaintext[1], vectors[i].plaintext_size - 1); @@ -1390,6 +1399,24 @@ static int test_digest(gnutls_digest_algorithm_t dig, gnutls_digest_get_name(dig), i); return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + + if (copy != NULL) { + ret = gnutls_hash(copy, + &vectors[i].plaintext[1], + vectors[i].plaintext_size - 1); + if (ret < 0) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + + memset(data, 0xaa, data_size); + gnutls_hash_deinit(copy, data); + + if (memcmp(data, vectors[i].output, + vectors[i].output_size) != 0) { + _gnutls_debug_log("%s copy test vector %d failed!\n", + gnutls_digest_get_name(dig), i); + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } } _gnutls_debug_log("%s self check succeeded\n", diff --git a/lib/hash_int.c b/lib/hash_int.c index 61e24d5375..d326960e80 100644 --- a/lib/hash_int.c +++ b/lib/hash_int.c @@ -54,6 +54,7 @@ int _gnutls_hash_init(digest_hd_st * dig, const mac_entry_st * e) dig->hash = cc->hash; dig->output = cc->output; dig->deinit = cc->deinit; + dig->copy = cc->copy; return 0; } @@ -67,6 +68,7 @@ int _gnutls_hash_init(digest_hd_st * dig, const mac_entry_st * e) dig->hash = _gnutls_digest_ops.hash; dig->output = _gnutls_digest_ops.output; dig->deinit = _gnutls_digest_ops.deinit; + dig->copy = _gnutls_digest_ops.copy; return 0; } @@ -88,6 +90,20 @@ int _gnutls_digest_exists(gnutls_digest_algorithm_t algo) return _gnutls_digest_ops.exists(algo); } +int _gnutls_hash_copy(const digest_hd_st * handle, digest_hd_st * dst) +{ + if (handle->copy == NULL) + return gnutls_assert_val(GNUTLS_E_HASH_FAILED); + + *dst = *handle; /* copy data */ + dst->handle = handle->copy(handle->handle); + + if (dst->handle == NULL) + return GNUTLS_E_HASH_FAILED; + + return 0; +} + void _gnutls_hash_deinit(digest_hd_st * handle, void *digest) { if (handle->handle == NULL) { diff --git a/lib/hash_int.h b/lib/hash_int.h index 8e3154daa6..9f6059da33 100644 --- a/lib/hash_int.h +++ b/lib/hash_int.h @@ -48,6 +48,7 @@ typedef struct { hash_func hash; output_func output; hash_deinit_func deinit; + copy_func copy; const void *key; /* esoteric use by SSL3 MAC functions */ int keysize; @@ -126,6 +127,8 @@ _gnutls_hash(digest_hd_st * handle, const void *text, size_t textlen) void _gnutls_hash_deinit(digest_hd_st * handle, void *digest); +int _gnutls_hash_copy(const digest_hd_st * handle, digest_hd_st * dst); + int _gnutls_hash_fast(gnutls_digest_algorithm_t algorithm, const void *text, size_t textlen, void *digest); diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h index 1afadd8759..d2b8cae8f4 100644 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -122,6 +122,7 @@ void gnutls_hash_deinit(gnutls_hash_hd_t handle, void *digest); unsigned gnutls_hash_get_len(gnutls_digest_algorithm_t algorithm) __GNUTLS_CONST__; int gnutls_hash_fast(gnutls_digest_algorithm_t algorithm, const void *text, size_t textlen, void *digest); +gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle); /* register ciphers */ @@ -229,6 +230,7 @@ typedef int (*gnutls_digest_output_func) (void *src_ctx, void *digest, size_t di typedef void (*gnutls_digest_deinit_func) (void *ctx); typedef int (*gnutls_digest_fast_func) (gnutls_digest_algorithm_t, const void *text, size_t textsize, void *digest); +typedef void *(*gnutls_digest_copy_func) (const void *ctx); int gnutls_crypto_register_digest(gnutls_digest_algorithm_t digest, diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 8f504b70f0..0f31f4aef4 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1291,6 +1291,7 @@ GNUTLS_3_6_9 global: gnutls_get_system_config_file; gnutls_hmac_copy; + gnutls_hash_copy; } GNUTLS_3_6_8; GNUTLS_FIPS140_3_4 { diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c index 90789d876f..8107f7cea4 100644 --- a/lib/nettle/mac.c +++ b/lib/nettle/mac.c @@ -632,6 +632,22 @@ wrap_nettle_hash_init(gnutls_digest_algorithm_t algo, void **_ctx) return 0; } +static void *wrap_nettle_hash_copy(const void *_ctx) +{ + const struct nettle_hash_ctx *ctx = _ctx; + struct nettle_hash_ctx *new_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_calloc(1, sizeof(struct nettle_hash_ctx)); + if (new_ctx == NULL) + return NULL; + + memcpy(new_ctx, ctx, sizeof(*ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + static int wrap_nettle_hash_output(void *src_ctx, void *digest, size_t digestsize) { @@ -667,4 +683,5 @@ gnutls_crypto_digest_st _gnutls_digest_ops = { .deinit = wrap_nettle_hash_deinit, .fast = wrap_nettle_hash_fast, .exists = wrap_nettle_hash_exists, + .copy = wrap_nettle_hash_copy, }; -- cgit v1.2.1 From 30f860261b73a03f26da43a1898b17d185e4042c Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Wed, 26 Jun 2019 11:20:25 +0200 Subject: accelerated ciphers: implement hmac and hash copy This implements the new API to all internal implementations. Signed-off-by: Nikos Mavrogiannopoulos --- lib/accelerated/aarch64/hmac-sha-aarch64.c | 21 +++++++++++++++++++++ lib/accelerated/aarch64/sha-aarch64.c | 20 ++++++++++++++++++++ lib/accelerated/x86/hmac-padlock.c | 20 ++++++++++++++++++++ lib/accelerated/x86/hmac-x86-ssse3.c | 20 ++++++++++++++++++++ lib/accelerated/x86/sha-padlock.c | 20 ++++++++++++++++++++ lib/accelerated/x86/sha-x86-ssse3.c | 20 ++++++++++++++++++++ 6 files changed, 121 insertions(+) diff --git a/lib/accelerated/aarch64/hmac-sha-aarch64.c b/lib/accelerated/aarch64/hmac-sha-aarch64.c index d9081060c6..47d6c516ce 100644 --- a/lib/accelerated/aarch64/hmac-sha-aarch64.c +++ b/lib/accelerated/aarch64/hmac-sha-aarch64.c @@ -218,6 +218,26 @@ static int wrap_aarch64_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx) return 0; } +static void * +wrap_aarch64_hmac_copy(const void *_ctx) +{ + struct aarch64_hmac_ctx *new_ctx; + const struct aarch64_hmac_ctx *ctx=_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_malloc(sizeof(struct aarch64_hmac_ctx)); + if (new_ctx == NULL) { + gnutls_assert(); + return NULL; + } + + memcpy(new_ctx, ctx, sizeof(*new_ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + + static int wrap_aarch64_hmac_setkey(void *_ctx, const void *key, size_t keylen) { @@ -287,6 +307,7 @@ const gnutls_crypto_mac_st _gnutls_hmac_sha_aarch64 = { .setnonce = NULL, .hash = wrap_aarch64_hmac_update, .output = wrap_aarch64_hmac_output, + .copy = wrap_aarch64_hmac_copy, .deinit = wrap_aarch64_hmac_deinit, .fast = wrap_aarch64_hmac_fast, }; diff --git a/lib/accelerated/aarch64/sha-aarch64.c b/lib/accelerated/aarch64/sha-aarch64.c index 9cdf12ca3a..e4871293e5 100644 --- a/lib/accelerated/aarch64/sha-aarch64.c +++ b/lib/accelerated/aarch64/sha-aarch64.c @@ -305,6 +305,25 @@ static int wrap_aarch64_hash_init(gnutls_digest_algorithm_t algo, void **_ctx) return 0; } +static void * +wrap_aarch64_hash_copy(const void *_ctx) +{ + struct aarch64_hash_ctx *new_ctx; + const struct aarch64_hash_ctx *ctx=_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_malloc(sizeof(struct aarch64_hash_ctx)); + if (new_ctx == NULL) { + gnutls_assert(); + return NULL; + } + + memcpy(new_ctx, ctx, sizeof(*new_ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + static int wrap_aarch64_hash_output(void *src_ctx, void *digest, size_t digestsize) { @@ -352,6 +371,7 @@ const gnutls_crypto_digest_st _gnutls_sha_aarch64 = { .init = wrap_aarch64_hash_init, .hash = wrap_aarch64_hash_update, .output = wrap_aarch64_hash_output, + .copy = wrap_aarch64_hash_copy, .deinit = wrap_aarch64_hash_deinit, .fast = wrap_aarch64_hash_fast, }; diff --git a/lib/accelerated/x86/hmac-padlock.c b/lib/accelerated/x86/hmac-padlock.c index 5e1f918fa7..be6c55bc33 100644 --- a/lib/accelerated/x86/hmac-padlock.c +++ b/lib/accelerated/x86/hmac-padlock.c @@ -223,6 +223,25 @@ static int wrap_padlock_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx) return 0; } +static void * +wrap_padlock_hmac_copy(const void *_ctx) +{ + struct padlock_hmac_ctx *new_ctx; + const struct padlock_hmac_ctx *ctx=_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_malloc(sizeof(struct padlock_hmac_ctx)); + if (new_ctx == NULL) { + gnutls_assert(); + return NULL; + } + + memcpy(new_ctx, ctx, sizeof(*new_ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + static int wrap_padlock_hmac_setkey(void *_ctx, const void *key, size_t keylen) { @@ -344,6 +363,7 @@ const gnutls_crypto_mac_st _gnutls_hmac_sha_padlock_nano = { .setnonce = NULL, .hash = wrap_padlock_hmac_update, .output = wrap_padlock_hmac_output, + .copy = wrap_padlock_hmac_copy, .deinit = wrap_padlock_hmac_deinit, .fast = wrap_padlock_hmac_fast, }; diff --git a/lib/accelerated/x86/hmac-x86-ssse3.c b/lib/accelerated/x86/hmac-x86-ssse3.c index 62adf0c4ef..5a4677b405 100644 --- a/lib/accelerated/x86/hmac-x86-ssse3.c +++ b/lib/accelerated/x86/hmac-x86-ssse3.c @@ -224,6 +224,25 @@ static int wrap_x86_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx) return 0; } +static void * +wrap_x86_hmac_copy(const void *_ctx) +{ + struct x86_hmac_ctx *new_ctx; + const struct x86_hmac_ctx *ctx=_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_malloc(sizeof(struct x86_hmac_ctx)); + if (new_ctx == NULL) { + gnutls_assert(); + return NULL; + } + + memcpy(new_ctx, ctx, sizeof(*new_ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + static int wrap_x86_hmac_setkey(void *_ctx, const void *key, size_t keylen) { @@ -293,6 +312,7 @@ const gnutls_crypto_mac_st _gnutls_hmac_sha_x86_ssse3 = { .setnonce = NULL, .hash = wrap_x86_hmac_update, .output = wrap_x86_hmac_output, + .copy = wrap_x86_hmac_copy, .deinit = wrap_x86_hmac_deinit, .fast = wrap_x86_hmac_fast, }; diff --git a/lib/accelerated/x86/sha-padlock.c b/lib/accelerated/x86/sha-padlock.c index 16a63d80cb..e878ebe310 100644 --- a/lib/accelerated/x86/sha-padlock.c +++ b/lib/accelerated/x86/sha-padlock.c @@ -292,6 +292,25 @@ wrap_padlock_hash_init(gnutls_digest_algorithm_t algo, void **_ctx) return 0; } +static void * +wrap_padlock_hash_copy(const void *_ctx) +{ + struct padlock_hash_ctx *new_ctx; + const struct padlock_hash_ctx *ctx=_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_malloc(sizeof(struct padlock_hash_ctx)); + if (new_ctx == NULL) { + gnutls_assert(); + return NULL; + } + + memcpy(new_ctx, ctx, sizeof(*new_ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + static int wrap_padlock_hash_output(void *src_ctx, void *digest, size_t digestsize) { @@ -367,6 +386,7 @@ const gnutls_crypto_digest_st _gnutls_sha_padlock_nano = { .init = wrap_padlock_hash_init, .hash = wrap_padlock_hash_update, .output = wrap_padlock_hash_output, + .copy = wrap_padlock_hash_copy, .deinit = wrap_padlock_hash_deinit, .fast = wrap_padlock_hash_fast, }; diff --git a/lib/accelerated/x86/sha-x86-ssse3.c b/lib/accelerated/x86/sha-x86-ssse3.c index 5dc9da6349..b6393488cf 100644 --- a/lib/accelerated/x86/sha-x86-ssse3.c +++ b/lib/accelerated/x86/sha-x86-ssse3.c @@ -311,6 +311,25 @@ static int wrap_x86_hash_init(gnutls_digest_algorithm_t algo, void **_ctx) return 0; } +static void * +wrap_x86_hash_copy(const void *_ctx) +{ + struct x86_hash_ctx *new_ctx; + const struct x86_hash_ctx *ctx=_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_malloc(sizeof(struct x86_hash_ctx)); + if (new_ctx == NULL) { + gnutls_assert(); + return NULL; + } + + memcpy(new_ctx, ctx, sizeof(*new_ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + static int wrap_x86_hash_output(void *src_ctx, void *digest, size_t digestsize) { @@ -360,6 +379,7 @@ const gnutls_crypto_digest_st _gnutls_sha_x86_ssse3 = { .init = wrap_x86_hash_init, .hash = wrap_x86_hash_update, .output = wrap_x86_hash_output, + .copy = wrap_x86_hash_copy, .deinit = wrap_x86_hash_deinit, .fast = wrap_x86_hash_fast, }; -- cgit v1.2.1 From 5d7284a8abdcc0cfd31a8938e61510d4f0ff469d Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Wed, 26 Jun 2019 11:27:27 +0200 Subject: gnutls_hash/hmac_copy: check its usability in all cases During the test suite run we require that all supported MAC and hash algorithms implement the copy function. Signed-off-by: Nikos Mavrogiannopoulos --- lib/crypto-selftests.c | 8 ++------ tests/Makefile.am | 1 + tests/cert-tests/Makefile.am | 1 + tests/slow/Makefile.am | 1 + tests/slow/override-ciphers | 5 +++++ tests/suite/Makefile.am | 1 + tests/windows/Makefile.am | 1 + 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index 5110593845..eddf935680 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -1375,10 +1375,8 @@ static int test_digest(gnutls_digest_algorithm_t dig, copy = gnutls_hash_copy(hd); /* Returning NULL is not an error here for the time being, but * it might become one later */ -#if 0 - if (!copy) + if (!copy && secure_getenv("GNUTLS_TEST_SUITE_RUN")) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); -#endif ret = gnutls_hash(hd, &vectors[i].plaintext[1], @@ -1591,10 +1589,8 @@ static int test_mac(gnutls_mac_algorithm_t mac, copy = gnutls_hmac_copy(hd); /* Returning NULL is not an error here for the time being, but * it might become one later */ -#if 0 - if (!copy) + if (!copy && secure_getenv("GNUTLS_TEST_SUITE_RUN")) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); -#endif ret = gnutls_hmac(hd, &vectors[i].plaintext[1], diff --git a/tests/Makefile.am b/tests/Makefile.am index 62b2db75e5..98623a20c8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -571,6 +571,7 @@ TESTS_ENVIRONMENT += \ PSK_FILE=$(srcdir)/psk.passwd \ OPENSSL_ia32cap=0x00000000 \ EXEEXT=$(EXEEXT) \ + GNUTLS_TEST_SUITE_RUN=1 \ builddir="$(builddir)" \ top_builddir="$(top_builddir)" \ libdir="$(libdir)" \ diff --git a/tests/cert-tests/Makefile.am b/tests/cert-tests/Makefile.am index 06bdf42950..c34b69c40a 100644 --- a/tests/cert-tests/Makefile.am +++ b/tests/cert-tests/Makefile.am @@ -146,6 +146,7 @@ TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) \ top_builddir="$(top_builddir)" \ ac_cv_sizeof_time_t="$(ac_cv_sizeof_time_t)" \ ASAN_OPTIONS="detect_leaks=0:exitcode=6" \ + GNUTLS_TEST_SUITE_RUN=1 \ srcdir="$(srcdir)" if ENABLE_FIPS140 diff --git a/tests/slow/Makefile.am b/tests/slow/Makefile.am index 7e8e4650ca..b4c43c6aa3 100644 --- a/tests/slow/Makefile.am +++ b/tests/slow/Makefile.am @@ -65,6 +65,7 @@ EXTRA_DIST = README gnutls-asan.supp TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) \ LC_ALL="C" \ LSAN_OPTIONS=suppressions=gnutls-asan.supp \ + GNUTLS_TEST_SUITE_RUN=1 \ OPENSSL_ia32cap=0x00000000 \ top_builddir="$(top_builddir)" \ srcdir="$(srcdir)" diff --git a/tests/slow/override-ciphers b/tests/slow/override-ciphers index 2a87b7655f..3c00e5be3e 100755 --- a/tests/slow/override-ciphers +++ b/tests/slow/override-ciphers @@ -26,6 +26,11 @@ if ! test -z "${VALGRIND}"; then fi PROG=./cipher-override${EXEEXT} +# we are explicitly unsetting this variable, because we want +# the "production" checks to be triggered, not the ones in the +# test suite. + +unset GNUTLS_TEST_SUITE_RUN GNUTLS_NO_EXPLICIT_INIT=1 ${VALGRIND} ${PROG} ret=$? if test $ret != 0; then diff --git a/tests/suite/Makefile.am b/tests/suite/Makefile.am index bd3a56cc35..b4da01a375 100644 --- a/tests/suite/Makefile.am +++ b/tests/suite/Makefile.am @@ -102,6 +102,7 @@ TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) \ top_builddir="$(top_builddir)" \ srcdir="$(srcdir)" \ ASAN_OPTIONS="detect_leaks=0" \ + GNUTLS_TEST_SUITE_RUN=1 \ OPENSSL_ia32cap=0x00000000 if ENABLE_NON_SUITEB_CURVES diff --git a/tests/windows/Makefile.am b/tests/windows/Makefile.am index 86de084bb7..5a81043772 100644 --- a/tests/windows/Makefile.am +++ b/tests/windows/Makefile.am @@ -69,6 +69,7 @@ TESTS = $(ctests) $(dist_check_SCRIPTS) TESTS_ENVIRONMENT = \ WINEDLLOVERRIDES="crypt32=n,ncrypt=n" \ LC_ALL="C" \ + GNUTLS_TEST_SUITE_RUN=1 \ EXEEXT=$(EXEEXT) \ top_builddir="$(top_builddir)" \ srcdir="$(srcdir)" -- cgit v1.2.1 From 4d1967a3c48c4e54fda4e3cf996160b466188f6c Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 26 Jun 2019 14:24:42 +0300 Subject: NEWS: document gnutls_hash/hmac_copy addition Signed-off-by: Dmitry Eremin-Solenikov --- NEWS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS b/NEWS index 32236eb375..cf5b127760 100644 --- a/NEWS +++ b/NEWS @@ -34,12 +34,18 @@ See the end for copying conditions. the GNUTLS_SYSTEM_PRIORITY_FAIL_ON_INVALID environment parameter is set to 1. +** libgnutls: add gnutls_hash_copy/gnutls_hmac_copy functions that will create a copy + of digest or MAC context. Copying contexts for externally-registered digest and MAC + contexts is unupported. + ** API and ABI modifications: gnutls_get_system_config_file: Added gnutls_crypto_register_cipher: Deprecated gnutls_crypto_register_aead_cipher: Deprecated gnutls_crypto_register_digest: Deprecated gnutls_crypto_register_mac: Deprecated +gnutls_hash_copy: Added +gnutls_hmac_copy: Added * Version 3.6.8 (released 2019-05-28) -- cgit v1.2.1