xref: /illumos-gate/usr/src/common/crypto/modes/ccm.c (revision 74e7dc986c89efca1f2e4451c7a572e05e4a6e4f)
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 }
972