From 33e113b0cbd9a0845f6f8a63e8aad558a897cac6 Mon Sep 17 00:00:00 2001 From: Antoine Salon Date: Thu, 20 Dec 2018 15:36:07 -0800 Subject: [PATCH] blake2: backport changes to blake2s Signed-off-by: Antoine Salon Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/7726) --- crypto/blake2/blake2_locl.h | 9 +- crypto/blake2/blake2s.c | 58 ++++++++- crypto/blake2/blake2s_mac.c | 190 ++++++++++++++++++++++++++++++ crypto/blake2/build.info | 2 +- crypto/blake2/m_blake2s.c | 8 +- crypto/err/openssl.txt | 2 + crypto/evp/c_allm.c | 1 + crypto/evp/evp_err.c | 2 + crypto/include/internal/evp_int.h | 1 + include/openssl/evperr.h | 2 + 10 files changed, 264 insertions(+), 11 deletions(-) create mode 100644 crypto/blake2/blake2s_mac.c diff --git a/crypto/blake2/blake2_locl.h b/crypto/blake2/blake2_locl.h index 96af32500d..e8c86dbd07 100644 --- a/crypto/blake2/blake2_locl.h +++ b/crypto/blake2/blake2_locl.h @@ -99,6 +99,13 @@ void blake2b_param_set_key_length(BLAKE2B_PARAM *P, uint8_t keylen); void blake2b_param_set_personal(BLAKE2B_PARAM *P, const uint8_t *personal, size_t length); void blake2b_param_set_salt(BLAKE2B_PARAM *P, const uint8_t *salt, size_t length); -int BLAKE2s_Init(BLAKE2S_CTX *c); +int BLAKE2s_Init(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P); +int BLAKE2s_Init_key(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P, const void *key); int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen); int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c); + +void blake2s_param_init(BLAKE2S_PARAM *P); +void blake2s_param_set_digest_length(BLAKE2S_PARAM *P, uint8_t outlen); +void blake2s_param_set_key_length(BLAKE2S_PARAM *P, uint8_t keylen); +void blake2s_param_set_personal(BLAKE2S_PARAM *P, const uint8_t *personal, size_t length); +void blake2s_param_set_salt(BLAKE2S_PARAM *P, const uint8_t *salt, size_t length); diff --git a/crypto/blake2/blake2s.c b/crypto/blake2/blake2s.c index 4a02778d73..94333d18c8 100644 --- a/crypto/blake2/blake2s.c +++ b/crypto/blake2/blake2s.c @@ -61,9 +61,9 @@ static ossl_inline void blake2s_init0(BLAKE2S_CTX *S) /* init xors IV with input parameter block and sets the output length */ static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P) { - const uint8_t *p = (const uint8_t *)(P); size_t i; - + const uint8_t *p = (const uint8_t *)(P); + blake2s_init0(S); S->outlen = P->digest_length; @@ -76,11 +76,8 @@ static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P) } } -/* Initialize the hashing context. Always returns 1. */ -int BLAKE2s_Init(BLAKE2S_CTX *c) +void blake2s_param_init(BLAKE2S_PARAM *P) { - BLAKE2S_PARAM P[1]; - P->digest_length = BLAKE2S_DIGEST_LENGTH; P->key_length = 0; P->fanout = 1; @@ -91,7 +88,56 @@ int BLAKE2s_Init(BLAKE2S_CTX *c) P->inner_length = 0; memset(P->salt, 0, sizeof(P->salt)); memset(P->personal, 0, sizeof(P->personal)); +} + +void blake2s_param_set_digest_length(BLAKE2S_PARAM *P, uint8_t outlen) +{ + P->digest_length = outlen; +} + +void blake2s_param_set_key_length(BLAKE2S_PARAM *P, uint8_t keylen) +{ + P->key_length = keylen; +} + +void blake2s_param_set_personal(BLAKE2S_PARAM *P, const uint8_t *personal, size_t len) +{ + memcpy(P->personal, personal, len); + memset(P->personal + len, 0, BLAKE2S_PERSONALBYTES - len); +} + +void blake2s_param_set_salt(BLAKE2S_PARAM *P, const uint8_t *salt, size_t len) +{ + memcpy(P->salt, salt, len); + memset(P->salt + len, 0, BLAKE2S_SALTBYTES - len);} + +/* + * Initialize the hashing context with the given parameter block. + * Always returns 1. + */ +int BLAKE2s_Init(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P) +{ + blake2s_init_param(c, P); + return 1; +} + +/* + * Initialize the hashing context with the given parameter block and key. + * Always returns 1. + */ +int BLAKE2s_Init_key(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P, const void *key) +{ blake2s_init_param(c, P); + + /* Pad the key to form first data block */ + { + uint8_t block[BLAKE2S_BLOCKBYTES] = {0}; + + memcpy(block, key, P->key_length); + BLAKE2s_Update(c, block, BLAKE2S_BLOCKBYTES); + OPENSSL_cleanse(block, BLAKE2S_BLOCKBYTES); + } + return 1; } diff --git a/crypto/blake2/blake2s_mac.c b/crypto/blake2/blake2s_mac.c new file mode 100644 index 0000000000..d40778cb12 --- /dev/null +++ b/crypto/blake2/blake2s_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 { + BLAKE2S_CTX ctx; + BLAKE2S_PARAM params; + unsigned char key[BLAKE2S_KEYBYTES]; +}; + +static EVP_MAC_IMPL *blake2s_mac_new(void) +{ + EVP_MAC_IMPL *macctx = OPENSSL_zalloc(sizeof(*macctx)); + if (macctx != NULL) { + blake2s_param_init(&macctx->params); + /* ctx initialization is deferred to BLAKE2s_Init() */ + } + return macctx; +} + +static void blake2s_mac_free(EVP_MAC_IMPL *macctx) +{ + if (macctx != NULL) { + OPENSSL_cleanse(macctx->key, sizeof(macctx->key)); + OPENSSL_free(macctx); + } +} + +static int blake2s_mac_copy(EVP_MAC_IMPL *dst, EVP_MAC_IMPL *src) +{ + *dst = *src; + return 1; +} + +static int blake2s_mac_init(EVP_MAC_IMPL *macctx) +{ + /* Check key has been set */ + if (macctx->params.key_length == 0) { + EVPerr(EVP_F_BLAKE2S_MAC_INIT, EVP_R_NO_KEY_SET); + return 0; + } + + return BLAKE2s_Init_key(&macctx->ctx, &macctx->params, macctx->key); +} + +static int blake2s_mac_update(EVP_MAC_IMPL *macctx, const unsigned char *data, + size_t datalen) +{ + return BLAKE2s_Update(&macctx->ctx, data, datalen); +} + +static int blake2s_mac_final(EVP_MAC_IMPL *macctx, unsigned char *out) +{ + return BLAKE2s_Final(out, &macctx->ctx); +} + +/* + * ALL Ctrl functions should be set before init(). + */ +static int blake2s_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 > BLAKE2S_OUTBYTES) { + EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_NOT_XOF_OR_INVALID_LENGTH); + return 0; + } + blake2s_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 > BLAKE2S_KEYBYTES) { + EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_KEY_LENGTH); + return 0; + } + blake2s_param_set_key_length(&macctx->params, (uint8_t)len); + memcpy(macctx->key, p, len); + memset(macctx->key + len, 0, BLAKE2S_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 > BLAKE2S_PERSONALBYTES) { + EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH); + return 0; + } + blake2s_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 > BLAKE2S_SALTBYTES) { + EVPerr(EVP_F_BLAKE2S_MAC_CTRL, EVP_R_INVALID_SALT_LENGTH); + return 0; + } + blake2s_param_set_salt(&macctx->params, p, len); + return 1; + + default: + return -2; + } +} + +static int blake2s_mac_ctrl_int(EVP_MAC_IMPL *macctx, int cmd, ...) +{ + int rv; + va_list args; + + va_start(args, cmd); + rv = blake2s_mac_ctrl(macctx, cmd, args); + va_end(args); + + return rv; +} + +static int blake2s_mac_ctrl_str_cb(void *macctx, int cmd, void *buf, size_t buflen) +{ + return blake2s_mac_ctrl_int(macctx, cmd, buf, buflen); +} + +static int blake2s_mac_ctrl_str(EVP_MAC_IMPL *macctx, const char *type, + const char *value) +{ + if (value == NULL) + return 0; + + if (strcmp(type, "outlen") == 0) + return blake2s_mac_ctrl_int(macctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value)); + if (strcmp(type, "key") == 0) + return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, + value); + if (strcmp(type, "hexkey") == 0) + return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_KEY, + value); + if (strcmp(type, "custom") == 0) + return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, + value); + if (strcmp(type, "hexcustom") == 0) + return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_CUSTOM, + value); + if (strcmp(type, "salt") == 0) + return EVP_str2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, + value); + if (strcmp(type, "hexsalt") == 0) + return EVP_hex2ctrl(blake2s_mac_ctrl_str_cb, macctx, EVP_MAC_CTRL_SET_SALT, + value); + return -2; +} + +static size_t blake2s_mac_size(EVP_MAC_IMPL *macctx) +{ + return macctx->params.digest_length; +} + +const EVP_MAC blake2s_mac_meth = { + EVP_MAC_BLAKE2S, + blake2s_mac_new, + blake2s_mac_copy, + blake2s_mac_free, + blake2s_mac_size, + blake2s_mac_init, + blake2s_mac_update, + blake2s_mac_final, + blake2s_mac_ctrl, + blake2s_mac_ctrl_str +}; + +#endif diff --git a/crypto/blake2/build.info b/crypto/blake2/build.info index c164677de7..ab72ef2aca 100644 --- a/crypto/blake2/build.info +++ b/crypto/blake2/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - blake2b.c blake2s.c blake2b_mac.c m_blake2b.c m_blake2s.c + blake2b.c blake2s.c blake2b_mac.c blake2s_mac.c m_blake2b.c m_blake2s.c diff --git a/crypto/blake2/m_blake2s.c b/crypto/blake2/m_blake2s.c index 2c5f42b2a4..8ff172751d 100644 --- a/crypto/blake2/m_blake2s.c +++ b/crypto/blake2/m_blake2s.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-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 @@ -25,7 +25,9 @@ static int init(EVP_MD_CTX *ctx) { - return BLAKE2s_Init(EVP_MD_CTX_md_data(ctx)); + BLAKE2S_PARAM P; + blake2s_param_init(&P); + return BLAKE2s_Init(EVP_MD_CTX_md_data(ctx), &P); } static int update(EVP_MD_CTX *ctx, const void *data, size_t count) @@ -49,7 +51,7 @@ static const EVP_MD blake2s_md = { NULL, NULL, BLAKE2S_BLOCKBYTES, - sizeof(EVP_MD *) + sizeof(BLAKE2S_CTX), + sizeof(BLAKE2S_CTX), }; const EVP_MD *EVP_blake2s256(void) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index f4e0dd6ca6..aaea598ba7 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -732,6 +732,8 @@ 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_BLAKE2S_MAC_CTRL:222:blake2s_mac_ctrl +EVP_F_BLAKE2S_MAC_INIT:223:blake2s_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 diff --git a/crypto/evp/c_allm.c b/crypto/evp/c_allm.c index e3e03e1261..f5442dfa6c 100644 --- a/crypto/evp/c_allm.c +++ b/crypto/evp/c_allm.c @@ -14,6 +14,7 @@ void openssl_add_all_macs_int(void) { #ifndef OPENSSL_NO_BLAKE2 EVP_add_mac(&blake2b_mac_meth); + EVP_add_mac(&blake2s_mac_meth); #endif #ifndef OPENSSL_NO_CMAC EVP_add_mac(&cmac_meth); diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 1e9e0338d7..a4dd97b53a 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -29,6 +29,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = { {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_BLAKE2S_MAC_CTRL, 0), "blake2s_mac_ctrl"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2S_MAC_INIT, 0), "blake2s_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"}, diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index e0914006ce..189d8aa56e 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -129,6 +129,7 @@ struct evp_mac_st { }; extern const EVP_MAC blake2b_mac_meth; +extern const EVP_MAC blake2s_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/evperr.h b/include/openssl/evperr.h index ebea7fa674..d3ed5b5a76 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -34,6 +34,8 @@ int ERR_load_EVP_strings(void); # define EVP_F_B64_NEW 198 # define EVP_F_BLAKE2B_MAC_CTRL 220 # define EVP_F_BLAKE2B_MAC_INIT 221 +# define EVP_F_BLAKE2S_MAC_CTRL 222 +# define EVP_F_BLAKE2S_MAC_INIT 223 # define EVP_F_CAMELLIA_INIT_KEY 159 # define EVP_F_CHACHA20_POLY1305_CTRL 182 # define EVP_F_CMLL_T4_INIT_KEY 179 -- 2.25.1