7ed66e2634
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> GH: #7651
196 lines
5.6 KiB
C
196 lines
5.6 KiB
C
/*
|
|
* 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 <openssl/evp.h>
|
|
# include "internal/blake2.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 EVP_MAC_IMPL *blake2b_mac_dup(const EVP_MAC_IMPL *src)
|
|
{
|
|
EVP_MAC_IMPL *dst;
|
|
|
|
dst = OPENSSL_zalloc(sizeof(*dst));
|
|
if (dst == NULL)
|
|
return NULL;
|
|
|
|
*dst = *src;
|
|
return dst;
|
|
}
|
|
|
|
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_dup,
|
|
blake2b_mac_free,
|
|
blake2b_mac_size,
|
|
blake2b_mac_init,
|
|
blake2b_mac_update,
|
|
blake2b_mac_final,
|
|
blake2b_mac_ctrl,
|
|
blake2b_mac_ctrl_str
|
|
};
|
|
|
|
#endif
|