diff options
author | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2019-09-28 18:24:56 +0000 |
---|---|---|
committer | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2019-09-28 18:24:56 +0000 |
commit | 477d44b3a3afffd05b275b9d40e4e66c6b55d68c (patch) | |
tree | c2b20e9721de325e2454ebd5e54d0b07cf7a4446 | |
parent | 320137bf17c6ba80b7b866339e9aaf9ef558ad57 (diff) | |
parent | 2902a436cb0fbb3d9706a182c87d2625fed0c3d9 (diff) | |
download | gnutls-477d44b3a3afffd05b275b9d40e4e66c6b55d68c.tar.gz |
Merge branch 'gost-split-1' into 'master'
GOST-CNT split, part 1
See merge request gnutls/gnutls!1072
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | devel/libgnutls-latest-x86_64.abi | 2 | ||||
-rw-r--r-- | lib/algorithms/ciphers.c | 7 | ||||
-rw-r--r-- | lib/algorithms/mac.c | 5 | ||||
-rw-r--r-- | lib/crypto-selftests.c | 31 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 4 | ||||
-rw-r--r-- | lib/nettle/cipher.c | 33 | ||||
-rw-r--r-- | lib/nettle/gost/gost28147.c | 184 | ||||
-rw-r--r-- | lib/nettle/gost/gost28147.h | 71 | ||||
-rw-r--r-- | lib/nettle/mac.c | 19 |
10 files changed, 363 insertions, 1 deletions
@@ -25,10 +25,16 @@ See the end for copying conditions. ** libgnutls: the server now selects the highest TLS protocol version, if TLS 1.3 is enabled and the client advertises an older protocol version first (#837). +** libgnutls: added support for GOST 28147-89 cipher in CNT (GOST counter) mode + and MAC generation based on GOST 28147-89 (IMIT). For description of the + modes see RFC 5830. S-Box is id-tc26-gost-28147-param-Z (TC26Z) defined in + RFC 7836. + ** API and ABI modifications: gnutls_aead_cipher_encryptv2: Added gnutls_aead_cipher_decryptv2: Added - +GNUTLS_CIPHER_GOST28147_TC26Z_CNT: Added +GNUTLS_MAC_GOST28147_TC26Z_IMIT: Added * Version 3.6.9 (released 2019-07-25) diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi index 49044fe938..7198fa4632 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -1492,6 +1492,7 @@ <enumerator name='GNUTLS_CIPHER_AES_256_CFB8' value='31'/> <enumerator name='GNUTLS_CIPHER_AES_128_XTS' value='32'/> <enumerator name='GNUTLS_CIPHER_AES_256_XTS' value='33'/> + <enumerator name='GNUTLS_CIPHER_GOST28147_TC26Z_CNT' value='34'/> <enumerator name='GNUTLS_CIPHER_IDEA_PGP_CFB' value='200'/> <enumerator name='GNUTLS_CIPHER_3DES_PGP_CFB' value='201'/> <enumerator name='GNUTLS_CIPHER_CAST5_PGP_CFB' value='202'/> @@ -1551,6 +1552,7 @@ <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'/> + <enumerator name='GNUTLS_MAC_GOST28147_TC26Z_IMIT' value='208'/> </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/ciphers.c b/lib/algorithms/ciphers.c index 6f503fd0b2..aab3708128 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -255,6 +255,13 @@ static const cipher_entry_st algorithms[] = { .type = CIPHER_BLOCK, .explicit_iv = 16, .cipher_iv = 16}, + { .name = "GOST28147-TC26Z-CNT", + .id = GNUTLS_CIPHER_GOST28147_TC26Z_CNT, + .blocksize = 8, + .keysize = 32, + .type = CIPHER_STREAM, + .implicit_iv = 8, + .cipher_iv = 8}, { .name = "3DES-CBC", .id = GNUTLS_CIPHER_3DES_CBC, .blocksize = 8, diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c index ddbba2f453..fc2e99b186 100644 --- a/lib/algorithms/mac.c +++ b/lib/algorithms/mac.c @@ -177,6 +177,11 @@ mac_entry_st hash_algorithms[] = { .output_size = 16, .key_size = 32, .nonce_size = 12}, + {.name = "GOST28147-TC26Z-IMIT", + .id = GNUTLS_MAC_GOST28147_TC26Z_IMIT, + .output_size = 4, + .key_size = 32, + .block_size = 8}, {.name = "MAC-NULL", .id = GNUTLS_MAC_NULL}, {0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/lib/crypto-selftests.c b/lib/crypto-selftests.c index 821271f22b..6caf817e82 100644 --- a/lib/crypto-selftests.c +++ b/lib/crypto-selftests.c @@ -511,6 +511,20 @@ const struct cipher_vectors_st gost28147_tc26z_cfb_vectors[] = { }, }; +const struct cipher_vectors_st gost28147_tc26z_cnt_vectors[] = { + { + STR(key, key_size, + "\x59\x9f\x84\xba\xc3\xf3\xd2\xf1\x60\xe1\xe3\xf2\x6a\x96\x1a\xf9" + "\x9c\x48\xb2\x4e\xbc\xbb\xbf\x7c\xd8\xf3\xac\xcd\x96\x8d\x28\x6a"), + STR(plaintext, plaintext_size, + "\x90\xa2\x39\x66\xae\x01\xb9\xa3\x52\x4e\xc8\xed\x6c\xdd\x88\x30"), + .ciphertext = (uint8_t *) + "\xe8\xb1\x4f\xc7\x30\xdc\x25\xbb\x36\xba\x64\x3c\x17\xdb\xff\x99", + STR(iv, iv_size, + "\x8d\xaf\xa8\xd1\x58\xed\x05\x8d"), + } +}; + const struct cipher_vectors_st aes128_xts_vectors[] = { { STR(key, key_size, @@ -1603,6 +1617,18 @@ const struct mac_vectors_st aes_gmac_256_vectors[] = { /* NIST test vectors */ }, }; +const struct mac_vectors_st gost28147_tc26z_imit_vectors[] = { + { + STR(key, key_size, + "\x9d\x05\xb7\x9e\x90\xca\xd0\x0a\x2c\xda\xd2\x2e\xf4\xe8\x6f\x5c" + "\xf5\xdc\x37\x68\x19\x85\xb3\xbf\xaa\x18\xc1\xc3\x05\x0a\x91\xa2"), + STR(plaintext, plaintext_size, + "\xb5\xa1\xf0\xe3\xce\x2f\x02\x1d\x67\x61\x94\x34\x5c\x41\xe3\x6e"), + STR(output, output_size, + "\x03\xe5\x67\x66"), + }, +}; + static int test_mac(gnutls_mac_algorithm_t mac, const struct mac_vectors_st *vectors, size_t vectors_size, unsigned flags) @@ -1790,6 +1816,9 @@ int gnutls_cipher_self_test(unsigned flags, gnutls_cipher_algorithm_t cipher) FALLTHROUGH; NON_FIPS_CASE(GNUTLS_CIPHER_GOST28147_TC26Z_CFB, test_cipher, gost28147_tc26z_cfb_vectors); + FALLTHROUGH; + NON_FIPS_CASE(GNUTLS_CIPHER_GOST28147_TC26Z_CNT, test_cipher, + gost28147_tc26z_cnt_vectors); #endif break; default: @@ -1837,6 +1866,8 @@ int gnutls_mac_self_test(unsigned flags, gnutls_mac_algorithm_t mac) NON_FIPS_CASE(GNUTLS_MAC_STREEBOG_512, test_mac, hmac_streebog_512_vectors); FALLTHROUGH; NON_FIPS_CASE(GNUTLS_MAC_STREEBOG_256, test_mac, hmac_streebog_256_vectors); + FALLTHROUGH; + NON_FIPS_CASE(GNUTLS_MAC_GOST28147_TC26Z_IMIT, test_mac, gost28147_tc26z_imit_vectors); #endif FALLTHROUGH; CASE(GNUTLS_MAC_AES_CMAC_128, test_mac, aes_cmac_128_vectors); diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index f5a5a66acb..6b35c44342 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -125,6 +125,7 @@ extern "C" { * The whole message needs to be provided with a single call, because * cipher-stealing requires to know where the message actually terminates * in order to be able to compute where the stealing occurs. + * @GNUTLS_CIPHER_GOST28147_TC26Z_CNT: GOST 28147-89 (Magma) cipher in CNT mode with TC26 Z S-box. * @GNUTLS_CIPHER_IDEA_PGP_CFB: IDEA in CFB mode (placeholder - unsupported). * @GNUTLS_CIPHER_3DES_PGP_CFB: 3DES in CFB mode (placeholder - unsupported). * @GNUTLS_CIPHER_CAST5_PGP_CFB: CAST5 in CFB mode (placeholder - unsupported). @@ -172,6 +173,7 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_AES_256_CFB8 = 31, GNUTLS_CIPHER_AES_128_XTS = 32, GNUTLS_CIPHER_AES_256_XTS = 33, + GNUTLS_CIPHER_GOST28147_TC26Z_CNT = 34, /* used only for PGP internals. Ignored in TLS/SSL */ @@ -289,6 +291,7 @@ typedef enum { * @GNUTLS_MAC_SHA3_256: Reserved; unimplemented. * @GNUTLS_MAC_SHA3_384: Reserved; unimplemented. * @GNUTLS_MAC_SHA3_512: Reserved; unimplemented. + * @GNUTLS_MAC_GOST28147_TC26Z_IMIT: The GOST 28147-89 working in IMIT mode with TC26 Z S-box. * * Enumeration of different Message Authentication Code (MAC) * algorithms. @@ -322,6 +325,7 @@ typedef enum { GNUTLS_MAC_AES_GMAC_128 = 205, GNUTLS_MAC_AES_GMAC_192 = 206, GNUTLS_MAC_AES_GMAC_256 = 207, + GNUTLS_MAC_GOST28147_TC26Z_IMIT = 208, } gnutls_mac_algorithm_t; /** diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c index 09032f353d..28f676a480 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -197,6 +197,25 @@ _gost28147_set_key_cpd(void *ctx, const uint8_t *key) gost28147_set_key(ctx, key); gost28147_set_param(ctx, &gost28147_param_CryptoPro_D); } + +static void +_gost28147_cnt_set_key_tc26z(void *ctx, const uint8_t *key) +{ + gost28147_cnt_init(ctx, key, &gost28147_param_TC26_Z); +} + +static void +_gost28147_cnt_set_nonce (void *ctx, size_t length, const uint8_t *nonce) +{ + gost28147_cnt_set_iv (ctx, nonce); +} + +static void +_gost28147_cnt_crypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, + const uint8_t * src) +{ + gost28147_cnt_crypt((void *)ctx->ctx_ptr, length, dst, src); +} #endif static void @@ -670,6 +689,20 @@ static const struct nettle_cipher_st builtin_ciphers[] = { .set_encrypt_key = _gost28147_set_key_cpd, .set_decrypt_key = _gost28147_set_key_cpd, }, + { + .algo = GNUTLS_CIPHER_GOST28147_TC26Z_CNT, + .block_size = GOST28147_BLOCK_SIZE, + .key_size = GOST28147_KEY_SIZE, + .encrypt_block = (nettle_cipher_func*)gost28147_encrypt, /* unused */ + .decrypt_block = (nettle_cipher_func*)gost28147_decrypt, /* unused */ + + .ctx_size = sizeof(struct gost28147_cnt_ctx), + .encrypt = _gost28147_cnt_crypt, + .decrypt = _gost28147_cnt_crypt, + .set_encrypt_key = _gost28147_cnt_set_key_tc26z, + .set_decrypt_key = _gost28147_cnt_set_key_tc26z, + .set_iv = (setiv_func)_gost28147_cnt_set_nonce, + }, #endif { .algo = GNUTLS_CIPHER_AES_128_CFB8, .block_size = AES_BLOCK_SIZE, diff --git a/lib/nettle/gost/gost28147.c b/lib/nettle/gost/gost28147.c index 0b047242f2..da8ec9ef14 100644 --- a/lib/nettle/gost/gost28147.c +++ b/lib/nettle/gost/gost28147.c @@ -2244,6 +2244,23 @@ static void gost28147_decrypt_simple (const uint32_t *key, const uint32_t *sbox, *out = l, *(out + 1) = r; } +static void gost28147_imit_simple (const uint32_t *key, const uint32_t *sbox, + const uint32_t *in, uint32_t *out) +{ + uint32_t l, r, tmp; + + r = in[0], l = in[1]; + GOST_ENCRYPT_ROUND(key[0], key[1], sbox) + GOST_ENCRYPT_ROUND(key[2], key[3], sbox) + GOST_ENCRYPT_ROUND(key[4], key[5], sbox) + GOST_ENCRYPT_ROUND(key[6], key[7], sbox) + GOST_ENCRYPT_ROUND(key[0], key[1], sbox) + GOST_ENCRYPT_ROUND(key[2], key[3], sbox) + GOST_ENCRYPT_ROUND(key[4], key[5], sbox) + GOST_ENCRYPT_ROUND(key[6], key[7], sbox) + *out = r, *(out + 1) = l; +} + static const uint32_t gost28147_key_mesh_cryptopro_data[GOST28147_KEY_SIZE / 4] = { 0x22720069, 0x2304c964, 0x96db3a8d, 0xc42ae946, @@ -2367,4 +2384,171 @@ gost28147_encrypt_for_cfb(struct gost28147_ctx *ctx, ctx->key_count += GOST28147_BLOCK_SIZE; } } + +static void +gost28147_cnt_next_iv(struct gost28147_cnt_ctx *ctx, + uint8_t *out) +{ + uint32_t block[2]; + uint32_t temp; + + if (ctx->ctx.key_meshing && ctx->ctx.key_count == 1024) + { + gost28147_key_mesh_cryptopro(&ctx->ctx); + gost28147_encrypt_simple(ctx->ctx.key, ctx->ctx.sbox, ctx->iv, ctx->iv); + ctx->ctx.key_count = 0; + } + + ctx->iv[0] += 0x01010101; + temp = ctx->iv[1] + 0x01010104; + if (temp < ctx->iv[1]) + ctx->iv[1] = temp + 1; /* Overflow */ + else + ctx->iv[1] = temp; + + gost28147_encrypt_simple(ctx->ctx.key, ctx->ctx.sbox, ctx->iv, block); + + LE_WRITE_UINT32(out + 0, block[0]); + LE_WRITE_UINT32(out + 4, block[1]); + + ctx->ctx.key_count += GOST28147_BLOCK_SIZE; +} + +void +gost28147_cnt_init(struct gost28147_cnt_ctx *ctx, + const uint8_t *key, + const struct gost28147_param *param) +{ + gost28147_set_key(&ctx->ctx, key); + gost28147_set_param(&ctx->ctx, param); + ctx->bytes = 0; +} + +void +gost28147_cnt_set_iv(struct gost28147_cnt_ctx *ctx, + const uint8_t *iv) +{ + uint32_t block[2]; + + block[0] = LE_READ_UINT32(iv + 0); + block[1] = LE_READ_UINT32(iv + 4); + + gost28147_encrypt_simple(ctx->ctx.key, ctx->ctx.sbox, block, ctx->iv); +} + +void +gost28147_cnt_crypt(struct gost28147_cnt_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src) +{ + size_t block_size = GOST28147_BLOCK_SIZE; + + if (ctx->bytes) + { + size_t part = ctx->bytes < length ? ctx->bytes : length; + memxor3(dst, src, ctx->buffer + block_size - ctx->bytes, part); + dst += part; + src += part; + length -= part; + ctx->bytes -= part; + ctx->bytes %= block_size; + } + while (length >= block_size) + { + gost28147_cnt_next_iv(ctx, ctx->buffer); + memxor3(dst, src, ctx->buffer, block_size); + length -= block_size; + src += block_size; + dst += block_size; + } + + if (length != 0) + { + gost28147_cnt_next_iv(ctx, ctx->buffer); + memxor3(dst, src, ctx->buffer, length); + ctx->bytes = block_size - length; + } +} + +void +gost28147_imit_init(struct gost28147_imit_ctx *ctx) +{ + memset(ctx->state, 0, GOST28147_BLOCK_SIZE); + ctx->index = 0; + ctx->count = 0; + gost28147_set_param(&ctx->cctx, &gost28147_param_TC26_Z); /* Default */ +} + +void +gost28147_imit_set_key(struct gost28147_imit_ctx *ctx, + size_t length, + const uint8_t *key) +{ + assert(length == GOST28147_IMIT_KEY_SIZE); + assert(key); + + _gost28147_set_key(&ctx->cctx, key); + /* Do not reset param here */ +} + +void +gost28147_imit_set_nonce(struct gost28147_imit_ctx *ctx, const uint8_t *nonce) +{ + ctx->state[0] = LE_READ_UINT32(nonce + 0); + ctx->state[1] = LE_READ_UINT32(nonce + 4); +} + +void +gost28147_imit_set_param(struct gost28147_imit_ctx *ctx, + const struct gost28147_param *param) +{ + assert(param); + gost28147_set_param(&ctx->cctx, param); +} + +static void +gost28147_imit_compress(struct gost28147_imit_ctx *ctx, + const uint8_t *data) +{ + uint32_t block[2]; + + if (ctx->cctx.key_meshing && ctx->cctx.key_count == 1024) + gost28147_key_mesh_cryptopro(&ctx->cctx); + + block[0] = LE_READ_UINT32(data + 0) ^ ctx->state[0]; + block[1] = LE_READ_UINT32(data + 4) ^ ctx->state[1]; + gost28147_imit_simple(ctx->cctx.key, ctx->cctx.sbox, block, ctx->state); + ctx->cctx.key_count += 8; +} + +void +gost28147_imit_update(struct gost28147_imit_ctx *ctx, + size_t length, + const uint8_t *data) +{ + MD_UPDATE(ctx, length, data, gost28147_imit_compress, ctx->count++); +} + +void +gost28147_imit_digest(struct gost28147_imit_ctx *ctx, + size_t length, + uint8_t *digest) +{ + assert(length <= GOST28147_IMIT_DIGEST_SIZE); + const uint8_t zero[GOST28147_IMIT_BLOCK_SIZE] = { 0 }; + + if (ctx->index) + { + assert(ctx->index < GOST28147_IMIT_BLOCK_SIZE); + gost28147_imit_update(ctx, GOST28147_IMIT_BLOCK_SIZE - ctx->index, zero); + } + + if (ctx->count == 1) + { + gost28147_imit_update(ctx, GOST28147_IMIT_BLOCK_SIZE, zero); + } + + _nettle_write_le32(length, digest, ctx->state); + gost28147_imit_init(ctx); +} #endif diff --git a/lib/nettle/gost/gost28147.h b/lib/nettle/gost/gost28147.h index 7329d2ed8b..5fbab90ef1 100644 --- a/lib/nettle/gost/gost28147.h +++ b/lib/nettle/gost/gost28147.h @@ -65,6 +65,17 @@ extern "C" { #define gost28147_encrypt_for_cfb _gnutls_gost28147_encrypt_for_cfb #define gost28147_decrypt _gnutls_gost28147_decrypt +#define gost28147_cnt_init _gnutls_gost28147_cnt_init +#define gost28147_cnt_set_iv _gnutls_gost28147_cnt_set_iv +#define gost28147_cnt_crypt _gnutls_gost28147_cnt_crypt + +#define gost28147_imit_init _gnutls_gost28147_imit_init +#define gost28147_imit_set_key _gnutls_gost28147_imit_set_key +#define gost28147_imit_set_nonce _gnutls_gost28147_imit_set_nonce +#define gost28147_imit_set_param _gnutls_gost28147_imit_set_param +#define gost28147_imit_update _gnutls_gost28147_imit_update +#define gost28147_imit_digest _gnutls_gost28147_imit_digest + #define GOST28147_KEY_SIZE 32 #define GOST28147_BLOCK_SIZE 8 @@ -115,6 +126,66 @@ gost28147_encrypt_for_cfb(struct gost28147_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src); +struct gost28147_cnt_ctx { + struct gost28147_ctx ctx; + size_t bytes; + uint32_t iv[2]; + uint8_t buffer[GOST28147_BLOCK_SIZE]; +}; + +void +gost28147_cnt_init(struct gost28147_cnt_ctx *ctx, + const uint8_t *key, + const struct gost28147_param *param); + +void +gost28147_cnt_set_iv(struct gost28147_cnt_ctx *ctx, + const uint8_t *iv); + +void +gost28147_cnt_crypt(struct gost28147_cnt_ctx *ctx, + size_t length, uint8_t *dst, + const uint8_t *src); + +#define GOST28147_IMIT_DIGEST_SIZE 4 +#define GOST28147_IMIT_BLOCK_SIZE GOST28147_BLOCK_SIZE +#define GOST28147_IMIT_KEY_SIZE GOST28147_KEY_SIZE + +struct gost28147_imit_ctx +{ + struct gost28147_ctx cctx; + uint64_t count; /* Block count */ + uint8_t block[GOST28147_IMIT_BLOCK_SIZE]; /* Block buffer */ + unsigned index; /* Into buffer */ + uint32_t state[GOST28147_IMIT_BLOCK_SIZE/4]; +}; + +void +gost28147_imit_init(struct gost28147_imit_ctx *ctx); + +void +gost28147_imit_set_key(struct gost28147_imit_ctx *ctx, + size_t length, + const uint8_t *key); + +void +gost28147_imit_set_nonce(struct gost28147_imit_ctx *ctx, + const uint8_t *nonce); + +void +gost28147_imit_set_param(struct gost28147_imit_ctx *ctx, + const struct gost28147_param *param); + +void +gost28147_imit_update(struct gost28147_imit_ctx *ctx, + size_t length, + const uint8_t *data); + +void +gost28147_imit_digest(struct gost28147_imit_ctx *ctx, + size_t length, + uint8_t *digest); + #ifdef __cplusplus } #endif diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c index b6c0bce85d..ac3140fcfb 100644 --- a/lib/nettle/mac.c +++ b/lib/nettle/mac.c @@ -39,6 +39,7 @@ #endif #ifndef HAVE_NETTLE_STREEBOG512_UPDATE #include "gost/streebog.h" +#include "gost/gost28147.h" #endif #endif #ifdef HAVE_NETTLE_CMAC128_UPDATE @@ -113,6 +114,7 @@ struct nettle_mac_ctx { struct hmac_gosthash94cp_ctx gosthash94cp; struct hmac_streebog256_ctx streebog256; struct hmac_streebog512_ctx streebog512; + struct gost28147_imit_ctx gost28147_imit; #endif struct umac96_ctx umac96; struct umac128_ctx umac128; @@ -130,6 +132,15 @@ struct nettle_mac_ctx { set_nonce_func set_nonce; }; +#if ENABLE_GOST +static void +_wrap_gost28147_imit_set_key_tc26z(void *ctx, size_t len, const uint8_t * key) +{ + gost28147_imit_set_key(ctx, len, key); + gost28147_imit_set_param(ctx, &gost28147_param_TC26_Z); +} +#endif + static void _wrap_umac96_set_key(void *ctx, size_t len, const uint8_t * key) { @@ -316,6 +327,13 @@ static int _mac_ctx_init(gnutls_mac_algorithm_t algo, ctx->ctx_ptr = &ctx->ctx.streebog512; ctx->length = STREEBOG512_DIGEST_SIZE; break; + case GNUTLS_MAC_GOST28147_TC26Z_IMIT: + ctx->update = (update_func) gost28147_imit_update; + ctx->digest = (digest_func) gost28147_imit_digest; + ctx->set_key = _wrap_gost28147_imit_set_key_tc26z; + ctx->ctx_ptr = &ctx->ctx.gost28147_imit; + ctx->length = GOST28147_IMIT_DIGEST_SIZE; + break; #endif case GNUTLS_MAC_UMAC_96: ctx->update = (update_func) umac96_update; @@ -430,6 +448,7 @@ static int wrap_nettle_mac_exists(gnutls_mac_algorithm_t algo) case GNUTLS_MAC_GOSTR_94: case GNUTLS_MAC_STREEBOG_256: case GNUTLS_MAC_STREEBOG_512: + case GNUTLS_MAC_GOST28147_TC26Z_IMIT: #endif return 1; default: |