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