diff options
Diffstat (limited to 'lib/nettle/mac.c')
-rw-r--r-- | lib/nettle/mac.c | 122 |
1 files changed, 116 insertions, 6 deletions
diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c index 25054dc267..07a218ea48 100644 --- a/lib/nettle/mac.c +++ b/lib/nettle/mac.c @@ -32,6 +32,16 @@ #include <nettle/sha3.h> #include <nettle/hmac.h> #include <nettle/umac.h> +#include <nettle/hkdf.h> +#include <nettle/pbkdf2.h> +#ifdef HAVE_NETTLE_CMAC128_UPDATE +#include <nettle/cmac.h> +#ifndef HAVE_NETTLE_CMAC64_UPDATE +#include "cmac64.h" +#endif /* HAVE_NETTLE_CMAC64_UPDATE */ +#else +#include "cmac.h" +#endif /* HAVE_NETTLE_CMAC128_UPDATE */ #if ENABLE_GOST #include "gost/hmac-gost.h" #ifndef HAVE_NETTLE_GOSTHASH94CP_UPDATE @@ -42,13 +52,10 @@ #endif #ifndef HAVE_NETTLE_GOST28147_SET_KEY #include "gost/gost28147.h" +#include "gost/cmac.h" #endif +#include "gost/cmac.h" #endif -#ifdef HAVE_NETTLE_CMAC128_UPDATE -#include <nettle/cmac.h> -#else -#include "cmac.h" -#endif /* HAVE_NETTLE_CMAC128_UPDATE */ #include <nettle/gcm.h> typedef void (*update_func) (void *, size_t, const uint8_t *); @@ -117,6 +124,8 @@ struct nettle_mac_ctx { struct hmac_streebog256_ctx streebog256; struct hmac_streebog512_ctx streebog512; struct gost28147_imit_ctx gost28147_imit; + struct cmac_magma_ctx magma; + struct cmac_kuznyechik_ctx kuznyechik; #endif struct umac96_ctx umac96; struct umac128_ctx umac128; @@ -138,8 +147,20 @@ struct nettle_mac_ctx { 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); + gost28147_imit_set_key(ctx, len, key); +} + +static void +_wrap_cmac_magma_set_key(void *ctx, size_t len, const uint8_t * key) +{ + cmac_magma_set_key(ctx, key); +} + +static void +_wrap_cmac_kuznyechik_set_key(void *ctx, size_t len, const uint8_t * key) +{ + cmac_kuznyechik_set_key(ctx, key); } #endif @@ -336,6 +357,20 @@ static int _mac_ctx_init(gnutls_mac_algorithm_t algo, ctx->ctx_ptr = &ctx->ctx.gost28147_imit; ctx->length = GOST28147_IMIT_DIGEST_SIZE; break; + case GNUTLS_MAC_MAGMA_OMAC: + ctx->update = (update_func) cmac_magma_update; + ctx->digest = (digest_func) cmac_magma_digest; + ctx->set_key = _wrap_cmac_magma_set_key; + ctx->ctx_ptr = &ctx->ctx.magma; + ctx->length = CMAC64_DIGEST_SIZE; + break; + case GNUTLS_MAC_KUZNYECHIK_OMAC: + ctx->update = (update_func) cmac_kuznyechik_update; + ctx->digest = (digest_func) cmac_kuznyechik_digest; + ctx->set_key = _wrap_cmac_kuznyechik_set_key; + ctx->ctx_ptr = &ctx->ctx.kuznyechik; + ctx->length = CMAC128_DIGEST_SIZE; + break; #endif case GNUTLS_MAC_UMAC_96: ctx->update = (update_func) umac96_update; @@ -451,6 +486,8 @@ static int wrap_nettle_mac_exists(gnutls_mac_algorithm_t algo) case GNUTLS_MAC_STREEBOG_256: case GNUTLS_MAC_STREEBOG_512: case GNUTLS_MAC_GOST28147_TC26Z_IMIT: + case GNUTLS_MAC_MAGMA_OMAC: + case GNUTLS_MAC_KUZNYECHIK_OMAC: #endif return 1; default: @@ -825,6 +862,69 @@ wrap_nettle_hash_output(void *src_ctx, void *digest, size_t digestsize) return 0; } +/* KDF functions based on MAC + */ +static int +wrap_nettle_hkdf_extract (gnutls_mac_algorithm_t mac, + const void *key, size_t keysize, + const void *salt, size_t saltsize, + void *output) +{ + struct nettle_mac_ctx ctx; + int ret; + + ret = _mac_ctx_init(mac, &ctx); + if (ret < 0) + return gnutls_assert_val(ret); + + ctx.set_key(&ctx, saltsize, salt); + hkdf_extract(&ctx.ctx, ctx.update, ctx.digest, ctx.length, + keysize, key, output); + + return 0; +} + +static int +wrap_nettle_hkdf_expand (gnutls_mac_algorithm_t mac, + const void *key, size_t keysize, + const void *info, size_t infosize, + void *output, size_t length) +{ + struct nettle_mac_ctx ctx; + int ret; + + ret = _mac_ctx_init(mac, &ctx); + if (ret < 0) + return gnutls_assert_val(ret); + + ctx.set_key(&ctx, keysize, key); + hkdf_expand(&ctx.ctx, ctx.update, ctx.digest, ctx.length, + infosize, info, length, output); + + return 0; +} + +static int +wrap_nettle_pbkdf2 (gnutls_mac_algorithm_t mac, + const void *key, size_t keysize, + const void *salt, size_t saltsize, + unsigned iter_count, + void *output, size_t length) +{ + struct nettle_mac_ctx ctx; + int ret; + + ret = _mac_ctx_init(mac, &ctx); + if (ret < 0) + return gnutls_assert_val(ret); + + ctx.set_key(&ctx, keysize, key); + pbkdf2(&ctx.ctx, ctx.update, ctx.digest, ctx.length, + iter_count, saltsize, salt, length, output); + + return 0; +} + gnutls_crypto_mac_st _gnutls_mac_ops = { .init = wrap_nettle_mac_init, .setkey = wrap_nettle_mac_set_key, @@ -846,3 +946,13 @@ gnutls_crypto_digest_st _gnutls_digest_ops = { .exists = wrap_nettle_hash_exists, .copy = wrap_nettle_hash_copy, }; + +/* These names are clashing with nettle's name mangling. */ +#undef hkdf_extract +#undef hkdf_expand +#undef pbkdf2 +gnutls_crypto_kdf_st _gnutls_kdf_ops = { + .hkdf_extract = wrap_nettle_hkdf_extract, + .hkdf_expand = wrap_nettle_hkdf_expand, + .pbkdf2 = wrap_nettle_pbkdf2, +}; |