openssl/crypto/blake2/blake2s_mac.c

191 lines
5.5 KiB
C
Raw Normal View History

/*
* 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 "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