xref: /onnv-gate/usr/src/common/crypto/fips/fips_dsa_util.c (revision 13012:c176c071a066)
112573SDina.Nimeh@Sun.COM /*
212573SDina.Nimeh@Sun.COM  * CDDL HEADER START
312573SDina.Nimeh@Sun.COM  *
412573SDina.Nimeh@Sun.COM  * The contents of this file are subject to the terms of the
512573SDina.Nimeh@Sun.COM  * Common Development and Distribution License (the "License").
612573SDina.Nimeh@Sun.COM  * You may not use this file except in compliance with the License.
712573SDina.Nimeh@Sun.COM  *
812573SDina.Nimeh@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
912573SDina.Nimeh@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1012573SDina.Nimeh@Sun.COM  * See the License for the specific language governing permissions
1112573SDina.Nimeh@Sun.COM  * and limitations under the License.
1212573SDina.Nimeh@Sun.COM  *
1312573SDina.Nimeh@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1412573SDina.Nimeh@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1512573SDina.Nimeh@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1612573SDina.Nimeh@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1712573SDina.Nimeh@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1812573SDina.Nimeh@Sun.COM  *
1912573SDina.Nimeh@Sun.COM  * CDDL HEADER END
2012573SDina.Nimeh@Sun.COM  */
2112573SDina.Nimeh@Sun.COM 
2212573SDina.Nimeh@Sun.COM /*
2312573SDina.Nimeh@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2412573SDina.Nimeh@Sun.COM  */
2512573SDina.Nimeh@Sun.COM 
2612573SDina.Nimeh@Sun.COM #include <sys/types.h>
2712573SDina.Nimeh@Sun.COM #include <sys/sha1.h>
2812573SDina.Nimeh@Sun.COM #define	_SHA2_IMPL
2912573SDina.Nimeh@Sun.COM #include <sys/sha2.h>
3012573SDina.Nimeh@Sun.COM 
3112573SDina.Nimeh@Sun.COM #ifdef	_KERNEL
3212573SDina.Nimeh@Sun.COM #include <sys/param.h>
3312573SDina.Nimeh@Sun.COM #include <sys/kmem.h>
3412573SDina.Nimeh@Sun.COM #else
3512573SDina.Nimeh@Sun.COM #include <strings.h>
3612573SDina.Nimeh@Sun.COM #include <cryptoutil.h>
3712573SDina.Nimeh@Sun.COM #include "softMAC.h"
3812573SDina.Nimeh@Sun.COM #endif
3912573SDina.Nimeh@Sun.COM 
4012573SDina.Nimeh@Sun.COM #include <security/cryptoki.h>
4112573SDina.Nimeh@Sun.COM #include <sys/crypto/common.h>
4212573SDina.Nimeh@Sun.COM 
4312573SDina.Nimeh@Sun.COM #include <sha1/sha1_impl.h>
4412573SDina.Nimeh@Sun.COM #define	_DSA_FIPS_POST
4512573SDina.Nimeh@Sun.COM #include <dsa/dsa_impl.h>
4612573SDina.Nimeh@Sun.COM 
4712573SDina.Nimeh@Sun.COM 
4812573SDina.Nimeh@Sun.COM /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */
4912573SDina.Nimeh@Sun.COM static uint8_t dsa_P[] = {
5012573SDina.Nimeh@Sun.COM 	0x80, 0xb0, 0xd1, 0x9d, 0x6e, 0xa4, 0xf3, 0x28,
5112573SDina.Nimeh@Sun.COM 	0x9f, 0x24, 0xa9, 0x8a, 0x49, 0xd0, 0x0c, 0x63,
5212573SDina.Nimeh@Sun.COM 	0xe8, 0x59, 0x04, 0xf9, 0x89, 0x4a, 0x5e, 0xc0,
5312573SDina.Nimeh@Sun.COM 	0x6d, 0xd2, 0x67, 0x6b, 0x37, 0x81, 0x83, 0x0c,
5412573SDina.Nimeh@Sun.COM 	0xfe, 0x3a, 0x8a, 0xfd, 0xa0, 0x3b, 0x08, 0x91,
5512573SDina.Nimeh@Sun.COM 	0x1c, 0xcb, 0xb5, 0x63, 0xb0, 0x1c, 0x70, 0xd0,
5612573SDina.Nimeh@Sun.COM 	0xae, 0xe1, 0x60, 0x2e, 0x12, 0xeb, 0x54, 0xc7,
5712573SDina.Nimeh@Sun.COM 	0xcf, 0xc6, 0xcc, 0xae, 0x97, 0x52, 0x32, 0x63,
5812573SDina.Nimeh@Sun.COM 	0xd3, 0xeb, 0x55, 0xea, 0x2f, 0x4c, 0xd5, 0xd7,
5912573SDina.Nimeh@Sun.COM 	0x3f, 0xda, 0xec, 0x49, 0x27, 0x0b, 0x14, 0x56,
6012573SDina.Nimeh@Sun.COM 	0xc5, 0x09, 0xbe, 0x4d, 0x09, 0x15, 0x75, 0x2b,
6112573SDina.Nimeh@Sun.COM 	0xa3, 0x42, 0x0d, 0x03, 0x71, 0xdf, 0x0f, 0xf4,
6212573SDina.Nimeh@Sun.COM 	0x0e, 0xe9, 0x0c, 0x46, 0x93, 0x3d, 0x3f, 0xa6,
6312573SDina.Nimeh@Sun.COM 	0x6c, 0xdb, 0xca, 0xe5, 0xac, 0x96, 0xc8, 0x64,
6412573SDina.Nimeh@Sun.COM 	0x5c, 0xec, 0x4b, 0x35, 0x65, 0xfc, 0xfb, 0x5a,
6512573SDina.Nimeh@Sun.COM 	0x1b, 0x04, 0x1b, 0xa1, 0x0e, 0xfd, 0x88, 0x15
6612573SDina.Nimeh@Sun.COM };
6712573SDina.Nimeh@Sun.COM 
6812573SDina.Nimeh@Sun.COM static uint8_t dsa_Q[] = {
6912573SDina.Nimeh@Sun.COM 	0xad, 0x22, 0x59, 0xdf, 0xe5, 0xec, 0x4c, 0x6e,
7012573SDina.Nimeh@Sun.COM 	0xf9, 0x43, 0xf0, 0x4b, 0x2d, 0x50, 0x51, 0xc6,
7112573SDina.Nimeh@Sun.COM 	0x91, 0x99, 0x8b, 0xcf
7212573SDina.Nimeh@Sun.COM };
7312573SDina.Nimeh@Sun.COM 
7412573SDina.Nimeh@Sun.COM static uint8_t dsa_G[] = {
7512573SDina.Nimeh@Sun.COM 	0x78, 0x6e, 0xa9, 0xd8, 0xcd, 0x4a, 0x85, 0xa4,
7612573SDina.Nimeh@Sun.COM 	0x45, 0xb6, 0x6e, 0x5d, 0x21, 0x50, 0x61, 0xf6,
7712573SDina.Nimeh@Sun.COM 	0x5f, 0xdf, 0x5c, 0x7a, 0xde, 0x0d, 0x19, 0xd3,
7812573SDina.Nimeh@Sun.COM 	0xc1, 0x3b, 0x14, 0xcc, 0x8e, 0xed, 0xdb, 0x17,
7912573SDina.Nimeh@Sun.COM 	0xb6, 0xca, 0xba, 0x86, 0xa9, 0xea, 0x51, 0x2d,
8012573SDina.Nimeh@Sun.COM 	0xc1, 0xa9, 0x16, 0xda, 0xf8, 0x7b, 0x59, 0x8a,
8112573SDina.Nimeh@Sun.COM 	0xdf, 0xcb, 0xa4, 0x67, 0x00, 0x44, 0xea, 0x24,
8212573SDina.Nimeh@Sun.COM 	0x73, 0xe5, 0xcb, 0x4b, 0xaf, 0x2a, 0x31, 0x25,
8312573SDina.Nimeh@Sun.COM 	0x22, 0x28, 0x3f, 0x16, 0x10, 0x82, 0xf7, 0xeb,
8412573SDina.Nimeh@Sun.COM 	0x94, 0x0d, 0xdd, 0x09, 0x22, 0x14, 0x08, 0x79,
8512573SDina.Nimeh@Sun.COM 	0xba, 0x11, 0x0b, 0xf1, 0xff, 0x2d, 0x67, 0xac,
8612573SDina.Nimeh@Sun.COM 	0xeb, 0xb6, 0x55, 0x51, 0x69, 0x97, 0xa7, 0x25,
8712573SDina.Nimeh@Sun.COM 	0x6b, 0x9c, 0xa0, 0x9b, 0xd5, 0x08, 0x9b, 0x27,
8812573SDina.Nimeh@Sun.COM 	0x42, 0x1c, 0x7a, 0x69, 0x57, 0xe6, 0x2e, 0xed,
8912573SDina.Nimeh@Sun.COM 	0xa9, 0x5b, 0x25, 0xe8, 0x1f, 0xd2, 0xed, 0x1f,
9012573SDina.Nimeh@Sun.COM 	0xdf, 0xe7, 0x80, 0x17, 0xba, 0x0d, 0x4d, 0x38
9112573SDina.Nimeh@Sun.COM };
9212573SDina.Nimeh@Sun.COM 
9312573SDina.Nimeh@Sun.COM /*
9412573SDina.Nimeh@Sun.COM  * DSA Known Random Values (known random key block is 160-bits)
9512573SDina.Nimeh@Sun.COM  * and (known random signature block is 160-bits).
96*13012SMisaki.Miyashita@Oracle.COM  * Note: known random key block must be numerically smaller than
97*13012SMisaki.Miyashita@Oracle.COM  * dsa_Q even after bignum_random() turns on the MSB.
9812573SDina.Nimeh@Sun.COM  */
9912573SDina.Nimeh@Sun.COM static uint8_t dsa_known_random_key_block[] = {
100*13012SMisaki.Miyashita@Oracle.COM 	0x91, 0x22, 0x59, 0xdf, 0xe5, 0xec, 0x4c, 0x6e,
101*13012SMisaki.Miyashita@Oracle.COM 	0xf9, 0x43, 0xf0, 0x4b, 0x2d, 0x50, 0x51, 0xc6,
102*13012SMisaki.Miyashita@Oracle.COM 	0x91, 0x99, 0x8b, 0xcf
10312573SDina.Nimeh@Sun.COM };
10412573SDina.Nimeh@Sun.COM 
10512573SDina.Nimeh@Sun.COM static uint8_t dsa_known_random_signature_block[] = {
10612573SDina.Nimeh@Sun.COM 	"Random DSA Signature"
10712573SDina.Nimeh@Sun.COM };
10812573SDina.Nimeh@Sun.COM 
10912573SDina.Nimeh@Sun.COM /* DSA Known Digest (160-bits) */
11012573SDina.Nimeh@Sun.COM static uint8_t dsa_known_digest[] = {
11112573SDina.Nimeh@Sun.COM 	"DSA Signature Digest"
11212573SDina.Nimeh@Sun.COM };
11312573SDina.Nimeh@Sun.COM 
11412573SDina.Nimeh@Sun.COM /* DSA Known Signature (320-bits). */
11512573SDina.Nimeh@Sun.COM static uint8_t dsa_known_signature[] = {
11612573SDina.Nimeh@Sun.COM 	0x25, 0x7c, 0x3a, 0x79, 0x32, 0x45, 0xb7, 0x32,
11712573SDina.Nimeh@Sun.COM 	0x70, 0xca, 0x62, 0x63, 0x2b, 0xf6, 0x29, 0x2c,
11812573SDina.Nimeh@Sun.COM 	0x22, 0x2a, 0x03, 0xce, 0x65, 0x02, 0x72, 0x5a,
11912573SDina.Nimeh@Sun.COM 	0x66, 0x29, 0xcf, 0x56, 0xe6, 0xdf, 0xb0, 0xcc,
12012573SDina.Nimeh@Sun.COM 	0x53, 0x72, 0x56, 0x70, 0x92, 0xb5, 0x45, 0x75
12112573SDina.Nimeh@Sun.COM 
12212573SDina.Nimeh@Sun.COM };
12312573SDina.Nimeh@Sun.COM 
12412573SDina.Nimeh@Sun.COM 
12512573SDina.Nimeh@Sun.COM static int
fips_dsa_random_func(void * buf,size_t buflen)12612573SDina.Nimeh@Sun.COM fips_dsa_random_func(void *buf, size_t buflen)
12712573SDina.Nimeh@Sun.COM {
12812573SDina.Nimeh@Sun.COM 	/* should not happen */
12912573SDina.Nimeh@Sun.COM 	if (buflen != FIPS_DSA_SEED_LENGTH)
13012573SDina.Nimeh@Sun.COM 		return (-1);
13112573SDina.Nimeh@Sun.COM 
13212573SDina.Nimeh@Sun.COM 	(void) memcpy(buf, dsa_known_random_key_block,
13312573SDina.Nimeh@Sun.COM 	    FIPS_DSA_SEED_LENGTH);
13412573SDina.Nimeh@Sun.COM 	return (0);
13512573SDina.Nimeh@Sun.COM }
13612573SDina.Nimeh@Sun.COM 
13712573SDina.Nimeh@Sun.COM static int
fips_dsa_signature_func(void * buf,size_t buflen)13812573SDina.Nimeh@Sun.COM fips_dsa_signature_func(void *buf, size_t buflen)
13912573SDina.Nimeh@Sun.COM {
14012573SDina.Nimeh@Sun.COM 	/* should not happen */
14112573SDina.Nimeh@Sun.COM 	if (buflen != FIPS_DSA_SEED_LENGTH)
14212573SDina.Nimeh@Sun.COM 		return (-1);
14312573SDina.Nimeh@Sun.COM 
14412573SDina.Nimeh@Sun.COM 	(void) memcpy(buf, dsa_known_random_signature_block,
14512573SDina.Nimeh@Sun.COM 	    FIPS_DSA_SEED_LENGTH);
14612573SDina.Nimeh@Sun.COM 	return (0);
14712573SDina.Nimeh@Sun.COM }
14812573SDina.Nimeh@Sun.COM 
14912573SDina.Nimeh@Sun.COM int
fips_dsa_genkey_pair(DSAbytekey * bkey)15012573SDina.Nimeh@Sun.COM fips_dsa_genkey_pair(DSAbytekey *bkey)
15112573SDina.Nimeh@Sun.COM {
15212573SDina.Nimeh@Sun.COM 	return (dsa_genkey_pair(bkey));
15312573SDina.Nimeh@Sun.COM }
15412573SDina.Nimeh@Sun.COM 
15512573SDina.Nimeh@Sun.COM int
fips_dsa_digest_sign(DSAbytekey * bkey,uint8_t * in,uint32_t inlen,uint8_t * out)15612573SDina.Nimeh@Sun.COM fips_dsa_digest_sign(DSAbytekey *bkey,
15712573SDina.Nimeh@Sun.COM 	uint8_t *in, uint32_t inlen, uint8_t *out)
15812573SDina.Nimeh@Sun.COM {
15912573SDina.Nimeh@Sun.COM 	CK_RV rv;
16012573SDina.Nimeh@Sun.COM 	SHA1_CTX *sha1_context;
16112573SDina.Nimeh@Sun.COM 	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
16212573SDina.Nimeh@Sun.COM 
16312573SDina.Nimeh@Sun.COM 	sha1_context = fips_sha1_build_context();
16412573SDina.Nimeh@Sun.COM 	if (sha1_context == NULL)
16512573SDina.Nimeh@Sun.COM 		return (CKR_HOST_MEMORY);
16612573SDina.Nimeh@Sun.COM 
167*13012SMisaki.Miyashita@Oracle.COM 	/* hash the message: context is freed by the function */
16812573SDina.Nimeh@Sun.COM 	rv = fips_sha1_hash(sha1_context, in, inlen, sha1_computed_digest);
16912573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
170*13012SMisaki.Miyashita@Oracle.COM 		return (rv);
17112573SDina.Nimeh@Sun.COM 
172*13012SMisaki.Miyashita@Oracle.COM 	return (dsa_sign(bkey, sha1_computed_digest,
173*13012SMisaki.Miyashita@Oracle.COM 	    FIPS_DSA_DIGEST_LENGTH, out));
17412573SDina.Nimeh@Sun.COM }
17512573SDina.Nimeh@Sun.COM 
17612573SDina.Nimeh@Sun.COM int
fips_dsa_verify(DSAbytekey * bkey,uint8_t * data,uint8_t * sig)17712573SDina.Nimeh@Sun.COM fips_dsa_verify(DSAbytekey *bkey, uint8_t *data, uint8_t *sig)
17812573SDina.Nimeh@Sun.COM {
17912573SDina.Nimeh@Sun.COM 	CK_RV rv;
18012573SDina.Nimeh@Sun.COM 	SHA1_CTX *sha1_context;
18112573SDina.Nimeh@Sun.COM 	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
18212573SDina.Nimeh@Sun.COM 
18312573SDina.Nimeh@Sun.COM 	sha1_context = fips_sha1_build_context();
18412573SDina.Nimeh@Sun.COM 	if (sha1_context == NULL)
18512573SDina.Nimeh@Sun.COM 		return (CKR_HOST_MEMORY);
18612573SDina.Nimeh@Sun.COM 
187*13012SMisaki.Miyashita@Oracle.COM 	/* hash the message: context is freed by the function */
18812573SDina.Nimeh@Sun.COM 	rv = fips_sha1_hash(sha1_context, data, FIPS_DSA_DIGEST_LENGTH,
18912573SDina.Nimeh@Sun.COM 	    sha1_computed_digest);
19012573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
191*13012SMisaki.Miyashita@Oracle.COM 		return (rv);
19212573SDina.Nimeh@Sun.COM 
193*13012SMisaki.Miyashita@Oracle.COM 	return (dsa_verify(bkey, sha1_computed_digest, sig));
19412573SDina.Nimeh@Sun.COM }
19512573SDina.Nimeh@Sun.COM 
19612573SDina.Nimeh@Sun.COM /*
19712573SDina.Nimeh@Sun.COM  * DSA Power-On SelfTest(s).
19812573SDina.Nimeh@Sun.COM  */
19912573SDina.Nimeh@Sun.COM int
fips_dsa_post(void)20012573SDina.Nimeh@Sun.COM fips_dsa_post(void)
20112573SDina.Nimeh@Sun.COM {
20212573SDina.Nimeh@Sun.COM 	DSAbytekey dsa_params;
20312573SDina.Nimeh@Sun.COM 	CK_RV rv;
20412573SDina.Nimeh@Sun.COM 	uint8_t dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH];
205*13012SMisaki.Miyashita@Oracle.COM 	uint8_t pubvalue[FIPS_DSA_PRIME_LENGTH];
206*13012SMisaki.Miyashita@Oracle.COM 	uint8_t	privalue[FIPS_DSA_SUBPRIME_LENGTH];
20712573SDina.Nimeh@Sun.COM 
20812573SDina.Nimeh@Sun.COM 	/*
20912573SDina.Nimeh@Sun.COM 	 * Generate a DSA public/private key pair.
21012573SDina.Nimeh@Sun.COM 	 */
21112573SDina.Nimeh@Sun.COM 	dsa_params.prime = dsa_P;
21212573SDina.Nimeh@Sun.COM 	dsa_params.prime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_PRIME_LENGTH);
21312573SDina.Nimeh@Sun.COM 	dsa_params.subprime = dsa_Q;
21412573SDina.Nimeh@Sun.COM 	dsa_params.subprime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_SUBPRIME_LENGTH);
21512573SDina.Nimeh@Sun.COM 	dsa_params.base = dsa_G;
21612573SDina.Nimeh@Sun.COM 	dsa_params.base_bytes = FIPS_DSA_BASE_LENGTH;
21712573SDina.Nimeh@Sun.COM 
218*13012SMisaki.Miyashita@Oracle.COM 	/* Output from DSA key pair generation */
219*13012SMisaki.Miyashita@Oracle.COM 	dsa_params.private_x = privalue;
220*13012SMisaki.Miyashita@Oracle.COM 	dsa_params.private_x_bits = CRYPTO_BYTES2BITS(sizeof (privalue));
221*13012SMisaki.Miyashita@Oracle.COM 	dsa_params.public_y = pubvalue;
222*13012SMisaki.Miyashita@Oracle.COM 	dsa_params.public_y_bits = CRYPTO_BYTES2BITS(sizeof (pubvalue));
223*13012SMisaki.Miyashita@Oracle.COM 
22412573SDina.Nimeh@Sun.COM 	dsa_params.rfunc = fips_dsa_random_func;
22512573SDina.Nimeh@Sun.COM 
22612573SDina.Nimeh@Sun.COM 	rv = fips_dsa_genkey_pair(&dsa_params);
22712573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
22812573SDina.Nimeh@Sun.COM 		return (CKR_DEVICE_ERROR);
22912573SDina.Nimeh@Sun.COM 
23012573SDina.Nimeh@Sun.COM 	/*
23112573SDina.Nimeh@Sun.COM 	 * DSA Known Answer Signature Test
23212573SDina.Nimeh@Sun.COM 	 */
23312573SDina.Nimeh@Sun.COM 
23412573SDina.Nimeh@Sun.COM 	dsa_params.rfunc = fips_dsa_signature_func;
23512573SDina.Nimeh@Sun.COM 
23612573SDina.Nimeh@Sun.COM 	/* Perform DSA signature process. */
23712573SDina.Nimeh@Sun.COM 	rv = fips_dsa_digest_sign(&dsa_params,
23812573SDina.Nimeh@Sun.COM 	    dsa_known_digest, FIPS_DSA_DIGEST_LENGTH, dsa_computed_signature);
23912573SDina.Nimeh@Sun.COM 
24012573SDina.Nimeh@Sun.COM 	if ((rv != CKR_OK) ||
24112573SDina.Nimeh@Sun.COM 	    (memcmp(dsa_computed_signature, dsa_known_signature,
24212573SDina.Nimeh@Sun.COM 	    FIPS_DSA_SIGNATURE_LENGTH) != 0)) {
24312573SDina.Nimeh@Sun.COM 		goto clean;
24412573SDina.Nimeh@Sun.COM 	}
24512573SDina.Nimeh@Sun.COM 
24612573SDina.Nimeh@Sun.COM 	/*
24712573SDina.Nimeh@Sun.COM 	 * DSA Known Answer Verification Test
24812573SDina.Nimeh@Sun.COM 	 */
24912573SDina.Nimeh@Sun.COM 
25012573SDina.Nimeh@Sun.COM 	/* Perform DSA verification process. */
25112573SDina.Nimeh@Sun.COM 	rv = fips_dsa_verify(&dsa_params,
25212573SDina.Nimeh@Sun.COM 	    dsa_known_digest, dsa_computed_signature);
25312573SDina.Nimeh@Sun.COM 
25412573SDina.Nimeh@Sun.COM clean:
25512573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
25612573SDina.Nimeh@Sun.COM 		return (CKR_DEVICE_ERROR);
25712573SDina.Nimeh@Sun.COM 	else
25812573SDina.Nimeh@Sun.COM 		return (CKR_OK);
25912573SDina.Nimeh@Sun.COM }
260