xref: /onnv-gate/usr/src/common/crypto/fips/fips_aes_util.c (revision 12929:f2051cc42292)
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