xref: /onnv-gate/usr/src/common/crypto/fips/fips_dsa_util.c (revision 12573:fb4ef506980f)
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  */
97 static uint8_t dsa_known_random_key_block[] = {
98 	"This is DSA RNG key!"
99 };
100 
101 static uint8_t dsa_known_random_signature_block[] = {
102 	"Random DSA Signature"
103 };
104 
105 /* DSA Known Digest (160-bits) */
106 static uint8_t dsa_known_digest[] = {
107 	"DSA Signature Digest"
108 };
109 
110 /* DSA Known Signature (320-bits). */
111 static uint8_t dsa_known_signature[] = {
112 	0x25, 0x7c, 0x3a, 0x79, 0x32, 0x45, 0xb7, 0x32,
113 	0x70, 0xca, 0x62, 0x63, 0x2b, 0xf6, 0x29, 0x2c,
114 	0x22, 0x2a, 0x03, 0xce, 0x65, 0x02, 0x72, 0x5a,
115 	0x66, 0x29, 0xcf, 0x56, 0xe6, 0xdf, 0xb0, 0xcc,
116 	0x53, 0x72, 0x56, 0x70, 0x92, 0xb5, 0x45, 0x75
117 
118 };
119 
120 
121 static int
122 fips_dsa_random_func(void *buf, size_t buflen)
123 {
124 	/* should not happen */
125 	if (buflen != FIPS_DSA_SEED_LENGTH)
126 		return (-1);
127 
128 	(void) memcpy(buf, dsa_known_random_key_block,
129 	    FIPS_DSA_SEED_LENGTH);
130 	return (0);
131 }
132 
133 static int
134 fips_dsa_signature_func(void *buf, size_t buflen)
135 {
136 	/* should not happen */
137 	if (buflen != FIPS_DSA_SEED_LENGTH)
138 		return (-1);
139 
140 	(void) memcpy(buf, dsa_known_random_signature_block,
141 	    FIPS_DSA_SEED_LENGTH);
142 	return (0);
143 }
144 
145 int
146 fips_dsa_genkey_pair(DSAbytekey *bkey)
147 {
148 	return (dsa_genkey_pair(bkey));
149 }
150 
151 int
152 fips_dsa_digest_sign(DSAbytekey *bkey,
153 	uint8_t *in, uint32_t inlen, uint8_t *out)
154 {
155 	CK_RV rv;
156 	SHA1_CTX *sha1_context;
157 	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
158 
159 	sha1_context = fips_sha1_build_context();
160 	if (sha1_context == NULL)
161 		return (CKR_HOST_MEMORY);
162 
163 	rv = fips_sha1_hash(sha1_context, in, inlen, sha1_computed_digest);
164 	if (rv != CKR_OK)
165 		goto clean1;
166 
167 	rv = dsa_sign(bkey, sha1_computed_digest, FIPS_DSA_DIGEST_LENGTH, out);
168 
169 clean1:
170 #ifdef _KERNEL
171 	kmem_free(sha1_context, sizeof (SHA1_CTX));
172 #else
173 	free(sha1_context);
174 #endif
175 	return (rv);
176 }
177 
178 int
179 fips_dsa_verify(DSAbytekey *bkey, uint8_t *data, uint8_t *sig)
180 {
181 	CK_RV rv;
182 	SHA1_CTX *sha1_context;
183 	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
184 
185 	sha1_context = fips_sha1_build_context();
186 	if (sha1_context == NULL)
187 		return (CKR_HOST_MEMORY);
188 
189 	rv = fips_sha1_hash(sha1_context, data, FIPS_DSA_DIGEST_LENGTH,
190 	    sha1_computed_digest);
191 	if (rv != CKR_OK)
192 		goto clean1;
193 
194 	rv = dsa_verify(bkey, sha1_computed_digest, sig);
195 
196 clean1:
197 #ifdef _KERNEL
198 	kmem_free(sha1_context, sizeof (SHA1_CTX));
199 #else
200 	free(sha1_context);
201 #endif
202 	return (rv);
203 }
204 
205 /*
206  * DSA Power-On SelfTest(s).
207  */
208 int
209 fips_dsa_post(void)
210 {
211 	DSAbytekey dsa_params;
212 	CK_RV rv;
213 	uint8_t dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH];
214 
215 	/*
216 	 * Generate a DSA public/private key pair.
217 	 */
218 	dsa_params.prime = dsa_P;
219 	dsa_params.prime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_PRIME_LENGTH);
220 	dsa_params.subprime = dsa_Q;
221 	dsa_params.subprime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_SUBPRIME_LENGTH);
222 	dsa_params.base = dsa_G;
223 	dsa_params.base_bytes = FIPS_DSA_BASE_LENGTH;
224 
225 	dsa_params.rfunc = fips_dsa_random_func;
226 
227 	rv = fips_dsa_genkey_pair(&dsa_params);
228 	if (rv != CKR_OK)
229 		return (CKR_DEVICE_ERROR);
230 
231 	/*
232 	 * DSA Known Answer Signature Test
233 	 */
234 
235 	dsa_params.rfunc = fips_dsa_signature_func;
236 
237 	/* Perform DSA signature process. */
238 	rv = fips_dsa_digest_sign(&dsa_params,
239 	    dsa_known_digest, FIPS_DSA_DIGEST_LENGTH, dsa_computed_signature);
240 
241 	if ((rv != CKR_OK) ||
242 	    (memcmp(dsa_computed_signature, dsa_known_signature,
243 	    FIPS_DSA_SIGNATURE_LENGTH) != 0)) {
244 		goto clean;
245 	}
246 
247 	/*
248 	 * DSA Known Answer Verification Test
249 	 */
250 
251 	/* Perform DSA verification process. */
252 	rv = fips_dsa_verify(&dsa_params,
253 	    dsa_known_digest, dsa_computed_signature);
254 
255 clean:
256 	if (rv != CKR_OK)
257 		return (CKR_DEVICE_ERROR);
258 	else
259 		return (CKR_OK);
260 }
261