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 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2015 by Saso Kiselkov. All rights reserved.
24 */
25
26 #ifndef _KERNEL
27 #include <strings.h>
28 #include <limits.h>
29 #include <assert.h>
30 #include <security/cryptoki.h>
31 #endif
32
33 #include <sys/types.h>
34 #include <sys/kmem.h>
35 #define INLINE_CRYPTO_GET_PTRS
36 #include <modes/modes.h>
37 #include <sys/crypto/common.h>
38 #include <sys/crypto/impl.h>
39 #include <sys/byteorder.h>
40
41 #if defined(__i386) || defined(__amd64)
42 #define UNALIGNED_POINTERS_PERMITTED
43 #endif
44
45 /*
46 * Encrypt multiple blocks of data in CCM mode. Decrypt for CCM mode
47 * is done in another function.
48 */
49 int
50 ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
51 crypto_data_t *out, size_t block_size,
52 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
53 void (*copy_block)(const uint8_t *, uint8_t *),
54 void (*xor_block)(const uint8_t *, uint8_t *))
55 {
56 size_t remainder = length;
57 size_t need;
58 uint8_t *datap = (uint8_t *)data;
59 uint8_t *blockp;
60 uint8_t *lastp;
61 void *iov_or_mp;
62 offset_t offset;
63 uint8_t *out_data_1;
64 uint8_t *out_data_2;
65 size_t out_data_1_len;
66 uint64_t counter;
67 uint8_t *mac_buf;
68
69 if (length + ctx->ccm_remainder_len < block_size) {
70 /* accumulate bytes here and return */
71 bcopy(datap,
72 (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len,
73 length);
74 ctx->ccm_remainder_len += length;
75 ctx->ccm_copy_to = datap;
76 return (CRYPTO_SUCCESS);
77 }
78
79 lastp = (uint8_t *)ctx->ccm_cb;
80 if (out != NULL)
81 crypto_init_ptrs(out, &iov_or_mp, &offset);
82
83 mac_buf = (uint8_t *)ctx->ccm_mac_buf;
84
85 do {
86 /* Unprocessed data from last call. */
87 if (ctx->ccm_remainder_len > 0) {
88 need = block_size - ctx->ccm_remainder_len;
89
90 if (need > remainder)
91 return (CRYPTO_DATA_LEN_RANGE);
92
93 bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
94 [ctx->ccm_remainder_len], need);
95
96 blockp = (uint8_t *)ctx->ccm_remainder;
97 } else {
98 blockp = datap;
99 }
100
101 /*
102 * do CBC MAC
103 *
104 * XOR the previous cipher block current clear block.
105 * mac_buf always contain previous cipher block.
106 */
107 xor_block(blockp, mac_buf);
108 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
109
110 /* ccm_cb is the counter block */
111 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb,
112 (uint8_t *)ctx->ccm_tmp);
113
114 lastp = (uint8_t *)ctx->ccm_tmp;
115
116 /*
117 * Increment counter. Counter bits are confined
118 * to the bottom 64 bits of the counter block.
119 */
120 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
121 counter = htonll(counter + 1);
122 counter &= ctx->ccm_counter_mask;
123 ctx->ccm_cb[1] =
124 (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
125
126 /*
127 * XOR encrypted counter block with the current clear block.
128 */
129 xor_block(blockp, lastp);
130
131 ctx->ccm_processed_data_len += block_size;
132
133 if (out == NULL) {
134 if (ctx->ccm_remainder_len > 0) {
135 bcopy(blockp, ctx->ccm_copy_to,
136 ctx->ccm_remainder_len);
137 bcopy(blockp + ctx->ccm_remainder_len, datap,
138 need);
139 }
140 } else {
141 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
142 &out_data_1_len, &out_data_2, block_size);
143
144 /* copy block to where it belongs */
145 if (out_data_1_len == block_size) {
146 copy_block(lastp, out_data_1);
147 } else {
148 bcopy(lastp, out_data_1, out_data_1_len);
149 if (out_data_2 != NULL) {
150 bcopy(lastp + out_data_1_len,
151 out_data_2,
152 block_size - out_data_1_len);
153 }
154 }
155 /* update offset */
156 out->cd_offset += block_size;
157 }
158
159 /* Update pointer to next block of data to be processed. */
160 if (ctx->ccm_remainder_len != 0) {
161 datap += need;
162 ctx->ccm_remainder_len = 0;
163 } else {
164 datap += block_size;
165 }
166
167 remainder = (size_t)&data[length] - (size_t)datap;
168
169 /* Incomplete last block. */
170 if (remainder > 0 && remainder < block_size) {
171 bcopy(datap, ctx->ccm_remainder, remainder);
172 ctx->ccm_remainder_len = remainder;
173 ctx->ccm_copy_to = datap;
174 goto out;
175 }
176 ctx->ccm_copy_to = NULL;
177
178 } while (remainder > 0);
179
180 out:
181 return (CRYPTO_SUCCESS);
182 }
183
184 void
185 calculate_ccm_mac(ccm_ctx_t *ctx, uint8_t *ccm_mac,
186 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
187 {
188 uint64_t counter;
189 uint8_t *counterp, *mac_buf;
190 int i;
191
192 mac_buf = (uint8_t *)ctx->ccm_mac_buf;
193
194 /* first counter block start with index 0 */
195 counter = 0;
196 ctx->ccm_cb[1] = (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
197
198 counterp = (uint8_t *)ctx->ccm_tmp;
199 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp);
200
201 /* calculate XOR of MAC with first counter block */
202 for (i = 0; i < ctx->ccm_mac_len; i++) {
203 ccm_mac[i] = mac_buf[i] ^ counterp[i];
204 }
205 }
206
207 /* ARGSUSED */
208 int
209 ccm_encrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size,
210 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
211 void (*xor_block)(const uint8_t *, uint8_t *))
212 {
213 uint8_t *lastp, *mac_buf, *ccm_mac_p, *macp;
214 void *iov_or_mp;
215 offset_t offset;
216 uint8_t *out_data_1;
217 uint8_t *out_data_2;
218 size_t out_data_1_len;
219 int i;
220
221 if (out->cd_length < (ctx->ccm_remainder_len + ctx->ccm_mac_len)) {
222 return (CRYPTO_DATA_LEN_RANGE);
223 }
224
225 /*
226 * When we get here, the number of bytes of payload processed
227 * plus whatever data remains, if any,
228 * should be the same as the number of bytes that's being
229 * passed in the argument during init time.
230 */
231 if ((ctx->ccm_processed_data_len + ctx->ccm_remainder_len)
232 != (ctx->ccm_data_len)) {
233 return (CRYPTO_DATA_LEN_RANGE);
234 }
235
236 mac_buf = (uint8_t *)ctx->ccm_mac_buf;
237
238 if (ctx->ccm_remainder_len > 0) {
239
240 /* ccm_mac_input_buf is not used for encryption */
241 macp = (uint8_t *)ctx->ccm_mac_input_buf;
242 bzero(macp, block_size);
243
244 /* copy remainder to temporary buffer */
245 bcopy(ctx->ccm_remainder, macp, ctx->ccm_remainder_len);
246
247 /* calculate the CBC MAC */
248 xor_block(macp, mac_buf);
249 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
250
251 /* calculate the counter mode */
252 lastp = (uint8_t *)ctx->ccm_tmp;
253 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, lastp);
254
255 /* XOR with counter block */
256 for (i = 0; i < ctx->ccm_remainder_len; i++) {
257 macp[i] ^= lastp[i];
258 }
259 ctx->ccm_processed_data_len += ctx->ccm_remainder_len;
260 }
261
262 /* Calculate the CCM MAC */
263 ccm_mac_p = (uint8_t *)ctx->ccm_tmp;
264 calculate_ccm_mac(ctx, ccm_mac_p, encrypt_block);
265
266 crypto_init_ptrs(out, &iov_or_mp, &offset);
267 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
268 &out_data_1_len, &out_data_2,
269 ctx->ccm_remainder_len + ctx->ccm_mac_len);
270
271 if (ctx->ccm_remainder_len > 0) {
272
273 /* copy temporary block to where it belongs */
274 if (out_data_2 == NULL) {
275 /* everything will fit in out_data_1 */
276 bcopy(macp, out_data_1, ctx->ccm_remainder_len);
277 bcopy(ccm_mac_p, out_data_1 + ctx->ccm_remainder_len,
278 ctx->ccm_mac_len);
279 } else {
280
281 if (out_data_1_len < ctx->ccm_remainder_len) {
282
283 size_t data_2_len_used;
284
285 bcopy(macp, out_data_1, out_data_1_len);
286
287 data_2_len_used = ctx->ccm_remainder_len
288 - out_data_1_len;
289
290 bcopy((uint8_t *)macp + out_data_1_len,
291 out_data_2, data_2_len_used);
292 bcopy(ccm_mac_p, out_data_2 + data_2_len_used,
293 ctx->ccm_mac_len);
294 } else {
295 bcopy(macp, out_data_1, out_data_1_len);
296 if (out_data_1_len == ctx->ccm_remainder_len) {
297 /* mac will be in out_data_2 */
298 bcopy(ccm_mac_p, out_data_2,
299 ctx->ccm_mac_len);
300 } else {
301 size_t len_not_used = out_data_1_len -
302 ctx->ccm_remainder_len;
303 /*
304 * part of mac in will be in
305 * out_data_1, part of the mac will be
306 * in out_data_2
307 */
308 bcopy(ccm_mac_p,
309 out_data_1 + ctx->ccm_remainder_len,
310 len_not_used);
311 bcopy(ccm_mac_p + len_not_used,
312 out_data_2,
313 ctx->ccm_mac_len - len_not_used);
314
315 }
316 }
317 }
318 } else {
319 /* copy block to where it belongs */
320 bcopy(ccm_mac_p, out_data_1, out_data_1_len);
321 if (out_data_2 != NULL) {
322 bcopy(ccm_mac_p + out_data_1_len, out_data_2,
323 block_size - out_data_1_len);
324 }
325 }
326 out->cd_offset += ctx->ccm_remainder_len + ctx->ccm_mac_len;
327 ctx->ccm_remainder_len = 0;
328 return (CRYPTO_SUCCESS);
329 }
330
331 /*
332 * This will only deal with decrypting the last block of the input that
333 * might not be a multiple of block length.
334 */
335 void
336 ccm_decrypt_incomplete_block(ccm_ctx_t *ctx,
337 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
338 {
339 uint8_t *datap, *outp, *counterp;
340 int i;
341
342 datap = (uint8_t *)ctx->ccm_remainder;
343 outp = &((ctx->ccm_pt_buf)[ctx->ccm_processed_data_len]);
344
345 counterp = (uint8_t *)ctx->ccm_tmp;
346 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, counterp);
347
348 /* XOR with counter block */
349 for (i = 0; i < ctx->ccm_remainder_len; i++) {
350 outp[i] = datap[i] ^ counterp[i];
351 }
352 }
353
354 /*
355 * This will decrypt the cipher text. However, the plaintext won't be
356 * returned to the caller. It will be returned when decrypt_final() is
357 * called if the MAC matches
358 */
359 /* ARGSUSED */
360 int
361 ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
362 crypto_data_t *out, size_t block_size,
363 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
364 void (*copy_block)(const uint8_t *, uint8_t *),
365 void (*xor_block)(const uint8_t *, uint8_t *))
366 {
367 size_t remainder = length;
368 size_t need;
369 uint8_t *datap = (uint8_t *)data;
370 uint8_t *blockp;
371 uint8_t *cbp;
372 uint64_t counter;
373 size_t pt_len, total_decrypted_len, mac_len, pm_len, pd_len;
374 uint8_t *resultp;
375
376
377 pm_len = ctx->ccm_processed_mac_len;
378
379 if (pm_len > 0) {
380 uint8_t *tmp;
381 /*
382 * all ciphertext has been processed, just waiting for
383 * part of the value of the mac
384 */
385 if ((pm_len + length) > ctx->ccm_mac_len) {
386 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
387 }
388 tmp = (uint8_t *)ctx->ccm_mac_input_buf;
389
390 bcopy(datap, tmp + pm_len, length);
391
392 ctx->ccm_processed_mac_len += length;
393 return (CRYPTO_SUCCESS);
394 }
395
396 /*
397 * If we decrypt the given data, what total amount of data would
398 * have been decrypted?
399 */
400 pd_len = ctx->ccm_processed_data_len;
401 total_decrypted_len = pd_len + length + ctx->ccm_remainder_len;
402
403 if (total_decrypted_len >
404 (ctx->ccm_data_len + ctx->ccm_mac_len)) {
405 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
406 }
407
408 pt_len = ctx->ccm_data_len;
409
410 if (total_decrypted_len > pt_len) {
411 /*
412 * part of the input will be the MAC, need to isolate that
413 * to be dealt with later. The left-over data in
414 * ccm_remainder_len from last time will not be part of the
415 * MAC. Otherwise, it would have already been taken out
416 * when this call is made last time.
417 */
418 size_t pt_part = pt_len - pd_len - ctx->ccm_remainder_len;
419
420 mac_len = length - pt_part;
421
422 ctx->ccm_processed_mac_len = mac_len;
423 bcopy(data + pt_part, ctx->ccm_mac_input_buf, mac_len);
424
425 if (pt_part + ctx->ccm_remainder_len < block_size) {
426 /*
427 * since this is last of the ciphertext, will
428 * just decrypt with it here
429 */
430 bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
431 [ctx->ccm_remainder_len], pt_part);
432 ctx->ccm_remainder_len += pt_part;
433 ccm_decrypt_incomplete_block(ctx, encrypt_block);
434 ctx->ccm_processed_data_len += ctx->ccm_remainder_len;
435 ctx->ccm_remainder_len = 0;
436 return (CRYPTO_SUCCESS);
437 } else {
438 /* let rest of the code handle this */
439 length = pt_part;
440 }
441 } else if (length + ctx->ccm_remainder_len < block_size) {
442 /* accumulate bytes here and return */
443 bcopy(datap,
444 (uint8_t *)ctx->ccm_remainder + ctx->ccm_remainder_len,
445 length);
446 ctx->ccm_remainder_len += length;
447 ctx->ccm_copy_to = datap;
448 return (CRYPTO_SUCCESS);
449 }
450
451 do {
452 /* Unprocessed data from last call. */
453 if (ctx->ccm_remainder_len > 0) {
454 need = block_size - ctx->ccm_remainder_len;
455
456 if (need > remainder)
457 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
458
459 bcopy(datap, &((uint8_t *)ctx->ccm_remainder)
460 [ctx->ccm_remainder_len], need);
461
462 blockp = (uint8_t *)ctx->ccm_remainder;
463 } else {
464 blockp = datap;
465 }
466
467 /* Calculate the counter mode, ccm_cb is the counter block */
468 cbp = (uint8_t *)ctx->ccm_tmp;
469 encrypt_block(ctx->ccm_keysched, (uint8_t *)ctx->ccm_cb, cbp);
470
471 /*
472 * Increment counter.
473 * Counter bits are confined to the bottom 64 bits
474 */
475 counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
476 counter = htonll(counter + 1);
477 counter &= ctx->ccm_counter_mask;
478 ctx->ccm_cb[1] =
479 (ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
480
481 /* XOR with the ciphertext */
482 xor_block(blockp, cbp);
483
484 /* Copy the plaintext to the "holding buffer" */
485 resultp = (uint8_t *)ctx->ccm_pt_buf +
486 ctx->ccm_processed_data_len;
487 copy_block(cbp, resultp);
488
489 ctx->ccm_processed_data_len += block_size;
490
491 ctx->ccm_lastp = blockp;
492
493 /* Update pointer to next block of data to be processed. */
494 if (ctx->ccm_remainder_len != 0) {
495 datap += need;
496 ctx->ccm_remainder_len = 0;
497 } else {
498 datap += block_size;
499 }
500
501 remainder = (size_t)&data[length] - (size_t)datap;
502
503 /* Incomplete last block */
504 if (remainder > 0 && remainder < block_size) {
505 bcopy(datap, ctx->ccm_remainder, remainder);
506 ctx->ccm_remainder_len = remainder;
507 ctx->ccm_copy_to = datap;
508 if (ctx->ccm_processed_mac_len > 0) {
509 /*
510 * not expecting anymore ciphertext, just
511 * compute plaintext for the remaining input
512 */
513 ccm_decrypt_incomplete_block(ctx,
514 encrypt_block);
515 ctx->ccm_processed_data_len += remainder;
516 ctx->ccm_remainder_len = 0;
517 }
518 goto out;
519 }
520 ctx->ccm_copy_to = NULL;
521
522 } while (remainder > 0);
523
524 out:
525 return (CRYPTO_SUCCESS);
526 }
527
528 int
529 ccm_decrypt_final(ccm_ctx_t *ctx, crypto_data_t *out, size_t block_size,
530 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
531 void (*copy_block)(const uint8_t *, uint8_t *),
532 void (*xor_block)(const uint8_t *, uint8_t *))
533 {
534 size_t mac_remain, pt_len;
535 uint8_t *pt, *mac_buf, *macp, *ccm_mac_p;
536 int rv;
537
538 pt_len = ctx->ccm_data_len;
539
540 /* Make sure output buffer can fit all of the plaintext */
541 if (out->cd_length < pt_len) {
542 return (CRYPTO_DATA_LEN_RANGE);
543 }
544
545 pt = ctx->ccm_pt_buf;
546 mac_remain = ctx->ccm_processed_data_len;
547 mac_buf = (uint8_t *)ctx->ccm_mac_buf;
548
549 macp = (uint8_t *)ctx->ccm_tmp;
550
551 while (mac_remain > 0) {
552
553 if (mac_remain < block_size) {
554 bzero(macp, block_size);
555 bcopy(pt, macp, mac_remain);
556 mac_remain = 0;
557 } else {
558 copy_block(pt, macp);
559 mac_remain -= block_size;
560 pt += block_size;
561 }
562
563 /* calculate the CBC MAC */
564 xor_block(macp, mac_buf);
565 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
566 }
567
568 /* Calculate the CCM MAC */
569 ccm_mac_p = (uint8_t *)ctx->ccm_tmp;
570 calculate_ccm_mac((ccm_ctx_t *)ctx, ccm_mac_p, encrypt_block);
571
572 /* compare the input CCM MAC value with what we calculated */
573 if (bcmp(ctx->ccm_mac_input_buf, ccm_mac_p, ctx->ccm_mac_len)) {
574 /* They don't match */
575 return (CRYPTO_INVALID_MAC);
576 } else {
577 rv = crypto_put_output_data(ctx->ccm_pt_buf, out, pt_len);
578 if (rv != CRYPTO_SUCCESS)
579 return (rv);
580 out->cd_offset += pt_len;
581 }
582 return (CRYPTO_SUCCESS);
583 }
584
585 int
586 ccm_validate_args(CK_AES_CCM_PARAMS *ccm_param, boolean_t is_encrypt_init)
587 {
588 size_t macSize, nonceSize;
589 uint8_t q;
590 uint64_t maxValue;
591
592 /*
593 * Check the length of the MAC. The only valid
594 * lengths for the MAC are: 4, 6, 8, 10, 12, 14, 16
595 */
596 macSize = ccm_param->ulMACSize;
597 if ((macSize < 4) || (macSize > 16) || ((macSize % 2) != 0)) {
598 return (CRYPTO_MECHANISM_PARAM_INVALID);
599 }
600
601 /* Check the nonce length. Valid values are 7, 8, 9, 10, 11, 12, 13 */
602 nonceSize = ccm_param->ulNonceSize;
603 if ((nonceSize < 7) || (nonceSize > 13)) {
604 return (CRYPTO_MECHANISM_PARAM_INVALID);
605 }
606
607 /* q is the length of the field storing the length, in bytes */
608 q = (uint8_t)((15 - nonceSize) & 0xFF);
609
610
611 /*
612 * If it is decrypt, need to make sure size of ciphertext is at least
613 * bigger than MAC len
614 */
615 if ((!is_encrypt_init) && (ccm_param->ulDataSize < macSize)) {
616 return (CRYPTO_MECHANISM_PARAM_INVALID);
617 }
618
619 /*
620 * Check to make sure the length of the payload is within the
621 * range of values allowed by q
622 */
623 if (q < 8) {
624 maxValue = (1ULL << (q * 8)) - 1;
625 } else {
626 maxValue = ULONG_MAX;
627 }
628
629 if (ccm_param->ulDataSize > maxValue) {
630 return (CRYPTO_MECHANISM_PARAM_INVALID);
631 }
632 return (CRYPTO_SUCCESS);
633 }
634
635 /*
636 * Format the first block used in CBC-MAC (B0) and the initial counter
637 * block based on formatting functions and counter generation functions
638 * specified in RFC 3610 and NIST publication 800-38C, appendix A
639 *
640 * b0 is the first block used in CBC-MAC
641 * cb0 is the first counter block
642 *
643 * It's assumed that the arguments b0 and cb0 are preallocated AES blocks
644 *
645 */
646 static void
647 ccm_format_initial_blocks(uchar_t *nonce, ulong_t nonceSize,
648 ulong_t authDataSize, uint8_t *b0, ccm_ctx_t *aes_ctx)
649 {
650 uint64_t payloadSize;
651 uint8_t t, q, have_adata = 0;
652 size_t limit;
653 int i, j, k;
654 uint64_t mask = 0;
655 uint8_t *cb;
656
657 q = (uint8_t)((15 - nonceSize) & 0xFF);
658 t = (uint8_t)((aes_ctx->ccm_mac_len) & 0xFF);
659
660 /* Construct the first octet of b0 */
661 if (authDataSize > 0) {
662 have_adata = 1;
663 }
664 b0[0] = (have_adata << 6) | (((t - 2) / 2) << 3) | (q - 1);
665
666 /* copy the nonce value into b0 */
667 bcopy(nonce, &(b0[1]), nonceSize);
668
669 /* store the length of the payload into b0 */
670 bzero(&(b0[1+nonceSize]), q);
671
672 payloadSize = aes_ctx->ccm_data_len;
673 limit = 8 < q ? 8 : q;
674
675 for (i = 0, j = 0, k = 15; i < limit; i++, j += 8, k--) {
676 b0[k] = (uint8_t)((payloadSize >> j) & 0xFF);
677 }
678
679 /* format the counter block */
680
681 cb = (uint8_t *)aes_ctx->ccm_cb;
682
683 cb[0] = 0x07 & (q-1); /* first byte */
684
685 /* copy the nonce value into the counter block */
686 bcopy(nonce, &(cb[1]), nonceSize);
687
688 bzero(&(cb[1+nonceSize]), q);
689
690 /* Create the mask for the counter field based on the size of nonce */
691 q <<= 3;
692 while (q-- > 0) {
693 mask |= (1ULL << q);
694 }
695
696 aes_ctx->ccm_counter_mask = htonll(mask);
697
698 /*
699 * During calculation, we start using counter block 1, we will
700 * set it up right here.
701 * We can just set the last byte to have the value 1, because
702 * even with the biggest nonce of 13, the last byte of the
703 * counter block will be used for the counter value.
704 */
705 cb[15] = 0x01;
706 }
707
708 /*
709 * Encode the length of the associated data as
710 * specified in RFC 3610 and NIST publication 800-38C, appendix A
711 */
712 static void
713 encode_adata_len(ulong_t auth_data_len, uint8_t *encoded, size_t *encoded_len)
714 {
715 #ifdef UNALIGNED_POINTERS_PERMITTED
716 uint32_t *lencoded_ptr;
717 #ifdef _LP64
718 uint64_t *llencoded_ptr;
719 #endif
720 #endif /* UNALIGNED_POINTERS_PERMITTED */
721
722 if (auth_data_len < ((1ULL<<16) - (1ULL<<8))) {
723 /* 0 < a < (2^16-2^8) */
724 *encoded_len = 2;
725 encoded[0] = (auth_data_len & 0xff00) >> 8;
726 encoded[1] = auth_data_len & 0xff;
727
728 } else if ((auth_data_len >= ((1ULL<<16) - (1ULL<<8))) &&
729 (auth_data_len < (1ULL << 31))) {
730 /* (2^16-2^8) <= a < 2^32 */
731 *encoded_len = 6;
732 encoded[0] = 0xff;
733 encoded[1] = 0xfe;
734 #ifdef UNALIGNED_POINTERS_PERMITTED
735 lencoded_ptr = (uint32_t *)(void *)&encoded[2];
736 *lencoded_ptr = htonl(auth_data_len);
737 #else
738 encoded[2] = (auth_data_len & 0xff000000) >> 24;
739 encoded[3] = (auth_data_len & 0xff0000) >> 16;
740 encoded[4] = (auth_data_len & 0xff00) >> 8;
741 encoded[5] = auth_data_len & 0xff;
742 #endif /* UNALIGNED_POINTERS_PERMITTED */
743
744 #ifdef _LP64
745 } else {
746 /* 2^32 <= a < 2^64 */
747 *encoded_len = 10;
748 encoded[0] = 0xff;
749 encoded[1] = 0xff;
750 #ifdef UNALIGNED_POINTERS_PERMITTED
751 llencoded_ptr = (uint64_t *)(void *)&encoded[2];
752 *llencoded_ptr = htonl(auth_data_len);
753 #else
754 encoded[2] = (auth_data_len & 0xff00000000000000) >> 56;
755 encoded[3] = (auth_data_len & 0xff000000000000) >> 48;
756 encoded[4] = (auth_data_len & 0xff0000000000) >> 40;
757 encoded[5] = (auth_data_len & 0xff00000000) >> 32;
758 encoded[6] = (auth_data_len & 0xff000000) >> 24;
759 encoded[7] = (auth_data_len & 0xff0000) >> 16;
760 encoded[8] = (auth_data_len & 0xff00) >> 8;
761 encoded[9] = auth_data_len & 0xff;
762 #endif /* UNALIGNED_POINTERS_PERMITTED */
763 #endif /* _LP64 */
764 }
765 }
766
767 /*
768 * The following function should be call at encrypt or decrypt init time
769 * for AES CCM mode.
770 */
771 int
772 ccm_init(ccm_ctx_t *ctx, unsigned char *nonce, size_t nonce_len,
773 unsigned char *auth_data, size_t auth_data_len, size_t block_size,
774 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
775 void (*xor_block)(const uint8_t *, uint8_t *))
776 {
777 uint8_t *mac_buf, *datap, *ivp, *authp;
778 size_t remainder, processed;
779 uint8_t encoded_a[10]; /* max encoded auth data length is 10 octets */
780 size_t encoded_a_len = 0;
781
782 mac_buf = (uint8_t *)&(ctx->ccm_mac_buf);
783
784 /*
785 * Format the 1st block for CBC-MAC and construct the
786 * 1st counter block.
787 *
788 * aes_ctx->ccm_iv is used for storing the counter block
789 * mac_buf will store b0 at this time.
790 */
791 ccm_format_initial_blocks(nonce, nonce_len,
792 auth_data_len, mac_buf, ctx);
793
794 /* The IV for CBC MAC for AES CCM mode is always zero */
795 ivp = (uint8_t *)ctx->ccm_tmp;
796 bzero(ivp, block_size);
797
798 xor_block(ivp, mac_buf);
799
800 /* encrypt the nonce */
801 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
802
803 /* take care of the associated data, if any */
804 if (auth_data_len == 0) {
805 return (CRYPTO_SUCCESS);
806 }
807
808 encode_adata_len(auth_data_len, encoded_a, &encoded_a_len);
809
810 remainder = auth_data_len;
811
812 /* 1st block: it contains encoded associated data, and some data */
813 authp = (uint8_t *)ctx->ccm_tmp;
814 bzero(authp, block_size);
815 bcopy(encoded_a, authp, encoded_a_len);
816 processed = block_size - encoded_a_len;
817 if (processed > auth_data_len) {
818 /* in case auth_data is very small */
819 processed = auth_data_len;
820 }
821 bcopy(auth_data, authp+encoded_a_len, processed);
822 /* xor with previous buffer */
823 xor_block(authp, mac_buf);
824 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
825 remainder -= processed;
826 if (remainder == 0) {
827 /* a small amount of associated data, it's all done now */
828 return (CRYPTO_SUCCESS);
829 }
830
831 do {
832 if (remainder < block_size) {
833 /*
834 * There's not a block full of data, pad rest of
835 * buffer with zero
836 */
837 bzero(authp, block_size);
838 bcopy(&(auth_data[processed]), authp, remainder);
839 datap = (uint8_t *)authp;
840 remainder = 0;
841 } else {
842 datap = (uint8_t *)(&(auth_data[processed]));
843 processed += block_size;
844 remainder -= block_size;
845 }
846
847 xor_block(datap, mac_buf);
848 encrypt_block(ctx->ccm_keysched, mac_buf, mac_buf);
849
850 } while (remainder > 0);
851
852 return (CRYPTO_SUCCESS);
853 }
854
855 int
856 ccm_init_ctx(ccm_ctx_t *ccm_ctx, char *param, int kmflag,
857 boolean_t is_encrypt_init, size_t block_size,
858 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *),
859 void (*xor_block)(const uint8_t *, uint8_t *))
860 {
861 int rv;
862 CK_AES_CCM_PARAMS *ccm_param;
863
864 if (param != NULL) {
865 ccm_param = (CK_AES_CCM_PARAMS *)(void *)param;
866
867 if ((rv = ccm_validate_args(ccm_param,
868 is_encrypt_init)) != 0) {
869 return (rv);
870 }
871
872 ccm_ctx->ccm_mac_len = ccm_param->ulMACSize;
873 if (is_encrypt_init) {
874 ccm_ctx->ccm_data_len = ccm_param->ulDataSize;
875 } else {
876 ccm_ctx->ccm_data_len =
877 ccm_param->ulDataSize - ccm_ctx->ccm_mac_len;
878 ccm_ctx->ccm_processed_mac_len = 0;
879 }
880 ccm_ctx->ccm_processed_data_len = 0;
881
882 ccm_ctx->ccm_flags |= CCM_MODE;
883 } else {
884 rv = CRYPTO_MECHANISM_PARAM_INVALID;
885 goto out;
886 }
887
888 if (ccm_init(ccm_ctx, ccm_param->nonce, ccm_param->ulNonceSize,
889 ccm_param->authData, ccm_param->ulAuthDataSize, block_size,
890 encrypt_block, xor_block) != 0) {
891 rv = CRYPTO_MECHANISM_PARAM_INVALID;
892 goto out;
893 }
894 if (!is_encrypt_init) {
895 /* allocate buffer for storing decrypted plaintext */
896 #ifdef _KERNEL
897 ccm_ctx->ccm_pt_buf = kmem_alloc(ccm_ctx->ccm_data_len,
898 kmflag);
899 #else
900 ccm_ctx->ccm_pt_buf = malloc(ccm_ctx->ccm_data_len);
901 #endif
902 if (ccm_ctx->ccm_pt_buf == NULL) {
903 rv = CRYPTO_HOST_MEMORY;
904 }
905 }
906 out:
907 return (rv);
908 }
909
910 void *
911 ccm_alloc_ctx(int kmflag)
912 {
913 ccm_ctx_t *ccm_ctx;
914
915 #ifdef _KERNEL
916 if ((ccm_ctx = kmem_zalloc(sizeof (ccm_ctx_t), kmflag)) == NULL)
917 #else
918 if ((ccm_ctx = calloc(1, sizeof (ccm_ctx_t))) == NULL)
919 #endif
920 return (NULL);
921
922 ccm_ctx->ccm_flags = CCM_MODE;
923 return (ccm_ctx);
924 }