Path: blob/main/crypto/openssl/providers/implementations/macs/siphash_prov.c
48383 views
/*1* Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <string.h>10#include <openssl/core_dispatch.h>11#include <openssl/core_names.h>12#include <openssl/params.h>13#include <openssl/evp.h>14#include <openssl/err.h>15#include <openssl/proverr.h>1617#include "crypto/siphash.h"1819#include "prov/implementations.h"20#include "prov/providercommon.h"2122/*23* Forward declaration of everything implemented here. This is not strictly24* necessary for the compiler, but provides an assurance that the signatures25* of the functions in the dispatch table are correct.26*/27static OSSL_FUNC_mac_newctx_fn siphash_new;28static OSSL_FUNC_mac_dupctx_fn siphash_dup;29static OSSL_FUNC_mac_freectx_fn siphash_free;30static OSSL_FUNC_mac_gettable_ctx_params_fn siphash_gettable_ctx_params;31static OSSL_FUNC_mac_get_ctx_params_fn siphash_get_ctx_params;32static OSSL_FUNC_mac_settable_ctx_params_fn siphash_settable_ctx_params;33static OSSL_FUNC_mac_set_ctx_params_fn siphash_set_params;34static OSSL_FUNC_mac_init_fn siphash_init;35static OSSL_FUNC_mac_update_fn siphash_update;36static OSSL_FUNC_mac_final_fn siphash_final;3738struct siphash_data_st {39void *provctx;40SIPHASH siphash; /* Siphash data */41SIPHASH sipcopy; /* Siphash data copy for reinitialization */42unsigned int crounds, drounds;43};4445static unsigned int crounds(struct siphash_data_st *ctx)46{47return ctx->crounds != 0 ? ctx->crounds : SIPHASH_C_ROUNDS;48}4950static unsigned int drounds(struct siphash_data_st *ctx)51{52return ctx->drounds != 0 ? ctx->drounds : SIPHASH_D_ROUNDS;53}5455static void *siphash_new(void *provctx)56{57struct siphash_data_st *ctx;5859if (!ossl_prov_is_running())60return NULL;61ctx = OPENSSL_zalloc(sizeof(*ctx));62if (ctx != NULL)63ctx->provctx = provctx;64return ctx;65}6667static void siphash_free(void *vmacctx)68{69OPENSSL_free(vmacctx);70}7172static void *siphash_dup(void *vsrc)73{74struct siphash_data_st *ssrc = vsrc;75struct siphash_data_st *sdst;7677if (!ossl_prov_is_running())78return NULL;79sdst = OPENSSL_malloc(sizeof(*sdst));80if (sdst == NULL)81return NULL;8283*sdst = *ssrc;84return sdst;85}8687static size_t siphash_size(void *vmacctx)88{89struct siphash_data_st *ctx = vmacctx;9091return SipHash_hash_size(&ctx->siphash);92}9394static int siphash_setkey(struct siphash_data_st *ctx,95const unsigned char *key, size_t keylen)96{97int ret;9899if (keylen != SIPHASH_KEY_SIZE)100return 0;101ret = SipHash_Init(&ctx->siphash, key, crounds(ctx), drounds(ctx));102if (ret)103ctx->sipcopy = ctx->siphash;104return ret;105}106107static int siphash_init(void *vmacctx, const unsigned char *key, size_t keylen,108const OSSL_PARAM params[])109{110struct siphash_data_st *ctx = vmacctx;111112if (!ossl_prov_is_running() || !siphash_set_params(ctx, params))113return 0;114/*115* Without a key, there is not much to do here,116* The actual initialization happens through controls.117*/118if (key == NULL) {119ctx->siphash = ctx->sipcopy;120return 1;121}122return siphash_setkey(ctx, key, keylen);123}124125static int siphash_update(void *vmacctx, const unsigned char *data,126size_t datalen)127{128struct siphash_data_st *ctx = vmacctx;129130if (datalen == 0)131return 1;132133SipHash_Update(&ctx->siphash, data, datalen);134return 1;135}136137static int siphash_final(void *vmacctx, unsigned char *out, size_t *outl,138size_t outsize)139{140struct siphash_data_st *ctx = vmacctx;141size_t hlen = siphash_size(ctx);142143if (!ossl_prov_is_running() || outsize < hlen)144return 0;145146*outl = hlen;147return SipHash_Final(&ctx->siphash, out, hlen);148}149150static const OSSL_PARAM *siphash_gettable_ctx_params(ossl_unused void *ctx,151ossl_unused void *provctx)152{153static const OSSL_PARAM known_gettable_ctx_params[] = {154OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),155OSSL_PARAM_uint(OSSL_MAC_PARAM_C_ROUNDS, NULL),156OSSL_PARAM_uint(OSSL_MAC_PARAM_D_ROUNDS, NULL),157OSSL_PARAM_END158};159160return known_gettable_ctx_params;161}162163static int siphash_get_ctx_params(void *vmacctx, OSSL_PARAM params[])164{165struct siphash_data_st *ctx = vmacctx;166OSSL_PARAM *p;167168if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL169&& !OSSL_PARAM_set_size_t(p, siphash_size(vmacctx)))170return 0;171if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_C_ROUNDS)) != NULL172&& !OSSL_PARAM_set_uint(p, crounds(ctx)))173return 0;174if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_D_ROUNDS)) != NULL175&& !OSSL_PARAM_set_uint(p, drounds(ctx)))176return 0;177return 1;178}179180static const OSSL_PARAM *siphash_settable_ctx_params(ossl_unused void *ctx,181void *provctx)182{183static const OSSL_PARAM known_settable_ctx_params[] = {184OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),185OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),186OSSL_PARAM_uint(OSSL_MAC_PARAM_C_ROUNDS, NULL),187OSSL_PARAM_uint(OSSL_MAC_PARAM_D_ROUNDS, NULL),188OSSL_PARAM_END189};190191return known_settable_ctx_params;192}193194static int siphash_set_params(void *vmacctx, const OSSL_PARAM *params)195{196struct siphash_data_st *ctx = vmacctx;197const OSSL_PARAM *p = NULL;198size_t size;199200if (ossl_param_is_empty(params))201return 1;202203if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {204if (!OSSL_PARAM_get_size_t(p, &size)205|| !SipHash_set_hash_size(&ctx->siphash, size)206|| !SipHash_set_hash_size(&ctx->sipcopy, size))207return 0;208}209if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_C_ROUNDS)) != NULL210&& !OSSL_PARAM_get_uint(p, &ctx->crounds))211return 0;212if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_D_ROUNDS)) != NULL213&& !OSSL_PARAM_get_uint(p, &ctx->drounds))214return 0;215if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)216if (p->data_type != OSSL_PARAM_OCTET_STRING217|| !siphash_setkey(ctx, p->data, p->data_size))218return 0;219return 1;220}221222const OSSL_DISPATCH ossl_siphash_functions[] = {223{ OSSL_FUNC_MAC_NEWCTX, (void (*)(void))siphash_new },224{ OSSL_FUNC_MAC_DUPCTX, (void (*)(void))siphash_dup },225{ OSSL_FUNC_MAC_FREECTX, (void (*)(void))siphash_free },226{ OSSL_FUNC_MAC_INIT, (void (*)(void))siphash_init },227{ OSSL_FUNC_MAC_UPDATE, (void (*)(void))siphash_update },228{ OSSL_FUNC_MAC_FINAL, (void (*)(void))siphash_final },229{ OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,230(void (*)(void))siphash_gettable_ctx_params },231{ OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))siphash_get_ctx_params },232{ OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,233(void (*)(void))siphash_settable_ctx_params },234{ OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))siphash_set_params },235OSSL_DISPATCH_END236};237238239