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