xref: /onnv-gate/usr/src/common/crypto/fips/fips_aes_util.c (revision 10500:a10fbcfc2f21)
1*10500SHai-May.Chao@Sun.COM /*
2*10500SHai-May.Chao@Sun.COM  * CDDL HEADER START
3*10500SHai-May.Chao@Sun.COM  *
4*10500SHai-May.Chao@Sun.COM  * The contents of this file are subject to the terms of the
5*10500SHai-May.Chao@Sun.COM  * Common Development and Distribution License (the "License").
6*10500SHai-May.Chao@Sun.COM  * You may not use this file except in compliance with the License.
7*10500SHai-May.Chao@Sun.COM  *
8*10500SHai-May.Chao@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10500SHai-May.Chao@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*10500SHai-May.Chao@Sun.COM  * See the License for the specific language governing permissions
11*10500SHai-May.Chao@Sun.COM  * and limitations under the License.
12*10500SHai-May.Chao@Sun.COM  *
13*10500SHai-May.Chao@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*10500SHai-May.Chao@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10500SHai-May.Chao@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*10500SHai-May.Chao@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*10500SHai-May.Chao@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*10500SHai-May.Chao@Sun.COM  *
19*10500SHai-May.Chao@Sun.COM  * CDDL HEADER END
20*10500SHai-May.Chao@Sun.COM  */
21*10500SHai-May.Chao@Sun.COM /*
22*10500SHai-May.Chao@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*10500SHai-May.Chao@Sun.COM  * Use is subject to license terms.
24*10500SHai-May.Chao@Sun.COM  */
25*10500SHai-May.Chao@Sun.COM 
26*10500SHai-May.Chao@Sun.COM #include <sys/types.h>
27*10500SHai-May.Chao@Sun.COM #include <sys/param.h>
28*10500SHai-May.Chao@Sun.COM #include <sys/cmn_err.h>
29*10500SHai-May.Chao@Sun.COM #include <sys/errno.h>
30*10500SHai-May.Chao@Sun.COM #include <sys/kmem.h>
31*10500SHai-May.Chao@Sun.COM #include <sys/systm.h>
32*10500SHai-May.Chao@Sun.COM #include <sys/crypto/common.h>
33*10500SHai-May.Chao@Sun.COM #include <modes/modes.h>
34*10500SHai-May.Chao@Sun.COM #define	_AES_FIPS_POST
35*10500SHai-May.Chao@Sun.COM #ifndef	_KERNEL
36*10500SHai-May.Chao@Sun.COM #include <stdlib.h>
37*10500SHai-May.Chao@Sun.COM #include <string.h>
38*10500SHai-May.Chao@Sun.COM #include <strings.h>
39*10500SHai-May.Chao@Sun.COM #include <stdio.h>
40*10500SHai-May.Chao@Sun.COM #include <security/cryptoki.h>
41*10500SHai-May.Chao@Sun.COM #include <cryptoutil.h>
42*10500SHai-May.Chao@Sun.COM #include "softCrypt.h"
43*10500SHai-May.Chao@Sun.COM #else
44*10500SHai-May.Chao@Sun.COM #define	_AES_IMPL
45*10500SHai-May.Chao@Sun.COM #include <aes/aes_impl.h>
46*10500SHai-May.Chao@Sun.COM #endif
47*10500SHai-May.Chao@Sun.COM 
48*10500SHai-May.Chao@Sun.COM 
49*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
50*10500SHai-May.Chao@Sun.COM void *
51*10500SHai-May.Chao@Sun.COM aes_cbc_ctx_init(void *key_sched, size_t size, uint8_t *ivec)
52*10500SHai-May.Chao@Sun.COM {
53*10500SHai-May.Chao@Sun.COM 
54*10500SHai-May.Chao@Sun.COM 	cbc_ctx_t *cbc_ctx;
55*10500SHai-May.Chao@Sun.COM 
56*10500SHai-May.Chao@Sun.COM 	if ((cbc_ctx = kmem_zalloc(sizeof (cbc_ctx_t), KM_SLEEP)) == NULL)
57*10500SHai-May.Chao@Sun.COM 		return (NULL);
58*10500SHai-May.Chao@Sun.COM 
59*10500SHai-May.Chao@Sun.COM 	cbc_ctx->cbc_keysched = key_sched;
60*10500SHai-May.Chao@Sun.COM 	cbc_ctx->cbc_keysched_len = size;
61*10500SHai-May.Chao@Sun.COM 
62*10500SHai-May.Chao@Sun.COM 	(void) memcpy(&cbc_ctx->cbc_iv[0], ivec, AES_BLOCK_LEN);
63*10500SHai-May.Chao@Sun.COM 
64*10500SHai-May.Chao@Sun.COM 	cbc_ctx->cbc_lastp = (uint8_t *)cbc_ctx->cbc_iv;
65*10500SHai-May.Chao@Sun.COM 	cbc_ctx->cbc_flags |= CBC_MODE;
66*10500SHai-May.Chao@Sun.COM 
67*10500SHai-May.Chao@Sun.COM 	return (cbc_ctx);
68*10500SHai-May.Chao@Sun.COM }
69*10500SHai-May.Chao@Sun.COM 
70*10500SHai-May.Chao@Sun.COM /*
71*10500SHai-May.Chao@Sun.COM  * Allocate and initialize a context for AES CTR mode of operation.
72*10500SHai-May.Chao@Sun.COM  */
73*10500SHai-May.Chao@Sun.COM void *
74*10500SHai-May.Chao@Sun.COM aes_ctr_ctx_init(void *key_sched, size_t size, uint8_t *param)
75*10500SHai-May.Chao@Sun.COM {
76*10500SHai-May.Chao@Sun.COM 
77*10500SHai-May.Chao@Sun.COM 	ctr_ctx_t *ctr_ctx;
78*10500SHai-May.Chao@Sun.COM 	CK_AES_CTR_PARAMS *pp;
79*10500SHai-May.Chao@Sun.COM 
80*10500SHai-May.Chao@Sun.COM 	/* LINTED: pointer alignment */
81*10500SHai-May.Chao@Sun.COM 	pp = (CK_AES_CTR_PARAMS *)param;
82*10500SHai-May.Chao@Sun.COM 
83*10500SHai-May.Chao@Sun.COM 	if ((ctr_ctx = kmem_zalloc(sizeof (ctr_ctx_t), KM_SLEEP)) == NULL)
84*10500SHai-May.Chao@Sun.COM 		return (NULL);
85*10500SHai-May.Chao@Sun.COM 
86*10500SHai-May.Chao@Sun.COM 	ctr_ctx->ctr_keysched = key_sched;
87*10500SHai-May.Chao@Sun.COM 	ctr_ctx->ctr_keysched_len = size;
88*10500SHai-May.Chao@Sun.COM 
89*10500SHai-May.Chao@Sun.COM 	if (ctr_init_ctx(ctr_ctx, pp->ulCounterBits, pp->cb,
90*10500SHai-May.Chao@Sun.COM 	    aes_copy_block) != CRYPTO_SUCCESS) {
91*10500SHai-May.Chao@Sun.COM 		kmem_free(ctr_ctx, sizeof (ctr_ctx_t));
92*10500SHai-May.Chao@Sun.COM 		return (NULL);
93*10500SHai-May.Chao@Sun.COM 	}
94*10500SHai-May.Chao@Sun.COM 	ctr_ctx->ctr_flags |= CTR_MODE;
95*10500SHai-May.Chao@Sun.COM 
96*10500SHai-May.Chao@Sun.COM 	return (ctr_ctx);
97*10500SHai-May.Chao@Sun.COM }
98*10500SHai-May.Chao@Sun.COM 
99*10500SHai-May.Chao@Sun.COM /*
100*10500SHai-May.Chao@Sun.COM  * Allocate and initialize a context for AES CCM mode of operation.
101*10500SHai-May.Chao@Sun.COM  */
102*10500SHai-May.Chao@Sun.COM void *
103*10500SHai-May.Chao@Sun.COM aes_ccm_ctx_init(void *key_sched, size_t size, uint8_t *param,
104*10500SHai-May.Chao@Sun.COM 	boolean_t is_encrypt_init)
105*10500SHai-May.Chao@Sun.COM {
106*10500SHai-May.Chao@Sun.COM 
107*10500SHai-May.Chao@Sun.COM 	ccm_ctx_t *ccm_ctx;
108*10500SHai-May.Chao@Sun.COM 
109*10500SHai-May.Chao@Sun.COM 	if ((ccm_ctx = kmem_zalloc(sizeof (ccm_ctx_t), KM_SLEEP)) == NULL)
110*10500SHai-May.Chao@Sun.COM 		return (NULL);
111*10500SHai-May.Chao@Sun.COM 
112*10500SHai-May.Chao@Sun.COM 	ccm_ctx->ccm_keysched = key_sched;
113*10500SHai-May.Chao@Sun.COM 	ccm_ctx->ccm_keysched_len = size;
114*10500SHai-May.Chao@Sun.COM 
115*10500SHai-May.Chao@Sun.COM 	if (ccm_init_ctx(ccm_ctx, (char *)param, KM_SLEEP,
116*10500SHai-May.Chao@Sun.COM 	    is_encrypt_init, AES_BLOCK_LEN, aes_encrypt_block,
117*10500SHai-May.Chao@Sun.COM 	    aes_xor_block) != CRYPTO_SUCCESS) {
118*10500SHai-May.Chao@Sun.COM 		kmem_free(ccm_ctx, sizeof (ccm_ctx_t));
119*10500SHai-May.Chao@Sun.COM 		return (NULL);
120*10500SHai-May.Chao@Sun.COM 	}
121*10500SHai-May.Chao@Sun.COM 	ccm_ctx->ccm_flags |= CCM_MODE;
122*10500SHai-May.Chao@Sun.COM 
123*10500SHai-May.Chao@Sun.COM 	return (ccm_ctx);
124*10500SHai-May.Chao@Sun.COM }
125*10500SHai-May.Chao@Sun.COM 
126*10500SHai-May.Chao@Sun.COM /*
127*10500SHai-May.Chao@Sun.COM  * Allocate and initialize a context for AES CCM mode of operation.
128*10500SHai-May.Chao@Sun.COM  */
129*10500SHai-May.Chao@Sun.COM void *
130*10500SHai-May.Chao@Sun.COM aes_gcm_ctx_init(void *key_sched, size_t size, uint8_t *param)
131*10500SHai-May.Chao@Sun.COM {
132*10500SHai-May.Chao@Sun.COM 
133*10500SHai-May.Chao@Sun.COM 	gcm_ctx_t *gcm_ctx;
134*10500SHai-May.Chao@Sun.COM 
135*10500SHai-May.Chao@Sun.COM 	if ((gcm_ctx = kmem_zalloc(sizeof (gcm_ctx_t), KM_SLEEP)) == NULL)
136*10500SHai-May.Chao@Sun.COM 		return (NULL);
137*10500SHai-May.Chao@Sun.COM 
138*10500SHai-May.Chao@Sun.COM 	gcm_ctx->gcm_keysched = key_sched;
139*10500SHai-May.Chao@Sun.COM 	gcm_ctx->gcm_keysched_len = size;
140*10500SHai-May.Chao@Sun.COM 
141*10500SHai-May.Chao@Sun.COM 	if (gcm_init_ctx(gcm_ctx, (char *)param, AES_BLOCK_LEN,
142*10500SHai-May.Chao@Sun.COM 	    aes_encrypt_block, aes_copy_block,
143*10500SHai-May.Chao@Sun.COM 	    aes_xor_block) != CRYPTO_SUCCESS) {
144*10500SHai-May.Chao@Sun.COM 		kmem_free(gcm_ctx, sizeof (gcm_ctx_t));
145*10500SHai-May.Chao@Sun.COM 		return (NULL);
146*10500SHai-May.Chao@Sun.COM 	}
147*10500SHai-May.Chao@Sun.COM 	gcm_ctx->gcm_flags |= GCM_MODE;
148*10500SHai-May.Chao@Sun.COM 
149*10500SHai-May.Chao@Sun.COM 	return (gcm_ctx);
150*10500SHai-May.Chao@Sun.COM }
151*10500SHai-May.Chao@Sun.COM 
152*10500SHai-May.Chao@Sun.COM void *
153*10500SHai-May.Chao@Sun.COM aes_gmac_ctx_init(void *key_sched, size_t size, uint8_t *param)
154*10500SHai-May.Chao@Sun.COM {
155*10500SHai-May.Chao@Sun.COM 
156*10500SHai-May.Chao@Sun.COM 	gcm_ctx_t *gcm_ctx;
157*10500SHai-May.Chao@Sun.COM 
158*10500SHai-May.Chao@Sun.COM 	if ((gcm_ctx = kmem_zalloc(sizeof (gcm_ctx_t), KM_SLEEP)) == NULL)
159*10500SHai-May.Chao@Sun.COM 		return (NULL);
160*10500SHai-May.Chao@Sun.COM 
161*10500SHai-May.Chao@Sun.COM 	gcm_ctx->gcm_keysched = key_sched;
162*10500SHai-May.Chao@Sun.COM 	gcm_ctx->gcm_keysched_len = size;
163*10500SHai-May.Chao@Sun.COM 
164*10500SHai-May.Chao@Sun.COM 	if (gmac_init_ctx(gcm_ctx, (char *)param, AES_BLOCK_LEN,
165*10500SHai-May.Chao@Sun.COM 	    aes_encrypt_block, aes_copy_block,
166*10500SHai-May.Chao@Sun.COM 	    aes_xor_block) != CRYPTO_SUCCESS) {
167*10500SHai-May.Chao@Sun.COM 		kmem_free(gcm_ctx, sizeof (gcm_ctx_t));
168*10500SHai-May.Chao@Sun.COM 		return (NULL);
169*10500SHai-May.Chao@Sun.COM 	}
170*10500SHai-May.Chao@Sun.COM 	gcm_ctx->gcm_flags |= GMAC_MODE;
171*10500SHai-May.Chao@Sun.COM 
172*10500SHai-May.Chao@Sun.COM 	return (gcm_ctx);
173*10500SHai-May.Chao@Sun.COM }
174*10500SHai-May.Chao@Sun.COM #endif
175*10500SHai-May.Chao@Sun.COM 
176*10500SHai-May.Chao@Sun.COM 
177*10500SHai-May.Chao@Sun.COM /*
178*10500SHai-May.Chao@Sun.COM  * Allocate context for the active encryption or decryption operation, and
179*10500SHai-May.Chao@Sun.COM  * generate AES key schedule to speed up the operation.
180*10500SHai-May.Chao@Sun.COM  */
181*10500SHai-May.Chao@Sun.COM soft_aes_ctx_t *
182*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
183*10500SHai-May.Chao@Sun.COM fips_aes_build_context(uint8_t *key, int key_len, uint8_t *iv,
184*10500SHai-May.Chao@Sun.COM 	aes_mech_type_t mechanism, boolean_t is_encrypt_init)
185*10500SHai-May.Chao@Sun.COM #else
186*10500SHai-May.Chao@Sun.COM fips_aes_build_context(uint8_t *key, int key_len, uint8_t *iv,
187*10500SHai-May.Chao@Sun.COM 	CK_MECHANISM_TYPE mechanism)
188*10500SHai-May.Chao@Sun.COM #endif
189*10500SHai-May.Chao@Sun.COM {
190*10500SHai-May.Chao@Sun.COM 	size_t size;
191*10500SHai-May.Chao@Sun.COM 	soft_aes_ctx_t *soft_aes_ctx;
192*10500SHai-May.Chao@Sun.COM 	CK_AES_CTR_PARAMS pp;
193*10500SHai-May.Chao@Sun.COM 
194*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
195*10500SHai-May.Chao@Sun.COM 	if ((soft_aes_ctx = kmem_zalloc(sizeof (soft_aes_ctx_t),
196*10500SHai-May.Chao@Sun.COM 	    KM_SLEEP)) == NULL)
197*10500SHai-May.Chao@Sun.COM #else
198*10500SHai-May.Chao@Sun.COM 	if ((soft_aes_ctx = calloc(1, sizeof (soft_aes_ctx_t)))
199*10500SHai-May.Chao@Sun.COM 	    == NULL)
200*10500SHai-May.Chao@Sun.COM #endif
201*10500SHai-May.Chao@Sun.COM 		return (NULL);
202*10500SHai-May.Chao@Sun.COM 
203*10500SHai-May.Chao@Sun.COM 
204*10500SHai-May.Chao@Sun.COM 	soft_aes_ctx->key_sched = aes_alloc_keysched(&size, 0);
205*10500SHai-May.Chao@Sun.COM 
206*10500SHai-May.Chao@Sun.COM 	if (soft_aes_ctx->key_sched == NULL) {
207*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
208*10500SHai-May.Chao@Sun.COM 		kmem_free(soft_aes_ctx, sizeof (soft_aes_ctx_t));
209*10500SHai-May.Chao@Sun.COM #else
210*10500SHai-May.Chao@Sun.COM 		free(soft_aes_ctx);
211*10500SHai-May.Chao@Sun.COM #endif
212*10500SHai-May.Chao@Sun.COM 		return (NULL);
213*10500SHai-May.Chao@Sun.COM 	}
214*10500SHai-May.Chao@Sun.COM 
215*10500SHai-May.Chao@Sun.COM 	soft_aes_ctx->keysched_len = size;
216*10500SHai-May.Chao@Sun.COM 
217*10500SHai-May.Chao@Sun.COM #ifdef	__sparcv9
218*10500SHai-May.Chao@Sun.COM 	aes_init_keysched(key, (uint_t)(key_len * 8),
219*10500SHai-May.Chao@Sun.COM 	    soft_aes_ctx->key_sched);
220*10500SHai-May.Chao@Sun.COM #else	/* !__sparcv9 */
221*10500SHai-May.Chao@Sun.COM 	aes_init_keysched(key, (key_len * 8),
222*10500SHai-May.Chao@Sun.COM 	    soft_aes_ctx->key_sched);
223*10500SHai-May.Chao@Sun.COM #endif	/* __sparcv9 */
224*10500SHai-May.Chao@Sun.COM 
225*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
226*10500SHai-May.Chao@Sun.COM 
227*10500SHai-May.Chao@Sun.COM 	case CKM_AES_CBC:
228*10500SHai-May.Chao@Sun.COM 
229*10500SHai-May.Chao@Sun.COM 		/* Save Initialization Vector (IV) in the context. */
230*10500SHai-May.Chao@Sun.COM 		(void) memcpy(soft_aes_ctx->ivec, iv, AES_BLOCK_LEN);
231*10500SHai-May.Chao@Sun.COM 		/* Allocate a context for AES cipher-block chaining. */
232*10500SHai-May.Chao@Sun.COM 		soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
233*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->key_sched,
234*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->keysched_len,
235*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->ivec);
236*10500SHai-May.Chao@Sun.COM 		break;
237*10500SHai-May.Chao@Sun.COM 
238*10500SHai-May.Chao@Sun.COM 	case CKM_AES_CTR:
239*10500SHai-May.Chao@Sun.COM 
240*10500SHai-May.Chao@Sun.COM 		pp.ulCounterBits = 16;
241*10500SHai-May.Chao@Sun.COM 		(void) memcpy(pp.cb, iv, AES_BLOCK_LEN);
242*10500SHai-May.Chao@Sun.COM 		soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
243*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->key_sched,
244*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->keysched_len,
245*10500SHai-May.Chao@Sun.COM 		    (uint8_t *)&pp);
246*10500SHai-May.Chao@Sun.COM 		break;
247*10500SHai-May.Chao@Sun.COM 
248*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
249*10500SHai-May.Chao@Sun.COM 	case AES_CCM_MECH_INFO_TYPE:
250*10500SHai-May.Chao@Sun.COM 		soft_aes_ctx->aes_cbc = aes_ccm_ctx_init(
251*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->key_sched,
252*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->keysched_len, iv,
253*10500SHai-May.Chao@Sun.COM 		    is_encrypt_init);
254*10500SHai-May.Chao@Sun.COM 		break;
255*10500SHai-May.Chao@Sun.COM 
256*10500SHai-May.Chao@Sun.COM 	case AES_GCM_MECH_INFO_TYPE:
257*10500SHai-May.Chao@Sun.COM 		soft_aes_ctx->aes_cbc = aes_gcm_ctx_init(
258*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->key_sched,
259*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->keysched_len, iv);
260*10500SHai-May.Chao@Sun.COM 		break;
261*10500SHai-May.Chao@Sun.COM 
262*10500SHai-May.Chao@Sun.COM 	case AES_GMAC_MECH_INFO_TYPE:
263*10500SHai-May.Chao@Sun.COM 		soft_aes_ctx->aes_cbc = aes_gmac_ctx_init(
264*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->key_sched,
265*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->keysched_len, iv);
266*10500SHai-May.Chao@Sun.COM 		break;
267*10500SHai-May.Chao@Sun.COM #endif
268*10500SHai-May.Chao@Sun.COM 	default:
269*10500SHai-May.Chao@Sun.COM 		return (soft_aes_ctx);
270*10500SHai-May.Chao@Sun.COM 	}
271*10500SHai-May.Chao@Sun.COM 
272*10500SHai-May.Chao@Sun.COM 	if (soft_aes_ctx->aes_cbc == NULL) {
273*10500SHai-May.Chao@Sun.COM 		bzero(soft_aes_ctx->key_sched,
274*10500SHai-May.Chao@Sun.COM 		    soft_aes_ctx->keysched_len);
275*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
276*10500SHai-May.Chao@Sun.COM 		kmem_free(soft_aes_ctx->key_sched, size);
277*10500SHai-May.Chao@Sun.COM #else
278*10500SHai-May.Chao@Sun.COM 		free(soft_aes_ctx->key_sched);
279*10500SHai-May.Chao@Sun.COM #endif
280*10500SHai-May.Chao@Sun.COM 		return (NULL);
281*10500SHai-May.Chao@Sun.COM 	}
282*10500SHai-May.Chao@Sun.COM 
283*10500SHai-May.Chao@Sun.COM 	return (soft_aes_ctx);
284*10500SHai-May.Chao@Sun.COM }
285*10500SHai-May.Chao@Sun.COM 
286*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
287*10500SHai-May.Chao@Sun.COM void
288*10500SHai-May.Chao@Sun.COM fips_aes_free_context(soft_aes_ctx_t *soft_aes_ctx)
289*10500SHai-May.Chao@Sun.COM {
290*10500SHai-May.Chao@Sun.COM 
291*10500SHai-May.Chao@Sun.COM 	common_ctx_t *aes_ctx;
292*10500SHai-May.Chao@Sun.COM 
293*10500SHai-May.Chao@Sun.COM 	aes_ctx = (common_ctx_t *)soft_aes_ctx->aes_cbc;
294*10500SHai-May.Chao@Sun.COM 
295*10500SHai-May.Chao@Sun.COM 	if (aes_ctx != NULL) {
296*10500SHai-May.Chao@Sun.COM 		bzero(aes_ctx->cc_keysched, aes_ctx->cc_keysched_len);
297*10500SHai-May.Chao@Sun.COM 		kmem_free(aes_ctx->cc_keysched,
298*10500SHai-May.Chao@Sun.COM 		    aes_ctx->cc_keysched_len);
299*10500SHai-May.Chao@Sun.COM 		crypto_free_mode_ctx(aes_ctx);
300*10500SHai-May.Chao@Sun.COM 	} else {
301*10500SHai-May.Chao@Sun.COM 		/* ECB MODE */
302*10500SHai-May.Chao@Sun.COM 		bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
303*10500SHai-May.Chao@Sun.COM 		kmem_free(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
304*10500SHai-May.Chao@Sun.COM 	}
305*10500SHai-May.Chao@Sun.COM 
306*10500SHai-May.Chao@Sun.COM 	kmem_free(soft_aes_ctx, sizeof (soft_aes_ctx_t));
307*10500SHai-May.Chao@Sun.COM 
308*10500SHai-May.Chao@Sun.COM }
309*10500SHai-May.Chao@Sun.COM 
310*10500SHai-May.Chao@Sun.COM #else
311*10500SHai-May.Chao@Sun.COM void
312*10500SHai-May.Chao@Sun.COM fips_aes_free_context(soft_aes_ctx_t *soft_aes_ctx)
313*10500SHai-May.Chao@Sun.COM {
314*10500SHai-May.Chao@Sun.COM 
315*10500SHai-May.Chao@Sun.COM 	common_ctx_t *aes_ctx;
316*10500SHai-May.Chao@Sun.COM 
317*10500SHai-May.Chao@Sun.COM 	aes_ctx = (common_ctx_t *)soft_aes_ctx->aes_cbc;
318*10500SHai-May.Chao@Sun.COM 
319*10500SHai-May.Chao@Sun.COM 	if (aes_ctx != NULL) {
320*10500SHai-May.Chao@Sun.COM 		bzero(aes_ctx->cc_keysched, aes_ctx->cc_keysched_len);
321*10500SHai-May.Chao@Sun.COM 		free(aes_ctx->cc_keysched);
322*10500SHai-May.Chao@Sun.COM 		free(soft_aes_ctx->aes_cbc);
323*10500SHai-May.Chao@Sun.COM 	} else {
324*10500SHai-May.Chao@Sun.COM 		/* ECB MODE */
325*10500SHai-May.Chao@Sun.COM 		bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
326*10500SHai-May.Chao@Sun.COM 		free(soft_aes_ctx->key_sched);
327*10500SHai-May.Chao@Sun.COM 	}
328*10500SHai-May.Chao@Sun.COM 
329*10500SHai-May.Chao@Sun.COM 	free(soft_aes_ctx);
330*10500SHai-May.Chao@Sun.COM 
331*10500SHai-May.Chao@Sun.COM }
332*10500SHai-May.Chao@Sun.COM #endif
333*10500SHai-May.Chao@Sun.COM 
334*10500SHai-May.Chao@Sun.COM /*
335*10500SHai-May.Chao@Sun.COM  * fips_aes_encrypt()
336*10500SHai-May.Chao@Sun.COM  *
337*10500SHai-May.Chao@Sun.COM  * Arguments:
338*10500SHai-May.Chao@Sun.COM  *	soft_aes_ctx:	pointer to AES context
339*10500SHai-May.Chao@Sun.COM  *	in_buf:		pointer to the input data to be encrypted
340*10500SHai-May.Chao@Sun.COM  *	ulDataLen:	length of the input data
341*10500SHai-May.Chao@Sun.COM  *	out_buf:	pointer to the output data after encryption
342*10500SHai-May.Chao@Sun.COM  *	pulEncryptedLen: pointer to the length of the output data
343*10500SHai-May.Chao@Sun.COM  *	mechanism:	CKM_AES_ECB or CKM_AES_CBC
344*10500SHai-May.Chao@Sun.COM  *
345*10500SHai-May.Chao@Sun.COM  * Description:
346*10500SHai-May.Chao@Sun.COM  *	This function calls the corresponding low-level encrypt
347*10500SHai-May.Chao@Sun.COM  *	routine based on the mechanism.
348*10500SHai-May.Chao@Sun.COM  *
349*10500SHai-May.Chao@Sun.COM  */
350*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
351*10500SHai-May.Chao@Sun.COM int
352*10500SHai-May.Chao@Sun.COM fips_aes_encrypt(soft_aes_ctx_t *soft_aes_ctx, uchar_t *in_buf,
353*10500SHai-May.Chao@Sun.COM 	ulong_t ulDataLen, uchar_t *out_buf,
354*10500SHai-May.Chao@Sun.COM 	ulong_t *pulEncryptedLen, aes_mech_type_t mechanism)
355*10500SHai-May.Chao@Sun.COM #else
356*10500SHai-May.Chao@Sun.COM CK_RV
357*10500SHai-May.Chao@Sun.COM fips_aes_encrypt(soft_aes_ctx_t *soft_aes_ctx, CK_BYTE_PTR in_buf,
358*10500SHai-May.Chao@Sun.COM 	CK_ULONG ulDataLen, CK_BYTE_PTR out_buf,
359*10500SHai-May.Chao@Sun.COM 	CK_ULONG_PTR pulEncryptedLen, CK_MECHANISM_TYPE mechanism)
360*10500SHai-May.Chao@Sun.COM #endif
361*10500SHai-May.Chao@Sun.COM {
362*10500SHai-May.Chao@Sun.COM 
363*10500SHai-May.Chao@Sun.COM 	int rc = 0;
364*10500SHai-May.Chao@Sun.COM 	CK_RV rv = CKR_OK;
365*10500SHai-May.Chao@Sun.COM 	ulong_t out_len;
366*10500SHai-May.Chao@Sun.COM 
367*10500SHai-May.Chao@Sun.COM 	/*
368*10500SHai-May.Chao@Sun.COM 	 * AES only takes input length that is a multiple of 16-byte
369*10500SHai-May.Chao@Sun.COM 	 */
370*10500SHai-May.Chao@Sun.COM 	if ((ulDataLen % AES_BLOCK_LEN) != 0)
371*10500SHai-May.Chao@Sun.COM 		return (CKR_DATA_LEN_RANGE);
372*10500SHai-May.Chao@Sun.COM 
373*10500SHai-May.Chao@Sun.COM 	/*
374*10500SHai-May.Chao@Sun.COM 	 * For non-padding mode, the output length will
375*10500SHai-May.Chao@Sun.COM 	 * be same as the input length.
376*10500SHai-May.Chao@Sun.COM 	 */
377*10500SHai-May.Chao@Sun.COM 	out_len = ulDataLen;
378*10500SHai-May.Chao@Sun.COM 
379*10500SHai-May.Chao@Sun.COM 	/*
380*10500SHai-May.Chao@Sun.COM 	 * Begin Encryption now.
381*10500SHai-May.Chao@Sun.COM 	 */
382*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
383*10500SHai-May.Chao@Sun.COM 
384*10500SHai-May.Chao@Sun.COM 	case CKM_AES_ECB:
385*10500SHai-May.Chao@Sun.COM 	{
386*10500SHai-May.Chao@Sun.COM 
387*10500SHai-May.Chao@Sun.COM 		ulong_t i;
388*10500SHai-May.Chao@Sun.COM 		uint8_t *tmp_inbuf;
389*10500SHai-May.Chao@Sun.COM 		uint8_t *tmp_outbuf;
390*10500SHai-May.Chao@Sun.COM 
391*10500SHai-May.Chao@Sun.COM 		for (i = 0; i < out_len; i += AES_BLOCK_LEN) {
392*10500SHai-May.Chao@Sun.COM 			tmp_inbuf = &in_buf[i];
393*10500SHai-May.Chao@Sun.COM 			tmp_outbuf = &out_buf[i];
394*10500SHai-May.Chao@Sun.COM 			/* Crunch one block of data for AES. */
395*10500SHai-May.Chao@Sun.COM 			(void) aes_encrypt_block(soft_aes_ctx->key_sched,
396*10500SHai-May.Chao@Sun.COM 			    tmp_inbuf, tmp_outbuf);
397*10500SHai-May.Chao@Sun.COM 		}
398*10500SHai-May.Chao@Sun.COM 
399*10500SHai-May.Chao@Sun.COM 		*pulEncryptedLen = out_len;
400*10500SHai-May.Chao@Sun.COM 
401*10500SHai-May.Chao@Sun.COM 		break;
402*10500SHai-May.Chao@Sun.COM 	}
403*10500SHai-May.Chao@Sun.COM 
404*10500SHai-May.Chao@Sun.COM 	case CKM_AES_CBC:
405*10500SHai-May.Chao@Sun.COM 	{
406*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
407*10500SHai-May.Chao@Sun.COM 
408*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
409*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
410*10500SHai-May.Chao@Sun.COM 		out.cd_length = out_len;
411*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
412*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = out_len;
413*10500SHai-May.Chao@Sun.COM 
414*10500SHai-May.Chao@Sun.COM 		/* Encrypt multiple blocks of data. */
415*10500SHai-May.Chao@Sun.COM 		rc = aes_encrypt_contiguous_blocks(
416*10500SHai-May.Chao@Sun.COM 		    (aes_ctx_t *)soft_aes_ctx->aes_cbc,
417*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, out_len, &out);
418*10500SHai-May.Chao@Sun.COM 
419*10500SHai-May.Chao@Sun.COM 		if (rc != 0)
420*10500SHai-May.Chao@Sun.COM 			goto encrypt_failed;
421*10500SHai-May.Chao@Sun.COM 
422*10500SHai-May.Chao@Sun.COM 		if (rc == 0) {
423*10500SHai-May.Chao@Sun.COM 			*pulEncryptedLen = out_len;
424*10500SHai-May.Chao@Sun.COM 			break;
425*10500SHai-May.Chao@Sun.COM 		}
426*10500SHai-May.Chao@Sun.COM encrypt_failed:
427*10500SHai-May.Chao@Sun.COM 		*pulEncryptedLen = 0;
428*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
429*10500SHai-May.Chao@Sun.COM 	}
430*10500SHai-May.Chao@Sun.COM 
431*10500SHai-May.Chao@Sun.COM 	case CKM_AES_CTR:
432*10500SHai-May.Chao@Sun.COM 	{
433*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
434*10500SHai-May.Chao@Sun.COM 
435*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
436*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
437*10500SHai-May.Chao@Sun.COM 		out.cd_length = out_len;
438*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
439*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = out_len;
440*10500SHai-May.Chao@Sun.COM 
441*10500SHai-May.Chao@Sun.COM 		rc = aes_encrypt_contiguous_blocks(soft_aes_ctx->aes_cbc,
442*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, out_len, &out);
443*10500SHai-May.Chao@Sun.COM 
444*10500SHai-May.Chao@Sun.COM 		if (rc != 0) {
445*10500SHai-May.Chao@Sun.COM 			*pulEncryptedLen = 0;
446*10500SHai-May.Chao@Sun.COM 			return (CKR_DEVICE_ERROR);
447*10500SHai-May.Chao@Sun.COM 		}
448*10500SHai-May.Chao@Sun.COM 		/*
449*10500SHai-May.Chao@Sun.COM 		 * Since AES counter mode is a stream cipher, we call
450*10500SHai-May.Chao@Sun.COM 		 * aes_counter_final() to pick up any remaining bytes.
451*10500SHai-May.Chao@Sun.COM 		 * It is an internal function that does not destroy
452*10500SHai-May.Chao@Sun.COM 		 * the context like *normal* final routines.
453*10500SHai-May.Chao@Sun.COM 		 */
454*10500SHai-May.Chao@Sun.COM 		if (((aes_ctx_t *)soft_aes_ctx->aes_cbc)->ac_remainder_len
455*10500SHai-May.Chao@Sun.COM 		    > 0) {
456*10500SHai-May.Chao@Sun.COM 			rc = ctr_mode_final(soft_aes_ctx->aes_cbc, &out,
457*10500SHai-May.Chao@Sun.COM 			    aes_encrypt_block);
458*10500SHai-May.Chao@Sun.COM 			if (rc != 0) {
459*10500SHai-May.Chao@Sun.COM 				*pulEncryptedLen = 0;
460*10500SHai-May.Chao@Sun.COM 				return (CKR_DEVICE_ERROR);
461*10500SHai-May.Chao@Sun.COM 			}
462*10500SHai-May.Chao@Sun.COM 		}
463*10500SHai-May.Chao@Sun.COM 
464*10500SHai-May.Chao@Sun.COM 		*pulEncryptedLen = out_len;
465*10500SHai-May.Chao@Sun.COM 		break;
466*10500SHai-May.Chao@Sun.COM 	}
467*10500SHai-May.Chao@Sun.COM 
468*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
469*10500SHai-May.Chao@Sun.COM 	case AES_CCM_MECH_INFO_TYPE:
470*10500SHai-May.Chao@Sun.COM 	{
471*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
472*10500SHai-May.Chao@Sun.COM 		size_t saved_length, length_needed;
473*10500SHai-May.Chao@Sun.COM 		aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
474*10500SHai-May.Chao@Sun.COM 		ccm_ctx_t *ccm_ctx = soft_aes_ctx->aes_cbc;
475*10500SHai-May.Chao@Sun.COM 
476*10500SHai-May.Chao@Sun.COM 		length_needed = ulDataLen + aes_ctx->ac_mac_len;
477*10500SHai-May.Chao@Sun.COM 
478*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
479*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
480*10500SHai-May.Chao@Sun.COM 		out.cd_length = length_needed;
481*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
482*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = length_needed;
483*10500SHai-May.Chao@Sun.COM 
484*10500SHai-May.Chao@Sun.COM 		saved_length = out.cd_length;
485*10500SHai-May.Chao@Sun.COM 
486*10500SHai-May.Chao@Sun.COM 		rc = aes_encrypt_contiguous_blocks(aes_ctx,
487*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, ulDataLen, &out);
488*10500SHai-May.Chao@Sun.COM 
489*10500SHai-May.Chao@Sun.COM 		if (rc != 0) {
490*10500SHai-May.Chao@Sun.COM 			*pulEncryptedLen = 0;
491*10500SHai-May.Chao@Sun.COM 			return (rc);
492*10500SHai-May.Chao@Sun.COM 		}
493*10500SHai-May.Chao@Sun.COM 
494*10500SHai-May.Chao@Sun.COM 		/*
495*10500SHai-May.Chao@Sun.COM 		 * ccm_encrypt_final() will compute the MAC and append
496*10500SHai-May.Chao@Sun.COM 		 * it to existing ciphertext. So, need to adjust the left over
497*10500SHai-May.Chao@Sun.COM 		 * length value accordingly
498*10500SHai-May.Chao@Sun.COM 		 */
499*10500SHai-May.Chao@Sun.COM 
500*10500SHai-May.Chao@Sun.COM 		/* order of following 2 lines MUST not be reversed */
501*10500SHai-May.Chao@Sun.COM 		out.cd_offset = ccm_ctx->ccm_processed_data_len;
502*10500SHai-May.Chao@Sun.COM 		out.cd_length = saved_length - ccm_ctx->ccm_processed_data_len;
503*10500SHai-May.Chao@Sun.COM 
504*10500SHai-May.Chao@Sun.COM 		rc = ccm_encrypt_final((ccm_ctx_t *)aes_ctx, &out,
505*10500SHai-May.Chao@Sun.COM 		    AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
506*10500SHai-May.Chao@Sun.COM 
507*10500SHai-May.Chao@Sun.COM 		if (rc != CRYPTO_SUCCESS) {
508*10500SHai-May.Chao@Sun.COM 			*pulEncryptedLen = 0;
509*10500SHai-May.Chao@Sun.COM 			return (rc);
510*10500SHai-May.Chao@Sun.COM 		}
511*10500SHai-May.Chao@Sun.COM 
512*10500SHai-May.Chao@Sun.COM 		*pulEncryptedLen = length_needed;
513*10500SHai-May.Chao@Sun.COM 		break;
514*10500SHai-May.Chao@Sun.COM 	}
515*10500SHai-May.Chao@Sun.COM 
516*10500SHai-May.Chao@Sun.COM 	case AES_GCM_MECH_INFO_TYPE:
517*10500SHai-May.Chao@Sun.COM 	{
518*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
519*10500SHai-May.Chao@Sun.COM 		size_t saved_length, length_needed;
520*10500SHai-May.Chao@Sun.COM 		aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
521*10500SHai-May.Chao@Sun.COM 		gcm_ctx_t *gcm_ctx = soft_aes_ctx->aes_cbc;
522*10500SHai-May.Chao@Sun.COM 
523*10500SHai-May.Chao@Sun.COM 		/*
524*10500SHai-May.Chao@Sun.COM 		 * Output:
525*10500SHai-May.Chao@Sun.COM 		 * A ciphertext, denoted C, whose bit length is the same as
526*10500SHai-May.Chao@Sun.COM 		 * that of the plaintext.
527*10500SHai-May.Chao@Sun.COM 		 * An authentication tag, or tag, for short, denoted T.
528*10500SHai-May.Chao@Sun.COM 		 */
529*10500SHai-May.Chao@Sun.COM 
530*10500SHai-May.Chao@Sun.COM 		length_needed = ulDataLen + aes_ctx->ac_tag_len;
531*10500SHai-May.Chao@Sun.COM 
532*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
533*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
534*10500SHai-May.Chao@Sun.COM 		out.cd_length = length_needed;
535*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
536*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = length_needed;
537*10500SHai-May.Chao@Sun.COM 
538*10500SHai-May.Chao@Sun.COM 		saved_length = out.cd_length;
539*10500SHai-May.Chao@Sun.COM 
540*10500SHai-May.Chao@Sun.COM 		rc = aes_encrypt_contiguous_blocks(aes_ctx,
541*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, ulDataLen, &out);
542*10500SHai-May.Chao@Sun.COM 
543*10500SHai-May.Chao@Sun.COM 		if (rc != 0) {
544*10500SHai-May.Chao@Sun.COM 			*pulEncryptedLen = 0;
545*10500SHai-May.Chao@Sun.COM 			return (rc);
546*10500SHai-May.Chao@Sun.COM 		}
547*10500SHai-May.Chao@Sun.COM 
548*10500SHai-May.Chao@Sun.COM 		/*
549*10500SHai-May.Chao@Sun.COM 		 * ccm_encrypt_final() will compute the MAC and append
550*10500SHai-May.Chao@Sun.COM 		 * it to existing ciphertext. So, need to adjust the left over
551*10500SHai-May.Chao@Sun.COM 		 * length value accordingly
552*10500SHai-May.Chao@Sun.COM 		 */
553*10500SHai-May.Chao@Sun.COM 
554*10500SHai-May.Chao@Sun.COM 		/* order of following 2 lines MUST not be reversed */
555*10500SHai-May.Chao@Sun.COM 		out.cd_offset = gcm_ctx->gcm_processed_data_len;
556*10500SHai-May.Chao@Sun.COM 		out.cd_length = saved_length - gcm_ctx->gcm_processed_data_len;
557*10500SHai-May.Chao@Sun.COM 
558*10500SHai-May.Chao@Sun.COM 		rc = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, &out,
559*10500SHai-May.Chao@Sun.COM 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
560*10500SHai-May.Chao@Sun.COM 		    aes_xor_block);
561*10500SHai-May.Chao@Sun.COM 
562*10500SHai-May.Chao@Sun.COM 		if (rc != CRYPTO_SUCCESS) {
563*10500SHai-May.Chao@Sun.COM 			*pulEncryptedLen = 0;
564*10500SHai-May.Chao@Sun.COM 			return (rc);
565*10500SHai-May.Chao@Sun.COM 		}
566*10500SHai-May.Chao@Sun.COM 
567*10500SHai-May.Chao@Sun.COM 		*pulEncryptedLen = length_needed;
568*10500SHai-May.Chao@Sun.COM 		break;
569*10500SHai-May.Chao@Sun.COM 	}
570*10500SHai-May.Chao@Sun.COM 
571*10500SHai-May.Chao@Sun.COM 	case AES_GMAC_MECH_INFO_TYPE:
572*10500SHai-May.Chao@Sun.COM 	{
573*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
574*10500SHai-May.Chao@Sun.COM 		size_t length_needed;
575*10500SHai-May.Chao@Sun.COM 		aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
576*10500SHai-May.Chao@Sun.COM 
577*10500SHai-May.Chao@Sun.COM 		length_needed = aes_ctx->ac_tag_len;
578*10500SHai-May.Chao@Sun.COM 
579*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
580*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
581*10500SHai-May.Chao@Sun.COM 		out.cd_length = length_needed;
582*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
583*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = length_needed;
584*10500SHai-May.Chao@Sun.COM 
585*10500SHai-May.Chao@Sun.COM 		rc = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, &out,
586*10500SHai-May.Chao@Sun.COM 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
587*10500SHai-May.Chao@Sun.COM 		    aes_xor_block);
588*10500SHai-May.Chao@Sun.COM 
589*10500SHai-May.Chao@Sun.COM 		if (rc != CRYPTO_SUCCESS) {
590*10500SHai-May.Chao@Sun.COM 			*pulEncryptedLen = 0;
591*10500SHai-May.Chao@Sun.COM 			return (rc);
592*10500SHai-May.Chao@Sun.COM 		}
593*10500SHai-May.Chao@Sun.COM 
594*10500SHai-May.Chao@Sun.COM 		*pulEncryptedLen = length_needed;
595*10500SHai-May.Chao@Sun.COM 		break;
596*10500SHai-May.Chao@Sun.COM 	}
597*10500SHai-May.Chao@Sun.COM #endif /* _KERNEL */
598*10500SHai-May.Chao@Sun.COM 	} /* end switch */
599*10500SHai-May.Chao@Sun.COM 
600*10500SHai-May.Chao@Sun.COM 	return (rv);
601*10500SHai-May.Chao@Sun.COM }
602*10500SHai-May.Chao@Sun.COM 
603*10500SHai-May.Chao@Sun.COM /*
604*10500SHai-May.Chao@Sun.COM  * fips_aes_decrypt()
605*10500SHai-May.Chao@Sun.COM  *
606*10500SHai-May.Chao@Sun.COM  * Arguments:
607*10500SHai-May.Chao@Sun.COM  *	soft_aes_ctx:	pointer to AES context
608*10500SHai-May.Chao@Sun.COM  *	in_buf:	pointer to the input data to be decrypted
609*10500SHai-May.Chao@Sun.COM  *	ulEncryptedLen:	length of the input data
610*10500SHai-May.Chao@Sun.COM  *	out_buf:	pointer to the output data
611*10500SHai-May.Chao@Sun.COM  *	pulDataLen:	pointer to the length of the output data
612*10500SHai-May.Chao@Sun.COM  *	mechanism:	CKM_AES_ECB or CKM_AES_CBC
613*10500SHai-May.Chao@Sun.COM  *
614*10500SHai-May.Chao@Sun.COM  * Description:
615*10500SHai-May.Chao@Sun.COM  *      This function calls the corresponding low-level decrypt
616*10500SHai-May.Chao@Sun.COM  *	function based on the mechanism.
617*10500SHai-May.Chao@Sun.COM  *
618*10500SHai-May.Chao@Sun.COM  */
619*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
620*10500SHai-May.Chao@Sun.COM int
621*10500SHai-May.Chao@Sun.COM fips_aes_decrypt(soft_aes_ctx_t *soft_aes_ctx, uchar_t *in_buf,
622*10500SHai-May.Chao@Sun.COM 	ulong_t ulEncryptedLen, uchar_t *out_buf,
623*10500SHai-May.Chao@Sun.COM 	ulong_t *pulDataLen, aes_mech_type_t mechanism)
624*10500SHai-May.Chao@Sun.COM #else
625*10500SHai-May.Chao@Sun.COM CK_RV
626*10500SHai-May.Chao@Sun.COM fips_aes_decrypt(soft_aes_ctx_t *soft_aes_ctx, CK_BYTE_PTR in_buf,
627*10500SHai-May.Chao@Sun.COM 	CK_ULONG ulEncryptedLen, CK_BYTE_PTR out_buf,
628*10500SHai-May.Chao@Sun.COM 	CK_ULONG_PTR pulDataLen, CK_MECHANISM_TYPE mechanism)
629*10500SHai-May.Chao@Sun.COM #endif
630*10500SHai-May.Chao@Sun.COM {
631*10500SHai-May.Chao@Sun.COM 
632*10500SHai-May.Chao@Sun.COM 	int rc = 0;
633*10500SHai-May.Chao@Sun.COM 	CK_RV rv = CKR_OK;
634*10500SHai-May.Chao@Sun.COM 	ulong_t out_len;
635*10500SHai-May.Chao@Sun.COM 
636*10500SHai-May.Chao@Sun.COM 	/*
637*10500SHai-May.Chao@Sun.COM 	 * AES only takes input length that is a multiple of 16 bytes
638*10500SHai-May.Chao@Sun.COM 	 */
639*10500SHai-May.Chao@Sun.COM 	if ((ulEncryptedLen % AES_BLOCK_LEN) != 0)
640*10500SHai-May.Chao@Sun.COM 		return (CKR_ENCRYPTED_DATA_LEN_RANGE);
641*10500SHai-May.Chao@Sun.COM 
642*10500SHai-May.Chao@Sun.COM 	/*
643*10500SHai-May.Chao@Sun.COM 	 * For non-padding mode, the output length will
644*10500SHai-May.Chao@Sun.COM 	 * be same as the input length.
645*10500SHai-May.Chao@Sun.COM 	 */
646*10500SHai-May.Chao@Sun.COM 	out_len = ulEncryptedLen;
647*10500SHai-May.Chao@Sun.COM 
648*10500SHai-May.Chao@Sun.COM 	/*
649*10500SHai-May.Chao@Sun.COM 	 * Begin Decryption.
650*10500SHai-May.Chao@Sun.COM 	 */
651*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
652*10500SHai-May.Chao@Sun.COM 
653*10500SHai-May.Chao@Sun.COM 	case CKM_AES_ECB:
654*10500SHai-May.Chao@Sun.COM 	{
655*10500SHai-May.Chao@Sun.COM 
656*10500SHai-May.Chao@Sun.COM 		ulong_t i;
657*10500SHai-May.Chao@Sun.COM 		uint8_t *tmp_inbuf;
658*10500SHai-May.Chao@Sun.COM 		uint8_t *tmp_outbuf;
659*10500SHai-May.Chao@Sun.COM 
660*10500SHai-May.Chao@Sun.COM 		for (i = 0; i < out_len; i += AES_BLOCK_LEN) {
661*10500SHai-May.Chao@Sun.COM 			tmp_inbuf = &in_buf[i];
662*10500SHai-May.Chao@Sun.COM 			tmp_outbuf = &out_buf[i];
663*10500SHai-May.Chao@Sun.COM 			/* Crunch one block of data for AES. */
664*10500SHai-May.Chao@Sun.COM 			(void) aes_decrypt_block(soft_aes_ctx->key_sched,
665*10500SHai-May.Chao@Sun.COM 			    tmp_inbuf, tmp_outbuf);
666*10500SHai-May.Chao@Sun.COM 		}
667*10500SHai-May.Chao@Sun.COM 
668*10500SHai-May.Chao@Sun.COM 		*pulDataLen = out_len;
669*10500SHai-May.Chao@Sun.COM 
670*10500SHai-May.Chao@Sun.COM 		break;
671*10500SHai-May.Chao@Sun.COM 	}
672*10500SHai-May.Chao@Sun.COM 
673*10500SHai-May.Chao@Sun.COM 	case CKM_AES_CBC:
674*10500SHai-May.Chao@Sun.COM 	{
675*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
676*10500SHai-May.Chao@Sun.COM 
677*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
678*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
679*10500SHai-May.Chao@Sun.COM 		out.cd_length = out_len;
680*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
681*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = out_len;
682*10500SHai-May.Chao@Sun.COM 
683*10500SHai-May.Chao@Sun.COM 		/* Decrypt multiple blocks of data. */
684*10500SHai-May.Chao@Sun.COM 		rc = aes_decrypt_contiguous_blocks(
685*10500SHai-May.Chao@Sun.COM 		    (aes_ctx_t *)soft_aes_ctx->aes_cbc,
686*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, out_len, &out);
687*10500SHai-May.Chao@Sun.COM 
688*10500SHai-May.Chao@Sun.COM 		if (rc != 0)
689*10500SHai-May.Chao@Sun.COM 			goto decrypt_failed;
690*10500SHai-May.Chao@Sun.COM 
691*10500SHai-May.Chao@Sun.COM 
692*10500SHai-May.Chao@Sun.COM 		*pulDataLen = out_len;
693*10500SHai-May.Chao@Sun.COM 
694*10500SHai-May.Chao@Sun.COM 		if (rc == 0)
695*10500SHai-May.Chao@Sun.COM 			break;
696*10500SHai-May.Chao@Sun.COM decrypt_failed:
697*10500SHai-May.Chao@Sun.COM 		*pulDataLen = 0;
698*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
699*10500SHai-May.Chao@Sun.COM 	}
700*10500SHai-May.Chao@Sun.COM 
701*10500SHai-May.Chao@Sun.COM 	case CKM_AES_CTR:
702*10500SHai-May.Chao@Sun.COM 	{
703*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
704*10500SHai-May.Chao@Sun.COM 
705*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
706*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
707*10500SHai-May.Chao@Sun.COM 		out.cd_length = *pulDataLen;
708*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
709*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = *pulDataLen;
710*10500SHai-May.Chao@Sun.COM 
711*10500SHai-May.Chao@Sun.COM 		rc = aes_decrypt_contiguous_blocks(soft_aes_ctx->aes_cbc,
712*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, out_len, &out);
713*10500SHai-May.Chao@Sun.COM 
714*10500SHai-May.Chao@Sun.COM 		if (rc != 0) {
715*10500SHai-May.Chao@Sun.COM 			*pulDataLen = 0;
716*10500SHai-May.Chao@Sun.COM 			return (CKR_DEVICE_ERROR);
717*10500SHai-May.Chao@Sun.COM 		}
718*10500SHai-May.Chao@Sun.COM 
719*10500SHai-May.Chao@Sun.COM 		/*
720*10500SHai-May.Chao@Sun.COM 		 * Since AES counter mode is a stream cipher, we call
721*10500SHai-May.Chao@Sun.COM 		 * aes_counter_final() to pick up any remaining bytes.
722*10500SHai-May.Chao@Sun.COM 		 * It is an internal function that does not destroy
723*10500SHai-May.Chao@Sun.COM 		 * the context like *normal* final routines.
724*10500SHai-May.Chao@Sun.COM 		 */
725*10500SHai-May.Chao@Sun.COM 		if (((aes_ctx_t *)soft_aes_ctx->aes_cbc)->ac_remainder_len
726*10500SHai-May.Chao@Sun.COM 		    > 0) {
727*10500SHai-May.Chao@Sun.COM 			rc = ctr_mode_final(soft_aes_ctx->aes_cbc, &out,
728*10500SHai-May.Chao@Sun.COM 			    aes_encrypt_block);
729*10500SHai-May.Chao@Sun.COM 
730*10500SHai-May.Chao@Sun.COM 			if (rc == CKR_DATA_LEN_RANGE)
731*10500SHai-May.Chao@Sun.COM 				return (CKR_ENCRYPTED_DATA_LEN_RANGE);
732*10500SHai-May.Chao@Sun.COM 		}
733*10500SHai-May.Chao@Sun.COM 
734*10500SHai-May.Chao@Sun.COM 		*pulDataLen = out_len;
735*10500SHai-May.Chao@Sun.COM 		break;
736*10500SHai-May.Chao@Sun.COM 	}
737*10500SHai-May.Chao@Sun.COM 
738*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
739*10500SHai-May.Chao@Sun.COM 	case AES_CCM_MECH_INFO_TYPE:
740*10500SHai-May.Chao@Sun.COM 	{
741*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
742*10500SHai-May.Chao@Sun.COM 		size_t length_needed;
743*10500SHai-May.Chao@Sun.COM 		aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
744*10500SHai-May.Chao@Sun.COM 		ccm_ctx_t *ccm_ctx = soft_aes_ctx->aes_cbc;
745*10500SHai-May.Chao@Sun.COM 
746*10500SHai-May.Chao@Sun.COM 		length_needed = ulEncryptedLen + ccm_ctx->ccm_mac_len;
747*10500SHai-May.Chao@Sun.COM 
748*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
749*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
750*10500SHai-May.Chao@Sun.COM 		out.cd_length = ulEncryptedLen;
751*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
752*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = ulEncryptedLen;
753*10500SHai-May.Chao@Sun.COM 
754*10500SHai-May.Chao@Sun.COM 		rc = aes_decrypt_contiguous_blocks(aes_ctx,
755*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, length_needed, &out);
756*10500SHai-May.Chao@Sun.COM 
757*10500SHai-May.Chao@Sun.COM 		if (rc != 0) {
758*10500SHai-May.Chao@Sun.COM 			*pulDataLen = 0;
759*10500SHai-May.Chao@Sun.COM 			return (CRYPTO_FAILED);
760*10500SHai-May.Chao@Sun.COM 		}
761*10500SHai-May.Chao@Sun.COM 
762*10500SHai-May.Chao@Sun.COM 		/* order of following 2 lines MUST not be reversed */
763*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
764*10500SHai-May.Chao@Sun.COM 		out.cd_length = ulEncryptedLen;
765*10500SHai-May.Chao@Sun.COM 
766*10500SHai-May.Chao@Sun.COM 		rc = ccm_decrypt_final((ccm_ctx_t *)aes_ctx, &out,
767*10500SHai-May.Chao@Sun.COM 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
768*10500SHai-May.Chao@Sun.COM 		    aes_xor_block);
769*10500SHai-May.Chao@Sun.COM 
770*10500SHai-May.Chao@Sun.COM 		if (rc != CRYPTO_SUCCESS) {
771*10500SHai-May.Chao@Sun.COM 			*pulDataLen = 0;
772*10500SHai-May.Chao@Sun.COM 			return (CRYPTO_FAILED);
773*10500SHai-May.Chao@Sun.COM 		}
774*10500SHai-May.Chao@Sun.COM 
775*10500SHai-May.Chao@Sun.COM 		*pulDataLen = ulEncryptedLen;
776*10500SHai-May.Chao@Sun.COM 
777*10500SHai-May.Chao@Sun.COM 		break;
778*10500SHai-May.Chao@Sun.COM 	}
779*10500SHai-May.Chao@Sun.COM 
780*10500SHai-May.Chao@Sun.COM 	case AES_GCM_MECH_INFO_TYPE:
781*10500SHai-May.Chao@Sun.COM 	{
782*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
783*10500SHai-May.Chao@Sun.COM 		size_t length_needed;
784*10500SHai-May.Chao@Sun.COM 		aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
785*10500SHai-May.Chao@Sun.COM 
786*10500SHai-May.Chao@Sun.COM 		length_needed = ulEncryptedLen + aes_ctx->ac_tag_len;
787*10500SHai-May.Chao@Sun.COM 
788*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
789*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
790*10500SHai-May.Chao@Sun.COM 		out.cd_length = ulEncryptedLen;
791*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)out_buf;
792*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = ulEncryptedLen;
793*10500SHai-May.Chao@Sun.COM 
794*10500SHai-May.Chao@Sun.COM 		rc = aes_decrypt_contiguous_blocks(aes_ctx,
795*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, length_needed, &out);
796*10500SHai-May.Chao@Sun.COM 
797*10500SHai-May.Chao@Sun.COM 		if (rc != 0) {
798*10500SHai-May.Chao@Sun.COM 			*pulDataLen = 0;
799*10500SHai-May.Chao@Sun.COM 			return (CRYPTO_FAILED);
800*10500SHai-May.Chao@Sun.COM 		}
801*10500SHai-May.Chao@Sun.COM 
802*10500SHai-May.Chao@Sun.COM 		/* order of following 2 lines MUST not be reversed */
803*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
804*10500SHai-May.Chao@Sun.COM 		out.cd_length = aes_ctx->ac_tag_len;
805*10500SHai-May.Chao@Sun.COM 
806*10500SHai-May.Chao@Sun.COM 		rc = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, &out,
807*10500SHai-May.Chao@Sun.COM 		    AES_BLOCK_LEN, aes_encrypt_block,
808*10500SHai-May.Chao@Sun.COM 		    aes_xor_block);
809*10500SHai-May.Chao@Sun.COM 
810*10500SHai-May.Chao@Sun.COM 		if (rc != CRYPTO_SUCCESS) {
811*10500SHai-May.Chao@Sun.COM 			*pulDataLen = 0;
812*10500SHai-May.Chao@Sun.COM 			return (CRYPTO_FAILED);
813*10500SHai-May.Chao@Sun.COM 		}
814*10500SHai-May.Chao@Sun.COM 
815*10500SHai-May.Chao@Sun.COM 		*pulDataLen = ulEncryptedLen;
816*10500SHai-May.Chao@Sun.COM 
817*10500SHai-May.Chao@Sun.COM 		break;
818*10500SHai-May.Chao@Sun.COM 	}
819*10500SHai-May.Chao@Sun.COM 
820*10500SHai-May.Chao@Sun.COM 	case AES_GMAC_MECH_INFO_TYPE:
821*10500SHai-May.Chao@Sun.COM 	{
822*10500SHai-May.Chao@Sun.COM 		crypto_data_t out;
823*10500SHai-May.Chao@Sun.COM 		size_t length_needed;
824*10500SHai-May.Chao@Sun.COM 		aes_ctx_t *aes_ctx = soft_aes_ctx->aes_cbc;
825*10500SHai-May.Chao@Sun.COM 
826*10500SHai-May.Chao@Sun.COM 		length_needed = aes_ctx->ac_tag_len;
827*10500SHai-May.Chao@Sun.COM 
828*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
829*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
830*10500SHai-May.Chao@Sun.COM 		out.cd_length = 0;
831*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)NULL;
832*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = 0;
833*10500SHai-May.Chao@Sun.COM 
834*10500SHai-May.Chao@Sun.COM 		rc = aes_decrypt_contiguous_blocks(aes_ctx,
835*10500SHai-May.Chao@Sun.COM 		    (char *)in_buf, length_needed, &out);
836*10500SHai-May.Chao@Sun.COM 
837*10500SHai-May.Chao@Sun.COM 		if (rc != 0) {
838*10500SHai-May.Chao@Sun.COM 			*pulDataLen = 0;
839*10500SHai-May.Chao@Sun.COM 			return (CRYPTO_FAILED);
840*10500SHai-May.Chao@Sun.COM 		}
841*10500SHai-May.Chao@Sun.COM 
842*10500SHai-May.Chao@Sun.COM 		/* order of following 2 lines MUST not be reversed */
843*10500SHai-May.Chao@Sun.COM 		out.cd_format = CRYPTO_DATA_RAW;
844*10500SHai-May.Chao@Sun.COM 		out.cd_offset = 0;
845*10500SHai-May.Chao@Sun.COM 		out.cd_length = 0;
846*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_base = (char *)NULL;
847*10500SHai-May.Chao@Sun.COM 		out.cd_raw.iov_len = 0;
848*10500SHai-May.Chao@Sun.COM 
849*10500SHai-May.Chao@Sun.COM 		rc = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, &out,
850*10500SHai-May.Chao@Sun.COM 		    AES_BLOCK_LEN, aes_encrypt_block,
851*10500SHai-May.Chao@Sun.COM 		    aes_xor_block);
852*10500SHai-May.Chao@Sun.COM 
853*10500SHai-May.Chao@Sun.COM 		if (rc != CRYPTO_SUCCESS) {
854*10500SHai-May.Chao@Sun.COM 			*pulDataLen = 0;
855*10500SHai-May.Chao@Sun.COM 			return (CRYPTO_FAILED);
856*10500SHai-May.Chao@Sun.COM 		}
857*10500SHai-May.Chao@Sun.COM 
858*10500SHai-May.Chao@Sun.COM 		*pulDataLen = 0;
859*10500SHai-May.Chao@Sun.COM 
860*10500SHai-May.Chao@Sun.COM 		break;
861*10500SHai-May.Chao@Sun.COM 	}
862*10500SHai-May.Chao@Sun.COM #endif
863*10500SHai-May.Chao@Sun.COM 	} /* end switch */
864*10500SHai-May.Chao@Sun.COM 
865*10500SHai-May.Chao@Sun.COM 	return (rv);
866*10500SHai-May.Chao@Sun.COM }
867*10500SHai-May.Chao@Sun.COM 
868*10500SHai-May.Chao@Sun.COM /* AES self-test for 128-bit, 192-bit, or 256-bit key sizes */
869*10500SHai-May.Chao@Sun.COM int
870*10500SHai-May.Chao@Sun.COM fips_aes_post(int aes_key_size)
871*10500SHai-May.Chao@Sun.COM {
872*10500SHai-May.Chao@Sun.COM 	/* AES Known Key (up to 256-bits). */
873*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_known_key[] = {
874*10500SHai-May.Chao@Sun.COM 		"AES-128 RIJNDAELLEADNJIR 821-SEA"
875*10500SHai-May.Chao@Sun.COM 	};
876*10500SHai-May.Chao@Sun.COM 
877*10500SHai-May.Chao@Sun.COM 	/* AES-CBC Known Initialization Vector (128-bits). */
878*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_cbc_known_initialization_vector[] =
879*10500SHai-May.Chao@Sun.COM 		{ "SecurityytiruceS" };
880*10500SHai-May.Chao@Sun.COM 
881*10500SHai-May.Chao@Sun.COM 	/* AES Known Plaintext (128-bits). (blocksize is 128-bits) */
882*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_known_plaintext[] = { "Sun Open Solaris" };
883*10500SHai-May.Chao@Sun.COM 
884*10500SHai-May.Chao@Sun.COM 	/* AES Known Ciphertext (128-bit key). */
885*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ecb128_known_ciphertext[] = {
886*10500SHai-May.Chao@Sun.COM 		0xcc, 0xd1, 0xd0, 0xf3, 0xfd, 0x44, 0xb1, 0x4d,
887*10500SHai-May.Chao@Sun.COM 		0xfe, 0x33, 0x20, 0x72, 0x3c, 0xf3, 0x4d, 0x27
888*10500SHai-May.Chao@Sun.COM 	};
889*10500SHai-May.Chao@Sun.COM 
890*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_cbc128_known_ciphertext[]  = {
891*10500SHai-May.Chao@Sun.COM 		0x59, 0x34, 0x55, 0xd1, 0x89, 0x9b, 0xf4, 0xa5,
892*10500SHai-May.Chao@Sun.COM 		0x16, 0x2c, 0x4c, 0x14, 0xd3, 0xe2, 0xe5, 0xed
893*10500SHai-May.Chao@Sun.COM 	};
894*10500SHai-May.Chao@Sun.COM 
895*10500SHai-May.Chao@Sun.COM 	/* AES Known Ciphertext (192-bit key). */
896*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ecb192_known_ciphertext[] = {
897*10500SHai-May.Chao@Sun.COM 		0xa3, 0x78, 0x10, 0x44, 0xd8, 0xee, 0x8a, 0x98,
898*10500SHai-May.Chao@Sun.COM 		0x41, 0xa4, 0xeb, 0x96, 0x57, 0xd8, 0xa0, 0xc5
899*10500SHai-May.Chao@Sun.COM 	};
900*10500SHai-May.Chao@Sun.COM 
901*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_cbc192_known_ciphertext[]  = {
902*10500SHai-May.Chao@Sun.COM 		0x22, 0x9c, 0x68, 0xc6, 0x86, 0x68, 0xcc, 0x6a,
903*10500SHai-May.Chao@Sun.COM 		0x56, 0x2c, 0xb8, 0xe0, 0x16, 0x4e, 0x8b, 0x78
904*10500SHai-May.Chao@Sun.COM 	};
905*10500SHai-May.Chao@Sun.COM 
906*10500SHai-May.Chao@Sun.COM 	/* AES Known Ciphertext (256-bit key). */
907*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ecb256_known_ciphertext[] = {
908*10500SHai-May.Chao@Sun.COM 		0xe4, 0x65, 0x92, 0x7f, 0xd0, 0xdd, 0x59, 0x49,
909*10500SHai-May.Chao@Sun.COM 		0x79, 0xc3, 0xac, 0x96, 0x30, 0xad, 0x32, 0x52
910*10500SHai-May.Chao@Sun.COM 	};
911*10500SHai-May.Chao@Sun.COM 
912*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_cbc256_known_ciphertext[]  = {
913*10500SHai-May.Chao@Sun.COM 		0xd9, 0x44, 0x43, 0xe8, 0xdb, 0x60, 0x6b, 0xde,
914*10500SHai-May.Chao@Sun.COM 		0xc2, 0x84, 0xbf, 0xb9, 0xaf, 0x43, 0x3f, 0x51
915*10500SHai-May.Chao@Sun.COM 	};
916*10500SHai-May.Chao@Sun.COM 
917*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ecb_known_ciphertext =
918*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
919*10500SHai-May.Chao@Sun.COM 	    aes_ecb128_known_ciphertext :
920*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
921*10500SHai-May.Chao@Sun.COM 	    aes_ecb192_known_ciphertext :
922*10500SHai-May.Chao@Sun.COM 	    aes_ecb256_known_ciphertext;
923*10500SHai-May.Chao@Sun.COM 
924*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_cbc_known_ciphertext =
925*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
926*10500SHai-May.Chao@Sun.COM 	    aes_cbc128_known_ciphertext :
927*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
928*10500SHai-May.Chao@Sun.COM 	    aes_cbc192_known_ciphertext :
929*10500SHai-May.Chao@Sun.COM 	    aes_cbc256_known_ciphertext;
930*10500SHai-May.Chao@Sun.COM 
931*10500SHai-May.Chao@Sun.COM 	/* AES-CTR Known Key (128-bits). */
932*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr128_known_key[] = {
933*10500SHai-May.Chao@Sun.COM 		0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
934*10500SHai-May.Chao@Sun.COM 		0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
935*10500SHai-May.Chao@Sun.COM 	};
936*10500SHai-May.Chao@Sun.COM 
937*10500SHai-May.Chao@Sun.COM 	/* AES-CTR Known Key (192-bits). */
938*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr192_known_key[] = {
939*10500SHai-May.Chao@Sun.COM 		0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
940*10500SHai-May.Chao@Sun.COM 		0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
941*10500SHai-May.Chao@Sun.COM 		0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
942*10500SHai-May.Chao@Sun.COM 	};
943*10500SHai-May.Chao@Sun.COM 
944*10500SHai-May.Chao@Sun.COM 	/* AES-CTR Known Key (256-bits). */
945*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr256_known_key[] = {
946*10500SHai-May.Chao@Sun.COM 		0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
947*10500SHai-May.Chao@Sun.COM 		0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
948*10500SHai-May.Chao@Sun.COM 		0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
949*10500SHai-May.Chao@Sun.COM 		0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
950*10500SHai-May.Chao@Sun.COM 	};
951*10500SHai-May.Chao@Sun.COM 
952*10500SHai-May.Chao@Sun.COM 	/* AES-CTR Known Initialization Counter (128-bits). */
953*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr_known_counter[] = {
954*10500SHai-May.Chao@Sun.COM 		0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
955*10500SHai-May.Chao@Sun.COM 		0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
956*10500SHai-May.Chao@Sun.COM 	};
957*10500SHai-May.Chao@Sun.COM 
958*10500SHai-May.Chao@Sun.COM 	/* AES-CTR Known Plaintext (128-bits). */
959*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr_known_plaintext[] = {
960*10500SHai-May.Chao@Sun.COM 		0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
961*10500SHai-May.Chao@Sun.COM 		0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
962*10500SHai-May.Chao@Sun.COM 	};
963*10500SHai-May.Chao@Sun.COM 
964*10500SHai-May.Chao@Sun.COM 	/* AES-CTR Known Ciphertext. */
965*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr128_known_ciphertext[] = {
966*10500SHai-May.Chao@Sun.COM 		0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
967*10500SHai-May.Chao@Sun.COM 		0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce
968*10500SHai-May.Chao@Sun.COM 	};
969*10500SHai-May.Chao@Sun.COM 
970*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr192_known_ciphertext[]  = {
971*10500SHai-May.Chao@Sun.COM 		0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2,
972*10500SHai-May.Chao@Sun.COM 		0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b
973*10500SHai-May.Chao@Sun.COM 	};
974*10500SHai-May.Chao@Sun.COM 
975*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ctr256_known_ciphertext[]  = {
976*10500SHai-May.Chao@Sun.COM 		0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
977*10500SHai-May.Chao@Sun.COM 		0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28
978*10500SHai-May.Chao@Sun.COM 	};
979*10500SHai-May.Chao@Sun.COM 
980*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ctr_known_ciphertext =
981*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
982*10500SHai-May.Chao@Sun.COM 	    aes_ctr128_known_ciphertext :
983*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
984*10500SHai-May.Chao@Sun.COM 	    aes_ctr192_known_ciphertext :
985*10500SHai-May.Chao@Sun.COM 	    aes_ctr256_known_ciphertext;
986*10500SHai-May.Chao@Sun.COM 
987*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ctr_known_key =
988*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
989*10500SHai-May.Chao@Sun.COM 	    aes_ctr128_known_key :
990*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
991*10500SHai-May.Chao@Sun.COM 	    aes_ctr192_known_key :
992*10500SHai-May.Chao@Sun.COM 	    aes_ctr256_known_key;
993*10500SHai-May.Chao@Sun.COM 
994*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
995*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Key (128-bits). */
996*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm128_known_key[] = {
997*10500SHai-May.Chao@Sun.COM 		0x06, 0xfd, 0xf0, 0x83, 0xb5, 0xcb, 0x3b, 0xc7,
998*10500SHai-May.Chao@Sun.COM 		0xc0, 0x6d, 0x4d, 0xe5, 0xa6, 0x34, 0xc6, 0x50
999*10500SHai-May.Chao@Sun.COM 	};
1000*10500SHai-May.Chao@Sun.COM 
1001*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Key (192-bits). */
1002*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm192_known_key[] = {
1003*10500SHai-May.Chao@Sun.COM 		0xde, 0x91, 0x08, 0x63, 0xbe, 0x59, 0xb8, 0x7a,
1004*10500SHai-May.Chao@Sun.COM 		0x45, 0x9b, 0xa6, 0xce, 0x2d, 0x7e, 0x71, 0x56,
1005*10500SHai-May.Chao@Sun.COM 		0x1c, 0x5c, 0x15, 0xea, 0x1b, 0x6b, 0x05, 0x06
1006*10500SHai-May.Chao@Sun.COM 	};
1007*10500SHai-May.Chao@Sun.COM 
1008*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Key (256-bits). */
1009*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm256_known_key[] = {
1010*10500SHai-May.Chao@Sun.COM 		0x84, 0x9c, 0x1d, 0xeb, 0x80, 0xf8, 0x5b, 0x7d,
1011*10500SHai-May.Chao@Sun.COM 		0x25, 0x33, 0x64, 0x75, 0x4b, 0xdc, 0x5d, 0xf0,
1012*10500SHai-May.Chao@Sun.COM 		0xe8, 0x1c, 0x98, 0x8a, 0x78, 0x8f, 0x15, 0xd1,
1013*10500SHai-May.Chao@Sun.COM 		0xa2, 0x52, 0x49, 0xfa, 0x18, 0x5e, 0x1f, 0xd3
1014*10500SHai-May.Chao@Sun.COM 	};
1015*10500SHai-May.Chao@Sun.COM 
1016*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Nonce Nlen = 7 bytes (for 128-bits key). */
1017*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm128_known_nonce[] = {
1018*10500SHai-May.Chao@Sun.COM 		0xfd, 0xe2, 0xd5, 0x4c, 0x65, 0x4e, 0xe4
1019*10500SHai-May.Chao@Sun.COM 	};
1020*10500SHai-May.Chao@Sun.COM 
1021*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Nonce Nlen = 7 bytes (192-bits). */
1022*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm192_known_nonce[] = {
1023*10500SHai-May.Chao@Sun.COM 		0xcf, 0xb3, 0x48, 0xfa, 0x04, 0x36, 0xa2
1024*10500SHai-May.Chao@Sun.COM 	};
1025*10500SHai-May.Chao@Sun.COM 
1026*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Nonce Nlen = 7 bytes (256-bits). */
1027*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm256_known_nonce[] = {
1028*10500SHai-May.Chao@Sun.COM 		0x75, 0xa5, 0x5b, 0x58, 0x33, 0x9d, 0x1c
1029*10500SHai-May.Chao@Sun.COM 	};
1030*10500SHai-May.Chao@Sun.COM 
1031*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Adata Alen = 30 bytes (128-bits). */
1032*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm128_known_adata[] = {
1033*10500SHai-May.Chao@Sun.COM 		0xe0, 0xdf, 0xfc, 0x4c, 0x92, 0x90, 0xd8, 0x28,
1034*10500SHai-May.Chao@Sun.COM 		0xef, 0xe7, 0xc6, 0xbe, 0x4a, 0xbc, 0xd1, 0x3e,
1035*10500SHai-May.Chao@Sun.COM 		0x23, 0x61, 0x92, 0x2f, 0xfa, 0x27, 0xa4, 0x0e,
1036*10500SHai-May.Chao@Sun.COM 		0x61, 0x24, 0x58, 0x38, 0x55, 0x33
1037*10500SHai-May.Chao@Sun.COM 	};
1038*10500SHai-May.Chao@Sun.COM 
1039*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Adata Alen = 30 bytes (192-bits). */
1040*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm192_known_adata[] = {
1041*10500SHai-May.Chao@Sun.COM 		0x4c, 0x5b, 0x4f, 0xfe, 0x80, 0xba, 0x7a, 0xe5,
1042*10500SHai-May.Chao@Sun.COM 		0xd3, 0xe8, 0xbc, 0xf6, 0x55, 0x83, 0xcf, 0x58,
1043*10500SHai-May.Chao@Sun.COM 		0xa2, 0x82, 0x59, 0x65, 0xba, 0xbd, 0x63, 0x53,
1044*10500SHai-May.Chao@Sun.COM 		0x0c, 0xb0, 0x0c, 0x14, 0xd4, 0x7b
1045*10500SHai-May.Chao@Sun.COM 	};
1046*10500SHai-May.Chao@Sun.COM 
1047*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Adata Alen = 30 bytes (256-bits). */
1048*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm256_known_adata[] = {
1049*10500SHai-May.Chao@Sun.COM 		0x27, 0xb7, 0xec, 0x91, 0x08, 0xe1, 0x4d, 0x12,
1050*10500SHai-May.Chao@Sun.COM 		0xd3, 0xd3, 0xb8, 0x49, 0x09, 0xde, 0xd0, 0x9a,
1051*10500SHai-May.Chao@Sun.COM 		0x8f, 0x23, 0xbf, 0xd6, 0x02, 0x9b, 0x2a, 0x5e,
1052*10500SHai-May.Chao@Sun.COM 		0x4a, 0x5a, 0x63, 0x8c, 0x72, 0x14
1053*10500SHai-May.Chao@Sun.COM 	};
1054*10500SHai-May.Chao@Sun.COM 
1055*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Payload Plen = 32 bytes (128-bits). */
1056*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm128_known_plaintext[] = {
1057*10500SHai-May.Chao@Sun.COM 		0x77, 0xca, 0xdf, 0xa5, 0xb1, 0x23, 0xfe, 0x07,
1058*10500SHai-May.Chao@Sun.COM 		0x8d, 0xca, 0x94, 0xe2, 0x66, 0x3f, 0x73, 0xd0,
1059*10500SHai-May.Chao@Sun.COM 		0x3f, 0x0b, 0x4d, 0xc8, 0x05, 0xf6, 0x1c, 0xef,
1060*10500SHai-May.Chao@Sun.COM 		0x13, 0x79, 0xc0, 0xb1, 0xfc, 0x76, 0xea, 0x11
1061*10500SHai-May.Chao@Sun.COM 	};
1062*10500SHai-May.Chao@Sun.COM 
1063*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Payload Plen = 32 bytes (192-bits). */
1064*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm192_known_plaintext[] = {
1065*10500SHai-May.Chao@Sun.COM 		0xf9, 0x8a, 0x58, 0x59, 0x44, 0x2d, 0x2a, 0xf9,
1066*10500SHai-May.Chao@Sun.COM 		0x65, 0x03, 0x36, 0x6d, 0x8a, 0x58, 0x29, 0xf9,
1067*10500SHai-May.Chao@Sun.COM 		0xef, 0x47, 0x44, 0x30, 0xf4, 0x7e, 0x0d, 0xcd,
1068*10500SHai-May.Chao@Sun.COM 		0x73, 0x41, 0x45, 0xdf, 0x50, 0xb2, 0x1b, 0x29
1069*10500SHai-May.Chao@Sun.COM 	};
1070*10500SHai-May.Chao@Sun.COM 
1071*10500SHai-May.Chao@Sun.COM 	/* AES-CCM Known Payload Plen = 32 bytes (256-bits). */
1072*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm256_known_plaintext[] = {
1073*10500SHai-May.Chao@Sun.COM 		0x25, 0x28, 0x3f, 0x05, 0x41, 0xd6, 0x66, 0x3b,
1074*10500SHai-May.Chao@Sun.COM 		0xdb, 0x8f, 0xe9, 0xe7, 0x7b, 0x06, 0xc0, 0xee,
1075*10500SHai-May.Chao@Sun.COM 		0xfe, 0xf6, 0xc9, 0x8b, 0x45, 0x08, 0x18, 0x4e,
1076*10500SHai-May.Chao@Sun.COM 		0x2e, 0xf7, 0x8e, 0x64, 0xc3, 0xf2, 0xad, 0x18
1077*10500SHai-May.Chao@Sun.COM 	};
1078*10500SHai-May.Chao@Sun.COM 
1079*10500SHai-May.Chao@Sun.COM 	/*
1080*10500SHai-May.Chao@Sun.COM 	 * AES-CCM Known Ciphertext
1081*10500SHai-May.Chao@Sun.COM 	 * Clen = 32 bytes + Tlen = 16 bytes (128-bits).
1082*10500SHai-May.Chao@Sun.COM 	 */
1083*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm128_known_ciphertext[] = {
1084*10500SHai-May.Chao@Sun.COM 		0x33, 0x50, 0x58, 0xbb, 0x5f, 0x13, 0x8d, 0xc9,
1085*10500SHai-May.Chao@Sun.COM 		0x5b, 0x2c, 0xa4, 0x50, 0x1d, 0x7f, 0xd4, 0xa5,
1086*10500SHai-May.Chao@Sun.COM 		0xb9, 0xb8, 0x71, 0x83, 0x8f, 0x82, 0x27, 0x5f,
1087*10500SHai-May.Chao@Sun.COM 		0x75, 0x3e, 0x30, 0xf9, 0x9d, 0xad, 0xc2, 0xe9,
1088*10500SHai-May.Chao@Sun.COM 		0x66, 0x93, 0x56, 0x98, 0x01, 0x1e, 0x3c, 0x11,
1089*10500SHai-May.Chao@Sun.COM 		0x74, 0xdb, 0x9b, 0xca, 0xce, 0x0f, 0xc3, 0x35
1090*10500SHai-May.Chao@Sun.COM 	};
1091*10500SHai-May.Chao@Sun.COM 
1092*10500SHai-May.Chao@Sun.COM 	/*
1093*10500SHai-May.Chao@Sun.COM 	 * AES-CCM Known Ciphertext
1094*10500SHai-May.Chao@Sun.COM 	 * Clen = 32 bytes + Tlen = 16 bytes (192-bits).
1095*10500SHai-May.Chao@Sun.COM 	 */
1096*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm192_known_ciphertext[] = {
1097*10500SHai-May.Chao@Sun.COM 		0xa7, 0x40, 0xd0, 0x25, 0xbd, 0x3e, 0x8f, 0xd5,
1098*10500SHai-May.Chao@Sun.COM 		0x28, 0x3e, 0xee, 0xaa, 0xf9, 0xa7, 0xfc, 0xf2,
1099*10500SHai-May.Chao@Sun.COM 		0x33, 0xf6, 0x69, 0xb8, 0xdc, 0x9c, 0x74, 0xb1,
1100*10500SHai-May.Chao@Sun.COM 		0x46, 0xf4, 0xd6, 0xcc, 0x0a, 0x16, 0x12, 0x0c,
1101*10500SHai-May.Chao@Sun.COM 		0x7c, 0x3c, 0x43, 0x76, 0x94, 0xf6, 0x9a, 0x14,
1102*10500SHai-May.Chao@Sun.COM 		0xa0, 0xfb, 0xab, 0x9c, 0x2c, 0xd3, 0x5c, 0x09
1103*10500SHai-May.Chao@Sun.COM 	};
1104*10500SHai-May.Chao@Sun.COM 
1105*10500SHai-May.Chao@Sun.COM 	/*
1106*10500SHai-May.Chao@Sun.COM 	 * AES-CCM Known Ciphertext
1107*10500SHai-May.Chao@Sun.COM 	 * Clen = 32 bytes + Tlen = 16 bytes (256-bits).
1108*10500SHai-May.Chao@Sun.COM 	 */
1109*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_ccm256_known_ciphertext[] = {
1110*10500SHai-May.Chao@Sun.COM 		0xf6, 0x4d, 0x24, 0x69, 0x0e, 0xde, 0xc9, 0xc0,
1111*10500SHai-May.Chao@Sun.COM 		0x1e, 0x42, 0xc0, 0x78, 0x29, 0xcf, 0xdb, 0xfe,
1112*10500SHai-May.Chao@Sun.COM 		0xab, 0x52, 0x9a, 0xb1, 0x07, 0xe4, 0xac, 0xdf,
1113*10500SHai-May.Chao@Sun.COM 		0x48, 0x46, 0x46, 0xc1, 0xe2, 0xb2, 0x0f, 0x36,
1114*10500SHai-May.Chao@Sun.COM 		0x5f, 0xeb, 0x44, 0xcf, 0xa8, 0x80, 0x80, 0x23,
1115*10500SHai-May.Chao@Sun.COM 		0xc9, 0xee, 0xc7, 0x56, 0x24, 0x63, 0x6e, 0x7e
1116*10500SHai-May.Chao@Sun.COM 	};
1117*10500SHai-May.Chao@Sun.COM 
1118*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ccm_known_plaintext =
1119*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1120*10500SHai-May.Chao@Sun.COM 	    aes_ccm128_known_plaintext :
1121*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1122*10500SHai-May.Chao@Sun.COM 	    aes_ccm192_known_plaintext :
1123*10500SHai-May.Chao@Sun.COM 	    aes_ccm256_known_plaintext;
1124*10500SHai-May.Chao@Sun.COM 
1125*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ccm_known_ciphertext =
1126*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1127*10500SHai-May.Chao@Sun.COM 	    aes_ccm128_known_ciphertext :
1128*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1129*10500SHai-May.Chao@Sun.COM 	    aes_ccm192_known_ciphertext :
1130*10500SHai-May.Chao@Sun.COM 	    aes_ccm256_known_ciphertext;
1131*10500SHai-May.Chao@Sun.COM 
1132*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ccm_known_key =
1133*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1134*10500SHai-May.Chao@Sun.COM 	    aes_ccm128_known_key :
1135*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1136*10500SHai-May.Chao@Sun.COM 	    aes_ccm192_known_key :
1137*10500SHai-May.Chao@Sun.COM 	    aes_ccm256_known_key;
1138*10500SHai-May.Chao@Sun.COM 
1139*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ccm_known_adata =
1140*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1141*10500SHai-May.Chao@Sun.COM 	    aes_ccm128_known_adata :
1142*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1143*10500SHai-May.Chao@Sun.COM 	    aes_ccm192_known_adata :
1144*10500SHai-May.Chao@Sun.COM 	    aes_ccm256_known_adata;
1145*10500SHai-May.Chao@Sun.COM 
1146*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_ccm_known_nonce =
1147*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1148*10500SHai-May.Chao@Sun.COM 	    aes_ccm128_known_nonce :
1149*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1150*10500SHai-May.Chao@Sun.COM 	    aes_ccm192_known_nonce :
1151*10500SHai-May.Chao@Sun.COM 	    aes_ccm256_known_nonce;
1152*10500SHai-May.Chao@Sun.COM 
1153*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Key (128-bits). */
1154*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm128_known_key[] = {
1155*10500SHai-May.Chao@Sun.COM 		0x7d, 0xf9, 0x9c, 0xdf, 0x7d, 0x00, 0xd9, 0xea,
1156*10500SHai-May.Chao@Sun.COM 		0xd3, 0x85, 0x17, 0x1b, 0x29, 0xae, 0xcf, 0xbc
1157*10500SHai-May.Chao@Sun.COM 	};
1158*10500SHai-May.Chao@Sun.COM 
1159*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Key (192-bits). */
1160*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm192_known_key[] = {
1161*10500SHai-May.Chao@Sun.COM 		0x85, 0xf4, 0x34, 0x7a, 0xf5, 0x98, 0x1e, 0xd9,
1162*10500SHai-May.Chao@Sun.COM 		0x89, 0x85, 0x98, 0x1a, 0x53, 0xfc, 0xc5, 0xbf,
1163*10500SHai-May.Chao@Sun.COM 		0x53, 0x6c, 0x91, 0x4b, 0x18, 0x3c, 0xe8, 0x12
1164*10500SHai-May.Chao@Sun.COM 	};
1165*10500SHai-May.Chao@Sun.COM 
1166*10500SHai-May.Chao@Sun.COM 	/* AES-GCM	 Known Key (256-bits). */
1167*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm256_known_key[] = {
1168*10500SHai-May.Chao@Sun.COM 		0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92,
1169*10500SHai-May.Chao@Sun.COM 		0x1c, 0x04, 0x65, 0x66, 0x5f, 0x8a, 0xe6, 0xd1,
1170*10500SHai-May.Chao@Sun.COM 		0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69,
1171*10500SHai-May.Chao@Sun.COM 		0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f
1172*10500SHai-May.Chao@Sun.COM 	};
1173*10500SHai-May.Chao@Sun.COM 
1174*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Initialization Vector (128-bits). */
1175*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm128_known_iv[] = {
1176*10500SHai-May.Chao@Sun.COM 		0x27, 0x4c, 0x4e, 0xae, 0xfe, 0xef, 0xae, 0x26,
1177*10500SHai-May.Chao@Sun.COM 		0x80, 0xb0, 0xef, 0xd5
1178*10500SHai-May.Chao@Sun.COM 	};
1179*10500SHai-May.Chao@Sun.COM 
1180*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Initialization Vector (192-bits). */
1181*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm192_known_iv[] = {
1182*10500SHai-May.Chao@Sun.COM 		0xd4, 0xfb, 0x33, 0xc6, 0x51, 0xc8, 0x86, 0xff,
1183*10500SHai-May.Chao@Sun.COM 		0x28, 0x80, 0xef, 0x96
1184*10500SHai-May.Chao@Sun.COM 	};
1185*10500SHai-May.Chao@Sun.COM 
1186*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Initialization Vector (256-bits). */
1187*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm256_known_iv[] = {
1188*10500SHai-May.Chao@Sun.COM 		0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0,
1189*10500SHai-May.Chao@Sun.COM 		0xee, 0xd0, 0x66, 0x84
1190*10500SHai-May.Chao@Sun.COM 	};
1191*10500SHai-May.Chao@Sun.COM 
1192*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known AAD Alen = 16 bytes (128-bits). */
1193*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm128_known_adata[] = {
1194*10500SHai-May.Chao@Sun.COM 		0x60, 0xe8, 0xb0, 0x37, 0xec, 0xdf, 0x4d, 0x82,
1195*10500SHai-May.Chao@Sun.COM 		0x8c, 0x83, 0x0d, 0xcf, 0xc5, 0xce, 0xd4, 0x9c
1196*10500SHai-May.Chao@Sun.COM 	};
1197*10500SHai-May.Chao@Sun.COM 
1198*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known AAD Alen = 16 bytes (192-bits). */
1199*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm192_known_adata[] = {
1200*10500SHai-May.Chao@Sun.COM 		0x44, 0x3a, 0xdf, 0xad, 0xbb, 0x29, 0xd6, 0x8c,
1201*10500SHai-May.Chao@Sun.COM 		0x55, 0xe2, 0x02, 0x2d, 0xca, 0x62, 0x9b, 0x51
1202*10500SHai-May.Chao@Sun.COM 	};
1203*10500SHai-May.Chao@Sun.COM 
1204*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known AAD Alen = 16 bytes (256-bits). */
1205*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm256_known_adata[] = {
1206*10500SHai-May.Chao@Sun.COM 		0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b,
1207*10500SHai-May.Chao@Sun.COM 		0xdb, 0x37, 0x0c, 0x43, 0x7f, 0xec, 0x78, 0xde
1208*10500SHai-May.Chao@Sun.COM 	};
1209*10500SHai-May.Chao@Sun.COM 
1210*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Payload Plen = 16 bytes (128-bits). */
1211*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm128_known_plaintext[] = {
1212*10500SHai-May.Chao@Sun.COM 		0x99, 0x66, 0x7d, 0xc9, 0x62, 0xb3, 0x9f, 0x14,
1213*10500SHai-May.Chao@Sun.COM 		0x8c, 0xdd, 0xfe, 0x68, 0xf9, 0x0a, 0x43, 0xf9
1214*10500SHai-May.Chao@Sun.COM 	};
1215*10500SHai-May.Chao@Sun.COM 
1216*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Payload Plen = 16 bytes (192-bits). */
1217*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm192_known_plaintext[] = {
1218*10500SHai-May.Chao@Sun.COM 		0x7f, 0x9c, 0x08, 0x1d, 0x6a, 0xcc, 0xa8, 0xab,
1219*10500SHai-May.Chao@Sun.COM 		0x71, 0x75, 0xcb, 0xd0, 0x49, 0x42, 0xba, 0xad
1220*10500SHai-May.Chao@Sun.COM 	};
1221*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Payload Plen = 16 bytes (256-bits). */
1222*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm256_known_plaintext[] = {
1223*10500SHai-May.Chao@Sun.COM 		0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e,
1224*10500SHai-May.Chao@Sun.COM 		0xeb, 0x31, 0xb2, 0xea, 0xcc, 0x2b, 0xf2, 0xa5
1225*10500SHai-May.Chao@Sun.COM 	};
1226*10500SHai-May.Chao@Sun.COM 
1227*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Ciphertext Clen = 16 bytes (128-bits) + tag */
1228*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm128_known_ciphertext[] = {
1229*10500SHai-May.Chao@Sun.COM 		0x2b, 0x5f, 0x57, 0xf2, 0x62, 0x27, 0xe0, 0x94,
1230*10500SHai-May.Chao@Sun.COM 		0xe7, 0xf8, 0x01, 0x23, 0xf9, 0xed, 0xbd, 0xe8,
1231*10500SHai-May.Chao@Sun.COM 		0x16, 0xee, 0x08, 0xb4, 0xd8, 0x07, 0xe5, 0xdb,
1232*10500SHai-May.Chao@Sun.COM 		0xd5, 0x70, 0x3c, 0xb3, 0xcf, 0x53, 0x8c, 0x14
1233*10500SHai-May.Chao@Sun.COM 	};
1234*10500SHai-May.Chao@Sun.COM 
1235*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Ciphertext Clen = 16 bytes (192-bits) + tag */
1236*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm192_known_ciphertext[] = {
1237*10500SHai-May.Chao@Sun.COM 		0xdd, 0x7e, 0x7e, 0x45, 0x5b, 0x21, 0xd8, 0x84,
1238*10500SHai-May.Chao@Sun.COM 		0x3d, 0x7b, 0xc3, 0x1f, 0x21, 0x07, 0xf9, 0x55,
1239*10500SHai-May.Chao@Sun.COM 		0x9f, 0x0e, 0x8d, 0xe2, 0x6d, 0xb4, 0x95, 0xf5,
1240*10500SHai-May.Chao@Sun.COM 		0x91, 0x1f, 0xb6, 0x0c, 0xf5, 0xf2, 0x3a, 0xf9
1241*10500SHai-May.Chao@Sun.COM 	};
1242*10500SHai-May.Chao@Sun.COM 
1243*10500SHai-May.Chao@Sun.COM 	/* AES-GCM Known Ciphertext Clen = 16 bytes (256-bits)+ tag */
1244*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gcm256_known_ciphertext[] = {
1245*10500SHai-May.Chao@Sun.COM 		0xf7, 0x26, 0x44, 0x13, 0xa8, 0x4c, 0x0e, 0x7c,
1246*10500SHai-May.Chao@Sun.COM 		0xd5, 0x36, 0x86, 0x7e, 0xb9, 0xf2, 0x17, 0x36,
1247*10500SHai-May.Chao@Sun.COM 		0x67, 0xba, 0x05, 0x10, 0x26, 0x2a, 0xe4, 0x87,
1248*10500SHai-May.Chao@Sun.COM 		0xd7, 0x37, 0xee, 0x62, 0x98, 0xf7, 0x7e, 0x0c
1249*10500SHai-May.Chao@Sun.COM 	};
1250*10500SHai-May.Chao@Sun.COM 
1251*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gcm_known_key =
1252*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1253*10500SHai-May.Chao@Sun.COM 	    aes_gcm128_known_key :
1254*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1255*10500SHai-May.Chao@Sun.COM 	    aes_gcm192_known_key :
1256*10500SHai-May.Chao@Sun.COM 	    aes_gcm256_known_key;
1257*10500SHai-May.Chao@Sun.COM 
1258*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gcm_known_iv =
1259*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1260*10500SHai-May.Chao@Sun.COM 	    aes_gcm128_known_iv :
1261*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1262*10500SHai-May.Chao@Sun.COM 	    aes_gcm192_known_iv :
1263*10500SHai-May.Chao@Sun.COM 	    aes_gcm256_known_iv;
1264*10500SHai-May.Chao@Sun.COM 
1265*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gcm_known_plaintext =
1266*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1267*10500SHai-May.Chao@Sun.COM 	    aes_gcm128_known_plaintext :
1268*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1269*10500SHai-May.Chao@Sun.COM 	    aes_gcm192_known_plaintext :
1270*10500SHai-May.Chao@Sun.COM 	    aes_gcm256_known_plaintext;
1271*10500SHai-May.Chao@Sun.COM 
1272*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gcm_known_ciphertext =
1273*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1274*10500SHai-May.Chao@Sun.COM 	    aes_gcm128_known_ciphertext :
1275*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1276*10500SHai-May.Chao@Sun.COM 	    aes_gcm192_known_ciphertext :
1277*10500SHai-May.Chao@Sun.COM 	    aes_gcm256_known_ciphertext;
1278*10500SHai-May.Chao@Sun.COM 
1279*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gcm_known_adata =
1280*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1281*10500SHai-May.Chao@Sun.COM 	    aes_gcm128_known_adata :
1282*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1283*10500SHai-May.Chao@Sun.COM 	    aes_gcm192_known_adata :
1284*10500SHai-May.Chao@Sun.COM 	    aes_gcm256_known_adata;
1285*10500SHai-May.Chao@Sun.COM 
1286*10500SHai-May.Chao@Sun.COM 	/*
1287*10500SHai-May.Chao@Sun.COM 	 * Source: NIST gcmEncryptExtIV128.txt
1288*10500SHai-May.Chao@Sun.COM 	 * Count = 0, [Keylen = 128], [IVlen = 96], [PTlen = 0],
1289*10500SHai-May.Chao@Sun.COM 	 * [AADlen = 128], [Taglen = 128]
1290*10500SHai-May.Chao@Sun.COM 	 *
1291*10500SHai-May.Chao@Sun.COM 	 * Source: NIST gcmEncryptExtIV192.txt
1292*10500SHai-May.Chao@Sun.COM 	 * Count = 0, [Keylen = 192], [IVlen = 96], [PTlen = 0],
1293*10500SHai-May.Chao@Sun.COM 	 * [AADlen = 128], [Taglen = 128]
1294*10500SHai-May.Chao@Sun.COM 	 *
1295*10500SHai-May.Chao@Sun.COM 	 * Source: NIST gcmEncryptExtIV256.txt
1296*10500SHai-May.Chao@Sun.COM 	 * Count = 0, [Keylen = 256], [IVlen = 96], [PTlen = 0],
1297*10500SHai-May.Chao@Sun.COM 	 * [AADlen = 128], [Taglen = 128]
1298*10500SHai-May.Chao@Sun.COM 	 */
1299*10500SHai-May.Chao@Sun.COM 
1300*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Key (128-bits). */
1301*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac128_known_key[] = {
1302*10500SHai-May.Chao@Sun.COM 		0x7d, 0x70, 0xd2, 0x32, 0x48, 0xc4, 0x7e, 0xb3,
1303*10500SHai-May.Chao@Sun.COM 		0xd2, 0x73, 0xdf, 0x81, 0xed, 0x30, 0x24, 0xbd
1304*10500SHai-May.Chao@Sun.COM 	};
1305*10500SHai-May.Chao@Sun.COM 
1306*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Key (192-bits). */
1307*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac192_known_key[] = {
1308*10500SHai-May.Chao@Sun.COM 		0x03, 0x60, 0x22, 0xfe, 0x26, 0x9a, 0xdc, 0xad,
1309*10500SHai-May.Chao@Sun.COM 		0xb5, 0x73, 0x11, 0xa4, 0xa0, 0xed, 0x2a, 0x84,
1310*10500SHai-May.Chao@Sun.COM 		0x18, 0x34, 0xb8, 0xb6, 0xd8, 0xa0, 0x7f, 0x41
1311*10500SHai-May.Chao@Sun.COM 	};
1312*10500SHai-May.Chao@Sun.COM 
1313*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Key (256-bits). */
1314*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac256_known_key[] = {
1315*10500SHai-May.Chao@Sun.COM 		0xbb, 0x10, 0x10, 0x06, 0x4f, 0xb8, 0x35, 0x23,
1316*10500SHai-May.Chao@Sun.COM 		0xea, 0x9d, 0xf3, 0x2b, 0xad, 0x9f, 0x1f, 0x2a,
1317*10500SHai-May.Chao@Sun.COM 		0x4f, 0xce, 0xfc, 0x0f, 0x21, 0x07, 0xc0, 0xaa,
1318*10500SHai-May.Chao@Sun.COM 		0xba, 0xd9, 0xb7, 0x56, 0xd8, 0x09, 0x21, 0x9d
1319*10500SHai-May.Chao@Sun.COM 	};
1320*10500SHai-May.Chao@Sun.COM 
1321*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Initialization Vector (128-bits). */
1322*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac128_known_iv[] = {
1323*10500SHai-May.Chao@Sun.COM 		0xab, 0x53, 0x23, 0x33, 0xd6, 0x76, 0x51, 0x20,
1324*10500SHai-May.Chao@Sun.COM 		0x8b, 0x8c, 0x34, 0x85
1325*10500SHai-May.Chao@Sun.COM 	};
1326*10500SHai-May.Chao@Sun.COM 
1327*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Initialization Vector (192-bits). */
1328*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac192_known_iv[] = {
1329*10500SHai-May.Chao@Sun.COM 		0x85, 0x65, 0xb2, 0x15, 0x3a, 0x3f, 0x34, 0x9a,
1330*10500SHai-May.Chao@Sun.COM 		0x07, 0x31, 0x06, 0x79
1331*10500SHai-May.Chao@Sun.COM 	};
1332*10500SHai-May.Chao@Sun.COM 
1333*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Initialization Vector (256-bits). */
1334*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac256_known_iv[] = {
1335*10500SHai-May.Chao@Sun.COM 		0x2f, 0x9a, 0xd0, 0x12, 0xad, 0xfc, 0x12, 0x73,
1336*10500SHai-May.Chao@Sun.COM 		0x43, 0xfb, 0xe0, 0x56
1337*10500SHai-May.Chao@Sun.COM 	};
1338*10500SHai-May.Chao@Sun.COM 
1339*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Tag (128-bits). */
1340*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac128_known_tag[] = {
1341*10500SHai-May.Chao@Sun.COM 		0xcf, 0x89, 0x50, 0xa3, 0x10, 0xf5, 0xab, 0x8b,
1342*10500SHai-May.Chao@Sun.COM 		0x69, 0xd5, 0x00, 0x11, 0x1a, 0x44, 0xb0, 0x96
1343*10500SHai-May.Chao@Sun.COM 	};
1344*10500SHai-May.Chao@Sun.COM 
1345*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Tag (192-bits). */
1346*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac192_known_tag[] = {
1347*10500SHai-May.Chao@Sun.COM 		0x90, 0x21, 0xaf, 0x4c, 0xa0, 0x8d, 0x01, 0xef,
1348*10500SHai-May.Chao@Sun.COM 		0x82, 0x5a, 0x42, 0xf9, 0xbe, 0x3a, 0xb3, 0xe9
1349*10500SHai-May.Chao@Sun.COM 	};
1350*10500SHai-May.Chao@Sun.COM 
1351*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known Tag (256-bits). */
1352*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac256_known_tag[] = {
1353*10500SHai-May.Chao@Sun.COM 		0xef, 0x06, 0xd5, 0x4d, 0xfd, 0x00, 0x02, 0x1d,
1354*10500SHai-May.Chao@Sun.COM 		0x75, 0x27, 0xdf, 0xf2, 0x6f, 0xc9, 0xd4, 0x84
1355*10500SHai-May.Chao@Sun.COM 	};
1356*10500SHai-May.Chao@Sun.COM 
1357*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known AAD Alen = 16 bytes (128-bits). */
1358*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac128_known_adata[] = {
1359*10500SHai-May.Chao@Sun.COM 		0x7d, 0x1d, 0x42, 0xe8, 0x94, 0x60, 0xe9, 0x44,
1360*10500SHai-May.Chao@Sun.COM 		0xbf, 0xa4, 0x83, 0xdb, 0xe6, 0x92, 0xf0, 0x8d
1361*10500SHai-May.Chao@Sun.COM 	};
1362*10500SHai-May.Chao@Sun.COM 
1363*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known AAD Alen = 16 bytes (192-bits). */
1364*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac192_known_adata[] = {
1365*10500SHai-May.Chao@Sun.COM 		0xad, 0xcf, 0x4f, 0xbb, 0xa0, 0xe0, 0x6a, 0x63,
1366*10500SHai-May.Chao@Sun.COM 		0x70, 0x71, 0x1a, 0x57, 0xf8, 0xdc, 0xd0, 0xc9
1367*10500SHai-May.Chao@Sun.COM 	};
1368*10500SHai-May.Chao@Sun.COM 
1369*10500SHai-May.Chao@Sun.COM 	/* AES-GMAC Known AAD Alen = 16 bytes (256-bits). */
1370*10500SHai-May.Chao@Sun.COM 	static uint8_t aes_gmac256_known_adata[] = {
1371*10500SHai-May.Chao@Sun.COM 		0xdb, 0x98, 0xd9, 0x0d, 0x1b, 0x69, 0x5c, 0xdb,
1372*10500SHai-May.Chao@Sun.COM 		0x74, 0x7a, 0x34, 0x3f, 0xbb, 0xc9, 0xf1, 0x41
1373*10500SHai-May.Chao@Sun.COM 	};
1374*10500SHai-May.Chao@Sun.COM 
1375*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gmac_known_key =
1376*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1377*10500SHai-May.Chao@Sun.COM 	    aes_gmac128_known_key :
1378*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1379*10500SHai-May.Chao@Sun.COM 	    aes_gmac192_known_key :
1380*10500SHai-May.Chao@Sun.COM 	    aes_gmac256_known_key;
1381*10500SHai-May.Chao@Sun.COM 
1382*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gmac_known_iv =
1383*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1384*10500SHai-May.Chao@Sun.COM 	    aes_gmac128_known_iv :
1385*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1386*10500SHai-May.Chao@Sun.COM 	    aes_gmac192_known_iv :
1387*10500SHai-May.Chao@Sun.COM 	    aes_gmac256_known_iv;
1388*10500SHai-May.Chao@Sun.COM 
1389*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gmac_known_tag =
1390*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1391*10500SHai-May.Chao@Sun.COM 	    aes_gmac128_known_tag :
1392*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1393*10500SHai-May.Chao@Sun.COM 	    aes_gmac192_known_tag :
1394*10500SHai-May.Chao@Sun.COM 	    aes_gmac256_known_tag;
1395*10500SHai-May.Chao@Sun.COM 
1396*10500SHai-May.Chao@Sun.COM 	uint8_t *aes_gmac_known_adata =
1397*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_128_KEY_SIZE) ?
1398*10500SHai-May.Chao@Sun.COM 	    aes_gmac128_known_adata :
1399*10500SHai-May.Chao@Sun.COM 	    (aes_key_size == FIPS_AES_192_KEY_SIZE) ?
1400*10500SHai-May.Chao@Sun.COM 	    aes_gmac192_known_adata :
1401*10500SHai-May.Chao@Sun.COM 	    aes_gmac256_known_adata;
1402*10500SHai-May.Chao@Sun.COM 
1403*10500SHai-May.Chao@Sun.COM 	/* AES variables. */
1404*10500SHai-May.Chao@Sun.COM 	uint8_t aes_ccm_computed_ciphertext[3*FIPS_AES_ENCRYPT_LENGTH];
1405*10500SHai-May.Chao@Sun.COM 	uint8_t aes_ccm_computed_plaintext[2*FIPS_AES_DECRYPT_LENGTH];
1406*10500SHai-May.Chao@Sun.COM 	uint8_t aes_gcm_computed_ciphertext[2*FIPS_AES_ENCRYPT_LENGTH];
1407*10500SHai-May.Chao@Sun.COM 	uint8_t aes_gcm_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
1408*10500SHai-May.Chao@Sun.COM 	uint8_t aes_gmac_computed_tag[FIPS_AES_ENCRYPT_LENGTH];
1409*10500SHai-May.Chao@Sun.COM 	CK_AES_CCM_PARAMS ccm_param;
1410*10500SHai-May.Chao@Sun.COM 	CK_AES_GCM_PARAMS gcm_param;
1411*10500SHai-May.Chao@Sun.COM 	CK_AES_GMAC_PARAMS gmac_param;
1412*10500SHai-May.Chao@Sun.COM #endif
1413*10500SHai-May.Chao@Sun.COM 
1414*10500SHai-May.Chao@Sun.COM 	uint8_t aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH];
1415*10500SHai-May.Chao@Sun.COM 	uint8_t aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
1416*10500SHai-May.Chao@Sun.COM 	soft_aes_ctx_t  *aes_context;
1417*10500SHai-May.Chao@Sun.COM 	ulong_t aes_bytes_encrypted;
1418*10500SHai-May.Chao@Sun.COM 	ulong_t aes_bytes_decrypted;
1419*10500SHai-May.Chao@Sun.COM 	int rv;
1420*10500SHai-May.Chao@Sun.COM 
1421*10500SHai-May.Chao@Sun.COM 	/* check if aes_key_size is 128, 192, or 256 bits */
1422*10500SHai-May.Chao@Sun.COM 	if ((aes_key_size != FIPS_AES_128_KEY_SIZE) &&
1423*10500SHai-May.Chao@Sun.COM 	    (aes_key_size != FIPS_AES_192_KEY_SIZE) &&
1424*10500SHai-May.Chao@Sun.COM 	    (aes_key_size != FIPS_AES_256_KEY_SIZE))
1425*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
1426*10500SHai-May.Chao@Sun.COM 
1427*10500SHai-May.Chao@Sun.COM 	/*
1428*10500SHai-May.Chao@Sun.COM 	 * AES-ECB Known Answer Encryption Test
1429*10500SHai-May.Chao@Sun.COM 	 */
1430*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
1431*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1432*10500SHai-May.Chao@Sun.COM 	    aes_key_size, NULL, AES_ECB_MECH_INFO_TYPE, B_FALSE);
1433*10500SHai-May.Chao@Sun.COM #else
1434*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1435*10500SHai-May.Chao@Sun.COM 	    aes_key_size, NULL, CKM_AES_ECB);
1436*10500SHai-May.Chao@Sun.COM #endif
1437*10500SHai-May.Chao@Sun.COM 
1438*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1439*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
1440*10500SHai-May.Chao@Sun.COM 	}
1441*10500SHai-May.Chao@Sun.COM 
1442*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_encrypt(aes_context, aes_known_plaintext,
1443*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH, aes_computed_ciphertext,
1444*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_encrypted, CKM_AES_ECB);
1445*10500SHai-May.Chao@Sun.COM 
1446*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1447*10500SHai-May.Chao@Sun.COM 
1448*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
1449*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1450*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_computed_ciphertext, aes_ecb_known_ciphertext,
1451*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH) != 0))
1452*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
1453*10500SHai-May.Chao@Sun.COM 
1454*10500SHai-May.Chao@Sun.COM 	/*
1455*10500SHai-May.Chao@Sun.COM 	 * AES-ECB Known Answer Decryption Test
1456*10500SHai-May.Chao@Sun.COM 	 */
1457*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
1458*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1459*10500SHai-May.Chao@Sun.COM 	    aes_key_size, NULL, AES_ECB_MECH_INFO_TYPE, B_FALSE);
1460*10500SHai-May.Chao@Sun.COM #else
1461*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1462*10500SHai-May.Chao@Sun.COM 	    aes_key_size, NULL, CKM_AES_ECB);
1463*10500SHai-May.Chao@Sun.COM #endif
1464*10500SHai-May.Chao@Sun.COM 
1465*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1466*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
1467*10500SHai-May.Chao@Sun.COM 	}
1468*10500SHai-May.Chao@Sun.COM 
1469*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_decrypt(aes_context, aes_ecb_known_ciphertext,
1470*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH, aes_computed_plaintext,
1471*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_decrypted, CKM_AES_ECB);
1472*10500SHai-May.Chao@Sun.COM 
1473*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1474*10500SHai-May.Chao@Sun.COM 
1475*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
1476*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1477*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_computed_plaintext, aes_known_plaintext,
1478*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH) != 0))
1479*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
1480*10500SHai-May.Chao@Sun.COM 
1481*10500SHai-May.Chao@Sun.COM 	/*
1482*10500SHai-May.Chao@Sun.COM 	 * AES-CBC Known Answer Encryption Test
1483*10500SHai-May.Chao@Sun.COM 	 */
1484*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
1485*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1486*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_cbc_known_initialization_vector,
1487*10500SHai-May.Chao@Sun.COM 	    AES_CBC_MECH_INFO_TYPE, B_FALSE);
1488*10500SHai-May.Chao@Sun.COM #else
1489*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1490*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_cbc_known_initialization_vector,
1491*10500SHai-May.Chao@Sun.COM 	    CKM_AES_CBC);
1492*10500SHai-May.Chao@Sun.COM #endif
1493*10500SHai-May.Chao@Sun.COM 
1494*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1495*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
1496*10500SHai-May.Chao@Sun.COM 	}
1497*10500SHai-May.Chao@Sun.COM 
1498*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_encrypt(aes_context, aes_known_plaintext,
1499*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH, aes_computed_ciphertext,
1500*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_encrypted, CKM_AES_CBC);
1501*10500SHai-May.Chao@Sun.COM 
1502*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1503*10500SHai-May.Chao@Sun.COM 
1504*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
1505*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1506*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_computed_ciphertext, aes_cbc_known_ciphertext,
1507*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH) != 0))
1508*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
1509*10500SHai-May.Chao@Sun.COM 
1510*10500SHai-May.Chao@Sun.COM 	/*
1511*10500SHai-May.Chao@Sun.COM 	 * AES-CBC Known Answer Decryption Test
1512*10500SHai-May.Chao@Sun.COM 	 */
1513*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
1514*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1515*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_cbc_known_initialization_vector,
1516*10500SHai-May.Chao@Sun.COM 	    AES_CBC_MECH_INFO_TYPE, B_FALSE);
1517*10500SHai-May.Chao@Sun.COM #else
1518*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_known_key,
1519*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_cbc_known_initialization_vector,
1520*10500SHai-May.Chao@Sun.COM 	    CKM_AES_CBC);
1521*10500SHai-May.Chao@Sun.COM #endif
1522*10500SHai-May.Chao@Sun.COM 
1523*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL)
1524*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_HOST_MEMORY);
1525*10500SHai-May.Chao@Sun.COM 
1526*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_decrypt(aes_context, aes_cbc_known_ciphertext,
1527*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH, aes_computed_plaintext,
1528*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_decrypted, CKM_AES_CBC);
1529*10500SHai-May.Chao@Sun.COM 
1530*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1531*10500SHai-May.Chao@Sun.COM 
1532*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
1533*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1534*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_computed_plaintext, aes_known_plaintext,
1535*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH) != 0))
1536*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
1537*10500SHai-May.Chao@Sun.COM 
1538*10500SHai-May.Chao@Sun.COM 	/*
1539*10500SHai-May.Chao@Sun.COM 	 * AES-CTR Known Answer Encryption Test
1540*10500SHai-May.Chao@Sun.COM 	 */
1541*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
1542*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_ctr_known_key,
1543*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_ctr_known_counter,
1544*10500SHai-May.Chao@Sun.COM 	    AES_CTR_MECH_INFO_TYPE, B_FALSE);
1545*10500SHai-May.Chao@Sun.COM #else
1546*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_ctr_known_key,
1547*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_ctr_known_counter, CKM_AES_CTR);
1548*10500SHai-May.Chao@Sun.COM #endif
1549*10500SHai-May.Chao@Sun.COM 
1550*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1551*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
1552*10500SHai-May.Chao@Sun.COM 	}
1553*10500SHai-May.Chao@Sun.COM 
1554*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_encrypt(aes_context, aes_ctr_known_plaintext,
1555*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH, aes_computed_ciphertext,
1556*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_encrypted, CKM_AES_CTR);
1557*10500SHai-May.Chao@Sun.COM 
1558*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1559*10500SHai-May.Chao@Sun.COM 
1560*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
1561*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1562*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_computed_ciphertext, aes_ctr_known_ciphertext,
1563*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH) != 0))
1564*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
1565*10500SHai-May.Chao@Sun.COM 
1566*10500SHai-May.Chao@Sun.COM 	/*
1567*10500SHai-May.Chao@Sun.COM 	 * AES-CTR Known Answer Decryption Test
1568*10500SHai-May.Chao@Sun.COM 	 */
1569*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
1570*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_ctr_known_key,
1571*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_ctr_known_counter,
1572*10500SHai-May.Chao@Sun.COM 	    AES_CTR_MECH_INFO_TYPE, B_FALSE);
1573*10500SHai-May.Chao@Sun.COM #else
1574*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_ctr_known_key,
1575*10500SHai-May.Chao@Sun.COM 	    aes_key_size, aes_ctr_known_counter,
1576*10500SHai-May.Chao@Sun.COM 	    CKM_AES_CTR);
1577*10500SHai-May.Chao@Sun.COM #endif
1578*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1579*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
1580*10500SHai-May.Chao@Sun.COM 	}
1581*10500SHai-May.Chao@Sun.COM 
1582*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_decrypt(aes_context, aes_ctr_known_ciphertext,
1583*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH, aes_computed_plaintext,
1584*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_decrypted, CKM_AES_CTR);
1585*10500SHai-May.Chao@Sun.COM 
1586*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1587*10500SHai-May.Chao@Sun.COM 
1588*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
1589*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1590*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_computed_plaintext, aes_ctr_known_plaintext,
1591*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH) != 0))
1592*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
1593*10500SHai-May.Chao@Sun.COM 
1594*10500SHai-May.Chao@Sun.COM 	/*
1595*10500SHai-May.Chao@Sun.COM 	 * The following POSTs are only available in Kernel
1596*10500SHai-May.Chao@Sun.COM 	 *
1597*10500SHai-May.Chao@Sun.COM 	 * CCM, GCM, and GMAC
1598*10500SHai-May.Chao@Sun.COM 	 */
1599*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
1600*10500SHai-May.Chao@Sun.COM 
1601*10500SHai-May.Chao@Sun.COM 	/*
1602*10500SHai-May.Chao@Sun.COM 	 * AES-CCM Known Answer Encryption Test
1603*10500SHai-May.Chao@Sun.COM 	 */
1604*10500SHai-May.Chao@Sun.COM 	ccm_param.ulMACSize = 16; /* Tlen */
1605*10500SHai-May.Chao@Sun.COM 	ccm_param.ulNonceSize = 7; /* Nlen */
1606*10500SHai-May.Chao@Sun.COM 	ccm_param.ulAuthDataSize = 30; /* Alen */
1607*10500SHai-May.Chao@Sun.COM 	ccm_param.ulDataSize = 32; /* Plen or Clen */
1608*10500SHai-May.Chao@Sun.COM 	ccm_param.nonce = aes_ccm_known_nonce;
1609*10500SHai-May.Chao@Sun.COM 	ccm_param.authData = aes_ccm_known_adata;
1610*10500SHai-May.Chao@Sun.COM 
1611*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_ccm_known_key,
1612*10500SHai-May.Chao@Sun.COM 	    aes_key_size, (uint8_t *)&ccm_param,
1613*10500SHai-May.Chao@Sun.COM 	    AES_CCM_MECH_INFO_TYPE, B_TRUE);
1614*10500SHai-May.Chao@Sun.COM 
1615*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1616*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_HOST_MEMORY);
1617*10500SHai-May.Chao@Sun.COM 	}
1618*10500SHai-May.Chao@Sun.COM 
1619*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_encrypt(aes_context, aes_ccm_known_plaintext,
1620*10500SHai-May.Chao@Sun.COM 	    2*FIPS_AES_ENCRYPT_LENGTH, aes_ccm_computed_ciphertext,
1621*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_encrypted, AES_CCM_MECH_INFO_TYPE);
1622*10500SHai-May.Chao@Sun.COM 
1623*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1624*10500SHai-May.Chao@Sun.COM 
1625*10500SHai-May.Chao@Sun.COM 	if ((rv != CRYPTO_SUCCESS) ||
1626*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_encrypted != 3*FIPS_AES_ENCRYPT_LENGTH) ||
1627*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_ccm_computed_ciphertext, aes_ccm_known_ciphertext,
1628*10500SHai-May.Chao@Sun.COM 	    3*FIPS_AES_ENCRYPT_LENGTH) != 0))
1629*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_DEVICE_ERROR);
1630*10500SHai-May.Chao@Sun.COM 
1631*10500SHai-May.Chao@Sun.COM 	/*
1632*10500SHai-May.Chao@Sun.COM 	 * AES-CCM Known Answer Decryption Test
1633*10500SHai-May.Chao@Sun.COM 	 */
1634*10500SHai-May.Chao@Sun.COM 	ccm_param.ulMACSize = 16; /* Tlen */
1635*10500SHai-May.Chao@Sun.COM 	ccm_param.ulNonceSize = 7; /* Nlen */
1636*10500SHai-May.Chao@Sun.COM 	ccm_param.ulAuthDataSize = 30; /* Alen */
1637*10500SHai-May.Chao@Sun.COM 	ccm_param.ulDataSize = 48; /* Plen or Clen */
1638*10500SHai-May.Chao@Sun.COM 	ccm_param.nonce = aes_ccm_known_nonce;
1639*10500SHai-May.Chao@Sun.COM 	ccm_param.authData = aes_ccm_known_adata;
1640*10500SHai-May.Chao@Sun.COM 
1641*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_ccm_known_key,
1642*10500SHai-May.Chao@Sun.COM 	    aes_key_size, (uint8_t *)&ccm_param,
1643*10500SHai-May.Chao@Sun.COM 	    AES_CCM_MECH_INFO_TYPE, B_FALSE);
1644*10500SHai-May.Chao@Sun.COM 
1645*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1646*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_HOST_MEMORY);
1647*10500SHai-May.Chao@Sun.COM 	}
1648*10500SHai-May.Chao@Sun.COM 
1649*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_decrypt(aes_context, aes_ccm_known_ciphertext,
1650*10500SHai-May.Chao@Sun.COM 	    2*FIPS_AES_DECRYPT_LENGTH, aes_ccm_computed_plaintext,
1651*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_decrypted, AES_CCM_MECH_INFO_TYPE);
1652*10500SHai-May.Chao@Sun.COM 
1653*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1654*10500SHai-May.Chao@Sun.COM 
1655*10500SHai-May.Chao@Sun.COM 	if ((rv != CRYPTO_SUCCESS) ||
1656*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_decrypted != 2*FIPS_AES_DECRYPT_LENGTH) ||
1657*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_ccm_computed_plaintext, aes_ccm_known_plaintext,
1658*10500SHai-May.Chao@Sun.COM 	    2*FIPS_AES_DECRYPT_LENGTH) != 0))
1659*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_DEVICE_ERROR);
1660*10500SHai-May.Chao@Sun.COM 
1661*10500SHai-May.Chao@Sun.COM 	/*
1662*10500SHai-May.Chao@Sun.COM 	 * AES-GCM Known Answer Encryption Test
1663*10500SHai-May.Chao@Sun.COM 	 */
1664*10500SHai-May.Chao@Sun.COM 	gcm_param.pIv = aes_gcm_known_iv;
1665*10500SHai-May.Chao@Sun.COM 	gcm_param.ulIvLen = AES_GMAC_IV_LEN; /* IVlen = 96 bits */
1666*10500SHai-May.Chao@Sun.COM 	gcm_param.ulTagBits = AES_GMAC_TAG_BITS; /* Taglen = 128 bits */
1667*10500SHai-May.Chao@Sun.COM 	gcm_param.ulAADLen = 16;
1668*10500SHai-May.Chao@Sun.COM 	gcm_param.pAAD = aes_gcm_known_adata;
1669*10500SHai-May.Chao@Sun.COM 
1670*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_gcm_known_key,
1671*10500SHai-May.Chao@Sun.COM 	    aes_key_size, (uint8_t *)&gcm_param,
1672*10500SHai-May.Chao@Sun.COM 	    AES_GCM_MECH_INFO_TYPE, B_TRUE);
1673*10500SHai-May.Chao@Sun.COM 
1674*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1675*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_HOST_MEMORY);
1676*10500SHai-May.Chao@Sun.COM 	}
1677*10500SHai-May.Chao@Sun.COM 
1678*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_encrypt(aes_context, aes_gcm_known_plaintext,
1679*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH, aes_gcm_computed_ciphertext,
1680*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_encrypted, AES_GCM_MECH_INFO_TYPE);
1681*10500SHai-May.Chao@Sun.COM 
1682*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1683*10500SHai-May.Chao@Sun.COM 
1684*10500SHai-May.Chao@Sun.COM 	if ((rv != CRYPTO_SUCCESS) ||
1685*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_encrypted != 2*FIPS_AES_ENCRYPT_LENGTH) ||
1686*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_gcm_computed_ciphertext, aes_gcm_known_ciphertext,
1687*10500SHai-May.Chao@Sun.COM 	    2*FIPS_AES_ENCRYPT_LENGTH) != 0))
1688*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_DEVICE_ERROR);
1689*10500SHai-May.Chao@Sun.COM 
1690*10500SHai-May.Chao@Sun.COM 	/*
1691*10500SHai-May.Chao@Sun.COM 	 * AES-GCM Known Answer Decryption Test
1692*10500SHai-May.Chao@Sun.COM 	 */
1693*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_gcm_known_key,
1694*10500SHai-May.Chao@Sun.COM 	    aes_key_size, (uint8_t *)&gcm_param,
1695*10500SHai-May.Chao@Sun.COM 	    AES_GCM_MECH_INFO_TYPE, B_FALSE);
1696*10500SHai-May.Chao@Sun.COM 
1697*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1698*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_HOST_MEMORY);
1699*10500SHai-May.Chao@Sun.COM 	}
1700*10500SHai-May.Chao@Sun.COM 
1701*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_decrypt(aes_context, aes_gcm_known_ciphertext,
1702*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH, aes_gcm_computed_plaintext,
1703*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_decrypted, AES_GCM_MECH_INFO_TYPE);
1704*10500SHai-May.Chao@Sun.COM 
1705*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1706*10500SHai-May.Chao@Sun.COM 
1707*10500SHai-May.Chao@Sun.COM 	if ((rv != CRYPTO_SUCCESS) ||
1708*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
1709*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_gcm_computed_plaintext, aes_gcm_known_plaintext,
1710*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH) != 0))
1711*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_DEVICE_ERROR);
1712*10500SHai-May.Chao@Sun.COM 
1713*10500SHai-May.Chao@Sun.COM 	/*
1714*10500SHai-May.Chao@Sun.COM 	 * AES-GMAC Known Answer Encryption Test
1715*10500SHai-May.Chao@Sun.COM 	 */
1716*10500SHai-May.Chao@Sun.COM 	gmac_param.pIv = aes_gmac_known_iv;
1717*10500SHai-May.Chao@Sun.COM 	gmac_param.ulAADLen = 16;
1718*10500SHai-May.Chao@Sun.COM 	gmac_param.pAAD = aes_gmac_known_adata;
1719*10500SHai-May.Chao@Sun.COM 
1720*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_gmac_known_key,
1721*10500SHai-May.Chao@Sun.COM 	    aes_key_size, (uint8_t *)&gmac_param,
1722*10500SHai-May.Chao@Sun.COM 	    AES_GMAC_MECH_INFO_TYPE, B_TRUE);
1723*10500SHai-May.Chao@Sun.COM 
1724*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1725*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_HOST_MEMORY);
1726*10500SHai-May.Chao@Sun.COM 	}
1727*10500SHai-May.Chao@Sun.COM 
1728*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_encrypt(aes_context, NULL,
1729*10500SHai-May.Chao@Sun.COM 	    0, aes_gmac_computed_tag,
1730*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_encrypted, AES_GMAC_MECH_INFO_TYPE);
1731*10500SHai-May.Chao@Sun.COM 
1732*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1733*10500SHai-May.Chao@Sun.COM 
1734*10500SHai-May.Chao@Sun.COM 	if ((rv != CRYPTO_SUCCESS) ||
1735*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH) ||
1736*10500SHai-May.Chao@Sun.COM 	    (memcmp(aes_gmac_computed_tag, aes_gmac_known_tag,
1737*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_ENCRYPT_LENGTH) != 0))
1738*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_DEVICE_ERROR);
1739*10500SHai-May.Chao@Sun.COM 
1740*10500SHai-May.Chao@Sun.COM 	/*
1741*10500SHai-May.Chao@Sun.COM 	 * AES-GMAC Known Answer Decryption Test
1742*10500SHai-May.Chao@Sun.COM 	 */
1743*10500SHai-May.Chao@Sun.COM 
1744*10500SHai-May.Chao@Sun.COM 	aes_context = fips_aes_build_context(aes_gmac_known_key,
1745*10500SHai-May.Chao@Sun.COM 	    aes_key_size, (uint8_t *)&gmac_param,
1746*10500SHai-May.Chao@Sun.COM 	    AES_GMAC_MECH_INFO_TYPE, B_FALSE);
1747*10500SHai-May.Chao@Sun.COM 
1748*10500SHai-May.Chao@Sun.COM 	if (aes_context == NULL) {
1749*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_HOST_MEMORY);
1750*10500SHai-May.Chao@Sun.COM 	}
1751*10500SHai-May.Chao@Sun.COM 
1752*10500SHai-May.Chao@Sun.COM 	rv = fips_aes_decrypt(aes_context, aes_gmac_known_tag,
1753*10500SHai-May.Chao@Sun.COM 	    FIPS_AES_DECRYPT_LENGTH, NULL,
1754*10500SHai-May.Chao@Sun.COM 	    &aes_bytes_decrypted, AES_GMAC_MECH_INFO_TYPE);
1755*10500SHai-May.Chao@Sun.COM 
1756*10500SHai-May.Chao@Sun.COM 	fips_aes_free_context(aes_context);
1757*10500SHai-May.Chao@Sun.COM 
1758*10500SHai-May.Chao@Sun.COM 	if ((rv != CRYPTO_SUCCESS) ||
1759*10500SHai-May.Chao@Sun.COM 	    (aes_bytes_decrypted != 0))
1760*10500SHai-May.Chao@Sun.COM 		return (CRYPTO_DEVICE_ERROR);
1761*10500SHai-May.Chao@Sun.COM 
1762*10500SHai-May.Chao@Sun.COM #endif /* _KERNEL */
1763*10500SHai-May.Chao@Sun.COM 
1764*10500SHai-May.Chao@Sun.COM 	return (CRYPTO_SUCCESS);
1765*10500SHai-May.Chao@Sun.COM }
1766