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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/types.h>
26 #include <sys/param.h>
27 #include <sys/cmn_err.h>
28 #include <sys/errno.h>
29 #include <sys/kmem.h>
30 #include <sys/systm.h>
31 #include <sys/crypto/common.h>
32 #include <modes/modes.h>
33 #define _AES_FIPS_POST
34 #include <fips/fips_test_vectors.h>
35 #ifndef _KERNEL
36 #include <stdlib.h>
37 #include <string.h>
38 #include <strings.h>
39 #include <stdio.h>
40 #include <security/cryptoki.h>
41 #include <cryptoutil.h>
42 #include "softCrypt.h"
43 #else
44 #define _AES_IMPL
45 #include <aes/aes_impl.h>
46 #endif
47
48
49 #ifdef _KERNEL
50 void *
aes_cbc_ctx_init(void * key_sched,size_t size,uint8_t * ivec)51 aes_cbc_ctx_init(void *key_sched, size_t size, uint8_t *ivec)
52 {
53
54 cbc_ctx_t *cbc_ctx;
55
56 if ((cbc_ctx = kmem_zalloc(sizeof (cbc_ctx_t), KM_SLEEP)) == NULL)
57 return (NULL);
58
59 cbc_ctx->cbc_keysched = key_sched;
60 cbc_ctx->cbc_keysched_len = size;
61
62 (void) memcpy(&cbc_ctx->cbc_iv[0], ivec, AES_BLOCK_LEN);
63
64 cbc_ctx->cbc_lastp = (uint8_t *)cbc_ctx->cbc_iv;
65 cbc_ctx->cbc_flags |= CBC_MODE;
66
67 return (cbc_ctx);
68 }
69
70 /*
71 * Allocate and initialize a context for AES CTR mode of operation.
72 */
73 void *
aes_ctr_ctx_init(void * key_sched,size_t size,uint8_t * param)74 aes_ctr_ctx_init(void *key_sched, size_t size, uint8_t *param)
75 {
76
77 ctr_ctx_t *ctr_ctx;
78 CK_AES_CTR_PARAMS *pp;
79
80 /* LINTED: pointer alignment */
81 pp = (CK_AES_CTR_PARAMS *)param;
82
83 if ((ctr_ctx = kmem_zalloc(sizeof (ctr_ctx_t), KM_SLEEP)) == NULL)
84 return (NULL);
85
86 ctr_ctx->ctr_keysched = key_sched;
87 ctr_ctx->ctr_keysched_len = size;
88
89 if (ctr_init_ctx(ctr_ctx, pp->ulCounterBits, pp->cb,
90 aes_copy_block) != CRYPTO_SUCCESS) {
91 kmem_free(ctr_ctx, sizeof (ctr_ctx_t));
92 return (NULL);
93 }
94 ctr_ctx->ctr_flags |= CTR_MODE;
95
96 return (ctr_ctx);
97 }
98
99 /*
100 * Allocate and initialize a context for AES CCM mode of operation.
101 */
102 void *
aes_ccm_ctx_init(void * key_sched,size_t size,uint8_t * param,boolean_t is_encrypt_init)103 aes_ccm_ctx_init(void *key_sched, size_t size, uint8_t *param,
104 boolean_t is_encrypt_init)
105 {
106
107 ccm_ctx_t *ccm_ctx;
108
109 if ((ccm_ctx = kmem_zalloc(sizeof (ccm_ctx_t), KM_SLEEP)) == NULL)
110 return (NULL);
111
112 ccm_ctx->ccm_keysched = key_sched;
113 ccm_ctx->ccm_keysched_len = size;
114
115 if (ccm_init_ctx(ccm_ctx, (char *)param, KM_SLEEP,
116 is_encrypt_init, AES_BLOCK_LEN, aes_encrypt_block,
117 aes_xor_block) != CRYPTO_SUCCESS) {
118 kmem_free(ccm_ctx, sizeof (ccm_ctx_t));
119 return (NULL);
120 }
121 ccm_ctx->ccm_flags |= CCM_MODE;
122
123 return (ccm_ctx);
124 }
125
126 /*
127 * Allocate and initialize a context for AES CCM mode of operation.
128 */
129 void *
aes_gcm_ctx_init(void * key_sched,size_t size,uint8_t * param)130 aes_gcm_ctx_init(void *key_sched, size_t size, uint8_t *param)
131 {
132
133 gcm_ctx_t *gcm_ctx;
134
135 if ((gcm_ctx = kmem_zalloc(sizeof (gcm_ctx_t), KM_SLEEP)) == NULL)
136 return (NULL);
137
138 gcm_ctx->gcm_keysched = key_sched;
139 gcm_ctx->gcm_keysched_len = size;
140
141 if (gcm_init_ctx(gcm_ctx, (char *)param, AES_BLOCK_LEN,
142 aes_encrypt_block, aes_copy_block,
143 aes_xor_block) != CRYPTO_SUCCESS) {
144 kmem_free(gcm_ctx, sizeof (gcm_ctx_t));
145 return (NULL);
146 }
147 gcm_ctx->gcm_flags |= GCM_MODE;
148
149 return (gcm_ctx);
150 }
151
152 void *
aes_gmac_ctx_init(void * key_sched,size_t size,uint8_t * param)153 aes_gmac_ctx_init(void *key_sched, size_t size, uint8_t *param)
154 {
155
156 gcm_ctx_t *gcm_ctx;
157
158 if ((gcm_ctx = kmem_zalloc(sizeof (gcm_ctx_t), KM_SLEEP)) == NULL)
159 return (NULL);
160
161 gcm_ctx->gcm_keysched = key_sched;
162 gcm_ctx->gcm_keysched_len = size;
163
164 if (gmac_init_ctx(gcm_ctx, (char *)param, AES_BLOCK_LEN,
165 aes_encrypt_block, aes_copy_block,
166 aes_xor_block) != CRYPTO_SUCCESS) {
167 kmem_free(gcm_ctx, sizeof (gcm_ctx_t));
168 return (NULL);
169 }
170 gcm_ctx->gcm_flags |= GMAC_MODE;
171
172 return (gcm_ctx);
173 }
174 #endif
175
176
177 /*
178 * Allocate context for the active encryption or decryption operation, and
179 * generate AES key schedule to speed up the operation.
180 */
181 soft_aes_ctx_t *
182 #ifdef _KERNEL
fips_aes_build_context(uint8_t * key,int key_len,uint8_t * iv,aes_mech_type_t mechanism,boolean_t is_encrypt_init)183 fips_aes_build_context(uint8_t *key, int key_len, uint8_t *iv,
184 aes_mech_type_t mechanism, boolean_t is_encrypt_init)
185 #else
186 fips_aes_build_context(uint8_t *key, int key_len, uint8_t *iv,
187 CK_MECHANISM_TYPE mechanism)
188 #endif
189 {
190 size_t size;
191 soft_aes_ctx_t *soft_aes_ctx;
192 CK_AES_CTR_PARAMS pp;
193
194 #ifdef _KERNEL
195 if ((soft_aes_ctx = kmem_zalloc(sizeof (soft_aes_ctx_t),
196 KM_SLEEP)) == NULL)
197 #else
198 if ((soft_aes_ctx = calloc(1, sizeof (soft_aes_ctx_t)))
199 == NULL)
200 #endif
201 return (NULL);
202
203
204 soft_aes_ctx->key_sched = aes_alloc_keysched(&size, 0);
205
206 if (soft_aes_ctx->key_sched == NULL) {
207 #ifdef _KERNEL
208 kmem_free(soft_aes_ctx, sizeof (soft_aes_ctx_t));
209 #else
210 free(soft_aes_ctx);
211 #endif
212 return (NULL);
213 }
214
215 soft_aes_ctx->keysched_len = size;
216
217 #ifdef __sparcv9
218 aes_init_keysched(key, (uint_t)(key_len * 8),
219 soft_aes_ctx->key_sched);
220 #else /* !__sparcv9 */
221 aes_init_keysched(key, (key_len * 8),
222 soft_aes_ctx->key_sched);
223 #endif /* __sparcv9 */
224
225 switch (mechanism) {
226
227 case CKM_AES_CBC:
228
229 /* Save Initialization Vector (IV) in the context. */
230 (void) memcpy(soft_aes_ctx->ivec, iv, AES_BLOCK_LEN);
231 /* Allocate a context for AES cipher-block chaining. */
232 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
233 soft_aes_ctx->key_sched,
234 soft_aes_ctx->keysched_len,
235 soft_aes_ctx->ivec);
236 break;
237
238 case CKM_AES_CTR:
239
240 pp.ulCounterBits = 16;
241 (void) memcpy(pp.cb, iv, AES_BLOCK_LEN);
242 soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
243 soft_aes_ctx->key_sched,
244 soft_aes_ctx->keysched_len,
245 (uint8_t *)&pp);
246 break;
247
248 #ifdef _KERNEL
249 case AES_CCM_MECH_INFO_TYPE:
250 soft_aes_ctx->aes_cbc = aes_ccm_ctx_init(
251 soft_aes_ctx->key_sched,
252 soft_aes_ctx->keysched_len, iv,
253 is_encrypt_init);
254 break;
255
256 case AES_GCM_MECH_INFO_TYPE:
257 soft_aes_ctx->aes_cbc = aes_gcm_ctx_init(
258 soft_aes_ctx->key_sched,
259 soft_aes_ctx->keysched_len, iv);
260 break;
261
262 case AES_GMAC_MECH_INFO_TYPE:
263 soft_aes_ctx->aes_cbc = aes_gmac_ctx_init(
264 soft_aes_ctx->key_sched,
265 soft_aes_ctx->keysched_len, iv);
266 break;
267 #endif
268 default:
269 return (soft_aes_ctx);
270 }
271
272 if (soft_aes_ctx->aes_cbc == NULL) {
273 bzero(soft_aes_ctx->key_sched,
274 soft_aes_ctx->keysched_len);
275 #ifdef _KERNEL
276 kmem_free(soft_aes_ctx->key_sched, size);
277 #else
278 free(soft_aes_ctx->key_sched);
279 #endif
280 return (NULL);
281 }
282
283 return (soft_aes_ctx);
284 }
285
286 #ifdef _KERNEL
287 void
fips_aes_free_context(soft_aes_ctx_t * soft_aes_ctx)288 fips_aes_free_context(soft_aes_ctx_t *soft_aes_ctx)
289 {
290
291 common_ctx_t *aes_ctx;
292
293 aes_ctx = (common_ctx_t *)soft_aes_ctx->aes_cbc;
294
295 if (aes_ctx != NULL) {
296 bzero(aes_ctx->cc_keysched, aes_ctx->cc_keysched_len);
297 kmem_free(aes_ctx->cc_keysched,
298 aes_ctx->cc_keysched_len);
299 crypto_free_mode_ctx(aes_ctx);
300 } else {
301 /* ECB MODE */
302 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
303 kmem_free(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
304 }
305
306 kmem_free(soft_aes_ctx, sizeof (soft_aes_ctx_t));
307
308 }
309
310 #else
311 void
fips_aes_free_context(soft_aes_ctx_t * soft_aes_ctx)312 fips_aes_free_context(soft_aes_ctx_t *soft_aes_ctx)
313 {
314
315 common_ctx_t *aes_ctx;
316
317 aes_ctx = (common_ctx_t *)soft_aes_ctx->aes_cbc;
318
319 if (aes_ctx != NULL) {
320 bzero(aes_ctx->cc_keysched, aes_ctx->cc_keysched_len);
321 free(aes_ctx->cc_keysched);
322 free(soft_aes_ctx->aes_cbc);
323 } else {
324 /* ECB MODE */
325 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
326 free(soft_aes_ctx->key_sched);
327 }
328
329 free(soft_aes_ctx);
330
331 }
332 #endif
333
334 /*
335 * fips_aes_encrypt()
336 *
337 * Arguments:
338 * soft_aes_ctx: pointer to AES context
339 * in_buf: pointer to the input data to be encrypted
340 * ulDataLen: length of the input data
341 * out_buf: pointer to the output data after encryption
342 * pulEncryptedLen: pointer to the length of the output data
343 * mechanism: CKM_AES_ECB or CKM_AES_CBC
344 *
345 * Description:
346 * This function calls the corresponding low-level encrypt
347 * routine based on the mechanism.
348 *
349 */
350 #ifdef _KERNEL
351 int
fips_aes_encrypt(soft_aes_ctx_t * soft_aes_ctx,uchar_t * in_buf,ulong_t ulDataLen,uchar_t * out_buf,ulong_t * pulEncryptedLen,aes_mech_type_t mechanism)352 fips_aes_encrypt(soft_aes_ctx_t *soft_aes_ctx, uchar_t *in_buf,
353 ulong_t ulDataLen, uchar_t *out_buf,
354 ulong_t *pulEncryptedLen, aes_mech_type_t mechanism)
355 #else
356 CK_RV
357 fips_aes_encrypt(soft_aes_ctx_t *soft_aes_ctx, CK_BYTE_PTR in_buf,
358 CK_ULONG ulDataLen, CK_BYTE_PTR out_buf,
359 CK_ULONG_PTR pulEncryptedLen, CK_MECHANISM_TYPE mechanism)
360 #endif
361 {
362
363 int rc = 0;
364 CK_RV rv = CKR_OK;
365 ulong_t out_len;
366
367 /*
368 * AES only takes input length that is a multiple of 16-byte
369 */
370 if ((ulDataLen % AES_BLOCK_LEN) != 0)
371 return (CKR_DATA_LEN_RANGE);
372
373 /*
374 * For non-padding mode, the output length will
375 * be same as the input length.
376 */
377 out_len = ulDataLen;
378
379 /*
380 * Begin Encryption now.
381 */
382 switch (mechanism) {
383
384 case CKM_AES_ECB:
385 {
386
387 ulong_t i;
388 uint8_t *tmp_inbuf;
389 uint8_t *tmp_outbuf;
390
391 for (i = 0; i < out_len; i += AES_BLOCK_LEN) {
392 tmp_inbuf = &in_buf[i];
393 tmp_outbuf = &out_buf[i];
394 /* Crunch one block of data for AES. */
395 (void) aes_encrypt_block(soft_aes_ctx->key_sched,
396 tmp_inbuf, tmp_outbuf);
397 }
398
399 *pulEncryptedLen = out_len;
400
401 break;
402 }
403
404 case CKM_AES_CBC:
405 {
406 crypto_data_t out;
407
408 out.cd_format = CRYPTO_DATA_RAW;
409 out.cd_offset = 0;
410 out.cd_length = out_len;
411 out.cd_raw.iov_base = (char *)out_buf;
412 out.cd_raw.iov_len = out_len;
413
414 /* Encrypt multiple blocks of data. */
415 rc = aes_encrypt_contiguous_blocks(
416 (aes_ctx_t *)soft_aes_ctx->aes_cbc,
417 (char *)in_buf, out_len, &out);
418
419 if (rc != 0)
420 goto encrypt_failed;
421
422 if (rc == 0) {
423 *pulEncryptedLen = out_len;
424 break;
425 }
426 encrypt_failed:
427 *pulEncryptedLen = 0;
428 return (CKR_DEVICE_ERROR);
429 }
430
431 case CKM_AES_CTR:
432 {
433 crypto_data_t out;
434
435 out.cd_format = CRYPTO_DATA_RAW;
436 out.cd_offset = 0;
437 out.cd_length = out_len;
438 out.cd_raw.iov_base = (char *)out_buf;
439 out.cd_raw.iov_len = out_len;
440
441 rc = aes_encrypt_contiguous_blocks(soft_aes_ctx->aes_cbc,
442 (char *)in_buf, out_len, &out);
443
444 if (rc != 0) {
445 *pulEncryptedLen = 0;
446 return (CKR_DEVICE_ERROR);
447 }
448 /*
449 * Since AES counter mode is a stream cipher, we call
450 * aes_counter_final() to pick up any remaining bytes.
451 * It is an internal function that does not destroy
452 * the context like *normal* final routines.
453 */
454 if (((aes_ctx_t *)soft_aes_ctx->aes_cbc)->ac_remainder_len
455 > 0) {
456 rc = ctr_mode_final(soft_aes_ctx->aes_cbc, &out,
457 aes_encrypt_block);
458 if (rc != 0) {
459 *pulEncryptedLen = 0;
460 return (CKR_DEVICE_ERROR);
461 }
462 }
463
464 *pulEncryptedLen = out_len;
465 break;
466 }
467
468 #ifdef _KERNEL
469 case AES_CCM_MECH_INFO_TYPE:
470 {
471 crypto_data_t out;
472 size_t saved_length, length_needed;
473 aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
474 ccm_ctx_t *ccm_ctx = soft_aes_ctx->aes_cbc;
475
476 length_needed = ulDataLen + aes_ctx->ac_mac_len;
477
478 out.cd_format = CRYPTO_DATA_RAW;
479 out.cd_offset = 0;
480 out.cd_length = length_needed;
481 out.cd_raw.iov_base = (char *)out_buf;
482 out.cd_raw.iov_len = length_needed;
483
484 saved_length = out.cd_length;
485
486 rc = aes_encrypt_contiguous_blocks(aes_ctx,
487 (char *)in_buf, ulDataLen, &out);
488
489 if (rc != 0) {
490 *pulEncryptedLen = 0;
491 return (rc);
492 }
493
494 /*
495 * ccm_encrypt_final() will compute the MAC and append
496 * it to existing ciphertext. So, need to adjust the left over
497 * length value accordingly
498 */
499
500 /* order of following 2 lines MUST not be reversed */
501 out.cd_offset = ccm_ctx->ccm_processed_data_len;
502 out.cd_length = saved_length - ccm_ctx->ccm_processed_data_len;
503
504 rc = ccm_encrypt_final((ccm_ctx_t *)aes_ctx, &out,
505 AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
506
507 if (rc != CRYPTO_SUCCESS) {
508 *pulEncryptedLen = 0;
509 return (rc);
510 }
511
512 *pulEncryptedLen = length_needed;
513 break;
514 }
515
516 case AES_GCM_MECH_INFO_TYPE:
517 {
518 crypto_data_t out;
519 size_t saved_length, length_needed;
520 aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
521 gcm_ctx_t *gcm_ctx = soft_aes_ctx->aes_cbc;
522
523 /*
524 * Output:
525 * A ciphertext, denoted C, whose bit length is the same as
526 * that of the plaintext.
527 * An authentication tag, or tag, for short, denoted T.
528 */
529
530 length_needed = ulDataLen + aes_ctx->ac_tag_len;
531
532 out.cd_format = CRYPTO_DATA_RAW;
533 out.cd_offset = 0;
534 out.cd_length = length_needed;
535 out.cd_raw.iov_base = (char *)out_buf;
536 out.cd_raw.iov_len = length_needed;
537
538 saved_length = out.cd_length;
539
540 rc = aes_encrypt_contiguous_blocks(aes_ctx,
541 (char *)in_buf, ulDataLen, &out);
542
543 if (rc != 0) {
544 *pulEncryptedLen = 0;
545 return (rc);
546 }
547
548 /*
549 * ccm_encrypt_final() will compute the MAC and append
550 * it to existing ciphertext. So, need to adjust the left over
551 * length value accordingly
552 */
553
554 /* order of following 2 lines MUST not be reversed */
555 out.cd_offset = gcm_ctx->gcm_processed_data_len;
556 out.cd_length = saved_length - gcm_ctx->gcm_processed_data_len;
557
558 rc = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, &out,
559 AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
560 aes_xor_block);
561
562 if (rc != CRYPTO_SUCCESS) {
563 *pulEncryptedLen = 0;
564 return (rc);
565 }
566
567 *pulEncryptedLen = length_needed;
568 break;
569 }
570
571 case AES_GMAC_MECH_INFO_TYPE:
572 {
573 crypto_data_t out;
574 size_t length_needed;
575 aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
576
577 length_needed = aes_ctx->ac_tag_len;
578
579 out.cd_format = CRYPTO_DATA_RAW;
580 out.cd_offset = 0;
581 out.cd_length = length_needed;
582 out.cd_raw.iov_base = (char *)out_buf;
583 out.cd_raw.iov_len = length_needed;
584
585 rc = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, &out,
586 AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
587 aes_xor_block);
588
589 if (rc != CRYPTO_SUCCESS) {
590 *pulEncryptedLen = 0;
591 return (rc);
592 }
593
594 *pulEncryptedLen = length_needed;
595 break;
596 }
597 #endif /* _KERNEL */
598 } /* end switch */
599
600 return (rv);
601 }
602
603 /*
604 * fips_aes_decrypt()
605 *
606 * Arguments:
607 * soft_aes_ctx: pointer to AES context
608 * in_buf: pointer to the input data to be decrypted
609 * ulEncryptedLen: length of the input data
610 * out_buf: pointer to the output data
611 * pulDataLen: pointer to the length of the output data
612 * mechanism: CKM_AES_ECB or CKM_AES_CBC
613 *
614 * Description:
615 * This function calls the corresponding low-level decrypt
616 * function based on the mechanism.
617 *
618 */
619 #ifdef _KERNEL
620 int
fips_aes_decrypt(soft_aes_ctx_t * soft_aes_ctx,uchar_t * in_buf,ulong_t ulEncryptedLen,uchar_t * out_buf,ulong_t * pulDataLen,aes_mech_type_t mechanism)621 fips_aes_decrypt(soft_aes_ctx_t *soft_aes_ctx, uchar_t *in_buf,
622 ulong_t ulEncryptedLen, uchar_t *out_buf,
623 ulong_t *pulDataLen, aes_mech_type_t mechanism)
624 #else
625 CK_RV
626 fips_aes_decrypt(soft_aes_ctx_t *soft_aes_ctx, CK_BYTE_PTR in_buf,
627 CK_ULONG ulEncryptedLen, CK_BYTE_PTR out_buf,
628 CK_ULONG_PTR pulDataLen, CK_MECHANISM_TYPE mechanism)
629 #endif
630 {
631
632 int rc = 0;
633 CK_RV rv = CKR_OK;
634 ulong_t out_len;
635
636 /*
637 * AES only takes input length that is a multiple of 16 bytes
638 */
639 if ((ulEncryptedLen % AES_BLOCK_LEN) != 0)
640 return (CKR_ENCRYPTED_DATA_LEN_RANGE);
641
642 /*
643 * For non-padding mode, the output length will
644 * be same as the input length.
645 */
646 out_len = ulEncryptedLen;
647
648 /*
649 * Begin Decryption.
650 */
651 switch (mechanism) {
652
653 case CKM_AES_ECB:
654 {
655
656 ulong_t i;
657 uint8_t *tmp_inbuf;
658 uint8_t *tmp_outbuf;
659
660 for (i = 0; i < out_len; i += AES_BLOCK_LEN) {
661 tmp_inbuf = &in_buf[i];
662 tmp_outbuf = &out_buf[i];
663 /* Crunch one block of data for AES. */
664 (void) aes_decrypt_block(soft_aes_ctx->key_sched,
665 tmp_inbuf, tmp_outbuf);
666 }
667
668 *pulDataLen = out_len;
669
670 break;
671 }
672
673 case CKM_AES_CBC:
674 {
675 crypto_data_t out;
676
677 out.cd_format = CRYPTO_DATA_RAW;
678 out.cd_offset = 0;
679 out.cd_length = out_len;
680 out.cd_raw.iov_base = (char *)out_buf;
681 out.cd_raw.iov_len = out_len;
682
683 /* Decrypt multiple blocks of data. */
684 rc = aes_decrypt_contiguous_blocks(
685 (aes_ctx_t *)soft_aes_ctx->aes_cbc,
686 (char *)in_buf, out_len, &out);
687
688 if (rc != 0)
689 goto decrypt_failed;
690
691
692 *pulDataLen = out_len;
693
694 if (rc == 0)
695 break;
696 decrypt_failed:
697 *pulDataLen = 0;
698 return (CKR_DEVICE_ERROR);
699 }
700
701 case CKM_AES_CTR:
702 {
703 crypto_data_t out;
704
705 out.cd_format = CRYPTO_DATA_RAW;
706 out.cd_offset = 0;
707 out.cd_length = *pulDataLen;
708 out.cd_raw.iov_base = (char *)out_buf;
709 out.cd_raw.iov_len = *pulDataLen;
710
711 rc = aes_decrypt_contiguous_blocks(soft_aes_ctx->aes_cbc,
712 (char *)in_buf, out_len, &out);
713
714 if (rc != 0) {
715 *pulDataLen = 0;
716 return (CKR_DEVICE_ERROR);
717 }
718
719 /*
720 * Since AES counter mode is a stream cipher, we call
721 * aes_counter_final() to pick up any remaining bytes.
722 * It is an internal function that does not destroy
723 * the context like *normal* final routines.
724 */
725 if (((aes_ctx_t *)soft_aes_ctx->aes_cbc)->ac_remainder_len
726 > 0) {
727 rc = ctr_mode_final(soft_aes_ctx->aes_cbc, &out,
728 aes_encrypt_block);
729
730 if (rc == CKR_DATA_LEN_RANGE)
731 return (CKR_ENCRYPTED_DATA_LEN_RANGE);
732 }
733
734 *pulDataLen = out_len;
735 break;
736 }
737
738 #ifdef _KERNEL
739 case AES_CCM_MECH_INFO_TYPE:
740 {
741 crypto_data_t out;
742 size_t length_needed;
743 aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
744 ccm_ctx_t *ccm_ctx = soft_aes_ctx->aes_cbc;
745
746 length_needed = ulEncryptedLen + ccm_ctx->ccm_mac_len;
747
748 out.cd_format = CRYPTO_DATA_RAW;
749 out.cd_offset = 0;
750 out.cd_length = ulEncryptedLen;
751 out.cd_raw.iov_base = (char *)out_buf;
752 out.cd_raw.iov_len = ulEncryptedLen;
753
754 rc = aes_decrypt_contiguous_blocks(aes_ctx,
755 (char *)in_buf, length_needed, &out);
756
757 if (rc != 0) {
758 *pulDataLen = 0;
759 return (CRYPTO_FAILED);
760 }
761
762 /* order of following 2 lines MUST not be reversed */
763 out.cd_offset = 0;
764 out.cd_length = ulEncryptedLen;
765
766 rc = ccm_decrypt_final((ccm_ctx_t *)aes_ctx, &out,
767 AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
768 aes_xor_block);
769
770 if (rc != CRYPTO_SUCCESS) {
771 *pulDataLen = 0;
772 return (CRYPTO_FAILED);
773 }
774
775 *pulDataLen = ulEncryptedLen;
776
777 break;
778 }
779
780 case AES_GCM_MECH_INFO_TYPE:
781 {
782 crypto_data_t out;
783 size_t length_needed;
784 aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
785
786 length_needed = ulEncryptedLen + aes_ctx->ac_tag_len;
787
788 out.cd_format = CRYPTO_DATA_RAW;
789 out.cd_offset = 0;
790 out.cd_length = ulEncryptedLen;
791 out.cd_raw.iov_base = (char *)out_buf;
792 out.cd_raw.iov_len = ulEncryptedLen;
793
794 rc = aes_decrypt_contiguous_blocks(aes_ctx,
795 (char *)in_buf, length_needed, &out);
796
797 if (rc != 0) {
798 *pulDataLen = 0;
799 return (CRYPTO_FAILED);
800 }
801
802 /* order of following 2 lines MUST not be reversed */
803 out.cd_offset = 0;
804 out.cd_length = aes_ctx->ac_tag_len;
805
806 rc = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, &out,
807 AES_BLOCK_LEN, aes_encrypt_block,
808 aes_xor_block);
809
810 if (rc != CRYPTO_SUCCESS) {
811 *pulDataLen = 0;
812 return (CRYPTO_FAILED);
813 }
814
815 *pulDataLen = ulEncryptedLen;
816
817 break;
818 }
819
820 case AES_GMAC_MECH_INFO_TYPE:
821 {
822 crypto_data_t out;
823 size_t length_needed;
824 aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
825
826 length_needed = aes_ctx->ac_tag_len;
827
828 out.cd_format = CRYPTO_DATA_RAW;
829 out.cd_offset = 0;
830 out.cd_length = 0;
831 out.cd_raw.iov_base = (char *)NULL;
832 out.cd_raw.iov_len = 0;
833
834 rc = aes_decrypt_contiguous_blocks(aes_ctx,
835 (char *)in_buf, length_needed, &out);
836
837 if (rc != 0) {
838 *pulDataLen = 0;
839 return (CRYPTO_FAILED);
840 }
841
842 /* order of following 2 lines MUST not be reversed */
843 out.cd_format = CRYPTO_DATA_RAW;
844 out.cd_offset = 0;
845 out.cd_length = 0;
846 out.cd_raw.iov_base = (char *)NULL;
847 out.cd_raw.iov_len = 0;
848
849 rc = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, &out,
850 AES_BLOCK_LEN, aes_encrypt_block,
851 aes_xor_block);
852
853 if (rc != CRYPTO_SUCCESS) {
854 *pulDataLen = 0;
855 return (CRYPTO_FAILED);
856 }
857
858 *pulDataLen = 0;
859
860 break;
861 }
862 #endif
863 } /* end switch */
864
865 return (rv);
866 }
867
868 /* AES self-test for 128-bit, 192-bit, or 256-bit key sizes */
869 int
fips_aes_post(int aes_key_size)870 fips_aes_post(int aes_key_size)
871 {
872 uint8_t *aes_ecb_known_ciphertext =
873 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
874 aes_ecb128_known_ciphertext :
875 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
876 aes_ecb192_known_ciphertext :
877 aes_ecb256_known_ciphertext;
878
879 uint8_t *aes_cbc_known_ciphertext =
880 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
881 aes_cbc128_known_ciphertext :
882 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
883 aes_cbc192_known_ciphertext :
884 aes_cbc256_known_ciphertext;
885
886 uint8_t *aes_ctr_known_ciphertext =
887 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
888 aes_ctr128_known_ciphertext :
889 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
890 aes_ctr192_known_ciphertext :
891 aes_ctr256_known_ciphertext;
892
893 uint8_t *aes_ctr_known_key =
894 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
895 aes_ctr128_known_key :
896 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
897 aes_ctr192_known_key :
898 aes_ctr256_known_key;
899
900 #ifdef _KERNEL
901 uint8_t *aes_ccm_known_plaintext =
902 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
903 aes_ccm128_known_plaintext :
904 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
905 aes_ccm192_known_plaintext :
906 aes_ccm256_known_plaintext;
907
908 uint8_t *aes_ccm_known_ciphertext =
909 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
910 aes_ccm128_known_ciphertext :
911 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
912 aes_ccm192_known_ciphertext :
913 aes_ccm256_known_ciphertext;
914
915 uint8_t *aes_ccm_known_key =
916 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
917 aes_ccm128_known_key :
918 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
919 aes_ccm192_known_key :
920 aes_ccm256_known_key;
921
922 uint8_t *aes_ccm_known_adata =
923 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
924 aes_ccm128_known_adata :
925 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
926 aes_ccm192_known_adata :
927 aes_ccm256_known_adata;
928
929 uint8_t *aes_ccm_known_nonce =
930 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
931 aes_ccm128_known_nonce :
932 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
933 aes_ccm192_known_nonce :
934 aes_ccm256_known_nonce;
935
936 uint8_t *aes_gcm_known_key =
937 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
938 aes_gcm128_known_key :
939 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
940 aes_gcm192_known_key :
941 aes_gcm256_known_key;
942
943 uint8_t *aes_gcm_known_iv =
944 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
945 aes_gcm128_known_iv :
946 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
947 aes_gcm192_known_iv :
948 aes_gcm256_known_iv;
949
950 uint8_t *aes_gcm_known_plaintext =
951 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
952 aes_gcm128_known_plaintext :
953 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
954 aes_gcm192_known_plaintext :
955 aes_gcm256_known_plaintext;
956
957 uint8_t *aes_gcm_known_ciphertext =
958 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
959 aes_gcm128_known_ciphertext :
960 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
961 aes_gcm192_known_ciphertext :
962 aes_gcm256_known_ciphertext;
963
964 uint8_t *aes_gcm_known_adata =
965 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
966 aes_gcm128_known_adata :
967 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
968 aes_gcm192_known_adata :
969 aes_gcm256_known_adata;
970
971 uint8_t *aes_gmac_known_key =
972 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
973 aes_gmac128_known_key :
974 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
975 aes_gmac192_known_key :
976 aes_gmac256_known_key;
977
978 uint8_t *aes_gmac_known_iv =
979 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
980 aes_gmac128_known_iv :
981 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
982 aes_gmac192_known_iv :
983 aes_gmac256_known_iv;
984
985 uint8_t *aes_gmac_known_tag =
986 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
987 aes_gmac128_known_tag :
988 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
989 aes_gmac192_known_tag :
990 aes_gmac256_known_tag;
991
992 uint8_t *aes_gmac_known_adata =
993 (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
994 aes_gmac128_known_adata :
995 (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
996 aes_gmac192_known_adata :
997 aes_gmac256_known_adata;
998
999 /* AES variables. */
1000 uint8_t aes_ccm_computed_ciphertext[3*FIPS_AES_ENCRYPT_LENGTH];
1001 uint8_t aes_ccm_computed_plaintext[2*FIPS_AES_DECRYPT_LENGTH];
1002 uint8_t aes_gcm_computed_ciphertext[2*FIPS_AES_ENCRYPT_LENGTH];
1003 uint8_t aes_gcm_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
1004 uint8_t aes_gmac_computed_tag[FIPS_AES_ENCRYPT_LENGTH];
1005 CK_AES_CCM_PARAMS ccm_param;
1006 CK_AES_GCM_PARAMS gcm_param;
1007 CK_AES_GMAC_PARAMS gmac_param;
1008 #endif
1009
1010 uint8_t aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH];
1011 uint8_t aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
1012 soft_aes_ctx_t *aes_context;
1013 ulong_t aes_bytes_encrypted;
1014 ulong_t aes_bytes_decrypted;
1015 int rv;
1016
1017 /* check if aes_key_size is 128, 192, or 256 bits */
1018 if ((aes_key_size != FIPS_AES_128_KEY_SIZE) &&
1019 (aes_key_size != FIPS_AES_192_KEY_SIZE) &&
1020 (aes_key_size != FIPS_AES_256_KEY_SIZE))
1021 return (CKR_DEVICE_ERROR);
1022
1023 /*
1024 * AES-ECB Known Answer Encryption Test
1025 */
1026 #ifdef _KERNEL
1027 aes_context = fips_aes_build_context(aes_known_key,
1028 aes_key_size, NULL, AES_ECB_MECH_INFO_TYPE, B_FALSE);
1029 #else
1030 aes_context = fips_aes_build_context(aes_known_key,
1031 aes_key_size, NULL, CKM_AES_ECB);
1032 #endif
1033
1034 if (aes_context == NULL) {
1035 return (CKR_HOST_MEMORY);
1036 }
1037
1038 rv = fips_aes_encrypt(aes_context, aes_known_plaintext,
1039 FIPS_AES_ENCRYPT_LENGTH, aes_computed_ciphertext,
1040 &aes_bytes_encrypted, CKM_AES_ECB);
1041
1042 fips_aes_free_context(aes_context);
1043
1044 if ((rv != CKR_OK) ||
1045 (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1046 (memcmp(aes_computed_ciphertext, aes_ecb_known_ciphertext,
1047 FIPS_AES_ENCRYPT_LENGTH) != 0))
1048 return (CKR_DEVICE_ERROR);
1049
1050 /*
1051 * AES-ECB Known Answer Decryption Test
1052 */
1053 #ifdef _KERNEL
1054 aes_context = fips_aes_build_context(aes_known_key,
1055 aes_key_size, NULL, AES_ECB_MECH_INFO_TYPE, B_FALSE);
1056 #else
1057 aes_context = fips_aes_build_context(aes_known_key,
1058 aes_key_size, NULL, CKM_AES_ECB);
1059 #endif
1060
1061 if (aes_context == NULL) {
1062 return (CKR_HOST_MEMORY);
1063 }
1064
1065 rv = fips_aes_decrypt(aes_context, aes_ecb_known_ciphertext,
1066 FIPS_AES_DECRYPT_LENGTH, aes_computed_plaintext,
1067 &aes_bytes_decrypted, CKM_AES_ECB);
1068
1069 fips_aes_free_context(aes_context);
1070
1071 if ((rv != CKR_OK) ||
1072 (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1073 (memcmp(aes_computed_plaintext, aes_known_plaintext,
1074 FIPS_AES_DECRYPT_LENGTH) != 0))
1075 return (CKR_DEVICE_ERROR);
1076
1077 /*
1078 * AES-CBC Known Answer Encryption Test
1079 */
1080 #ifdef _KERNEL
1081 aes_context = fips_aes_build_context(aes_known_key,
1082 aes_key_size, aes_cbc_known_initialization_vector,
1083 AES_CBC_MECH_INFO_TYPE, B_FALSE);
1084 #else
1085 aes_context = fips_aes_build_context(aes_known_key,
1086 aes_key_size, aes_cbc_known_initialization_vector,
1087 CKM_AES_CBC);
1088 #endif
1089
1090 if (aes_context == NULL) {
1091 return (CKR_HOST_MEMORY);
1092 }
1093
1094 rv = fips_aes_encrypt(aes_context, aes_known_plaintext,
1095 FIPS_AES_ENCRYPT_LENGTH, aes_computed_ciphertext,
1096 &aes_bytes_encrypted, CKM_AES_CBC);
1097
1098 fips_aes_free_context(aes_context);
1099
1100 if ((rv != CKR_OK) ||
1101 (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1102 (memcmp(aes_computed_ciphertext, aes_cbc_known_ciphertext,
1103 FIPS_AES_ENCRYPT_LENGTH) != 0))
1104 return (CKR_DEVICE_ERROR);
1105
1106 /*
1107 * AES-CBC Known Answer Decryption Test
1108 */
1109 #ifdef _KERNEL
1110 aes_context = fips_aes_build_context(aes_known_key,
1111 aes_key_size, aes_cbc_known_initialization_vector,
1112 AES_CBC_MECH_INFO_TYPE, B_FALSE);
1113 #else
1114 aes_context = fips_aes_build_context(aes_known_key,
1115 aes_key_size, aes_cbc_known_initialization_vector,
1116 CKM_AES_CBC);
1117 #endif
1118
1119 if (aes_context == NULL)
1120 return (CRYPTO_HOST_MEMORY);
1121
1122 rv = fips_aes_decrypt(aes_context, aes_cbc_known_ciphertext,
1123 FIPS_AES_DECRYPT_LENGTH, aes_computed_plaintext,
1124 &aes_bytes_decrypted, CKM_AES_CBC);
1125
1126 fips_aes_free_context(aes_context);
1127
1128 if ((rv != CKR_OK) ||
1129 (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1130 (memcmp(aes_computed_plaintext, aes_known_plaintext,
1131 FIPS_AES_DECRYPT_LENGTH) != 0))
1132 return (CKR_DEVICE_ERROR);
1133
1134 /*
1135 * AES-CTR Known Answer Encryption Test
1136 */
1137 #ifdef _KERNEL
1138 aes_context = fips_aes_build_context(aes_ctr_known_key,
1139 aes_key_size, aes_ctr_known_counter,
1140 AES_CTR_MECH_INFO_TYPE, B_FALSE);
1141 #else
1142 aes_context = fips_aes_build_context(aes_ctr_known_key,
1143 aes_key_size, aes_ctr_known_counter, CKM_AES_CTR);
1144 #endif
1145
1146 if (aes_context == NULL) {
1147 return (CKR_HOST_MEMORY);
1148 }
1149
1150 rv = fips_aes_encrypt(aes_context, aes_ctr_known_plaintext,
1151 FIPS_AES_ENCRYPT_LENGTH, aes_computed_ciphertext,
1152 &aes_bytes_encrypted, CKM_AES_CTR);
1153
1154 fips_aes_free_context(aes_context);
1155
1156 if ((rv != CKR_OK) ||
1157 (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1158 (memcmp(aes_computed_ciphertext, aes_ctr_known_ciphertext,
1159 FIPS_AES_ENCRYPT_LENGTH) != 0))
1160 return (CKR_DEVICE_ERROR);
1161
1162 /*
1163 * AES-CTR Known Answer Decryption Test
1164 */
1165 #ifdef _KERNEL
1166 aes_context = fips_aes_build_context(aes_ctr_known_key,
1167 aes_key_size, aes_ctr_known_counter,
1168 AES_CTR_MECH_INFO_TYPE, B_FALSE);
1169 #else
1170 aes_context = fips_aes_build_context(aes_ctr_known_key,
1171 aes_key_size, aes_ctr_known_counter,
1172 CKM_AES_CTR);
1173 #endif
1174 if (aes_context == NULL) {
1175 return (CKR_HOST_MEMORY);
1176 }
1177
1178 rv = fips_aes_decrypt(aes_context, aes_ctr_known_ciphertext,
1179 FIPS_AES_DECRYPT_LENGTH, aes_computed_plaintext,
1180 &aes_bytes_decrypted, CKM_AES_CTR);
1181
1182 fips_aes_free_context(aes_context);
1183
1184 if ((rv != CKR_OK) ||
1185 (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1186 (memcmp(aes_computed_plaintext, aes_ctr_known_plaintext,
1187 FIPS_AES_DECRYPT_LENGTH) != 0))
1188 return (CKR_DEVICE_ERROR);
1189
1190 /*
1191 * The following POSTs are only available in Kernel
1192 *
1193 * CCM, GCM, and GMAC
1194 */
1195 #ifdef _KERNEL
1196
1197 /*
1198 * AES-CCM Known Answer Encryption Test
1199 */
1200 ccm_param.ulMACSize = 16; /* Tlen */
1201 ccm_param.ulNonceSize = 7; /* Nlen */
1202 ccm_param.ulAuthDataSize = 30; /* Alen */
1203 ccm_param.ulDataSize = 32; /* Plen or Clen */
1204 ccm_param.nonce = aes_ccm_known_nonce;
1205 ccm_param.authData = aes_ccm_known_adata;
1206
1207 aes_context = fips_aes_build_context(aes_ccm_known_key,
1208 aes_key_size, (uint8_t *)&ccm_param,
1209 AES_CCM_MECH_INFO_TYPE, B_TRUE);
1210
1211 if (aes_context == NULL) {
1212 return (CRYPTO_HOST_MEMORY);
1213 }
1214
1215 rv = fips_aes_encrypt(aes_context, aes_ccm_known_plaintext,
1216 2*FIPS_AES_ENCRYPT_LENGTH, aes_ccm_computed_ciphertext,
1217 &aes_bytes_encrypted, AES_CCM_MECH_INFO_TYPE);
1218
1219 fips_aes_free_context(aes_context);
1220
1221 if ((rv != CRYPTO_SUCCESS) ||
1222 (aes_bytes_encrypted != 3*FIPS_AES_ENCRYPT_LENGTH) ||
1223 (memcmp(aes_ccm_computed_ciphertext, aes_ccm_known_ciphertext,
1224 3*FIPS_AES_ENCRYPT_LENGTH) != 0))
1225 return (CRYPTO_DEVICE_ERROR);
1226
1227 /*
1228 * AES-CCM Known Answer Decryption Test
1229 */
1230 ccm_param.ulMACSize = 16; /* Tlen */
1231 ccm_param.ulNonceSize = 7; /* Nlen */
1232 ccm_param.ulAuthDataSize = 30; /* Alen */
1233 ccm_param.ulDataSize = 48; /* Plen or Clen */
1234 ccm_param.nonce = aes_ccm_known_nonce;
1235 ccm_param.authData = aes_ccm_known_adata;
1236
1237 aes_context = fips_aes_build_context(aes_ccm_known_key,
1238 aes_key_size, (uint8_t *)&ccm_param,
1239 AES_CCM_MECH_INFO_TYPE, B_FALSE);
1240
1241 if (aes_context == NULL) {
1242 return (CRYPTO_HOST_MEMORY);
1243 }
1244
1245 rv = fips_aes_decrypt(aes_context, aes_ccm_known_ciphertext,
1246 2*FIPS_AES_DECRYPT_LENGTH, aes_ccm_computed_plaintext,
1247 &aes_bytes_decrypted, AES_CCM_MECH_INFO_TYPE);
1248
1249 fips_aes_free_context(aes_context);
1250
1251 if ((rv != CRYPTO_SUCCESS) ||
1252 (aes_bytes_decrypted != 2*FIPS_AES_DECRYPT_LENGTH) ||
1253 (memcmp(aes_ccm_computed_plaintext, aes_ccm_known_plaintext,
1254 2*FIPS_AES_DECRYPT_LENGTH) != 0))
1255 return (CRYPTO_DEVICE_ERROR);
1256
1257 /*
1258 * AES-GCM Known Answer Encryption Test
1259 */
1260 gcm_param.pIv = aes_gcm_known_iv;
1261 gcm_param.ulIvLen = AES_GMAC_IV_LEN; /* IVlen = 96 bits */
1262 gcm_param.ulTagBits = AES_GMAC_TAG_BITS; /* Taglen = 128 bits */
1263 gcm_param.ulAADLen = 16;
1264 gcm_param.pAAD = aes_gcm_known_adata;
1265
1266 aes_context = fips_aes_build_context(aes_gcm_known_key,
1267 aes_key_size, (uint8_t *)&gcm_param,
1268 AES_GCM_MECH_INFO_TYPE, B_TRUE);
1269
1270 if (aes_context == NULL) {
1271 return (CRYPTO_HOST_MEMORY);
1272 }
1273
1274 rv = fips_aes_encrypt(aes_context, aes_gcm_known_plaintext,
1275 FIPS_AES_ENCRYPT_LENGTH, aes_gcm_computed_ciphertext,
1276 &aes_bytes_encrypted, AES_GCM_MECH_INFO_TYPE);
1277
1278 fips_aes_free_context(aes_context);
1279
1280 if ((rv != CRYPTO_SUCCESS) ||
1281 (aes_bytes_encrypted != 2*FIPS_AES_ENCRYPT_LENGTH) ||
1282 (memcmp(aes_gcm_computed_ciphertext, aes_gcm_known_ciphertext,
1283 2*FIPS_AES_ENCRYPT_LENGTH) != 0))
1284 return (CRYPTO_DEVICE_ERROR);
1285
1286 /*
1287 * AES-GCM Known Answer Decryption Test
1288 */
1289 aes_context = fips_aes_build_context(aes_gcm_known_key,
1290 aes_key_size, (uint8_t *)&gcm_param,
1291 AES_GCM_MECH_INFO_TYPE, B_FALSE);
1292
1293 if (aes_context == NULL) {
1294 return (CRYPTO_HOST_MEMORY);
1295 }
1296
1297 rv = fips_aes_decrypt(aes_context, aes_gcm_known_ciphertext,
1298 FIPS_AES_DECRYPT_LENGTH, aes_gcm_computed_plaintext,
1299 &aes_bytes_decrypted, AES_GCM_MECH_INFO_TYPE);
1300
1301 fips_aes_free_context(aes_context);
1302
1303 if ((rv != CRYPTO_SUCCESS) ||
1304 (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1305 (memcmp(aes_gcm_computed_plaintext, aes_gcm_known_plaintext,
1306 FIPS_AES_DECRYPT_LENGTH) != 0))
1307 return (CRYPTO_DEVICE_ERROR);
1308
1309 /*
1310 * AES-GMAC Known Answer Encryption Test
1311 */
1312 gmac_param.pIv = aes_gmac_known_iv;
1313 gmac_param.ulAADLen = 16;
1314 gmac_param.pAAD = aes_gmac_known_adata;
1315
1316 aes_context = fips_aes_build_context(aes_gmac_known_key,
1317 aes_key_size, (uint8_t *)&gmac_param,
1318 AES_GMAC_MECH_INFO_TYPE, B_TRUE);
1319
1320 if (aes_context == NULL) {
1321 return (CRYPTO_HOST_MEMORY);
1322 }
1323
1324 rv = fips_aes_encrypt(aes_context, NULL,
1325 0, aes_gmac_computed_tag,
1326 &aes_bytes_encrypted, AES_GMAC_MECH_INFO_TYPE);
1327
1328 fips_aes_free_context(aes_context);
1329
1330 if ((rv != CRYPTO_SUCCESS) ||
1331 (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1332 (memcmp(aes_gmac_computed_tag, aes_gmac_known_tag,
1333 FIPS_AES_ENCRYPT_LENGTH) != 0))
1334 return (CRYPTO_DEVICE_ERROR);
1335
1336 /*
1337 * AES-GMAC Known Answer Decryption Test
1338 */
1339
1340 aes_context = fips_aes_build_context(aes_gmac_known_key,
1341 aes_key_size, (uint8_t *)&gmac_param,
1342 AES_GMAC_MECH_INFO_TYPE, B_FALSE);
1343
1344 if (aes_context == NULL) {
1345 return (CRYPTO_HOST_MEMORY);
1346 }
1347
1348 rv = fips_aes_decrypt(aes_context, aes_gmac_known_tag,
1349 FIPS_AES_DECRYPT_LENGTH, NULL,
1350 &aes_bytes_decrypted, AES_GMAC_MECH_INFO_TYPE);
1351
1352 fips_aes_free_context(aes_context);
1353
1354 if ((rv != CRYPTO_SUCCESS) ||
1355 (aes_bytes_decrypted != 0))
1356 return (CRYPTO_DEVICE_ERROR);
1357
1358 #endif /* _KERNEL */
1359
1360 return (CRYPTO_SUCCESS);
1361 }
1362