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