diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | devel/libgnutls-latest-x86_64.abi | 3 | ||||
-rw-r--r-- | lib/algorithms/mac.c | 15 | ||||
-rw-r--r-- | lib/crypto-api.c | 3 | ||||
-rw-r--r-- | lib/crypto-selftests.c | 54 | ||||
-rw-r--r-- | lib/fips.h | 3 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 10 | ||||
-rw-r--r-- | lib/nettle/mac.c | 142 | ||||
-rw-r--r-- | lib/nettle/rnd-fips.c | 102 | ||||
-rw-r--r-- | lib/x509/x509.c | 2 | ||||
-rw-r--r-- | tests/gnutls_hmac_fast.c | 51 | ||||
-rw-r--r-- | tests/gnutls_x509_crt_list_import.c | 3 |
12 files changed, 365 insertions, 28 deletions
@@ -41,6 +41,8 @@ See the end for copying conditions. ** libgnutls: Added new flag for GNUTLS_CPUID_OVERRIDE 0x20: Enable SHA_NI instruction set +** libgnutls: Added support for AES-GMAC MAC (#781) + ** API and ABI modifications: gnutls_get_system_config_file: Added gnutls_crypto_register_cipher: Deprecated @@ -49,6 +51,9 @@ gnutls_crypto_register_digest: Deprecated gnutls_crypto_register_mac: Deprecated gnutls_hash_copy: Added gnutls_hmac_copy: Added +GNUTLS_MAC_AES_GMAC_128: Added +GNUTLS_MAC_AES_GMAC_192: Added +GNUTLS_MAC_AES_CMAC_256: 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 3fa7f45238..17e8d40663 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -1546,6 +1546,9 @@ <enumerator name='GNUTLS_MAC_UMAC_128' value='202'/> <enumerator name='GNUTLS_MAC_AES_CMAC_128' value='203'/> <enumerator name='GNUTLS_MAC_AES_CMAC_256' value='204'/> + <enumerator name='GNUTLS_MAC_AES_GMAC_128' value='205'/> + <enumerator name='GNUTLS_MAC_AES_GMAC_192' value='206'/> + <enumerator name='GNUTLS_MAC_AES_GMAC_256' value='207'/> </enum-decl> <typedef-decl name='gnutls_mac_algorithm_t' type-id='type-id-44' id='type-id-31'/> <enum-decl name='__anonymous_enum__' is-anonymous='yes' id='type-id-45'> diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c index 11847f5246..ddbba2f453 100644 --- a/lib/algorithms/mac.c +++ b/lib/algorithms/mac.c @@ -162,6 +162,21 @@ mac_entry_st hash_algorithms[] = { .id = GNUTLS_MAC_AES_CMAC_256, .output_size = 16, .key_size = 32}, + {.name = "AES-GMAC-128", + .id = GNUTLS_MAC_AES_GMAC_128, + .output_size = 16, + .key_size = 16, + .nonce_size = 12}, + {.name = "AES-GMAC-192", + .id = GNUTLS_MAC_AES_GMAC_192, + .output_size = 16, + .key_size = 24, + .nonce_size = 12}, + {.name = "AES-GMAC-256", + .id = GNUTLS_MAC_AES_GMAC_256, + .output_size = 16, + .key_size = 32, + .nonce_size = 12}, {.name = "MAC-NULL", .id = GNUTLS_MAC_NULL}, {0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/lib/crypto-api.c b/lib/crypto-api.c index 0cd3d21723..8af3f3b7dc 100644 --- a/lib/crypto-api.c +++ b/lib/crypto-api.c @@ -464,7 +464,8 @@ unsigned gnutls_hmac_get_len(gnutls_mac_algorithm_t algorithm) * @digest: is the output value of the hash * * This convenience function will hash the given data and return output - * on a single call. + * on a single call. Note, this call will not work for MAC algorithms + * that require nonce (like UMAC or GMAC). * * Returns: Zero or a negative error code on error. * diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index eddf935680..821271f22b 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -1427,6 +1427,8 @@ static int test_digest(gnutls_digest_algorithm_t dig, struct mac_vectors_st { const uint8_t *key; unsigned int key_size; + const uint8_t *nonce; + unsigned int nonce_size; const uint8_t *plaintext; unsigned int plaintext_size; const uint8_t *output; @@ -1560,6 +1562,47 @@ const struct mac_vectors_st aes_cmac_256_vectors[] = { /* NIST SP800-38A */ }, }; +const struct mac_vectors_st aes_gmac_128_vectors[] = { /* NIST test vectors */ + { + STR(key, key_size, + "\x23\x70\xe3\x20\xd4\x34\x42\x08\xe0\xff\x56\x83\xf2\x43\xb2\x13"), + STR(nonce, nonce_size, + "\x04\xdb\xb8\x2f\x04\x4d\x30\x83\x1c\x44\x12\x28"), + STR(plaintext, plaintext_size, + "\xd4\x3a\x8e\x50\x89\xee\xa0\xd0\x26\xc0\x3a\x85\x17\x8b\x27\xda"), + STR(output, output_size, + "\x2a\x04\x9c\x04\x9d\x25\xaa\x95\x96\x9b\x45\x1d\x93\xc3\x1c\x6e"), + }, +}; + +const struct mac_vectors_st aes_gmac_192_vectors[] = { /* NIST test vectors */ + { + STR(key, key_size, + "\xaa\x92\x1c\xb5\xa2\x43\xab\x08\x91\x1f\x32\x89\x26\x6b\x39\xda" + "\xb1\x33\xf5\xc4\x20\xa6\xc5\xcd"), + STR(nonce, nonce_size, + "\x8f\x73\xdb\x68\xda\xee\xed\x2d\x15\x5f\xb1\xa0"), + STR(plaintext, plaintext_size, + "\x48\x74\x43\xc7\xc1\x4c\xe4\x74\xcb\x3d\x29\x1f\x25\x70\x70\xa2"), + STR(output, output_size, + "\xb1\x26\x74\xfb\xea\xc6\x88\x9a\x24\x94\x8f\x27\x92\xe3\x0a\x50"), + }, +}; + +const struct mac_vectors_st aes_gmac_256_vectors[] = { /* NIST test vectors */ + { + STR(key, key_size, + "\x6d\xfd\xaf\xd6\x70\x3c\x28\x5c\x01\xf1\x4f\xd1\x0a\x60\x12\x86" + "\x2b\x2a\xf9\x50\xd4\x73\x3a\xbb\x40\x3b\x2e\x74\x5b\x26\x94\x5d"), + STR(nonce, nonce_size, + "\x37\x49\xd0\xb3\xd5\xba\xcb\x71\xbe\x06\xad\xe6"), + STR(plaintext, plaintext_size, + "\xc0\xd2\x49\x87\x19\x92\xe7\x03\x02\xae\x00\x81\x93\xd1\xe8\x9f"), + STR(output, output_size, + "\x4a\xa4\xcc\x69\xf8\x4e\xe6\xac\x16\xd9\xbf\xb4\xe0\x5d\xe5\x00"), + }, +}; + static int test_mac(gnutls_mac_algorithm_t mac, const struct mac_vectors_st *vectors, size_t vectors_size, unsigned flags) @@ -1582,6 +1625,11 @@ static int test_mac(gnutls_mac_algorithm_t mac, return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); } + if (vectors[i].nonce_size) + gnutls_hmac_set_nonce(hd, + vectors[i].nonce, + vectors[i].nonce_size); + ret = gnutls_hmac(hd, vectors[i].plaintext, 1); if (ret < 0) return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); @@ -1794,6 +1842,12 @@ int gnutls_mac_self_test(unsigned flags, gnutls_mac_algorithm_t mac) CASE(GNUTLS_MAC_AES_CMAC_128, test_mac, aes_cmac_128_vectors); FALLTHROUGH; CASE(GNUTLS_MAC_AES_CMAC_256, test_mac, aes_cmac_256_vectors); + FALLTHROUGH; + CASE(GNUTLS_MAC_AES_GMAC_128, test_mac, aes_gmac_128_vectors); + FALLTHROUGH; + CASE(GNUTLS_MAC_AES_GMAC_192, test_mac, aes_gmac_192_vectors); + FALLTHROUGH; + CASE(GNUTLS_MAC_AES_GMAC_256, test_mac, aes_gmac_256_vectors); break; default: diff --git a/lib/fips.h b/lib/fips.h index 7385a95de0..1464c9595b 100644 --- a/lib/fips.h +++ b/lib/fips.h @@ -107,6 +107,9 @@ static unsigned is_mac_algo_forbidden(gnutls_mac_algorithm_t algo) case GNUTLS_MAC_SHA3_512: case GNUTLS_MAC_AES_CMAC_128: case GNUTLS_MAC_AES_CMAC_256: + case GNUTLS_MAC_AES_GMAC_128: + case GNUTLS_MAC_AES_GMAC_192: + case GNUTLS_MAC_AES_GMAC_256: return 0; default: if (mode == GNUTLS_FIPS140_LAX) diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 365a582805..11652a8c2b 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -278,10 +278,13 @@ typedef enum { * @GNUTLS_MAC_STREEBOG_256: HMAC GOST R 34.11-2001 (Streebog) algorithm, 256 bit. * @GNUTLS_MAC_STREEBOG_512: HMAC GOST R 34.11-2001 (Streebog) algorithm, 512 bit. * @GNUTLS_MAC_AEAD: MAC implicit through AEAD cipher. - * @GNUTLS_MAC_UMAC_96: The UMAC-96 MAC algorithm. - * @GNUTLS_MAC_UMAC_128: The UMAC-128 MAC algorithm. + * @GNUTLS_MAC_UMAC_96: The UMAC-96 MAC algorithm (requires nonce). + * @GNUTLS_MAC_UMAC_128: The UMAC-128 MAC algorithm (requires nonce). * @GNUTLS_MAC_AES_CMAC_128: The AES-CMAC-128 MAC algorithm. * @GNUTLS_MAC_AES_CMAC_256: The AES-CMAC-256 MAC algorithm. + * @GNUTLS_MAC_AES_GMAC_128: The AES-GMAC-128 MAC algorithm (requires nonce). + * @GNUTLS_MAC_AES_GMAC_192: The AES-GMAC-192 MAC algorithm (requires nonce). + * @GNUTLS_MAC_AES_GMAC_256: The AES-GMAC-256 MAC algorithm (requires nonce). * @GNUTLS_MAC_SHA3_224: Reserved; unimplemented. * @GNUTLS_MAC_SHA3_256: Reserved; unimplemented. * @GNUTLS_MAC_SHA3_384: Reserved; unimplemented. @@ -316,6 +319,9 @@ typedef enum { GNUTLS_MAC_UMAC_128 = 202, GNUTLS_MAC_AES_CMAC_128 = 203, GNUTLS_MAC_AES_CMAC_256 = 204, + GNUTLS_MAC_AES_GMAC_128 = 205, + GNUTLS_MAC_AES_GMAC_192 = 206, + GNUTLS_MAC_AES_GMAC_256 = 207, } gnutls_mac_algorithm_t; /** diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c index 8107f7cea4..5e8bcec0a7 100644 --- a/lib/nettle/mac.c +++ b/lib/nettle/mac.c @@ -42,6 +42,7 @@ #else #include "cmac.h" #endif /* HAVE_NETTLE_CMAC128_UPDATE */ +#include <nettle/gcm.h> typedef void (*update_func) (void *, size_t, const uint8_t *); typedef void (*digest_func) (void *, size_t, uint8_t *); @@ -56,6 +57,19 @@ struct md5_sha1_ctx { struct sha1_ctx sha1; }; +struct gmac_ctx { + unsigned int pos; + uint8_t buffer[GCM_BLOCK_SIZE]; + struct gcm_key key; + struct gcm_ctx ctx; + nettle_cipher_func *encrypt; + union { + struct aes128_ctx aes128; + struct aes192_ctx aes192; + struct aes256_ctx aes256; + } cipher; +}; + struct nettle_hash_ctx { union { struct md5_ctx md5; @@ -100,6 +114,7 @@ struct nettle_mac_ctx { struct umac128_ctx umac128; struct cmac_aes128_ctx cmac128; struct cmac_aes256_ctx cmac256; + struct gmac_ctx gmac; } ctx; void *ctx_ptr; @@ -143,6 +158,88 @@ _wrap_cmac256_set_key(void *ctx, size_t len, const uint8_t * key) cmac_aes256_set_key(ctx, key); } +static void +_wrap_gmac_aes128_set_key(void *_ctx, size_t len, const uint8_t * key) +{ + struct gmac_ctx *ctx = _ctx; + + if (unlikely(len != 16)) + abort(); + aes128_set_encrypt_key(&ctx->cipher.aes128, key); + gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt); + ctx->pos = 0; +} + +static void +_wrap_gmac_aes192_set_key(void *_ctx, size_t len, const uint8_t * key) +{ + struct gmac_ctx *ctx = _ctx; + + if (unlikely(len != 24)) + abort(); + aes192_set_encrypt_key(&ctx->cipher.aes192, key); + gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt); + ctx->pos = 0; +} + +static void +_wrap_gmac_aes256_set_key(void *_ctx, size_t len, const uint8_t * key) +{ + struct gmac_ctx *ctx = _ctx; + + if (unlikely(len != 32)) + abort(); + aes256_set_encrypt_key(&ctx->cipher.aes256, key); + gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt); + ctx->pos = 0; +} + +static void _wrap_gmac_set_nonce(void *_ctx, size_t nonce_length, const uint8_t *nonce) +{ + struct gmac_ctx *ctx = _ctx; + + gcm_set_iv(&ctx->ctx, &ctx->key, nonce_length, nonce); +} + +static void _wrap_gmac_update(void *_ctx, size_t length, const uint8_t *data) +{ + struct gmac_ctx *ctx = _ctx; + + if (ctx->pos + length < GCM_BLOCK_SIZE) { + memcpy(&ctx->buffer[ctx->pos], data, length); + ctx->pos += length; + return; + } + + if (ctx->pos) { + memcpy(&ctx->buffer[ctx->pos], data, GCM_BLOCK_SIZE - ctx->pos); + gcm_update(&ctx->ctx, &ctx->key, GCM_BLOCK_SIZE, ctx->buffer); + data += GCM_BLOCK_SIZE - ctx->pos; + length -= GCM_BLOCK_SIZE - ctx->pos; + } + + if (length >= GCM_BLOCK_SIZE) { + gcm_update(&ctx->ctx, &ctx->key, + length / GCM_BLOCK_SIZE * GCM_BLOCK_SIZE, + data); + data += length / GCM_BLOCK_SIZE * GCM_BLOCK_SIZE; + length %= GCM_BLOCK_SIZE; + } + + memcpy(ctx->buffer, data, length); + ctx->pos = length; +} + +static void _wrap_gmac_digest(void *_ctx, size_t length, uint8_t *digest) +{ + struct gmac_ctx *ctx = _ctx; + + if (ctx->pos) + gcm_update(&ctx->ctx, &ctx->key, ctx->pos, ctx->buffer); + gcm_digest(&ctx->ctx, &ctx->key, &ctx->cipher, ctx->encrypt, length, digest); + ctx->pos = 0; +} + static int _mac_ctx_init(gnutls_mac_algorithm_t algo, struct nettle_mac_ctx *ctx) { @@ -246,6 +343,33 @@ static int _mac_ctx_init(gnutls_mac_algorithm_t algo, ctx->ctx_ptr = &ctx->ctx.cmac256; ctx->length = CMAC128_DIGEST_SIZE; break; + case GNUTLS_MAC_AES_GMAC_128: + ctx->set_key = _wrap_gmac_aes128_set_key; + ctx->set_nonce = _wrap_gmac_set_nonce; + ctx->update = _wrap_gmac_update; + ctx->digest = _wrap_gmac_digest; + ctx->ctx_ptr = &ctx->ctx.gmac; + ctx->length = GCM_DIGEST_SIZE; + ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes128_encrypt; + break; + case GNUTLS_MAC_AES_GMAC_192: + ctx->set_key = _wrap_gmac_aes192_set_key; + ctx->set_nonce = _wrap_gmac_set_nonce; + ctx->update = _wrap_gmac_update; + ctx->digest = _wrap_gmac_digest; + ctx->ctx_ptr = &ctx->ctx.gmac; + ctx->length = GCM_DIGEST_SIZE; + ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes192_encrypt; + break; + case GNUTLS_MAC_AES_GMAC_256: + ctx->set_key = _wrap_gmac_aes256_set_key; + ctx->set_nonce = _wrap_gmac_set_nonce; + ctx->update = _wrap_gmac_update; + ctx->digest = _wrap_gmac_digest; + ctx->ctx_ptr = &ctx->ctx.gmac; + ctx->length = GCM_DIGEST_SIZE; + ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes256_encrypt; + break; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; @@ -267,9 +391,13 @@ static int wrap_nettle_mac_fast(gnutls_mac_algorithm_t algo, if (ret < 0) return gnutls_assert_val(ret); - if (ctx.set_nonce) - ctx.set_nonce(&ctx, nonce_size, nonce); ctx.set_key(&ctx, key_size, key); + if (ctx.set_nonce) { + if (nonce == NULL || nonce_size == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + ctx.set_nonce(&ctx, nonce_size, nonce); + } ctx.update(&ctx, text_size, text); ctx.digest(&ctx, ctx.length, digest); @@ -289,6 +417,11 @@ static int wrap_nettle_mac_exists(gnutls_mac_algorithm_t algo) case GNUTLS_MAC_SHA512: case GNUTLS_MAC_UMAC_96: case GNUTLS_MAC_UMAC_128: + case GNUTLS_MAC_AES_CMAC_128: + case GNUTLS_MAC_AES_CMAC_256: + case GNUTLS_MAC_AES_GMAC_128: + case GNUTLS_MAC_AES_GMAC_192: + case GNUTLS_MAC_AES_GMAC_256: #if ENABLE_GOST case GNUTLS_MAC_GOSTR_94: case GNUTLS_MAC_STREEBOG_256: @@ -355,7 +488,10 @@ wrap_nettle_mac_set_nonce(void *_ctx, const void *nonce, size_t noncelen) struct nettle_mac_ctx *ctx = _ctx; if (ctx->set_nonce == NULL) - return GNUTLS_E_INVALID_REQUEST; + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + if (nonce == NULL || noncelen == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ctx->set_nonce(ctx->ctx_ptr, noncelen, nonce); diff --git a/lib/nettle/rnd-fips.c b/lib/nettle/rnd-fips.c index ee68cf68d5..ccb92d25a2 100644 --- a/lib/nettle/rnd-fips.c +++ b/lib/nettle/rnd-fips.c @@ -27,12 +27,13 @@ #include "gnutls_int.h" #include "errors.h" -#include <nettle/aes.h> -#include <nettle/memxor.h> -#include <locks.h> +#include <nettle/sha2.h> #include <atfork.h> #include <rnd-common.h> +/* The block size is chosen arbitrarily */ +#define ENTROPY_BLOCK_SIZE SHA256_DIGEST_SIZE + /* This provides a random generator for gnutls. It uses * two instances of the DRBG-AES-CTR generator, one for * nonce level and another for the other levels of randomness. @@ -41,11 +42,13 @@ struct fips_ctx { struct drbg_aes_ctx nonce_context; struct drbg_aes_ctx normal_context; unsigned int forkid; + uint8_t entropy_hash[SHA256_DIGEST_SIZE]; }; static int _rngfips_ctx_reinit(struct fips_ctx *fctx); static int _rngfips_ctx_init(struct fips_ctx *fctx); -static int drbg_reseed(struct drbg_aes_ctx *ctx); +static int drbg_reseed(struct fips_ctx *fctx, struct drbg_aes_ctx *ctx); +static int get_entropy(struct fips_ctx *fctx, uint8_t *buffer, size_t length); static int get_random(struct drbg_aes_ctx *ctx, struct fips_ctx *fctx, void *buffer, size_t length) @@ -59,7 +62,7 @@ static int get_random(struct drbg_aes_ctx *ctx, struct fips_ctx *fctx, } if (ctx->reseed_counter > DRBG_AES_RESEED_TIME) { - ret = drbg_reseed(ctx); + ret = drbg_reseed(fctx, ctx); if (ret < 0) return gnutls_assert_val(ret); } @@ -71,54 +74,111 @@ static int get_random(struct drbg_aes_ctx *ctx, struct fips_ctx *fctx, return 0; } +static int get_entropy(struct fips_ctx *fctx, uint8_t *buffer, size_t length) +{ + int ret; + uint8_t block[ENTROPY_BLOCK_SIZE]; + uint8_t hash[SHA256_DIGEST_SIZE]; + struct sha256_ctx ctx; + size_t total = 0; + + /* For FIPS 140-2 4.9.2 continuous random number generator + * test, iteratively fetch fixed sized block from the system + * RNG and compare consecutive blocks. + * + * Note that we store the hash of the entropy block rather + * than the block itself for backward secrecy. + */ + while (total < length) { + ret = _rnd_get_system_entropy(block, ENTROPY_BLOCK_SIZE); + if (ret < 0) + return gnutls_assert_val(ret); + + sha256_init(&ctx); + sha256_update(&ctx, sizeof(block), block); + sha256_digest(&ctx, sizeof(hash), hash); + + if (memcmp(hash, fctx->entropy_hash, sizeof(hash)) == 0) { + _gnutls_switch_lib_state(LIB_STATE_ERROR); + return gnutls_assert_val(GNUTLS_E_RANDOM_FAILED); + } + memcpy(fctx->entropy_hash, hash, sizeof(hash)); + + memcpy(buffer, block, MIN(length - total, sizeof(block))); + total += sizeof(block); + buffer += sizeof(block); + } + zeroize_key(block, sizeof(block)); + + return 0; +} + #define PSTRING "gnutls-rng" #define PSTRING_SIZE (sizeof(PSTRING)-1) -static int drbg_init(struct drbg_aes_ctx *ctx) +static int drbg_init(struct fips_ctx *fctx, struct drbg_aes_ctx *ctx) { uint8_t buffer[DRBG_AES_SEED_SIZE]; int ret; - /* Get a key from the standard RNG or from the entropy source. */ - ret = _rnd_get_system_entropy(buffer, sizeof(buffer)); + ret = get_entropy(fctx, buffer, sizeof(buffer)); if (ret < 0) return gnutls_assert_val(ret); - ret = drbg_aes_init(ctx, sizeof(buffer), buffer, PSTRING_SIZE, (void*)PSTRING); + ret = drbg_aes_init(ctx, sizeof(buffer), buffer, + PSTRING_SIZE, (void*)PSTRING); + zeroize_key(buffer, sizeof(buffer)); if (ret == 0) return gnutls_assert_val(GNUTLS_E_RANDOM_FAILED); - zeroize_key(buffer, sizeof(buffer)); - - return 0; + return GNUTLS_E_SUCCESS; } /* Reseed a generator. */ -static int drbg_reseed(struct drbg_aes_ctx *ctx) +static int drbg_reseed(struct fips_ctx *fctx, struct drbg_aes_ctx *ctx) { uint8_t buffer[DRBG_AES_SEED_SIZE]; int ret; - /* The other two generators are seeded from /dev/random. */ - ret = _rnd_get_system_entropy(buffer, sizeof(buffer)); + ret = get_entropy(fctx, buffer, sizeof(buffer)); if (ret < 0) return gnutls_assert_val(ret); - drbg_aes_reseed(ctx, sizeof(buffer), buffer, 0, NULL); + ret = drbg_aes_reseed(ctx, sizeof(buffer), buffer, 0, NULL); + zeroize_key(buffer, sizeof(buffer)); + if (ret == 0) + return gnutls_assert_val(GNUTLS_E_RANDOM_FAILED); - return 0; + return GNUTLS_E_SUCCESS; } static int _rngfips_ctx_init(struct fips_ctx *fctx) { + uint8_t block[ENTROPY_BLOCK_SIZE]; + struct sha256_ctx ctx; int ret; + /* For FIPS 140-2 4.9.2 continuous random number generator + * test, get the initial entropy from the system RNG and keep + * it for comparison. + * + * Note that we store the hash of the entropy block rather + * than the block itself for backward secrecy. + */ + ret = _rnd_get_system_entropy(block, sizeof(block)); + if (ret < 0) + return gnutls_assert_val(ret); + sha256_init(&ctx); + sha256_update(&ctx, sizeof(block), block); + zeroize_key(block, sizeof(block)); + sha256_digest(&ctx, sizeof(fctx->entropy_hash), fctx->entropy_hash); + /* normal */ - ret = drbg_init(&fctx->normal_context); + ret = drbg_init(fctx, &fctx->normal_context); if (ret < 0) return gnutls_assert_val(ret); /* nonce */ - ret = drbg_init(&fctx->nonce_context); + ret = drbg_init(fctx, &fctx->nonce_context); if (ret < 0) return gnutls_assert_val(ret); @@ -132,12 +192,12 @@ static int _rngfips_ctx_reinit(struct fips_ctx *fctx) int ret; /* normal */ - ret = drbg_reseed(&fctx->normal_context); + ret = drbg_reseed(fctx, &fctx->normal_context); if (ret < 0) return gnutls_assert_val(ret); /* nonce */ - ret = drbg_reseed(&fctx->nonce_context); + ret = drbg_reseed(fctx, &fctx->nonce_context); if (ret < 0) return gnutls_assert_val(ret); diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 44418cb45f..26055e08a3 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -3644,7 +3644,7 @@ gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt, * To deinitialize @certs, you need to deinitialize each crt structure * independently, and use gnutls_free() at @certs. * - * Returns: the number of certificates read or a negative error value. + * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. * * Since: 3.0 **/ diff --git a/tests/gnutls_hmac_fast.c b/tests/gnutls_hmac_fast.c index 604ffcd396..67b10d6283 100644 --- a/tests/gnutls_hmac_fast.c +++ b/tests/gnutls_hmac_fast.c @@ -81,6 +81,57 @@ void doit(void) } } + err = + gnutls_hmac_fast(GNUTLS_MAC_AES_GMAC_128, "keykeykeykeykeyk", 16, "abcdefghabc", 8, + digest); + if (err >= 0) + fail("gnutls_hmac_fast(GMAC-128) succeeded unexpectedly: %d\n", err); + else if (err != GNUTLS_E_INVALID_REQUEST) + fail("gnutls_hmac_fast(GMAC-128) failure: %d\n", err); + else if (debug) + success("gnutls_hmac_fast(GMAC-128) OK\n"); + + err = + gnutls_hmac_fast(GNUTLS_MAC_AES_GMAC_192, "keykeykeykeykeykeykeykey", 24, + "abcdefghabc", 8, + digest); + if (err >= 0) + fail("gnutls_hmac_fast(GMAC-192) succeeded unexpectedly: %d\n", err); + else if (err != GNUTLS_E_INVALID_REQUEST) + fail("gnutls_hmac_fast(GMAC-192) failure: %d\n", err); + else if (debug) + success("gnutls_hmac_fast(GMAC-192) OK\n"); + + err = + gnutls_hmac_fast(GNUTLS_MAC_AES_GMAC_256, "keykeykeykeykeykeykeykeykeykeyke", 32, + "abcdefghabc", 8, + digest); + if (err >= 0) + fail("gnutls_hmac_fast(GMAC-256) succeeded unexpectedly: %d\n", err); + else if (err != GNUTLS_E_INVALID_REQUEST) + fail("gnutls_hmac_fast(GMAC-256) failure: %d\n", err); + else if (debug) + success("gnutls_hmac_fast(GMAC-256) OK\n"); + + err = + gnutls_hmac_fast(GNUTLS_MAC_UMAC_96, "keykeykeykeykeyk", 16, "abcdefghabc", 8, + digest); + if (err >= 0) + fail("gnutls_hmac_fast(UMAC-96) succeeded unexpectedly: %d\n", err); + else if (err != GNUTLS_E_INVALID_REQUEST) + fail("gnutls_hmac_fast(UMAC-96) failure: %d\n", err); + else if (debug) + success("gnutls_hmac_fast(UMAC-96) OK\n"); + + err = + gnutls_hmac_fast(GNUTLS_MAC_UMAC_128, "keykeykeykeykeyk", 16, "abcdefghabc", 8, + digest); + if (err >= 0) + fail("gnutls_hmac_fast(UMAC-128) succeeded unexpectedly: %d\n", err); + else if (err != GNUTLS_E_INVALID_REQUEST) + fail("gnutls_hmac_fast(UMAC-128) failure: %d\n", err); + else if (debug) + success("gnutls_hmac_fast(UMAC-128) OK\n"); gnutls_global_deinit(); } diff --git a/tests/gnutls_x509_crt_list_import.c b/tests/gnutls_x509_crt_list_import.c index a8cad7fbf2..51fdfcb9f4 100644 --- a/tests/gnutls_x509_crt_list_import.c +++ b/tests/gnutls_x509_crt_list_import.c @@ -80,6 +80,9 @@ static void load_list(const char *name, const gnutls_datum_t *txt, if (max != ncerts) testfail("imported number (%d) doesn't match expected (%d)\n", max, ncerts); + if (ret != (int)ncerts) + testfail("imported number (%d) doesn't match return value (%d)\n", ncerts, ret); + return; } |