1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * CDDL HEADER START
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or https://opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 #include <sys/zfs_context.h>
29 #include <sys/crypto/common.h>
30 #include <sys/crypto/spi.h>
31 #include <sys/crypto/icp.h>
32 #include <sys/sha2.h>
33 #include <sha2/sha2_impl.h>
34
35 /*
36 * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed
37 * by KCF to one of the entry points.
38 */
39
40 #define PROV_SHA2_CTX(ctx) ((sha2_ctx_t *)(ctx)->cc_provider_private)
41 #define PROV_SHA2_HMAC_CTX(ctx) ((sha2_hmac_ctx_t *)(ctx)->cc_provider_private)
42
43 /* to extract the digest length passed as mechanism parameter */
44 #define PROV_SHA2_GET_DIGEST_LEN(m, len) { \
45 if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
46 (len) = (uint32_t)*((ulong_t *)(m)->cm_param); \
47 else { \
48 ulong_t tmp_ulong; \
49 memcpy(&tmp_ulong, (m)->cm_param, sizeof (ulong_t)); \
50 (len) = (uint32_t)tmp_ulong; \
51 } \
52 }
53
54 #define PROV_SHA2_DIGEST_KEY(mech, ctx, key, len, digest) { \
55 SHA2Init(mech, ctx); \
56 SHA2Update(ctx, key, len); \
57 SHA2Final(digest, ctx); \
58 }
59
60 /*
61 * Mechanism info structure passed to KCF during registration.
62 */
63 static const crypto_mech_info_t sha2_mech_info_tab[] = {
64 /* SHA512-HMAC */
65 {SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
66 CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
67 };
68
69 static int sha2_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
70 crypto_spi_ctx_template_t);
71 static int sha2_mac_update(crypto_ctx_t *, crypto_data_t *);
72 static int sha2_mac_final(crypto_ctx_t *, crypto_data_t *);
73 static int sha2_mac_atomic(crypto_mechanism_t *, crypto_key_t *,
74 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t);
75 static int sha2_mac_verify_atomic(crypto_mechanism_t *, crypto_key_t *,
76 crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t);
77
78 static const crypto_mac_ops_t sha2_mac_ops = {
79 .mac_init = sha2_mac_init,
80 .mac = NULL,
81 .mac_update = sha2_mac_update,
82 .mac_final = sha2_mac_final,
83 .mac_atomic = sha2_mac_atomic,
84 .mac_verify_atomic = sha2_mac_verify_atomic
85 };
86
87 static int sha2_create_ctx_template(crypto_mechanism_t *, crypto_key_t *,
88 crypto_spi_ctx_template_t *, size_t *);
89 static int sha2_free_context(crypto_ctx_t *);
90
91 static const crypto_ctx_ops_t sha2_ctx_ops = {
92 .create_ctx_template = sha2_create_ctx_template,
93 .free_context = sha2_free_context
94 };
95
96 static const crypto_ops_t sha2_crypto_ops = {
97 NULL,
98 &sha2_mac_ops,
99 &sha2_ctx_ops,
100 };
101
102 static const crypto_provider_info_t sha2_prov_info = {
103 "SHA2 Software Provider",
104 &sha2_crypto_ops,
105 sizeof (sha2_mech_info_tab) / sizeof (crypto_mech_info_t),
106 sha2_mech_info_tab
107 };
108
109 static crypto_kcf_provider_handle_t sha2_prov_handle = 0;
110
111 int
sha2_mod_init(void)112 sha2_mod_init(void)
113 {
114 int ret;
115
116 /*
117 * Register with KCF. If the registration fails, log an
118 * error but do not uninstall the module, since the functionality
119 * provided by misc/sha2 should still be available.
120 */
121 if ((ret = crypto_register_provider(&sha2_prov_info,
122 &sha2_prov_handle)) != CRYPTO_SUCCESS)
123 cmn_err(CE_WARN, "sha2 _init: "
124 "crypto_register_provider() failed (0x%x)", ret);
125
126 return (0);
127 }
128
129 int
sha2_mod_fini(void)130 sha2_mod_fini(void)
131 {
132 int ret = 0;
133
134 if (sha2_prov_handle != 0) {
135 if ((ret = crypto_unregister_provider(sha2_prov_handle)) !=
136 CRYPTO_SUCCESS) {
137 cmn_err(CE_WARN,
138 "sha2 _fini: crypto_unregister_provider() "
139 "failed (0x%x)", ret);
140 return (EBUSY);
141 }
142 sha2_prov_handle = 0;
143 }
144
145 return (ret);
146 }
147
148 /*
149 * Helper SHA2 digest update function for uio data.
150 */
151 static int
sha2_digest_update_uio(SHA2_CTX * sha2_ctx,crypto_data_t * data)152 sha2_digest_update_uio(SHA2_CTX *sha2_ctx, crypto_data_t *data)
153 {
154 off_t offset = data->cd_offset;
155 size_t length = data->cd_length;
156 uint_t vec_idx = 0;
157 size_t cur_len;
158
159 /* we support only kernel buffer */
160 if (zfs_uio_segflg(data->cd_uio) != UIO_SYSSPACE)
161 return (CRYPTO_ARGUMENTS_BAD);
162
163 /*
164 * Jump to the first iovec containing data to be
165 * digested.
166 */
167 offset = zfs_uio_index_at_offset(data->cd_uio, offset, &vec_idx);
168 if (vec_idx == zfs_uio_iovcnt(data->cd_uio)) {
169 /*
170 * The caller specified an offset that is larger than the
171 * total size of the buffers it provided.
172 */
173 return (CRYPTO_DATA_LEN_RANGE);
174 }
175
176 /*
177 * Now do the digesting on the iovecs.
178 */
179 while (vec_idx < zfs_uio_iovcnt(data->cd_uio) && length > 0) {
180 cur_len = MIN(zfs_uio_iovlen(data->cd_uio, vec_idx) -
181 offset, length);
182
183 SHA2Update(sha2_ctx, (uint8_t *)zfs_uio_iovbase(data->cd_uio,
184 vec_idx) + offset, cur_len);
185 length -= cur_len;
186 vec_idx++;
187 offset = 0;
188 }
189
190 if (vec_idx == zfs_uio_iovcnt(data->cd_uio) && length > 0) {
191 /*
192 * The end of the specified iovec's was reached but
193 * the length requested could not be processed, i.e.
194 * The caller requested to digest more data than it provided.
195 */
196 return (CRYPTO_DATA_LEN_RANGE);
197 }
198
199 return (CRYPTO_SUCCESS);
200 }
201
202 /*
203 * Helper SHA2 digest final function for uio data.
204 * digest_len is the length of the desired digest. If digest_len
205 * is smaller than the default SHA2 digest length, the caller
206 * must pass a scratch buffer, digest_scratch, which must
207 * be at least the algorithm's digest length bytes.
208 */
209 static int
sha2_digest_final_uio(SHA2_CTX * sha2_ctx,crypto_data_t * digest,ulong_t digest_len,uchar_t * digest_scratch)210 sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
211 ulong_t digest_len, uchar_t *digest_scratch)
212 {
213 off_t offset = digest->cd_offset;
214 uint_t vec_idx = 0;
215
216 /* we support only kernel buffer */
217 if (zfs_uio_segflg(digest->cd_uio) != UIO_SYSSPACE)
218 return (CRYPTO_ARGUMENTS_BAD);
219
220 /*
221 * Jump to the first iovec containing ptr to the digest to
222 * be returned.
223 */
224 offset = zfs_uio_index_at_offset(digest->cd_uio, offset, &vec_idx);
225 if (vec_idx == zfs_uio_iovcnt(digest->cd_uio)) {
226 /*
227 * The caller specified an offset that is
228 * larger than the total size of the buffers
229 * it provided.
230 */
231 return (CRYPTO_DATA_LEN_RANGE);
232 }
233
234 if (offset + digest_len <=
235 zfs_uio_iovlen(digest->cd_uio, vec_idx)) {
236 /*
237 * The computed SHA2 digest will fit in the current
238 * iovec.
239 */
240 ASSERT3U(sha2_ctx->algotype, ==, SHA512_HMAC_MECH_INFO_TYPE);
241 if (digest_len != SHA512_DIGEST_LENGTH) {
242 /*
243 * The caller requested a short digest. Digest
244 * into a scratch buffer and return to
245 * the user only what was requested.
246 */
247 SHA2Final(digest_scratch, sha2_ctx);
248
249 memcpy((uchar_t *)
250 zfs_uio_iovbase(digest->cd_uio, vec_idx) + offset,
251 digest_scratch, digest_len);
252 } else {
253 SHA2Final((uchar_t *)zfs_uio_iovbase(digest->
254 cd_uio, vec_idx) + offset,
255 sha2_ctx);
256
257 }
258 } else {
259 /*
260 * The computed digest will be crossing one or more iovec's.
261 * This is bad performance-wise but we need to support it.
262 * Allocate a small scratch buffer on the stack and
263 * copy it piece meal to the specified digest iovec's.
264 */
265 uchar_t digest_tmp[SHA512_DIGEST_LENGTH];
266 off_t scratch_offset = 0;
267 size_t length = digest_len;
268 size_t cur_len;
269
270 SHA2Final(digest_tmp, sha2_ctx);
271
272 while (vec_idx < zfs_uio_iovcnt(digest->cd_uio) && length > 0) {
273 cur_len =
274 MIN(zfs_uio_iovlen(digest->cd_uio, vec_idx) -
275 offset, length);
276 memcpy(
277 zfs_uio_iovbase(digest->cd_uio, vec_idx) + offset,
278 digest_tmp + scratch_offset,
279 cur_len);
280
281 length -= cur_len;
282 vec_idx++;
283 scratch_offset += cur_len;
284 offset = 0;
285 }
286
287 if (vec_idx == zfs_uio_iovcnt(digest->cd_uio) && length > 0) {
288 /*
289 * The end of the specified iovec's was reached but
290 * the length requested could not be processed, i.e.
291 * The caller requested to digest more data than it
292 * provided.
293 */
294 return (CRYPTO_DATA_LEN_RANGE);
295 }
296 }
297
298 return (CRYPTO_SUCCESS);
299 }
300
301 /*
302 * KCF software provider mac entry points.
303 *
304 * SHA2 HMAC is: SHA2(key XOR opad, SHA2(key XOR ipad, text))
305 *
306 * Init:
307 * The initialization routine initializes what we denote
308 * as the inner and outer contexts by doing
309 * - for inner context: SHA2(key XOR ipad)
310 * - for outer context: SHA2(key XOR opad)
311 *
312 * Update:
313 * Each subsequent SHA2 HMAC update will result in an
314 * update of the inner context with the specified data.
315 *
316 * Final:
317 * The SHA2 HMAC final will do a SHA2 final operation on the
318 * inner context, and the resulting digest will be used
319 * as the data for an update on the outer context. Last
320 * but not least, a SHA2 final on the outer context will
321 * be performed to obtain the SHA2 HMAC digest to return
322 * to the user.
323 */
324
325 /*
326 * Initialize a SHA2-HMAC context.
327 */
328 static void
sha2_mac_init_ctx(sha2_hmac_ctx_t * ctx,void * keyval,uint_t length_in_bytes)329 sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
330 {
331 uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)] = {0};
332 uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)] = {0};
333 int i, block_size, blocks_per_int64;
334
335 /* Determine the block size */
336 ASSERT3U(ctx->hc_mech_type, ==, SHA512_HMAC_MECH_INFO_TYPE);
337 block_size = SHA512_HMAC_BLOCK_SIZE;
338 blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t);
339
340 (void) memset(ipad, 0, block_size);
341 (void) memset(opad, 0, block_size);
342
343 if (keyval != NULL) {
344 (void) memcpy(ipad, keyval, length_in_bytes);
345 (void) memcpy(opad, keyval, length_in_bytes);
346 } else {
347 ASSERT0(length_in_bytes);
348 }
349
350 /* XOR key with ipad (0x36) and opad (0x5c) */
351 for (i = 0; i < blocks_per_int64; i ++) {
352 ipad[i] ^= 0x3636363636363636;
353 opad[i] ^= 0x5c5c5c5c5c5c5c5c;
354 }
355
356 /* perform SHA2 on ipad */
357 SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext);
358 SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
359
360 /* perform SHA2 on opad */
361 SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext);
362 SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
363 }
364
365 /*
366 */
367 static int
sha2_mac_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t ctx_template)368 sha2_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
369 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template)
370 {
371 int ret = CRYPTO_SUCCESS;
372 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
373 uint_t sha_digest_len, sha_hmac_block_size;
374
375 /*
376 * Set the digest length and block size to values appropriate to the
377 * mechanism
378 */
379 switch (mechanism->cm_type) {
380 case SHA512_HMAC_MECH_INFO_TYPE:
381 sha_digest_len = SHA512_DIGEST_LENGTH;
382 sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
383 break;
384 default:
385 return (CRYPTO_MECHANISM_INVALID);
386 }
387
388 ctx->cc_provider_private =
389 kmem_alloc(sizeof (sha2_hmac_ctx_t), KM_SLEEP);
390 if (ctx->cc_provider_private == NULL)
391 return (CRYPTO_HOST_MEMORY);
392
393 PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
394 if (ctx_template != NULL) {
395 /* reuse context template */
396 memcpy(PROV_SHA2_HMAC_CTX(ctx), ctx_template,
397 sizeof (sha2_hmac_ctx_t));
398 } else {
399 /* no context template, compute context */
400 if (keylen_in_bytes > sha_hmac_block_size) {
401 uchar_t digested_key[SHA512_DIGEST_LENGTH];
402 sha2_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
403
404 /*
405 * Hash the passed-in key to get a smaller key.
406 * The inner context is used since it hasn't been
407 * initialized yet.
408 */
409 PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
410 &hmac_ctx->hc_icontext,
411 key->ck_data, keylen_in_bytes, digested_key);
412 sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
413 digested_key, sha_digest_len);
414 } else {
415 sha2_mac_init_ctx(PROV_SHA2_HMAC_CTX(ctx),
416 key->ck_data, keylen_in_bytes);
417 }
418 }
419
420 if (ret != CRYPTO_SUCCESS) {
421 memset(ctx->cc_provider_private, 0, sizeof (sha2_hmac_ctx_t));
422 kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
423 ctx->cc_provider_private = NULL;
424 }
425
426 return (ret);
427 }
428
429 static int
sha2_mac_update(crypto_ctx_t * ctx,crypto_data_t * data)430 sha2_mac_update(crypto_ctx_t *ctx, crypto_data_t *data)
431 {
432 int ret = CRYPTO_SUCCESS;
433
434 ASSERT(ctx->cc_provider_private != NULL);
435
436 /*
437 * Do a SHA2 update of the inner context using the specified
438 * data.
439 */
440 switch (data->cd_format) {
441 case CRYPTO_DATA_RAW:
442 SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_icontext,
443 (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
444 data->cd_length);
445 break;
446 case CRYPTO_DATA_UIO:
447 ret = sha2_digest_update_uio(
448 &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext, data);
449 break;
450 default:
451 ret = CRYPTO_ARGUMENTS_BAD;
452 }
453
454 return (ret);
455 }
456
457 static int
sha2_mac_final(crypto_ctx_t * ctx,crypto_data_t * mac)458 sha2_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac)
459 {
460 int ret = CRYPTO_SUCCESS;
461 uchar_t digest[SHA512_DIGEST_LENGTH];
462 uint32_t digest_len, sha_digest_len;
463
464 ASSERT(ctx->cc_provider_private != NULL);
465
466 /* Set the digest lengths to values appropriate to the mechanism */
467 switch (PROV_SHA2_HMAC_CTX(ctx)->hc_mech_type) {
468 case SHA512_HMAC_MECH_INFO_TYPE:
469 sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
470 break;
471 default:
472 return (CRYPTO_ARGUMENTS_BAD);
473 }
474
475 /*
476 * We need to just return the length needed to store the output.
477 * We should not destroy the context for the following cases.
478 */
479 if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
480 mac->cd_length = digest_len;
481 return (CRYPTO_BUFFER_TOO_SMALL);
482 }
483
484 /*
485 * Do a SHA2 final on the inner context.
486 */
487 SHA2Final(digest, &PROV_SHA2_HMAC_CTX(ctx)->hc_icontext);
488
489 /*
490 * Do a SHA2 update on the outer context, feeding the inner
491 * digest as data.
492 */
493 SHA2Update(&PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, digest,
494 sha_digest_len);
495
496 /*
497 * Do a SHA2 final on the outer context, storing the computing
498 * digest in the users buffer.
499 */
500 switch (mac->cd_format) {
501 case CRYPTO_DATA_RAW:
502 if (digest_len != sha_digest_len) {
503 /*
504 * The caller requested a short digest. Digest
505 * into a scratch buffer and return to
506 * the user only what was requested.
507 */
508 SHA2Final(digest,
509 &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
510 memcpy((unsigned char *)mac->cd_raw.iov_base +
511 mac->cd_offset, digest, digest_len);
512 } else {
513 SHA2Final((unsigned char *)mac->cd_raw.iov_base +
514 mac->cd_offset,
515 &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext);
516 }
517 break;
518 case CRYPTO_DATA_UIO:
519 ret = sha2_digest_final_uio(
520 &PROV_SHA2_HMAC_CTX(ctx)->hc_ocontext, mac,
521 digest_len, digest);
522 break;
523 default:
524 ret = CRYPTO_ARGUMENTS_BAD;
525 }
526
527 if (ret == CRYPTO_SUCCESS)
528 mac->cd_length = digest_len;
529 else
530 mac->cd_length = 0;
531
532 memset(ctx->cc_provider_private, 0, sizeof (sha2_hmac_ctx_t));
533 kmem_free(ctx->cc_provider_private, sizeof (sha2_hmac_ctx_t));
534 ctx->cc_provider_private = NULL;
535
536 return (ret);
537 }
538
539 #define SHA2_MAC_UPDATE(data, ctx, ret) { \
540 switch (data->cd_format) { \
541 case CRYPTO_DATA_RAW: \
542 SHA2Update(&(ctx).hc_icontext, \
543 (uint8_t *)data->cd_raw.iov_base + \
544 data->cd_offset, data->cd_length); \
545 break; \
546 case CRYPTO_DATA_UIO: \
547 ret = sha2_digest_update_uio(&(ctx).hc_icontext, data); \
548 break; \
549 default: \
550 ret = CRYPTO_ARGUMENTS_BAD; \
551 } \
552 }
553
554 static int
sha2_mac_atomic(crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * mac,crypto_spi_ctx_template_t ctx_template)555 sha2_mac_atomic(crypto_mechanism_t *mechanism,
556 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
557 crypto_spi_ctx_template_t ctx_template)
558 {
559 int ret = CRYPTO_SUCCESS;
560 uchar_t digest[SHA512_DIGEST_LENGTH];
561 sha2_hmac_ctx_t sha2_hmac_ctx;
562 uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
563 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
564
565 /*
566 * Set the digest length and block size to values appropriate to the
567 * mechanism
568 */
569 switch (mechanism->cm_type) {
570 case SHA512_HMAC_MECH_INFO_TYPE:
571 sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
572 sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
573 break;
574 default:
575 return (CRYPTO_MECHANISM_INVALID);
576 }
577
578 if (ctx_template != NULL) {
579 /* reuse context template */
580 memcpy(&sha2_hmac_ctx, ctx_template, sizeof (sha2_hmac_ctx_t));
581 } else {
582 sha2_hmac_ctx.hc_mech_type = mechanism->cm_type;
583 /* no context template, initialize context */
584 if (keylen_in_bytes > sha_hmac_block_size) {
585 /*
586 * Hash the passed-in key to get a smaller key.
587 * The inner context is used since it hasn't been
588 * initialized yet.
589 */
590 PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
591 &sha2_hmac_ctx.hc_icontext,
592 key->ck_data, keylen_in_bytes, digest);
593 sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
594 sha_digest_len);
595 } else {
596 sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
597 keylen_in_bytes);
598 }
599 }
600
601 /* do a SHA2 update of the inner context using the specified data */
602 SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
603 if (ret != CRYPTO_SUCCESS)
604 /* the update failed, free context and bail */
605 goto bail;
606
607 /*
608 * Do a SHA2 final on the inner context.
609 */
610 SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
611
612 /*
613 * Do an SHA2 update on the outer context, feeding the inner
614 * digest as data.
615 */
616 ASSERT3U(mechanism->cm_type, ==, SHA512_HMAC_MECH_INFO_TYPE);
617 SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
618
619 /*
620 * Do a SHA2 final on the outer context, storing the computed
621 * digest in the users buffer.
622 */
623 switch (mac->cd_format) {
624 case CRYPTO_DATA_RAW:
625 if (digest_len != sha_digest_len) {
626 /*
627 * The caller requested a short digest. Digest
628 * into a scratch buffer and return to
629 * the user only what was requested.
630 */
631 SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
632 memcpy((unsigned char *)mac->cd_raw.iov_base +
633 mac->cd_offset, digest, digest_len);
634 } else {
635 SHA2Final((unsigned char *)mac->cd_raw.iov_base +
636 mac->cd_offset, &sha2_hmac_ctx.hc_ocontext);
637 }
638 break;
639 case CRYPTO_DATA_UIO:
640 ret = sha2_digest_final_uio(&sha2_hmac_ctx.hc_ocontext, mac,
641 digest_len, digest);
642 break;
643 default:
644 ret = CRYPTO_ARGUMENTS_BAD;
645 }
646
647 if (ret == CRYPTO_SUCCESS) {
648 mac->cd_length = digest_len;
649 return (CRYPTO_SUCCESS);
650 }
651 bail:
652 memset(&sha2_hmac_ctx, 0, sizeof (sha2_hmac_ctx_t));
653 mac->cd_length = 0;
654 return (ret);
655 }
656
657 static int
sha2_mac_verify_atomic(crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * data,crypto_data_t * mac,crypto_spi_ctx_template_t ctx_template)658 sha2_mac_verify_atomic(crypto_mechanism_t *mechanism,
659 crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
660 crypto_spi_ctx_template_t ctx_template)
661 {
662 int ret = CRYPTO_SUCCESS;
663 uchar_t digest[SHA512_DIGEST_LENGTH];
664 sha2_hmac_ctx_t sha2_hmac_ctx;
665 uint32_t sha_digest_len, digest_len, sha_hmac_block_size;
666 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
667
668 /*
669 * Set the digest length and block size to values appropriate to the
670 * mechanism
671 */
672 switch (mechanism->cm_type) {
673 case SHA512_HMAC_MECH_INFO_TYPE:
674 sha_digest_len = digest_len = SHA512_DIGEST_LENGTH;
675 sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
676 break;
677 default:
678 return (CRYPTO_MECHANISM_INVALID);
679 }
680
681 if (ctx_template != NULL) {
682 /* reuse context template */
683 memcpy(&sha2_hmac_ctx, ctx_template, sizeof (sha2_hmac_ctx_t));
684 } else {
685 sha2_hmac_ctx.hc_mech_type = mechanism->cm_type;
686 /* no context template, initialize context */
687 if (keylen_in_bytes > sha_hmac_block_size) {
688 /*
689 * Hash the passed-in key to get a smaller key.
690 * The inner context is used since it hasn't been
691 * initialized yet.
692 */
693 PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
694 &sha2_hmac_ctx.hc_icontext,
695 key->ck_data, keylen_in_bytes, digest);
696 sha2_mac_init_ctx(&sha2_hmac_ctx, digest,
697 sha_digest_len);
698 } else {
699 sha2_mac_init_ctx(&sha2_hmac_ctx, key->ck_data,
700 keylen_in_bytes);
701 }
702 }
703
704 if (mac->cd_length != digest_len) {
705 ret = CRYPTO_INVALID_MAC;
706 goto bail;
707 }
708
709 /* do a SHA2 update of the inner context using the specified data */
710 SHA2_MAC_UPDATE(data, sha2_hmac_ctx, ret);
711 if (ret != CRYPTO_SUCCESS)
712 /* the update failed, free context and bail */
713 goto bail;
714
715 /* do a SHA2 final on the inner context */
716 SHA2Final(digest, &sha2_hmac_ctx.hc_icontext);
717
718 /*
719 * Do an SHA2 update on the outer context, feeding the inner
720 * digest as data.
721 */
722 ASSERT3U(mechanism->cm_type, ==, SHA512_HMAC_MECH_INFO_TYPE);
723 SHA2Update(&sha2_hmac_ctx.hc_ocontext, digest, sha_digest_len);
724
725 /*
726 * Do a SHA2 final on the outer context, storing the computed
727 * digest in the users buffer.
728 */
729 SHA2Final(digest, &sha2_hmac_ctx.hc_ocontext);
730
731 /*
732 * Compare the computed digest against the expected digest passed
733 * as argument.
734 */
735
736 switch (mac->cd_format) {
737
738 case CRYPTO_DATA_RAW:
739 if (memcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
740 mac->cd_offset, digest_len) != 0)
741 ret = CRYPTO_INVALID_MAC;
742 break;
743
744 case CRYPTO_DATA_UIO: {
745 off_t offset = mac->cd_offset;
746 uint_t vec_idx = 0;
747 off_t scratch_offset = 0;
748 size_t length = digest_len;
749 size_t cur_len;
750
751 /* we support only kernel buffer */
752 if (zfs_uio_segflg(mac->cd_uio) != UIO_SYSSPACE)
753 return (CRYPTO_ARGUMENTS_BAD);
754
755 /* jump to the first iovec containing the expected digest */
756 offset = zfs_uio_index_at_offset(mac->cd_uio, offset, &vec_idx);
757 if (vec_idx == zfs_uio_iovcnt(mac->cd_uio)) {
758 /*
759 * The caller specified an offset that is
760 * larger than the total size of the buffers
761 * it provided.
762 */
763 ret = CRYPTO_DATA_LEN_RANGE;
764 break;
765 }
766
767 /* do the comparison of computed digest vs specified one */
768 while (vec_idx < zfs_uio_iovcnt(mac->cd_uio) && length > 0) {
769 cur_len = MIN(zfs_uio_iovlen(mac->cd_uio, vec_idx) -
770 offset, length);
771
772 if (memcmp(digest + scratch_offset,
773 zfs_uio_iovbase(mac->cd_uio, vec_idx) + offset,
774 cur_len) != 0) {
775 ret = CRYPTO_INVALID_MAC;
776 break;
777 }
778
779 length -= cur_len;
780 vec_idx++;
781 scratch_offset += cur_len;
782 offset = 0;
783 }
784 break;
785 }
786
787 default:
788 ret = CRYPTO_ARGUMENTS_BAD;
789 }
790
791 return (ret);
792 bail:
793 memset(&sha2_hmac_ctx, 0, sizeof (sha2_hmac_ctx_t));
794 mac->cd_length = 0;
795 return (ret);
796 }
797
798 /*
799 * KCF software provider context management entry points.
800 */
801
802 static int
sha2_create_ctx_template(crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t * ctx_template,size_t * ctx_template_size)803 sha2_create_ctx_template(crypto_mechanism_t *mechanism, crypto_key_t *key,
804 crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size)
805 {
806 sha2_hmac_ctx_t *sha2_hmac_ctx_tmpl;
807 uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
808 uint32_t sha_digest_len, sha_hmac_block_size;
809
810 /*
811 * Set the digest length and block size to values appropriate to the
812 * mechanism
813 */
814 switch (mechanism->cm_type) {
815 case SHA512_HMAC_MECH_INFO_TYPE:
816 sha_digest_len = SHA512_DIGEST_LENGTH;
817 sha_hmac_block_size = SHA512_HMAC_BLOCK_SIZE;
818 break;
819 default:
820 return (CRYPTO_MECHANISM_INVALID);
821 }
822
823 /*
824 * Allocate and initialize SHA2 context.
825 */
826 sha2_hmac_ctx_tmpl = kmem_alloc(sizeof (sha2_hmac_ctx_t), KM_SLEEP);
827 if (sha2_hmac_ctx_tmpl == NULL)
828 return (CRYPTO_HOST_MEMORY);
829
830 sha2_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
831
832 if (keylen_in_bytes > sha_hmac_block_size) {
833 uchar_t digested_key[SHA512_DIGEST_LENGTH];
834
835 /*
836 * Hash the passed-in key to get a smaller key.
837 * The inner context is used since it hasn't been
838 * initialized yet.
839 */
840 PROV_SHA2_DIGEST_KEY(mechanism->cm_type / 3,
841 &sha2_hmac_ctx_tmpl->hc_icontext,
842 key->ck_data, keylen_in_bytes, digested_key);
843 sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, digested_key,
844 sha_digest_len);
845 } else {
846 sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, key->ck_data,
847 keylen_in_bytes);
848 }
849
850 *ctx_template = (crypto_spi_ctx_template_t)sha2_hmac_ctx_tmpl;
851 *ctx_template_size = sizeof (sha2_hmac_ctx_t);
852
853 return (CRYPTO_SUCCESS);
854 }
855
856 static int
sha2_free_context(crypto_ctx_t * ctx)857 sha2_free_context(crypto_ctx_t *ctx)
858 {
859 uint_t ctx_len;
860
861 if (ctx->cc_provider_private == NULL)
862 return (CRYPTO_SUCCESS);
863
864 ASSERT3U(PROV_SHA2_CTX(ctx)->sc_mech_type, ==,
865 SHA512_HMAC_MECH_INFO_TYPE);
866 ctx_len = sizeof (sha2_hmac_ctx_t);
867
868 memset(ctx->cc_provider_private, 0, ctx_len);
869 kmem_free(ctx->cc_provider_private, ctx_len);
870 ctx->cc_provider_private = NULL;
871
872 return (CRYPTO_SUCCESS);
873 }
874