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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
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>
36 #include <sha2/sha2_impl.h>
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
47 static struct modlmisc modlmisc
= {
49 "SHA2 Message-Digest Algorithm"
52 static struct modlcrypto modlcrypto
= {
54 "SHA2 Kernel SW Provider"
57 static struct modlinkage modlinkage
= {
58 MODREV_1
, &modlmisc
, &modlcrypto
, NULL
62 * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed
63 * by KCF to one of the entry points.
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)
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); \
75 bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
76 (len) = (uint32_t)tmp_ulong; \
80 #define PROV_SHA2_DIGEST_KEY(mech, ctx, key, len, digest) { \
81 SHA2Init(mech, ctx); \
82 SHA2Update(ctx, key, len); \
83 SHA2Final(digest, ctx); \
87 * Mechanism info structure passed to KCF during registration.
89 static crypto_mech_info_t sha2_mech_info_tab
[] = {
91 {SUN_CKM_SHA256
, SHA256_MECH_INFO_TYPE
,
92 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
,
93 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
},
105 {SUN_CKM_SHA384
, SHA384_MECH_INFO_TYPE
,
106 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
,
107 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
},
119 {SUN_CKM_SHA512
, SHA512_MECH_INFO_TYPE
,
120 CRYPTO_FG_DIGEST
| CRYPTO_FG_DIGEST_ATOMIC
,
121 0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS
},
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
}
134 static void sha2_provider_status(crypto_provider_handle_t
, uint_t
*);
136 static crypto_control_ops_t sha2_control_ops
= {
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
);
152 static crypto_digest_ops_t sha2_digest_ops
= {
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
);
173 static crypto_mac_ops_t sha2_mac_ops
= {
179 sha2_mac_verify_atomic
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
*);
187 static crypto_ctx_ops_t sha2_ctx_ops
= {
188 sha2_create_ctx_template
,
192 static crypto_ops_t sha2_crypto_ops
= {
212 static crypto_provider_info_t sha2_prov_info
= {
213 CRYPTO_SPI_VERSION_4
,
214 "SHA2 Software Provider",
219 sizeof (sha2_mech_info_tab
)/sizeof (crypto_mech_info_t
),
223 static crypto_kcf_provider_handle_t sha2_prov_handle
= 0;
230 if ((ret
= mod_install(&modlinkage
)) != 0)
234 * Register with KCF. If the registration fails, do not uninstall the
235 * module, since the functionality provided by misc/sha2 should still
238 (void) crypto_register_provider(&sha2_prov_info
, &sha2_prov_handle
);
244 _info(struct modinfo
*modinfop
)
246 return (mod_info(&modlinkage
, modinfop
));
250 * KCF software provider control entry points.
254 sha2_provider_status(crypto_provider_handle_t provider
, uint_t
*status
)
256 *status
= CRYPTO_PROVIDER_READY
;
260 * KCF software provider digest entry points.
264 sha2_digest_init(crypto_ctx_t
*ctx
, crypto_mechanism_t
*mechanism
,
265 crypto_req_handle_t req
)
269 * Allocate and initialize SHA2 context.
271 ctx
->cc_provider_private
= kmem_alloc(sizeof (sha2_ctx_t
),
273 if (ctx
->cc_provider_private
== NULL
)
274 return (CRYPTO_HOST_MEMORY
);
276 PROV_SHA2_CTX(ctx
)->sc_mech_type
= mechanism
->cm_type
;
277 SHA2Init(mechanism
->cm_type
, &PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
);
279 return (CRYPTO_SUCCESS
);
283 * Helper SHA2 digest update function for uio data.
286 sha2_digest_update_uio(SHA2_CTX
*sha2_ctx
, crypto_data_t
*data
)
288 off_t offset
= data
->cd_offset
;
289 size_t length
= data
->cd_length
;
293 /* we support only kernel buffer */
294 if (data
->cd_uio
->uio_segflg
!= UIO_SYSSPACE
)
295 return (CRYPTO_ARGUMENTS_BAD
);
298 * Jump to the first iovec containing data to be
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
)
305 if (vec_idx
== data
->cd_uio
->uio_iovcnt
) {
307 * The caller specified an offset that is larger than the
308 * total size of the buffers it provided.
310 return (CRYPTO_DATA_LEN_RANGE
);
314 * Now do the digesting on the iovecs.
316 while (vec_idx
< data
->cd_uio
->uio_iovcnt
&& length
> 0) {
317 cur_len
= MIN(data
->cd_uio
->uio_iov
[vec_idx
].iov_len
-
320 SHA2Update(sha2_ctx
, (uint8_t *)data
->cd_uio
->
321 uio_iov
[vec_idx
].iov_base
+ offset
, cur_len
);
327 if (vec_idx
== data
->cd_uio
->uio_iovcnt
&& length
> 0) {
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.
333 return (CRYPTO_DATA_LEN_RANGE
);
336 return (CRYPTO_SUCCESS
);
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.
347 sha2_digest_final_uio(SHA2_CTX
*sha2_ctx
, crypto_data_t
*digest
,
348 ulong_t digest_len
, uchar_t
*digest_scratch
)
350 off_t offset
= digest
->cd_offset
;
353 /* we support only kernel buffer */
354 if (digest
->cd_uio
->uio_segflg
!= UIO_SYSSPACE
)
355 return (CRYPTO_ARGUMENTS_BAD
);
358 * Jump to the first iovec containing ptr to the digest to
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
)
365 if (vec_idx
== digest
->cd_uio
->uio_iovcnt
) {
367 * The caller specified an offset that is
368 * larger than the total size of the buffers
371 return (CRYPTO_DATA_LEN_RANGE
);
374 if (offset
+ digest_len
<=
375 digest
->cd_uio
->uio_iov
[vec_idx
].iov_len
) {
377 * The computed SHA2 digest will fit in the current
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
))) {
385 * The caller requested a short digest. Digest
386 * into a scratch buffer and return to
387 * the user only what was requested.
389 SHA2Final(digest_scratch
, sha2_ctx
);
391 bcopy(digest_scratch
, (uchar_t
*)digest
->
392 cd_uio
->uio_iov
[vec_idx
].iov_base
+ offset
,
395 SHA2Final((uchar_t
*)digest
->
396 cd_uio
->uio_iov
[vec_idx
].iov_base
+ offset
,
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.
407 uchar_t digest_tmp
[SHA512_DIGEST_LENGTH
];
408 off_t scratch_offset
= 0;
409 size_t length
= digest_len
;
412 SHA2Final(digest_tmp
, sha2_ctx
);
414 while (vec_idx
< digest
->cd_uio
->uio_iovcnt
&& length
> 0) {
416 MIN(digest
->cd_uio
->uio_iov
[vec_idx
].iov_len
-
418 bcopy(digest_tmp
+ scratch_offset
,
419 digest
->cd_uio
->uio_iov
[vec_idx
].iov_base
+ offset
,
424 scratch_offset
+= cur_len
;
428 if (vec_idx
== digest
->cd_uio
->uio_iovcnt
&& length
> 0) {
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
435 return (CRYPTO_DATA_LEN_RANGE
);
439 return (CRYPTO_SUCCESS
);
443 * Helper SHA2 digest update for mblk's.
446 sha2_digest_update_mblk(SHA2_CTX
*sha2_ctx
, crypto_data_t
*data
)
448 off_t offset
= data
->cd_offset
;
449 size_t length
= data
->cd_length
;
454 * Jump to the first mblk_t containing data to be digested.
456 for (mp
= data
->cd_mp
; mp
!= NULL
&& offset
>= MBLKL(mp
);
457 offset
-= MBLKL(mp
), mp
= mp
->b_cont
)
461 * The caller specified an offset that is larger than the
462 * total size of the buffers it provided.
464 return (CRYPTO_DATA_LEN_RANGE
);
468 * Now do the digesting on the mblk chain.
470 while (mp
!= NULL
&& length
> 0) {
471 cur_len
= MIN(MBLKL(mp
) - offset
, length
);
472 SHA2Update(sha2_ctx
, mp
->b_rptr
+ offset
, cur_len
);
478 if (mp
== NULL
&& length
> 0) {
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.
484 return (CRYPTO_DATA_LEN_RANGE
);
487 return (CRYPTO_SUCCESS
);
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.
498 sha2_digest_final_mblk(SHA2_CTX
*sha2_ctx
, crypto_data_t
*digest
,
499 ulong_t digest_len
, uchar_t
*digest_scratch
)
501 off_t offset
= digest
->cd_offset
;
505 * Jump to the first mblk_t that will be used to store the digest.
507 for (mp
= digest
->cd_mp
; mp
!= NULL
&& offset
>= MBLKL(mp
);
508 offset
-= MBLKL(mp
), mp
= mp
->b_cont
)
512 * The caller specified an offset that is larger than the
513 * total size of the buffers it provided.
515 return (CRYPTO_DATA_LEN_RANGE
);
518 if (offset
+ digest_len
<= MBLKL(mp
)) {
520 * The computed SHA2 digest will fit in the current mblk.
521 * Do the SHA2Final() in-place.
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
))) {
528 * The caller requested a short digest. Digest
529 * into a scratch buffer and return to
530 * the user only what was requested.
532 SHA2Final(digest_scratch
, sha2_ctx
);
533 bcopy(digest_scratch
, mp
->b_rptr
+ offset
, digest_len
);
535 SHA2Final(mp
->b_rptr
+ offset
, sha2_ctx
);
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.
544 uchar_t digest_tmp
[SHA512_DIGEST_LENGTH
];
545 off_t scratch_offset
= 0;
546 size_t length
= digest_len
;
549 SHA2Final(digest_tmp
, sha2_ctx
);
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
);
558 scratch_offset
+= cur_len
;
562 if (mp
== NULL
&& length
> 0) {
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
569 return (CRYPTO_DATA_LEN_RANGE
);
573 return (CRYPTO_SUCCESS
);
578 sha2_digest(crypto_ctx_t
*ctx
, crypto_data_t
*data
, crypto_data_t
*digest
,
579 crypto_req_handle_t req
)
581 int ret
= CRYPTO_SUCCESS
;
582 uint_t sha_digest_len
;
584 ASSERT(ctx
->cc_provider_private
!= NULL
);
586 switch (PROV_SHA2_CTX(ctx
)->sc_mech_type
) {
587 case SHA256_MECH_INFO_TYPE
:
588 sha_digest_len
= SHA256_DIGEST_LENGTH
;
590 case SHA384_MECH_INFO_TYPE
:
591 sha_digest_len
= SHA384_DIGEST_LENGTH
;
593 case SHA512_MECH_INFO_TYPE
:
594 sha_digest_len
= SHA512_DIGEST_LENGTH
;
597 return (CRYPTO_MECHANISM_INVALID
);
601 * We need to just return the length needed to store the output.
602 * We should not destroy the context for the following cases.
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
);
611 * Do the SHA2 update on the specified input data.
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
,
619 case CRYPTO_DATA_UIO
:
620 ret
= sha2_digest_update_uio(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
623 case CRYPTO_DATA_MBLK
:
624 ret
= sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
628 ret
= CRYPTO_ARGUMENTS_BAD
;
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;
640 * Do a SHA2 final, must be done separately since the digest
641 * type can be different than the input data type.
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
);
648 case CRYPTO_DATA_UIO
:
649 ret
= sha2_digest_final_uio(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
650 digest
, sha_digest_len
, NULL
);
652 case CRYPTO_DATA_MBLK
:
653 ret
= sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
654 digest
, sha_digest_len
, NULL
);
657 ret
= CRYPTO_ARGUMENTS_BAD
;
660 /* all done, free context and return */
662 if (ret
== CRYPTO_SUCCESS
)
663 digest
->cd_length
= sha_digest_len
;
665 digest
->cd_length
= 0;
667 kmem_free(ctx
->cc_provider_private
, sizeof (sha2_ctx_t
));
668 ctx
->cc_provider_private
= NULL
;
674 sha2_digest_update(crypto_ctx_t
*ctx
, crypto_data_t
*data
,
675 crypto_req_handle_t req
)
677 int ret
= CRYPTO_SUCCESS
;
679 ASSERT(ctx
->cc_provider_private
!= NULL
);
682 * Do the SHA2 update on the specified input data.
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
,
690 case CRYPTO_DATA_UIO
:
691 ret
= sha2_digest_update_uio(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
694 case CRYPTO_DATA_MBLK
:
695 ret
= sha2_digest_update_mblk(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
699 ret
= CRYPTO_ARGUMENTS_BAD
;
707 sha2_digest_final(crypto_ctx_t
*ctx
, crypto_data_t
*digest
,
708 crypto_req_handle_t req
)
710 int ret
= CRYPTO_SUCCESS
;
711 uint_t sha_digest_len
;
713 ASSERT(ctx
->cc_provider_private
!= NULL
);
715 switch (PROV_SHA2_CTX(ctx
)->sc_mech_type
) {
716 case SHA256_MECH_INFO_TYPE
:
717 sha_digest_len
= SHA256_DIGEST_LENGTH
;
719 case SHA384_MECH_INFO_TYPE
:
720 sha_digest_len
= SHA384_DIGEST_LENGTH
;
722 case SHA512_MECH_INFO_TYPE
:
723 sha_digest_len
= SHA512_DIGEST_LENGTH
;
726 return (CRYPTO_MECHANISM_INVALID
);
730 * We need to just return the length needed to store the output.
731 * We should not destroy the context for the following cases.
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
);
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
);
747 case CRYPTO_DATA_UIO
:
748 ret
= sha2_digest_final_uio(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
749 digest
, sha_digest_len
, NULL
);
751 case CRYPTO_DATA_MBLK
:
752 ret
= sha2_digest_final_mblk(&PROV_SHA2_CTX(ctx
)->sc_sha2_ctx
,
753 digest
, sha_digest_len
, NULL
);
756 ret
= CRYPTO_ARGUMENTS_BAD
;
759 /* all done, free context and return */
761 if (ret
== CRYPTO_SUCCESS
)
762 digest
->cd_length
= sha_digest_len
;
764 digest
->cd_length
= 0;
766 kmem_free(ctx
->cc_provider_private
, sizeof (sha2_ctx_t
));
767 ctx
->cc_provider_private
= NULL
;
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
)
779 int ret
= CRYPTO_SUCCESS
;
781 uint32_t sha_digest_len
;
787 SHA2Init(mechanism
->cm_type
, &sha2_ctx
);
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
);
794 case CRYPTO_DATA_UIO
:
795 ret
= sha2_digest_update_uio(&sha2_ctx
, data
);
797 case CRYPTO_DATA_MBLK
:
798 ret
= sha2_digest_update_mblk(&sha2_ctx
, data
);
801 ret
= CRYPTO_ARGUMENTS_BAD
;
805 * Do the SHA updates on the specified input data.
808 if (ret
!= CRYPTO_SUCCESS
) {
809 /* the update failed, bail */
810 digest
->cd_length
= 0;
814 if (mechanism
->cm_type
<= SHA256_HMAC_GEN_MECH_INFO_TYPE
)
815 sha_digest_len
= SHA256_DIGEST_LENGTH
;
817 sha_digest_len
= SHA512_DIGEST_LENGTH
;
820 * Do a SHA2 final, must be done separately since the digest
821 * type can be different than the input data type.
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
);
828 case CRYPTO_DATA_UIO
:
829 ret
= sha2_digest_final_uio(&sha2_ctx
, digest
,
830 sha_digest_len
, NULL
);
832 case CRYPTO_DATA_MBLK
:
833 ret
= sha2_digest_final_mblk(&sha2_ctx
, digest
,
834 sha_digest_len
, NULL
);
837 ret
= CRYPTO_ARGUMENTS_BAD
;
840 if (ret
== CRYPTO_SUCCESS
)
841 digest
->cd_length
= sha_digest_len
;
843 digest
->cd_length
= 0;
849 * KCF software provider mac entry points.
851 * SHA2 HMAC is: SHA2(key XOR opad, SHA2(key XOR ipad, text))
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)
860 * Each subsequent SHA2 HMAC update will result in an
861 * update of the inner context with the specified data.
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
873 * Initialize a SHA2-HMAC context.
876 sha2_mac_init_ctx(sha2_hmac_ctx_t
*ctx
, void *keyval
, uint_t length_in_bytes
)
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
;
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);
887 block_size
= SHA512_HMAC_BLOCK_SIZE
;
888 blocks_per_int64
= SHA512_HMAC_BLOCK_SIZE
/ sizeof (uint64_t);
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
);
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;
902 /* perform SHA2 on ipad */
903 SHA2Init(ctx
->hc_mech_type
, &ctx
->hc_icontext
);
904 SHA2Update(&ctx
->hc_icontext
, (uint8_t *)ipad
, block_size
);
906 /* perform SHA2 on opad */
907 SHA2Init(ctx
->hc_mech_type
, &ctx
->hc_ocontext
);
908 SHA2Update(&ctx
->hc_ocontext
, (uint8_t *)opad
, block_size
);
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
)
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
;
924 * Set the digest length and block size to values appropriate to the
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
;
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
;
941 return (CRYPTO_MECHANISM_INVALID
);
944 if (key
->ck_format
!= CRYPTO_KEY_RAW
)
945 return (CRYPTO_ARGUMENTS_BAD
);
947 ctx
->cc_provider_private
= kmem_alloc(sizeof (sha2_hmac_ctx_t
),
949 if (ctx
->cc_provider_private
== NULL
)
950 return (CRYPTO_HOST_MEMORY
);
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
));
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
;
964 * Hash the passed-in key to get a smaller key.
965 * The inner context is used since it hasn't been
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
);
974 sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx
),
975 key
->ck_data
, keylen_in_bytes
);
980 * Get the mechanism parameters, if applicable.
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
;
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
;
1003 sha2_mac_update(crypto_ctx_t
*ctx
, crypto_data_t
*data
,
1004 crypto_req_handle_t req
)
1006 int ret
= CRYPTO_SUCCESS
;
1008 ASSERT(ctx
->cc_provider_private
!= NULL
);
1011 * Do a SHA2 update of the inner context using the specified
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
,
1020 case CRYPTO_DATA_UIO
:
1021 ret
= sha2_digest_update_uio(
1022 &PROV_SHA2_HMAC_CTX(ctx
)->hc_icontext
, data
);
1024 case CRYPTO_DATA_MBLK
:
1025 ret
= sha2_digest_update_mblk(
1026 &PROV_SHA2_HMAC_CTX(ctx
)->hc_icontext
, data
);
1029 ret
= CRYPTO_ARGUMENTS_BAD
;
1037 sha2_mac_final(crypto_ctx_t
*ctx
, crypto_data_t
*mac
, crypto_req_handle_t req
)
1039 int ret
= CRYPTO_SUCCESS
;
1040 uchar_t digest
[SHA512_DIGEST_LENGTH
];
1041 uint32_t digest_len
, sha_digest_len
;
1043 ASSERT(ctx
->cc_provider_private
!= NULL
);
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
;
1050 case SHA384_HMAC_MECH_INFO_TYPE
:
1051 sha_digest_len
= digest_len
= SHA384_DIGEST_LENGTH
;
1053 case SHA512_HMAC_MECH_INFO_TYPE
:
1054 sha_digest_len
= digest_len
= SHA512_DIGEST_LENGTH
;
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
;
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
;
1068 * We need to just return the length needed to store the output.
1069 * We should not destroy the context for the following cases.
1071 if ((mac
->cd_length
== 0) || (mac
->cd_length
< digest_len
)) {
1072 mac
->cd_length
= digest_len
;
1073 return (CRYPTO_BUFFER_TOO_SMALL
);
1077 * Do a SHA2 final on the inner context.
1079 SHA2Final(digest
, &PROV_SHA2_HMAC_CTX(ctx
)->hc_icontext
);
1082 * Do a SHA2 update on the outer context, feeding the inner
1085 SHA2Update(&PROV_SHA2_HMAC_CTX(ctx
)->hc_ocontext
, digest
,
1089 * Do a SHA2 final on the outer context, storing the computing
1090 * digest in the users buffer.
1092 switch (mac
->cd_format
) {
1093 case CRYPTO_DATA_RAW
:
1094 if (digest_len
!= sha_digest_len
) {
1096 * The caller requested a short digest. Digest
1097 * into a scratch buffer and return to
1098 * the user only what was requested.
1101 &PROV_SHA2_HMAC_CTX(ctx
)->hc_ocontext
);
1102 bcopy(digest
, (unsigned char *)mac
->cd_raw
.iov_base
+
1103 mac
->cd_offset
, digest_len
);
1105 SHA2Final((unsigned char *)mac
->cd_raw
.iov_base
+
1107 &PROV_SHA2_HMAC_CTX(ctx
)->hc_ocontext
);
1110 case CRYPTO_DATA_UIO
:
1111 ret
= sha2_digest_final_uio(
1112 &PROV_SHA2_HMAC_CTX(ctx
)->hc_ocontext
, mac
,
1113 digest_len
, digest
);
1115 case CRYPTO_DATA_MBLK
:
1116 ret
= sha2_digest_final_mblk(
1117 &PROV_SHA2_HMAC_CTX(ctx
)->hc_ocontext
, mac
,
1118 digest_len
, digest
);
1121 ret
= CRYPTO_ARGUMENTS_BAD
;
1124 if (ret
== CRYPTO_SUCCESS
)
1125 mac
->cd_length
= digest_len
;
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
;
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); \
1143 case CRYPTO_DATA_UIO: \
1144 ret = sha2_digest_update_uio(&(ctx).hc_icontext, data); \
1146 case CRYPTO_DATA_MBLK: \
1147 ret = sha2_digest_update_mblk(&(ctx).hc_icontext, \
1151 ret = CRYPTO_ARGUMENTS_BAD; \
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
)
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
);
1169 * Set the digest length and block size to values appropriate to the
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
;
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
;
1186 return (CRYPTO_MECHANISM_INVALID
);
1189 /* Add support for key by attributes (RFE 4706552) */
1190 if (key
->ck_format
!= CRYPTO_KEY_RAW
)
1191 return (CRYPTO_ARGUMENTS_BAD
);
1193 if (ctx_template
!= NULL
) {
1194 /* reuse context template */
1195 bcopy(ctx_template
, &sha2_hmac_ctx
, sizeof (sha2_hmac_ctx_t
));
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
) {
1201 * Hash the passed-in key to get a smaller key.
1202 * The inner context is used since it hasn't been
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
,
1211 sha2_mac_init_ctx(&sha2_hmac_ctx
, key
->ck_data
,
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
;
1223 PROV_SHA2_GET_DIGEST_LEN(mechanism
, digest_len
);
1224 if (digest_len
> sha_digest_len
) {
1225 ret
= CRYPTO_MECHANISM_PARAM_INVALID
;
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 */
1237 * Do a SHA2 final on the inner context.
1239 SHA2Final(digest
, &sha2_hmac_ctx
.hc_icontext
);
1242 * Do an SHA2 update on the outer context, feeding the inner
1245 * HMAC-SHA384 needs special handling as the outer hash needs only 48
1246 * bytes of the inner hash value.
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
);
1253 SHA2Update(&sha2_hmac_ctx
.hc_ocontext
, digest
, sha_digest_len
);
1256 * Do a SHA2 final on the outer context, storing the computed
1257 * digest in the users buffer.
1259 switch (mac
->cd_format
) {
1260 case CRYPTO_DATA_RAW
:
1261 if (digest_len
!= sha_digest_len
) {
1263 * The caller requested a short digest. Digest
1264 * into a scratch buffer and return to
1265 * the user only what was requested.
1267 SHA2Final(digest
, &sha2_hmac_ctx
.hc_ocontext
);
1268 bcopy(digest
, (unsigned char *)mac
->cd_raw
.iov_base
+
1269 mac
->cd_offset
, digest_len
);
1271 SHA2Final((unsigned char *)mac
->cd_raw
.iov_base
+
1272 mac
->cd_offset
, &sha2_hmac_ctx
.hc_ocontext
);
1275 case CRYPTO_DATA_UIO
:
1276 ret
= sha2_digest_final_uio(&sha2_hmac_ctx
.hc_ocontext
, mac
,
1277 digest_len
, digest
);
1279 case CRYPTO_DATA_MBLK
:
1280 ret
= sha2_digest_final_mblk(&sha2_hmac_ctx
.hc_ocontext
, mac
,
1281 digest_len
, digest
);
1284 ret
= CRYPTO_ARGUMENTS_BAD
;
1287 if (ret
== CRYPTO_SUCCESS
) {
1288 mac
->cd_length
= digest_len
;
1289 return (CRYPTO_SUCCESS
);
1292 bzero(&sha2_hmac_ctx
, sizeof (sha2_hmac_ctx_t
));
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
)
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
);
1311 * Set the digest length and block size to values appropriate to the
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
;
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
;
1328 return (CRYPTO_MECHANISM_INVALID
);
1331 /* Add support for key by attributes (RFE 4706552) */
1332 if (key
->ck_format
!= CRYPTO_KEY_RAW
)
1333 return (CRYPTO_ARGUMENTS_BAD
);
1335 if (ctx_template
!= NULL
) {
1336 /* reuse context template */
1337 bcopy(ctx_template
, &sha2_hmac_ctx
, sizeof (sha2_hmac_ctx_t
));
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
) {
1343 * Hash the passed-in key to get a smaller key.
1344 * The inner context is used since it hasn't been
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
,
1353 sha2_mac_init_ctx(&sha2_hmac_ctx
, key
->ck_data
,
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
;
1365 PROV_SHA2_GET_DIGEST_LEN(mechanism
, digest_len
);
1366 if (digest_len
> sha_digest_len
) {
1367 ret
= CRYPTO_MECHANISM_PARAM_INVALID
;
1372 if (mac
->cd_length
!= digest_len
) {
1373 ret
= CRYPTO_INVALID_MAC
;
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 */
1383 /* do a SHA2 final on the inner context */
1384 SHA2Final(digest
, &sha2_hmac_ctx
.hc_icontext
);
1387 * Do an SHA2 update on the outer context, feeding the inner
1390 * HMAC-SHA384 needs special handling as the outer hash needs only 48
1391 * bytes of the inner hash value.
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
);
1398 SHA2Update(&sha2_hmac_ctx
.hc_ocontext
, digest
, sha_digest_len
);
1401 * Do a SHA2 final on the outer context, storing the computed
1402 * digest in the users buffer.
1404 SHA2Final(digest
, &sha2_hmac_ctx
.hc_ocontext
);
1407 * Compare the computed digest against the expected digest passed
1411 switch (mac
->cd_format
) {
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
;
1419 case CRYPTO_DATA_UIO
: {
1420 off_t offset
= mac
->cd_offset
;
1422 off_t scratch_offset
= 0;
1423 size_t length
= digest_len
;
1426 /* we support only kernel buffer */
1427 if (mac
->cd_uio
->uio_segflg
!= UIO_SYSSPACE
)
1428 return (CRYPTO_ARGUMENTS_BAD
);
1430 /* jump to the first iovec containing the expected digest */
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
)
1436 if (vec_idx
== mac
->cd_uio
->uio_iovcnt
) {
1438 * The caller specified an offset that is
1439 * larger than the total size of the buffers
1442 ret
= CRYPTO_DATA_LEN_RANGE
;
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
-
1451 if (bcmp(digest
+ scratch_offset
,
1452 mac
->cd_uio
->uio_iov
[vec_idx
].iov_base
+ offset
,
1454 ret
= CRYPTO_INVALID_MAC
;
1460 scratch_offset
+= cur_len
;
1466 case CRYPTO_DATA_MBLK
: {
1467 off_t offset
= mac
->cd_offset
;
1469 off_t scratch_offset
= 0;
1470 size_t length
= digest_len
;
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
)
1479 * The caller specified an offset that is larger than
1480 * the total size of the buffers it provided.
1482 ret
= CRYPTO_DATA_LEN_RANGE
;
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
;
1496 scratch_offset
+= cur_len
;
1503 ret
= CRYPTO_ARGUMENTS_BAD
;
1508 bzero(&sha2_hmac_ctx
, sizeof (sha2_hmac_ctx_t
));
1514 * KCF software provider context management entry points.
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
)
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
;
1529 * Set the digest length and block size to values appropriate to the
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
;
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
;
1546 return (CRYPTO_MECHANISM_INVALID
);
1549 /* Add support for key by attributes (RFE 4706552) */
1550 if (key
->ck_format
!= CRYPTO_KEY_RAW
)
1551 return (CRYPTO_ARGUMENTS_BAD
);
1554 * Allocate and initialize SHA2 context.
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
);
1561 sha2_hmac_ctx_tmpl
->hc_mech_type
= mechanism
->cm_type
;
1563 if (keylen_in_bytes
> sha_hmac_block_size
) {
1564 uchar_t digested_key
[SHA512_DIGEST_LENGTH
];
1567 * Hash the passed-in key to get a smaller key.
1568 * The inner context is used since it hasn't been
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
,
1577 sha2_mac_init_ctx(sha2_hmac_ctx_tmpl
, key
->ck_data
,
1581 *ctx_template
= (crypto_spi_ctx_template_t
)sha2_hmac_ctx_tmpl
;
1582 *ctx_template_size
= sizeof (sha2_hmac_ctx_t
);
1584 return (CRYPTO_SUCCESS
);
1588 sha2_free_context(crypto_ctx_t
*ctx
)
1592 if (ctx
->cc_provider_private
== NULL
)
1593 return (CRYPTO_SUCCESS
);
1596 * We have to free either SHA2 or SHA2-HMAC contexts, which
1597 * have different lengths.
1599 * Note: Below is dependent on the mechanism ordering.
1602 if (PROV_SHA2_CTX(ctx
)->sc_mech_type
% 3 == 0)
1603 ctx_len
= sizeof (sha2_ctx_t
);
1605 ctx_len
= sizeof (sha2_hmac_ctx_t
);
1607 bzero(ctx
->cc_provider_private
, ctx_len
);
1608 kmem_free(ctx
->cc_provider_private
, ctx_len
);
1609 ctx
->cc_provider_private
= NULL
;
1611 return (CRYPTO_SUCCESS
);