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