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