xref: /onnv-gate/usr/src/common/crypto/fips/fips_sha1_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/errno.h>
29*10500SHai-May.Chao@Sun.COM #include <sys/kmem.h>
30*10500SHai-May.Chao@Sun.COM #include <sys/systm.h>
31*10500SHai-May.Chao@Sun.COM #include <sys/sha1.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 <sha1/sha1_impl.h>
44*10500SHai-May.Chao@Sun.COM 
45*10500SHai-May.Chao@Sun.COM /*
46*10500SHai-May.Chao@Sun.COM  * fips_sha1_build_context()
47*10500SHai-May.Chao@Sun.COM  *
48*10500SHai-May.Chao@Sun.COM  * Description:
49*10500SHai-May.Chao@Sun.COM  *	This function allocates and initializes SHA1 context
50*10500SHai-May.Chao@Sun.COM  *	context.
51*10500SHai-May.Chao@Sun.COM  */
52*10500SHai-May.Chao@Sun.COM SHA1_CTX *
53*10500SHai-May.Chao@Sun.COM fips_sha1_build_context(void)
54*10500SHai-May.Chao@Sun.COM {
55*10500SHai-May.Chao@Sun.COM 	SHA1_CTX *sha1_context;
56*10500SHai-May.Chao@Sun.COM 
57*10500SHai-May.Chao@Sun.COM 
58*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL
59*10500SHai-May.Chao@Sun.COM 	if ((sha1_context = malloc(sizeof (SHA1_CTX))) == NULL)
60*10500SHai-May.Chao@Sun.COM #else
61*10500SHai-May.Chao@Sun.COM 	if ((sha1_context = kmem_zalloc(sizeof (SHA1_CTX),
62*10500SHai-May.Chao@Sun.COM 	    KM_SLEEP)) == NULL)
63*10500SHai-May.Chao@Sun.COM #endif
64*10500SHai-May.Chao@Sun.COM 		return (NULL);
65*10500SHai-May.Chao@Sun.COM 
66*10500SHai-May.Chao@Sun.COM 	SHA1Init(sha1_context);
67*10500SHai-May.Chao@Sun.COM 
68*10500SHai-May.Chao@Sun.COM 	return (sha1_context);
69*10500SHai-May.Chao@Sun.COM 
70*10500SHai-May.Chao@Sun.COM }
71*10500SHai-May.Chao@Sun.COM 
72*10500SHai-May.Chao@Sun.COM /*
73*10500SHai-May.Chao@Sun.COM  * fips_sha1_hash()
74*10500SHai-May.Chao@Sun.COM  *
75*10500SHai-May.Chao@Sun.COM  * Arguments:
76*10500SHai-May.Chao@Sun.COM  *	sha1_context:	pointer to SHA1 context
77*10500SHai-May.Chao@Sun.COM  *	in:	pointer to the input data to be hashed
78*10500SHai-May.Chao@Sun.COM  *	inlen:	length of the input data
79*10500SHai-May.Chao@Sun.COM  *	out:	pointer to the output data after hashing
80*10500SHai-May.Chao@Sun.COM  *
81*10500SHai-May.Chao@Sun.COM  * Description:
82*10500SHai-May.Chao@Sun.COM  *	This function calls the low-level SHA1 routines for hashing.
83*10500SHai-May.Chao@Sun.COM  *
84*10500SHai-May.Chao@Sun.COM  */
85*10500SHai-May.Chao@Sun.COM int
86*10500SHai-May.Chao@Sun.COM fips_sha1_hash(SHA1_CTX *sha1_context, uchar_t *in, ulong_t inlen, uchar_t *out)
87*10500SHai-May.Chao@Sun.COM {
88*10500SHai-May.Chao@Sun.COM 
89*10500SHai-May.Chao@Sun.COM 	if (in != NULL) {
90*10500SHai-May.Chao@Sun.COM #ifdef	__sparcv9
91*10500SHai-May.Chao@Sun.COM 		SHA1Update((SHA1_CTX *)sha1_context, in, (uint_t)inlen);
92*10500SHai-May.Chao@Sun.COM #else	/* !__sparcv9 */
93*10500SHai-May.Chao@Sun.COM 		SHA1Update((SHA1_CTX *)sha1_context, in, inlen);
94*10500SHai-May.Chao@Sun.COM #endif	/* __sparcv9 */
95*10500SHai-May.Chao@Sun.COM 		SHA1Final(out, (SHA1_CTX *)sha1_context);
96*10500SHai-May.Chao@Sun.COM 		return (CKR_OK);
97*10500SHai-May.Chao@Sun.COM 	} else
98*10500SHai-May.Chao@Sun.COM 		return (CKR_ARGUMENTS_BAD);
99*10500SHai-May.Chao@Sun.COM 
100*10500SHai-May.Chao@Sun.COM }
101*10500SHai-May.Chao@Sun.COM 
102*10500SHai-May.Chao@Sun.COM 
103*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL
104*10500SHai-May.Chao@Sun.COM soft_hmac_ctx_t *
105*10500SHai-May.Chao@Sun.COM fips_sha1_hmac_build_context(uint8_t *secret_key,
106*10500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
107*10500SHai-May.Chao@Sun.COM {
108*10500SHai-May.Chao@Sun.COM 
109*10500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx;
110*10500SHai-May.Chao@Sun.COM 	uint32_t sha1_ipad[SHA1_HMAC_INTS_PER_BLOCK];
111*10500SHai-May.Chao@Sun.COM 	uint32_t sha1_opad[SHA1_HMAC_INTS_PER_BLOCK];
112*10500SHai-May.Chao@Sun.COM 
113*10500SHai-May.Chao@Sun.COM 	hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
114*10500SHai-May.Chao@Sun.COM 
115*10500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL) {
116*10500SHai-May.Chao@Sun.COM 		return (NULL);
117*10500SHai-May.Chao@Sun.COM 	}
118*10500SHai-May.Chao@Sun.COM 
119*10500SHai-May.Chao@Sun.COM 	hmac_ctx->hmac_len = SHA1_HASH_SIZE;
120*10500SHai-May.Chao@Sun.COM 	bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
121*10500SHai-May.Chao@Sun.COM 	bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
122*10500SHai-May.Chao@Sun.COM 
123*10500SHai-May.Chao@Sun.COM 	(void) memcpy(sha1_ipad, secret_key, secret_key_length);
124*10500SHai-May.Chao@Sun.COM 	(void) memcpy(sha1_opad, secret_key, secret_key_length);
125*10500SHai-May.Chao@Sun.COM 
126*10500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_init(&hmac_ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
127*10500SHai-May.Chao@Sun.COM 	    sha1_opad);
128*10500SHai-May.Chao@Sun.COM 
129*10500SHai-May.Chao@Sun.COM 	return (hmac_ctx);
130*10500SHai-May.Chao@Sun.COM 
131*10500SHai-May.Chao@Sun.COM }
132*10500SHai-May.Chao@Sun.COM 
133*10500SHai-May.Chao@Sun.COM CK_RV
134*10500SHai-May.Chao@Sun.COM fips_hmac_sha1_hash(unsigned char *hmac_computed,
135*10500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
136*10500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length,
137*10500SHai-May.Chao@Sun.COM 	uint8_t *message,
138*10500SHai-May.Chao@Sun.COM 	unsigned int message_length)
139*10500SHai-May.Chao@Sun.COM {
140*10500SHai-May.Chao@Sun.COM 
141*10500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx = NULL;
142*10500SHai-May.Chao@Sun.COM 
143*10500SHai-May.Chao@Sun.COM 	hmac_ctx = fips_sha1_hmac_build_context(secret_key,
144*10500SHai-May.Chao@Sun.COM 	    secret_key_length);
145*10500SHai-May.Chao@Sun.COM 
146*10500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL)
147*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
148*10500SHai-May.Chao@Sun.COM 
149*10500SHai-May.Chao@Sun.COM 	if (message != NULL) {
150*10500SHai-May.Chao@Sun.COM 		SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx),
151*10500SHai-May.Chao@Sun.COM 		    message, message_length);
152*10500SHai-May.Chao@Sun.COM 	}
153*10500SHai-May.Chao@Sun.COM 
154*10500SHai-May.Chao@Sun.COM 	SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), hmac_computed);
155*10500SHai-May.Chao@Sun.COM 
156*10500SHai-May.Chao@Sun.COM 	free(hmac_ctx);
157*10500SHai-May.Chao@Sun.COM 	return (CKR_OK);
158*10500SHai-May.Chao@Sun.COM }
159*10500SHai-May.Chao@Sun.COM 
160*10500SHai-May.Chao@Sun.COM #else /* _KERNEL */
161*10500SHai-May.Chao@Sun.COM 
162*10500SHai-May.Chao@Sun.COM /*
163*10500SHai-May.Chao@Sun.COM  * Initialize a SHA1-HMAC context.
164*10500SHai-May.Chao@Sun.COM  */
165*10500SHai-May.Chao@Sun.COM void
166*10500SHai-May.Chao@Sun.COM sha1_mac_init_ctx(sha1_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
167*10500SHai-May.Chao@Sun.COM {
168*10500SHai-May.Chao@Sun.COM 	uint32_t ipad[SHA1_HMAC_INTS_PER_BLOCK];
169*10500SHai-May.Chao@Sun.COM 	uint32_t opad[SHA1_HMAC_INTS_PER_BLOCK];
170*10500SHai-May.Chao@Sun.COM 	uint_t i;
171*10500SHai-May.Chao@Sun.COM 
172*10500SHai-May.Chao@Sun.COM 	bzero(ipad, SHA1_HMAC_BLOCK_SIZE);
173*10500SHai-May.Chao@Sun.COM 	bzero(opad, SHA1_HMAC_BLOCK_SIZE);
174*10500SHai-May.Chao@Sun.COM 
175*10500SHai-May.Chao@Sun.COM 	bcopy(keyval, ipad, length_in_bytes);
176*10500SHai-May.Chao@Sun.COM 	bcopy(keyval, opad, length_in_bytes);
177*10500SHai-May.Chao@Sun.COM 
178*10500SHai-May.Chao@Sun.COM 	/* XOR key with ipad (0x36) and opad (0x5c) */
179*10500SHai-May.Chao@Sun.COM 	for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
180*10500SHai-May.Chao@Sun.COM 		ipad[i] ^= 0x36363636;
181*10500SHai-May.Chao@Sun.COM 		opad[i] ^= 0x5c5c5c5c;
182*10500SHai-May.Chao@Sun.COM 	}
183*10500SHai-May.Chao@Sun.COM 
184*10500SHai-May.Chao@Sun.COM 	/* perform SHA1 on ipad */
185*10500SHai-May.Chao@Sun.COM 	SHA1Init(&ctx->hc_icontext);
186*10500SHai-May.Chao@Sun.COM 	SHA1Update(&ctx->hc_icontext, (uint8_t *)ipad, SHA1_HMAC_BLOCK_SIZE);
187*10500SHai-May.Chao@Sun.COM 
188*10500SHai-May.Chao@Sun.COM 	/* perform SHA1 on opad */
189*10500SHai-May.Chao@Sun.COM 	SHA1Init(&ctx->hc_ocontext);
190*10500SHai-May.Chao@Sun.COM 	SHA1Update(&ctx->hc_ocontext, (uint8_t *)opad, SHA1_HMAC_BLOCK_SIZE);
191*10500SHai-May.Chao@Sun.COM }
192*10500SHai-May.Chao@Sun.COM 
193*10500SHai-May.Chao@Sun.COM sha1_hmac_ctx_t *
194*10500SHai-May.Chao@Sun.COM fips_sha1_hmac_build_context(uint8_t *secret_key,
195*10500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
196*10500SHai-May.Chao@Sun.COM {
197*10500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_t *sha1_hmac_ctx_tmpl;
198*10500SHai-May.Chao@Sun.COM 
199*10500SHai-May.Chao@Sun.COM 
200*10500SHai-May.Chao@Sun.COM 	/*
201*10500SHai-May.Chao@Sun.COM 	 * Allocate and initialize SHA1 context.
202*10500SHai-May.Chao@Sun.COM 	 */
203*10500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_tmpl = kmem_alloc(sizeof (sha1_hmac_ctx_t),
204*10500SHai-May.Chao@Sun.COM 	    KM_SLEEP);
205*10500SHai-May.Chao@Sun.COM 	if (sha1_hmac_ctx_tmpl == NULL)
206*10500SHai-May.Chao@Sun.COM 		return (NULL);
207*10500SHai-May.Chao@Sun.COM 
208*10500SHai-May.Chao@Sun.COM 	/*
209*10500SHai-May.Chao@Sun.COM 	 * initialize ctx->hc_icontext and ctx->hc_ocontext
210*10500SHai-May.Chao@Sun.COM 	 */
211*10500SHai-May.Chao@Sun.COM 	sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, secret_key,
212*10500SHai-May.Chao@Sun.COM 	    secret_key_length);
213*10500SHai-May.Chao@Sun.COM 
214*10500SHai-May.Chao@Sun.COM 
215*10500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_tmpl->hc_mech_type = SHA1_HMAC_MECH_INFO_TYPE;
216*10500SHai-May.Chao@Sun.COM 
217*10500SHai-May.Chao@Sun.COM 
218*10500SHai-May.Chao@Sun.COM 	return (sha1_hmac_ctx_tmpl);
219*10500SHai-May.Chao@Sun.COM }
220*10500SHai-May.Chao@Sun.COM 
221*10500SHai-May.Chao@Sun.COM void
222*10500SHai-May.Chao@Sun.COM fips_hmac_sha1_hash(sha1_hmac_ctx_t *sha1_hmac_ctx,
223*10500SHai-May.Chao@Sun.COM 	uint8_t *message, uint32_t message_len,
224*10500SHai-May.Chao@Sun.COM 	uint8_t *hmac_computed)
225*10500SHai-May.Chao@Sun.COM {
226*10500SHai-May.Chao@Sun.COM 
227*10500SHai-May.Chao@Sun.COM 	/* do a SHA1 update of the inner context using the specified data */
228*10500SHai-May.Chao@Sun.COM 	SHA1Update(&((sha1_hmac_ctx)->hc_icontext), message,
229*10500SHai-May.Chao@Sun.COM 	    message_len);
230*10500SHai-May.Chao@Sun.COM 
231*10500SHai-May.Chao@Sun.COM 	/*
232*10500SHai-May.Chao@Sun.COM 	 * Do a SHA1 final on the inner context.
233*10500SHai-May.Chao@Sun.COM 	 */
234*10500SHai-May.Chao@Sun.COM 	SHA1Final(hmac_computed, &((sha1_hmac_ctx)->hc_icontext));
235*10500SHai-May.Chao@Sun.COM 
236*10500SHai-May.Chao@Sun.COM 	/*
237*10500SHai-May.Chao@Sun.COM 	 * Do an SHA1 update on the outer context, feeding the inner
238*10500SHai-May.Chao@Sun.COM 	 * digest as data.
239*10500SHai-May.Chao@Sun.COM 	 */
240*10500SHai-May.Chao@Sun.COM 	SHA1Update(&((sha1_hmac_ctx)->hc_ocontext), hmac_computed,
241*10500SHai-May.Chao@Sun.COM 	    SHA1_HASH_SIZE);
242*10500SHai-May.Chao@Sun.COM 
243*10500SHai-May.Chao@Sun.COM 	/*
244*10500SHai-May.Chao@Sun.COM 	 * Do a SHA1 final on the outer context, storing the computed
245*10500SHai-May.Chao@Sun.COM 	 * digest in the caller's buffer.
246*10500SHai-May.Chao@Sun.COM 	 */
247*10500SHai-May.Chao@Sun.COM 	SHA1Final(hmac_computed, &((sha1_hmac_ctx)->hc_ocontext));
248*10500SHai-May.Chao@Sun.COM 
249*10500SHai-May.Chao@Sun.COM }
250*10500SHai-May.Chao@Sun.COM 
251*10500SHai-May.Chao@Sun.COM #endif
252*10500SHai-May.Chao@Sun.COM 
253*10500SHai-May.Chao@Sun.COM /*
254*10500SHai-May.Chao@Sun.COM  * SHA1 Power-On SelfTest(s).
255*10500SHai-May.Chao@Sun.COM  */
256*10500SHai-May.Chao@Sun.COM int
257*10500SHai-May.Chao@Sun.COM fips_sha1_post(void)
258*10500SHai-May.Chao@Sun.COM {
259*10500SHai-May.Chao@Sun.COM 
260*10500SHai-May.Chao@Sun.COM 	/*
261*10500SHai-May.Chao@Sun.COM 	 * SHA-1 Known Hash Message
262*10500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA1ShortMsg (L = 512-bits).
263*10500SHai-May.Chao@Sun.COM 	 */
264*10500SHai-May.Chao@Sun.COM 	static uint8_t sha1_known_hash_message[] = {
265*10500SHai-May.Chao@Sun.COM 		0x7e, 0x3a, 0x4c, 0x32, 0x5c, 0xb9, 0xc5, 0x2b,
266*10500SHai-May.Chao@Sun.COM 		0x88, 0x38, 0x7f, 0x93, 0xd0, 0x1a, 0xe8, 0x6d,
267*10500SHai-May.Chao@Sun.COM 		0x42, 0x09, 0x8f, 0x5e, 0xfa, 0x7f, 0x94, 0x57,
268*10500SHai-May.Chao@Sun.COM 		0x38, 0x8b, 0x5e, 0x74, 0xb6, 0xd2, 0x8b, 0x24,
269*10500SHai-May.Chao@Sun.COM 		0x38, 0xd4, 0x2d, 0x8b, 0x64, 0x70, 0x33, 0x24,
270*10500SHai-May.Chao@Sun.COM 		0xd4, 0xaa, 0x25, 0xab, 0x6a, 0xad, 0x15, 0x3a,
271*10500SHai-May.Chao@Sun.COM 		0xe3, 0x0c, 0xd2, 0xb2, 0xaf, 0x4d, 0x5e, 0x5c,
272*10500SHai-May.Chao@Sun.COM 		0x00, 0xa8, 0xa2, 0xd0, 0x22, 0x0c, 0x61, 0x16
273*10500SHai-May.Chao@Sun.COM 	};
274*10500SHai-May.Chao@Sun.COM 
275*10500SHai-May.Chao@Sun.COM 	/* SHA-1 Known Digest Message (160-bits). */
276*10500SHai-May.Chao@Sun.COM 	static  uint8_t sha1_known_digest[] = {
277*10500SHai-May.Chao@Sun.COM 		0xa3, 0x05, 0x44, 0x27, 0xcd, 0xb1, 0x3f, 0x16,
278*10500SHai-May.Chao@Sun.COM 		0x4a, 0x61, 0x0b, 0x34, 0x87, 0x02, 0x72, 0x4c,
279*10500SHai-May.Chao@Sun.COM 		0x80, 0x8a, 0x0d, 0xcc
280*10500SHai-May.Chao@Sun.COM 	};
281*10500SHai-May.Chao@Sun.COM 
282*10500SHai-May.Chao@Sun.COM 	/* Source from NIST HMAC.txt Count = 0 */
283*10500SHai-May.Chao@Sun.COM 	static uint8_t HMAC_known_secret_key[] = {
284*10500SHai-May.Chao@Sun.COM 		0x7b, 0x10, 0xf4, 0x12, 0x4b, 0x15, 0xc8, 0x2e
285*10500SHai-May.Chao@Sun.COM 	};
286*10500SHai-May.Chao@Sun.COM 
287*10500SHai-May.Chao@Sun.COM 	static uint8_t HMAC_known_secret_key_length
288*10500SHai-May.Chao@Sun.COM 	    = sizeof (HMAC_known_secret_key);
289*10500SHai-May.Chao@Sun.COM 
290*10500SHai-May.Chao@Sun.COM 	/* known SHA1 hmac - truncated (10 bytes) */
291*10500SHai-May.Chao@Sun.COM 	static uint8_t known_SHA1_hmac[] = {
292*10500SHai-May.Chao@Sun.COM 		0x4e, 0xad, 0x12, 0xc2, 0xfe, 0x3d, 0x6e, 0xa4,
293*10500SHai-May.Chao@Sun.COM 		0x3a, 0xcb
294*10500SHai-May.Chao@Sun.COM 	};
295*10500SHai-May.Chao@Sun.COM 
296*10500SHai-May.Chao@Sun.COM 	static uint8_t hmac_sha1_known_hash_message[] = {
297*10500SHai-May.Chao@Sun.COM 		0x27, 0xdc, 0xb5, 0xb1, 0xda, 0xf6, 0x0c, 0xfd,
298*10500SHai-May.Chao@Sun.COM 		0x3e, 0x2f, 0x73, 0xd4, 0xd6, 0x4c, 0xa9, 0xc6,
299*10500SHai-May.Chao@Sun.COM 		0x84, 0xf8, 0xbf, 0x71, 0xfc, 0x68, 0x2a, 0x46,
300*10500SHai-May.Chao@Sun.COM 		0x79, 0x3b, 0x17, 0x90, 0xaf, 0xa4, 0xfe, 0xb1,
301*10500SHai-May.Chao@Sun.COM 		0x00, 0xca, 0x7a, 0xaf, 0xf2, 0x6f, 0x58, 0xf0,
302*10500SHai-May.Chao@Sun.COM 		0xe1, 0xd0, 0xed, 0x42, 0xf1, 0xcd, 0xad, 0x1f,
303*10500SHai-May.Chao@Sun.COM 		0x47, 0x4a, 0xfa, 0x2e, 0x79, 0xd5, 0x3a, 0x0c,
304*10500SHai-May.Chao@Sun.COM 		0x42, 0x89, 0x2c, 0x4d, 0x7b, 0x32, 0x7c, 0xbe,
305*10500SHai-May.Chao@Sun.COM 		0x46, 0xb2, 0x95, 0xed, 0x8d, 0xa3, 0xb6, 0xec,
306*10500SHai-May.Chao@Sun.COM 		0xab, 0x3d, 0x48, 0x51, 0x68, 0x7a, 0x6f, 0x81,
307*10500SHai-May.Chao@Sun.COM 		0x2b, 0x79, 0xdf, 0x2f, 0x6b, 0x20, 0xf1, 0x1f,
308*10500SHai-May.Chao@Sun.COM 		0x67, 0x06, 0xf5, 0x30, 0x17, 0x90, 0xca, 0x99,
309*10500SHai-May.Chao@Sun.COM 		0x62, 0x5a, 0xad, 0x73, 0x91, 0xd8, 0x4f, 0x78,
310*10500SHai-May.Chao@Sun.COM 		0x04, 0x3d, 0x2a, 0x0a, 0x23, 0x9b, 0x14, 0x77,
311*10500SHai-May.Chao@Sun.COM 		0x98, 0x4c, 0x15, 0x7b, 0xbc, 0x92, 0x76, 0x06,
312*10500SHai-May.Chao@Sun.COM 		0x4e, 0x7a, 0x1a, 0x40, 0x6b, 0x06, 0x12, 0xca
313*10500SHai-May.Chao@Sun.COM 	};
314*10500SHai-May.Chao@Sun.COM 
315*10500SHai-May.Chao@Sun.COM 	/* SHA-1 variables. */
316*10500SHai-May.Chao@Sun.COM 	uint8_t sha1_computed_digest[SHA1_DIGEST_LENGTH];
317*10500SHai-May.Chao@Sun.COM 	uint8_t hmac_computed[SHA1_HMAC_BLOCK_SIZE];
318*10500SHai-May.Chao@Sun.COM 	SHA1_CTX *sha1_context = NULL;
319*10500SHai-May.Chao@Sun.COM 
320*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
321*10500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_t *sha1_hmac_ctx = NULL;
322*10500SHai-May.Chao@Sun.COM #endif
323*10500SHai-May.Chao@Sun.COM 
324*10500SHai-May.Chao@Sun.COM 	int rv;
325*10500SHai-May.Chao@Sun.COM 
326*10500SHai-May.Chao@Sun.COM 	/* SHA-1 Known Answer Hashing Test. */
327*10500SHai-May.Chao@Sun.COM 	sha1_context = fips_sha1_build_context();
328*10500SHai-May.Chao@Sun.COM 	if (sha1_context == NULL)
329*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
330*10500SHai-May.Chao@Sun.COM 
331*10500SHai-May.Chao@Sun.COM 	rv = fips_sha1_hash(sha1_context, sha1_known_hash_message,
332*10500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH, sha1_computed_digest);
333*10500SHai-May.Chao@Sun.COM 
334*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
335*10500SHai-May.Chao@Sun.COM 	    (memcmp(sha1_computed_digest, sha1_known_digest,
336*10500SHai-May.Chao@Sun.COM 	    SHA1_DIGEST_LENGTH) != 0))
337*10500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
338*10500SHai-May.Chao@Sun.COM 
339*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
340*10500SHai-May.Chao@Sun.COM 	/* SHA-1 HMAC Known Answer Hashing Test */
341*10500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx = fips_sha1_hmac_build_context(HMAC_known_secret_key,
342*10500SHai-May.Chao@Sun.COM 	    HMAC_known_secret_key_length);
343*10500SHai-May.Chao@Sun.COM 
344*10500SHai-May.Chao@Sun.COM 	if (sha1_hmac_ctx == NULL)
345*10500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
346*10500SHai-May.Chao@Sun.COM 
347*10500SHai-May.Chao@Sun.COM 	fips_hmac_sha1_hash(sha1_hmac_ctx, hmac_sha1_known_hash_message,
348*10500SHai-May.Chao@Sun.COM 	    sizeof (hmac_sha1_known_hash_message), hmac_computed);
349*10500SHai-May.Chao@Sun.COM #else
350*10500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha1_hash(hmac_computed, HMAC_known_secret_key,
351*10500SHai-May.Chao@Sun.COM 	    HMAC_known_secret_key_length, hmac_sha1_known_hash_message,
352*10500SHai-May.Chao@Sun.COM 	    sizeof (hmac_sha1_known_hash_message));
353*10500SHai-May.Chao@Sun.COM 
354*10500SHai-May.Chao@Sun.COM #endif
355*10500SHai-May.Chao@Sun.COM 
356*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL
357*10500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_SHA1_hmac,
358*10500SHai-May.Chao@Sun.COM 	    sizeof (known_SHA1_hmac)) != 0)
359*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
360*10500SHai-May.Chao@Sun.COM #else
361*10500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
362*10500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_SHA1_hmac,
363*10500SHai-May.Chao@Sun.COM 	    sizeof (known_SHA1_hmac)) != 0))
364*10500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
365*10500SHai-May.Chao@Sun.COM #endif
366*10500SHai-May.Chao@Sun.COM 
367*10500SHai-May.Chao@Sun.COM 	return (rv);
368*10500SHai-May.Chao@Sun.COM 
369*10500SHai-May.Chao@Sun.COM }
370