xref: /onnv-gate/usr/src/common/crypto/fips/fips_sha2_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/errno.h>
28*10500SHai-May.Chao@Sun.COM #include <sys/kmem.h>
29*10500SHai-May.Chao@Sun.COM #include <sys/systm.h>
30*10500SHai-May.Chao@Sun.COM #define	_SHA2_IMPL
31*10500SHai-May.Chao@Sun.COM #include <sys/sha2.h>
32*10500SHai-May.Chao@Sun.COM #include <sys/crypto/common.h>
33*10500SHai-May.Chao@Sun.COM #include <sys/cmn_err.h>
34*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL
35*10500SHai-May.Chao@Sun.COM #include <stdlib.h>
36*10500SHai-May.Chao@Sun.COM #include <string.h>
37*10500SHai-May.Chao@Sun.COM #include <strings.h>
38*10500SHai-May.Chao@Sun.COM #include <stdio.h>
39*10500SHai-May.Chao@Sun.COM #include <security/cryptoki.h>
40*10500SHai-May.Chao@Sun.COM #include <cryptoutil.h>
41*10500SHai-May.Chao@Sun.COM #include "softMAC.h"
42*10500SHai-May.Chao@Sun.COM #endif
43*10500SHai-May.Chao@Sun.COM #include <sha2/sha2_impl.h>
44*10500SHai-May.Chao@Sun.COM 
45*10500SHai-May.Chao@Sun.COM 
46*10500SHai-May.Chao@Sun.COM /*
47*10500SHai-May.Chao@Sun.COM  * fips_sha2_build_context()
48*10500SHai-May.Chao@Sun.COM  *
49*10500SHai-May.Chao@Sun.COM  * Description:
50*10500SHai-May.Chao@Sun.COM  *	This function allocates and initializes SHA2 context.
51*10500SHai-May.Chao@Sun.COM  */
52*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL
53*10500SHai-May.Chao@Sun.COM SHA2_CTX *
54*10500SHai-May.Chao@Sun.COM fips_sha2_build_context(CK_MECHANISM_TYPE mechanism)
55*10500SHai-May.Chao@Sun.COM {
56*10500SHai-May.Chao@Sun.COM 	SHA2_CTX *sha2_context;
57*10500SHai-May.Chao@Sun.COM 
58*10500SHai-May.Chao@Sun.COM 	if ((sha2_context = malloc(sizeof (SHA2_CTX))) == NULL)
59*10500SHai-May.Chao@Sun.COM 		return (NULL);
60*10500SHai-May.Chao@Sun.COM 
61*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
62*10500SHai-May.Chao@Sun.COM 	case CKM_SHA256:
63*10500SHai-May.Chao@Sun.COM 		SHA2Init(SHA256, sha2_context);
64*10500SHai-May.Chao@Sun.COM 		break;
65*10500SHai-May.Chao@Sun.COM 
66*10500SHai-May.Chao@Sun.COM 	case CKM_SHA384:
67*10500SHai-May.Chao@Sun.COM 		SHA2Init(SHA384, sha2_context);
68*10500SHai-May.Chao@Sun.COM 		break;
69*10500SHai-May.Chao@Sun.COM 
70*10500SHai-May.Chao@Sun.COM 	case CKM_SHA512:
71*10500SHai-May.Chao@Sun.COM 		SHA2Init(SHA512, sha2_context);
72*10500SHai-May.Chao@Sun.COM 		break;
73*10500SHai-May.Chao@Sun.COM 	}
74*10500SHai-May.Chao@Sun.COM 
75*10500SHai-May.Chao@Sun.COM 	return (sha2_context);
76*10500SHai-May.Chao@Sun.COM }
77*10500SHai-May.Chao@Sun.COM 
78*10500SHai-May.Chao@Sun.COM #else
79*10500SHai-May.Chao@Sun.COM SHA2_CTX *
80*10500SHai-May.Chao@Sun.COM fips_sha2_build_context(sha2_mech_t mechanism)
81*10500SHai-May.Chao@Sun.COM {
82*10500SHai-May.Chao@Sun.COM 	SHA2_CTX *sha2_context;
83*10500SHai-May.Chao@Sun.COM 
84*10500SHai-May.Chao@Sun.COM 	if ((sha2_context = kmem_zalloc(sizeof (SHA2_CTX),
85*10500SHai-May.Chao@Sun.COM 	    KM_SLEEP)) == NULL)
86*10500SHai-May.Chao@Sun.COM 		return (NULL);
87*10500SHai-May.Chao@Sun.COM 
88*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
89*10500SHai-May.Chao@Sun.COM 	case SHA256_TYPE:
90*10500SHai-May.Chao@Sun.COM 		SHA2Init(SHA256, sha2_context);
91*10500SHai-May.Chao@Sun.COM 		break;
92*10500SHai-May.Chao@Sun.COM 
93*10500SHai-May.Chao@Sun.COM 	case SHA384_TYPE:
94*10500SHai-May.Chao@Sun.COM 		SHA2Init(SHA384, sha2_context);
95*10500SHai-May.Chao@Sun.COM 		break;
96*10500SHai-May.Chao@Sun.COM 
97*10500SHai-May.Chao@Sun.COM 	case SHA512_TYPE:
98*10500SHai-May.Chao@Sun.COM 		SHA2Init(SHA512, sha2_context);
99*10500SHai-May.Chao@Sun.COM 		break;
100*10500SHai-May.Chao@Sun.COM 	}
101*10500SHai-May.Chao@Sun.COM 
102*10500SHai-May.Chao@Sun.COM 	return (sha2_context);
103*10500SHai-May.Chao@Sun.COM }
104*10500SHai-May.Chao@Sun.COM #endif
105*10500SHai-May.Chao@Sun.COM 
106*10500SHai-May.Chao@Sun.COM /*
107*10500SHai-May.Chao@Sun.COM  * fips_sha2_hash()
108*10500SHai-May.Chao@Sun.COM  *
109*10500SHai-May.Chao@Sun.COM  * Arguments:
110*10500SHai-May.Chao@Sun.COM  *	sha2_context:	pointer to SHA2 context
111*10500SHai-May.Chao@Sun.COM  *	in:	pointer to the input data to be hashed
112*10500SHai-May.Chao@Sun.COM  *	inlen:	length of the input data
113*10500SHai-May.Chao@Sun.COM  *	out:	pointer to the output data after hashing
114*10500SHai-May.Chao@Sun.COM  *
115*10500SHai-May.Chao@Sun.COM  * Description:
116*10500SHai-May.Chao@Sun.COM  *	This function calls the low-level SHA2 routines for hashing.
117*10500SHai-May.Chao@Sun.COM  *
118*10500SHai-May.Chao@Sun.COM  */
119*10500SHai-May.Chao@Sun.COM int
120*10500SHai-May.Chao@Sun.COM fips_sha2_hash(SHA2_CTX *sha2_context, uchar_t *in,
121*10500SHai-May.Chao@Sun.COM 	ulong_t inlen, uchar_t *out)
122*10500SHai-May.Chao@Sun.COM {
123*10500SHai-May.Chao@Sun.COM 
124*10500SHai-May.Chao@Sun.COM 	if (in != NULL) {
125*10500SHai-May.Chao@Sun.COM 		SHA2Update((SHA2_CTX *)sha2_context, in, inlen);
126*10500SHai-May.Chao@Sun.COM 		SHA2Final(out, (SHA2_CTX *)sha2_context);
127*10500SHai-May.Chao@Sun.COM 		return (CKR_OK);
128*10500SHai-May.Chao@Sun.COM 	} else {
129*10500SHai-May.Chao@Sun.COM 		return (CKR_ARGUMENTS_BAD);
130*10500SHai-May.Chao@Sun.COM 	}
131*10500SHai-May.Chao@Sun.COM }
132*10500SHai-May.Chao@Sun.COM 
133*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL
134*10500SHai-May.Chao@Sun.COM soft_hmac_ctx_t *
135*10500SHai-May.Chao@Sun.COM fips_sha2_hmac_build_context(CK_MECHANISM_TYPE mechanism,
136*10500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
137*10500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
138*10500SHai-May.Chao@Sun.COM {
139*10500SHai-May.Chao@Sun.COM 
140*10500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx;
141*10500SHai-May.Chao@Sun.COM 
142*10500SHai-May.Chao@Sun.COM 	hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
143*10500SHai-May.Chao@Sun.COM 
144*10500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL) {
145*10500SHai-May.Chao@Sun.COM 		return (NULL);
146*10500SHai-May.Chao@Sun.COM 	}
147*10500SHai-May.Chao@Sun.COM 
148*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
149*10500SHai-May.Chao@Sun.COM 	case CKM_SHA256_HMAC:
150*10500SHai-May.Chao@Sun.COM 	{
151*10500SHai-May.Chao@Sun.COM 		uint64_t sha_ipad[SHA256_HMAC_INTS_PER_BLOCK];
152*10500SHai-May.Chao@Sun.COM 		uint64_t sha_opad[SHA256_HMAC_INTS_PER_BLOCK];
153*10500SHai-May.Chao@Sun.COM 
154*10500SHai-May.Chao@Sun.COM 		hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
155*10500SHai-May.Chao@Sun.COM 		bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
156*10500SHai-May.Chao@Sun.COM 		bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
157*10500SHai-May.Chao@Sun.COM 
158*10500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_ipad, secret_key, secret_key_length);
159*10500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_opad, secret_key, secret_key_length);
160*10500SHai-May.Chao@Sun.COM 
161*10500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_init(CKM_TO_SHA2(mechanism),
162*10500SHai-May.Chao@Sun.COM 		    &hmac_ctx->hc_ctx_u.sha2_ctx,
163*10500SHai-May.Chao@Sun.COM 		    sha_ipad, sha_opad,
164*10500SHai-May.Chao@Sun.COM 		    SHA256_HMAC_INTS_PER_BLOCK,
165*10500SHai-May.Chao@Sun.COM 		    SHA256_HMAC_BLOCK_SIZE);
166*10500SHai-May.Chao@Sun.COM 
167*10500SHai-May.Chao@Sun.COM 		break;
168*10500SHai-May.Chao@Sun.COM 	}
169*10500SHai-May.Chao@Sun.COM 
170*10500SHai-May.Chao@Sun.COM 	case CKM_SHA384_HMAC:
171*10500SHai-May.Chao@Sun.COM 	{
172*10500SHai-May.Chao@Sun.COM 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
173*10500SHai-May.Chao@Sun.COM 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
174*10500SHai-May.Chao@Sun.COM 
175*10500SHai-May.Chao@Sun.COM 		hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
176*10500SHai-May.Chao@Sun.COM 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
177*10500SHai-May.Chao@Sun.COM 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
178*10500SHai-May.Chao@Sun.COM 
179*10500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_ipad, secret_key, secret_key_length);
180*10500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_opad, secret_key, secret_key_length);
181*10500SHai-May.Chao@Sun.COM 
182*10500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_init(CKM_TO_SHA2(mechanism),
183*10500SHai-May.Chao@Sun.COM 		    &hmac_ctx->hc_ctx_u.sha2_ctx,
184*10500SHai-May.Chao@Sun.COM 		    sha_ipad, sha_opad,
185*10500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_INTS_PER_BLOCK,
186*10500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_BLOCK_SIZE);
187*10500SHai-May.Chao@Sun.COM 		break;
188*10500SHai-May.Chao@Sun.COM 	}
189*10500SHai-May.Chao@Sun.COM 
190*10500SHai-May.Chao@Sun.COM 	case CKM_SHA512_HMAC:
191*10500SHai-May.Chao@Sun.COM 	{
192*10500SHai-May.Chao@Sun.COM 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
193*10500SHai-May.Chao@Sun.COM 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
194*10500SHai-May.Chao@Sun.COM 
195*10500SHai-May.Chao@Sun.COM 		hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
196*10500SHai-May.Chao@Sun.COM 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
197*10500SHai-May.Chao@Sun.COM 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
198*10500SHai-May.Chao@Sun.COM 
199*10500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_ipad, secret_key, secret_key_length);
200*10500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_opad, secret_key, secret_key_length);
201*10500SHai-May.Chao@Sun.COM 
202*10500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_init(CKM_TO_SHA2(mechanism),
203*10500SHai-May.Chao@Sun.COM 		    &hmac_ctx->hc_ctx_u.sha2_ctx,
204*10500SHai-May.Chao@Sun.COM 		    sha_ipad, sha_opad,
205*10500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_INTS_PER_BLOCK,
206*10500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_BLOCK_SIZE);
207*10500SHai-May.Chao@Sun.COM 
208*10500SHai-May.Chao@Sun.COM 		break;
209*10500SHai-May.Chao@Sun.COM 	}
210*10500SHai-May.Chao@Sun.COM 	}
211*10500SHai-May.Chao@Sun.COM 
212*10500SHai-May.Chao@Sun.COM 	return (hmac_ctx);
213*10500SHai-May.Chao@Sun.COM }
214*10500SHai-May.Chao@Sun.COM 
215*10500SHai-May.Chao@Sun.COM CK_RV
216*10500SHai-May.Chao@Sun.COM fips_hmac_sha2_hash(unsigned char *hmac_computed,
217*10500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
218*10500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length,
219*10500SHai-May.Chao@Sun.COM 	uint8_t *message,
220*10500SHai-May.Chao@Sun.COM 	unsigned int message_length,
221*10500SHai-May.Chao@Sun.COM 	CK_MECHANISM_TYPE mechanism)
222*10500SHai-May.Chao@Sun.COM {
223*10500SHai-May.Chao@Sun.COM 
224*10500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx = NULL;
225*10500SHai-May.Chao@Sun.COM 
226*10500SHai-May.Chao@Sun.COM 	hmac_ctx = fips_sha2_hmac_build_context(mechanism,
227*10500SHai-May.Chao@Sun.COM 	    secret_key, secret_key_length);
228*10500SHai-May.Chao@Sun.COM 
229*10500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL)
230*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
231*10500SHai-May.Chao@Sun.COM 
232*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
233*10500SHai-May.Chao@Sun.COM 	case CKM_SHA256_HMAC:
234*10500SHai-May.Chao@Sun.COM 		if (message != NULL)
235*10500SHai-May.Chao@Sun.COM 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
236*10500SHai-May.Chao@Sun.COM 			    message, message_length);
237*10500SHai-May.Chao@Sun.COM 
238*10500SHai-May.Chao@Sun.COM 		SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
239*10500SHai-May.Chao@Sun.COM 		    hmac_computed);
240*10500SHai-May.Chao@Sun.COM 		break;
241*10500SHai-May.Chao@Sun.COM 
242*10500SHai-May.Chao@Sun.COM 	case CKM_SHA384_HMAC:
243*10500SHai-May.Chao@Sun.COM 		if (message != NULL)
244*10500SHai-May.Chao@Sun.COM 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
245*10500SHai-May.Chao@Sun.COM 			    message, message_length);
246*10500SHai-May.Chao@Sun.COM 
247*10500SHai-May.Chao@Sun.COM 		SOFT_MAC_FINAL_2(SHA384, &(hmac_ctx->hc_ctx_u.sha2_ctx),
248*10500SHai-May.Chao@Sun.COM 		    hmac_computed);
249*10500SHai-May.Chao@Sun.COM 		break;
250*10500SHai-May.Chao@Sun.COM 
251*10500SHai-May.Chao@Sun.COM 	case CKM_SHA512_HMAC:
252*10500SHai-May.Chao@Sun.COM 		if (message != NULL)
253*10500SHai-May.Chao@Sun.COM 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
254*10500SHai-May.Chao@Sun.COM 			    message, message_length);
255*10500SHai-May.Chao@Sun.COM 
256*10500SHai-May.Chao@Sun.COM 		SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
257*10500SHai-May.Chao@Sun.COM 		    hmac_computed);
258*10500SHai-May.Chao@Sun.COM 		break;
259*10500SHai-May.Chao@Sun.COM 	}
260*10500SHai-May.Chao@Sun.COM 
261*10500SHai-May.Chao@Sun.COM 	free(hmac_ctx);
262*10500SHai-May.Chao@Sun.COM 	return (CKR_OK);
263*10500SHai-May.Chao@Sun.COM }
264*10500SHai-May.Chao@Sun.COM 
265*10500SHai-May.Chao@Sun.COM #else
266*10500SHai-May.Chao@Sun.COM 
267*10500SHai-May.Chao@Sun.COM /*
268*10500SHai-May.Chao@Sun.COM  * Initialize a SHA2-HMAC context.
269*10500SHai-May.Chao@Sun.COM  */
270*10500SHai-May.Chao@Sun.COM void
271*10500SHai-May.Chao@Sun.COM sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
272*10500SHai-May.Chao@Sun.COM {
273*10500SHai-May.Chao@Sun.COM 	uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
274*10500SHai-May.Chao@Sun.COM 	uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
275*10500SHai-May.Chao@Sun.COM 	int i, block_size, blocks_per_int64;
276*10500SHai-May.Chao@Sun.COM 
277*10500SHai-May.Chao@Sun.COM 	/* Determine the block size */
278*10500SHai-May.Chao@Sun.COM 	if (ctx->hc_mech_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) {
279*10500SHai-May.Chao@Sun.COM 		block_size = SHA256_HMAC_BLOCK_SIZE;
280*10500SHai-May.Chao@Sun.COM 		blocks_per_int64 = SHA256_HMAC_BLOCK_SIZE / sizeof (uint64_t);
281*10500SHai-May.Chao@Sun.COM 	} else {
282*10500SHai-May.Chao@Sun.COM 		block_size = SHA512_HMAC_BLOCK_SIZE;
283*10500SHai-May.Chao@Sun.COM 		blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t);
284*10500SHai-May.Chao@Sun.COM 	}
285*10500SHai-May.Chao@Sun.COM 
286*10500SHai-May.Chao@Sun.COM 	(void) bzero(ipad, block_size);
287*10500SHai-May.Chao@Sun.COM 	(void) bzero(opad, block_size);
288*10500SHai-May.Chao@Sun.COM 	(void) bcopy(keyval, ipad, length_in_bytes);
289*10500SHai-May.Chao@Sun.COM 	(void) bcopy(keyval, opad, length_in_bytes);
290*10500SHai-May.Chao@Sun.COM 
291*10500SHai-May.Chao@Sun.COM 	/* XOR key with ipad (0x36) and opad (0x5c) */
292*10500SHai-May.Chao@Sun.COM 	for (i = 0; i < blocks_per_int64; i ++) {
293*10500SHai-May.Chao@Sun.COM 		ipad[i] ^= 0x3636363636363636;
294*10500SHai-May.Chao@Sun.COM 		opad[i] ^= 0x5c5c5c5c5c5c5c5c;
295*10500SHai-May.Chao@Sun.COM 	}
296*10500SHai-May.Chao@Sun.COM 
297*10500SHai-May.Chao@Sun.COM 	/* perform SHA2 on ipad */
298*10500SHai-May.Chao@Sun.COM 	SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext);
299*10500SHai-May.Chao@Sun.COM 	SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
300*10500SHai-May.Chao@Sun.COM 
301*10500SHai-May.Chao@Sun.COM 	/* perform SHA2 on opad */
302*10500SHai-May.Chao@Sun.COM 	SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext);
303*10500SHai-May.Chao@Sun.COM 	SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
304*10500SHai-May.Chao@Sun.COM 
305*10500SHai-May.Chao@Sun.COM }
306*10500SHai-May.Chao@Sun.COM 
307*10500SHai-May.Chao@Sun.COM sha2_hmac_ctx_t *
308*10500SHai-May.Chao@Sun.COM fips_sha2_hmac_build_context(sha2_mech_t mechanism,
309*10500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
310*10500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
311*10500SHai-May.Chao@Sun.COM {
312*10500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx_t *sha2_hmac_ctx_tmpl;
313*10500SHai-May.Chao@Sun.COM 
314*10500SHai-May.Chao@Sun.COM 	/*
315*10500SHai-May.Chao@Sun.COM 	 * Allocate and initialize SHA2 context.
316*10500SHai-May.Chao@Sun.COM 	 */
317*10500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx_tmpl = kmem_alloc(sizeof (sha2_hmac_ctx_t),
318*10500SHai-May.Chao@Sun.COM 	    KM_SLEEP);
319*10500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx_tmpl == NULL)
320*10500SHai-May.Chao@Sun.COM 		return (NULL);
321*10500SHai-May.Chao@Sun.COM 
322*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
323*10500SHai-May.Chao@Sun.COM 	case SHA256_TYPE:
324*10500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_tmpl->hc_mech_type =
325*10500SHai-May.Chao@Sun.COM 		    SHA256_HMAC_MECH_INFO_TYPE;
326*10500SHai-May.Chao@Sun.COM 		break;
327*10500SHai-May.Chao@Sun.COM 
328*10500SHai-May.Chao@Sun.COM 	case SHA384_TYPE:
329*10500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_tmpl->hc_mech_type =
330*10500SHai-May.Chao@Sun.COM 		    SHA384_HMAC_MECH_INFO_TYPE;
331*10500SHai-May.Chao@Sun.COM 		break;
332*10500SHai-May.Chao@Sun.COM 
333*10500SHai-May.Chao@Sun.COM 	case SHA512_TYPE:
334*10500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_tmpl->hc_mech_type =
335*10500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_MECH_INFO_TYPE;
336*10500SHai-May.Chao@Sun.COM 		break;
337*10500SHai-May.Chao@Sun.COM 	}
338*10500SHai-May.Chao@Sun.COM 
339*10500SHai-May.Chao@Sun.COM 	/*
340*10500SHai-May.Chao@Sun.COM 	 * initialize ctx->hc_icontext and ctx->hc_ocontext
341*10500SHai-May.Chao@Sun.COM 	 */
342*10500SHai-May.Chao@Sun.COM 	sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, secret_key,
343*10500SHai-May.Chao@Sun.COM 	    secret_key_length);
344*10500SHai-May.Chao@Sun.COM 
345*10500SHai-May.Chao@Sun.COM 	return (sha2_hmac_ctx_tmpl);
346*10500SHai-May.Chao@Sun.COM }
347*10500SHai-May.Chao@Sun.COM 
348*10500SHai-May.Chao@Sun.COM void
349*10500SHai-May.Chao@Sun.COM fips_hmac_sha2_hash(sha2_hmac_ctx_t *sha2_hmac_ctx,
350*10500SHai-May.Chao@Sun.COM 	uint8_t *message,
351*10500SHai-May.Chao@Sun.COM 	uint32_t message_len,
352*10500SHai-May.Chao@Sun.COM 	uint8_t *hmac_computed,
353*10500SHai-May.Chao@Sun.COM 	sha2_mech_t mechanism)
354*10500SHai-May.Chao@Sun.COM 
355*10500SHai-May.Chao@Sun.COM {
356*10500SHai-May.Chao@Sun.COM 
357*10500SHai-May.Chao@Sun.COM 	SHA2Update(&((sha2_hmac_ctx)->hc_icontext), message,
358*10500SHai-May.Chao@Sun.COM 	    message_len);
359*10500SHai-May.Chao@Sun.COM 	SHA2Final(hmac_computed, &((sha2_hmac_ctx)->hc_icontext));
360*10500SHai-May.Chao@Sun.COM 
361*10500SHai-May.Chao@Sun.COM 	switch (mechanism) {
362*10500SHai-May.Chao@Sun.COM 	case SHA256_TYPE:
363*10500SHai-May.Chao@Sun.COM 		SHA2Update(&((sha2_hmac_ctx)->hc_ocontext),
364*10500SHai-May.Chao@Sun.COM 		    hmac_computed, SHA256_DIGEST_LENGTH);
365*10500SHai-May.Chao@Sun.COM 		break;
366*10500SHai-May.Chao@Sun.COM 
367*10500SHai-May.Chao@Sun.COM 	case SHA384_TYPE:
368*10500SHai-May.Chao@Sun.COM 		SHA2Update(&((sha2_hmac_ctx)->hc_ocontext),
369*10500SHai-May.Chao@Sun.COM 		    hmac_computed, SHA384_DIGEST_LENGTH);
370*10500SHai-May.Chao@Sun.COM 		break;
371*10500SHai-May.Chao@Sun.COM 
372*10500SHai-May.Chao@Sun.COM 	case SHA512_TYPE:
373*10500SHai-May.Chao@Sun.COM 		SHA2Update(&((sha2_hmac_ctx)->hc_ocontext),
374*10500SHai-May.Chao@Sun.COM 			hmac_computed, SHA512_DIGEST_LENGTH);
375*10500SHai-May.Chao@Sun.COM 		break;
376*10500SHai-May.Chao@Sun.COM 	}
377*10500SHai-May.Chao@Sun.COM 
378*10500SHai-May.Chao@Sun.COM 	SHA2Final(hmac_computed, &((sha2_hmac_ctx)->hc_ocontext));
379*10500SHai-May.Chao@Sun.COM }
380*10500SHai-May.Chao@Sun.COM 
381*10500SHai-May.Chao@Sun.COM #endif
382*10500SHai-May.Chao@Sun.COM 
383*10500SHai-May.Chao@Sun.COM /*
384*10500SHai-May.Chao@Sun.COM  * SHA2 Power-On SelfTest(s).
385*10500SHai-May.Chao@Sun.COM  */
386*10500SHai-May.Chao@Sun.COM int
387*10500SHai-May.Chao@Sun.COM fips_sha2_post(void)
388*10500SHai-May.Chao@Sun.COM {
389*10500SHai-May.Chao@Sun.COM 
390*10500SHai-May.Chao@Sun.COM 	/*
391*10500SHai-May.Chao@Sun.COM 	 * SHA-256 Known Hash Message (512-bits).
392*10500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA256ShortMsg (Len = 512)
393*10500SHai-May.Chao@Sun.COM 	 */
394*10500SHai-May.Chao@Sun.COM 	static uint8_t sha256_known_hash_message[] = {
395*10500SHai-May.Chao@Sun.COM 		0x35, 0x92, 0xec, 0xfd, 0x1e, 0xac, 0x61, 0x8f,
396*10500SHai-May.Chao@Sun.COM 		0xd3, 0x90, 0xe7, 0xa9, 0xc2, 0x4b, 0x65, 0x65,
397*10500SHai-May.Chao@Sun.COM 		0x32, 0x50, 0x93, 0x67, 0xc2, 0x1a, 0x0e, 0xac,
398*10500SHai-May.Chao@Sun.COM 		0x12, 0x12, 0xac, 0x83, 0xc0, 0xb2, 0x0c, 0xd8,
399*10500SHai-May.Chao@Sun.COM 		0x96, 0xeb, 0x72, 0xb8, 0x01, 0xc4, 0xd2, 0x12,
400*10500SHai-May.Chao@Sun.COM 		0xc5, 0x45, 0x2b, 0xbb, 0xf0, 0x93, 0x17, 0xb5,
401*10500SHai-May.Chao@Sun.COM 		0x0c, 0x5c, 0x9f, 0xb1, 0x99, 0x75, 0x53, 0xd2,
402*10500SHai-May.Chao@Sun.COM 		0xbb, 0xc2, 0x9b, 0xb4, 0x2f, 0x57, 0x48, 0xad
403*10500SHai-May.Chao@Sun.COM 	};
404*10500SHai-May.Chao@Sun.COM 
405*10500SHai-May.Chao@Sun.COM 	/* known SHA256 Digest Message (32 bytes) */
406*10500SHai-May.Chao@Sun.COM 	static uint8_t known_sha256_digest[] = {
407*10500SHai-May.Chao@Sun.COM 		0x10, 0x5a, 0x60, 0x86, 0x58, 0x30, 0xac, 0x3a,
408*10500SHai-May.Chao@Sun.COM 		0x37, 0x1d, 0x38, 0x43, 0x32, 0x4d, 0x4b, 0xb5,
409*10500SHai-May.Chao@Sun.COM 		0xfa, 0x8e, 0xc0, 0xe0, 0x2d, 0xda, 0xa3, 0x89,
410*10500SHai-May.Chao@Sun.COM 		0xad, 0x8d, 0xa4, 0xf1, 0x02, 0x15, 0xc4, 0x54
411*10500SHai-May.Chao@Sun.COM 	};
412*10500SHai-May.Chao@Sun.COM 
413*10500SHai-May.Chao@Sun.COM 	/*
414*10500SHai-May.Chao@Sun.COM 	 * SHA-384 Known Hash Message (512-bits).
415*10500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA384ShortMsg (Len = 512)
416*10500SHai-May.Chao@Sun.COM 	 */
417*10500SHai-May.Chao@Sun.COM 	static uint8_t sha384_known_hash_message[] = {
418*10500SHai-May.Chao@Sun.COM 		0x58, 0xbe, 0xab, 0xf9, 0x79, 0xab, 0x35, 0xab,
419*10500SHai-May.Chao@Sun.COM 		0xba, 0x29, 0x37, 0x6d, 0x5d, 0xc2, 0x27, 0xab,
420*10500SHai-May.Chao@Sun.COM 		0xb3, 0xd2, 0xff, 0x4d, 0x90, 0x30, 0x49, 0x82,
421*10500SHai-May.Chao@Sun.COM 		0xfc, 0x10, 0x79, 0xbc, 0x2b, 0x28, 0x80, 0xfc,
422*10500SHai-May.Chao@Sun.COM 		0xb0, 0x12, 0x9e, 0x4f, 0xed, 0xf2, 0x78, 0x98,
423*10500SHai-May.Chao@Sun.COM 		0xce, 0x58, 0x6a, 0x91, 0xb7, 0x68, 0x1e, 0x0d,
424*10500SHai-May.Chao@Sun.COM 		0xba, 0x38, 0x5e, 0x80, 0x0e, 0x79, 0x26, 0xc0,
425*10500SHai-May.Chao@Sun.COM 		0xbc, 0x5a, 0xfe, 0x0d, 0x9c, 0xa9, 0x86, 0x50
426*10500SHai-May.Chao@Sun.COM 	};
427*10500SHai-May.Chao@Sun.COM 
428*10500SHai-May.Chao@Sun.COM 	/* known SHA384 Digest Message (48 bytes) */
429*10500SHai-May.Chao@Sun.COM 	static uint8_t known_sha384_digest[] = {
430*10500SHai-May.Chao@Sun.COM 		0xa0, 0x88, 0x8e, 0x1c, 0x4d, 0x7e, 0x80, 0xcb,
431*10500SHai-May.Chao@Sun.COM 		0xaa, 0xaf, 0xa8, 0xbb, 0x1c, 0xa1, 0xca, 0x91,
432*10500SHai-May.Chao@Sun.COM 		0x2a, 0x93, 0x21, 0x75, 0xc2, 0xef, 0x98, 0x2c,
433*10500SHai-May.Chao@Sun.COM 		0xe1, 0xf1, 0x23, 0xa8, 0xc1, 0xae, 0xe9, 0x63,
434*10500SHai-May.Chao@Sun.COM 		0x5a, 0xd7, 0x5b, 0xe5, 0x25, 0x90, 0xa9, 0x24,
435*10500SHai-May.Chao@Sun.COM 		0xbe, 0xd3, 0xf5, 0xec, 0x36, 0xc3, 0x56, 0x90
436*10500SHai-May.Chao@Sun.COM 	};
437*10500SHai-May.Chao@Sun.COM 
438*10500SHai-May.Chao@Sun.COM 	/*
439*10500SHai-May.Chao@Sun.COM 	 * SHA-512 Known Hash Message (512-bits).
440*10500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA512ShortMsg (Len = 512)
441*10500SHai-May.Chao@Sun.COM 	 */
442*10500SHai-May.Chao@Sun.COM 	static uint8_t sha512_known_hash_message[] = {
443*10500SHai-May.Chao@Sun.COM 		0x09, 0x5c, 0x7f, 0x30, 0x82, 0x4f, 0xc9, 0x28,
444*10500SHai-May.Chao@Sun.COM 		0x58, 0xcc, 0x93, 0x47, 0xc0, 0x85, 0xd5, 0x78,
445*10500SHai-May.Chao@Sun.COM 		0x88, 0x5f, 0xf3, 0x61, 0x4d, 0xd3, 0x8e, 0xe7,
446*10500SHai-May.Chao@Sun.COM 		0xee, 0x94, 0xa0, 0xf4, 0x40, 0x72, 0xc8, 0x77,
447*10500SHai-May.Chao@Sun.COM 		0x04, 0x7e, 0xe2, 0xad, 0x16, 0x6f, 0xdb, 0xa0,
448*10500SHai-May.Chao@Sun.COM 		0xe7, 0x44, 0xc3, 0xed, 0x2c, 0x2b, 0x24, 0xc9,
449*10500SHai-May.Chao@Sun.COM 		0xd8, 0xa2, 0x93, 0x46, 0x48, 0xdc, 0x84, 0xd3,
450*10500SHai-May.Chao@Sun.COM 		0xbe, 0x66, 0x63, 0x02, 0x11, 0x0a, 0xe0, 0x8f
451*10500SHai-May.Chao@Sun.COM 	};
452*10500SHai-May.Chao@Sun.COM 
453*10500SHai-May.Chao@Sun.COM 	/* known SHA512 Digest Message (64 bytes) */
454*10500SHai-May.Chao@Sun.COM 	static uint8_t known_sha512_digest[] = {
455*10500SHai-May.Chao@Sun.COM 		0xd5, 0xcd, 0xaf, 0x83, 0xbb, 0x4a, 0x27, 0xea,
456*10500SHai-May.Chao@Sun.COM 		0xad, 0x8d, 0x8f, 0x18, 0xe4, 0xbe, 0xe9, 0xc2,
457*10500SHai-May.Chao@Sun.COM 		0x5b, 0xe9, 0x49, 0xa7, 0x61, 0xa0, 0xfd, 0x0f,
458*10500SHai-May.Chao@Sun.COM 		0xb2, 0x28, 0x4c, 0xab, 0x14, 0x3c, 0xad, 0x60,
459*10500SHai-May.Chao@Sun.COM 		0xbe, 0xb5, 0x68, 0x87, 0x34, 0xb2, 0xf8, 0x1e,
460*10500SHai-May.Chao@Sun.COM 		0x9e, 0x2d, 0x64, 0x0b, 0x42, 0x5f, 0xd3, 0x2c,
461*10500SHai-May.Chao@Sun.COM 		0xcb, 0x3d, 0x20, 0xd0, 0x2d, 0x63, 0xc2, 0xc9,
462*10500SHai-May.Chao@Sun.COM 		0x4c, 0x03, 0xab, 0x3d, 0x9e, 0x7d, 0x9b, 0x4a
463*10500SHai-May.Chao@Sun.COM 	};
464*10500SHai-May.Chao@Sun.COM 
465*10500SHai-May.Chao@Sun.COM 	/* SHA-2 HMAC Test Vectors */
466*10500SHai-May.Chao@Sun.COM 
467*10500SHai-May.Chao@Sun.COM 	/*
468*10500SHai-May.Chao@Sun.COM 	 * SHA-256 HMAC Known Hash Message (512-bits).
469*10500SHai-May.Chao@Sun.COM 	 */
470*10500SHai-May.Chao@Sun.COM 	static uint8_t sha256_hmac_known_hash_message[] = {
471*10500SHai-May.Chao@Sun.COM 		0x54, 0x68, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74,
472*10500SHai-May.Chao@Sun.COM 		0x20, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
473*10500SHai-May.Chao@Sun.COM 		0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65,
474*10500SHai-May.Chao@Sun.COM 		0x20, 0x4D, 0x44, 0x32, 0x2C, 0x20, 0x4D, 0x44,
475*10500SHai-May.Chao@Sun.COM 		0x35, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x53,
476*10500SHai-May.Chao@Sun.COM 		0x48, 0x41, 0x2D, 0x31, 0x20, 0x68, 0x61, 0x73,
477*10500SHai-May.Chao@Sun.COM 		0x68, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x6C, 0x67,
478*10500SHai-May.Chao@Sun.COM 		0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x73, 0x2E
479*10500SHai-May.Chao@Sun.COM 	};
480*10500SHai-May.Chao@Sun.COM 
481*10500SHai-May.Chao@Sun.COM 	static uint8_t sha256_hmac_known_secret_key[] = {
482*10500SHai-May.Chao@Sun.COM 		0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
483*10500SHai-May.Chao@Sun.COM 		0x74, 0x68, 0x65, 0x20, 0x53, 0x48, 0x41, 0x2D,
484*10500SHai-May.Chao@Sun.COM 		0x32, 0x35, 0x36, 0x20, 0x48, 0x4D, 0x41, 0x43,
485*10500SHai-May.Chao@Sun.COM 		0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20,
486*10500SHai-May.Chao@Sun.COM 		0x6B, 0x65, 0x79, 0x21
487*10500SHai-May.Chao@Sun.COM 	};
488*10500SHai-May.Chao@Sun.COM 
489*10500SHai-May.Chao@Sun.COM 	static uint8_t sha256_hmac_known_secret_key_length
490*10500SHai-May.Chao@Sun.COM 	    = sizeof (sha256_hmac_known_secret_key);
491*10500SHai-May.Chao@Sun.COM 
492*10500SHai-May.Chao@Sun.COM 
493*10500SHai-May.Chao@Sun.COM 	/* known SHA256 hmac (32 bytes) */
494*10500SHai-May.Chao@Sun.COM 	static uint8_t known_sha256_hmac[] = {
495*10500SHai-May.Chao@Sun.COM 		0x02, 0x87, 0x21, 0x93, 0x84, 0x8a, 0x35, 0xae,
496*10500SHai-May.Chao@Sun.COM 		0xdb, 0xb6, 0x79, 0x26, 0x96, 0xf0, 0x50, 0xeb,
497*10500SHai-May.Chao@Sun.COM 		0x33, 0x49, 0x57, 0xf1, 0xb2, 0x32, 0xd3, 0x63,
498*10500SHai-May.Chao@Sun.COM 		0x03, 0x65, 0x57, 0xa2, 0xba, 0xa2, 0x5f, 0x35
499*10500SHai-May.Chao@Sun.COM 	};
500*10500SHai-May.Chao@Sun.COM 
501*10500SHai-May.Chao@Sun.COM 	/*
502*10500SHai-May.Chao@Sun.COM 	 * SHA-384 HMAC Known Hash Message (512-bits).
503*10500SHai-May.Chao@Sun.COM 	 * Source from NIST HMAC.txt (Count = 15, Klen = 16, Tlen = 48)
504*10500SHai-May.Chao@Sun.COM 	 */
505*10500SHai-May.Chao@Sun.COM 	static uint8_t sha384_hmac_known_secret_key[] = {
506*10500SHai-May.Chao@Sun.COM 		0x01, 0xac, 0x59, 0xf4, 0x2f, 0x8b, 0xb9, 0x1d,
507*10500SHai-May.Chao@Sun.COM 		0x1b, 0xd1, 0x0f, 0xe6, 0x99, 0x0d, 0x7a, 0x87
508*10500SHai-May.Chao@Sun.COM 	};
509*10500SHai-May.Chao@Sun.COM 
510*10500SHai-May.Chao@Sun.COM 	static uint8_t sha384_hmac_known_secret_key_length
511*10500SHai-May.Chao@Sun.COM 	    = sizeof (sha384_hmac_known_secret_key);
512*10500SHai-May.Chao@Sun.COM 
513*10500SHai-May.Chao@Sun.COM 	static uint8_t sha384_hmac_known_hash_message[] = {
514*10500SHai-May.Chao@Sun.COM 		0x3c, 0xaf, 0x18, 0xc4, 0x76, 0xed, 0xd5, 0x61,
515*10500SHai-May.Chao@Sun.COM 		0x5f, 0x34, 0x3a, 0xc7, 0xb7, 0xd3, 0xa9, 0xda,
516*10500SHai-May.Chao@Sun.COM 		0x9e, 0xfa, 0xde, 0x75, 0x56, 0x72, 0xd5, 0xba,
517*10500SHai-May.Chao@Sun.COM 		0x4b, 0x8a, 0xe8, 0xa7, 0x50, 0x55, 0x39, 0xea,
518*10500SHai-May.Chao@Sun.COM 		0x2c, 0x12, 0x4f, 0xf7, 0x55, 0xec, 0x04, 0x57,
519*10500SHai-May.Chao@Sun.COM 		0xfb, 0xe4, 0x9e, 0x43, 0x48, 0x0b, 0x3c, 0x71,
520*10500SHai-May.Chao@Sun.COM 		0xe7, 0xf4, 0x74, 0x2e, 0xc3, 0x69, 0x3a, 0xad,
521*10500SHai-May.Chao@Sun.COM 		0x11, 0x5d, 0x03, 0x9f, 0x90, 0x22, 0x2b, 0x03,
522*10500SHai-May.Chao@Sun.COM 		0x0f, 0xdc, 0x94, 0x40, 0x31, 0x36, 0x91, 0x71,
523*10500SHai-May.Chao@Sun.COM 		0x6d, 0x53, 0x02, 0x00, 0x58, 0x08, 0xc0, 0x76,
524*10500SHai-May.Chao@Sun.COM 		0x27, 0x48, 0x3b, 0x91, 0x6f, 0xdf, 0x61, 0x98,
525*10500SHai-May.Chao@Sun.COM 		0x30, 0x63, 0xc2, 0xeb, 0x12, 0x68, 0xf2, 0xde,
526*10500SHai-May.Chao@Sun.COM 		0xee, 0xf4, 0x2f, 0xc7, 0x90, 0x33, 0x44, 0x56,
527*10500SHai-May.Chao@Sun.COM 		0xbc, 0x6b, 0xad, 0x25, 0x6e, 0x31, 0xfc, 0x90,
528*10500SHai-May.Chao@Sun.COM 		0x66, 0xde, 0x7c, 0xc7, 0xe4, 0x3d, 0x13, 0x21,
529*10500SHai-May.Chao@Sun.COM 		0xb1, 0x86, 0x6d, 0xb4, 0x5e, 0x90, 0x56, 0x22
530*10500SHai-May.Chao@Sun.COM 	};
531*10500SHai-May.Chao@Sun.COM 
532*10500SHai-May.Chao@Sun.COM 	/* known SHA384 hmac (48 bytes) */
533*10500SHai-May.Chao@Sun.COM 	static uint8_t known_sha384_hmac[] = {
534*10500SHai-May.Chao@Sun.COM 		0x19, 0x85, 0xfa, 0x21, 0x63, 0xa5, 0x94, 0x3f,
535*10500SHai-May.Chao@Sun.COM 		0xc5, 0xd9, 0x2f, 0x1f, 0xe8, 0x83, 0x12, 0x15,
536*10500SHai-May.Chao@Sun.COM 		0xe7, 0xe9, 0x1f, 0x0b, 0xff, 0x53, 0x32, 0xbc,
537*10500SHai-May.Chao@Sun.COM 		0x71, 0x3a, 0x07, 0x2b, 0xdb, 0x3a, 0x8f, 0x9e,
538*10500SHai-May.Chao@Sun.COM 		0x5c, 0x51, 0x57, 0x46, 0x3a, 0x3b, 0xfe, 0xb3,
539*10500SHai-May.Chao@Sun.COM 		0x62, 0x31, 0x41, 0x6e, 0x65, 0x97, 0x3e, 0x64
540*10500SHai-May.Chao@Sun.COM 	};
541*10500SHai-May.Chao@Sun.COM 
542*10500SHai-May.Chao@Sun.COM 	/*
543*10500SHai-May.Chao@Sun.COM 	 * SHA-512 HMAC Known Hash Message (512-bits).
544*10500SHai-May.Chao@Sun.COM 	 * Source from NIST HMAC.txt (Count = 30, Klen = 20, Tlen = 64)
545*10500SHai-May.Chao@Sun.COM 	 */
546*10500SHai-May.Chao@Sun.COM 	static uint8_t sha512_hmac_known_secret_key[] = {
547*10500SHai-May.Chao@Sun.COM 		0xa7, 0x36, 0xf2, 0x74, 0xfd, 0xa6, 0x8e, 0x1b,
548*10500SHai-May.Chao@Sun.COM 		0xd5, 0xf9, 0x47, 0x1e, 0x85, 0xfd, 0x41, 0x5d,
549*10500SHai-May.Chao@Sun.COM 		0x7f, 0x2b, 0xa1, 0xbc
550*10500SHai-May.Chao@Sun.COM 	};
551*10500SHai-May.Chao@Sun.COM 
552*10500SHai-May.Chao@Sun.COM 	static uint8_t sha512_hmac_known_secret_key_length
553*10500SHai-May.Chao@Sun.COM 	    = sizeof (sha512_hmac_known_secret_key);
554*10500SHai-May.Chao@Sun.COM 
555*10500SHai-May.Chao@Sun.COM 	static uint8_t sha512_hmac_known_hash_message[] = {
556*10500SHai-May.Chao@Sun.COM 		0xa6, 0xcc, 0xc3, 0x55, 0x2c, 0x33, 0xe9, 0x17,
557*10500SHai-May.Chao@Sun.COM 		0x8b, 0x6b, 0x82, 0xc6, 0x53, 0xd6, 0x3d, 0xe2,
558*10500SHai-May.Chao@Sun.COM 		0x54, 0x0f, 0x17, 0x08, 0x07, 0xc3, 0xd9, 0x6a,
559*10500SHai-May.Chao@Sun.COM 		0x2a, 0xc2, 0xe2, 0x7d, 0xab, 0x55, 0x26, 0xf1,
560*10500SHai-May.Chao@Sun.COM 		0xc7, 0xd3, 0x77, 0xe6, 0x73, 0x6f, 0x04, 0x5d,
561*10500SHai-May.Chao@Sun.COM 		0xfb, 0x54, 0x1f, 0xec, 0xe9, 0xf4, 0x43, 0xb7,
562*10500SHai-May.Chao@Sun.COM 		0x28, 0x9c, 0x55, 0x9b, 0x69, 0x4c, 0x2a, 0xac,
563*10500SHai-May.Chao@Sun.COM 		0xc6, 0xc7, 0x4a, 0xe2, 0xa5, 0xe6, 0xf3, 0x0f,
564*10500SHai-May.Chao@Sun.COM 		0xe0, 0x31, 0x61, 0x14, 0x23, 0xb0, 0x4d, 0x55,
565*10500SHai-May.Chao@Sun.COM 		0x95, 0xff, 0xb4, 0x6a, 0xba, 0xa1, 0xd9, 0x18,
566*10500SHai-May.Chao@Sun.COM 		0x98, 0x96, 0x8d, 0x7f, 0x18, 0x30, 0xae, 0x94,
567*10500SHai-May.Chao@Sun.COM 		0xb0, 0x22, 0xee, 0xd2, 0x3f, 0xda, 0xd5, 0x2d,
568*10500SHai-May.Chao@Sun.COM 		0x38, 0x11, 0x0a, 0x48, 0x03, 0xa0, 0xce, 0xe7,
569*10500SHai-May.Chao@Sun.COM 		0xa0, 0x95, 0xc9, 0xa7, 0x8e, 0x86, 0x09, 0xed,
570*10500SHai-May.Chao@Sun.COM 		0xeb, 0x25, 0x48, 0x1c, 0xdc, 0x15, 0x6d, 0x0b,
571*10500SHai-May.Chao@Sun.COM 		0x2f, 0xfc, 0x56, 0xb6, 0x3f, 0xda, 0xd5, 0x33
572*10500SHai-May.Chao@Sun.COM 	};
573*10500SHai-May.Chao@Sun.COM 
574*10500SHai-May.Chao@Sun.COM 	/* known SHA512 hmac (64 bytes) */
575*10500SHai-May.Chao@Sun.COM 	static uint8_t known_sha512_hmac[] = {
576*10500SHai-May.Chao@Sun.COM 		0xf7, 0x18, 0x03, 0x43, 0x1e, 0x07, 0xa5, 0xa6,
577*10500SHai-May.Chao@Sun.COM 		0xe5, 0xfd, 0x4a, 0xe4, 0xcf, 0xc2, 0x75, 0x3b,
578*10500SHai-May.Chao@Sun.COM 		0xc8, 0x0d, 0x26, 0xe1, 0x67, 0x23, 0xd9, 0xe8,
579*10500SHai-May.Chao@Sun.COM 		0x8b, 0x40, 0x5a, 0x02, 0x34, 0x8e, 0xf4, 0xb9,
580*10500SHai-May.Chao@Sun.COM 		0x67, 0x92, 0xc9, 0x9c, 0xed, 0x64, 0xdc, 0x70,
581*10500SHai-May.Chao@Sun.COM 		0xea, 0x47, 0x53, 0x78, 0xb7, 0x46, 0x6a, 0xc2,
582*10500SHai-May.Chao@Sun.COM 		0xca, 0xf4, 0xa4, 0x20, 0xb0, 0x1f, 0xf6, 0x1e,
583*10500SHai-May.Chao@Sun.COM 		0x72, 0xc5, 0xb5, 0xee, 0x8e, 0xaa, 0xd4, 0xd4
584*10500SHai-May.Chao@Sun.COM 	};
585*10500SHai-May.Chao@Sun.COM 
586*10500SHai-May.Chao@Sun.COM 	/* SHA-2 variables. */
587*10500SHai-May.Chao@Sun.COM 	uint8_t sha256_computed_digest[SHA256_DIGEST_LENGTH];
588*10500SHai-May.Chao@Sun.COM 	uint8_t sha384_computed_digest[SHA384_DIGEST_LENGTH];
589*10500SHai-May.Chao@Sun.COM 	uint8_t sha512_computed_digest[SHA512_DIGEST_LENGTH];
590*10500SHai-May.Chao@Sun.COM 
591*10500SHai-May.Chao@Sun.COM 	uint8_t hmac_computed[SHA512_DIGEST_LENGTH];
592*10500SHai-May.Chao@Sun.COM 	SHA2_CTX *sha2_context = NULL;
593*10500SHai-May.Chao@Sun.COM 
594*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
595*10500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx_t *sha2_hmac_ctx;
596*10500SHai-May.Chao@Sun.COM #endif
597*10500SHai-May.Chao@Sun.COM 
598*10500SHai-May.Chao@Sun.COM 	int rv;
599*10500SHai-May.Chao@Sun.COM 
600*10500SHai-May.Chao@Sun.COM 	/*
601*10500SHai-May.Chao@Sun.COM 	 * SHA-2 Known Answer Hashing Test.
602*10500SHai-May.Chao@Sun.COM 	 */
603*10500SHai-May.Chao@Sun.COM 
604*10500SHai-May.Chao@Sun.COM 	/* SHA-256 POST */
605*10500SHai-May.Chao@Sun.COM 
606*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
607*10500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(SHA256_TYPE);
608*10500SHai-May.Chao@Sun.COM #else
609*10500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(CKM_SHA256);
610*10500SHai-May.Chao@Sun.COM #endif
611*10500SHai-May.Chao@Sun.COM 
612*10500SHai-May.Chao@Sun.COM 	if (sha2_context == NULL)
613*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
614*10500SHai-May.Chao@Sun.COM 
615*10500SHai-May.Chao@Sun.COM 	rv = fips_sha2_hash(sha2_context,
616*10500SHai-May.Chao@Sun.COM 	    sha256_known_hash_message,
617*10500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
618*10500SHai-May.Chao@Sun.COM 	    sha256_computed_digest);
619*10500SHai-May.Chao@Sun.COM 
620*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
621*10500SHai-May.Chao@Sun.COM 	    (memcmp(sha256_computed_digest, known_sha256_digest,
622*10500SHai-May.Chao@Sun.COM 	    SHA256_DIGEST_LENGTH) != 0))
623*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
624*10500SHai-May.Chao@Sun.COM 
625*10500SHai-May.Chao@Sun.COM 	/* SHA-384 POST */
626*10500SHai-May.Chao@Sun.COM 
627*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
628*10500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(SHA384_TYPE);
629*10500SHai-May.Chao@Sun.COM #else
630*10500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(CKM_SHA384);
631*10500SHai-May.Chao@Sun.COM #endif
632*10500SHai-May.Chao@Sun.COM 
633*10500SHai-May.Chao@Sun.COM 	if (sha2_context == NULL)
634*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
635*10500SHai-May.Chao@Sun.COM 
636*10500SHai-May.Chao@Sun.COM 	rv = fips_sha2_hash(sha2_context,
637*10500SHai-May.Chao@Sun.COM 	    sha384_known_hash_message,
638*10500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
639*10500SHai-May.Chao@Sun.COM 	    sha384_computed_digest);
640*10500SHai-May.Chao@Sun.COM 
641*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
642*10500SHai-May.Chao@Sun.COM 	    (memcmp(sha384_computed_digest, known_sha384_digest,
643*10500SHai-May.Chao@Sun.COM 	    SHA384_DIGEST_LENGTH) != 0))
644*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
645*10500SHai-May.Chao@Sun.COM 
646*10500SHai-May.Chao@Sun.COM 	/* SHA-512 POST */
647*10500SHai-May.Chao@Sun.COM 
648*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
649*10500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(SHA512_TYPE);
650*10500SHai-May.Chao@Sun.COM #else
651*10500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(CKM_SHA512);
652*10500SHai-May.Chao@Sun.COM #endif
653*10500SHai-May.Chao@Sun.COM 
654*10500SHai-May.Chao@Sun.COM 	if (sha2_context == NULL)
655*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
656*10500SHai-May.Chao@Sun.COM 
657*10500SHai-May.Chao@Sun.COM 	rv = fips_sha2_hash(sha2_context,
658*10500SHai-May.Chao@Sun.COM 	    sha512_known_hash_message,
659*10500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
660*10500SHai-May.Chao@Sun.COM 	    sha512_computed_digest);
661*10500SHai-May.Chao@Sun.COM 
662*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
663*10500SHai-May.Chao@Sun.COM 	    (memcmp(sha512_computed_digest, known_sha512_digest,
664*10500SHai-May.Chao@Sun.COM 	    SHA512_DIGEST_LENGTH) != 0))
665*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
666*10500SHai-May.Chao@Sun.COM 
667*10500SHai-May.Chao@Sun.COM 	/*
668*10500SHai-May.Chao@Sun.COM 	 * SHA-2 HMAC Known Answer Hashing Test.
669*10500SHai-May.Chao@Sun.COM 	 */
670*10500SHai-May.Chao@Sun.COM 
671*10500SHai-May.Chao@Sun.COM 	/* HMAC SHA-256 POST */
672*10500SHai-May.Chao@Sun.COM 
673*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
674*10500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx = fips_sha2_hmac_build_context(
675*10500SHai-May.Chao@Sun.COM 	    SHA256_TYPE,
676*10500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key,
677*10500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key_length);
678*10500SHai-May.Chao@Sun.COM 
679*10500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx == NULL)
680*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
681*10500SHai-May.Chao@Sun.COM 
682*10500SHai-May.Chao@Sun.COM 	fips_hmac_sha2_hash(sha2_hmac_ctx,
683*10500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_hash_message,
684*10500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
685*10500SHai-May.Chao@Sun.COM 	    hmac_computed,
686*10500SHai-May.Chao@Sun.COM 	    SHA256_TYPE);
687*10500SHai-May.Chao@Sun.COM 
688*10500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_sha256_hmac,
689*10500SHai-May.Chao@Sun.COM 	    SHA256_DIGEST_LENGTH) != 0)
690*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
691*10500SHai-May.Chao@Sun.COM 
692*10500SHai-May.Chao@Sun.COM #else
693*10500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha2_hash(hmac_computed,
694*10500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key,
695*10500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key_length,
696*10500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_hash_message,
697*10500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
698*10500SHai-May.Chao@Sun.COM 	    CKM_SHA256_HMAC);
699*10500SHai-May.Chao@Sun.COM 
700*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
701*10500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_sha256_hmac,
702*10500SHai-May.Chao@Sun.COM 	    SHA256_DIGEST_LENGTH) != 0))
703*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
704*10500SHai-May.Chao@Sun.COM 
705*10500SHai-May.Chao@Sun.COM #endif
706*10500SHai-May.Chao@Sun.COM 
707*10500SHai-May.Chao@Sun.COM 	/* HMAC SHA-384 POST */
708*10500SHai-May.Chao@Sun.COM 
709*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
710*10500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx = fips_sha2_hmac_build_context(
711*10500SHai-May.Chao@Sun.COM 	    SHA384_TYPE,
712*10500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key,
713*10500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key_length);
714*10500SHai-May.Chao@Sun.COM 
715*10500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx == NULL)
716*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
717*10500SHai-May.Chao@Sun.COM 
718*10500SHai-May.Chao@Sun.COM 	fips_hmac_sha2_hash(sha2_hmac_ctx,
719*10500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_hash_message,
720*10500SHai-May.Chao@Sun.COM 	    sizeof (sha384_hmac_known_hash_message),
721*10500SHai-May.Chao@Sun.COM 	    hmac_computed,
722*10500SHai-May.Chao@Sun.COM 	    SHA384_TYPE);
723*10500SHai-May.Chao@Sun.COM 
724*10500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_sha384_hmac,
725*10500SHai-May.Chao@Sun.COM 	    SHA384_DIGEST_LENGTH) != 0)
726*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
727*10500SHai-May.Chao@Sun.COM #else
728*10500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha2_hash(hmac_computed,
729*10500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key,
730*10500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key_length,
731*10500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_hash_message,
732*10500SHai-May.Chao@Sun.COM 	    sizeof (sha384_hmac_known_hash_message),
733*10500SHai-May.Chao@Sun.COM 	    CKM_SHA384_HMAC);
734*10500SHai-May.Chao@Sun.COM 
735*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
736*10500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_sha384_hmac,
737*10500SHai-May.Chao@Sun.COM 	    SHA384_DIGEST_LENGTH) != 0))
738*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
739*10500SHai-May.Chao@Sun.COM 
740*10500SHai-May.Chao@Sun.COM #endif
741*10500SHai-May.Chao@Sun.COM 
742*10500SHai-May.Chao@Sun.COM 	/* HMAC SHA-512 POST */
743*10500SHai-May.Chao@Sun.COM 
744*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
745*10500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx = fips_sha2_hmac_build_context(
746*10500SHai-May.Chao@Sun.COM 	    SHA512_TYPE,
747*10500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key,
748*10500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key_length);
749*10500SHai-May.Chao@Sun.COM 
750*10500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx == NULL)
751*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
752*10500SHai-May.Chao@Sun.COM 
753*10500SHai-May.Chao@Sun.COM 	fips_hmac_sha2_hash(sha2_hmac_ctx,
754*10500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_hash_message,
755*10500SHai-May.Chao@Sun.COM 	    sizeof (sha512_hmac_known_hash_message),
756*10500SHai-May.Chao@Sun.COM 	    hmac_computed,
757*10500SHai-May.Chao@Sun.COM 	    SHA512_TYPE);
758*10500SHai-May.Chao@Sun.COM 
759*10500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_sha512_hmac,
760*10500SHai-May.Chao@Sun.COM 	    SHA512_DIGEST_LENGTH) != 0)
761*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
762*10500SHai-May.Chao@Sun.COM 
763*10500SHai-May.Chao@Sun.COM #else
764*10500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha2_hash(hmac_computed,
765*10500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key,
766*10500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key_length,
767*10500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_hash_message,
768*10500SHai-May.Chao@Sun.COM 	    sizeof (sha512_hmac_known_hash_message),
769*10500SHai-May.Chao@Sun.COM 	    CKM_SHA512_HMAC);
770*10500SHai-May.Chao@Sun.COM 
771*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
772*10500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_sha512_hmac,
773*10500SHai-May.Chao@Sun.COM 	    SHA512_DIGEST_LENGTH) != 0))
774*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
775*10500SHai-May.Chao@Sun.COM 
776*10500SHai-May.Chao@Sun.COM #endif
777*10500SHai-May.Chao@Sun.COM 
778*10500SHai-May.Chao@Sun.COM 	return (CKR_OK);
779*10500SHai-May.Chao@Sun.COM }
780