diff options
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | devel/libgnutls-latest-x86_64.abi | 2 | ||||
-rw-r--r-- | devel/symbols.last | 2 | ||||
-rw-r--r-- | doc/Makefile.am | 4 | ||||
-rw-r--r-- | doc/manpages/Makefile.am | 2 | ||||
-rw-r--r-- | lib/accelerated/aarch64/hmac-sha-aarch64.c | 21 | ||||
-rw-r--r-- | lib/accelerated/aarch64/sha-aarch64.c | 20 | ||||
-rw-r--r-- | lib/accelerated/x86/hmac-padlock.c | 20 | ||||
-rw-r--r-- | lib/accelerated/x86/hmac-x86-ssse3.c | 20 | ||||
-rw-r--r-- | lib/accelerated/x86/sha-padlock.c | 20 | ||||
-rw-r--r-- | lib/accelerated/x86/sha-x86-ssse3.c | 20 | ||||
-rw-r--r-- | lib/crypto-api.c | 64 | ||||
-rw-r--r-- | lib/crypto-backend.h | 2 | ||||
-rw-r--r-- | lib/crypto-selftests.c | 51 | ||||
-rw-r--r-- | lib/hash_int.c | 32 | ||||
-rw-r--r-- | lib/hash_int.h | 7 | ||||
-rw-r--r-- | lib/includes/gnutls/crypto.h | 4 | ||||
-rw-r--r-- | lib/libgnutls.map | 2 | ||||
-rw-r--r-- | lib/nettle/mac.c | 34 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/cert-tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/slow/Makefile.am | 1 | ||||
-rwxr-xr-x | tests/slow/override-ciphers | 5 | ||||
-rw-r--r-- | tests/suite/Makefile.am | 1 | ||||
-rw-r--r-- | tests/windows/Makefile.am | 1 |
25 files changed, 343 insertions, 0 deletions
@@ -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) diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi index 11c4174508..3fa7f45238 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -292,6 +292,7 @@ <elf-symbol name='gnutls_handshake_set_random' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_handshake_set_timeout' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hash' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='gnutls_hash_copy' version='GNUTLS_3_6_9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hash_deinit' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hash_fast' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hash_get_len' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> @@ -309,6 +310,7 @@ <elf-symbol name='gnutls_hex_encode2' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hex_encode' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hmac' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='gnutls_hmac_copy' version='GNUTLS_3_6_9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hmac_deinit' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hmac_fast' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='gnutls_hmac_get_len' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> diff --git a/devel/symbols.last b/devel/symbols.last index c2287e0f53..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 @@ -279,6 +280,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..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 @@ -1113,6 +1115,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..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 @@ -358,6 +359,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/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, }; diff --git a/lib/crypto-api.c b/lib/crypto-api.c index 0b6be4eed2..0cd3d21723 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 */ /** @@ -605,6 +637,38 @@ gnutls_hash_fast(gnutls_digest_algorithm_t algorithm, } /** + * 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 * created key diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index f2fbba947d..43124abafb 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. */ @@ -67,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 02e92849e9..eddf935680 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,12 @@ 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 (!copy && secure_getenv("GNUTLS_TEST_SUITE_RUN")) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + ret = gnutls_hash(hd, &vectors[i].plaintext[1], vectors[i].plaintext_size - 1); @@ -1390,6 +1397,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", @@ -1544,6 +1569,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 +1586,12 @@ 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 (!copy && secure_getenv("GNUTLS_TEST_SUITE_RUN")) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + ret = gnutls_hmac(hd, &vectors[i].plaintext[1], vectors[i].plaintext_size - 1); @@ -1582,6 +1614,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 diff --git a/lib/hash_int.c b/lib/hash_int.c index fbc56b4333..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) { @@ -225,6 +241,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 +256,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 +267,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..9f6059da33 100644 --- a/lib/hash_int.h +++ b/lib/hash_int.h @@ -41,12 +41,14 @@ 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; hash_func hash; output_func output; hash_deinit_func deinit; + copy_func copy; const void *key; /* esoteric use by SSL3 MAC functions */ int keysize; @@ -62,6 +64,7 @@ typedef struct { nonce_func setnonce; output_func output; hash_deinit_func deinit; + copy_func copy; void *handle; } mac_hd_st; @@ -73,6 +76,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); @@ -122,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 93a157857c..d2b8cae8f4 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); @@ -121,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 */ @@ -208,6 +210,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, @@ -227,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 338cae2b1b..0f31f4aef4 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1290,6 +1290,8 @@ 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 249ff2e2d7..8107f7cea4 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) { @@ -616,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) { @@ -641,6 +673,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 = { @@ -650,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, }; 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)" |