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