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