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
50void *
51aes_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 */
73void *
74aes_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 */
102void *
103aes_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 */
129void *
130aes_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
152void *
153aes_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 */
181soft_aes_ctx_t *
182#ifdef _KERNEL
183fips_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
186fips_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
287void
288fips_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
311void
312fips_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
351int
352fips_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
356CK_RV
357fips_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		}
426encrypt_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
620int
621fips_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
625CK_RV
626fips_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;
696decrypt_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 */
869int
870fips_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