xref: /onnv-gate/usr/src/common/crypto/fips/fips_sha2_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/errno.h>
2810500SHai-May.Chao@Sun.COM #include <sys/kmem.h>
2910500SHai-May.Chao@Sun.COM #include <sys/systm.h>
3010500SHai-May.Chao@Sun.COM #define	_SHA2_IMPL
3110500SHai-May.Chao@Sun.COM #include <sys/sha2.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 <sha2/sha2_impl.h>
4410500SHai-May.Chao@Sun.COM 
4510500SHai-May.Chao@Sun.COM 
4610500SHai-May.Chao@Sun.COM /*
4710500SHai-May.Chao@Sun.COM  * fips_sha2_build_context()
4810500SHai-May.Chao@Sun.COM  *
4910500SHai-May.Chao@Sun.COM  * Description:
5010500SHai-May.Chao@Sun.COM  *	This function allocates and initializes SHA2 context.
5110500SHai-May.Chao@Sun.COM  */
5210500SHai-May.Chao@Sun.COM #ifndef _KERNEL
5310500SHai-May.Chao@Sun.COM SHA2_CTX *
fips_sha2_build_context(CK_MECHANISM_TYPE mechanism)5410500SHai-May.Chao@Sun.COM fips_sha2_build_context(CK_MECHANISM_TYPE mechanism)
5510500SHai-May.Chao@Sun.COM {
5610500SHai-May.Chao@Sun.COM 	SHA2_CTX *sha2_context;
5710500SHai-May.Chao@Sun.COM 
5810500SHai-May.Chao@Sun.COM 	if ((sha2_context = malloc(sizeof (SHA2_CTX))) == NULL)
5910500SHai-May.Chao@Sun.COM 		return (NULL);
6010500SHai-May.Chao@Sun.COM 
6110500SHai-May.Chao@Sun.COM 	switch (mechanism) {
6210500SHai-May.Chao@Sun.COM 	case CKM_SHA256:
6310500SHai-May.Chao@Sun.COM 		SHA2Init(SHA256, sha2_context);
6410500SHai-May.Chao@Sun.COM 		break;
6510500SHai-May.Chao@Sun.COM 
6610500SHai-May.Chao@Sun.COM 	case CKM_SHA384:
6710500SHai-May.Chao@Sun.COM 		SHA2Init(SHA384, sha2_context);
6810500SHai-May.Chao@Sun.COM 		break;
6910500SHai-May.Chao@Sun.COM 
7010500SHai-May.Chao@Sun.COM 	case CKM_SHA512:
7110500SHai-May.Chao@Sun.COM 		SHA2Init(SHA512, sha2_context);
7210500SHai-May.Chao@Sun.COM 		break;
7310500SHai-May.Chao@Sun.COM 	}
7410500SHai-May.Chao@Sun.COM 
7510500SHai-May.Chao@Sun.COM 	return (sha2_context);
7610500SHai-May.Chao@Sun.COM }
7710500SHai-May.Chao@Sun.COM 
7810500SHai-May.Chao@Sun.COM #else
7910500SHai-May.Chao@Sun.COM SHA2_CTX *
fips_sha2_build_context(sha2_mech_t mechanism)8010500SHai-May.Chao@Sun.COM fips_sha2_build_context(sha2_mech_t mechanism)
8110500SHai-May.Chao@Sun.COM {
8210500SHai-May.Chao@Sun.COM 	SHA2_CTX *sha2_context;
8310500SHai-May.Chao@Sun.COM 
8410500SHai-May.Chao@Sun.COM 	if ((sha2_context = kmem_zalloc(sizeof (SHA2_CTX),
8510500SHai-May.Chao@Sun.COM 	    KM_SLEEP)) == NULL)
8610500SHai-May.Chao@Sun.COM 		return (NULL);
8710500SHai-May.Chao@Sun.COM 
8810500SHai-May.Chao@Sun.COM 	switch (mechanism) {
8910500SHai-May.Chao@Sun.COM 	case SHA256_TYPE:
9010500SHai-May.Chao@Sun.COM 		SHA2Init(SHA256, sha2_context);
9110500SHai-May.Chao@Sun.COM 		break;
9210500SHai-May.Chao@Sun.COM 
9310500SHai-May.Chao@Sun.COM 	case SHA384_TYPE:
9410500SHai-May.Chao@Sun.COM 		SHA2Init(SHA384, sha2_context);
9510500SHai-May.Chao@Sun.COM 		break;
9610500SHai-May.Chao@Sun.COM 
9710500SHai-May.Chao@Sun.COM 	case SHA512_TYPE:
9810500SHai-May.Chao@Sun.COM 		SHA2Init(SHA512, sha2_context);
9910500SHai-May.Chao@Sun.COM 		break;
10010500SHai-May.Chao@Sun.COM 	}
10110500SHai-May.Chao@Sun.COM 
10210500SHai-May.Chao@Sun.COM 	return (sha2_context);
10310500SHai-May.Chao@Sun.COM }
10410500SHai-May.Chao@Sun.COM #endif
10510500SHai-May.Chao@Sun.COM 
10610500SHai-May.Chao@Sun.COM /*
10710500SHai-May.Chao@Sun.COM  * fips_sha2_hash()
10810500SHai-May.Chao@Sun.COM  *
10910500SHai-May.Chao@Sun.COM  * Arguments:
11010500SHai-May.Chao@Sun.COM  *	sha2_context:	pointer to SHA2 context
11110500SHai-May.Chao@Sun.COM  *	in:	pointer to the input data to be hashed
11210500SHai-May.Chao@Sun.COM  *	inlen:	length of the input data
11310500SHai-May.Chao@Sun.COM  *	out:	pointer to the output data after hashing
11410500SHai-May.Chao@Sun.COM  *
11510500SHai-May.Chao@Sun.COM  * Description:
11610500SHai-May.Chao@Sun.COM  *	This function calls the low-level SHA2 routines for hashing.
11710500SHai-May.Chao@Sun.COM  *
11810500SHai-May.Chao@Sun.COM  */
11910500SHai-May.Chao@Sun.COM int
fips_sha2_hash(SHA2_CTX * sha2_context,uchar_t * in,ulong_t inlen,uchar_t * out)12010500SHai-May.Chao@Sun.COM fips_sha2_hash(SHA2_CTX *sha2_context, uchar_t *in,
12110500SHai-May.Chao@Sun.COM 	ulong_t inlen, uchar_t *out)
12210500SHai-May.Chao@Sun.COM {
12310500SHai-May.Chao@Sun.COM 
124*10979SHai-May.Chao@Sun.COM 	int rv;
125*10979SHai-May.Chao@Sun.COM 
12610500SHai-May.Chao@Sun.COM 	if (in != NULL) {
12710500SHai-May.Chao@Sun.COM 		SHA2Update((SHA2_CTX *)sha2_context, in, inlen);
12810500SHai-May.Chao@Sun.COM 		SHA2Final(out, (SHA2_CTX *)sha2_context);
129*10979SHai-May.Chao@Sun.COM 		rv = CKR_OK;
13010500SHai-May.Chao@Sun.COM 	} else {
131*10979SHai-May.Chao@Sun.COM 		rv = CKR_ARGUMENTS_BAD;
13210500SHai-May.Chao@Sun.COM 	}
133*10979SHai-May.Chao@Sun.COM 
134*10979SHai-May.Chao@Sun.COM 	if (sha2_context)
135*10979SHai-May.Chao@Sun.COM #ifdef _KERNEL
136*10979SHai-May.Chao@Sun.COM 		kmem_free(sha2_context, sizeof (SHA2_CTX));
137*10979SHai-May.Chao@Sun.COM #else
138*10979SHai-May.Chao@Sun.COM 		free(sha2_context);
139*10979SHai-May.Chao@Sun.COM #endif
140*10979SHai-May.Chao@Sun.COM 	return (rv);
141*10979SHai-May.Chao@Sun.COM 
14210500SHai-May.Chao@Sun.COM }
14310500SHai-May.Chao@Sun.COM 
14410500SHai-May.Chao@Sun.COM #ifndef _KERNEL
14510500SHai-May.Chao@Sun.COM soft_hmac_ctx_t *
fips_sha2_hmac_build_context(CK_MECHANISM_TYPE mechanism,uint8_t * secret_key,unsigned int secret_key_length)14610500SHai-May.Chao@Sun.COM fips_sha2_hmac_build_context(CK_MECHANISM_TYPE mechanism,
14710500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
14810500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
14910500SHai-May.Chao@Sun.COM {
15010500SHai-May.Chao@Sun.COM 
15110500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx;
15210500SHai-May.Chao@Sun.COM 
15310500SHai-May.Chao@Sun.COM 	hmac_ctx = malloc(sizeof (soft_hmac_ctx_t));
15410500SHai-May.Chao@Sun.COM 
15510500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL) {
15610500SHai-May.Chao@Sun.COM 		return (NULL);
15710500SHai-May.Chao@Sun.COM 	}
15810500SHai-May.Chao@Sun.COM 
15910500SHai-May.Chao@Sun.COM 	switch (mechanism) {
16010500SHai-May.Chao@Sun.COM 	case CKM_SHA256_HMAC:
16110500SHai-May.Chao@Sun.COM 	{
16210500SHai-May.Chao@Sun.COM 		uint64_t sha_ipad[SHA256_HMAC_INTS_PER_BLOCK];
16310500SHai-May.Chao@Sun.COM 		uint64_t sha_opad[SHA256_HMAC_INTS_PER_BLOCK];
16410500SHai-May.Chao@Sun.COM 
16510500SHai-May.Chao@Sun.COM 		hmac_ctx->hmac_len = SHA256_DIGEST_LENGTH;
16610500SHai-May.Chao@Sun.COM 		bzero(sha_ipad, SHA256_HMAC_BLOCK_SIZE);
16710500SHai-May.Chao@Sun.COM 		bzero(sha_opad, SHA256_HMAC_BLOCK_SIZE);
16810500SHai-May.Chao@Sun.COM 
16910500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_ipad, secret_key, secret_key_length);
17010500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_opad, secret_key, secret_key_length);
17110500SHai-May.Chao@Sun.COM 
17210500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_init(CKM_TO_SHA2(mechanism),
17310500SHai-May.Chao@Sun.COM 		    &hmac_ctx->hc_ctx_u.sha2_ctx,
17410500SHai-May.Chao@Sun.COM 		    sha_ipad, sha_opad,
17510500SHai-May.Chao@Sun.COM 		    SHA256_HMAC_INTS_PER_BLOCK,
17610500SHai-May.Chao@Sun.COM 		    SHA256_HMAC_BLOCK_SIZE);
17710500SHai-May.Chao@Sun.COM 
17810500SHai-May.Chao@Sun.COM 		break;
17910500SHai-May.Chao@Sun.COM 	}
18010500SHai-May.Chao@Sun.COM 
18110500SHai-May.Chao@Sun.COM 	case CKM_SHA384_HMAC:
18210500SHai-May.Chao@Sun.COM 	{
18310500SHai-May.Chao@Sun.COM 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
18410500SHai-May.Chao@Sun.COM 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
18510500SHai-May.Chao@Sun.COM 
18610500SHai-May.Chao@Sun.COM 		hmac_ctx->hmac_len = SHA384_DIGEST_LENGTH;
18710500SHai-May.Chao@Sun.COM 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
18810500SHai-May.Chao@Sun.COM 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
18910500SHai-May.Chao@Sun.COM 
19010500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_ipad, secret_key, secret_key_length);
19110500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_opad, secret_key, secret_key_length);
19210500SHai-May.Chao@Sun.COM 
19310500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_init(CKM_TO_SHA2(mechanism),
19410500SHai-May.Chao@Sun.COM 		    &hmac_ctx->hc_ctx_u.sha2_ctx,
19510500SHai-May.Chao@Sun.COM 		    sha_ipad, sha_opad,
19610500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_INTS_PER_BLOCK,
19710500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_BLOCK_SIZE);
19810500SHai-May.Chao@Sun.COM 		break;
19910500SHai-May.Chao@Sun.COM 	}
20010500SHai-May.Chao@Sun.COM 
20110500SHai-May.Chao@Sun.COM 	case CKM_SHA512_HMAC:
20210500SHai-May.Chao@Sun.COM 	{
20310500SHai-May.Chao@Sun.COM 		uint64_t sha_ipad[SHA512_HMAC_INTS_PER_BLOCK];
20410500SHai-May.Chao@Sun.COM 		uint64_t sha_opad[SHA512_HMAC_INTS_PER_BLOCK];
20510500SHai-May.Chao@Sun.COM 
20610500SHai-May.Chao@Sun.COM 		hmac_ctx->hmac_len = SHA512_DIGEST_LENGTH;
20710500SHai-May.Chao@Sun.COM 		bzero(sha_ipad, SHA512_HMAC_BLOCK_SIZE);
20810500SHai-May.Chao@Sun.COM 		bzero(sha_opad, SHA512_HMAC_BLOCK_SIZE);
20910500SHai-May.Chao@Sun.COM 
21010500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_ipad, secret_key, secret_key_length);
21110500SHai-May.Chao@Sun.COM 		(void) memcpy(sha_opad, secret_key, secret_key_length);
21210500SHai-May.Chao@Sun.COM 
21310500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_init(CKM_TO_SHA2(mechanism),
21410500SHai-May.Chao@Sun.COM 		    &hmac_ctx->hc_ctx_u.sha2_ctx,
21510500SHai-May.Chao@Sun.COM 		    sha_ipad, sha_opad,
21610500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_INTS_PER_BLOCK,
21710500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_BLOCK_SIZE);
21810500SHai-May.Chao@Sun.COM 
21910500SHai-May.Chao@Sun.COM 		break;
22010500SHai-May.Chao@Sun.COM 	}
22110500SHai-May.Chao@Sun.COM 	}
22210500SHai-May.Chao@Sun.COM 
22310500SHai-May.Chao@Sun.COM 	return (hmac_ctx);
22410500SHai-May.Chao@Sun.COM }
22510500SHai-May.Chao@Sun.COM 
22610500SHai-May.Chao@Sun.COM CK_RV
fips_hmac_sha2_hash(unsigned char * hmac_computed,uint8_t * secret_key,unsigned int secret_key_length,uint8_t * message,unsigned int message_length,CK_MECHANISM_TYPE mechanism)22710500SHai-May.Chao@Sun.COM fips_hmac_sha2_hash(unsigned char *hmac_computed,
22810500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
22910500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length,
23010500SHai-May.Chao@Sun.COM 	uint8_t *message,
23110500SHai-May.Chao@Sun.COM 	unsigned int message_length,
23210500SHai-May.Chao@Sun.COM 	CK_MECHANISM_TYPE mechanism)
23310500SHai-May.Chao@Sun.COM {
23410500SHai-May.Chao@Sun.COM 
23510500SHai-May.Chao@Sun.COM 	soft_hmac_ctx_t *hmac_ctx = NULL;
23610500SHai-May.Chao@Sun.COM 
23710500SHai-May.Chao@Sun.COM 	hmac_ctx = fips_sha2_hmac_build_context(mechanism,
23810500SHai-May.Chao@Sun.COM 	    secret_key, secret_key_length);
23910500SHai-May.Chao@Sun.COM 
24010500SHai-May.Chao@Sun.COM 	if (hmac_ctx == NULL)
24110500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
24210500SHai-May.Chao@Sun.COM 
24310500SHai-May.Chao@Sun.COM 	switch (mechanism) {
24410500SHai-May.Chao@Sun.COM 	case CKM_SHA256_HMAC:
24510500SHai-May.Chao@Sun.COM 		if (message != NULL)
24610500SHai-May.Chao@Sun.COM 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
24710500SHai-May.Chao@Sun.COM 			    message, message_length);
24810500SHai-May.Chao@Sun.COM 
24910500SHai-May.Chao@Sun.COM 		SOFT_MAC_FINAL_2(SHA256, &(hmac_ctx->hc_ctx_u.sha2_ctx),
25010500SHai-May.Chao@Sun.COM 		    hmac_computed);
25110500SHai-May.Chao@Sun.COM 		break;
25210500SHai-May.Chao@Sun.COM 
25310500SHai-May.Chao@Sun.COM 	case CKM_SHA384_HMAC:
25410500SHai-May.Chao@Sun.COM 		if (message != NULL)
25510500SHai-May.Chao@Sun.COM 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
25610500SHai-May.Chao@Sun.COM 			    message, message_length);
25710500SHai-May.Chao@Sun.COM 
25810500SHai-May.Chao@Sun.COM 		SOFT_MAC_FINAL_2(SHA384, &(hmac_ctx->hc_ctx_u.sha2_ctx),
25910500SHai-May.Chao@Sun.COM 		    hmac_computed);
26010500SHai-May.Chao@Sun.COM 		break;
26110500SHai-May.Chao@Sun.COM 
26210500SHai-May.Chao@Sun.COM 	case CKM_SHA512_HMAC:
26310500SHai-May.Chao@Sun.COM 		if (message != NULL)
26410500SHai-May.Chao@Sun.COM 			SHA2Update(&(hmac_ctx->hc_ctx_u.sha2_ctx.hc_icontext),
26510500SHai-May.Chao@Sun.COM 			    message, message_length);
26610500SHai-May.Chao@Sun.COM 
26710500SHai-May.Chao@Sun.COM 		SOFT_MAC_FINAL_2(SHA512, &(hmac_ctx->hc_ctx_u.sha2_ctx),
26810500SHai-May.Chao@Sun.COM 		    hmac_computed);
26910500SHai-May.Chao@Sun.COM 		break;
27010500SHai-May.Chao@Sun.COM 	}
27110500SHai-May.Chao@Sun.COM 
27210500SHai-May.Chao@Sun.COM 	free(hmac_ctx);
27310500SHai-May.Chao@Sun.COM 	return (CKR_OK);
27410500SHai-May.Chao@Sun.COM }
27510500SHai-May.Chao@Sun.COM 
27610500SHai-May.Chao@Sun.COM #else
27710500SHai-May.Chao@Sun.COM 
27810500SHai-May.Chao@Sun.COM /*
27910500SHai-May.Chao@Sun.COM  * Initialize a SHA2-HMAC context.
28010500SHai-May.Chao@Sun.COM  */
28110500SHai-May.Chao@Sun.COM void
sha2_mac_init_ctx(sha2_hmac_ctx_t * ctx,void * keyval,uint_t length_in_bytes)28210500SHai-May.Chao@Sun.COM sha2_mac_init_ctx(sha2_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
28310500SHai-May.Chao@Sun.COM {
28410500SHai-May.Chao@Sun.COM 	uint64_t ipad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
28510500SHai-May.Chao@Sun.COM 	uint64_t opad[SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t)];
28610500SHai-May.Chao@Sun.COM 	int i, block_size, blocks_per_int64;
28710500SHai-May.Chao@Sun.COM 
28810500SHai-May.Chao@Sun.COM 	/* Determine the block size */
28910500SHai-May.Chao@Sun.COM 	if (ctx->hc_mech_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE) {
29010500SHai-May.Chao@Sun.COM 		block_size = SHA256_HMAC_BLOCK_SIZE;
29110500SHai-May.Chao@Sun.COM 		blocks_per_int64 = SHA256_HMAC_BLOCK_SIZE / sizeof (uint64_t);
29210500SHai-May.Chao@Sun.COM 	} else {
29310500SHai-May.Chao@Sun.COM 		block_size = SHA512_HMAC_BLOCK_SIZE;
29410500SHai-May.Chao@Sun.COM 		blocks_per_int64 = SHA512_HMAC_BLOCK_SIZE / sizeof (uint64_t);
29510500SHai-May.Chao@Sun.COM 	}
29610500SHai-May.Chao@Sun.COM 
29710500SHai-May.Chao@Sun.COM 	(void) bzero(ipad, block_size);
29810500SHai-May.Chao@Sun.COM 	(void) bzero(opad, block_size);
29910500SHai-May.Chao@Sun.COM 	(void) bcopy(keyval, ipad, length_in_bytes);
30010500SHai-May.Chao@Sun.COM 	(void) bcopy(keyval, opad, length_in_bytes);
30110500SHai-May.Chao@Sun.COM 
30210500SHai-May.Chao@Sun.COM 	/* XOR key with ipad (0x36) and opad (0x5c) */
30310500SHai-May.Chao@Sun.COM 	for (i = 0; i < blocks_per_int64; i ++) {
30410500SHai-May.Chao@Sun.COM 		ipad[i] ^= 0x3636363636363636;
30510500SHai-May.Chao@Sun.COM 		opad[i] ^= 0x5c5c5c5c5c5c5c5c;
30610500SHai-May.Chao@Sun.COM 	}
30710500SHai-May.Chao@Sun.COM 
30810500SHai-May.Chao@Sun.COM 	/* perform SHA2 on ipad */
30910500SHai-May.Chao@Sun.COM 	SHA2Init(ctx->hc_mech_type, &ctx->hc_icontext);
31010500SHai-May.Chao@Sun.COM 	SHA2Update(&ctx->hc_icontext, (uint8_t *)ipad, block_size);
31110500SHai-May.Chao@Sun.COM 
31210500SHai-May.Chao@Sun.COM 	/* perform SHA2 on opad */
31310500SHai-May.Chao@Sun.COM 	SHA2Init(ctx->hc_mech_type, &ctx->hc_ocontext);
31410500SHai-May.Chao@Sun.COM 	SHA2Update(&ctx->hc_ocontext, (uint8_t *)opad, block_size);
31510500SHai-May.Chao@Sun.COM 
31610500SHai-May.Chao@Sun.COM }
31710500SHai-May.Chao@Sun.COM 
31810500SHai-May.Chao@Sun.COM sha2_hmac_ctx_t *
fips_sha2_hmac_build_context(sha2_mech_t mechanism,uint8_t * secret_key,unsigned int secret_key_length)31910500SHai-May.Chao@Sun.COM fips_sha2_hmac_build_context(sha2_mech_t mechanism,
32010500SHai-May.Chao@Sun.COM 	uint8_t *secret_key,
32110500SHai-May.Chao@Sun.COM 	unsigned int secret_key_length)
32210500SHai-May.Chao@Sun.COM {
32310500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx_t *sha2_hmac_ctx_tmpl;
32410500SHai-May.Chao@Sun.COM 
32510500SHai-May.Chao@Sun.COM 	/*
32610500SHai-May.Chao@Sun.COM 	 * Allocate and initialize SHA2 context.
32710500SHai-May.Chao@Sun.COM 	 */
32810500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx_tmpl = kmem_alloc(sizeof (sha2_hmac_ctx_t),
32910500SHai-May.Chao@Sun.COM 	    KM_SLEEP);
33010500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx_tmpl == NULL)
33110500SHai-May.Chao@Sun.COM 		return (NULL);
33210500SHai-May.Chao@Sun.COM 
33310500SHai-May.Chao@Sun.COM 	switch (mechanism) {
33410500SHai-May.Chao@Sun.COM 	case SHA256_TYPE:
33510500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_tmpl->hc_mech_type =
33610500SHai-May.Chao@Sun.COM 		    SHA256_HMAC_MECH_INFO_TYPE;
33710500SHai-May.Chao@Sun.COM 		break;
33810500SHai-May.Chao@Sun.COM 
33910500SHai-May.Chao@Sun.COM 	case SHA384_TYPE:
34010500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_tmpl->hc_mech_type =
34110500SHai-May.Chao@Sun.COM 		    SHA384_HMAC_MECH_INFO_TYPE;
34210500SHai-May.Chao@Sun.COM 		break;
34310500SHai-May.Chao@Sun.COM 
34410500SHai-May.Chao@Sun.COM 	case SHA512_TYPE:
34510500SHai-May.Chao@Sun.COM 		sha2_hmac_ctx_tmpl->hc_mech_type =
34610500SHai-May.Chao@Sun.COM 		    SHA512_HMAC_MECH_INFO_TYPE;
34710500SHai-May.Chao@Sun.COM 		break;
34810500SHai-May.Chao@Sun.COM 	}
34910500SHai-May.Chao@Sun.COM 
35010500SHai-May.Chao@Sun.COM 	/*
35110500SHai-May.Chao@Sun.COM 	 * initialize ctx->hc_icontext and ctx->hc_ocontext
35210500SHai-May.Chao@Sun.COM 	 */
35310500SHai-May.Chao@Sun.COM 	sha2_mac_init_ctx(sha2_hmac_ctx_tmpl, secret_key,
35410500SHai-May.Chao@Sun.COM 	    secret_key_length);
35510500SHai-May.Chao@Sun.COM 
35610500SHai-May.Chao@Sun.COM 	return (sha2_hmac_ctx_tmpl);
35710500SHai-May.Chao@Sun.COM }
35810500SHai-May.Chao@Sun.COM 
35910500SHai-May.Chao@Sun.COM void
fips_hmac_sha2_hash(sha2_hmac_ctx_t * sha2_hmac_ctx,uint8_t * message,uint32_t message_len,uint8_t * hmac_computed,sha2_mech_t mechanism)36010500SHai-May.Chao@Sun.COM fips_hmac_sha2_hash(sha2_hmac_ctx_t *sha2_hmac_ctx,
36110500SHai-May.Chao@Sun.COM 	uint8_t *message,
36210500SHai-May.Chao@Sun.COM 	uint32_t message_len,
36310500SHai-May.Chao@Sun.COM 	uint8_t *hmac_computed,
36410500SHai-May.Chao@Sun.COM 	sha2_mech_t mechanism)
36510500SHai-May.Chao@Sun.COM 
36610500SHai-May.Chao@Sun.COM {
36710500SHai-May.Chao@Sun.COM 
36810500SHai-May.Chao@Sun.COM 	SHA2Update(&((sha2_hmac_ctx)->hc_icontext), message,
36910500SHai-May.Chao@Sun.COM 	    message_len);
37010500SHai-May.Chao@Sun.COM 	SHA2Final(hmac_computed, &((sha2_hmac_ctx)->hc_icontext));
37110500SHai-May.Chao@Sun.COM 
37210500SHai-May.Chao@Sun.COM 	switch (mechanism) {
37310500SHai-May.Chao@Sun.COM 	case SHA256_TYPE:
37410500SHai-May.Chao@Sun.COM 		SHA2Update(&((sha2_hmac_ctx)->hc_ocontext),
37510500SHai-May.Chao@Sun.COM 		    hmac_computed, SHA256_DIGEST_LENGTH);
37610500SHai-May.Chao@Sun.COM 		break;
37710500SHai-May.Chao@Sun.COM 
37810500SHai-May.Chao@Sun.COM 	case SHA384_TYPE:
37910500SHai-May.Chao@Sun.COM 		SHA2Update(&((sha2_hmac_ctx)->hc_ocontext),
38010500SHai-May.Chao@Sun.COM 		    hmac_computed, SHA384_DIGEST_LENGTH);
38110500SHai-May.Chao@Sun.COM 		break;
38210500SHai-May.Chao@Sun.COM 
38310500SHai-May.Chao@Sun.COM 	case SHA512_TYPE:
38410500SHai-May.Chao@Sun.COM 		SHA2Update(&((sha2_hmac_ctx)->hc_ocontext),
38510500SHai-May.Chao@Sun.COM 			hmac_computed, SHA512_DIGEST_LENGTH);
38610500SHai-May.Chao@Sun.COM 		break;
38710500SHai-May.Chao@Sun.COM 	}
38810500SHai-May.Chao@Sun.COM 
38910500SHai-May.Chao@Sun.COM 	SHA2Final(hmac_computed, &((sha2_hmac_ctx)->hc_ocontext));
390*10979SHai-May.Chao@Sun.COM 
391*10979SHai-May.Chao@Sun.COM 	kmem_free(sha2_hmac_ctx, sizeof (sha2_hmac_ctx_t));
39210500SHai-May.Chao@Sun.COM }
39310500SHai-May.Chao@Sun.COM 
39410500SHai-May.Chao@Sun.COM #endif
39510500SHai-May.Chao@Sun.COM 
39610500SHai-May.Chao@Sun.COM /*
39710500SHai-May.Chao@Sun.COM  * SHA2 Power-On SelfTest(s).
39810500SHai-May.Chao@Sun.COM  */
39910500SHai-May.Chao@Sun.COM int
fips_sha2_post(void)40010500SHai-May.Chao@Sun.COM fips_sha2_post(void)
40110500SHai-May.Chao@Sun.COM {
40210500SHai-May.Chao@Sun.COM 
40310500SHai-May.Chao@Sun.COM 	/*
40410500SHai-May.Chao@Sun.COM 	 * SHA-256 Known Hash Message (512-bits).
40510500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA256ShortMsg (Len = 512)
40610500SHai-May.Chao@Sun.COM 	 */
40710500SHai-May.Chao@Sun.COM 	static uint8_t sha256_known_hash_message[] = {
40810500SHai-May.Chao@Sun.COM 		0x35, 0x92, 0xec, 0xfd, 0x1e, 0xac, 0x61, 0x8f,
40910500SHai-May.Chao@Sun.COM 		0xd3, 0x90, 0xe7, 0xa9, 0xc2, 0x4b, 0x65, 0x65,
41010500SHai-May.Chao@Sun.COM 		0x32, 0x50, 0x93, 0x67, 0xc2, 0x1a, 0x0e, 0xac,
41110500SHai-May.Chao@Sun.COM 		0x12, 0x12, 0xac, 0x83, 0xc0, 0xb2, 0x0c, 0xd8,
41210500SHai-May.Chao@Sun.COM 		0x96, 0xeb, 0x72, 0xb8, 0x01, 0xc4, 0xd2, 0x12,
41310500SHai-May.Chao@Sun.COM 		0xc5, 0x45, 0x2b, 0xbb, 0xf0, 0x93, 0x17, 0xb5,
41410500SHai-May.Chao@Sun.COM 		0x0c, 0x5c, 0x9f, 0xb1, 0x99, 0x75, 0x53, 0xd2,
41510500SHai-May.Chao@Sun.COM 		0xbb, 0xc2, 0x9b, 0xb4, 0x2f, 0x57, 0x48, 0xad
41610500SHai-May.Chao@Sun.COM 	};
41710500SHai-May.Chao@Sun.COM 
41810500SHai-May.Chao@Sun.COM 	/* known SHA256 Digest Message (32 bytes) */
41910500SHai-May.Chao@Sun.COM 	static uint8_t known_sha256_digest[] = {
42010500SHai-May.Chao@Sun.COM 		0x10, 0x5a, 0x60, 0x86, 0x58, 0x30, 0xac, 0x3a,
42110500SHai-May.Chao@Sun.COM 		0x37, 0x1d, 0x38, 0x43, 0x32, 0x4d, 0x4b, 0xb5,
42210500SHai-May.Chao@Sun.COM 		0xfa, 0x8e, 0xc0, 0xe0, 0x2d, 0xda, 0xa3, 0x89,
42310500SHai-May.Chao@Sun.COM 		0xad, 0x8d, 0xa4, 0xf1, 0x02, 0x15, 0xc4, 0x54
42410500SHai-May.Chao@Sun.COM 	};
42510500SHai-May.Chao@Sun.COM 
42610500SHai-May.Chao@Sun.COM 	/*
42710500SHai-May.Chao@Sun.COM 	 * SHA-384 Known Hash Message (512-bits).
42810500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA384ShortMsg (Len = 512)
42910500SHai-May.Chao@Sun.COM 	 */
43010500SHai-May.Chao@Sun.COM 	static uint8_t sha384_known_hash_message[] = {
43110500SHai-May.Chao@Sun.COM 		0x58, 0xbe, 0xab, 0xf9, 0x79, 0xab, 0x35, 0xab,
43210500SHai-May.Chao@Sun.COM 		0xba, 0x29, 0x37, 0x6d, 0x5d, 0xc2, 0x27, 0xab,
43310500SHai-May.Chao@Sun.COM 		0xb3, 0xd2, 0xff, 0x4d, 0x90, 0x30, 0x49, 0x82,
43410500SHai-May.Chao@Sun.COM 		0xfc, 0x10, 0x79, 0xbc, 0x2b, 0x28, 0x80, 0xfc,
43510500SHai-May.Chao@Sun.COM 		0xb0, 0x12, 0x9e, 0x4f, 0xed, 0xf2, 0x78, 0x98,
43610500SHai-May.Chao@Sun.COM 		0xce, 0x58, 0x6a, 0x91, 0xb7, 0x68, 0x1e, 0x0d,
43710500SHai-May.Chao@Sun.COM 		0xba, 0x38, 0x5e, 0x80, 0x0e, 0x79, 0x26, 0xc0,
43810500SHai-May.Chao@Sun.COM 		0xbc, 0x5a, 0xfe, 0x0d, 0x9c, 0xa9, 0x86, 0x50
43910500SHai-May.Chao@Sun.COM 	};
44010500SHai-May.Chao@Sun.COM 
44110500SHai-May.Chao@Sun.COM 	/* known SHA384 Digest Message (48 bytes) */
44210500SHai-May.Chao@Sun.COM 	static uint8_t known_sha384_digest[] = {
44310500SHai-May.Chao@Sun.COM 		0xa0, 0x88, 0x8e, 0x1c, 0x4d, 0x7e, 0x80, 0xcb,
44410500SHai-May.Chao@Sun.COM 		0xaa, 0xaf, 0xa8, 0xbb, 0x1c, 0xa1, 0xca, 0x91,
44510500SHai-May.Chao@Sun.COM 		0x2a, 0x93, 0x21, 0x75, 0xc2, 0xef, 0x98, 0x2c,
44610500SHai-May.Chao@Sun.COM 		0xe1, 0xf1, 0x23, 0xa8, 0xc1, 0xae, 0xe9, 0x63,
44710500SHai-May.Chao@Sun.COM 		0x5a, 0xd7, 0x5b, 0xe5, 0x25, 0x90, 0xa9, 0x24,
44810500SHai-May.Chao@Sun.COM 		0xbe, 0xd3, 0xf5, 0xec, 0x36, 0xc3, 0x56, 0x90
44910500SHai-May.Chao@Sun.COM 	};
45010500SHai-May.Chao@Sun.COM 
45110500SHai-May.Chao@Sun.COM 	/*
45210500SHai-May.Chao@Sun.COM 	 * SHA-512 Known Hash Message (512-bits).
45310500SHai-May.Chao@Sun.COM 	 * Source from NIST SHA512ShortMsg (Len = 512)
45410500SHai-May.Chao@Sun.COM 	 */
45510500SHai-May.Chao@Sun.COM 	static uint8_t sha512_known_hash_message[] = {
45610500SHai-May.Chao@Sun.COM 		0x09, 0x5c, 0x7f, 0x30, 0x82, 0x4f, 0xc9, 0x28,
45710500SHai-May.Chao@Sun.COM 		0x58, 0xcc, 0x93, 0x47, 0xc0, 0x85, 0xd5, 0x78,
45810500SHai-May.Chao@Sun.COM 		0x88, 0x5f, 0xf3, 0x61, 0x4d, 0xd3, 0x8e, 0xe7,
45910500SHai-May.Chao@Sun.COM 		0xee, 0x94, 0xa0, 0xf4, 0x40, 0x72, 0xc8, 0x77,
46010500SHai-May.Chao@Sun.COM 		0x04, 0x7e, 0xe2, 0xad, 0x16, 0x6f, 0xdb, 0xa0,
46110500SHai-May.Chao@Sun.COM 		0xe7, 0x44, 0xc3, 0xed, 0x2c, 0x2b, 0x24, 0xc9,
46210500SHai-May.Chao@Sun.COM 		0xd8, 0xa2, 0x93, 0x46, 0x48, 0xdc, 0x84, 0xd3,
46310500SHai-May.Chao@Sun.COM 		0xbe, 0x66, 0x63, 0x02, 0x11, 0x0a, 0xe0, 0x8f
46410500SHai-May.Chao@Sun.COM 	};
46510500SHai-May.Chao@Sun.COM 
46610500SHai-May.Chao@Sun.COM 	/* known SHA512 Digest Message (64 bytes) */
46710500SHai-May.Chao@Sun.COM 	static uint8_t known_sha512_digest[] = {
46810500SHai-May.Chao@Sun.COM 		0xd5, 0xcd, 0xaf, 0x83, 0xbb, 0x4a, 0x27, 0xea,
46910500SHai-May.Chao@Sun.COM 		0xad, 0x8d, 0x8f, 0x18, 0xe4, 0xbe, 0xe9, 0xc2,
47010500SHai-May.Chao@Sun.COM 		0x5b, 0xe9, 0x49, 0xa7, 0x61, 0xa0, 0xfd, 0x0f,
47110500SHai-May.Chao@Sun.COM 		0xb2, 0x28, 0x4c, 0xab, 0x14, 0x3c, 0xad, 0x60,
47210500SHai-May.Chao@Sun.COM 		0xbe, 0xb5, 0x68, 0x87, 0x34, 0xb2, 0xf8, 0x1e,
47310500SHai-May.Chao@Sun.COM 		0x9e, 0x2d, 0x64, 0x0b, 0x42, 0x5f, 0xd3, 0x2c,
47410500SHai-May.Chao@Sun.COM 		0xcb, 0x3d, 0x20, 0xd0, 0x2d, 0x63, 0xc2, 0xc9,
47510500SHai-May.Chao@Sun.COM 		0x4c, 0x03, 0xab, 0x3d, 0x9e, 0x7d, 0x9b, 0x4a
47610500SHai-May.Chao@Sun.COM 	};
47710500SHai-May.Chao@Sun.COM 
47810500SHai-May.Chao@Sun.COM 	/* SHA-2 HMAC Test Vectors */
47910500SHai-May.Chao@Sun.COM 
48010500SHai-May.Chao@Sun.COM 	/*
48110500SHai-May.Chao@Sun.COM 	 * SHA-256 HMAC Known Hash Message (512-bits).
48210500SHai-May.Chao@Sun.COM 	 */
48310500SHai-May.Chao@Sun.COM 	static uint8_t sha256_hmac_known_hash_message[] = {
48410500SHai-May.Chao@Sun.COM 		0x54, 0x68, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74,
48510500SHai-May.Chao@Sun.COM 		0x20, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
48610500SHai-May.Chao@Sun.COM 		0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65,
48710500SHai-May.Chao@Sun.COM 		0x20, 0x4D, 0x44, 0x32, 0x2C, 0x20, 0x4D, 0x44,
48810500SHai-May.Chao@Sun.COM 		0x35, 0x2C, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x53,
48910500SHai-May.Chao@Sun.COM 		0x48, 0x41, 0x2D, 0x31, 0x20, 0x68, 0x61, 0x73,
49010500SHai-May.Chao@Sun.COM 		0x68, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x6C, 0x67,
49110500SHai-May.Chao@Sun.COM 		0x6F, 0x72, 0x69, 0x74, 0x68, 0x6D, 0x73, 0x2E
49210500SHai-May.Chao@Sun.COM 	};
49310500SHai-May.Chao@Sun.COM 
49410500SHai-May.Chao@Sun.COM 	static uint8_t sha256_hmac_known_secret_key[] = {
49510500SHai-May.Chao@Sun.COM 		0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
49610500SHai-May.Chao@Sun.COM 		0x74, 0x68, 0x65, 0x20, 0x53, 0x48, 0x41, 0x2D,
49710500SHai-May.Chao@Sun.COM 		0x32, 0x35, 0x36, 0x20, 0x48, 0x4D, 0x41, 0x43,
49810500SHai-May.Chao@Sun.COM 		0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20,
49910500SHai-May.Chao@Sun.COM 		0x6B, 0x65, 0x79, 0x21
50010500SHai-May.Chao@Sun.COM 	};
50110500SHai-May.Chao@Sun.COM 
50210500SHai-May.Chao@Sun.COM 	static uint8_t sha256_hmac_known_secret_key_length
50310500SHai-May.Chao@Sun.COM 	    = sizeof (sha256_hmac_known_secret_key);
50410500SHai-May.Chao@Sun.COM 
50510500SHai-May.Chao@Sun.COM 
50610500SHai-May.Chao@Sun.COM 	/* known SHA256 hmac (32 bytes) */
50710500SHai-May.Chao@Sun.COM 	static uint8_t known_sha256_hmac[] = {
50810500SHai-May.Chao@Sun.COM 		0x02, 0x87, 0x21, 0x93, 0x84, 0x8a, 0x35, 0xae,
50910500SHai-May.Chao@Sun.COM 		0xdb, 0xb6, 0x79, 0x26, 0x96, 0xf0, 0x50, 0xeb,
51010500SHai-May.Chao@Sun.COM 		0x33, 0x49, 0x57, 0xf1, 0xb2, 0x32, 0xd3, 0x63,
51110500SHai-May.Chao@Sun.COM 		0x03, 0x65, 0x57, 0xa2, 0xba, 0xa2, 0x5f, 0x35
51210500SHai-May.Chao@Sun.COM 	};
51310500SHai-May.Chao@Sun.COM 
51410500SHai-May.Chao@Sun.COM 	/*
51510500SHai-May.Chao@Sun.COM 	 * SHA-384 HMAC Known Hash Message (512-bits).
51610500SHai-May.Chao@Sun.COM 	 * Source from NIST HMAC.txt (Count = 15, Klen = 16, Tlen = 48)
51710500SHai-May.Chao@Sun.COM 	 */
51810500SHai-May.Chao@Sun.COM 	static uint8_t sha384_hmac_known_secret_key[] = {
51910500SHai-May.Chao@Sun.COM 		0x01, 0xac, 0x59, 0xf4, 0x2f, 0x8b, 0xb9, 0x1d,
52010500SHai-May.Chao@Sun.COM 		0x1b, 0xd1, 0x0f, 0xe6, 0x99, 0x0d, 0x7a, 0x87
52110500SHai-May.Chao@Sun.COM 	};
52210500SHai-May.Chao@Sun.COM 
52310500SHai-May.Chao@Sun.COM 	static uint8_t sha384_hmac_known_secret_key_length
52410500SHai-May.Chao@Sun.COM 	    = sizeof (sha384_hmac_known_secret_key);
52510500SHai-May.Chao@Sun.COM 
52610500SHai-May.Chao@Sun.COM 	static uint8_t sha384_hmac_known_hash_message[] = {
52710500SHai-May.Chao@Sun.COM 		0x3c, 0xaf, 0x18, 0xc4, 0x76, 0xed, 0xd5, 0x61,
52810500SHai-May.Chao@Sun.COM 		0x5f, 0x34, 0x3a, 0xc7, 0xb7, 0xd3, 0xa9, 0xda,
52910500SHai-May.Chao@Sun.COM 		0x9e, 0xfa, 0xde, 0x75, 0x56, 0x72, 0xd5, 0xba,
53010500SHai-May.Chao@Sun.COM 		0x4b, 0x8a, 0xe8, 0xa7, 0x50, 0x55, 0x39, 0xea,
53110500SHai-May.Chao@Sun.COM 		0x2c, 0x12, 0x4f, 0xf7, 0x55, 0xec, 0x04, 0x57,
53210500SHai-May.Chao@Sun.COM 		0xfb, 0xe4, 0x9e, 0x43, 0x48, 0x0b, 0x3c, 0x71,
53310500SHai-May.Chao@Sun.COM 		0xe7, 0xf4, 0x74, 0x2e, 0xc3, 0x69, 0x3a, 0xad,
53410500SHai-May.Chao@Sun.COM 		0x11, 0x5d, 0x03, 0x9f, 0x90, 0x22, 0x2b, 0x03,
53510500SHai-May.Chao@Sun.COM 		0x0f, 0xdc, 0x94, 0x40, 0x31, 0x36, 0x91, 0x71,
53610500SHai-May.Chao@Sun.COM 		0x6d, 0x53, 0x02, 0x00, 0x58, 0x08, 0xc0, 0x76,
53710500SHai-May.Chao@Sun.COM 		0x27, 0x48, 0x3b, 0x91, 0x6f, 0xdf, 0x61, 0x98,
53810500SHai-May.Chao@Sun.COM 		0x30, 0x63, 0xc2, 0xeb, 0x12, 0x68, 0xf2, 0xde,
53910500SHai-May.Chao@Sun.COM 		0xee, 0xf4, 0x2f, 0xc7, 0x90, 0x33, 0x44, 0x56,
54010500SHai-May.Chao@Sun.COM 		0xbc, 0x6b, 0xad, 0x25, 0x6e, 0x31, 0xfc, 0x90,
54110500SHai-May.Chao@Sun.COM 		0x66, 0xde, 0x7c, 0xc7, 0xe4, 0x3d, 0x13, 0x21,
54210500SHai-May.Chao@Sun.COM 		0xb1, 0x86, 0x6d, 0xb4, 0x5e, 0x90, 0x56, 0x22
54310500SHai-May.Chao@Sun.COM 	};
54410500SHai-May.Chao@Sun.COM 
54510500SHai-May.Chao@Sun.COM 	/* known SHA384 hmac (48 bytes) */
54610500SHai-May.Chao@Sun.COM 	static uint8_t known_sha384_hmac[] = {
54710500SHai-May.Chao@Sun.COM 		0x19, 0x85, 0xfa, 0x21, 0x63, 0xa5, 0x94, 0x3f,
54810500SHai-May.Chao@Sun.COM 		0xc5, 0xd9, 0x2f, 0x1f, 0xe8, 0x83, 0x12, 0x15,
54910500SHai-May.Chao@Sun.COM 		0xe7, 0xe9, 0x1f, 0x0b, 0xff, 0x53, 0x32, 0xbc,
55010500SHai-May.Chao@Sun.COM 		0x71, 0x3a, 0x07, 0x2b, 0xdb, 0x3a, 0x8f, 0x9e,
55110500SHai-May.Chao@Sun.COM 		0x5c, 0x51, 0x57, 0x46, 0x3a, 0x3b, 0xfe, 0xb3,
55210500SHai-May.Chao@Sun.COM 		0x62, 0x31, 0x41, 0x6e, 0x65, 0x97, 0x3e, 0x64
55310500SHai-May.Chao@Sun.COM 	};
55410500SHai-May.Chao@Sun.COM 
55510500SHai-May.Chao@Sun.COM 	/*
55610500SHai-May.Chao@Sun.COM 	 * SHA-512 HMAC Known Hash Message (512-bits).
55710500SHai-May.Chao@Sun.COM 	 * Source from NIST HMAC.txt (Count = 30, Klen = 20, Tlen = 64)
55810500SHai-May.Chao@Sun.COM 	 */
55910500SHai-May.Chao@Sun.COM 	static uint8_t sha512_hmac_known_secret_key[] = {
56010500SHai-May.Chao@Sun.COM 		0xa7, 0x36, 0xf2, 0x74, 0xfd, 0xa6, 0x8e, 0x1b,
56110500SHai-May.Chao@Sun.COM 		0xd5, 0xf9, 0x47, 0x1e, 0x85, 0xfd, 0x41, 0x5d,
56210500SHai-May.Chao@Sun.COM 		0x7f, 0x2b, 0xa1, 0xbc
56310500SHai-May.Chao@Sun.COM 	};
56410500SHai-May.Chao@Sun.COM 
56510500SHai-May.Chao@Sun.COM 	static uint8_t sha512_hmac_known_secret_key_length
56610500SHai-May.Chao@Sun.COM 	    = sizeof (sha512_hmac_known_secret_key);
56710500SHai-May.Chao@Sun.COM 
56810500SHai-May.Chao@Sun.COM 	static uint8_t sha512_hmac_known_hash_message[] = {
56910500SHai-May.Chao@Sun.COM 		0xa6, 0xcc, 0xc3, 0x55, 0x2c, 0x33, 0xe9, 0x17,
57010500SHai-May.Chao@Sun.COM 		0x8b, 0x6b, 0x82, 0xc6, 0x53, 0xd6, 0x3d, 0xe2,
57110500SHai-May.Chao@Sun.COM 		0x54, 0x0f, 0x17, 0x08, 0x07, 0xc3, 0xd9, 0x6a,
57210500SHai-May.Chao@Sun.COM 		0x2a, 0xc2, 0xe2, 0x7d, 0xab, 0x55, 0x26, 0xf1,
57310500SHai-May.Chao@Sun.COM 		0xc7, 0xd3, 0x77, 0xe6, 0x73, 0x6f, 0x04, 0x5d,
57410500SHai-May.Chao@Sun.COM 		0xfb, 0x54, 0x1f, 0xec, 0xe9, 0xf4, 0x43, 0xb7,
57510500SHai-May.Chao@Sun.COM 		0x28, 0x9c, 0x55, 0x9b, 0x69, 0x4c, 0x2a, 0xac,
57610500SHai-May.Chao@Sun.COM 		0xc6, 0xc7, 0x4a, 0xe2, 0xa5, 0xe6, 0xf3, 0x0f,
57710500SHai-May.Chao@Sun.COM 		0xe0, 0x31, 0x61, 0x14, 0x23, 0xb0, 0x4d, 0x55,
57810500SHai-May.Chao@Sun.COM 		0x95, 0xff, 0xb4, 0x6a, 0xba, 0xa1, 0xd9, 0x18,
57910500SHai-May.Chao@Sun.COM 		0x98, 0x96, 0x8d, 0x7f, 0x18, 0x30, 0xae, 0x94,
58010500SHai-May.Chao@Sun.COM 		0xb0, 0x22, 0xee, 0xd2, 0x3f, 0xda, 0xd5, 0x2d,
58110500SHai-May.Chao@Sun.COM 		0x38, 0x11, 0x0a, 0x48, 0x03, 0xa0, 0xce, 0xe7,
58210500SHai-May.Chao@Sun.COM 		0xa0, 0x95, 0xc9, 0xa7, 0x8e, 0x86, 0x09, 0xed,
58310500SHai-May.Chao@Sun.COM 		0xeb, 0x25, 0x48, 0x1c, 0xdc, 0x15, 0x6d, 0x0b,
58410500SHai-May.Chao@Sun.COM 		0x2f, 0xfc, 0x56, 0xb6, 0x3f, 0xda, 0xd5, 0x33
58510500SHai-May.Chao@Sun.COM 	};
58610500SHai-May.Chao@Sun.COM 
58710500SHai-May.Chao@Sun.COM 	/* known SHA512 hmac (64 bytes) */
58810500SHai-May.Chao@Sun.COM 	static uint8_t known_sha512_hmac[] = {
58910500SHai-May.Chao@Sun.COM 		0xf7, 0x18, 0x03, 0x43, 0x1e, 0x07, 0xa5, 0xa6,
59010500SHai-May.Chao@Sun.COM 		0xe5, 0xfd, 0x4a, 0xe4, 0xcf, 0xc2, 0x75, 0x3b,
59110500SHai-May.Chao@Sun.COM 		0xc8, 0x0d, 0x26, 0xe1, 0x67, 0x23, 0xd9, 0xe8,
59210500SHai-May.Chao@Sun.COM 		0x8b, 0x40, 0x5a, 0x02, 0x34, 0x8e, 0xf4, 0xb9,
59310500SHai-May.Chao@Sun.COM 		0x67, 0x92, 0xc9, 0x9c, 0xed, 0x64, 0xdc, 0x70,
59410500SHai-May.Chao@Sun.COM 		0xea, 0x47, 0x53, 0x78, 0xb7, 0x46, 0x6a, 0xc2,
59510500SHai-May.Chao@Sun.COM 		0xca, 0xf4, 0xa4, 0x20, 0xb0, 0x1f, 0xf6, 0x1e,
59610500SHai-May.Chao@Sun.COM 		0x72, 0xc5, 0xb5, 0xee, 0x8e, 0xaa, 0xd4, 0xd4
59710500SHai-May.Chao@Sun.COM 	};
59810500SHai-May.Chao@Sun.COM 
59910500SHai-May.Chao@Sun.COM 	/* SHA-2 variables. */
60010500SHai-May.Chao@Sun.COM 	uint8_t sha256_computed_digest[SHA256_DIGEST_LENGTH];
60110500SHai-May.Chao@Sun.COM 	uint8_t sha384_computed_digest[SHA384_DIGEST_LENGTH];
60210500SHai-May.Chao@Sun.COM 	uint8_t sha512_computed_digest[SHA512_DIGEST_LENGTH];
60310500SHai-May.Chao@Sun.COM 
60410500SHai-May.Chao@Sun.COM 	uint8_t hmac_computed[SHA512_DIGEST_LENGTH];
60510500SHai-May.Chao@Sun.COM 	SHA2_CTX *sha2_context = NULL;
60610500SHai-May.Chao@Sun.COM 
60710500SHai-May.Chao@Sun.COM #ifdef _KERNEL
60810500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx_t *sha2_hmac_ctx;
60910500SHai-May.Chao@Sun.COM #endif
61010500SHai-May.Chao@Sun.COM 
61110500SHai-May.Chao@Sun.COM 	int rv;
61210500SHai-May.Chao@Sun.COM 
61310500SHai-May.Chao@Sun.COM 	/*
61410500SHai-May.Chao@Sun.COM 	 * SHA-2 Known Answer Hashing Test.
61510500SHai-May.Chao@Sun.COM 	 */
61610500SHai-May.Chao@Sun.COM 
61710500SHai-May.Chao@Sun.COM 	/* SHA-256 POST */
61810500SHai-May.Chao@Sun.COM 
61910500SHai-May.Chao@Sun.COM #ifdef _KERNEL
62010500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(SHA256_TYPE);
62110500SHai-May.Chao@Sun.COM #else
62210500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(CKM_SHA256);
62310500SHai-May.Chao@Sun.COM #endif
62410500SHai-May.Chao@Sun.COM 
62510500SHai-May.Chao@Sun.COM 	if (sha2_context == NULL)
62610500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
62710500SHai-May.Chao@Sun.COM 
62810500SHai-May.Chao@Sun.COM 	rv = fips_sha2_hash(sha2_context,
62910500SHai-May.Chao@Sun.COM 	    sha256_known_hash_message,
63010500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
63110500SHai-May.Chao@Sun.COM 	    sha256_computed_digest);
63210500SHai-May.Chao@Sun.COM 
63310500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
63410500SHai-May.Chao@Sun.COM 	    (memcmp(sha256_computed_digest, known_sha256_digest,
63510500SHai-May.Chao@Sun.COM 	    SHA256_DIGEST_LENGTH) != 0))
63610500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
63710500SHai-May.Chao@Sun.COM 
63810500SHai-May.Chao@Sun.COM 	/* SHA-384 POST */
63910500SHai-May.Chao@Sun.COM 
64010500SHai-May.Chao@Sun.COM #ifdef _KERNEL
64110500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(SHA384_TYPE);
64210500SHai-May.Chao@Sun.COM #else
64310500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(CKM_SHA384);
64410500SHai-May.Chao@Sun.COM #endif
64510500SHai-May.Chao@Sun.COM 
64610500SHai-May.Chao@Sun.COM 	if (sha2_context == NULL)
64710500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
64810500SHai-May.Chao@Sun.COM 
64910500SHai-May.Chao@Sun.COM 	rv = fips_sha2_hash(sha2_context,
65010500SHai-May.Chao@Sun.COM 	    sha384_known_hash_message,
65110500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
65210500SHai-May.Chao@Sun.COM 	    sha384_computed_digest);
65310500SHai-May.Chao@Sun.COM 
65410500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
65510500SHai-May.Chao@Sun.COM 	    (memcmp(sha384_computed_digest, known_sha384_digest,
65610500SHai-May.Chao@Sun.COM 	    SHA384_DIGEST_LENGTH) != 0))
65710500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
65810500SHai-May.Chao@Sun.COM 
65910500SHai-May.Chao@Sun.COM 	/* SHA-512 POST */
66010500SHai-May.Chao@Sun.COM 
66110500SHai-May.Chao@Sun.COM #ifdef _KERNEL
66210500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(SHA512_TYPE);
66310500SHai-May.Chao@Sun.COM #else
66410500SHai-May.Chao@Sun.COM 	sha2_context = fips_sha2_build_context(CKM_SHA512);
66510500SHai-May.Chao@Sun.COM #endif
66610500SHai-May.Chao@Sun.COM 
66710500SHai-May.Chao@Sun.COM 	if (sha2_context == NULL)
66810500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
66910500SHai-May.Chao@Sun.COM 
67010500SHai-May.Chao@Sun.COM 	rv = fips_sha2_hash(sha2_context,
67110500SHai-May.Chao@Sun.COM 	    sha512_known_hash_message,
67210500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
67310500SHai-May.Chao@Sun.COM 	    sha512_computed_digest);
67410500SHai-May.Chao@Sun.COM 
67510500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
67610500SHai-May.Chao@Sun.COM 	    (memcmp(sha512_computed_digest, known_sha512_digest,
67710500SHai-May.Chao@Sun.COM 	    SHA512_DIGEST_LENGTH) != 0))
67810500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
67910500SHai-May.Chao@Sun.COM 
68010500SHai-May.Chao@Sun.COM 	/*
68110500SHai-May.Chao@Sun.COM 	 * SHA-2 HMAC Known Answer Hashing Test.
68210500SHai-May.Chao@Sun.COM 	 */
68310500SHai-May.Chao@Sun.COM 
68410500SHai-May.Chao@Sun.COM 	/* HMAC SHA-256 POST */
68510500SHai-May.Chao@Sun.COM 
68610500SHai-May.Chao@Sun.COM #ifdef _KERNEL
68710500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx = fips_sha2_hmac_build_context(
68810500SHai-May.Chao@Sun.COM 	    SHA256_TYPE,
68910500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key,
69010500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key_length);
69110500SHai-May.Chao@Sun.COM 
69210500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx == NULL)
69310500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
69410500SHai-May.Chao@Sun.COM 
69510500SHai-May.Chao@Sun.COM 	fips_hmac_sha2_hash(sha2_hmac_ctx,
69610500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_hash_message,
69710500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
69810500SHai-May.Chao@Sun.COM 	    hmac_computed,
69910500SHai-May.Chao@Sun.COM 	    SHA256_TYPE);
70010500SHai-May.Chao@Sun.COM 
70110500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_sha256_hmac,
70210500SHai-May.Chao@Sun.COM 	    SHA256_DIGEST_LENGTH) != 0)
70310500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
70410500SHai-May.Chao@Sun.COM 
70510500SHai-May.Chao@Sun.COM #else
70610500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha2_hash(hmac_computed,
70710500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key,
70810500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_secret_key_length,
70910500SHai-May.Chao@Sun.COM 	    sha256_hmac_known_hash_message,
71010500SHai-May.Chao@Sun.COM 	    FIPS_KNOWN_HMAC_MESSAGE_LENGTH,
71110500SHai-May.Chao@Sun.COM 	    CKM_SHA256_HMAC);
71210500SHai-May.Chao@Sun.COM 
71310500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
71410500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_sha256_hmac,
71510500SHai-May.Chao@Sun.COM 	    SHA256_DIGEST_LENGTH) != 0))
71610500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
71710500SHai-May.Chao@Sun.COM 
71810500SHai-May.Chao@Sun.COM #endif
71910500SHai-May.Chao@Sun.COM 
72010500SHai-May.Chao@Sun.COM 	/* HMAC SHA-384 POST */
72110500SHai-May.Chao@Sun.COM 
72210500SHai-May.Chao@Sun.COM #ifdef _KERNEL
72310500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx = fips_sha2_hmac_build_context(
72410500SHai-May.Chao@Sun.COM 	    SHA384_TYPE,
72510500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key,
72610500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key_length);
72710500SHai-May.Chao@Sun.COM 
72810500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx == NULL)
72910500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
73010500SHai-May.Chao@Sun.COM 
73110500SHai-May.Chao@Sun.COM 	fips_hmac_sha2_hash(sha2_hmac_ctx,
73210500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_hash_message,
73310500SHai-May.Chao@Sun.COM 	    sizeof (sha384_hmac_known_hash_message),
73410500SHai-May.Chao@Sun.COM 	    hmac_computed,
73510500SHai-May.Chao@Sun.COM 	    SHA384_TYPE);
73610500SHai-May.Chao@Sun.COM 
73710500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_sha384_hmac,
73810500SHai-May.Chao@Sun.COM 	    SHA384_DIGEST_LENGTH) != 0)
73910500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
74010500SHai-May.Chao@Sun.COM #else
74110500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha2_hash(hmac_computed,
74210500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key,
74310500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_secret_key_length,
74410500SHai-May.Chao@Sun.COM 	    sha384_hmac_known_hash_message,
74510500SHai-May.Chao@Sun.COM 	    sizeof (sha384_hmac_known_hash_message),
74610500SHai-May.Chao@Sun.COM 	    CKM_SHA384_HMAC);
74710500SHai-May.Chao@Sun.COM 
74810500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
74910500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_sha384_hmac,
75010500SHai-May.Chao@Sun.COM 	    SHA384_DIGEST_LENGTH) != 0))
75110500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
75210500SHai-May.Chao@Sun.COM 
75310500SHai-May.Chao@Sun.COM #endif
75410500SHai-May.Chao@Sun.COM 
75510500SHai-May.Chao@Sun.COM 	/* HMAC SHA-512 POST */
75610500SHai-May.Chao@Sun.COM 
75710500SHai-May.Chao@Sun.COM #ifdef _KERNEL
75810500SHai-May.Chao@Sun.COM 	sha2_hmac_ctx = fips_sha2_hmac_build_context(
75910500SHai-May.Chao@Sun.COM 	    SHA512_TYPE,
76010500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key,
76110500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key_length);
76210500SHai-May.Chao@Sun.COM 
76310500SHai-May.Chao@Sun.COM 	if (sha2_hmac_ctx == NULL)
76410500SHai-May.Chao@Sun.COM 		return (CKR_HOST_MEMORY);
76510500SHai-May.Chao@Sun.COM 
76610500SHai-May.Chao@Sun.COM 	fips_hmac_sha2_hash(sha2_hmac_ctx,
76710500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_hash_message,
76810500SHai-May.Chao@Sun.COM 	    sizeof (sha512_hmac_known_hash_message),
76910500SHai-May.Chao@Sun.COM 	    hmac_computed,
77010500SHai-May.Chao@Sun.COM 	    SHA512_TYPE);
77110500SHai-May.Chao@Sun.COM 
77210500SHai-May.Chao@Sun.COM 	if (memcmp(hmac_computed, known_sha512_hmac,
77310500SHai-May.Chao@Sun.COM 	    SHA512_DIGEST_LENGTH) != 0)
77410500SHai-May.Chao@Sun.COM 		return (CKR_DEVICE_ERROR);
77510500SHai-May.Chao@Sun.COM 
77610500SHai-May.Chao@Sun.COM #else
77710500SHai-May.Chao@Sun.COM 	rv = fips_hmac_sha2_hash(hmac_computed,
77810500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key,
77910500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_secret_key_length,
78010500SHai-May.Chao@Sun.COM 	    sha512_hmac_known_hash_message,
78110500SHai-May.Chao@Sun.COM 	    sizeof (sha512_hmac_known_hash_message),
78210500SHai-May.Chao@Sun.COM 	    CKM_SHA512_HMAC);
78310500SHai-May.Chao@Sun.COM 
78410500SHai-May.Chao@Sun.COM 	if ((rv != CKR_OK) ||
78510500SHai-May.Chao@Sun.COM 	    (memcmp(hmac_computed, known_sha512_hmac,
78610500SHai-May.Chao@Sun.COM 	    SHA512_DIGEST_LENGTH) != 0))
78710500SHai-May.Chao@Sun.COM 	return (CKR_DEVICE_ERROR);
78810500SHai-May.Chao@Sun.COM 
78910500SHai-May.Chao@Sun.COM #endif
79010500SHai-May.Chao@Sun.COM 
79110500SHai-May.Chao@Sun.COM 	return (CKR_OK);
79210500SHai-May.Chao@Sun.COM }
793