xref: /onnv-gate/usr/src/common/crypto/fips/fips_dsa_util.c (revision 12573:fb4ef506980f)
1*12573SDina.Nimeh@Sun.COM /*
2*12573SDina.Nimeh@Sun.COM  * CDDL HEADER START
3*12573SDina.Nimeh@Sun.COM  *
4*12573SDina.Nimeh@Sun.COM  * The contents of this file are subject to the terms of the
5*12573SDina.Nimeh@Sun.COM  * Common Development and Distribution License (the "License").
6*12573SDina.Nimeh@Sun.COM  * You may not use this file except in compliance with the License.
7*12573SDina.Nimeh@Sun.COM  *
8*12573SDina.Nimeh@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12573SDina.Nimeh@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12573SDina.Nimeh@Sun.COM  * See the License for the specific language governing permissions
11*12573SDina.Nimeh@Sun.COM  * and limitations under the License.
12*12573SDina.Nimeh@Sun.COM  *
13*12573SDina.Nimeh@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12573SDina.Nimeh@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12573SDina.Nimeh@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12573SDina.Nimeh@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12573SDina.Nimeh@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12573SDina.Nimeh@Sun.COM  *
19*12573SDina.Nimeh@Sun.COM  * CDDL HEADER END
20*12573SDina.Nimeh@Sun.COM  */
21*12573SDina.Nimeh@Sun.COM 
22*12573SDina.Nimeh@Sun.COM /*
23*12573SDina.Nimeh@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24*12573SDina.Nimeh@Sun.COM  */
25*12573SDina.Nimeh@Sun.COM 
26*12573SDina.Nimeh@Sun.COM #include <sys/types.h>
27*12573SDina.Nimeh@Sun.COM #include <sys/sha1.h>
28*12573SDina.Nimeh@Sun.COM #define	_SHA2_IMPL
29*12573SDina.Nimeh@Sun.COM #include <sys/sha2.h>
30*12573SDina.Nimeh@Sun.COM 
31*12573SDina.Nimeh@Sun.COM #ifdef	_KERNEL
32*12573SDina.Nimeh@Sun.COM #include <sys/param.h>
33*12573SDina.Nimeh@Sun.COM #include <sys/kmem.h>
34*12573SDina.Nimeh@Sun.COM #else
35*12573SDina.Nimeh@Sun.COM #include <strings.h>
36*12573SDina.Nimeh@Sun.COM #include <cryptoutil.h>
37*12573SDina.Nimeh@Sun.COM #include "softMAC.h"
38*12573SDina.Nimeh@Sun.COM #endif
39*12573SDina.Nimeh@Sun.COM 
40*12573SDina.Nimeh@Sun.COM #include <security/cryptoki.h>
41*12573SDina.Nimeh@Sun.COM #include <sys/crypto/common.h>
42*12573SDina.Nimeh@Sun.COM 
43*12573SDina.Nimeh@Sun.COM #include <sha1/sha1_impl.h>
44*12573SDina.Nimeh@Sun.COM #define	_DSA_FIPS_POST
45*12573SDina.Nimeh@Sun.COM #include <dsa/dsa_impl.h>
46*12573SDina.Nimeh@Sun.COM 
47*12573SDina.Nimeh@Sun.COM 
48*12573SDina.Nimeh@Sun.COM /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */
49*12573SDina.Nimeh@Sun.COM static uint8_t dsa_P[] = {
50*12573SDina.Nimeh@Sun.COM 	0x80, 0xb0, 0xd1, 0x9d, 0x6e, 0xa4, 0xf3, 0x28,
51*12573SDina.Nimeh@Sun.COM 	0x9f, 0x24, 0xa9, 0x8a, 0x49, 0xd0, 0x0c, 0x63,
52*12573SDina.Nimeh@Sun.COM 	0xe8, 0x59, 0x04, 0xf9, 0x89, 0x4a, 0x5e, 0xc0,
53*12573SDina.Nimeh@Sun.COM 	0x6d, 0xd2, 0x67, 0x6b, 0x37, 0x81, 0x83, 0x0c,
54*12573SDina.Nimeh@Sun.COM 	0xfe, 0x3a, 0x8a, 0xfd, 0xa0, 0x3b, 0x08, 0x91,
55*12573SDina.Nimeh@Sun.COM 	0x1c, 0xcb, 0xb5, 0x63, 0xb0, 0x1c, 0x70, 0xd0,
56*12573SDina.Nimeh@Sun.COM 	0xae, 0xe1, 0x60, 0x2e, 0x12, 0xeb, 0x54, 0xc7,
57*12573SDina.Nimeh@Sun.COM 	0xcf, 0xc6, 0xcc, 0xae, 0x97, 0x52, 0x32, 0x63,
58*12573SDina.Nimeh@Sun.COM 	0xd3, 0xeb, 0x55, 0xea, 0x2f, 0x4c, 0xd5, 0xd7,
59*12573SDina.Nimeh@Sun.COM 	0x3f, 0xda, 0xec, 0x49, 0x27, 0x0b, 0x14, 0x56,
60*12573SDina.Nimeh@Sun.COM 	0xc5, 0x09, 0xbe, 0x4d, 0x09, 0x15, 0x75, 0x2b,
61*12573SDina.Nimeh@Sun.COM 	0xa3, 0x42, 0x0d, 0x03, 0x71, 0xdf, 0x0f, 0xf4,
62*12573SDina.Nimeh@Sun.COM 	0x0e, 0xe9, 0x0c, 0x46, 0x93, 0x3d, 0x3f, 0xa6,
63*12573SDina.Nimeh@Sun.COM 	0x6c, 0xdb, 0xca, 0xe5, 0xac, 0x96, 0xc8, 0x64,
64*12573SDina.Nimeh@Sun.COM 	0x5c, 0xec, 0x4b, 0x35, 0x65, 0xfc, 0xfb, 0x5a,
65*12573SDina.Nimeh@Sun.COM 	0x1b, 0x04, 0x1b, 0xa1, 0x0e, 0xfd, 0x88, 0x15
66*12573SDina.Nimeh@Sun.COM };
67*12573SDina.Nimeh@Sun.COM 
68*12573SDina.Nimeh@Sun.COM static uint8_t dsa_Q[] = {
69*12573SDina.Nimeh@Sun.COM 	0xad, 0x22, 0x59, 0xdf, 0xe5, 0xec, 0x4c, 0x6e,
70*12573SDina.Nimeh@Sun.COM 	0xf9, 0x43, 0xf0, 0x4b, 0x2d, 0x50, 0x51, 0xc6,
71*12573SDina.Nimeh@Sun.COM 	0x91, 0x99, 0x8b, 0xcf
72*12573SDina.Nimeh@Sun.COM };
73*12573SDina.Nimeh@Sun.COM 
74*12573SDina.Nimeh@Sun.COM static uint8_t dsa_G[] = {
75*12573SDina.Nimeh@Sun.COM 	0x78, 0x6e, 0xa9, 0xd8, 0xcd, 0x4a, 0x85, 0xa4,
76*12573SDina.Nimeh@Sun.COM 	0x45, 0xb6, 0x6e, 0x5d, 0x21, 0x50, 0x61, 0xf6,
77*12573SDina.Nimeh@Sun.COM 	0x5f, 0xdf, 0x5c, 0x7a, 0xde, 0x0d, 0x19, 0xd3,
78*12573SDina.Nimeh@Sun.COM 	0xc1, 0x3b, 0x14, 0xcc, 0x8e, 0xed, 0xdb, 0x17,
79*12573SDina.Nimeh@Sun.COM 	0xb6, 0xca, 0xba, 0x86, 0xa9, 0xea, 0x51, 0x2d,
80*12573SDina.Nimeh@Sun.COM 	0xc1, 0xa9, 0x16, 0xda, 0xf8, 0x7b, 0x59, 0x8a,
81*12573SDina.Nimeh@Sun.COM 	0xdf, 0xcb, 0xa4, 0x67, 0x00, 0x44, 0xea, 0x24,
82*12573SDina.Nimeh@Sun.COM 	0x73, 0xe5, 0xcb, 0x4b, 0xaf, 0x2a, 0x31, 0x25,
83*12573SDina.Nimeh@Sun.COM 	0x22, 0x28, 0x3f, 0x16, 0x10, 0x82, 0xf7, 0xeb,
84*12573SDina.Nimeh@Sun.COM 	0x94, 0x0d, 0xdd, 0x09, 0x22, 0x14, 0x08, 0x79,
85*12573SDina.Nimeh@Sun.COM 	0xba, 0x11, 0x0b, 0xf1, 0xff, 0x2d, 0x67, 0xac,
86*12573SDina.Nimeh@Sun.COM 	0xeb, 0xb6, 0x55, 0x51, 0x69, 0x97, 0xa7, 0x25,
87*12573SDina.Nimeh@Sun.COM 	0x6b, 0x9c, 0xa0, 0x9b, 0xd5, 0x08, 0x9b, 0x27,
88*12573SDina.Nimeh@Sun.COM 	0x42, 0x1c, 0x7a, 0x69, 0x57, 0xe6, 0x2e, 0xed,
89*12573SDina.Nimeh@Sun.COM 	0xa9, 0x5b, 0x25, 0xe8, 0x1f, 0xd2, 0xed, 0x1f,
90*12573SDina.Nimeh@Sun.COM 	0xdf, 0xe7, 0x80, 0x17, 0xba, 0x0d, 0x4d, 0x38
91*12573SDina.Nimeh@Sun.COM };
92*12573SDina.Nimeh@Sun.COM 
93*12573SDina.Nimeh@Sun.COM /*
94*12573SDina.Nimeh@Sun.COM  * DSA Known Random Values (known random key block is 160-bits)
95*12573SDina.Nimeh@Sun.COM  * and (known random signature block is 160-bits).
96*12573SDina.Nimeh@Sun.COM  */
97*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_random_key_block[] = {
98*12573SDina.Nimeh@Sun.COM 	"This is DSA RNG key!"
99*12573SDina.Nimeh@Sun.COM };
100*12573SDina.Nimeh@Sun.COM 
101*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_random_signature_block[] = {
102*12573SDina.Nimeh@Sun.COM 	"Random DSA Signature"
103*12573SDina.Nimeh@Sun.COM };
104*12573SDina.Nimeh@Sun.COM 
105*12573SDina.Nimeh@Sun.COM /* DSA Known Digest (160-bits) */
106*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_digest[] = {
107*12573SDina.Nimeh@Sun.COM 	"DSA Signature Digest"
108*12573SDina.Nimeh@Sun.COM };
109*12573SDina.Nimeh@Sun.COM 
110*12573SDina.Nimeh@Sun.COM /* DSA Known Signature (320-bits). */
111*12573SDina.Nimeh@Sun.COM static uint8_t dsa_known_signature[] = {
112*12573SDina.Nimeh@Sun.COM 	0x25, 0x7c, 0x3a, 0x79, 0x32, 0x45, 0xb7, 0x32,
113*12573SDina.Nimeh@Sun.COM 	0x70, 0xca, 0x62, 0x63, 0x2b, 0xf6, 0x29, 0x2c,
114*12573SDina.Nimeh@Sun.COM 	0x22, 0x2a, 0x03, 0xce, 0x65, 0x02, 0x72, 0x5a,
115*12573SDina.Nimeh@Sun.COM 	0x66, 0x29, 0xcf, 0x56, 0xe6, 0xdf, 0xb0, 0xcc,
116*12573SDina.Nimeh@Sun.COM 	0x53, 0x72, 0x56, 0x70, 0x92, 0xb5, 0x45, 0x75
117*12573SDina.Nimeh@Sun.COM 
118*12573SDina.Nimeh@Sun.COM };
119*12573SDina.Nimeh@Sun.COM 
120*12573SDina.Nimeh@Sun.COM 
121*12573SDina.Nimeh@Sun.COM static int
122*12573SDina.Nimeh@Sun.COM fips_dsa_random_func(void *buf, size_t buflen)
123*12573SDina.Nimeh@Sun.COM {
124*12573SDina.Nimeh@Sun.COM 	/* should not happen */
125*12573SDina.Nimeh@Sun.COM 	if (buflen != FIPS_DSA_SEED_LENGTH)
126*12573SDina.Nimeh@Sun.COM 		return (-1);
127*12573SDina.Nimeh@Sun.COM 
128*12573SDina.Nimeh@Sun.COM 	(void) memcpy(buf, dsa_known_random_key_block,
129*12573SDina.Nimeh@Sun.COM 	    FIPS_DSA_SEED_LENGTH);
130*12573SDina.Nimeh@Sun.COM 	return (0);
131*12573SDina.Nimeh@Sun.COM }
132*12573SDina.Nimeh@Sun.COM 
133*12573SDina.Nimeh@Sun.COM static int
134*12573SDina.Nimeh@Sun.COM fips_dsa_signature_func(void *buf, size_t buflen)
135*12573SDina.Nimeh@Sun.COM {
136*12573SDina.Nimeh@Sun.COM 	/* should not happen */
137*12573SDina.Nimeh@Sun.COM 	if (buflen != FIPS_DSA_SEED_LENGTH)
138*12573SDina.Nimeh@Sun.COM 		return (-1);
139*12573SDina.Nimeh@Sun.COM 
140*12573SDina.Nimeh@Sun.COM 	(void) memcpy(buf, dsa_known_random_signature_block,
141*12573SDina.Nimeh@Sun.COM 	    FIPS_DSA_SEED_LENGTH);
142*12573SDina.Nimeh@Sun.COM 	return (0);
143*12573SDina.Nimeh@Sun.COM }
144*12573SDina.Nimeh@Sun.COM 
145*12573SDina.Nimeh@Sun.COM int
146*12573SDina.Nimeh@Sun.COM fips_dsa_genkey_pair(DSAbytekey *bkey)
147*12573SDina.Nimeh@Sun.COM {
148*12573SDina.Nimeh@Sun.COM 	return (dsa_genkey_pair(bkey));
149*12573SDina.Nimeh@Sun.COM }
150*12573SDina.Nimeh@Sun.COM 
151*12573SDina.Nimeh@Sun.COM int
152*12573SDina.Nimeh@Sun.COM fips_dsa_digest_sign(DSAbytekey *bkey,
153*12573SDina.Nimeh@Sun.COM 	uint8_t *in, uint32_t inlen, uint8_t *out)
154*12573SDina.Nimeh@Sun.COM {
155*12573SDina.Nimeh@Sun.COM 	CK_RV rv;
156*12573SDina.Nimeh@Sun.COM 	SHA1_CTX *sha1_context;
157*12573SDina.Nimeh@Sun.COM 	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
158*12573SDina.Nimeh@Sun.COM 
159*12573SDina.Nimeh@Sun.COM 	sha1_context = fips_sha1_build_context();
160*12573SDina.Nimeh@Sun.COM 	if (sha1_context == NULL)
161*12573SDina.Nimeh@Sun.COM 		return (CKR_HOST_MEMORY);
162*12573SDina.Nimeh@Sun.COM 
163*12573SDina.Nimeh@Sun.COM 	rv = fips_sha1_hash(sha1_context, in, inlen, sha1_computed_digest);
164*12573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
165*12573SDina.Nimeh@Sun.COM 		goto clean1;
166*12573SDina.Nimeh@Sun.COM 
167*12573SDina.Nimeh@Sun.COM 	rv = dsa_sign(bkey, sha1_computed_digest, FIPS_DSA_DIGEST_LENGTH, out);
168*12573SDina.Nimeh@Sun.COM 
169*12573SDina.Nimeh@Sun.COM clean1:
170*12573SDina.Nimeh@Sun.COM #ifdef _KERNEL
171*12573SDina.Nimeh@Sun.COM 	kmem_free(sha1_context, sizeof (SHA1_CTX));
172*12573SDina.Nimeh@Sun.COM #else
173*12573SDina.Nimeh@Sun.COM 	free(sha1_context);
174*12573SDina.Nimeh@Sun.COM #endif
175*12573SDina.Nimeh@Sun.COM 	return (rv);
176*12573SDina.Nimeh@Sun.COM }
177*12573SDina.Nimeh@Sun.COM 
178*12573SDina.Nimeh@Sun.COM int
179*12573SDina.Nimeh@Sun.COM fips_dsa_verify(DSAbytekey *bkey, uint8_t *data, uint8_t *sig)
180*12573SDina.Nimeh@Sun.COM {
181*12573SDina.Nimeh@Sun.COM 	CK_RV rv;
182*12573SDina.Nimeh@Sun.COM 	SHA1_CTX *sha1_context;
183*12573SDina.Nimeh@Sun.COM 	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
184*12573SDina.Nimeh@Sun.COM 
185*12573SDina.Nimeh@Sun.COM 	sha1_context = fips_sha1_build_context();
186*12573SDina.Nimeh@Sun.COM 	if (sha1_context == NULL)
187*12573SDina.Nimeh@Sun.COM 		return (CKR_HOST_MEMORY);
188*12573SDina.Nimeh@Sun.COM 
189*12573SDina.Nimeh@Sun.COM 	rv = fips_sha1_hash(sha1_context, data, FIPS_DSA_DIGEST_LENGTH,
190*12573SDina.Nimeh@Sun.COM 	    sha1_computed_digest);
191*12573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
192*12573SDina.Nimeh@Sun.COM 		goto clean1;
193*12573SDina.Nimeh@Sun.COM 
194*12573SDina.Nimeh@Sun.COM 	rv = dsa_verify(bkey, sha1_computed_digest, sig);
195*12573SDina.Nimeh@Sun.COM 
196*12573SDina.Nimeh@Sun.COM clean1:
197*12573SDina.Nimeh@Sun.COM #ifdef _KERNEL
198*12573SDina.Nimeh@Sun.COM 	kmem_free(sha1_context, sizeof (SHA1_CTX));
199*12573SDina.Nimeh@Sun.COM #else
200*12573SDina.Nimeh@Sun.COM 	free(sha1_context);
201*12573SDina.Nimeh@Sun.COM #endif
202*12573SDina.Nimeh@Sun.COM 	return (rv);
203*12573SDina.Nimeh@Sun.COM }
204*12573SDina.Nimeh@Sun.COM 
205*12573SDina.Nimeh@Sun.COM /*
206*12573SDina.Nimeh@Sun.COM  * DSA Power-On SelfTest(s).
207*12573SDina.Nimeh@Sun.COM  */
208*12573SDina.Nimeh@Sun.COM int
209*12573SDina.Nimeh@Sun.COM fips_dsa_post(void)
210*12573SDina.Nimeh@Sun.COM {
211*12573SDina.Nimeh@Sun.COM 	DSAbytekey dsa_params;
212*12573SDina.Nimeh@Sun.COM 	CK_RV rv;
213*12573SDina.Nimeh@Sun.COM 	uint8_t dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH];
214*12573SDina.Nimeh@Sun.COM 
215*12573SDina.Nimeh@Sun.COM 	/*
216*12573SDina.Nimeh@Sun.COM 	 * Generate a DSA public/private key pair.
217*12573SDina.Nimeh@Sun.COM 	 */
218*12573SDina.Nimeh@Sun.COM 	dsa_params.prime = dsa_P;
219*12573SDina.Nimeh@Sun.COM 	dsa_params.prime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_PRIME_LENGTH);
220*12573SDina.Nimeh@Sun.COM 	dsa_params.subprime = dsa_Q;
221*12573SDina.Nimeh@Sun.COM 	dsa_params.subprime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_SUBPRIME_LENGTH);
222*12573SDina.Nimeh@Sun.COM 	dsa_params.base = dsa_G;
223*12573SDina.Nimeh@Sun.COM 	dsa_params.base_bytes = FIPS_DSA_BASE_LENGTH;
224*12573SDina.Nimeh@Sun.COM 
225*12573SDina.Nimeh@Sun.COM 	dsa_params.rfunc = fips_dsa_random_func;
226*12573SDina.Nimeh@Sun.COM 
227*12573SDina.Nimeh@Sun.COM 	rv = fips_dsa_genkey_pair(&dsa_params);
228*12573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
229*12573SDina.Nimeh@Sun.COM 		return (CKR_DEVICE_ERROR);
230*12573SDina.Nimeh@Sun.COM 
231*12573SDina.Nimeh@Sun.COM 	/*
232*12573SDina.Nimeh@Sun.COM 	 * DSA Known Answer Signature Test
233*12573SDina.Nimeh@Sun.COM 	 */
234*12573SDina.Nimeh@Sun.COM 
235*12573SDina.Nimeh@Sun.COM 	dsa_params.rfunc = fips_dsa_signature_func;
236*12573SDina.Nimeh@Sun.COM 
237*12573SDina.Nimeh@Sun.COM 	/* Perform DSA signature process. */
238*12573SDina.Nimeh@Sun.COM 	rv = fips_dsa_digest_sign(&dsa_params,
239*12573SDina.Nimeh@Sun.COM 	    dsa_known_digest, FIPS_DSA_DIGEST_LENGTH, dsa_computed_signature);
240*12573SDina.Nimeh@Sun.COM 
241*12573SDina.Nimeh@Sun.COM 	if ((rv != CKR_OK) ||
242*12573SDina.Nimeh@Sun.COM 	    (memcmp(dsa_computed_signature, dsa_known_signature,
243*12573SDina.Nimeh@Sun.COM 	    FIPS_DSA_SIGNATURE_LENGTH) != 0)) {
244*12573SDina.Nimeh@Sun.COM 		goto clean;
245*12573SDina.Nimeh@Sun.COM 	}
246*12573SDina.Nimeh@Sun.COM 
247*12573SDina.Nimeh@Sun.COM 	/*
248*12573SDina.Nimeh@Sun.COM 	 * DSA Known Answer Verification Test
249*12573SDina.Nimeh@Sun.COM 	 */
250*12573SDina.Nimeh@Sun.COM 
251*12573SDina.Nimeh@Sun.COM 	/* Perform DSA verification process. */
252*12573SDina.Nimeh@Sun.COM 	rv = fips_dsa_verify(&dsa_params,
253*12573SDina.Nimeh@Sun.COM 	    dsa_known_digest, dsa_computed_signature);
254*12573SDina.Nimeh@Sun.COM 
255*12573SDina.Nimeh@Sun.COM clean:
256*12573SDina.Nimeh@Sun.COM 	if (rv != CKR_OK)
257*12573SDina.Nimeh@Sun.COM 		return (CKR_DEVICE_ERROR);
258*12573SDina.Nimeh@Sun.COM 	else
259*12573SDina.Nimeh@Sun.COM 		return (CKR_OK);
260*12573SDina.Nimeh@Sun.COM }
261