From: Antoine Salon Date: Thu, 20 Dec 2018 23:28:10 +0000 (-0800) Subject: blake2b: add EVP_MAC API X-Git-Tag: openssl-3.0.0-alpha1~2574 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=c3a261f8d31c1d04db01de36eccfe001b4ca0368 blake2b: add EVP_MAC API Signed-off-by: Antoine Salon Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/7726) --- diff --git a/crypto/blake2/blake2b_mac.c b/crypto/blake2/blake2b_mac.c new file mode 100644 index 0000000000..71b8517885 --- /dev/null +++ b/crypto/blake2/blake2b_mac.c @@ -0,0 +1,190 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_NO_BLAKE2 + +# include +# include "blake2_locl.h" +# include "internal/cryptlib.h" +# include "internal/evp_int.h" + +/* typedef EVP_MAC_IMPL */ +struct evp_mac_impl_st { + BLAKE2B_CTX ctx; + BLAKE2B_PARAM params; + unsigned char key[BLAKE2B_KEYBYTES]; +}; + +static EVP_MAC_IMPL *blake2b_mac_new(void) +{ + EVP_MAC_IMPL *macctx = OPENSSL_zalloc(sizeof(*macctx)); + if (macctx != NULL) { + blake2b_param_init(&macctx->params); + /* ctx initialization is deferred to BLAKE2b_Init() */ + } + return macctx; +} + +static void blake2b_mac_free(EVP_MAC_IMPL *macctx) +{ + if (macctx != NULL) { + OPENSSL_cleanse(macctx->key, sizeof(macctx->key)); + OPENSSL_free(macctx); + } +} + +static int blake2b_mac_copy(EVP_MAC_IMPL *dst, EVP_MAC_IMPL *src) +{ + *dst = *src; + return 1; +} + +static int blake2b_mac_init(EVP_MAC_IMPL *macctx) +{ + /* Check key has been set */ + if (macctx->params.key_length == 0) { + EVPerr(EVP_F_BLAKE2B_MAC_INIT, EVP_R_NO_KEY_SET); + return 0; + } + + return BLAKE2b_Init_key(&macctx->ctx, &macctx->params, macctx->key); +} + +static int blake2b_mac_update(EVP_MAC_IMPL *macctx, const unsigned char *data, + size_t datalen) +{ + return BLAKE2b_Update(&macctx->ctx, data, datalen); +} + +static int blake2b_mac_final(EVP_MAC_IMPL *macctx, unsigned char *out) +{ + return BLAKE2b_Final(out, &macctx->ctx); +} + +/* + * ALL Ctrl functions should be set before init(). + */ +static int blake2b_mac_ctrl(EVP_MAC_IMPL *macctx, int cmd, va_list args) +{ + const unsigned char *p; + size_t len; + size_t size; + + switch (cmd) { + case EVP_MAC_CTRL_SET_SIZE: + size = va_arg(args, size_t); + if (size < 1 || size > BLAKE2B_OUTBYTES) { + EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_NOT_XOF_OR_INVALID_LENGTH); + return 0; + } + blake2b_param_set_digest_length(&macctx->params, (uint8_t)size); + return 1; + + case EVP_MAC_CTRL_SET_KEY: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len < 1 || len > BLAKE2B_KEYBYTES) { + EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_KEY_LENGTH); + return 0; + } + blake2b_param_set_key_length(&macctx->params, (uint8_t)len); + memcpy(macctx->key, p, len); + memset(macctx->key + len, 0, BLAKE2B_KEYBYTES - len); + return 1; + + case EVP_MAC_CTRL_SET_CUSTOM: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len > BLAKE2B_PERSONALBYTES) { + EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH); + return 0; + } + blake2b_param_set_personal(&macctx->params, p, len); + return 1; + + case EVP_MAC_CTRL_SET_SALT: + p = va_arg(args, const unsigned char *); + len = va_arg(args, size_t); + if (len > BLAKE2B_SALTBYTES) { + EVPerr(EVP_F_BLAKE2B_MAC_CTRL, EVP_R_INVALID_SALT_LENGTH); + return 0; + } + blake2b_param_set_salt(&macctx->params, p, len); + return 1; + + default: + return -2; + } +} + +static int blake2b_mac_ctrl_int(EVP_MAC_IMPL *macctx, int cmd, ...) +{ + int rv; + va_list args; + + va_start(args, cmd); + rv = blake2b_mac_ctrl(macctx, cmd, args); + va_end(args); + + return rv; +} + +static int blake2b_mac_ctrl_str_cb(void *macctx, int cmd, void *buf, size_t buflen) +{ + return blake2b_mac_ctrl_int(macctx, cmd, buf, buflen); +} + +static int blake2b_mac_ctrl_str(EVP_MAC_IMPL *macctx, const char *type, + const char *value) +{ + if (value == NULL) + return 0; + + if (strcmp(type, "outlen") == 0) + return blake2b_mac_ctrl_int(macctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value)); + if (strcmp(type, "key") == 0) + return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, + value); + if (strcmp(type, "hexkey") == 0) + return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, + value); + if (strcmp(type, "custom") == 0) + return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, + value); + if (strcmp(type, "hexcustom") == 0) + return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, + value); + if (strcmp(type, "salt") == 0) + return EVP_str2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, + value); + if (strcmp(type, "hexsalt") == 0) + return EVP_hex2ctrl(blake2b_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, + value); + return -2; +} + +static size_t blake2b_mac_size(EVP_MAC_IMPL *macctx) +{ + return macctx->params.digest_length; +} + +const EVP_MAC blake2b_mac_meth = { + EVP_MAC_BLAKE2B, + blake2b_mac_new, + blake2b_mac_copy, + blake2b_mac_free, + blake2b_mac_size, + blake2b_mac_init, + blake2b_mac_update, + blake2b_mac_final, + blake2b_mac_ctrl, + blake2b_mac_ctrl_str +}; + +#endif diff --git a/crypto/blake2/build.info b/crypto/blake2/build.info index 0036f08482..c164677de7 100644 --- a/crypto/blake2/build.info +++ b/crypto/blake2/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - blake2b.c blake2s.c m_blake2b.c m_blake2s.c + blake2b.c blake2s.c blake2b_mac.c m_blake2b.c m_blake2s.c diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 0e133d6e7d..f4e0dd6ca6 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -730,6 +730,8 @@ EVP_F_ARIA_GCM_CTRL:197:aria_gcm_ctrl EVP_F_ARIA_GCM_INIT_KEY:176:aria_gcm_init_key EVP_F_ARIA_INIT_KEY:185:aria_init_key EVP_F_B64_NEW:198:b64_new +EVP_F_BLAKE2B_MAC_CTRL:220:blake2b_mac_ctrl +EVP_F_BLAKE2B_MAC_INIT:221:blake2b_mac_init EVP_F_CAMELLIA_INIT_KEY:159:camellia_init_key EVP_F_CHACHA20_POLY1305_CTRL:182:chacha20_poly1305_ctrl EVP_F_CMLL_T4_INIT_KEY:179:cmll_t4_init_key @@ -2263,6 +2265,7 @@ EVP_R_INVALID_FIPS_MODE:168:invalid fips mode EVP_R_INVALID_KEY:163:invalid key EVP_R_INVALID_KEY_LENGTH:130:invalid key length EVP_R_INVALID_OPERATION:148:invalid operation +EVP_R_INVALID_SALT_LENGTH:186:invalid salt length EVP_R_KEYGEN_FAILURE:120:keygen failure EVP_R_KEY_SETUP_FAILED:180:key setup failed EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 14e5ed6764..1e9e0338d7 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -27,6 +27,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = { {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_INIT_KEY, 0), "aria_gcm_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_INIT_KEY, 0), "aria_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_B64_NEW, 0), "b64_new"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_CTRL, 0), "blake2b_mac_ctrl"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_INIT, 0), "blake2b_mac_init"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_CAMELLIA_INIT_KEY, 0), "camellia_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_CHACHA20_POLY1305_CTRL, 0), "chacha20_poly1305_ctrl"}, @@ -226,6 +228,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH), + "invalid salt length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED), diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index 82d1a6bfb9..e0914006ce 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -128,6 +128,7 @@ struct evp_mac_st { int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value); }; +extern const EVP_MAC blake2b_mac_meth; extern const EVP_MAC cmac_meth; extern const EVP_MAC gmac_meth; extern const EVP_MAC hmac_meth; diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 940a4b11aa..0094806bd0 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1037,6 +1037,7 @@ void EVP_MAC_do_all_sorted(void (*fn) # define EVP_MAC_CTRL_SET_IV 0x07 /* unsigned char *, size_t */ # define EVP_MAC_CTRL_SET_CUSTOM 0x08 /* unsigned char *, size_t */ # define EVP_MAC_CTRL_SET_XOF 0x09 /* int */ +# define EVP_MAC_CTRL_SET_SALT 0x0a /* unsigned char *, size_t */ /* PKEY stuff */ int EVP_PKEY_decrypt_old(unsigned char *dec_key, diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index 0f78d3684c..ebea7fa674 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -32,6 +32,8 @@ int ERR_load_EVP_strings(void); # define EVP_F_ARIA_GCM_INIT_KEY 176 # define EVP_F_ARIA_INIT_KEY 185 # define EVP_F_B64_NEW 198 +# define EVP_F_BLAKE2B_MAC_CTRL 220 +# define EVP_F_BLAKE2B_MAC_INIT 221 # define EVP_F_CAMELLIA_INIT_KEY 159 # define EVP_F_CHACHA20_POLY1305_CTRL 182 # define EVP_F_CMLL_T4_INIT_KEY 179 @@ -168,6 +170,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_INVALID_KEY 163 # define EVP_R_INVALID_KEY_LENGTH 130 # define EVP_R_INVALID_OPERATION 148 +# define EVP_R_INVALID_SALT_LENGTH 186 # define EVP_R_KEYGEN_FAILURE 120 # define EVP_R_KEY_SETUP_FAILED 180 # define EVP_R_MEMORY_LIMIT_EXCEEDED 172