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