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