1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* We need to use some engine deprecated APIs */ 11e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ci#include <openssl/crypto.h> 14e1051a39Sopenharmony_ci#include <openssl/evp.h> 15e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 16e1051a39Sopenharmony_ci#include <openssl/core_names.h> 17e1051a39Sopenharmony_ci#include <openssl/params.h> 18e1051a39Sopenharmony_ci#include <openssl/err.h> 19e1051a39Sopenharmony_ci#include <openssl/proverr.h> 20e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 21e1051a39Sopenharmony_ci# include <openssl/engine.h> 22e1051a39Sopenharmony_ci#endif 23e1051a39Sopenharmony_ci#include "prov/implementations.h" 24e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 25e1051a39Sopenharmony_ci#include "prov/macsignature.h" 26e1051a39Sopenharmony_ci#include "prov/providercommon.h" 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_newctx_fn mac_hmac_newctx; 29e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_newctx_fn mac_siphash_newctx; 30e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_newctx_fn mac_poly1305_newctx; 31e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_newctx_fn mac_cmac_newctx; 32e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_init_fn mac_digest_sign_init; 33e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_update_fn mac_digest_sign_update; 34e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_final_fn mac_digest_sign_final; 35e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_freectx_fn mac_freectx; 36e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_dupctx_fn mac_dupctx; 37e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_set_ctx_params_fn mac_set_ctx_params; 38e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_params_fn mac_hmac_settable_ctx_params; 39e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_params_fn mac_siphash_settable_ctx_params; 40e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_params_fn mac_poly1305_settable_ctx_params; 41e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_settable_ctx_params_fn mac_cmac_settable_ctx_params; 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_citypedef struct { 44e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 45e1051a39Sopenharmony_ci char *propq; 46e1051a39Sopenharmony_ci MAC_KEY *key; 47e1051a39Sopenharmony_ci EVP_MAC_CTX *macctx; 48e1051a39Sopenharmony_ci} PROV_MAC_CTX; 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_cistatic void *mac_newctx(void *provctx, const char *propq, const char *macname) 51e1051a39Sopenharmony_ci{ 52e1051a39Sopenharmony_ci PROV_MAC_CTX *pmacctx; 53e1051a39Sopenharmony_ci EVP_MAC *mac = NULL; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 56e1051a39Sopenharmony_ci return NULL; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci pmacctx = OPENSSL_zalloc(sizeof(PROV_MAC_CTX)); 59e1051a39Sopenharmony_ci if (pmacctx == NULL) 60e1051a39Sopenharmony_ci return NULL; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci pmacctx->libctx = PROV_LIBCTX_OF(provctx); 63e1051a39Sopenharmony_ci if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL) { 64e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 65e1051a39Sopenharmony_ci goto err; 66e1051a39Sopenharmony_ci } 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq); 69e1051a39Sopenharmony_ci if (mac == NULL) 70e1051a39Sopenharmony_ci goto err; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci pmacctx->macctx = EVP_MAC_CTX_new(mac); 73e1051a39Sopenharmony_ci if (pmacctx->macctx == NULL) 74e1051a39Sopenharmony_ci goto err; 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci EVP_MAC_free(mac); 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci return pmacctx; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci err: 81e1051a39Sopenharmony_ci OPENSSL_free(pmacctx->propq); 82e1051a39Sopenharmony_ci OPENSSL_free(pmacctx); 83e1051a39Sopenharmony_ci EVP_MAC_free(mac); 84e1051a39Sopenharmony_ci return NULL; 85e1051a39Sopenharmony_ci} 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_ci#define MAC_NEWCTX(funcname, macname) \ 88e1051a39Sopenharmony_ci static void *mac_##funcname##_newctx(void *provctx, const char *propq) \ 89e1051a39Sopenharmony_ci { \ 90e1051a39Sopenharmony_ci return mac_newctx(provctx, propq, macname); \ 91e1051a39Sopenharmony_ci } 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ciMAC_NEWCTX(hmac, "HMAC") 94e1051a39Sopenharmony_ciMAC_NEWCTX(siphash, "SIPHASH") 95e1051a39Sopenharmony_ciMAC_NEWCTX(poly1305, "POLY1305") 96e1051a39Sopenharmony_ciMAC_NEWCTX(cmac, "CMAC") 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_cistatic int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey, 99e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; 102e1051a39Sopenharmony_ci const char *ciphername = NULL, *engine = NULL; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci if (!ossl_prov_is_running() 105e1051a39Sopenharmony_ci || pmacctx == NULL) 106e1051a39Sopenharmony_ci return 0; 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ci if (pmacctx->key == NULL && vkey == NULL) { 109e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 110e1051a39Sopenharmony_ci return 0; 111e1051a39Sopenharmony_ci } 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci if (vkey != NULL) { 114e1051a39Sopenharmony_ci if (!ossl_mac_key_up_ref(vkey)) 115e1051a39Sopenharmony_ci return 0; 116e1051a39Sopenharmony_ci ossl_mac_key_free(pmacctx->key); 117e1051a39Sopenharmony_ci pmacctx->key = vkey; 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (pmacctx->key->cipher.cipher != NULL) 121e1051a39Sopenharmony_ci ciphername = (char *)EVP_CIPHER_get0_name(pmacctx->key->cipher.cipher); 122e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 123e1051a39Sopenharmony_ci if (pmacctx->key->cipher.engine != NULL) 124e1051a39Sopenharmony_ci engine = (char *)ENGINE_get_id(pmacctx->key->cipher.engine); 125e1051a39Sopenharmony_ci#endif 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci if (!ossl_prov_set_macctx(pmacctx->macctx, NULL, 128e1051a39Sopenharmony_ci (char *)ciphername, 129e1051a39Sopenharmony_ci (char *)mdname, 130e1051a39Sopenharmony_ci (char *)engine, 131e1051a39Sopenharmony_ci pmacctx->key->properties, 132e1051a39Sopenharmony_ci NULL, 0)) 133e1051a39Sopenharmony_ci return 0; 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci if (!EVP_MAC_init(pmacctx->macctx, pmacctx->key->priv_key, 136e1051a39Sopenharmony_ci pmacctx->key->priv_key_len, params)) 137e1051a39Sopenharmony_ci return 0; 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci return 1; 140e1051a39Sopenharmony_ci} 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ciint mac_digest_sign_update(void *vpmacctx, const unsigned char *data, 143e1051a39Sopenharmony_ci size_t datalen) 144e1051a39Sopenharmony_ci{ 145e1051a39Sopenharmony_ci PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci if (pmacctx == NULL || pmacctx->macctx == NULL) 148e1051a39Sopenharmony_ci return 0; 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci return EVP_MAC_update(pmacctx->macctx, data, datalen); 151e1051a39Sopenharmony_ci} 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ciint mac_digest_sign_final(void *vpmacctx, unsigned char *mac, size_t *maclen, 154e1051a39Sopenharmony_ci size_t macsize) 155e1051a39Sopenharmony_ci{ 156e1051a39Sopenharmony_ci PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || pmacctx == NULL || pmacctx->macctx == NULL) 159e1051a39Sopenharmony_ci return 0; 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_ci return EVP_MAC_final(pmacctx->macctx, mac, maclen, macsize); 162e1051a39Sopenharmony_ci} 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_cistatic void mac_freectx(void *vpmacctx) 165e1051a39Sopenharmony_ci{ 166e1051a39Sopenharmony_ci PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx; 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_ci OPENSSL_free(ctx->propq); 169e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx->macctx); 170e1051a39Sopenharmony_ci ossl_mac_key_free(ctx->key); 171e1051a39Sopenharmony_ci OPENSSL_free(ctx); 172e1051a39Sopenharmony_ci} 173e1051a39Sopenharmony_ci 174e1051a39Sopenharmony_cistatic void *mac_dupctx(void *vpmacctx) 175e1051a39Sopenharmony_ci{ 176e1051a39Sopenharmony_ci PROV_MAC_CTX *srcctx = (PROV_MAC_CTX *)vpmacctx; 177e1051a39Sopenharmony_ci PROV_MAC_CTX *dstctx; 178e1051a39Sopenharmony_ci 179e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 180e1051a39Sopenharmony_ci return NULL; 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 183e1051a39Sopenharmony_ci if (dstctx == NULL) 184e1051a39Sopenharmony_ci return NULL; 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci *dstctx = *srcctx; 187e1051a39Sopenharmony_ci dstctx->propq = NULL; 188e1051a39Sopenharmony_ci dstctx->key = NULL; 189e1051a39Sopenharmony_ci dstctx->macctx = NULL; 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ci if (srcctx->propq != NULL && (dstctx->propq = OPENSSL_strdup(srcctx->propq)) == NULL) 192e1051a39Sopenharmony_ci goto err; 193e1051a39Sopenharmony_ci 194e1051a39Sopenharmony_ci if (srcctx->key != NULL && !ossl_mac_key_up_ref(srcctx->key)) 195e1051a39Sopenharmony_ci goto err; 196e1051a39Sopenharmony_ci dstctx->key = srcctx->key; 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_ci if (srcctx->macctx != NULL) { 199e1051a39Sopenharmony_ci dstctx->macctx = EVP_MAC_CTX_dup(srcctx->macctx); 200e1051a39Sopenharmony_ci if (dstctx->macctx == NULL) 201e1051a39Sopenharmony_ci goto err; 202e1051a39Sopenharmony_ci } 203e1051a39Sopenharmony_ci 204e1051a39Sopenharmony_ci return dstctx; 205e1051a39Sopenharmony_ci err: 206e1051a39Sopenharmony_ci mac_freectx(dstctx); 207e1051a39Sopenharmony_ci return NULL; 208e1051a39Sopenharmony_ci} 209e1051a39Sopenharmony_ci 210e1051a39Sopenharmony_cistatic int mac_set_ctx_params(void *vpmacctx, const OSSL_PARAM params[]) 211e1051a39Sopenharmony_ci{ 212e1051a39Sopenharmony_ci PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx; 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci return EVP_MAC_CTX_set_params(ctx->macctx, params); 215e1051a39Sopenharmony_ci} 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_cistatic const OSSL_PARAM *mac_settable_ctx_params(ossl_unused void *ctx, 218e1051a39Sopenharmony_ci void *provctx, 219e1051a39Sopenharmony_ci const char *macname) 220e1051a39Sopenharmony_ci{ 221e1051a39Sopenharmony_ci EVP_MAC *mac = EVP_MAC_fetch(PROV_LIBCTX_OF(provctx), macname, 222e1051a39Sopenharmony_ci NULL); 223e1051a39Sopenharmony_ci const OSSL_PARAM *params; 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci if (mac == NULL) 226e1051a39Sopenharmony_ci return NULL; 227e1051a39Sopenharmony_ci 228e1051a39Sopenharmony_ci params = EVP_MAC_settable_ctx_params(mac); 229e1051a39Sopenharmony_ci EVP_MAC_free(mac); 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ci return params; 232e1051a39Sopenharmony_ci} 233e1051a39Sopenharmony_ci 234e1051a39Sopenharmony_ci#define MAC_SETTABLE_CTX_PARAMS(funcname, macname) \ 235e1051a39Sopenharmony_ci static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *ctx, \ 236e1051a39Sopenharmony_ci void *provctx) \ 237e1051a39Sopenharmony_ci { \ 238e1051a39Sopenharmony_ci return mac_settable_ctx_params(ctx, provctx, macname); \ 239e1051a39Sopenharmony_ci } 240e1051a39Sopenharmony_ci 241e1051a39Sopenharmony_ciMAC_SETTABLE_CTX_PARAMS(hmac, "HMAC") 242e1051a39Sopenharmony_ciMAC_SETTABLE_CTX_PARAMS(siphash, "SIPHASH") 243e1051a39Sopenharmony_ciMAC_SETTABLE_CTX_PARAMS(poly1305, "POLY1305") 244e1051a39Sopenharmony_ciMAC_SETTABLE_CTX_PARAMS(cmac, "CMAC") 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci#define MAC_SIGNATURE_FUNCTIONS(funcname) \ 247e1051a39Sopenharmony_ci const OSSL_DISPATCH ossl_mac_legacy_##funcname##_signature_functions[] = { \ 248e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))mac_##funcname##_newctx }, \ 249e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \ 250e1051a39Sopenharmony_ci (void (*)(void))mac_digest_sign_init }, \ 251e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, \ 252e1051a39Sopenharmony_ci (void (*)(void))mac_digest_sign_update }, \ 253e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, \ 254e1051a39Sopenharmony_ci (void (*)(void))mac_digest_sign_final }, \ 255e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))mac_freectx }, \ 256e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))mac_dupctx }, \ 257e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ 258e1051a39Sopenharmony_ci (void (*)(void))mac_set_ctx_params }, \ 259e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ 260e1051a39Sopenharmony_ci (void (*)(void))mac_##funcname##_settable_ctx_params }, \ 261e1051a39Sopenharmony_ci { 0, NULL } \ 262e1051a39Sopenharmony_ci }; 263e1051a39Sopenharmony_ci 264e1051a39Sopenharmony_ciMAC_SIGNATURE_FUNCTIONS(hmac) 265e1051a39Sopenharmony_ciMAC_SIGNATURE_FUNCTIONS(siphash) 266e1051a39Sopenharmony_ciMAC_SIGNATURE_FUNCTIONS(poly1305) 267e1051a39Sopenharmony_ciMAC_SIGNATURE_FUNCTIONS(cmac) 268