xref: /onnv-gate/usr/src/common/crypto/fips/fips_sha1_util.c (revision 10979:00cad6413daf)
110500SHai-May.Chao@Sun.COM /*
210500SHai-May.Chao@Sun.COM  * CDDL HEADER START
310500SHai-May.Chao@Sun.COM  *
410500SHai-May.Chao@Sun.COM  * The contents of this file are subject to the terms of the
510500SHai-May.Chao@Sun.COM  * Common Development and Distribution License (the "License").
610500SHai-May.Chao@Sun.COM  * You may not use this file except in compliance with the License.
710500SHai-May.Chao@Sun.COM  *
810500SHai-May.Chao@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910500SHai-May.Chao@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1010500SHai-May.Chao@Sun.COM  * See the License for the specific language governing permissions
1110500SHai-May.Chao@Sun.COM  * and limitations under the License.
1210500SHai-May.Chao@Sun.COM  *
1310500SHai-May.Chao@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1410500SHai-May.Chao@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510500SHai-May.Chao@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1610500SHai-May.Chao@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1710500SHai-May.Chao@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1810500SHai-May.Chao@Sun.COM  *
1910500SHai-May.Chao@Sun.COM  * CDDL HEADER END
2010500SHai-May.Chao@Sun.COM  */
2110500SHai-May.Chao@Sun.COM /*
2210500SHai-May.Chao@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2310500SHai-May.Chao@Sun.COM  * Use is subject to license terms.
2410500SHai-May.Chao@Sun.COM  */
2510500SHai-May.Chao@Sun.COM 
2610500SHai-May.Chao@Sun.COM #include <sys/types.h>
2710500SHai-May.Chao@Sun.COM #include <sys/param.h>
2810500SHai-May.Chao@Sun.COM #include <sys/errno.h>
2910500SHai-May.Chao@Sun.COM #include <sys/kmem.h>
3010500SHai-May.Chao@Sun.COM #include <sys/systm.h>
3110500SHai-May.Chao@Sun.COM #include <sys/sha1.h>
3210500SHai-May.Chao@Sun.COM #include <sys/crypto/common.h>
3310500SHai-May.Chao@Sun.COM #include <sys/cmn_err.h>
3410500SHai-May.Chao@Sun.COM #ifndef _KERNEL
3510500SHai-May.Chao@Sun.COM #include <stdlib.h>
3610500SHai-May.Chao@Sun.COM #include <string.h>
3710500SHai-May.Chao@Sun.COM #include <strings.h>
3810500SHai-May.Chao@Sun.COM #include <stdio.h>
3910500SHai-May.Chao@Sun.COM #include <security/cryptoki.h>
4010500SHai-May.Chao@Sun.COM #include <cryptoutil.h>
4110500SHai-May.Chao@Sun.COM #include "softMAC.h"
4210500SHai-May.Chao@Sun.COM #endif
4310500SHai-May.Chao@Sun.COM #include <sha1/sha1_impl.h>
4410500SHai-May.Chao@Sun.COM 
4510500SHai-May.Chao@Sun.COM /*
4610500SHai-May.Chao@Sun.COM  * fips_sha1_build_context()
4710500SHai-May.Chao@Sun.COM  *
4810500SHai-May.Chao@Sun.COM  * Description:
4910500SHai-May.Chao@Sun.COM  *	This function allocates and initializes SHA1 context
5010500SHai-May.Chao@Sun.COM  *	context.
5110500SHai-May.Chao@Sun.COM  */
5210500SHai-May.Chao@Sun.COM SHA1_CTX *
5310500SHai-May.Chao@Sun.COM fips_sha1_build_context(void)
5410500SHai-May.Chao@Sun.COM {
5510500SHai-May.Chao@Sun.COM 	SHA1_CTX *sha1_context;
5610500SHai-May.Chao@Sun.COM 
5710500SHai-May.Chao@Sun.COM 
5810500SHai-May.Chao@Sun.COM #ifndef _KERNEL
5910500SHai-May.Chao@Sun.COM 	if ((sha1_context = malloc(sizeof (SHA1_CTX))) == NULL)
6010500SHai-May.Chao@Sun.COM #else
6110500SHai-May.Chao@Sun.COM 	if ((sha1_context = kmem_zalloc(sizeof (SHA1_CTX),
6210500SHai-May.Chao@Sun.COM 	    KM_SLEEP)) == NULL)
6310500SHai-May.Chao@Sun.COM #endif
6410500SHai-May.Chao@Sun.COM 		return (NULL);
6510500SHai-May.Chao@Sun.COM 
6610500SHai-May.Chao@Sun.COM 	SHA1Init(sha1_context);
6710500SHai-May.Chao@Sun.COM 
6810500SHai-May.Chao@Sun.COM 	return (sha1_context);
6910500SHai-May.Chao@Sun.COM 
7010500SHai-May.Chao@Sun.COM }
7110500SHai-May.Chao@Sun.COM 
7210500SHai-May.Chao@Sun.COM /*
7310500SHai-May.Chao@Sun.COM  * fips_sha1_hash()
7410500SHai-May.Chao@Sun.COM  *
7510500SHai-May.Chao@Sun.COM  * Arguments:
7610500SHai-May.Chao@Sun.COM  *	sha1_context:	pointer to SHA1 context
7710500SHai-May.Chao@Sun.COM  *	in:	pointer to the input data to be hashed
7810500SHai-May.Chao@Sun.COM  *	inlen:	length of the input data
7910500SHai-May.Chao@Sun.COM  *	out:	pointer to the output data after hashing
8010500SHai-May.Chao@Sun.COM  *
8110500SHai-May.Chao@Sun.COM  * Description:
8210500SHai-May.Chao@Sun.COM  *	This function calls the low-level SHA1 routines for hashing.
8310500SHai-May.Chao@Sun.COM  *
8410500SHai-May.Chao@Sun.COM  */
8510500SHai-May.Chao@Sun.COM int
8610500SHai-May.Chao@Sun.COM fips_sha1_hash(SHA1_CTX *sha1_context, uchar_t *in, ulong_t inlen, uchar_t *out)
8710500SHai-May.Chao@Sun.COM {
8810500SHai-May.Chao@Sun.COM 
89*10979SHai-May.Chao@Sun.COM 	int rv;
90*10979SHai-May.Chao@Sun.COM 
9110500SHai-May.Chao@Sun.COM 	if (in != NULL) {
9210500SHai-May.Chao@Sun.COM #ifdef	__sparcv9
9310500SHai-May.Chao@Sun.COM 		SHA1Update((SHA1_CTX *)sha1_context, in, (uint_t)inlen);
9410500SHai-May.Chao@Sun.COM #else	/* !__sparcv9 */
9510500SHai-May.Chao@Sun.COM 		SHA1Update((SHA1_CTX *)sha1_context, in, inlen);
9610500SHai-May.Chao@Sun.COM #endif	/* __sparcv9 */
9710500SHai-May.Chao@Sun.COM 		SHA1Final(out, (SHA1_CTX *)sha1_context);
98*10979SHai-May.Chao@Sun.COM 		rv = CKR_OK;
9910500SHai-May.Chao@Sun.COM 	} else
100*10979SHai-May.Chao@Sun.COM 		rv = CKR_ARGUMENTS_BAD;
10110500SHai-May.Chao@Sun.COM 
102*10979SHai-May.Chao@Sun.COM 	if (sha1_context)
103*10979SHai-May.Chao@Sun.COM #ifdef _KERNEL
104*10979SHai-May.Chao@Sun.COM 		kmem_free(sha1_context, sizeof (SHA1_CTX));
105*10979SHai-May.Chao@Sun.COM #else
106*10979SHai-May.Chao@Sun.COM 		free(sha1_context);
107*10979SHai-May.Chao@Sun.COM #endif
108*10979SHai-May.Chao@Sun.COM 	return (rv);
10910500SHai-May.Chao@Sun.COM }
11010500SHai-May.Chao@Sun.COM 
11110500SHai-May.Chao@Sun.COM 
11210500SHai-May.Chao@Sun.COM #ifndef _KERNEL
11310500SHai-May.Chao@Sun.COM soft_hmac_ctx_t *
11410500SHai-May.Chao@Sun.COM fips_sha1_hmac_build_context(uint8_t *secret_key,
11510500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
11610500SHai-May.Chao@Sun.COM {
11710500SHai-May.Chao@Sun.COM 
11810500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx;
11910500SHai-May.Chao@Sun.COM 	uint32_t sha1_ipad[SHA1_HMAC_INTS_PER_BLOCK];
12010500SHai-May.Chao@Sun.COM 	uint32_t sha1_opad[SHA1_HMAC_INTS_PER_BLOCK];
12110500SHai-May.Chao@Sun.COM 
12210500SHai-May.Chao@Sun.COM 	hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
12310500SHai-May.Chao@Sun.COM 
12410500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL) {
12510500SHai-May.Chao@Sun.COM 		return (NULL);
12610500SHai-May.Chao@Sun.COM 	}
12710500SHai-May.Chao@Sun.COM 
12810500SHai-May.Chao@Sun.COM 	hmac_ctx->hmac_len = SHA1_HASH_SIZE;
12910500SHai-May.Chao@Sun.COM 	bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
13010500SHai-May.Chao@Sun.COM 	bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
13110500SHai-May.Chao@Sun.COM 
13210500SHai-May.Chao@Sun.COM 	(void) memcpy(sha1_ipad, secret_key, secret_key_length);
13310500SHai-May.Chao@Sun.COM 	(void) memcpy(sha1_opad, secret_key, secret_key_length);
13410500SHai-May.Chao@Sun.COM 
13510500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_init(&hmac_ctx->hc_ctx_u.sha1_ctx, sha1_ipad,
13610500SHai-May.Chao@Sun.COM 	    sha1_opad);
13710500SHai-May.Chao@Sun.COM 
13810500SHai-May.Chao@Sun.COM 	return (hmac_ctx);
13910500SHai-May.Chao@Sun.COM 
14010500SHai-May.Chao@Sun.COM }
14110500SHai-May.Chao@Sun.COM 
14210500SHai-May.Chao@Sun.COM CK_RV
14310500SHai-May.Chao@Sun.COM fips_hmac_sha1_hash(unsigned char *hmac_computed,
14410500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
14510500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length,
14610500SHai-May.Chao@Sun.COM 	uint8_t *message,
14710500SHai-May.Chao@Sun.COM 	unsigned int message_length)
14810500SHai-May.Chao@Sun.COM {
14910500SHai-May.Chao@Sun.COM 
15010500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx = NULL;
15110500SHai-May.Chao@Sun.COM 
15210500SHai-May.Chao@Sun.COM 	hmac_ctx = fips_sha1_hmac_build_context(secret_key,
15310500SHai-May.Chao@Sun.COM 	    secret_key_length);
15410500SHai-May.Chao@Sun.COM 
15510500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL)
15610500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
15710500SHai-May.Chao@Sun.COM 
15810500SHai-May.Chao@Sun.COM 	if (message != NULL) {
15910500SHai-May.Chao@Sun.COM 		SOFT_MAC_UPDATE(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx),
16010500SHai-May.Chao@Sun.COM 		    message, message_length);
16110500SHai-May.Chao@Sun.COM 	}
16210500SHai-May.Chao@Sun.COM 
16310500SHai-May.Chao@Sun.COM 	SOFT_MAC_FINAL(SHA1, &(hmac_ctx->hc_ctx_u.sha1_ctx), hmac_computed);
16410500SHai-May.Chao@Sun.COM 
16510500SHai-May.Chao@Sun.COM 	free(hmac_ctx);
16610500SHai-May.Chao@Sun.COM 	return (CKR_OK);
16710500SHai-May.Chao@Sun.COM }
16810500SHai-May.Chao@Sun.COM 
16910500SHai-May.Chao@Sun.COM #else /* _KERNEL */
17010500SHai-May.Chao@Sun.COM 
17110500SHai-May.Chao@Sun.COM /*
17210500SHai-May.Chao@Sun.COM  * Initialize a SHA1-HMAC context.
17310500SHai-May.Chao@Sun.COM  */
17410500SHai-May.Chao@Sun.COM void
17510500SHai-May.Chao@Sun.COM sha1_mac_init_ctx(sha1_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
17610500SHai-May.Chao@Sun.COM {
17710500SHai-May.Chao@Sun.COM 	uint32_t ipad[SHA1_HMAC_INTS_PER_BLOCK];
17810500SHai-May.Chao@Sun.COM 	uint32_t opad[SHA1_HMAC_INTS_PER_BLOCK];
17910500SHai-May.Chao@Sun.COM 	uint_t i;
18010500SHai-May.Chao@Sun.COM 
18110500SHai-May.Chao@Sun.COM 	bzero(ipad, SHA1_HMAC_BLOCK_SIZE);
18210500SHai-May.Chao@Sun.COM 	bzero(opad, SHA1_HMAC_BLOCK_SIZE);
18310500SHai-May.Chao@Sun.COM 
18410500SHai-May.Chao@Sun.COM 	bcopy(keyval, ipad, length_in_bytes);
18510500SHai-May.Chao@Sun.COM 	bcopy(keyval, opad, length_in_bytes);
18610500SHai-May.Chao@Sun.COM 
18710500SHai-May.Chao@Sun.COM 	/* XOR key with ipad (0x36) and opad (0x5c) */
18810500SHai-May.Chao@Sun.COM 	for (i = 0; i < SHA1_HMAC_INTS_PER_BLOCK; i++) {
18910500SHai-May.Chao@Sun.COM 		ipad[i] ^= 0x36363636;
19010500SHai-May.Chao@Sun.COM 		opad[i] ^= 0x5c5c5c5c;
19110500SHai-May.Chao@Sun.COM 	}
19210500SHai-May.Chao@Sun.COM 
19310500SHai-May.Chao@Sun.COM 	/* perform SHA1 on ipad */
19410500SHai-May.Chao@Sun.COM 	SHA1Init(&ctx->hc_icontext);
19510500SHai-May.Chao@Sun.COM 	SHA1Update(&ctx->hc_icontext, (uint8_t *)ipad, SHA1_HMAC_BLOCK_SIZE);
19610500SHai-May.Chao@Sun.COM 
19710500SHai-May.Chao@Sun.COM 	/* perform SHA1 on opad */
19810500SHai-May.Chao@Sun.COM 	SHA1Init(&ctx->hc_ocontext);
19910500SHai-May.Chao@Sun.COM 	SHA1Update(&ctx->hc_ocontext, (uint8_t *)opad, SHA1_HMAC_BLOCK_SIZE);
20010500SHai-May.Chao@Sun.COM }
20110500SHai-May.Chao@Sun.COM 
20210500SHai-May.Chao@Sun.COM sha1_hmac_ctx_t *
20310500SHai-May.Chao@Sun.COM fips_sha1_hmac_build_context(uint8_t *secret_key,
20410500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
20510500SHai-May.Chao@Sun.COM {
20610500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_t *sha1_hmac_ctx_tmpl;
20710500SHai-May.Chao@Sun.COM 
20810500SHai-May.Chao@Sun.COM 
20910500SHai-May.Chao@Sun.COM 	/*
21010500SHai-May.Chao@Sun.COM 	 * Allocate and initialize SHA1 context.
21110500SHai-May.Chao@Sun.COM 	 */
21210500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_tmpl = kmem_alloc(sizeof (sha1_hmac_ctx_t),
21310500SHai-May.Chao@Sun.COM 	    KM_SLEEP);
21410500SHai-May.Chao@Sun.COM 	if (sha1_hmac_ctx_tmpl == NULL)
21510500SHai-May.Chao@Sun.COM 		return (NULL);
21610500SHai-May.Chao@Sun.COM 
21710500SHai-May.Chao@Sun.COM 	/*
21810500SHai-May.Chao@Sun.COM 	 * initialize ctx->hc_icontext and ctx->hc_ocontext
21910500SHai-May.Chao@Sun.COM 	 */
22010500SHai-May.Chao@Sun.COM 	sha1_mac_init_ctx(sha1_hmac_ctx_tmpl, secret_key,
22110500SHai-May.Chao@Sun.COM 	    secret_key_length);
22210500SHai-May.Chao@Sun.COM 
22310500SHai-May.Chao@Sun.COM 
22410500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_tmpl->hc_mech_type = SHA1_HMAC_MECH_INFO_TYPE;
22510500SHai-May.Chao@Sun.COM 
22610500SHai-May.Chao@Sun.COM 
22710500SHai-May.Chao@Sun.COM 	return (sha1_hmac_ctx_tmpl);
22810500SHai-May.Chao@Sun.COM }
22910500SHai-May.Chao@Sun.COM 
23010500SHai-May.Chao@Sun.COM void
23110500SHai-May.Chao@Sun.COM fips_hmac_sha1_hash(sha1_hmac_ctx_t *sha1_hmac_ctx,
23210500SHai-May.Chao@Sun.COM 	uint8_t *message, uint32_t message_len,
23310500SHai-May.Chao@Sun.COM 	uint8_t *hmac_computed)
23410500SHai-May.Chao@Sun.COM {
23510500SHai-May.Chao@Sun.COM 
23610500SHai-May.Chao@Sun.COM 	/* do a SHA1 update of the inner context using the specified data */
23710500SHai-May.Chao@Sun.COM 	SHA1Update(&((sha1_hmac_ctx)->hc_icontext), message,
23810500SHai-May.Chao@Sun.COM 	    message_len);
23910500SHai-May.Chao@Sun.COM 
24010500SHai-May.Chao@Sun.COM 	/*
24110500SHai-May.Chao@Sun.COM 	 * Do a SHA1 final on the inner context.
24210500SHai-May.Chao@Sun.COM 	 */
24310500SHai-May.Chao@Sun.COM 	SHA1Final(hmac_computed, &((sha1_hmac_ctx)->hc_icontext));
24410500SHai-May.Chao@Sun.COM 
24510500SHai-May.Chao@Sun.COM 	/*
24610500SHai-May.Chao@Sun.COM 	 * Do an SHA1 update on the outer context, feeding the inner
24710500SHai-May.Chao@Sun.COM 	 * digest as data.
24810500SHai-May.Chao@Sun.COM 	 */
24910500SHai-May.Chao@Sun.COM 	SHA1Update(&((sha1_hmac_ctx)->hc_ocontext), hmac_computed,
25010500SHai-May.Chao@Sun.COM 	    SHA1_HASH_SIZE);
25110500SHai-May.Chao@Sun.COM 
25210500SHai-May.Chao@Sun.COM 	/*
25310500SHai-May.Chao@Sun.COM 	 * Do a SHA1 final on the outer context, storing the computed
25410500SHai-May.Chao@Sun.COM 	 * digest in the caller's buffer.
25510500SHai-May.Chao@Sun.COM 	 */
25610500SHai-May.Chao@Sun.COM 	SHA1Final(hmac_computed, &((sha1_hmac_ctx)->hc_ocontext));
25710500SHai-May.Chao@Sun.COM 
258*10979SHai-May.Chao@Sun.COM 	kmem_free(sha1_hmac_ctx, sizeof (sha1_hmac_ctx_t));
25910500SHai-May.Chao@Sun.COM }
26010500SHai-May.Chao@Sun.COM 
26110500SHai-May.Chao@Sun.COM #endif
26210500SHai-May.Chao@Sun.COM 
26310500SHai-May.Chao@Sun.COM /*
26410500SHai-May.Chao@Sun.COM  * SHA1 Power-On SelfTest(s).
26510500SHai-May.Chao@Sun.COM  */
26610500SHai-May.Chao@Sun.COM int
26710500SHai-May.Chao@Sun.COM fips_sha1_post(void)
26810500SHai-May.Chao@Sun.COM {
26910500SHai-May.Chao@Sun.COM 
27010500SHai-May.Chao@Sun.COM 	/*
27110500SHai-May.Chao@Sun.COM 	 * SHA-1 Known Hash Message
27210500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA1ShortMsg (L = 512-bits).
27310500SHai-May.Chao@Sun.COM 	 */
27410500SHai-May.Chao@Sun.COM 	static uint8_t sha1_known_hash_message[] = {
27510500SHai-May.Chao@Sun.COM 		0x7e, 0x3a, 0x4c, 0x32, 0x5c, 0xb9, 0xc5, 0x2b,
27610500SHai-May.Chao@Sun.COM 		0x88, 0x38, 0x7f, 0x93, 0xd0, 0x1a, 0xe8, 0x6d,
27710500SHai-May.Chao@Sun.COM 		0x42, 0x09, 0x8f, 0x5e, 0xfa, 0x7f, 0x94, 0x57,
27810500SHai-May.Chao@Sun.COM 		0x38, 0x8b, 0x5e, 0x74, 0xb6, 0xd2, 0x8b, 0x24,
27910500SHai-May.Chao@Sun.COM 		0x38, 0xd4, 0x2d, 0x8b, 0x64, 0x70, 0x33, 0x24,
28010500SHai-May.Chao@Sun.COM 		0xd4, 0xaa, 0x25, 0xab, 0x6a, 0xad, 0x15, 0x3a,
28110500SHai-May.Chao@Sun.COM 		0xe3, 0x0c, 0xd2, 0xb2, 0xaf, 0x4d, 0x5e, 0x5c,
28210500SHai-May.Chao@Sun.COM 		0x00, 0xa8, 0xa2, 0xd0, 0x22, 0x0c, 0x61, 0x16
28310500SHai-May.Chao@Sun.COM 	};
28410500SHai-May.Chao@Sun.COM 
28510500SHai-May.Chao@Sun.COM 	/* SHA-1 Known Digest Message (160-bits). */
28610500SHai-May.Chao@Sun.COM 	static  uint8_t sha1_known_digest[] = {
28710500SHai-May.Chao@Sun.COM 		0xa3, 0x05, 0x44, 0x27, 0xcd, 0xb1, 0x3f, 0x16,
28810500SHai-May.Chao@Sun.COM 		0x4a, 0x61, 0x0b, 0x34, 0x87, 0x02, 0x72, 0x4c,
28910500SHai-May.Chao@Sun.COM 		0x80, 0x8a, 0x0d, 0xcc
29010500SHai-May.Chao@Sun.COM 	};
29110500SHai-May.Chao@Sun.COM 
29210500SHai-May.Chao@Sun.COM 	/* Source from NIST HMAC.txt Count = 0 */
29310500SHai-May.Chao@Sun.COM 	static uint8_t HMAC_known_secret_key[] = {
29410500SHai-May.Chao@Sun.COM 		0x7b, 0x10, 0xf4, 0x12, 0x4b, 0x15, 0xc8, 0x2e
29510500SHai-May.Chao@Sun.COM 	};
29610500SHai-May.Chao@Sun.COM 
29710500SHai-May.Chao@Sun.COM 	static uint8_t HMAC_known_secret_key_length
29810500SHai-May.Chao@Sun.COM 	    = sizeof (HMAC_known_secret_key);
29910500SHai-May.Chao@Sun.COM 
30010500SHai-May.Chao@Sun.COM 	/* known SHA1 hmac - truncated (10 bytes) */
30110500SHai-May.Chao@Sun.COM 	static uint8_t known_SHA1_hmac[] = {
30210500SHai-May.Chao@Sun.COM 		0x4e, 0xad, 0x12, 0xc2, 0xfe, 0x3d, 0x6e, 0xa4,
30310500SHai-May.Chao@Sun.COM 		0x3a, 0xcb
30410500SHai-May.Chao@Sun.COM 	};
30510500SHai-May.Chao@Sun.COM 
30610500SHai-May.Chao@Sun.COM 	static uint8_t hmac_sha1_known_hash_message[] = {
30710500SHai-May.Chao@Sun.COM 		0x27, 0xdc, 0xb5, 0xb1, 0xda, 0xf6, 0x0c, 0xfd,
30810500SHai-May.Chao@Sun.COM 		0x3e, 0x2f, 0x73, 0xd4, 0xd6, 0x4c, 0xa9, 0xc6,
30910500SHai-May.Chao@Sun.COM 		0x84, 0xf8, 0xbf, 0x71, 0xfc, 0x68, 0x2a, 0x46,
31010500SHai-May.Chao@Sun.COM 		0x79, 0x3b, 0x17, 0x90, 0xaf, 0xa4, 0xfe, 0xb1,
31110500SHai-May.Chao@Sun.COM 		0x00, 0xca, 0x7a, 0xaf, 0xf2, 0x6f, 0x58, 0xf0,
31210500SHai-May.Chao@Sun.COM 		0xe1, 0xd0, 0xed, 0x42, 0xf1, 0xcd, 0xad, 0x1f,
31310500SHai-May.Chao@Sun.COM 		0x47, 0x4a, 0xfa, 0x2e, 0x79, 0xd5, 0x3a, 0x0c,
31410500SHai-May.Chao@Sun.COM 		0x42, 0x89, 0x2c, 0x4d, 0x7b, 0x32, 0x7c, 0xbe,
31510500SHai-May.Chao@Sun.COM 		0x46, 0xb2, 0x95, 0xed, 0x8d, 0xa3, 0xb6, 0xec,
31610500SHai-May.Chao@Sun.COM 		0xab, 0x3d, 0x48, 0x51, 0x68, 0x7a, 0x6f, 0x81,
31710500SHai-May.Chao@Sun.COM 		0x2b, 0x79, 0xdf, 0x2f, 0x6b, 0x20, 0xf1, 0x1f,
31810500SHai-May.Chao@Sun.COM 		0x67, 0x06, 0xf5, 0x30, 0x17, 0x90, 0xca, 0x99,
31910500SHai-May.Chao@Sun.COM 		0x62, 0x5a, 0xad, 0x73, 0x91, 0xd8, 0x4f, 0x78,
32010500SHai-May.Chao@Sun.COM 		0x04, 0x3d, 0x2a, 0x0a, 0x23, 0x9b, 0x14, 0x77,
32110500SHai-May.Chao@Sun.COM 		0x98, 0x4c, 0x15, 0x7b, 0xbc, 0x92, 0x76, 0x06,
32210500SHai-May.Chao@Sun.COM 		0x4e, 0x7a, 0x1a, 0x40, 0x6b, 0x06, 0x12, 0xca
32310500SHai-May.Chao@Sun.COM 	};
32410500SHai-May.Chao@Sun.COM 
32510500SHai-May.Chao@Sun.COM 	/* SHA-1 variables. */
32610500SHai-May.Chao@Sun.COM 	uint8_t sha1_computed_digest[SHA1_DIGEST_LENGTH];
32710500SHai-May.Chao@Sun.COM 	uint8_t hmac_computed[SHA1_HMAC_BLOCK_SIZE];
32810500SHai-May.Chao@Sun.COM 	SHA1_CTX *sha1_context = NULL;
32910500SHai-May.Chao@Sun.COM 
33010500SHai-May.Chao@Sun.COM #ifdef _KERNEL
33110500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx_t *sha1_hmac_ctx = NULL;
33210500SHai-May.Chao@Sun.COM #endif
33310500SHai-May.Chao@Sun.COM 
33410500SHai-May.Chao@Sun.COM 	int rv;
33510500SHai-May.Chao@Sun.COM 
33610500SHai-May.Chao@Sun.COM 	/* SHA-1 Known Answer Hashing Test. */
33710500SHai-May.Chao@Sun.COM 	sha1_context = fips_sha1_build_context();
33810500SHai-May.Chao@Sun.COM 	if (sha1_context == NULL)
33910500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
34010500SHai-May.Chao@Sun.COM 
34110500SHai-May.Chao@Sun.COM 	rv = fips_sha1_hash(sha1_context, sha1_known_hash_message,
34210500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH, sha1_computed_digest);
34310500SHai-May.Chao@Sun.COM 
34410500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
34510500SHai-May.Chao@Sun.COM 	    (memcmp(sha1_computed_digest, sha1_known_digest,
34610500SHai-May.Chao@Sun.COM 	    SHA1_DIGEST_LENGTH) != 0))
34710500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
34810500SHai-May.Chao@Sun.COM 
34910500SHai-May.Chao@Sun.COM #ifdef _KERNEL
35010500SHai-May.Chao@Sun.COM 	/* SHA-1 HMAC Known Answer Hashing Test */
35110500SHai-May.Chao@Sun.COM 	sha1_hmac_ctx = fips_sha1_hmac_build_context(HMAC_known_secret_key,
35210500SHai-May.Chao@Sun.COM 	    HMAC_known_secret_key_length);
35310500SHai-May.Chao@Sun.COM 
35410500SHai-May.Chao@Sun.COM 	if (sha1_hmac_ctx == NULL)
35510500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
35610500SHai-May.Chao@Sun.COM 
35710500SHai-May.Chao@Sun.COM 	fips_hmac_sha1_hash(sha1_hmac_ctx, hmac_sha1_known_hash_message,
35810500SHai-May.Chao@Sun.COM 	    sizeof (hmac_sha1_known_hash_message), hmac_computed);
35910500SHai-May.Chao@Sun.COM #else
36010500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha1_hash(hmac_computed, HMAC_known_secret_key,
36110500SHai-May.Chao@Sun.COM 	    HMAC_known_secret_key_length, hmac_sha1_known_hash_message,
36210500SHai-May.Chao@Sun.COM 	    sizeof (hmac_sha1_known_hash_message));
36310500SHai-May.Chao@Sun.COM 
36410500SHai-May.Chao@Sun.COM #endif
36510500SHai-May.Chao@Sun.COM 
36610500SHai-May.Chao@Sun.COM #ifdef _KERNEL
36710500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_SHA1_hmac,
36810500SHai-May.Chao@Sun.COM 	    sizeof (known_SHA1_hmac)) != 0)
36910500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
37010500SHai-May.Chao@Sun.COM #else
37110500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
37210500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_SHA1_hmac,
37310500SHai-May.Chao@Sun.COM 	    sizeof (known_SHA1_hmac)) != 0))
37410500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
37510500SHai-May.Chao@Sun.COM #endif
37610500SHai-May.Chao@Sun.COM 
37710500SHai-May.Chao@Sun.COM 	return (rv);
37810500SHai-May.Chao@Sun.COM 
37910500SHai-May.Chao@Sun.COM }
380