xref: /illumos-gate/usr/src/uts/common/crypto/io/sha2_mod.c (revision e8d3efa1c56e5f2b5368600a2baeb7b1d54a07f8)
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  * Copyright 2023-2025 RackTop Systems, Inc.
27  */
28 
29 #include <sys/modctl.h>
30 #include <sys/cmn_err.h>
31 #include <sys/crypto/common.h>
32 #include <sys/crypto/spi.h>
33 #include <sys/strsun.h>
34 #include <sys/systm.h>
35 #include <sys/sysmacros.h>
36 #define	_SHA2_IMPL
37 #include <sys/sha2.h>
38 #include <sha2/sha2_impl.h>
39 
40 /*
41  * The sha2 module is created with two modlinkages:
42  * - a modlmisc that allows consumers to directly call the entry points
43  *   SHA2Init, SHA2Update, and SHA2Final.
44  * - a modlcrypto that allows the module to register with the Kernel
45  *   Cryptographic Framework (KCF) as a software provider for the SHA2
46  *   mechanisms.
47  */
48 
49 static struct modlmisc modlmisc = {
50 	&mod_miscops,
51 	"SHA2 Message-Digest Algorithm"
52 };
53 
54 static struct modlcrypto modlcrypto = {
55 	&mod_cryptoops,
56 	"SHA2 Kernel SW Provider"
57 };
58 
59 static struct modlinkage modlinkage = {
60 	MODREV_1, &modlmisc, &modlcrypto, NULL
61 };
62 
63 /*
64  * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed
65  * by KCF to one of the entry points.
66  */
67 
68 #define	PROV_SHA2_CTX(ctx)	((sha2_ctx_t *)(ctx)->cc_provider_private)
69 #define	PROV_SHA2_HMAC_CTX(ctx)	((sha2_hmac_ctx_t *)(ctx)->cc_provider_private)
70 
71 /* to extract the digest length passed as mechanism parameter */
72 #define	PROV_SHA2_GET_DIGEST_LEN(m, len) {				\
73 	if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t)))		\
74 		(len) = (uint32_t)*((ulong_t *)(void *)(m)->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_SHA2_DIGEST_KEY(mech, ctx, key, len, digest) {	\
83 	SHA2Init(mech, ctx);				\
84 	SHA2Update(ctx, key, len);			\
85 	SHA2Final(digest, ctx);				\
86 }
87 
88 /*
89  * Mechanism info structure passed to KCF during registration.
90  */
91 static crypto_mech_info_t sha2_mech_info_tab[] = {
92 	/* SHA256 */
93 	{SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
94 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
95 	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
96 	/* SHA256-HMAC */
97 	{SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
98 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
99 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
100 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
101 	/* SHA256-HMAC GENERAL */
102 	{SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_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 */
107 	{SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
108 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
109 	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
110 	/* SHA384-HMAC */
111 	{SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
112 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
113 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
114 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
115 	/* SHA384-HMAC GENERAL */
116 	{SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_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 */
121 	{SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
122 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
123 	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
124 	/* SHA512-HMAC */
125 	{SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
126 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
127 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
128 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
129 	/* SHA512-HMAC GENERAL */
130 	{SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
131 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
132 	    SHA2_HMAC_MIN_KEY_LEN, SHA2_HMAC_MAX_KEY_LEN,
133 	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
134 	/* SHA512_224 */
135 	{SUN_CKM_SHA512_224, SHA512_224_MECH_INFO_TYPE,
136 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
137 	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
138 	/* SHA512_256 */
139 	{SUN_CKM_SHA512_256, SHA512_256_MECH_INFO_TYPE,
140 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
141 	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS}
142 };
143 
144 static void sha2_provider_status(crypto_provider_handle_t, uint_t *);
145 
146 static crypto_control_ops_t sha2_control_ops = {
147 	sha2_provider_status
148 };
149 
150 static int sha2_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
151     crypto_req_handle_t);
152 static int sha2_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
153     crypto_req_handle_t);
154 static int sha2_digest_update(crypto_ctx_t *, crypto_data_t *,
155     crypto_req_handle_t);
156 static int sha2_digest_final(crypto_ctx_t *, crypto_data_t *,
157     crypto_req_handle_t);
158 static int sha2_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
159     crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
160     crypto_req_handle_t);
161 
162 static crypto_digest_ops_t sha2_digest_ops = {
163 	sha2_digest_init,
164 	sha2_digest,
165 	sha2_digest_update,
166 	NULL,
167 	sha2_digest_final,
168 	sha2_digest_atomic
169 };
170 
171 static int sha2_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
172     crypto_spi_ctx_template_t, crypto_req_handle_t);
173 static int sha2_mac(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
174     crypto_req_handle_t);
175 static int sha2_mac_update(crypto_ctx_t *, crypto_data_t *,
176     crypto_req_handle_t);
177 static int sha2_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
178 static int sha2_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
179     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
180     crypto_spi_ctx_template_t, crypto_req_handle_t);
181 static int sha2_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
182     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
183     crypto_spi_ctx_template_t, crypto_req_handle_t);
184 
185 static crypto_mac_ops_t sha2_mac_ops = {
186 	sha2_mac_init,
187 	sha2_mac,
188 	sha2_mac_update,
189 	sha2_mac_final,
190 	sha2_mac_atomic,
191 	sha2_mac_verify_atomic
192 };
193 
194 static int sha2_create_ctx_template(crypto_provider_handle_t,
195     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
196     size_t *, crypto_req_handle_t);
197 static int sha2_free_context(crypto_ctx_t *);
198 
199 static crypto_ctx_ops_t sha2_ctx_ops = {
200 	sha2_create_ctx_template,
201 	sha2_free_context
202 };
203 
204 static crypto_ops_t sha2_crypto_ops = {
205 	&sha2_control_ops,
206 	&sha2_digest_ops,
207 	NULL,
208 	&sha2_mac_ops,
209 	NULL,
210 	NULL,
211 	NULL,
212 	NULL,
213 	NULL,
214 	NULL,
215 	NULL,
216 	NULL,
217 	NULL,
218 	&sha2_ctx_ops,
219 	NULL,
220 	NULL,
221 	NULL,
222 };
223 
224 static crypto_provider_info_t sha2_prov_info = {
225 	CRYPTO_SPI_VERSION_4,
226 	"SHA2 Software Provider",
227 	CRYPTO_SW_PROVIDER,
228 	{&modlinkage},
229 	NULL,
230 	&sha2_crypto_ops,
231 	sizeof (sha2_mech_info_tab)/sizeof (crypto_mech_info_t),
232 	sha2_mech_info_tab
233 };
234 
235 static crypto_kcf_provider_handle_t sha2_prov_handle = 0;
236 
237 int
238 _init()
239 {
240 	int ret;
241 
242 	if ((ret = mod_install(&modlinkage)) != 0)
243 		return (ret);
244 
245 	/*
246 	 * Register with KCF. If the registration fails, do not uninstall the
247 	 * module, since the functionality provided by misc/sha2 should still
248 	 * be available.
249 	 */
250 	(void) crypto_register_provider(&sha2_prov_info, &sha2_prov_handle);
251 
252 	return (0);
253 }
254 
255 int
256 _info(struct modinfo *modinfop)
257 {
258 	return (mod_info(&modlinkage, modinfop));
259 }
260 
261 /*
262  * KCF software provider control entry points.
263  */
264 /* ARGSUSED */
265 static void
266 sha2_provider_status(crypto_provider_handle_t provider, uint_t *status)
267 {
268 	*status = CRYPTO_PROVIDER_READY;
269 }
270 
271 /*
272  * KCF software provider digest entry points.
273  */
274 
275 static int
276 sha2_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
277     crypto_req_handle_t req)
278 {
279 
280 	/*
281 	 * Allocate and initialize SHA2 context.
282 	 */
283 	ctx->cc_provider_private = kmem_alloc(sizeof (sha2_ctx_t),
284 	    crypto_kmflag(req));
285 	if (ctx->cc_provider_private == NULL)
286 		return (CRYPTO_HOST_MEMORY);
287 
288 	PROV_SHA2_CTX(ctx)->sc_mech_type = mechanism->cm_type;
289 	SHA2Init(mechanism->cm_type, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
290 
291 	return (CRYPTO_SUCCESS);
292 }
293 
294 /*
295  * Helper SHA2 digest update function for uio data.
296  */
297 static int
298 sha2_digest_update_uio(SHA2_CTX *sha2_ctx, crypto_data_t *data)
299 {
300 	off_t offset = data->cd_offset;
301 	size_t length = data->cd_length;
302 	uint_t vec_idx;
303 	size_t cur_len;
304 
305 	/* we support only kernel buffer */
306 	if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
307 		return (CRYPTO_ARGUMENTS_BAD);
308 
309 	/*
310 	 * Jump to the first iovec containing data to be
311 	 * digested.
312 	 */
313 	for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
314 	    offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
315 	    offset -= data->cd_uio->uio_iov[vec_idx++].iov_len)
316 		;
317 	if (vec_idx == data->cd_uio->uio_iovcnt) {
318 		/*
319 		 * The caller specified an offset that is larger than the
320 		 * total size of the buffers it provided.
321 		 */
322 		return (CRYPTO_DATA_LEN_RANGE);
323 	}
324 
325 	/*
326 	 * Now do the digesting on the iovecs.
327 	 */
328 	while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
329 		cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
330 		    offset, length);
331 
332 		SHA2Update(sha2_ctx, (uint8_t *)data->cd_uio->
333 		    uio_iov[vec_idx].iov_base + offset, cur_len);
334 		length -= cur_len;
335 		vec_idx++;
336 		offset = 0;
337 	}
338 
339 	if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
340 		/*
341 		 * The end of the specified iovec's was reached but
342 		 * the length requested could not be processed, i.e.
343 		 * The caller requested to digest more data than it provided.
344 		 */
345 		return (CRYPTO_DATA_LEN_RANGE);
346 	}
347 
348 	return (CRYPTO_SUCCESS);
349 }
350 
351 /*
352  * Helper SHA2 digest final function for uio data.
353  * digest_len is the length of the desired digest. If digest_len
354  * is smaller than the default SHA2 digest length, the caller
355  * must pass a scratch buffer, digest_scratch, which must
356  * be at least the algorithm's digest length bytes.
357  */
358 static int
359 sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
360     ulong_t digest_len, uchar_t *digest_scratch)
361 {
362 	off_t offset = digest->cd_offset;
363 	uint_t vec_idx;
364 
365 	/* we support only kernel buffer */
366 	if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
367 		return (CRYPTO_ARGUMENTS_BAD);
368 
369 	/*
370 	 * Jump to the first iovec containing ptr to the digest to
371 	 * be returned.
372 	 */
373 	for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
374 	    vec_idx < digest->cd_uio->uio_iovcnt;
375 	    offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len)
376 		;
377 	if (vec_idx == digest->cd_uio->uio_iovcnt) {
378 		/*
379 		 * The caller specified an offset that is
380 		 * larger than the total size of the buffers
381 		 * it provided.
382 		 */
383 		return (CRYPTO_DATA_LEN_RANGE);
384 	}
385 
386 	if (offset + digest_len <=
387 	    digest->cd_uio->uio_iov[vec_idx].iov_len) {
388 		/*
389 		 * The computed SHA2 digest will fit in the current
390 		 * iovec.
391 		 */
392 		if (((sha2_ctx->algotype <= SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
393 		    (digest_len != SHA256_DIGEST_LENGTH)) ||
394 		    ((sha2_ctx->algotype > SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
395 		    (digest_len != SHA512_DIGEST_LENGTH))) {
396 			/*
397 			 * The caller requested a short digest. Digest
398 			 * into a scratch buffer and return to
399 			 * the user only what was requested.
400 			 */
401 			SHA2Final(digest_scratch, sha2_ctx);
402 
403 			bcopy(digest_scratch, (uchar_t *)digest->
404 			    cd_uio->uio_iov[vec_idx].iov_base + offset,
405 			    digest_len);
406 		} else {
407 			SHA2Final((uchar_t *)digest->
408 			    cd_uio->uio_iov[vec_idx].iov_base + offset,
409 			    sha2_ctx);
410 
411 		}
412 	} else {
413 		/*
414 		 * The computed digest will be crossing one or more iovec's.
415 		 * This is bad performance-wise but we need to support it.
416 		 * Allocate a small scratch buffer on the stack and
417 		 * copy it piece meal to the specified digest iovec's.
418 		 */
419 		uchar_t digest_tmp[SHA512_DIGEST_LENGTH];
420 		off_t scratch_offset = 0;
421 		size_t length = digest_len;
422 		size_t cur_len;
423 
424 		SHA2Final(digest_tmp, sha2_ctx);
425 
426 		while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
427 			cur_len =
428 			    MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
429 			    offset, length);
430 			bcopy(digest_tmp + scratch_offset,
431 			    digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
432 			    cur_len);
433 
434 			length -= cur_len;
435 			vec_idx++;
436 			scratch_offset += cur_len;
437 			offset = 0;
438 		}
439 
440 		if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
441 			/*
442 			 * The end of the specified iovec's was reached but
443 			 * the length requested could not be processed, i.e.
444 			 * The caller requested to digest more data than it
445 			 * provided.
446 			 */
447 			return (CRYPTO_DATA_LEN_RANGE);
448 		}
449 	}
450 
451 	return (CRYPTO_SUCCESS);
452 }
453 
454 /*
455  * Helper SHA2 digest update for mblk's.
456  */
457 static int
458 sha2_digest_update_mblk(SHA2_CTX *sha2_ctx, crypto_data_t *data)
459 {
460 	off_t offset = data->cd_offset;
461 	size_t length = data->cd_length;
462 	mblk_t *mp;
463 	size_t cur_len;
464 
465 	/*
466 	 * Jump to the first mblk_t containing data to be digested.
467 	 */
468 	for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
469 	    offset -= MBLKL(mp), mp = mp->b_cont)
470 		;
471 	if (mp == NULL) {
472 		/*
473 		 * The caller specified an offset that is larger than the
474 		 * total size of the buffers it provided.
475 		 */
476 		return (CRYPTO_DATA_LEN_RANGE);
477 	}
478 
479 	/*
480 	 * Now do the digesting on the mblk chain.
481 	 */
482 	while (mp != NULL && length > 0) {
483 		cur_len = MIN(MBLKL(mp) - offset, length);
484 		SHA2Update(sha2_ctx, mp->b_rptr + offset, cur_len);
485 		length -= cur_len;
486 		offset = 0;
487 		mp = mp->b_cont;
488 	}
489 
490 	if (mp == NULL && length > 0) {
491 		/*
492 		 * The end of the mblk was reached but the length requested
493 		 * could not be processed, i.e. The caller requested
494 		 * to digest more data than it provided.
495 		 */
496 		return (CRYPTO_DATA_LEN_RANGE);
497 	}
498 
499 	return (CRYPTO_SUCCESS);
500 }
501 
502 /*
503  * Helper SHA2 digest final for mblk's.
504  * digest_len is the length of the desired digest. If digest_len
505  * is smaller than the default SHA2 digest length, the caller
506  * must pass a scratch buffer, digest_scratch, which must
507  * be at least the algorithm's digest length bytes.
508  */
509 static int
510 sha2_digest_final_mblk(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
511     ulong_t digest_len, uchar_t *digest_scratch)
512 {
513 	off_t offset = digest->cd_offset;
514 	mblk_t *mp;
515 
516 	/*
517 	 * Jump to the first mblk_t that will be used to store the digest.
518 	 */
519 	for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
520 	    offset -= MBLKL(mp), mp = mp->b_cont)
521 		;
522 	if (mp == NULL) {
523 		/*
524 		 * The caller specified an offset that is larger than the
525 		 * total size of the buffers it provided.
526 		 */
527 		return (CRYPTO_DATA_LEN_RANGE);
528 	}
529 
530 	if (offset + digest_len <= MBLKL(mp)) {
531 		/*
532 		 * The computed SHA2 digest will fit in the current mblk.
533 		 * Do the SHA2Final() in-place.
534 		 */
535 		if (((sha2_ctx->algotype <= SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
536 		    (digest_len != SHA256_DIGEST_LENGTH)) ||
537 		    ((sha2_ctx->algotype > SHA256_HMAC_GEN_MECH_INFO_TYPE) &&
538 		    (digest_len != SHA512_DIGEST_LENGTH))) {
539 			/*
540 			 * The caller requested a short digest. Digest
541 			 * into a scratch buffer and return to
542 			 * the user only what was requested.
543 			 */
544 			SHA2Final(digest_scratch, sha2_ctx);
545 			bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
546 		} else {
547 			SHA2Final(mp->b_rptr + offset, sha2_ctx);
548 		}
549 	} else {
550 		/*
551 		 * The computed digest will be crossing one or more mblk's.
552 		 * This is bad performance-wise but we need to support it.
553 		 * Allocate a small scratch buffer on the stack and
554 		 * copy it piece meal to the specified digest iovec's.
555 		 */
556 		uchar_t digest_tmp[SHA512_DIGEST_LENGTH];
557 		off_t scratch_offset = 0;
558 		size_t length = digest_len;
559 		size_t cur_len;
560 
561 		SHA2Final(digest_tmp, sha2_ctx);
562 
563 		while (mp != NULL && length > 0) {
564 			cur_len = MIN(MBLKL(mp) - offset, length);
565 			bcopy(digest_tmp + scratch_offset,
566 			    mp->b_rptr + offset, cur_len);
567 
568 			length -= cur_len;
569 			mp = mp->b_cont;
570 			scratch_offset += cur_len;
571 			offset = 0;
572 		}
573 
574 		if (mp == NULL && length > 0) {
575 			/*
576 			 * The end of the specified mblk was reached but
577 			 * the length requested could not be processed, i.e.
578 			 * The caller requested to digest more data than it
579 			 * provided.
580 			 */
581 			return (CRYPTO_DATA_LEN_RANGE);
582 		}
583 	}
584 
585 	return (CRYPTO_SUCCESS);
586 }
587 
588 /* ARGSUSED */
589 static int
590 sha2_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
591     crypto_req_handle_t req)
592 {
593 	int ret = CRYPTO_SUCCESS;
594 	uint_t sha_digest_len;
595 
596 	ASSERT(ctx->cc_provider_private != NULL);
597 
598 	switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
599 	case SHA256_MECH_INFO_TYPE:
600 		sha_digest_len = SHA256_DIGEST_LENGTH;
601 		break;
602 	case SHA384_MECH_INFO_TYPE:
603 		sha_digest_len = SHA384_DIGEST_LENGTH;
604 		break;
605 	case SHA512_MECH_INFO_TYPE:
606 		sha_digest_len = SHA512_DIGEST_LENGTH;
607 		break;
608 	case SHA512_224_MECH_INFO_TYPE:
609 		sha_digest_len = SHA512_224_DIGEST_LENGTH;
610 		break;
611 	case SHA512_256_MECH_INFO_TYPE:
612 		sha_digest_len = SHA512_256_DIGEST_LENGTH;
613 		break;
614 	default:
615 		return (CRYPTO_MECHANISM_INVALID);
616 	}
617 
618 	/*
619 	 * We need to just return the length needed to store the output.
620 	 * We should not destroy the context for the following cases.
621 	 */
622 	if ((digest->cd_length == 0) ||
623 	    (digest->cd_length < sha_digest_len)) {
624 		digest->cd_length = sha_digest_len;
625 		return (CRYPTO_BUFFER_TOO_SMALL);
626 	}
627 
628 	/*
629 	 * Do the SHA2 update on the specified input data.
630 	 */
631 	switch (data->cd_format) {
632 	case CRYPTO_DATA_RAW:
633 		SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
634 		    (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
635 		    data->cd_length);
636 		break;
637 	case CRYPTO_DATA_UIO:
638 		ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
639 		    data);
640 		break;
641 	case CRYPTO_DATA_MBLK:
642 		ret = sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
643 		    data);
644 		break;
645 	default:
646 		ret = CRYPTO_ARGUMENTS_BAD;
647 	}
648 
649 	if (ret != CRYPTO_SUCCESS) {
650 		/* the update failed, free context and bail */
651 		kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
652 		ctx->cc_provider_private = NULL;
653 		digest->cd_length = 0;
654 		return (ret);
655 	}
656 
657 	/*
658 	 * Do a SHA2 final, must be done separately since the digest
659 	 * type can be different than the input data type.
660 	 */
661 	switch (digest->cd_format) {
662 	case CRYPTO_DATA_RAW:
663 		SHA2Final((unsigned char *)digest->cd_raw.iov_base +
664 		    digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
665 		break;
666 	case CRYPTO_DATA_UIO:
667 		ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
668 		    digest, sha_digest_len, NULL);
669 		break;
670 	case CRYPTO_DATA_MBLK:
671 		ret = sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
672 		    digest, sha_digest_len, NULL);
673 		break;
674 	default:
675 		ret = CRYPTO_ARGUMENTS_BAD;
676 	}
677 
678 	/* all done, free context and return */
679 
680 	if (ret == CRYPTO_SUCCESS)
681 		digest->cd_length = sha_digest_len;
682 	else
683 		digest->cd_length = 0;
684 
685 	kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
686 	ctx->cc_provider_private = NULL;
687 	return (ret);
688 }
689 
690 /* ARGSUSED */
691 static int
692 sha2_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
693     crypto_req_handle_t req)
694 {
695 	int ret = CRYPTO_SUCCESS;
696 
697 	ASSERT(ctx->cc_provider_private != NULL);
698 
699 	/*
700 	 * Do the SHA2 update on the specified input data.
701 	 */
702 	switch (data->cd_format) {
703 	case CRYPTO_DATA_RAW:
704 		SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
705 		    (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
706 		    data->cd_length);
707 		break;
708 	case CRYPTO_DATA_UIO:
709 		ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
710 		    data);
711 		break;
712 	case CRYPTO_DATA_MBLK:
713 		ret = sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
714 		    data);
715 		break;
716 	default:
717 		ret = CRYPTO_ARGUMENTS_BAD;
718 	}
719 
720 	return (ret);
721 }
722 
723 /* ARGSUSED */
724 static int
725 sha2_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
726     crypto_req_handle_t req)
727 {
728 	int ret = CRYPTO_SUCCESS;
729 	uint_t sha_digest_len;
730 
731 	ASSERT(ctx->cc_provider_private != NULL);
732 
733 	switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
734 	case SHA256_MECH_INFO_TYPE:
735 		sha_digest_len = SHA256_DIGEST_LENGTH;
736 		break;
737 	case SHA384_MECH_INFO_TYPE:
738 		sha_digest_len = SHA384_DIGEST_LENGTH;
739 		break;
740 	case SHA512_MECH_INFO_TYPE:
741 		sha_digest_len = SHA512_DIGEST_LENGTH;
742 		break;
743 	case SHA512_224_MECH_INFO_TYPE:
744 		sha_digest_len = SHA512_224_DIGEST_LENGTH;
745 		break;
746 	case SHA512_256_MECH_INFO_TYPE:
747 		sha_digest_len = SHA512_256_DIGEST_LENGTH;
748 		break;
749 	default:
750 		return (CRYPTO_MECHANISM_INVALID);
751 	}
752 
753 	/*
754 	 * We need to just return the length needed to store the output.
755 	 * We should not destroy the context for the following cases.
756 	 */
757 	if ((digest->cd_length == 0) ||
758 	    (digest->cd_length < sha_digest_len)) {
759 		digest->cd_length = sha_digest_len;
760 		return (CRYPTO_BUFFER_TOO_SMALL);
761 	}
762 
763 	/*
764 	 * Do a SHA2 final.
765 	 */
766 	switch (digest->cd_format) {
767 	case CRYPTO_DATA_RAW:
768 		SHA2Final((unsigned char *)digest->cd_raw.iov_base +
769 		    digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
770 		break;
771 	case CRYPTO_DATA_UIO:
772 		ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
773 		    digest, sha_digest_len, NULL);
774 		break;
775 	case CRYPTO_DATA_MBLK:
776 		ret = sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
777 		    digest, sha_digest_len, NULL);
778 		break;
779 	default:
780 		ret = CRYPTO_ARGUMENTS_BAD;
781 	}
782 
783 	/* all done, free context and return */
784 
785 	if (ret == CRYPTO_SUCCESS)
786 		digest->cd_length = sha_digest_len;
787 	else
788 		digest->cd_length = 0;
789 
790 	kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
791 	ctx->cc_provider_private = NULL;
792 
793 	return (ret);
794 }
795 
796 /* ARGSUSED */
797 static int
798 sha2_digest_atomic(crypto_provider_handle_t provider,
799     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
800     crypto_data_t *data, crypto_data_t *digest,
801     crypto_req_handle_t req)
802 {
803 	int ret = CRYPTO_SUCCESS;
804 	SHA2_CTX sha2_ctx;
805 	uint32_t sha_digest_len;
806 
807 	/*
808 	 * Do the SHA inits.
809 	 */
810 
811 	SHA2Init(mechanism->cm_type, &sha2_ctx);
812 
813 	switch (data->cd_format) {
814 	case CRYPTO_DATA_RAW:
815 		SHA2Update(&sha2_ctx, (uint8_t *)data->
816 		    cd_raw.iov_base + data->cd_offset, data->cd_length);
817 		break;
818 	case CRYPTO_DATA_UIO:
819 		ret = sha2_digest_update_uio(&sha2_ctx, data);
820 		break;
821 	case CRYPTO_DATA_MBLK:
822 		ret = sha2_digest_update_mblk(&sha2_ctx, data);
823 		break;
824 	default:
825 		ret = CRYPTO_ARGUMENTS_BAD;
826 	}
827 
828 	/*
829 	 * Do the SHA updates on the specified input data.
830 	 */
831 
832 	if (ret != CRYPTO_SUCCESS) {
833 		/* the update failed, bail */
834 		digest->cd_length = 0;
835 		return (ret);
836 	}
837 
838 	if (mechanism->cm_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE)
839 		sha_digest_len = SHA256_DIGEST_LENGTH;
840 	else
841 		sha_digest_len = SHA512_DIGEST_LENGTH;
842 
843 	/*
844 	 * Do a SHA2 final, must be done separately since the digest
845 	 * type can be different than the input data type.
846 	 */
847 	switch (digest->cd_format) {
848 	case CRYPTO_DATA_RAW:
849 		SHA2Final((unsigned char *)digest->cd_raw.iov_base +
850 		    digest->cd_offset, &sha2_ctx);
851 		break;
852 	case CRYPTO_DATA_UIO:
853 		ret = sha2_digest_final_uio(&sha2_ctx, digest,
854 		    sha_digest_len, NULL);
855 		break;
856 	case CRYPTO_DATA_MBLK:
857 		ret = sha2_digest_final_mblk(&sha2_ctx, digest,
858 		    sha_digest_len, NULL);
859 		break;
860 	default:
861 		ret = CRYPTO_ARGUMENTS_BAD;
862 	}
863 
864 	if (ret == CRYPTO_SUCCESS)
865 		digest->cd_length = sha_digest_len;
866 	else
867 		digest->cd_length = 0;
868 
869 	return (ret);
870 }
871 
872 /*
873  * KCF software provider mac entry points.
874  *
875  * SHA2 HMAC is: SHA2(key XOR opad, SHA2(key XOR ipad, text))
876  *
877  * Init:
878  * The initialization routine initializes what we denote
879  * as the inner and outer contexts by doing
880  * - for inner context: SHA2(key XOR ipad)
881  * - for outer context: SHA2(key XOR opad)
882  *
883  * Update:
884  * Each subsequent SHA2 HMAC update will result in an
885  * update of the inner context with the specified data.
886  *
887  * Final:
888  * The SHA2 HMAC final will do a SHA2 final operation on the
889  * inner context, and the resulting digest will be used
890  * as the data for an update on the outer context. Last
891  * but not least, a SHA2 final on the outer context will
892  * be performed to obtain the SHA2 HMAC digest to return
893  * to the user.
894  */
895 
896 /*
897  * Initialize a SHA2-HMAC context.
898  */
899 static void
900 sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
901 {
902 	uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
903 	uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
904 	int i, block_size, blocks_per_int64;
905 
906 	/* Determine the block size */
907 	if (ctx->hc_mech_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) {
908 		block_size = SHA256_HMAC_BLOCK_SIZE;
909 		blocks_per_int64 = SHA256_HMAC_BLOCK_SIZE / sizeof (uint64_t);
910 	} else {
911 		block_size = SHA512_HMAC_BLOCK_SIZE;
912 		blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t);
913 	}
914 
915 	(void) bzero(ipad, block_size);
916 	(void) bzero(opad, block_size);
917 	(void) bcopy(keyval, ipad, length_in_bytes);
918 	(void) bcopy(keyval, opad, length_in_bytes);
919 
920 	/* XOR key with ipad (0x36) and opad (0x5c) */
921 	for (i = 0; i < blocks_per_int64; i ++) {
922 		ipad[i] ^= 0x3636363636363636;
923 		opad[i] ^= 0x5c5c5c5c5c5c5c5c;
924 	}
925 
926 	/* perform SHA2 on ipad */
927 	SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext);
928 	SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
929 
930 	/* perform SHA2 on opad */
931 	SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext);
932 	SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
933 
934 }
935 
936 static boolean_t
937 sha2_is_general_hmech(const crypto_mechanism_t *mechanism)
938 {
939 	switch (mechanism->cm_type) {
940 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
941 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
942 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
943 		return (B_TRUE);
944 	default:
945 		return (B_FALSE);
946 	}
947 }
948 
949 /*
950  */
951 static int
952 sha2_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
953     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
954     crypto_req_handle_t req)
955 {
956 	int ret = CRYPTO_SUCCESS;
957 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
958 	uint_t sha_digest_len, sha_hmac_block_size;
959 
960 	/*
961 	 * Set the digest length and block size to values appropriate to the
962 	 * mechanism
963 	 */
964 	switch (mechanism->cm_type) {
965 	case SHA256_HMAC_MECH_INFO_TYPE:
966 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
967 		sha_digest_len = SHA256_DIGEST_LENGTH;
968 		sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
969 		break;
970 	case SHA384_HMAC_MECH_INFO_TYPE:
971 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
972 	case SHA512_HMAC_MECH_INFO_TYPE:
973 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
974 		sha_digest_len = SHA512_DIGEST_LENGTH;
975 		sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
976 		break;
977 	default:
978 		return (CRYPTO_MECHANISM_INVALID);
979 	}
980 
981 	if (key->ck_format != CRYPTO_KEY_RAW)
982 		return (CRYPTO_ARGUMENTS_BAD);
983 
984 	ctx->cc_provider_private = kmem_alloc(sizeof (sha2_hmac_ctx_t),
985 	    crypto_kmflag(req));
986 	if (ctx->cc_provider_private == NULL)
987 		return (CRYPTO_HOST_MEMORY);
988 
989 	PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
990 	if (ctx_template != NULL) {
991 		/* reuse context template */
992 		bcopy(ctx_template, PROV_SHA2_HMAC_CTX(ctx),
993 		    sizeof (sha2_hmac_ctx_t));
994 	} else {
995 		/* no context template, compute context */
996 		if (keylen_in_bytes > sha_hmac_block_size) {
997 			uchar_t digested_key[SHA512_DIGEST_LENGTH];
998 			sha2_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
999 
1000 			/*
1001 			 * Hash the passed-in key to get a smaller key.
1002 			 * The inner context is used since it hasn't been
1003 			 * initialized yet.
1004 			 */
1005 			PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
1006 			    &hmac_ctx->hc_icontext,
1007 			    key->ck_data, keylen_in_bytes, digested_key);
1008 			sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
1009 			    digested_key, sha_digest_len);
1010 		} else {
1011 			sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
1012 			    key->ck_data, keylen_in_bytes);
1013 		}
1014 	}
1015 
1016 	/*
1017 	 * Get the mechanism parameters, if applicable.
1018 	 */
1019 	if (sha2_is_general_hmech(mechanism)) {
1020 		if (mechanism->cm_param == NULL ||
1021 		    mechanism->cm_param_len != sizeof (ulong_t)) {
1022 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1023 			goto bail;
1024 		}
1025 		PROV_SHA2_GET_DIGEST_LEN(mechanism,
1026 		    PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len);
1027 		if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len > sha_digest_len)
1028 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1029 	}
1030 
1031 bail:
1032 	if (ret != CRYPTO_SUCCESS) {
1033 		bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1034 		kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1035 		ctx->cc_provider_private = NULL;
1036 	}
1037 
1038 	return (ret);
1039 }
1040 
1041 static int
1042 sha2_mac(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *mac,
1043     crypto_req_handle_t req)
1044 {
1045 	SHA2_CTX *ictx = NULL;
1046 	SHA2_CTX *octx = NULL;
1047 	uchar_t digest[SHA512_DIGEST_LENGTH];
1048 	uint32_t digest_len, sha_digest_len;
1049 	int ret = CRYPTO_SUCCESS;
1050 
1051 	ASSERT(ctx->cc_provider_private != NULL);
1052 
1053 	/* Set the digest lengths to values appropriate to the mechanism */
1054 	switch (PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type) {
1055 	case SHA256_HMAC_MECH_INFO_TYPE:
1056 		sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
1057 		break;
1058 	case SHA384_HMAC_MECH_INFO_TYPE:
1059 		sha_digest_len = digest_len = SHA384_DIGEST_LENGTH;
1060 		break;
1061 	case SHA512_HMAC_MECH_INFO_TYPE:
1062 		sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
1063 		break;
1064 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
1065 		sha_digest_len = SHA256_DIGEST_LENGTH;
1066 		digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
1067 		break;
1068 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
1069 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
1070 		sha_digest_len = SHA512_DIGEST_LENGTH;
1071 		digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
1072 		break;
1073 	}
1074 
1075 	/*
1076 	 * We need to just return the length needed to store the output.
1077 	 * We should not destroy the context for the following cases.
1078 	 */
1079 	if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
1080 		mac->cd_length = digest_len;
1081 		return (CRYPTO_BUFFER_TOO_SMALL);
1082 	}
1083 
1084 	ictx = &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext;
1085 	octx = &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext;
1086 
1087 	/*
1088 	 * Do a SHA2 update of the inner context using the specified
1089 	 * data.
1090 	 */
1091 	switch (data->cd_format) {
1092 	case CRYPTO_DATA_RAW:
1093 		SHA2Update(ictx,
1094 		    (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
1095 		    data->cd_length);
1096 		break;
1097 	case CRYPTO_DATA_UIO:
1098 		ret = sha2_digest_update_uio(ictx, data);
1099 		break;
1100 	case CRYPTO_DATA_MBLK:
1101 		ret = sha2_digest_update_mblk(ictx, data);
1102 		break;
1103 	default:
1104 		ret = CRYPTO_ARGUMENTS_BAD;
1105 	}
1106 
1107 	if (ret != CRYPTO_SUCCESS) {
1108 		bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1109 		kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1110 		ctx->cc_provider_private = NULL;
1111 		mac->cd_length = 0;
1112 		return (ret);
1113 	}
1114 
1115 	/*
1116 	 * Do a SHA2 final on the inner context.
1117 	 */
1118 	SHA2Final(digest, ictx);
1119 
1120 	/*
1121 	 * Do a SHA2 update on the outer context, feeding the inner
1122 	 * digest as data.
1123 	 */
1124 	SHA2Update(octx, digest, sha_digest_len);
1125 
1126 	/*
1127 	 * Do a SHA2 final on the outer context, storing the computing
1128 	 * digest in the users buffer.
1129 	 */
1130 	switch (mac->cd_format) {
1131 	case CRYPTO_DATA_RAW:
1132 		if (digest_len != sha_digest_len) {
1133 			/*
1134 			 * The caller requested a short digest. Digest
1135 			 * into a scratch buffer and return to
1136 			 * the user only what was requested.
1137 			 */
1138 			SHA2Final(digest, octx);
1139 			bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
1140 			    mac->cd_offset, digest_len);
1141 		} else {
1142 			SHA2Final((unsigned char *)mac->cd_raw.iov_base +
1143 			    mac->cd_offset, octx);
1144 		}
1145 		break;
1146 	case CRYPTO_DATA_UIO:
1147 		ret = sha2_digest_final_uio(octx, mac, digest_len, digest);
1148 		break;
1149 	case CRYPTO_DATA_MBLK:
1150 		ret = sha2_digest_final_mblk(octx, mac, digest_len, digest);
1151 		break;
1152 	default:
1153 		ret = CRYPTO_ARGUMENTS_BAD;
1154 	}
1155 
1156 	if (ret == CRYPTO_SUCCESS)
1157 		mac->cd_length = digest_len;
1158 	else
1159 		mac->cd_length = 0;
1160 
1161 	bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1162 	kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1163 	ctx->cc_provider_private = NULL;
1164 
1165 	return (ret);
1166 }
1167 
1168 /* ARGSUSED */
1169 static int
1170 sha2_mac_update(crypto_ctx_t *ctx, crypto_data_t *data,
1171     crypto_req_handle_t req)
1172 {
1173 	int ret = CRYPTO_SUCCESS;
1174 
1175 	ASSERT(ctx->cc_provider_private != NULL);
1176 
1177 	/*
1178 	 * Do a SHA2 update of the inner context using the specified
1179 	 * data.
1180 	 */
1181 	switch (data->cd_format) {
1182 	case CRYPTO_DATA_RAW:
1183 		SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_icontext,
1184 		    (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
1185 		    data->cd_length);
1186 		break;
1187 	case CRYPTO_DATA_UIO:
1188 		ret = sha2_digest_update_uio(
1189 		    &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data);
1190 		break;
1191 	case CRYPTO_DATA_MBLK:
1192 		ret = sha2_digest_update_mblk(
1193 		    &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data);
1194 		break;
1195 	default:
1196 		ret = CRYPTO_ARGUMENTS_BAD;
1197 	}
1198 
1199 	return (ret);
1200 }
1201 
1202 /* ARGSUSED */
1203 static int
1204 sha2_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
1205 {
1206 	int ret = CRYPTO_SUCCESS;
1207 	uchar_t digest[SHA512_DIGEST_LENGTH];
1208 	uint32_t digest_len, sha_digest_len;
1209 
1210 	ASSERT(ctx->cc_provider_private != NULL);
1211 
1212 	/* Set the digest lengths to values appropriate to the mechanism */
1213 	switch (PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type) {
1214 	case SHA256_HMAC_MECH_INFO_TYPE:
1215 		sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
1216 		break;
1217 	case SHA384_HMAC_MECH_INFO_TYPE:
1218 		sha_digest_len = digest_len = SHA384_DIGEST_LENGTH;
1219 		break;
1220 	case SHA512_HMAC_MECH_INFO_TYPE:
1221 		sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
1222 		break;
1223 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
1224 		sha_digest_len = SHA256_DIGEST_LENGTH;
1225 		digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
1226 		break;
1227 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
1228 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
1229 		sha_digest_len = SHA512_DIGEST_LENGTH;
1230 		digest_len = PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len;
1231 		break;
1232 	}
1233 
1234 	/*
1235 	 * We need to just return the length needed to store the output.
1236 	 * We should not destroy the context for the following cases.
1237 	 */
1238 	if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
1239 		mac->cd_length = digest_len;
1240 		return (CRYPTO_BUFFER_TOO_SMALL);
1241 	}
1242 
1243 	/*
1244 	 * Do a SHA2 final on the inner context.
1245 	 */
1246 	SHA2Final(digest, &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext);
1247 
1248 	/*
1249 	 * Do a SHA2 update on the outer context, feeding the inner
1250 	 * digest as data.
1251 	 */
1252 	SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, digest,
1253 	    sha_digest_len);
1254 
1255 	/*
1256 	 * Do a SHA2 final on the outer context, storing the computing
1257 	 * digest in the users buffer.
1258 	 */
1259 	switch (mac->cd_format) {
1260 	case CRYPTO_DATA_RAW:
1261 		if (digest_len != sha_digest_len) {
1262 			/*
1263 			 * The caller requested a short digest. Digest
1264 			 * into a scratch buffer and return to
1265 			 * the user only what was requested.
1266 			 */
1267 			SHA2Final(digest,
1268 			    &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
1269 			bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
1270 			    mac->cd_offset, digest_len);
1271 		} else {
1272 			SHA2Final((unsigned char *)mac->cd_raw.iov_base +
1273 			    mac->cd_offset,
1274 			    &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
1275 		}
1276 		break;
1277 	case CRYPTO_DATA_UIO:
1278 		ret = sha2_digest_final_uio(
1279 		    &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac,
1280 		    digest_len, digest);
1281 		break;
1282 	case CRYPTO_DATA_MBLK:
1283 		ret = sha2_digest_final_mblk(
1284 		    &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac,
1285 		    digest_len, digest);
1286 		break;
1287 	default:
1288 		ret = CRYPTO_ARGUMENTS_BAD;
1289 	}
1290 
1291 	if (ret == CRYPTO_SUCCESS)
1292 		mac->cd_length = digest_len;
1293 	else
1294 		mac->cd_length = 0;
1295 
1296 	bzero(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1297 	kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
1298 	ctx->cc_provider_private = NULL;
1299 
1300 	return (ret);
1301 }
1302 
1303 #define	SHA2_MAC_UPDATE(data, ctx, ret) {				\
1304 	switch (data->cd_format) {					\
1305 	case CRYPTO_DATA_RAW:						\
1306 		SHA2Update(&(ctx).hc_icontext,				\
1307 		    (uint8_t *)data->cd_raw.iov_base +			\
1308 		    data->cd_offset, data->cd_length);			\
1309 		break;							\
1310 	case CRYPTO_DATA_UIO:						\
1311 		ret = sha2_digest_update_uio(&(ctx).hc_icontext, data);	\
1312 		break;							\
1313 	case CRYPTO_DATA_MBLK:						\
1314 		ret = sha2_digest_update_mblk(&(ctx).hc_icontext,	\
1315 		    data);						\
1316 		break;							\
1317 	default:							\
1318 		ret = CRYPTO_ARGUMENTS_BAD;				\
1319 	}								\
1320 }
1321 
1322 /* ARGSUSED */
1323 static int
1324 sha2_mac_atomic(crypto_provider_handle_t provider,
1325     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1326     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
1327     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
1328 {
1329 	int ret = CRYPTO_SUCCESS;
1330 	uchar_t digest[SHA512_DIGEST_LENGTH];
1331 	sha2_hmac_ctx_t sha2_hmac_ctx;
1332 	uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
1333 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
1334 
1335 	/*
1336 	 * Set the digest length and block size to values appropriate to the
1337 	 * mechanism
1338 	 */
1339 	switch (mechanism->cm_type) {
1340 	case SHA256_HMAC_MECH_INFO_TYPE:
1341 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
1342 		sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
1343 		sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
1344 		break;
1345 	case SHA384_HMAC_MECH_INFO_TYPE:
1346 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
1347 	case SHA512_HMAC_MECH_INFO_TYPE:
1348 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
1349 		sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
1350 		sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
1351 		break;
1352 	default:
1353 		return (CRYPTO_MECHANISM_INVALID);
1354 	}
1355 
1356 	/* Add support for key by attributes (RFE 4706552) */
1357 	if (key->ck_format != CRYPTO_KEY_RAW)
1358 		return (CRYPTO_ARGUMENTS_BAD);
1359 
1360 	if (ctx_template != NULL) {
1361 		/* reuse context template */
1362 		bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
1363 	} else {
1364 		sha2_hmac_ctx.hc_mech_type = mechanism->cm_type;
1365 		/* no context template, initialize context */
1366 		if (keylen_in_bytes > sha_hmac_block_size) {
1367 			/*
1368 			 * Hash the passed-in key to get a smaller key.
1369 			 * The inner context is used since it hasn't been
1370 			 * initialized yet.
1371 			 */
1372 			PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
1373 			    &sha2_hmac_ctx.hc_icontext,
1374 			    key->ck_data, keylen_in_bytes, digest);
1375 			sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
1376 			    sha_digest_len);
1377 		} else {
1378 			sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
1379 			    keylen_in_bytes);
1380 		}
1381 	}
1382 
1383 	/* get the mechanism parameters, if applicable */
1384 	if (sha2_is_general_hmech(mechanism)) {
1385 		if (mechanism->cm_param == NULL ||
1386 		    mechanism->cm_param_len != sizeof (ulong_t)) {
1387 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1388 			goto bail;
1389 		}
1390 		PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len);
1391 		if (digest_len > sha_digest_len) {
1392 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1393 			goto bail;
1394 		}
1395 	}
1396 
1397 	/* do a SHA2 update of the inner context using the specified data */
1398 	SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
1399 	if (ret != CRYPTO_SUCCESS)
1400 		/* the update failed, free context and bail */
1401 		goto bail;
1402 
1403 	/*
1404 	 * Do a SHA2 final on the inner context.
1405 	 */
1406 	SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
1407 
1408 	/*
1409 	 * Do an SHA2 update on the outer context, feeding the inner
1410 	 * digest as data.
1411 	 *
1412 	 * HMAC-SHA384 needs special handling as the outer hash needs only 48
1413 	 * bytes of the inner hash value.
1414 	 */
1415 	if (mechanism->cm_type == SHA384_HMAC_MECH_INFO_TYPE ||
1416 	    mechanism->cm_type == SHA384_HMAC_GEN_MECH_INFO_TYPE)
1417 		SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest,
1418 		    SHA384_DIGEST_LENGTH);
1419 	else
1420 		SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
1421 
1422 	/*
1423 	 * Do a SHA2 final on the outer context, storing the computed
1424 	 * digest in the users buffer.
1425 	 */
1426 	switch (mac->cd_format) {
1427 	case CRYPTO_DATA_RAW:
1428 		if (digest_len != sha_digest_len) {
1429 			/*
1430 			 * The caller requested a short digest. Digest
1431 			 * into a scratch buffer and return to
1432 			 * the user only what was requested.
1433 			 */
1434 			SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
1435 			bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
1436 			    mac->cd_offset, digest_len);
1437 		} else {
1438 			SHA2Final((unsigned char *)mac->cd_raw.iov_base +
1439 			    mac->cd_offset, &sha2_hmac_ctx.hc_ocontext);
1440 		}
1441 		break;
1442 	case CRYPTO_DATA_UIO:
1443 		ret = sha2_digest_final_uio(&sha2_hmac_ctx.hc_ocontext, mac,
1444 		    digest_len, digest);
1445 		break;
1446 	case CRYPTO_DATA_MBLK:
1447 		ret = sha2_digest_final_mblk(&sha2_hmac_ctx.hc_ocontext, mac,
1448 		    digest_len, digest);
1449 		break;
1450 	default:
1451 		ret = CRYPTO_ARGUMENTS_BAD;
1452 	}
1453 
1454 	if (ret == CRYPTO_SUCCESS) {
1455 		mac->cd_length = digest_len;
1456 		return (CRYPTO_SUCCESS);
1457 	}
1458 bail:
1459 	bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
1460 	mac->cd_length = 0;
1461 	return (ret);
1462 }
1463 
1464 /* ARGSUSED */
1465 static int
1466 sha2_mac_verify_atomic(crypto_provider_handle_t provider,
1467     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1468     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
1469     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
1470 {
1471 	int ret = CRYPTO_SUCCESS;
1472 	uchar_t digest[SHA512_DIGEST_LENGTH];
1473 	sha2_hmac_ctx_t sha2_hmac_ctx;
1474 	uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
1475 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
1476 
1477 	/*
1478 	 * Set the digest length and block size to values appropriate to the
1479 	 * mechanism
1480 	 */
1481 	switch (mechanism->cm_type) {
1482 	case SHA256_HMAC_MECH_INFO_TYPE:
1483 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
1484 		sha_digest_len = digest_len = SHA256_DIGEST_LENGTH;
1485 		sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
1486 		break;
1487 	case SHA384_HMAC_MECH_INFO_TYPE:
1488 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
1489 	case SHA512_HMAC_MECH_INFO_TYPE:
1490 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
1491 		sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
1492 		sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
1493 		break;
1494 	default:
1495 		return (CRYPTO_MECHANISM_INVALID);
1496 	}
1497 
1498 	/* Add support for key by attributes (RFE 4706552) */
1499 	if (key->ck_format != CRYPTO_KEY_RAW)
1500 		return (CRYPTO_ARGUMENTS_BAD);
1501 
1502 	if (ctx_template != NULL) {
1503 		/* reuse context template */
1504 		bcopy(ctx_template, &sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
1505 	} else {
1506 		sha2_hmac_ctx.hc_mech_type = mechanism->cm_type;
1507 		/* no context template, initialize context */
1508 		if (keylen_in_bytes > sha_hmac_block_size) {
1509 			/*
1510 			 * Hash the passed-in key to get a smaller key.
1511 			 * The inner context is used since it hasn't been
1512 			 * initialized yet.
1513 			 */
1514 			PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
1515 			    &sha2_hmac_ctx.hc_icontext,
1516 			    key->ck_data, keylen_in_bytes, digest);
1517 			sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
1518 			    sha_digest_len);
1519 		} else {
1520 			sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
1521 			    keylen_in_bytes);
1522 		}
1523 	}
1524 
1525 	/* get the mechanism parameters, if applicable */
1526 	if (sha2_is_general_hmech(mechanism)) {
1527 		if (mechanism->cm_param == NULL ||
1528 		    mechanism->cm_param_len != sizeof (ulong_t)) {
1529 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1530 			goto bail;
1531 		}
1532 		PROV_SHA2_GET_DIGEST_LEN(mechanism, digest_len);
1533 		if (digest_len > sha_digest_len) {
1534 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1535 			goto bail;
1536 		}
1537 	}
1538 
1539 	if (mac->cd_length != digest_len) {
1540 		ret = CRYPTO_INVALID_MAC;
1541 		goto bail;
1542 	}
1543 
1544 	/* do a SHA2 update of the inner context using the specified data */
1545 	SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
1546 	if (ret != CRYPTO_SUCCESS)
1547 		/* the update failed, free context and bail */
1548 		goto bail;
1549 
1550 	/* do a SHA2 final on the inner context */
1551 	SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
1552 
1553 	/*
1554 	 * Do an SHA2 update on the outer context, feeding the inner
1555 	 * digest as data.
1556 	 *
1557 	 * HMAC-SHA384 needs special handling as the outer hash needs only 48
1558 	 * bytes of the inner hash value.
1559 	 */
1560 	if (mechanism->cm_type == SHA384_HMAC_MECH_INFO_TYPE ||
1561 	    mechanism->cm_type == SHA384_HMAC_GEN_MECH_INFO_TYPE)
1562 		SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest,
1563 		    SHA384_DIGEST_LENGTH);
1564 	else
1565 		SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
1566 
1567 	/*
1568 	 * Do a SHA2 final on the outer context, storing the computed
1569 	 * digest in the users buffer.
1570 	 */
1571 	SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
1572 
1573 	/*
1574 	 * Compare the computed digest against the expected digest passed
1575 	 * as argument.
1576 	 */
1577 
1578 	switch (mac->cd_format) {
1579 
1580 	case CRYPTO_DATA_RAW:
1581 		if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
1582 		    mac->cd_offset, digest_len) != 0)
1583 			ret = CRYPTO_INVALID_MAC;
1584 		break;
1585 
1586 	case CRYPTO_DATA_UIO: {
1587 		off_t offset = mac->cd_offset;
1588 		uint_t vec_idx;
1589 		off_t scratch_offset = 0;
1590 		size_t length = digest_len;
1591 		size_t cur_len;
1592 
1593 		/* we support only kernel buffer */
1594 		if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
1595 			return (CRYPTO_ARGUMENTS_BAD);
1596 
1597 		/* jump to the first iovec containing the expected digest */
1598 		for (vec_idx = 0;
1599 		    offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
1600 		    vec_idx < mac->cd_uio->uio_iovcnt;
1601 		    offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len)
1602 			;
1603 		if (vec_idx == mac->cd_uio->uio_iovcnt) {
1604 			/*
1605 			 * The caller specified an offset that is
1606 			 * larger than the total size of the buffers
1607 			 * it provided.
1608 			 */
1609 			ret = CRYPTO_DATA_LEN_RANGE;
1610 			break;
1611 		}
1612 
1613 		/* do the comparison of computed digest vs specified one */
1614 		while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
1615 			cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
1616 			    offset, length);
1617 
1618 			if (bcmp(digest + scratch_offset,
1619 			    mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
1620 			    cur_len) != 0) {
1621 				ret = CRYPTO_INVALID_MAC;
1622 				break;
1623 			}
1624 
1625 			length -= cur_len;
1626 			vec_idx++;
1627 			scratch_offset += cur_len;
1628 			offset = 0;
1629 		}
1630 		break;
1631 	}
1632 
1633 	case CRYPTO_DATA_MBLK: {
1634 		off_t offset = mac->cd_offset;
1635 		mblk_t *mp;
1636 		off_t scratch_offset = 0;
1637 		size_t length = digest_len;
1638 		size_t cur_len;
1639 
1640 		/* jump to the first mblk_t containing the expected digest */
1641 		for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
1642 		    offset -= MBLKL(mp), mp = mp->b_cont)
1643 			;
1644 		if (mp == NULL) {
1645 			/*
1646 			 * The caller specified an offset that is larger than
1647 			 * the total size of the buffers it provided.
1648 			 */
1649 			ret = CRYPTO_DATA_LEN_RANGE;
1650 			break;
1651 		}
1652 
1653 		while (mp != NULL && length > 0) {
1654 			cur_len = MIN(MBLKL(mp) - offset, length);
1655 			if (bcmp(digest + scratch_offset,
1656 			    mp->b_rptr + offset, cur_len) != 0) {
1657 				ret = CRYPTO_INVALID_MAC;
1658 				break;
1659 			}
1660 
1661 			length -= cur_len;
1662 			mp = mp->b_cont;
1663 			scratch_offset += cur_len;
1664 			offset = 0;
1665 		}
1666 		break;
1667 	}
1668 
1669 	default:
1670 		ret = CRYPTO_ARGUMENTS_BAD;
1671 	}
1672 
1673 	return (ret);
1674 bail:
1675 	bzero(&sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
1676 	mac->cd_length = 0;
1677 	return (ret);
1678 }
1679 
1680 /*
1681  * KCF software provider context management entry points.
1682  */
1683 
1684 /* ARGSUSED */
1685 static int
1686 sha2_create_ctx_template(crypto_provider_handle_t provider,
1687     crypto_mechanism_t *mechanism, crypto_key_t *key,
1688     crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
1689     crypto_req_handle_t req)
1690 {
1691 	sha2_hmac_ctx_t *sha2_hmac_ctx_tmpl;
1692 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
1693 	uint32_t sha_digest_len, sha_hmac_block_size;
1694 
1695 	/*
1696 	 * Set the digest length and block size to values appropriate to the
1697 	 * mechanism
1698 	 */
1699 	switch (mechanism->cm_type) {
1700 	case SHA256_HMAC_MECH_INFO_TYPE:
1701 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
1702 		sha_digest_len = SHA256_DIGEST_LENGTH;
1703 		sha_hmac_block_size = SHA256_HMAC_BLOCK_SIZE;
1704 		break;
1705 	case SHA384_HMAC_MECH_INFO_TYPE:
1706 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
1707 	case SHA512_HMAC_MECH_INFO_TYPE:
1708 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
1709 		sha_digest_len = SHA512_DIGEST_LENGTH;
1710 		sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
1711 		break;
1712 	default:
1713 		return (CRYPTO_MECHANISM_INVALID);
1714 	}
1715 
1716 	/* Add support for key by attributes (RFE 4706552) */
1717 	if (key->ck_format != CRYPTO_KEY_RAW)
1718 		return (CRYPTO_ARGUMENTS_BAD);
1719 
1720 	/*
1721 	 * Allocate and initialize SHA2 context.
1722 	 */
1723 	sha2_hmac_ctx_tmpl = kmem_alloc(sizeof (sha2_hmac_ctx_t),
1724 	    crypto_kmflag(req));
1725 	if (sha2_hmac_ctx_tmpl == NULL)
1726 		return (CRYPTO_HOST_MEMORY);
1727 
1728 	sha2_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
1729 
1730 	if (keylen_in_bytes > sha_hmac_block_size) {
1731 		uchar_t digested_key[SHA512_DIGEST_LENGTH];
1732 
1733 		/*
1734 		 * Hash the passed-in key to get a smaller key.
1735 		 * The inner context is used since it hasn't been
1736 		 * initialized yet.
1737 		 */
1738 		PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
1739 		    &sha2_hmac_ctx_tmpl->hc_icontext,
1740 		    key->ck_data, keylen_in_bytes, digested_key);
1741 		sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, digested_key,
1742 		    sha_digest_len);
1743 	} else {
1744 		sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, key->ck_data,
1745 		    keylen_in_bytes);
1746 	}
1747 
1748 	*ctx_template = (crypto_spi_ctx_template_t)sha2_hmac_ctx_tmpl;
1749 	*ctx_template_size = sizeof (sha2_hmac_ctx_t);
1750 
1751 	return (CRYPTO_SUCCESS);
1752 }
1753 
1754 static int
1755 sha2_free_context(crypto_ctx_t *ctx)
1756 {
1757 	uint_t ctx_len;
1758 
1759 	if (ctx->cc_provider_private == NULL)
1760 		return (CRYPTO_SUCCESS);
1761 
1762 	switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
1763 	case SHA256_MECH_INFO_TYPE:
1764 	case SHA384_MECH_INFO_TYPE:
1765 	case SHA512_MECH_INFO_TYPE:
1766 	case SHA512_224_MECH_INFO_TYPE:
1767 	case SHA512_256_MECH_INFO_TYPE:
1768 		ctx_len = sizeof (sha2_ctx_t);
1769 		break;
1770 	case SHA256_HMAC_MECH_INFO_TYPE:
1771 	case SHA256_HMAC_GEN_MECH_INFO_TYPE:
1772 	case SHA384_HMAC_MECH_INFO_TYPE:
1773 	case SHA384_HMAC_GEN_MECH_INFO_TYPE:
1774 	case SHA512_HMAC_MECH_INFO_TYPE:
1775 	case SHA512_HMAC_GEN_MECH_INFO_TYPE:
1776 		ctx_len = sizeof (sha2_hmac_ctx_t);
1777 		break;
1778 	default:
1779 		/*
1780 		 * If we get here, someone forgot to update the above list
1781 		 * when adding a new mechanism.  Without the correct ctx_len
1782 		 * we will corrupt the heap when calling kmem_free, so panic
1783 		 * now and make it easier to identify the problem.
1784 		 */
1785 		panic("Unknown SHA2 mechanism %d",
1786 		    PROV_SHA2_CTX(ctx)->sc_mech_type);
1787 	}
1788 
1789 	bzero(ctx->cc_provider_private, ctx_len);
1790 	kmem_free(ctx->cc_provider_private, ctx_len);
1791 	ctx->cc_provider_private = NULL;
1792 
1793 	return (CRYPTO_SUCCESS);
1794 }
1795