1*eda14cbcSMatt Macy /* 2*eda14cbcSMatt Macy * CDDL HEADER START 3*eda14cbcSMatt Macy * 4*eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5*eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6*eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7*eda14cbcSMatt Macy * 8*eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*eda14cbcSMatt Macy * or http://www.opensolaris.org/os/licensing. 10*eda14cbcSMatt Macy * See the License for the specific language governing permissions 11*eda14cbcSMatt Macy * and limitations under the License. 12*eda14cbcSMatt Macy * 13*eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14*eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16*eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17*eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18*eda14cbcSMatt Macy * 19*eda14cbcSMatt Macy * CDDL HEADER END 20*eda14cbcSMatt Macy */ 21*eda14cbcSMatt Macy 22*eda14cbcSMatt Macy /* 23*eda14cbcSMatt Macy * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*eda14cbcSMatt Macy * Use is subject to license terms. 25*eda14cbcSMatt Macy */ 26*eda14cbcSMatt Macy 27*eda14cbcSMatt Macy #include <sys/zfs_context.h> 28*eda14cbcSMatt Macy #include <sys/modctl.h> 29*eda14cbcSMatt Macy #include <sys/crypto/common.h> 30*eda14cbcSMatt Macy #include <sys/crypto/spi.h> 31*eda14cbcSMatt Macy #include <sys/crypto/icp.h> 32*eda14cbcSMatt Macy #define _SHA2_IMPL 33*eda14cbcSMatt Macy #include <sys/sha2.h> 34*eda14cbcSMatt Macy #include <sha2/sha2_impl.h> 35*eda14cbcSMatt Macy 36*eda14cbcSMatt Macy /* 37*eda14cbcSMatt Macy * The sha2 module is created with two modlinkages: 38*eda14cbcSMatt Macy * - a modlmisc that allows consumers to directly call the entry points 39*eda14cbcSMatt Macy * SHA2Init, SHA2Update, and SHA2Final. 40*eda14cbcSMatt Macy * - a modlcrypto that allows the module to register with the Kernel 41*eda14cbcSMatt Macy * Cryptographic Framework (KCF) as a software provider for the SHA2 42*eda14cbcSMatt Macy * mechanisms. 43*eda14cbcSMatt Macy */ 44*eda14cbcSMatt Macy 45*eda14cbcSMatt Macy static struct modlcrypto modlcrypto = { 46*eda14cbcSMatt Macy &mod_cryptoops, 47*eda14cbcSMatt Macy "SHA2 Kernel SW Provider" 48*eda14cbcSMatt Macy }; 49*eda14cbcSMatt Macy 50*eda14cbcSMatt Macy static struct modlinkage modlinkage = { 51*eda14cbcSMatt Macy MODREV_1, {&modlcrypto, NULL} 52*eda14cbcSMatt Macy }; 53*eda14cbcSMatt Macy 54*eda14cbcSMatt Macy /* 55*eda14cbcSMatt Macy * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed 56*eda14cbcSMatt Macy * by KCF to one of the entry points. 57*eda14cbcSMatt Macy */ 58*eda14cbcSMatt Macy 59*eda14cbcSMatt Macy #define PROV_SHA2_CTX(ctx) ((sha2_ctx_t *)(ctx)->cc_provider_private) 60*eda14cbcSMatt Macy #define PROV_SHA2_HMAC_CTX(ctx) ((sha2_hmac_ctx_t *)(ctx)->cc_provider_private) 61*eda14cbcSMatt Macy 62*eda14cbcSMatt Macy /* to extract the digest length passed as mechanism parameter */ 63*eda14cbcSMatt Macy #define PROV_SHA2_GET_DIGEST_LEN(m, len) { \ 64*eda14cbcSMatt Macy if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \ 65*eda14cbcSMatt Macy (len) = (uint32_t)*((ulong_t *)(m)->cm_param); \ 66*eda14cbcSMatt Macy else { \ 67*eda14cbcSMatt Macy ulong_t tmp_ulong; \ 68*eda14cbcSMatt Macy bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \ 69*eda14cbcSMatt Macy (len) = (uint32_t)tmp_ulong; \ 70*eda14cbcSMatt Macy } \ 71*eda14cbcSMatt Macy } 72*eda14cbcSMatt Macy 73*eda14cbcSMatt Macy #define PROV_SHA2_DIGEST_KEY(mech, ctx, key, len, digest) { \ 74*eda14cbcSMatt Macy SHA2Init(mech, ctx); \ 75*eda14cbcSMatt Macy SHA2Update(ctx, key, len); \ 76*eda14cbcSMatt Macy SHA2Final(digest, ctx); \ 77*eda14cbcSMatt Macy } 78*eda14cbcSMatt Macy 79*eda14cbcSMatt Macy /* 80*eda14cbcSMatt Macy * Mechanism info structure passed to KCF during registration. 81*eda14cbcSMatt Macy */ 82*eda14cbcSMatt Macy static crypto_mech_info_t sha2_mech_info_tab[] = { 83*eda14cbcSMatt Macy /* SHA256 */ 84*eda14cbcSMatt Macy {SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE, 85*eda14cbcSMatt Macy CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 86*eda14cbcSMatt Macy 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 87*eda14cbcSMatt Macy /* SHA256-HMAC */ 88*eda14cbcSMatt Macy {SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE, 89*eda14cbcSMatt Macy CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 90*eda14cbcSMatt Macy SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 91*eda14cbcSMatt Macy CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 92*eda14cbcSMatt Macy /* SHA256-HMAC GENERAL */ 93*eda14cbcSMatt Macy {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE, 94*eda14cbcSMatt Macy CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 95*eda14cbcSMatt Macy SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 96*eda14cbcSMatt Macy CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 97*eda14cbcSMatt Macy /* SHA384 */ 98*eda14cbcSMatt Macy {SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE, 99*eda14cbcSMatt Macy CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 100*eda14cbcSMatt Macy 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 101*eda14cbcSMatt Macy /* SHA384-HMAC */ 102*eda14cbcSMatt Macy {SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE, 103*eda14cbcSMatt Macy CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 104*eda14cbcSMatt Macy SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 105*eda14cbcSMatt Macy CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 106*eda14cbcSMatt Macy /* SHA384-HMAC GENERAL */ 107*eda14cbcSMatt Macy {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE, 108*eda14cbcSMatt Macy CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 109*eda14cbcSMatt Macy SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 110*eda14cbcSMatt Macy CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 111*eda14cbcSMatt Macy /* SHA512 */ 112*eda14cbcSMatt Macy {SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE, 113*eda14cbcSMatt Macy CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC, 114*eda14cbcSMatt Macy 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 115*eda14cbcSMatt Macy /* SHA512-HMAC */ 116*eda14cbcSMatt Macy {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE, 117*eda14cbcSMatt Macy CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 118*eda14cbcSMatt Macy SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 119*eda14cbcSMatt Macy CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 120*eda14cbcSMatt Macy /* SHA512-HMAC GENERAL */ 121*eda14cbcSMatt Macy {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE, 122*eda14cbcSMatt Macy CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 123*eda14cbcSMatt Macy SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN, 124*eda14cbcSMatt Macy CRYPTO_KEYSIZE_UNIT_IN_BYTES} 125*eda14cbcSMatt Macy }; 126*eda14cbcSMatt Macy 127*eda14cbcSMatt Macy static void sha2_provider_status(crypto_provider_handle_t, uint_t *); 128*eda14cbcSMatt Macy 129*eda14cbcSMatt Macy static crypto_control_ops_t sha2_control_ops = { 130*eda14cbcSMatt Macy sha2_provider_status 131*eda14cbcSMatt Macy }; 132*eda14cbcSMatt Macy 133*eda14cbcSMatt Macy static int sha2_digest_init(crypto_ctx_t *, crypto_mechanism_t *, 134*eda14cbcSMatt Macy crypto_req_handle_t); 135*eda14cbcSMatt Macy static int sha2_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 136*eda14cbcSMatt Macy crypto_req_handle_t); 137*eda14cbcSMatt Macy static int sha2_digest_update(crypto_ctx_t *, crypto_data_t *, 138*eda14cbcSMatt Macy crypto_req_handle_t); 139*eda14cbcSMatt Macy static int sha2_digest_final(crypto_ctx_t *, crypto_data_t *, 140*eda14cbcSMatt Macy crypto_req_handle_t); 141*eda14cbcSMatt Macy static int sha2_digest_atomic(crypto_provider_handle_t, crypto_session_id_t, 142*eda14cbcSMatt Macy crypto_mechanism_t *, crypto_data_t *, crypto_data_t *, 143*eda14cbcSMatt Macy crypto_req_handle_t); 144*eda14cbcSMatt Macy 145*eda14cbcSMatt Macy static crypto_digest_ops_t sha2_digest_ops = { 146*eda14cbcSMatt Macy .digest_init = sha2_digest_init, 147*eda14cbcSMatt Macy .digest = sha2_digest, 148*eda14cbcSMatt Macy .digest_update = sha2_digest_update, 149*eda14cbcSMatt Macy .digest_key = NULL, 150*eda14cbcSMatt Macy .digest_final = sha2_digest_final, 151*eda14cbcSMatt Macy .digest_atomic = sha2_digest_atomic 152*eda14cbcSMatt Macy }; 153*eda14cbcSMatt Macy 154*eda14cbcSMatt Macy static int sha2_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, 155*eda14cbcSMatt Macy crypto_spi_ctx_template_t, crypto_req_handle_t); 156*eda14cbcSMatt Macy static int sha2_mac_update(crypto_ctx_t *, crypto_data_t *, 157*eda14cbcSMatt Macy crypto_req_handle_t); 158*eda14cbcSMatt Macy static int sha2_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t); 159*eda14cbcSMatt Macy static int sha2_mac_atomic(crypto_provider_handle_t, crypto_session_id_t, 160*eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 161*eda14cbcSMatt Macy crypto_spi_ctx_template_t, crypto_req_handle_t); 162*eda14cbcSMatt Macy static int sha2_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 163*eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 164*eda14cbcSMatt Macy crypto_spi_ctx_template_t, crypto_req_handle_t); 165*eda14cbcSMatt Macy 166*eda14cbcSMatt Macy static crypto_mac_ops_t sha2_mac_ops = { 167*eda14cbcSMatt Macy .mac_init = sha2_mac_init, 168*eda14cbcSMatt Macy .mac = NULL, 169*eda14cbcSMatt Macy .mac_update = sha2_mac_update, 170*eda14cbcSMatt Macy .mac_final = sha2_mac_final, 171*eda14cbcSMatt Macy .mac_atomic = sha2_mac_atomic, 172*eda14cbcSMatt Macy .mac_verify_atomic = sha2_mac_verify_atomic 173*eda14cbcSMatt Macy }; 174*eda14cbcSMatt Macy 175*eda14cbcSMatt Macy static int sha2_create_ctx_template(crypto_provider_handle_t, 176*eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *, 177*eda14cbcSMatt Macy size_t *, crypto_req_handle_t); 178*eda14cbcSMatt Macy static int sha2_free_context(crypto_ctx_t *); 179*eda14cbcSMatt Macy 180*eda14cbcSMatt Macy static crypto_ctx_ops_t sha2_ctx_ops = { 181*eda14cbcSMatt Macy .create_ctx_template = sha2_create_ctx_template, 182*eda14cbcSMatt Macy .free_context = sha2_free_context 183*eda14cbcSMatt Macy }; 184*eda14cbcSMatt Macy 185*eda14cbcSMatt Macy static crypto_ops_t sha2_crypto_ops = {{{{{ 186*eda14cbcSMatt Macy &sha2_control_ops, 187*eda14cbcSMatt Macy &sha2_digest_ops, 188*eda14cbcSMatt Macy NULL, 189*eda14cbcSMatt Macy &sha2_mac_ops, 190*eda14cbcSMatt Macy NULL, 191*eda14cbcSMatt Macy NULL, 192*eda14cbcSMatt Macy NULL, 193*eda14cbcSMatt Macy NULL, 194*eda14cbcSMatt Macy NULL, 195*eda14cbcSMatt Macy NULL, 196*eda14cbcSMatt Macy NULL, 197*eda14cbcSMatt Macy NULL, 198*eda14cbcSMatt Macy NULL, 199*eda14cbcSMatt Macy &sha2_ctx_ops 200*eda14cbcSMatt Macy }}}}}; 201*eda14cbcSMatt Macy 202*eda14cbcSMatt Macy static crypto_provider_info_t sha2_prov_info = {{{{ 203*eda14cbcSMatt Macy CRYPTO_SPI_VERSION_1, 204*eda14cbcSMatt Macy "SHA2 Software Provider", 205*eda14cbcSMatt Macy CRYPTO_SW_PROVIDER, 206*eda14cbcSMatt Macy NULL, 207*eda14cbcSMatt Macy &sha2_crypto_ops, 208*eda14cbcSMatt Macy sizeof (sha2_mech_info_tab)/sizeof (crypto_mech_info_t), 209*eda14cbcSMatt Macy sha2_mech_info_tab 210*eda14cbcSMatt Macy }}}}; 211*eda14cbcSMatt Macy 212*eda14cbcSMatt Macy static crypto_kcf_provider_handle_t sha2_prov_handle = 0; 213*eda14cbcSMatt Macy 214*eda14cbcSMatt Macy int 215*eda14cbcSMatt Macy sha2_mod_init(void) 216*eda14cbcSMatt Macy { 217*eda14cbcSMatt Macy int ret; 218*eda14cbcSMatt Macy 219*eda14cbcSMatt Macy if ((ret = mod_install(&modlinkage)) != 0) 220*eda14cbcSMatt Macy return (ret); 221*eda14cbcSMatt Macy 222*eda14cbcSMatt Macy /* 223*eda14cbcSMatt Macy * Register with KCF. If the registration fails, log an 224*eda14cbcSMatt Macy * error but do not uninstall the module, since the functionality 225*eda14cbcSMatt Macy * provided by misc/sha2 should still be available. 226*eda14cbcSMatt Macy */ 227*eda14cbcSMatt Macy if ((ret = crypto_register_provider(&sha2_prov_info, 228*eda14cbcSMatt Macy &sha2_prov_handle)) != CRYPTO_SUCCESS) 229*eda14cbcSMatt Macy cmn_err(CE_WARN, "sha2 _init: " 230*eda14cbcSMatt Macy "crypto_register_provider() failed (0x%x)", ret); 231*eda14cbcSMatt Macy 232*eda14cbcSMatt Macy return (0); 233*eda14cbcSMatt Macy } 234*eda14cbcSMatt Macy 235*eda14cbcSMatt Macy int 236*eda14cbcSMatt Macy sha2_mod_fini(void) 237*eda14cbcSMatt Macy { 238*eda14cbcSMatt Macy int ret; 239*eda14cbcSMatt Macy 240*eda14cbcSMatt Macy if (sha2_prov_handle != 0) { 241*eda14cbcSMatt Macy if ((ret = crypto_unregister_provider(sha2_prov_handle)) != 242*eda14cbcSMatt Macy CRYPTO_SUCCESS) { 243*eda14cbcSMatt Macy cmn_err(CE_WARN, 244*eda14cbcSMatt Macy "sha2 _fini: crypto_unregister_provider() " 245*eda14cbcSMatt Macy "failed (0x%x)", ret); 246*eda14cbcSMatt Macy return (EBUSY); 247*eda14cbcSMatt Macy } 248*eda14cbcSMatt Macy sha2_prov_handle = 0; 249*eda14cbcSMatt Macy } 250*eda14cbcSMatt Macy 251*eda14cbcSMatt Macy return (mod_remove(&modlinkage)); 252*eda14cbcSMatt Macy } 253*eda14cbcSMatt Macy 254*eda14cbcSMatt Macy /* 255*eda14cbcSMatt Macy * KCF software provider control entry points. 256*eda14cbcSMatt Macy */ 257*eda14cbcSMatt Macy /* ARGSUSED */ 258*eda14cbcSMatt Macy static void 259*eda14cbcSMatt Macy sha2_provider_status(crypto_provider_handle_t provider, uint_t *status) 260*eda14cbcSMatt Macy { 261*eda14cbcSMatt Macy *status = CRYPTO_PROVIDER_READY; 262*eda14cbcSMatt Macy } 263*eda14cbcSMatt Macy 264*eda14cbcSMatt Macy /* 265*eda14cbcSMatt Macy * KCF software provider digest entry points. 266*eda14cbcSMatt Macy */ 267*eda14cbcSMatt Macy 268*eda14cbcSMatt Macy static int 269*eda14cbcSMatt Macy sha2_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 270*eda14cbcSMatt Macy crypto_req_handle_t req) 271*eda14cbcSMatt Macy { 272*eda14cbcSMatt Macy 273*eda14cbcSMatt Macy /* 274*eda14cbcSMatt Macy * Allocate and initialize SHA2 context. 275*eda14cbcSMatt Macy */ 276*eda14cbcSMatt Macy ctx->cc_provider_private = kmem_alloc(sizeof (sha2_ctx_t), 277*eda14cbcSMatt Macy crypto_kmflag(req)); 278*eda14cbcSMatt Macy if (ctx->cc_provider_private == NULL) 279*eda14cbcSMatt Macy return (CRYPTO_HOST_MEMORY); 280*eda14cbcSMatt Macy 281*eda14cbcSMatt Macy PROV_SHA2_CTX(ctx)->sc_mech_type = mechanism->cm_type; 282*eda14cbcSMatt Macy SHA2Init(mechanism->cm_type, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx); 283*eda14cbcSMatt Macy 284*eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 285*eda14cbcSMatt Macy } 286*eda14cbcSMatt Macy 287*eda14cbcSMatt Macy /* 288*eda14cbcSMatt Macy * Helper SHA2 digest update function for uio data. 289*eda14cbcSMatt Macy */ 290*eda14cbcSMatt Macy static int 291*eda14cbcSMatt Macy sha2_digest_update_uio(SHA2_CTX *sha2_ctx, crypto_data_t *data) 292*eda14cbcSMatt Macy { 293*eda14cbcSMatt Macy off_t offset = data->cd_offset; 294*eda14cbcSMatt Macy size_t length = data->cd_length; 295*eda14cbcSMatt Macy uint_t vec_idx = 0; 296*eda14cbcSMatt Macy size_t cur_len; 297*eda14cbcSMatt Macy 298*eda14cbcSMatt Macy /* we support only kernel buffer */ 299*eda14cbcSMatt Macy if (uio_segflg(data->cd_uio) != UIO_SYSSPACE) 300*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 301*eda14cbcSMatt Macy 302*eda14cbcSMatt Macy /* 303*eda14cbcSMatt Macy * Jump to the first iovec containing data to be 304*eda14cbcSMatt Macy * digested. 305*eda14cbcSMatt Macy */ 306*eda14cbcSMatt Macy offset = uio_index_at_offset(data->cd_uio, offset, &vec_idx); 307*eda14cbcSMatt Macy if (vec_idx == uio_iovcnt(data->cd_uio)) { 308*eda14cbcSMatt Macy /* 309*eda14cbcSMatt Macy * The caller specified an offset that is larger than the 310*eda14cbcSMatt Macy * total size of the buffers it provided. 311*eda14cbcSMatt Macy */ 312*eda14cbcSMatt Macy return (CRYPTO_DATA_LEN_RANGE); 313*eda14cbcSMatt Macy } 314*eda14cbcSMatt Macy 315*eda14cbcSMatt Macy /* 316*eda14cbcSMatt Macy * Now do the digesting on the iovecs. 317*eda14cbcSMatt Macy */ 318*eda14cbcSMatt Macy while (vec_idx < uio_iovcnt(data->cd_uio) && length > 0) { 319*eda14cbcSMatt Macy cur_len = MIN(uio_iovlen(data->cd_uio, vec_idx) - 320*eda14cbcSMatt Macy offset, length); 321*eda14cbcSMatt Macy 322*eda14cbcSMatt Macy SHA2Update(sha2_ctx, (uint8_t *)uio_iovbase(data->cd_uio, 323*eda14cbcSMatt Macy vec_idx) + offset, cur_len); 324*eda14cbcSMatt Macy length -= cur_len; 325*eda14cbcSMatt Macy vec_idx++; 326*eda14cbcSMatt Macy offset = 0; 327*eda14cbcSMatt Macy } 328*eda14cbcSMatt Macy 329*eda14cbcSMatt Macy if (vec_idx == uio_iovcnt(data->cd_uio) && length > 0) { 330*eda14cbcSMatt Macy /* 331*eda14cbcSMatt Macy * The end of the specified iovec's was reached but 332*eda14cbcSMatt Macy * the length requested could not be processed, i.e. 333*eda14cbcSMatt Macy * The caller requested to digest more data than it provided. 334*eda14cbcSMatt Macy */ 335*eda14cbcSMatt Macy return (CRYPTO_DATA_LEN_RANGE); 336*eda14cbcSMatt Macy } 337*eda14cbcSMatt Macy 338*eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 339*eda14cbcSMatt Macy } 340*eda14cbcSMatt Macy 341*eda14cbcSMatt Macy /* 342*eda14cbcSMatt Macy * Helper SHA2 digest final function for uio data. 343*eda14cbcSMatt Macy * digest_len is the length of the desired digest. If digest_len 344*eda14cbcSMatt Macy * is smaller than the default SHA2 digest length, the caller 345*eda14cbcSMatt Macy * must pass a scratch buffer, digest_scratch, which must 346*eda14cbcSMatt Macy * be at least the algorithm's digest length bytes. 347*eda14cbcSMatt Macy */ 348*eda14cbcSMatt Macy static int 349*eda14cbcSMatt Macy sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest, 350*eda14cbcSMatt Macy ulong_t digest_len, uchar_t *digest_scratch) 351*eda14cbcSMatt Macy { 352*eda14cbcSMatt Macy off_t offset = digest->cd_offset; 353*eda14cbcSMatt Macy uint_t vec_idx = 0; 354*eda14cbcSMatt Macy 355*eda14cbcSMatt Macy /* we support only kernel buffer */ 356*eda14cbcSMatt Macy if (uio_segflg(digest->cd_uio) != UIO_SYSSPACE) 357*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 358*eda14cbcSMatt Macy 359*eda14cbcSMatt Macy /* 360*eda14cbcSMatt Macy * Jump to the first iovec containing ptr to the digest to 361*eda14cbcSMatt Macy * be returned. 362*eda14cbcSMatt Macy */ 363*eda14cbcSMatt Macy offset = uio_index_at_offset(digest->cd_uio, offset, &vec_idx); 364*eda14cbcSMatt Macy if (vec_idx == uio_iovcnt(digest->cd_uio)) { 365*eda14cbcSMatt Macy /* 366*eda14cbcSMatt Macy * The caller specified an offset that is 367*eda14cbcSMatt Macy * larger than the total size of the buffers 368*eda14cbcSMatt Macy * it provided. 369*eda14cbcSMatt Macy */ 370*eda14cbcSMatt Macy return (CRYPTO_DATA_LEN_RANGE); 371*eda14cbcSMatt Macy } 372*eda14cbcSMatt Macy 373*eda14cbcSMatt Macy if (offset + digest_len <= 374*eda14cbcSMatt Macy uio_iovlen(digest->cd_uio, vec_idx)) { 375*eda14cbcSMatt Macy /* 376*eda14cbcSMatt Macy * The computed SHA2 digest will fit in the current 377*eda14cbcSMatt Macy * iovec. 378*eda14cbcSMatt Macy */ 379*eda14cbcSMatt Macy if (((sha2_ctx->algotype <= SHA256_HMAC_GEN_MECH_INFO_TYPE) && 380*eda14cbcSMatt Macy (digest_len != SHA256_DIGEST_LENGTH)) || 381*eda14cbcSMatt Macy ((sha2_ctx->algotype > SHA256_HMAC_GEN_MECH_INFO_TYPE) && 382*eda14cbcSMatt Macy (digest_len != SHA512_DIGEST_LENGTH))) { 383*eda14cbcSMatt Macy /* 384*eda14cbcSMatt Macy * The caller requested a short digest. Digest 385*eda14cbcSMatt Macy * into a scratch buffer and return to 386*eda14cbcSMatt Macy * the user only what was requested. 387*eda14cbcSMatt Macy */ 388*eda14cbcSMatt Macy SHA2Final(digest_scratch, sha2_ctx); 389*eda14cbcSMatt Macy 390*eda14cbcSMatt Macy bcopy(digest_scratch, (uchar_t *)uio_iovbase(digest-> 391*eda14cbcSMatt Macy cd_uio, vec_idx) + offset, 392*eda14cbcSMatt Macy digest_len); 393*eda14cbcSMatt Macy } else { 394*eda14cbcSMatt Macy SHA2Final((uchar_t *)uio_iovbase(digest-> 395*eda14cbcSMatt Macy cd_uio, vec_idx) + offset, 396*eda14cbcSMatt Macy sha2_ctx); 397*eda14cbcSMatt Macy 398*eda14cbcSMatt Macy } 399*eda14cbcSMatt Macy } else { 400*eda14cbcSMatt Macy /* 401*eda14cbcSMatt Macy * The computed digest will be crossing one or more iovec's. 402*eda14cbcSMatt Macy * This is bad performance-wise but we need to support it. 403*eda14cbcSMatt Macy * Allocate a small scratch buffer on the stack and 404*eda14cbcSMatt Macy * copy it piece meal to the specified digest iovec's. 405*eda14cbcSMatt Macy */ 406*eda14cbcSMatt Macy uchar_t digest_tmp[SHA512_DIGEST_LENGTH]; 407*eda14cbcSMatt Macy off_t scratch_offset = 0; 408*eda14cbcSMatt Macy size_t length = digest_len; 409*eda14cbcSMatt Macy size_t cur_len; 410*eda14cbcSMatt Macy 411*eda14cbcSMatt Macy SHA2Final(digest_tmp, sha2_ctx); 412*eda14cbcSMatt Macy 413*eda14cbcSMatt Macy while (vec_idx < uio_iovcnt(digest->cd_uio) && length > 0) { 414*eda14cbcSMatt Macy cur_len = 415*eda14cbcSMatt Macy MIN(uio_iovlen(digest->cd_uio, vec_idx) - 416*eda14cbcSMatt Macy offset, length); 417*eda14cbcSMatt Macy bcopy(digest_tmp + scratch_offset, 418*eda14cbcSMatt Macy uio_iovbase(digest->cd_uio, vec_idx) + offset, 419*eda14cbcSMatt Macy cur_len); 420*eda14cbcSMatt Macy 421*eda14cbcSMatt Macy length -= cur_len; 422*eda14cbcSMatt Macy vec_idx++; 423*eda14cbcSMatt Macy scratch_offset += cur_len; 424*eda14cbcSMatt Macy offset = 0; 425*eda14cbcSMatt Macy } 426*eda14cbcSMatt Macy 427*eda14cbcSMatt Macy if (vec_idx == uio_iovcnt(digest->cd_uio) && length > 0) { 428*eda14cbcSMatt Macy /* 429*eda14cbcSMatt Macy * The end of the specified iovec's was reached but 430*eda14cbcSMatt Macy * the length requested could not be processed, i.e. 431*eda14cbcSMatt Macy * The caller requested to digest more data than it 432*eda14cbcSMatt Macy * provided. 433*eda14cbcSMatt Macy */ 434*eda14cbcSMatt Macy return (CRYPTO_DATA_LEN_RANGE); 435*eda14cbcSMatt Macy } 436*eda14cbcSMatt Macy } 437*eda14cbcSMatt Macy 438*eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 439*eda14cbcSMatt Macy } 440*eda14cbcSMatt Macy 441*eda14cbcSMatt Macy /* ARGSUSED */ 442*eda14cbcSMatt Macy static int 443*eda14cbcSMatt Macy sha2_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest, 444*eda14cbcSMatt Macy crypto_req_handle_t req) 445*eda14cbcSMatt Macy { 446*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 447*eda14cbcSMatt Macy uint_t sha_digest_len; 448*eda14cbcSMatt Macy 449*eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 450*eda14cbcSMatt Macy 451*eda14cbcSMatt Macy switch (PROV_SHA2_CTX(ctx)->sc_mech_type) { 452*eda14cbcSMatt Macy case SHA256_MECH_INFO_TYPE: 453*eda14cbcSMatt Macy sha_digest_len = SHA256_DIGEST_LENGTH; 454*eda14cbcSMatt Macy break; 455*eda14cbcSMatt Macy case SHA384_MECH_INFO_TYPE: 456*eda14cbcSMatt Macy sha_digest_len = SHA384_DIGEST_LENGTH; 457*eda14cbcSMatt Macy break; 458*eda14cbcSMatt Macy case SHA512_MECH_INFO_TYPE: 459*eda14cbcSMatt Macy sha_digest_len = SHA512_DIGEST_LENGTH; 460*eda14cbcSMatt Macy break; 461*eda14cbcSMatt Macy default: 462*eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 463*eda14cbcSMatt Macy } 464*eda14cbcSMatt Macy 465*eda14cbcSMatt Macy /* 466*eda14cbcSMatt Macy * We need to just return the length needed to store the output. 467*eda14cbcSMatt Macy * We should not destroy the context for the following cases. 468*eda14cbcSMatt Macy */ 469*eda14cbcSMatt Macy if ((digest->cd_length == 0) || 470*eda14cbcSMatt Macy (digest->cd_length < sha_digest_len)) { 471*eda14cbcSMatt Macy digest->cd_length = sha_digest_len; 472*eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 473*eda14cbcSMatt Macy } 474*eda14cbcSMatt Macy 475*eda14cbcSMatt Macy /* 476*eda14cbcSMatt Macy * Do the SHA2 update on the specified input data. 477*eda14cbcSMatt Macy */ 478*eda14cbcSMatt Macy switch (data->cd_format) { 479*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 480*eda14cbcSMatt Macy SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx, 481*eda14cbcSMatt Macy (uint8_t *)data->cd_raw.iov_base + data->cd_offset, 482*eda14cbcSMatt Macy data->cd_length); 483*eda14cbcSMatt Macy break; 484*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 485*eda14cbcSMatt Macy ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx, 486*eda14cbcSMatt Macy data); 487*eda14cbcSMatt Macy break; 488*eda14cbcSMatt Macy default: 489*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 490*eda14cbcSMatt Macy } 491*eda14cbcSMatt Macy 492*eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 493*eda14cbcSMatt Macy /* the update failed, free context and bail */ 494*eda14cbcSMatt Macy kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t)); 495*eda14cbcSMatt Macy ctx->cc_provider_private = NULL; 496*eda14cbcSMatt Macy digest->cd_length = 0; 497*eda14cbcSMatt Macy return (ret); 498*eda14cbcSMatt Macy } 499*eda14cbcSMatt Macy 500*eda14cbcSMatt Macy /* 501*eda14cbcSMatt Macy * Do a SHA2 final, must be done separately since the digest 502*eda14cbcSMatt Macy * type can be different than the input data type. 503*eda14cbcSMatt Macy */ 504*eda14cbcSMatt Macy switch (digest->cd_format) { 505*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 506*eda14cbcSMatt Macy SHA2Final((unsigned char *)digest->cd_raw.iov_base + 507*eda14cbcSMatt Macy digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx); 508*eda14cbcSMatt Macy break; 509*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 510*eda14cbcSMatt Macy ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx, 511*eda14cbcSMatt Macy digest, sha_digest_len, NULL); 512*eda14cbcSMatt Macy break; 513*eda14cbcSMatt Macy default: 514*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 515*eda14cbcSMatt Macy } 516*eda14cbcSMatt Macy 517*eda14cbcSMatt Macy /* all done, free context and return */ 518*eda14cbcSMatt Macy 519*eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) 520*eda14cbcSMatt Macy digest->cd_length = sha_digest_len; 521*eda14cbcSMatt Macy else 522*eda14cbcSMatt Macy digest->cd_length = 0; 523*eda14cbcSMatt Macy 524*eda14cbcSMatt Macy kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t)); 525*eda14cbcSMatt Macy ctx->cc_provider_private = NULL; 526*eda14cbcSMatt Macy return (ret); 527*eda14cbcSMatt Macy } 528*eda14cbcSMatt Macy 529*eda14cbcSMatt Macy /* ARGSUSED */ 530*eda14cbcSMatt Macy static int 531*eda14cbcSMatt Macy sha2_digest_update(crypto_ctx_t *ctx, crypto_data_t *data, 532*eda14cbcSMatt Macy crypto_req_handle_t req) 533*eda14cbcSMatt Macy { 534*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 535*eda14cbcSMatt Macy 536*eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 537*eda14cbcSMatt Macy 538*eda14cbcSMatt Macy /* 539*eda14cbcSMatt Macy * Do the SHA2 update on the specified input data. 540*eda14cbcSMatt Macy */ 541*eda14cbcSMatt Macy switch (data->cd_format) { 542*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 543*eda14cbcSMatt Macy SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx, 544*eda14cbcSMatt Macy (uint8_t *)data->cd_raw.iov_base + data->cd_offset, 545*eda14cbcSMatt Macy data->cd_length); 546*eda14cbcSMatt Macy break; 547*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 548*eda14cbcSMatt Macy ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx, 549*eda14cbcSMatt Macy data); 550*eda14cbcSMatt Macy break; 551*eda14cbcSMatt Macy default: 552*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 553*eda14cbcSMatt Macy } 554*eda14cbcSMatt Macy 555*eda14cbcSMatt Macy return (ret); 556*eda14cbcSMatt Macy } 557*eda14cbcSMatt Macy 558*eda14cbcSMatt Macy /* ARGSUSED */ 559*eda14cbcSMatt Macy static int 560*eda14cbcSMatt Macy sha2_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest, 561*eda14cbcSMatt Macy crypto_req_handle_t req) 562*eda14cbcSMatt Macy { 563*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 564*eda14cbcSMatt Macy uint_t sha_digest_len; 565*eda14cbcSMatt Macy 566*eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 567*eda14cbcSMatt Macy 568*eda14cbcSMatt Macy switch (PROV_SHA2_CTX(ctx)->sc_mech_type) { 569*eda14cbcSMatt Macy case SHA256_MECH_INFO_TYPE: 570*eda14cbcSMatt Macy sha_digest_len = SHA256_DIGEST_LENGTH; 571*eda14cbcSMatt Macy break; 572*eda14cbcSMatt Macy case SHA384_MECH_INFO_TYPE: 573*eda14cbcSMatt Macy sha_digest_len = SHA384_DIGEST_LENGTH; 574*eda14cbcSMatt Macy break; 575*eda14cbcSMatt Macy case SHA512_MECH_INFO_TYPE: 576*eda14cbcSMatt Macy sha_digest_len = SHA512_DIGEST_LENGTH; 577*eda14cbcSMatt Macy break; 578*eda14cbcSMatt Macy default: 579*eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 580*eda14cbcSMatt Macy } 581*eda14cbcSMatt Macy 582*eda14cbcSMatt Macy /* 583*eda14cbcSMatt Macy * We need to just return the length needed to store the output. 584*eda14cbcSMatt Macy * We should not destroy the context for the following cases. 585*eda14cbcSMatt Macy */ 586*eda14cbcSMatt Macy if ((digest->cd_length == 0) || 587*eda14cbcSMatt Macy (digest->cd_length < sha_digest_len)) { 588*eda14cbcSMatt Macy digest->cd_length = sha_digest_len; 589*eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 590*eda14cbcSMatt Macy } 591*eda14cbcSMatt Macy 592*eda14cbcSMatt Macy /* 593*eda14cbcSMatt Macy * Do a SHA2 final. 594*eda14cbcSMatt Macy */ 595*eda14cbcSMatt Macy switch (digest->cd_format) { 596*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 597*eda14cbcSMatt Macy SHA2Final((unsigned char *)digest->cd_raw.iov_base + 598*eda14cbcSMatt Macy digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx); 599*eda14cbcSMatt Macy break; 600*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 601*eda14cbcSMatt Macy ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx, 602*eda14cbcSMatt Macy digest, sha_digest_len, NULL); 603*eda14cbcSMatt Macy break; 604*eda14cbcSMatt Macy default: 605*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 606*eda14cbcSMatt Macy } 607*eda14cbcSMatt Macy 608*eda14cbcSMatt Macy /* all done, free context and return */ 609*eda14cbcSMatt Macy 610*eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) 611*eda14cbcSMatt Macy digest->cd_length = sha_digest_len; 612*eda14cbcSMatt Macy else 613*eda14cbcSMatt Macy digest->cd_length = 0; 614*eda14cbcSMatt Macy 615*eda14cbcSMatt Macy kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t)); 616*eda14cbcSMatt Macy ctx->cc_provider_private = NULL; 617*eda14cbcSMatt Macy 618*eda14cbcSMatt Macy return (ret); 619*eda14cbcSMatt Macy } 620*eda14cbcSMatt Macy 621*eda14cbcSMatt Macy /* ARGSUSED */ 622*eda14cbcSMatt Macy static int 623*eda14cbcSMatt Macy sha2_digest_atomic(crypto_provider_handle_t provider, 624*eda14cbcSMatt Macy crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 625*eda14cbcSMatt Macy crypto_data_t *data, crypto_data_t *digest, 626*eda14cbcSMatt Macy crypto_req_handle_t req) 627*eda14cbcSMatt Macy { 628*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 629*eda14cbcSMatt Macy SHA2_CTX sha2_ctx; 630*eda14cbcSMatt Macy uint32_t sha_digest_len; 631*eda14cbcSMatt Macy 632*eda14cbcSMatt Macy /* 633*eda14cbcSMatt Macy * Do the SHA inits. 634*eda14cbcSMatt Macy */ 635*eda14cbcSMatt Macy 636*eda14cbcSMatt Macy SHA2Init(mechanism->cm_type, &sha2_ctx); 637*eda14cbcSMatt Macy 638*eda14cbcSMatt Macy switch (data->cd_format) { 639*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 640*eda14cbcSMatt Macy SHA2Update(&sha2_ctx, (uint8_t *)data-> 641*eda14cbcSMatt Macy cd_raw.iov_base + data->cd_offset, data->cd_length); 642*eda14cbcSMatt Macy break; 643*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 644*eda14cbcSMatt Macy ret = sha2_digest_update_uio(&sha2_ctx, data); 645*eda14cbcSMatt Macy break; 646*eda14cbcSMatt Macy default: 647*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 648*eda14cbcSMatt Macy } 649*eda14cbcSMatt Macy 650*eda14cbcSMatt Macy /* 651*eda14cbcSMatt Macy * Do the SHA updates on the specified input data. 652*eda14cbcSMatt Macy */ 653*eda14cbcSMatt Macy 654*eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 655*eda14cbcSMatt Macy /* the update failed, bail */ 656*eda14cbcSMatt Macy digest->cd_length = 0; 657*eda14cbcSMatt Macy return (ret); 658*eda14cbcSMatt Macy } 659*eda14cbcSMatt Macy 660*eda14cbcSMatt Macy if (mechanism->cm_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) 661*eda14cbcSMatt Macy sha_digest_len = SHA256_DIGEST_LENGTH; 662*eda14cbcSMatt Macy else 663*eda14cbcSMatt Macy sha_digest_len = SHA512_DIGEST_LENGTH; 664*eda14cbcSMatt Macy 665*eda14cbcSMatt Macy /* 666*eda14cbcSMatt Macy * Do a SHA2 final, must be done separately since the digest 667*eda14cbcSMatt Macy * type can be different than the input data type. 668*eda14cbcSMatt Macy */ 669*eda14cbcSMatt Macy switch (digest->cd_format) { 670*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 671*eda14cbcSMatt Macy SHA2Final((unsigned char *)digest->cd_raw.iov_base + 672*eda14cbcSMatt Macy digest->cd_offset, &sha2_ctx); 673*eda14cbcSMatt Macy break; 674*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 675*eda14cbcSMatt Macy ret = sha2_digest_final_uio(&sha2_ctx, digest, 676*eda14cbcSMatt Macy sha_digest_len, NULL); 677*eda14cbcSMatt Macy break; 678*eda14cbcSMatt Macy default: 679*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 680*eda14cbcSMatt Macy } 681*eda14cbcSMatt Macy 682*eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) 683*eda14cbcSMatt Macy digest->cd_length = sha_digest_len; 684*eda14cbcSMatt Macy else 685*eda14cbcSMatt Macy digest->cd_length = 0; 686*eda14cbcSMatt Macy 687*eda14cbcSMatt Macy return (ret); 688*eda14cbcSMatt Macy } 689*eda14cbcSMatt Macy 690*eda14cbcSMatt Macy /* 691*eda14cbcSMatt Macy * KCF software provider mac entry points. 692*eda14cbcSMatt Macy * 693*eda14cbcSMatt Macy * SHA2 HMAC is: SHA2(key XOR opad, SHA2(key XOR ipad, text)) 694*eda14cbcSMatt Macy * 695*eda14cbcSMatt Macy * Init: 696*eda14cbcSMatt Macy * The initialization routine initializes what we denote 697*eda14cbcSMatt Macy * as the inner and outer contexts by doing 698*eda14cbcSMatt Macy * - for inner context: SHA2(key XOR ipad) 699*eda14cbcSMatt Macy * - for outer context: SHA2(key XOR opad) 700*eda14cbcSMatt Macy * 701*eda14cbcSMatt Macy * Update: 702*eda14cbcSMatt Macy * Each subsequent SHA2 HMAC update will result in an 703*eda14cbcSMatt Macy * update of the inner context with the specified data. 704*eda14cbcSMatt Macy * 705*eda14cbcSMatt Macy * Final: 706*eda14cbcSMatt Macy * The SHA2 HMAC final will do a SHA2 final operation on the 707*eda14cbcSMatt Macy * inner context, and the resulting digest will be used 708*eda14cbcSMatt Macy * as the data for an update on the outer context. Last 709*eda14cbcSMatt Macy * but not least, a SHA2 final on the outer context will 710*eda14cbcSMatt Macy * be performed to obtain the SHA2 HMAC digest to return 711*eda14cbcSMatt Macy * to the user. 712*eda14cbcSMatt Macy */ 713*eda14cbcSMatt Macy 714*eda14cbcSMatt Macy /* 715*eda14cbcSMatt Macy * Initialize a SHA2-HMAC context. 716*eda14cbcSMatt Macy */ 717*eda14cbcSMatt Macy static void 718*eda14cbcSMatt Macy sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes) 719*eda14cbcSMatt Macy { 720*eda14cbcSMatt Macy uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)]; 721*eda14cbcSMatt Macy uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)]; 722*eda14cbcSMatt Macy int i, block_size, blocks_per_int64; 723*eda14cbcSMatt Macy 724*eda14cbcSMatt Macy /* Determine the block size */ 725*eda14cbcSMatt Macy if (ctx->hc_mech_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) { 726*eda14cbcSMatt Macy block_size = SHA256_HMAC_BLOCK_SIZE; 727*eda14cbcSMatt Macy blocks_per_int64 = SHA256_HMAC_BLOCK_SIZE / sizeof (uint64_t); 728*eda14cbcSMatt Macy } else { 729*eda14cbcSMatt Macy block_size = SHA512_HMAC_BLOCK_SIZE; 730*eda14cbcSMatt Macy blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t); 731*eda14cbcSMatt Macy } 732*eda14cbcSMatt Macy 733*eda14cbcSMatt Macy (void) bzero(ipad, block_size); 734*eda14cbcSMatt Macy (void) bzero(opad, block_size); 735*eda14cbcSMatt Macy (void) bcopy(keyval, ipad, length_in_bytes); 736*eda14cbcSMatt Macy (void) bcopy(keyval, opad, length_in_bytes); 737*eda14cbcSMatt Macy 738*eda14cbcSMatt Macy /* XOR key with ipad (0x36) and opad (0x5c) */ 739*eda14cbcSMatt Macy for (i = 0; i < blocks_per_int64; i ++) { 740*eda14cbcSMatt Macy ipad[i] ^= 0x3636363636363636; 741*eda14cbcSMatt Macy opad[i] ^= 0x5c5c5c5c5c5c5c5c; 742*eda14cbcSMatt Macy } 743*eda14cbcSMatt Macy 744*eda14cbcSMatt Macy /* perform SHA2 on ipad */ 745*eda14cbcSMatt Macy SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext); 746*eda14cbcSMatt Macy SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size); 747*eda14cbcSMatt Macy 748*eda14cbcSMatt Macy /* perform SHA2 on opad */ 749*eda14cbcSMatt Macy SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext); 750*eda14cbcSMatt Macy SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size); 751*eda14cbcSMatt Macy 752*eda14cbcSMatt Macy } 753*eda14cbcSMatt Macy 754*eda14cbcSMatt Macy /* 755*eda14cbcSMatt Macy */ 756*eda14cbcSMatt Macy static int 757*eda14cbcSMatt Macy sha2_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 758*eda14cbcSMatt Macy crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 759*eda14cbcSMatt Macy crypto_req_handle_t req) 760*eda14cbcSMatt Macy { 761*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 762*eda14cbcSMatt Macy uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 763*eda14cbcSMatt Macy uint_t sha_digest_len, sha_hmac_block_size; 764*eda14cbcSMatt Macy 765*eda14cbcSMatt Macy /* 766*eda14cbcSMatt Macy * Set the digest length and block size to values appropriate to the 767*eda14cbcSMatt Macy * mechanism 768*eda14cbcSMatt Macy */ 769*eda14cbcSMatt Macy switch (mechanism->cm_type) { 770*eda14cbcSMatt Macy case SHA256_HMAC_MECH_INFO_TYPE: 771*eda14cbcSMatt Macy case SHA256_HMAC_GEN_MECH_INFO_TYPE: 772*eda14cbcSMatt Macy sha_digest_len = SHA256_DIGEST_LENGTH; 773*eda14cbcSMatt Macy sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE; 774*eda14cbcSMatt Macy break; 775*eda14cbcSMatt Macy case SHA384_HMAC_MECH_INFO_TYPE: 776*eda14cbcSMatt Macy case SHA384_HMAC_GEN_MECH_INFO_TYPE: 777*eda14cbcSMatt Macy case SHA512_HMAC_MECH_INFO_TYPE: 778*eda14cbcSMatt Macy case SHA512_HMAC_GEN_MECH_INFO_TYPE: 779*eda14cbcSMatt Macy sha_digest_len = SHA512_DIGEST_LENGTH; 780*eda14cbcSMatt Macy sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE; 781*eda14cbcSMatt Macy break; 782*eda14cbcSMatt Macy default: 783*eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 784*eda14cbcSMatt Macy } 785*eda14cbcSMatt Macy 786*eda14cbcSMatt Macy if (key->ck_format != CRYPTO_KEY_RAW) 787*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 788*eda14cbcSMatt Macy 789*eda14cbcSMatt Macy ctx->cc_provider_private = kmem_alloc(sizeof (sha2_hmac_ctx_t), 790*eda14cbcSMatt Macy crypto_kmflag(req)); 791*eda14cbcSMatt Macy if (ctx->cc_provider_private == NULL) 792*eda14cbcSMatt Macy return (CRYPTO_HOST_MEMORY); 793*eda14cbcSMatt Macy 794*eda14cbcSMatt Macy PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type; 795*eda14cbcSMatt Macy if (ctx_template != NULL) { 796*eda14cbcSMatt Macy /* reuse context template */ 797*eda14cbcSMatt Macy bcopy(ctx_template, PROV_SHA2_HMAC_CTX(ctx), 798*eda14cbcSMatt Macy sizeof (sha2_hmac_ctx_t)); 799*eda14cbcSMatt Macy } else { 800*eda14cbcSMatt Macy /* no context template, compute context */ 801*eda14cbcSMatt Macy if (keylen_in_bytes > sha_hmac_block_size) { 802*eda14cbcSMatt Macy uchar_t digested_key[SHA512_DIGEST_LENGTH]; 803*eda14cbcSMatt Macy sha2_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private; 804*eda14cbcSMatt Macy 805*eda14cbcSMatt Macy /* 806*eda14cbcSMatt Macy * Hash the passed-in key to get a smaller key. 807*eda14cbcSMatt Macy * The inner context is used since it hasn't been 808*eda14cbcSMatt Macy * initialized yet. 809*eda14cbcSMatt Macy */ 810*eda14cbcSMatt Macy PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3, 811*eda14cbcSMatt Macy &hmac_ctx->hc_icontext, 812*eda14cbcSMatt Macy key->ck_data, keylen_in_bytes, digested_key); 813*eda14cbcSMatt Macy sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx), 814*eda14cbcSMatt Macy digested_key, sha_digest_len); 815*eda14cbcSMatt Macy } else { 816*eda14cbcSMatt Macy sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx), 817*eda14cbcSMatt Macy key->ck_data, keylen_in_bytes); 818*eda14cbcSMatt Macy } 819*eda14cbcSMatt Macy } 820*eda14cbcSMatt Macy 821*eda14cbcSMatt Macy /* 822*eda14cbcSMatt Macy * Get the mechanism parameters, if applicable. 823*eda14cbcSMatt Macy */ 824*eda14cbcSMatt Macy if (mechanism->cm_type % 3 == 2) { 825*eda14cbcSMatt Macy if (mechanism->cm_param == NULL || 826*eda14cbcSMatt Macy mechanism->cm_param_len != sizeof (ulong_t)) 827*eda14cbcSMatt Macy ret = CRYPTO_MECHANISM_PARAM_INVALID; 828*eda14cbcSMatt Macy PROV_SHA2_GET_DIGEST_LEN(mechanism, 829*eda14cbcSMatt Macy PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len); 830*eda14cbcSMatt Macy if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len > sha_digest_len) 831*eda14cbcSMatt Macy ret = CRYPTO_MECHANISM_PARAM_INVALID; 832*eda14cbcSMatt Macy } 833*eda14cbcSMatt Macy 834*eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 835*eda14cbcSMatt Macy bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t)); 836*eda14cbcSMatt Macy kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t)); 837*eda14cbcSMatt Macy ctx->cc_provider_private = NULL; 838*eda14cbcSMatt Macy } 839*eda14cbcSMatt Macy 840*eda14cbcSMatt Macy return (ret); 841*eda14cbcSMatt Macy } 842*eda14cbcSMatt Macy 843*eda14cbcSMatt Macy /* ARGSUSED */ 844*eda14cbcSMatt Macy static int 845*eda14cbcSMatt Macy sha2_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, 846*eda14cbcSMatt Macy crypto_req_handle_t req) 847*eda14cbcSMatt Macy { 848*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 849*eda14cbcSMatt Macy 850*eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 851*eda14cbcSMatt Macy 852*eda14cbcSMatt Macy /* 853*eda14cbcSMatt Macy * Do a SHA2 update of the inner context using the specified 854*eda14cbcSMatt Macy * data. 855*eda14cbcSMatt Macy */ 856*eda14cbcSMatt Macy switch (data->cd_format) { 857*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 858*eda14cbcSMatt Macy SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, 859*eda14cbcSMatt Macy (uint8_t *)data->cd_raw.iov_base + data->cd_offset, 860*eda14cbcSMatt Macy data->cd_length); 861*eda14cbcSMatt Macy break; 862*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 863*eda14cbcSMatt Macy ret = sha2_digest_update_uio( 864*eda14cbcSMatt Macy &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data); 865*eda14cbcSMatt Macy break; 866*eda14cbcSMatt Macy default: 867*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 868*eda14cbcSMatt Macy } 869*eda14cbcSMatt Macy 870*eda14cbcSMatt Macy return (ret); 871*eda14cbcSMatt Macy } 872*eda14cbcSMatt Macy 873*eda14cbcSMatt Macy /* ARGSUSED */ 874*eda14cbcSMatt Macy static int 875*eda14cbcSMatt Macy sha2_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req) 876*eda14cbcSMatt Macy { 877*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 878*eda14cbcSMatt Macy uchar_t digest[SHA512_DIGEST_LENGTH]; 879*eda14cbcSMatt Macy uint32_t digest_len, sha_digest_len; 880*eda14cbcSMatt Macy 881*eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 882*eda14cbcSMatt Macy 883*eda14cbcSMatt Macy /* Set the digest lengths to values appropriate to the mechanism */ 884*eda14cbcSMatt Macy switch (PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type) { 885*eda14cbcSMatt Macy case SHA256_HMAC_MECH_INFO_TYPE: 886*eda14cbcSMatt Macy sha_digest_len = digest_len = SHA256_DIGEST_LENGTH; 887*eda14cbcSMatt Macy break; 888*eda14cbcSMatt Macy case SHA384_HMAC_MECH_INFO_TYPE: 889*eda14cbcSMatt Macy sha_digest_len = digest_len = SHA384_DIGEST_LENGTH; 890*eda14cbcSMatt Macy break; 891*eda14cbcSMatt Macy case SHA512_HMAC_MECH_INFO_TYPE: 892*eda14cbcSMatt Macy sha_digest_len = digest_len = SHA512_DIGEST_LENGTH; 893*eda14cbcSMatt Macy break; 894*eda14cbcSMatt Macy case SHA256_HMAC_GEN_MECH_INFO_TYPE: 895*eda14cbcSMatt Macy sha_digest_len = SHA256_DIGEST_LENGTH; 896*eda14cbcSMatt Macy digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len; 897*eda14cbcSMatt Macy break; 898*eda14cbcSMatt Macy case SHA384_HMAC_GEN_MECH_INFO_TYPE: 899*eda14cbcSMatt Macy case SHA512_HMAC_GEN_MECH_INFO_TYPE: 900*eda14cbcSMatt Macy sha_digest_len = SHA512_DIGEST_LENGTH; 901*eda14cbcSMatt Macy digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len; 902*eda14cbcSMatt Macy break; 903*eda14cbcSMatt Macy default: 904*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 905*eda14cbcSMatt Macy } 906*eda14cbcSMatt Macy 907*eda14cbcSMatt Macy /* 908*eda14cbcSMatt Macy * We need to just return the length needed to store the output. 909*eda14cbcSMatt Macy * We should not destroy the context for the following cases. 910*eda14cbcSMatt Macy */ 911*eda14cbcSMatt Macy if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) { 912*eda14cbcSMatt Macy mac->cd_length = digest_len; 913*eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 914*eda14cbcSMatt Macy } 915*eda14cbcSMatt Macy 916*eda14cbcSMatt Macy /* 917*eda14cbcSMatt Macy * Do a SHA2 final on the inner context. 918*eda14cbcSMatt Macy */ 919*eda14cbcSMatt Macy SHA2Final(digest, &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext); 920*eda14cbcSMatt Macy 921*eda14cbcSMatt Macy /* 922*eda14cbcSMatt Macy * Do a SHA2 update on the outer context, feeding the inner 923*eda14cbcSMatt Macy * digest as data. 924*eda14cbcSMatt Macy */ 925*eda14cbcSMatt Macy SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, digest, 926*eda14cbcSMatt Macy sha_digest_len); 927*eda14cbcSMatt Macy 928*eda14cbcSMatt Macy /* 929*eda14cbcSMatt Macy * Do a SHA2 final on the outer context, storing the computing 930*eda14cbcSMatt Macy * digest in the users buffer. 931*eda14cbcSMatt Macy */ 932*eda14cbcSMatt Macy switch (mac->cd_format) { 933*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 934*eda14cbcSMatt Macy if (digest_len != sha_digest_len) { 935*eda14cbcSMatt Macy /* 936*eda14cbcSMatt Macy * The caller requested a short digest. Digest 937*eda14cbcSMatt Macy * into a scratch buffer and return to 938*eda14cbcSMatt Macy * the user only what was requested. 939*eda14cbcSMatt Macy */ 940*eda14cbcSMatt Macy SHA2Final(digest, 941*eda14cbcSMatt Macy &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext); 942*eda14cbcSMatt Macy bcopy(digest, (unsigned char *)mac->cd_raw.iov_base + 943*eda14cbcSMatt Macy mac->cd_offset, digest_len); 944*eda14cbcSMatt Macy } else { 945*eda14cbcSMatt Macy SHA2Final((unsigned char *)mac->cd_raw.iov_base + 946*eda14cbcSMatt Macy mac->cd_offset, 947*eda14cbcSMatt Macy &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext); 948*eda14cbcSMatt Macy } 949*eda14cbcSMatt Macy break; 950*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 951*eda14cbcSMatt Macy ret = sha2_digest_final_uio( 952*eda14cbcSMatt Macy &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac, 953*eda14cbcSMatt Macy digest_len, digest); 954*eda14cbcSMatt Macy break; 955*eda14cbcSMatt Macy default: 956*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 957*eda14cbcSMatt Macy } 958*eda14cbcSMatt Macy 959*eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) 960*eda14cbcSMatt Macy mac->cd_length = digest_len; 961*eda14cbcSMatt Macy else 962*eda14cbcSMatt Macy mac->cd_length = 0; 963*eda14cbcSMatt Macy 964*eda14cbcSMatt Macy bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t)); 965*eda14cbcSMatt Macy kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t)); 966*eda14cbcSMatt Macy ctx->cc_provider_private = NULL; 967*eda14cbcSMatt Macy 968*eda14cbcSMatt Macy return (ret); 969*eda14cbcSMatt Macy } 970*eda14cbcSMatt Macy 971*eda14cbcSMatt Macy #define SHA2_MAC_UPDATE(data, ctx, ret) { \ 972*eda14cbcSMatt Macy switch (data->cd_format) { \ 973*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: \ 974*eda14cbcSMatt Macy SHA2Update(&(ctx).hc_icontext, \ 975*eda14cbcSMatt Macy (uint8_t *)data->cd_raw.iov_base + \ 976*eda14cbcSMatt Macy data->cd_offset, data->cd_length); \ 977*eda14cbcSMatt Macy break; \ 978*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: \ 979*eda14cbcSMatt Macy ret = sha2_digest_update_uio(&(ctx).hc_icontext, data); \ 980*eda14cbcSMatt Macy break; \ 981*eda14cbcSMatt Macy default: \ 982*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; \ 983*eda14cbcSMatt Macy } \ 984*eda14cbcSMatt Macy } 985*eda14cbcSMatt Macy 986*eda14cbcSMatt Macy /* ARGSUSED */ 987*eda14cbcSMatt Macy static int 988*eda14cbcSMatt Macy sha2_mac_atomic(crypto_provider_handle_t provider, 989*eda14cbcSMatt Macy crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 990*eda14cbcSMatt Macy crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 991*eda14cbcSMatt Macy crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 992*eda14cbcSMatt Macy { 993*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 994*eda14cbcSMatt Macy uchar_t digest[SHA512_DIGEST_LENGTH]; 995*eda14cbcSMatt Macy sha2_hmac_ctx_t sha2_hmac_ctx; 996*eda14cbcSMatt Macy uint32_t sha_digest_len, digest_len, sha_hmac_block_size; 997*eda14cbcSMatt Macy uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 998*eda14cbcSMatt Macy 999*eda14cbcSMatt Macy /* 1000*eda14cbcSMatt Macy * Set the digest length and block size to values appropriate to the 1001*eda14cbcSMatt Macy * mechanism 1002*eda14cbcSMatt Macy */ 1003*eda14cbcSMatt Macy switch (mechanism->cm_type) { 1004*eda14cbcSMatt Macy case SHA256_HMAC_MECH_INFO_TYPE: 1005*eda14cbcSMatt Macy case SHA256_HMAC_GEN_MECH_INFO_TYPE: 1006*eda14cbcSMatt Macy sha_digest_len = digest_len = SHA256_DIGEST_LENGTH; 1007*eda14cbcSMatt Macy sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE; 1008*eda14cbcSMatt Macy break; 1009*eda14cbcSMatt Macy case SHA384_HMAC_MECH_INFO_TYPE: 1010*eda14cbcSMatt Macy case SHA384_HMAC_GEN_MECH_INFO_TYPE: 1011*eda14cbcSMatt Macy case SHA512_HMAC_MECH_INFO_TYPE: 1012*eda14cbcSMatt Macy case SHA512_HMAC_GEN_MECH_INFO_TYPE: 1013*eda14cbcSMatt Macy sha_digest_len = digest_len = SHA512_DIGEST_LENGTH; 1014*eda14cbcSMatt Macy sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE; 1015*eda14cbcSMatt Macy break; 1016*eda14cbcSMatt Macy default: 1017*eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 1018*eda14cbcSMatt Macy } 1019*eda14cbcSMatt Macy 1020*eda14cbcSMatt Macy /* Add support for key by attributes (RFE 4706552) */ 1021*eda14cbcSMatt Macy if (key->ck_format != CRYPTO_KEY_RAW) 1022*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 1023*eda14cbcSMatt Macy 1024*eda14cbcSMatt Macy if (ctx_template != NULL) { 1025*eda14cbcSMatt Macy /* reuse context template */ 1026*eda14cbcSMatt Macy bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t)); 1027*eda14cbcSMatt Macy } else { 1028*eda14cbcSMatt Macy sha2_hmac_ctx.hc_mech_type = mechanism->cm_type; 1029*eda14cbcSMatt Macy /* no context template, initialize context */ 1030*eda14cbcSMatt Macy if (keylen_in_bytes > sha_hmac_block_size) { 1031*eda14cbcSMatt Macy /* 1032*eda14cbcSMatt Macy * Hash the passed-in key to get a smaller key. 1033*eda14cbcSMatt Macy * The inner context is used since it hasn't been 1034*eda14cbcSMatt Macy * initialized yet. 1035*eda14cbcSMatt Macy */ 1036*eda14cbcSMatt Macy PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3, 1037*eda14cbcSMatt Macy &sha2_hmac_ctx.hc_icontext, 1038*eda14cbcSMatt Macy key->ck_data, keylen_in_bytes, digest); 1039*eda14cbcSMatt Macy sha2_mac_init_ctx(&sha2_hmac_ctx, digest, 1040*eda14cbcSMatt Macy sha_digest_len); 1041*eda14cbcSMatt Macy } else { 1042*eda14cbcSMatt Macy sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data, 1043*eda14cbcSMatt Macy keylen_in_bytes); 1044*eda14cbcSMatt Macy } 1045*eda14cbcSMatt Macy } 1046*eda14cbcSMatt Macy 1047*eda14cbcSMatt Macy /* get the mechanism parameters, if applicable */ 1048*eda14cbcSMatt Macy if ((mechanism->cm_type % 3) == 2) { 1049*eda14cbcSMatt Macy if (mechanism->cm_param == NULL || 1050*eda14cbcSMatt Macy mechanism->cm_param_len != sizeof (ulong_t)) { 1051*eda14cbcSMatt Macy ret = CRYPTO_MECHANISM_PARAM_INVALID; 1052*eda14cbcSMatt Macy goto bail; 1053*eda14cbcSMatt Macy } 1054*eda14cbcSMatt Macy PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len); 1055*eda14cbcSMatt Macy if (digest_len > sha_digest_len) { 1056*eda14cbcSMatt Macy ret = CRYPTO_MECHANISM_PARAM_INVALID; 1057*eda14cbcSMatt Macy goto bail; 1058*eda14cbcSMatt Macy } 1059*eda14cbcSMatt Macy } 1060*eda14cbcSMatt Macy 1061*eda14cbcSMatt Macy /* do a SHA2 update of the inner context using the specified data */ 1062*eda14cbcSMatt Macy SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret); 1063*eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 1064*eda14cbcSMatt Macy /* the update failed, free context and bail */ 1065*eda14cbcSMatt Macy goto bail; 1066*eda14cbcSMatt Macy 1067*eda14cbcSMatt Macy /* 1068*eda14cbcSMatt Macy * Do a SHA2 final on the inner context. 1069*eda14cbcSMatt Macy */ 1070*eda14cbcSMatt Macy SHA2Final(digest, &sha2_hmac_ctx.hc_icontext); 1071*eda14cbcSMatt Macy 1072*eda14cbcSMatt Macy /* 1073*eda14cbcSMatt Macy * Do an SHA2 update on the outer context, feeding the inner 1074*eda14cbcSMatt Macy * digest as data. 1075*eda14cbcSMatt Macy * 1076*eda14cbcSMatt Macy * HMAC-SHA384 needs special handling as the outer hash needs only 48 1077*eda14cbcSMatt Macy * bytes of the inner hash value. 1078*eda14cbcSMatt Macy */ 1079*eda14cbcSMatt Macy if (mechanism->cm_type == SHA384_HMAC_MECH_INFO_TYPE || 1080*eda14cbcSMatt Macy mechanism->cm_type == SHA384_HMAC_GEN_MECH_INFO_TYPE) 1081*eda14cbcSMatt Macy SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, 1082*eda14cbcSMatt Macy SHA384_DIGEST_LENGTH); 1083*eda14cbcSMatt Macy else 1084*eda14cbcSMatt Macy SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len); 1085*eda14cbcSMatt Macy 1086*eda14cbcSMatt Macy /* 1087*eda14cbcSMatt Macy * Do a SHA2 final on the outer context, storing the computed 1088*eda14cbcSMatt Macy * digest in the users buffer. 1089*eda14cbcSMatt Macy */ 1090*eda14cbcSMatt Macy switch (mac->cd_format) { 1091*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 1092*eda14cbcSMatt Macy if (digest_len != sha_digest_len) { 1093*eda14cbcSMatt Macy /* 1094*eda14cbcSMatt Macy * The caller requested a short digest. Digest 1095*eda14cbcSMatt Macy * into a scratch buffer and return to 1096*eda14cbcSMatt Macy * the user only what was requested. 1097*eda14cbcSMatt Macy */ 1098*eda14cbcSMatt Macy SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext); 1099*eda14cbcSMatt Macy bcopy(digest, (unsigned char *)mac->cd_raw.iov_base + 1100*eda14cbcSMatt Macy mac->cd_offset, digest_len); 1101*eda14cbcSMatt Macy } else { 1102*eda14cbcSMatt Macy SHA2Final((unsigned char *)mac->cd_raw.iov_base + 1103*eda14cbcSMatt Macy mac->cd_offset, &sha2_hmac_ctx.hc_ocontext); 1104*eda14cbcSMatt Macy } 1105*eda14cbcSMatt Macy break; 1106*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 1107*eda14cbcSMatt Macy ret = sha2_digest_final_uio(&sha2_hmac_ctx.hc_ocontext, mac, 1108*eda14cbcSMatt Macy digest_len, digest); 1109*eda14cbcSMatt Macy break; 1110*eda14cbcSMatt Macy default: 1111*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 1112*eda14cbcSMatt Macy } 1113*eda14cbcSMatt Macy 1114*eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 1115*eda14cbcSMatt Macy mac->cd_length = digest_len; 1116*eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1117*eda14cbcSMatt Macy } 1118*eda14cbcSMatt Macy bail: 1119*eda14cbcSMatt Macy bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t)); 1120*eda14cbcSMatt Macy mac->cd_length = 0; 1121*eda14cbcSMatt Macy return (ret); 1122*eda14cbcSMatt Macy } 1123*eda14cbcSMatt Macy 1124*eda14cbcSMatt Macy /* ARGSUSED */ 1125*eda14cbcSMatt Macy static int 1126*eda14cbcSMatt Macy sha2_mac_verify_atomic(crypto_provider_handle_t provider, 1127*eda14cbcSMatt Macy crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1128*eda14cbcSMatt Macy crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 1129*eda14cbcSMatt Macy crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 1130*eda14cbcSMatt Macy { 1131*eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 1132*eda14cbcSMatt Macy uchar_t digest[SHA512_DIGEST_LENGTH]; 1133*eda14cbcSMatt Macy sha2_hmac_ctx_t sha2_hmac_ctx; 1134*eda14cbcSMatt Macy uint32_t sha_digest_len, digest_len, sha_hmac_block_size; 1135*eda14cbcSMatt Macy uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 1136*eda14cbcSMatt Macy 1137*eda14cbcSMatt Macy /* 1138*eda14cbcSMatt Macy * Set the digest length and block size to values appropriate to the 1139*eda14cbcSMatt Macy * mechanism 1140*eda14cbcSMatt Macy */ 1141*eda14cbcSMatt Macy switch (mechanism->cm_type) { 1142*eda14cbcSMatt Macy case SHA256_HMAC_MECH_INFO_TYPE: 1143*eda14cbcSMatt Macy case SHA256_HMAC_GEN_MECH_INFO_TYPE: 1144*eda14cbcSMatt Macy sha_digest_len = digest_len = SHA256_DIGEST_LENGTH; 1145*eda14cbcSMatt Macy sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE; 1146*eda14cbcSMatt Macy break; 1147*eda14cbcSMatt Macy case SHA384_HMAC_MECH_INFO_TYPE: 1148*eda14cbcSMatt Macy case SHA384_HMAC_GEN_MECH_INFO_TYPE: 1149*eda14cbcSMatt Macy case SHA512_HMAC_MECH_INFO_TYPE: 1150*eda14cbcSMatt Macy case SHA512_HMAC_GEN_MECH_INFO_TYPE: 1151*eda14cbcSMatt Macy sha_digest_len = digest_len = SHA512_DIGEST_LENGTH; 1152*eda14cbcSMatt Macy sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE; 1153*eda14cbcSMatt Macy break; 1154*eda14cbcSMatt Macy default: 1155*eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 1156*eda14cbcSMatt Macy } 1157*eda14cbcSMatt Macy 1158*eda14cbcSMatt Macy /* Add support for key by attributes (RFE 4706552) */ 1159*eda14cbcSMatt Macy if (key->ck_format != CRYPTO_KEY_RAW) 1160*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 1161*eda14cbcSMatt Macy 1162*eda14cbcSMatt Macy if (ctx_template != NULL) { 1163*eda14cbcSMatt Macy /* reuse context template */ 1164*eda14cbcSMatt Macy bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t)); 1165*eda14cbcSMatt Macy } else { 1166*eda14cbcSMatt Macy sha2_hmac_ctx.hc_mech_type = mechanism->cm_type; 1167*eda14cbcSMatt Macy /* no context template, initialize context */ 1168*eda14cbcSMatt Macy if (keylen_in_bytes > sha_hmac_block_size) { 1169*eda14cbcSMatt Macy /* 1170*eda14cbcSMatt Macy * Hash the passed-in key to get a smaller key. 1171*eda14cbcSMatt Macy * The inner context is used since it hasn't been 1172*eda14cbcSMatt Macy * initialized yet. 1173*eda14cbcSMatt Macy */ 1174*eda14cbcSMatt Macy PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3, 1175*eda14cbcSMatt Macy &sha2_hmac_ctx.hc_icontext, 1176*eda14cbcSMatt Macy key->ck_data, keylen_in_bytes, digest); 1177*eda14cbcSMatt Macy sha2_mac_init_ctx(&sha2_hmac_ctx, digest, 1178*eda14cbcSMatt Macy sha_digest_len); 1179*eda14cbcSMatt Macy } else { 1180*eda14cbcSMatt Macy sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data, 1181*eda14cbcSMatt Macy keylen_in_bytes); 1182*eda14cbcSMatt Macy } 1183*eda14cbcSMatt Macy } 1184*eda14cbcSMatt Macy 1185*eda14cbcSMatt Macy /* get the mechanism parameters, if applicable */ 1186*eda14cbcSMatt Macy if (mechanism->cm_type % 3 == 2) { 1187*eda14cbcSMatt Macy if (mechanism->cm_param == NULL || 1188*eda14cbcSMatt Macy mechanism->cm_param_len != sizeof (ulong_t)) { 1189*eda14cbcSMatt Macy ret = CRYPTO_MECHANISM_PARAM_INVALID; 1190*eda14cbcSMatt Macy goto bail; 1191*eda14cbcSMatt Macy } 1192*eda14cbcSMatt Macy PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len); 1193*eda14cbcSMatt Macy if (digest_len > sha_digest_len) { 1194*eda14cbcSMatt Macy ret = CRYPTO_MECHANISM_PARAM_INVALID; 1195*eda14cbcSMatt Macy goto bail; 1196*eda14cbcSMatt Macy } 1197*eda14cbcSMatt Macy } 1198*eda14cbcSMatt Macy 1199*eda14cbcSMatt Macy if (mac->cd_length != digest_len) { 1200*eda14cbcSMatt Macy ret = CRYPTO_INVALID_MAC; 1201*eda14cbcSMatt Macy goto bail; 1202*eda14cbcSMatt Macy } 1203*eda14cbcSMatt Macy 1204*eda14cbcSMatt Macy /* do a SHA2 update of the inner context using the specified data */ 1205*eda14cbcSMatt Macy SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret); 1206*eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 1207*eda14cbcSMatt Macy /* the update failed, free context and bail */ 1208*eda14cbcSMatt Macy goto bail; 1209*eda14cbcSMatt Macy 1210*eda14cbcSMatt Macy /* do a SHA2 final on the inner context */ 1211*eda14cbcSMatt Macy SHA2Final(digest, &sha2_hmac_ctx.hc_icontext); 1212*eda14cbcSMatt Macy 1213*eda14cbcSMatt Macy /* 1214*eda14cbcSMatt Macy * Do an SHA2 update on the outer context, feeding the inner 1215*eda14cbcSMatt Macy * digest as data. 1216*eda14cbcSMatt Macy * 1217*eda14cbcSMatt Macy * HMAC-SHA384 needs special handling as the outer hash needs only 48 1218*eda14cbcSMatt Macy * bytes of the inner hash value. 1219*eda14cbcSMatt Macy */ 1220*eda14cbcSMatt Macy if (mechanism->cm_type == SHA384_HMAC_MECH_INFO_TYPE || 1221*eda14cbcSMatt Macy mechanism->cm_type == SHA384_HMAC_GEN_MECH_INFO_TYPE) 1222*eda14cbcSMatt Macy SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, 1223*eda14cbcSMatt Macy SHA384_DIGEST_LENGTH); 1224*eda14cbcSMatt Macy else 1225*eda14cbcSMatt Macy SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len); 1226*eda14cbcSMatt Macy 1227*eda14cbcSMatt Macy /* 1228*eda14cbcSMatt Macy * Do a SHA2 final on the outer context, storing the computed 1229*eda14cbcSMatt Macy * digest in the users buffer. 1230*eda14cbcSMatt Macy */ 1231*eda14cbcSMatt Macy SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext); 1232*eda14cbcSMatt Macy 1233*eda14cbcSMatt Macy /* 1234*eda14cbcSMatt Macy * Compare the computed digest against the expected digest passed 1235*eda14cbcSMatt Macy * as argument. 1236*eda14cbcSMatt Macy */ 1237*eda14cbcSMatt Macy 1238*eda14cbcSMatt Macy switch (mac->cd_format) { 1239*eda14cbcSMatt Macy 1240*eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 1241*eda14cbcSMatt Macy if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base + 1242*eda14cbcSMatt Macy mac->cd_offset, digest_len) != 0) 1243*eda14cbcSMatt Macy ret = CRYPTO_INVALID_MAC; 1244*eda14cbcSMatt Macy break; 1245*eda14cbcSMatt Macy 1246*eda14cbcSMatt Macy case CRYPTO_DATA_UIO: { 1247*eda14cbcSMatt Macy off_t offset = mac->cd_offset; 1248*eda14cbcSMatt Macy uint_t vec_idx = 0; 1249*eda14cbcSMatt Macy off_t scratch_offset = 0; 1250*eda14cbcSMatt Macy size_t length = digest_len; 1251*eda14cbcSMatt Macy size_t cur_len; 1252*eda14cbcSMatt Macy 1253*eda14cbcSMatt Macy /* we support only kernel buffer */ 1254*eda14cbcSMatt Macy if (uio_segflg(mac->cd_uio) != UIO_SYSSPACE) 1255*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 1256*eda14cbcSMatt Macy 1257*eda14cbcSMatt Macy /* jump to the first iovec containing the expected digest */ 1258*eda14cbcSMatt Macy offset = uio_index_at_offset(mac->cd_uio, offset, &vec_idx); 1259*eda14cbcSMatt Macy if (vec_idx == uio_iovcnt(mac->cd_uio)) { 1260*eda14cbcSMatt Macy /* 1261*eda14cbcSMatt Macy * The caller specified an offset that is 1262*eda14cbcSMatt Macy * larger than the total size of the buffers 1263*eda14cbcSMatt Macy * it provided. 1264*eda14cbcSMatt Macy */ 1265*eda14cbcSMatt Macy ret = CRYPTO_DATA_LEN_RANGE; 1266*eda14cbcSMatt Macy break; 1267*eda14cbcSMatt Macy } 1268*eda14cbcSMatt Macy 1269*eda14cbcSMatt Macy /* do the comparison of computed digest vs specified one */ 1270*eda14cbcSMatt Macy while (vec_idx < uio_iovcnt(mac->cd_uio) && length > 0) { 1271*eda14cbcSMatt Macy cur_len = MIN(uio_iovlen(mac->cd_uio, vec_idx) - 1272*eda14cbcSMatt Macy offset, length); 1273*eda14cbcSMatt Macy 1274*eda14cbcSMatt Macy if (bcmp(digest + scratch_offset, 1275*eda14cbcSMatt Macy uio_iovbase(mac->cd_uio, vec_idx) + offset, 1276*eda14cbcSMatt Macy cur_len) != 0) { 1277*eda14cbcSMatt Macy ret = CRYPTO_INVALID_MAC; 1278*eda14cbcSMatt Macy break; 1279*eda14cbcSMatt Macy } 1280*eda14cbcSMatt Macy 1281*eda14cbcSMatt Macy length -= cur_len; 1282*eda14cbcSMatt Macy vec_idx++; 1283*eda14cbcSMatt Macy scratch_offset += cur_len; 1284*eda14cbcSMatt Macy offset = 0; 1285*eda14cbcSMatt Macy } 1286*eda14cbcSMatt Macy break; 1287*eda14cbcSMatt Macy } 1288*eda14cbcSMatt Macy 1289*eda14cbcSMatt Macy default: 1290*eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 1291*eda14cbcSMatt Macy } 1292*eda14cbcSMatt Macy 1293*eda14cbcSMatt Macy return (ret); 1294*eda14cbcSMatt Macy bail: 1295*eda14cbcSMatt Macy bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t)); 1296*eda14cbcSMatt Macy mac->cd_length = 0; 1297*eda14cbcSMatt Macy return (ret); 1298*eda14cbcSMatt Macy } 1299*eda14cbcSMatt Macy 1300*eda14cbcSMatt Macy /* 1301*eda14cbcSMatt Macy * KCF software provider context management entry points. 1302*eda14cbcSMatt Macy */ 1303*eda14cbcSMatt Macy 1304*eda14cbcSMatt Macy /* ARGSUSED */ 1305*eda14cbcSMatt Macy static int 1306*eda14cbcSMatt Macy sha2_create_ctx_template(crypto_provider_handle_t provider, 1307*eda14cbcSMatt Macy crypto_mechanism_t *mechanism, crypto_key_t *key, 1308*eda14cbcSMatt Macy crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size, 1309*eda14cbcSMatt Macy crypto_req_handle_t req) 1310*eda14cbcSMatt Macy { 1311*eda14cbcSMatt Macy sha2_hmac_ctx_t *sha2_hmac_ctx_tmpl; 1312*eda14cbcSMatt Macy uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length); 1313*eda14cbcSMatt Macy uint32_t sha_digest_len, sha_hmac_block_size; 1314*eda14cbcSMatt Macy 1315*eda14cbcSMatt Macy /* 1316*eda14cbcSMatt Macy * Set the digest length and block size to values appropriate to the 1317*eda14cbcSMatt Macy * mechanism 1318*eda14cbcSMatt Macy */ 1319*eda14cbcSMatt Macy switch (mechanism->cm_type) { 1320*eda14cbcSMatt Macy case SHA256_HMAC_MECH_INFO_TYPE: 1321*eda14cbcSMatt Macy case SHA256_HMAC_GEN_MECH_INFO_TYPE: 1322*eda14cbcSMatt Macy sha_digest_len = SHA256_DIGEST_LENGTH; 1323*eda14cbcSMatt Macy sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE; 1324*eda14cbcSMatt Macy break; 1325*eda14cbcSMatt Macy case SHA384_HMAC_MECH_INFO_TYPE: 1326*eda14cbcSMatt Macy case SHA384_HMAC_GEN_MECH_INFO_TYPE: 1327*eda14cbcSMatt Macy case SHA512_HMAC_MECH_INFO_TYPE: 1328*eda14cbcSMatt Macy case SHA512_HMAC_GEN_MECH_INFO_TYPE: 1329*eda14cbcSMatt Macy sha_digest_len = SHA512_DIGEST_LENGTH; 1330*eda14cbcSMatt Macy sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE; 1331*eda14cbcSMatt Macy break; 1332*eda14cbcSMatt Macy default: 1333*eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 1334*eda14cbcSMatt Macy } 1335*eda14cbcSMatt Macy 1336*eda14cbcSMatt Macy /* Add support for key by attributes (RFE 4706552) */ 1337*eda14cbcSMatt Macy if (key->ck_format != CRYPTO_KEY_RAW) 1338*eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 1339*eda14cbcSMatt Macy 1340*eda14cbcSMatt Macy /* 1341*eda14cbcSMatt Macy * Allocate and initialize SHA2 context. 1342*eda14cbcSMatt Macy */ 1343*eda14cbcSMatt Macy sha2_hmac_ctx_tmpl = kmem_alloc(sizeof (sha2_hmac_ctx_t), 1344*eda14cbcSMatt Macy crypto_kmflag(req)); 1345*eda14cbcSMatt Macy if (sha2_hmac_ctx_tmpl == NULL) 1346*eda14cbcSMatt Macy return (CRYPTO_HOST_MEMORY); 1347*eda14cbcSMatt Macy 1348*eda14cbcSMatt Macy sha2_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type; 1349*eda14cbcSMatt Macy 1350*eda14cbcSMatt Macy if (keylen_in_bytes > sha_hmac_block_size) { 1351*eda14cbcSMatt Macy uchar_t digested_key[SHA512_DIGEST_LENGTH]; 1352*eda14cbcSMatt Macy 1353*eda14cbcSMatt Macy /* 1354*eda14cbcSMatt Macy * Hash the passed-in key to get a smaller key. 1355*eda14cbcSMatt Macy * The inner context is used since it hasn't been 1356*eda14cbcSMatt Macy * initialized yet. 1357*eda14cbcSMatt Macy */ 1358*eda14cbcSMatt Macy PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3, 1359*eda14cbcSMatt Macy &sha2_hmac_ctx_tmpl->hc_icontext, 1360*eda14cbcSMatt Macy key->ck_data, keylen_in_bytes, digested_key); 1361*eda14cbcSMatt Macy sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, digested_key, 1362*eda14cbcSMatt Macy sha_digest_len); 1363*eda14cbcSMatt Macy } else { 1364*eda14cbcSMatt Macy sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, key->ck_data, 1365*eda14cbcSMatt Macy keylen_in_bytes); 1366*eda14cbcSMatt Macy } 1367*eda14cbcSMatt Macy 1368*eda14cbcSMatt Macy *ctx_template = (crypto_spi_ctx_template_t)sha2_hmac_ctx_tmpl; 1369*eda14cbcSMatt Macy *ctx_template_size = sizeof (sha2_hmac_ctx_t); 1370*eda14cbcSMatt Macy 1371*eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1372*eda14cbcSMatt Macy } 1373*eda14cbcSMatt Macy 1374*eda14cbcSMatt Macy static int 1375*eda14cbcSMatt Macy sha2_free_context(crypto_ctx_t *ctx) 1376*eda14cbcSMatt Macy { 1377*eda14cbcSMatt Macy uint_t ctx_len; 1378*eda14cbcSMatt Macy 1379*eda14cbcSMatt Macy if (ctx->cc_provider_private == NULL) 1380*eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1381*eda14cbcSMatt Macy 1382*eda14cbcSMatt Macy /* 1383*eda14cbcSMatt Macy * We have to free either SHA2 or SHA2-HMAC contexts, which 1384*eda14cbcSMatt Macy * have different lengths. 1385*eda14cbcSMatt Macy * 1386*eda14cbcSMatt Macy * Note: Below is dependent on the mechanism ordering. 1387*eda14cbcSMatt Macy */ 1388*eda14cbcSMatt Macy 1389*eda14cbcSMatt Macy if (PROV_SHA2_CTX(ctx)->sc_mech_type % 3 == 0) 1390*eda14cbcSMatt Macy ctx_len = sizeof (sha2_ctx_t); 1391*eda14cbcSMatt Macy else 1392*eda14cbcSMatt Macy ctx_len = sizeof (sha2_hmac_ctx_t); 1393*eda14cbcSMatt Macy 1394*eda14cbcSMatt Macy bzero(ctx->cc_provider_private, ctx_len); 1395*eda14cbcSMatt Macy kmem_free(ctx->cc_provider_private, ctx_len); 1396*eda14cbcSMatt Macy ctx->cc_provider_private = NULL; 1397*eda14cbcSMatt Macy 1398*eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1399*eda14cbcSMatt Macy } 1400