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