1 /* 2 * Copyright 2019-2021 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 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 65 goto err; 66 } 67 68 mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq); 69 if (mac == NULL) 70 goto err; 71 72 pmacctx->macctx = EVP_MAC_CTX_new(mac); 73 if (pmacctx->macctx == NULL) 74 goto err; 75 76 EVP_MAC_free(mac); 77 78 return pmacctx; 79 80 err: 81 OPENSSL_free(pmacctx->propq); 82 OPENSSL_free(pmacctx); 83 EVP_MAC_free(mac); 84 return NULL; 85 } 86 87 #define MAC_NEWCTX(funcname, macname) \ 88 static void *mac_##funcname##_newctx(void *provctx, const char *propq) \ 89 { \ 90 return mac_newctx(provctx, propq, macname); \ 91 } 92 93 MAC_NEWCTX(hmac, "HMAC") 94 MAC_NEWCTX(siphash, "SIPHASH") 95 MAC_NEWCTX(poly1305, "POLY1305") 96 MAC_NEWCTX(cmac, "CMAC") 97 98 static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey, 99 const OSSL_PARAM params[]) 100 { 101 PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; 102 const char *ciphername = NULL, *engine = NULL; 103 104 if (!ossl_prov_is_running() 105 || pmacctx == NULL) 106 return 0; 107 108 if (pmacctx->key == NULL && vkey == NULL) { 109 ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 110 return 0; 111 } 112 113 if (vkey != NULL) { 114 if (!ossl_mac_key_up_ref(vkey)) 115 return 0; 116 ossl_mac_key_free(pmacctx->key); 117 pmacctx->key = vkey; 118 } 119 120 if (pmacctx->key->cipher.cipher != NULL) 121 ciphername = (char *)EVP_CIPHER_get0_name(pmacctx->key->cipher.cipher); 122 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) 123 if (pmacctx->key->cipher.engine != NULL) 124 engine = (char *)ENGINE_get_id(pmacctx->key->cipher.engine); 125 #endif 126 127 if (!ossl_prov_set_macctx(pmacctx->macctx, NULL, 128 (char *)ciphername, 129 (char *)mdname, 130 (char *)engine, 131 pmacctx->key->properties, 132 NULL, 0)) 133 return 0; 134 135 if (!EVP_MAC_init(pmacctx->macctx, pmacctx->key->priv_key, 136 pmacctx->key->priv_key_len, params)) 137 return 0; 138 139 return 1; 140 } 141 142 int mac_digest_sign_update(void *vpmacctx, const unsigned char *data, 143 size_t datalen) 144 { 145 PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; 146 147 if (pmacctx == NULL || pmacctx->macctx == NULL) 148 return 0; 149 150 return EVP_MAC_update(pmacctx->macctx, data, datalen); 151 } 152 153 int mac_digest_sign_final(void *vpmacctx, unsigned char *mac, size_t *maclen, 154 size_t macsize) 155 { 156 PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; 157 158 if (!ossl_prov_is_running() || pmacctx == NULL || pmacctx->macctx == NULL) 159 return 0; 160 161 return EVP_MAC_final(pmacctx->macctx, mac, maclen, macsize); 162 } 163 164 static void mac_freectx(void *vpmacctx) 165 { 166 PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx; 167 168 OPENSSL_free(ctx->propq); 169 EVP_MAC_CTX_free(ctx->macctx); 170 ossl_mac_key_free(ctx->key); 171 OPENSSL_free(ctx); 172 } 173 174 static void *mac_dupctx(void *vpmacctx) 175 { 176 PROV_MAC_CTX *srcctx = (PROV_MAC_CTX *)vpmacctx; 177 PROV_MAC_CTX *dstctx; 178 179 if (!ossl_prov_is_running()) 180 return NULL; 181 182 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 183 if (dstctx == NULL) 184 return NULL; 185 186 *dstctx = *srcctx; 187 dstctx->propq = NULL; 188 dstctx->key = NULL; 189 dstctx->macctx = NULL; 190 191 if (srcctx->propq != NULL && (dstctx->propq = OPENSSL_strdup(srcctx->propq)) == NULL) 192 goto err; 193 194 if (srcctx->key != NULL && !ossl_mac_key_up_ref(srcctx->key)) 195 goto err; 196 dstctx->key = srcctx->key; 197 198 if (srcctx->macctx != NULL) { 199 dstctx->macctx = EVP_MAC_CTX_dup(srcctx->macctx); 200 if (dstctx->macctx == NULL) 201 goto err; 202 } 203 204 return dstctx; 205 err: 206 mac_freectx(dstctx); 207 return NULL; 208 } 209 210 static int mac_set_ctx_params(void *vpmacctx, const OSSL_PARAM params[]) 211 { 212 PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx; 213 214 return EVP_MAC_CTX_set_params(ctx->macctx, params); 215 } 216 217 static const OSSL_PARAM *mac_settable_ctx_params(ossl_unused void *ctx, 218 void *provctx, 219 const char *macname) 220 { 221 EVP_MAC *mac = EVP_MAC_fetch(PROV_LIBCTX_OF(provctx), macname, 222 NULL); 223 const OSSL_PARAM *params; 224 225 if (mac == NULL) 226 return NULL; 227 228 params = EVP_MAC_settable_ctx_params(mac); 229 EVP_MAC_free(mac); 230 231 return params; 232 } 233 234 #define MAC_SETTABLE_CTX_PARAMS(funcname, macname) \ 235 static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *ctx, \ 236 void *provctx) \ 237 { \ 238 return mac_settable_ctx_params(ctx, provctx, macname); \ 239 } 240 241 MAC_SETTABLE_CTX_PARAMS(hmac, "HMAC") 242 MAC_SETTABLE_CTX_PARAMS(siphash, "SIPHASH") 243 MAC_SETTABLE_CTX_PARAMS(poly1305, "POLY1305") 244 MAC_SETTABLE_CTX_PARAMS(cmac, "CMAC") 245 246 #define MAC_SIGNATURE_FUNCTIONS(funcname) \ 247 const OSSL_DISPATCH ossl_mac_legacy_##funcname##_signature_functions[] = { \ 248 { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))mac_##funcname##_newctx }, \ 249 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \ 250 (void (*)(void))mac_digest_sign_init }, \ 251 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, \ 252 (void (*)(void))mac_digest_sign_update }, \ 253 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, \ 254 (void (*)(void))mac_digest_sign_final }, \ 255 { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))mac_freectx }, \ 256 { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))mac_dupctx }, \ 257 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ 258 (void (*)(void))mac_set_ctx_params }, \ 259 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ 260 (void (*)(void))mac_##funcname##_settable_ctx_params }, \ 261 { 0, NULL } \ 262 }; 263 264 MAC_SIGNATURE_FUNCTIONS(hmac) 265 MAC_SIGNATURE_FUNCTIONS(siphash) 266 MAC_SIGNATURE_FUNCTIONS(poly1305) 267 MAC_SIGNATURE_FUNCTIONS(cmac) 268