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