1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 *
57 * The DSS routines are based on patches supplied by
58 * Steven Schoch <schoch@sheba.arc.nasa.gov>. */
59
60 #include <openssl/dsa.h>
61
62 #include <string.h>
63
64 #include <openssl/bn.h>
65 #include <openssl/crypto.h>
66 #include <openssl/err.h>
67
68
69 static int dsa_cb(int p, int n, BN_GENCB *arg);
70
71 /* The following values are taken from the updated Appendix 5 to FIPS PUB 186
72 * and also appear in Appendix 5 to FIPS PUB 186-1. */
73
74 static const uint8_t seed[20] = {
75 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b,
76 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
77 };
78
79 static const uint8_t fips_p[] = {
80 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, 0x3d, 0x25, 0x75,
81 0x9b, 0xb0, 0x68, 0x69, 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d,
82 0x0c, 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, 0xd0,
83 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, 0xc2, 0xe9, 0xad, 0xac,
84 0x32, 0xab, 0x7a, 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
85 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
86 };
87
88 static const uint8_t fips_q[] = {
89 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, 0x99, 0x3b, 0x4f,
90 0x2d, 0xed, 0x30, 0xf4, 0x8e, 0xda, 0xce, 0x91, 0x5f,
91 };
92
93 static const uint8_t fips_g[] = {
94 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, 0x41, 0x31, 0x63,
95 0xa5, 0x5b, 0x4c, 0xb5, 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c,
96 0xef, 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, 0x71,
97 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, 0x58, 0xe5, 0xb7, 0x95,
98 0x21, 0x92, 0x5c, 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
99 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
100 };
101
102 static const uint8_t fips_x[] = {
103 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f, 0xde, 0x1c, 0x0f,
104 0xfc, 0x7b, 0x2e, 0x3b, 0x49, 0x8b, 0x26, 0x06, 0x14,
105 };
106
107 static const uint8_t fips_y[] = {
108 0x19, 0x13, 0x18, 0x71, 0xd7, 0x5b, 0x16, 0x12, 0xa8, 0x19, 0xf2,
109 0x9d, 0x78, 0xd1, 0xb0, 0xd7, 0x34, 0x6f, 0x7a, 0xa7, 0x7b, 0xb6,
110 0x2a, 0x85, 0x9b, 0xfd, 0x6c, 0x56, 0x75, 0xda, 0x9d, 0x21, 0x2d,
111 0x3a, 0x36, 0xef, 0x16, 0x72, 0xef, 0x66, 0x0b, 0x8c, 0x7c, 0x25,
112 0x5c, 0xc0, 0xec, 0x74, 0x85, 0x8f, 0xba, 0x33, 0xf4, 0x4c, 0x06,
113 0x69, 0x96, 0x30, 0xa7, 0x6b, 0x03, 0x0e, 0xe3, 0x33,
114 };
115
116 static const uint8_t fips_digest[] = {
117 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25,
118 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d,
119 };
120
121 /* fips_sig is a DER-encoded version of the r and s values in FIPS PUB 186-1. */
122 static const uint8_t fips_sig[] = {
123 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
124 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
125 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
126 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
127 0xdc, 0xd8, 0xc8,
128 };
129
130 /* fips_sig_negative is fips_sig with r encoded as a negative number. */
131 static const uint8_t fips_sig_negative[] = {
132 0x30, 0x2c, 0x02, 0x14, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43,
133 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3,
134 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf,
135 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc,
136 0xd8, 0xc8,
137 };
138
139 /* fip_sig_extra is fips_sig with trailing data. */
140 static const uint8_t fips_sig_extra[] = {
141 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10,
142 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
143 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
144 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
145 0xdc, 0xd8, 0xc8, 0x00,
146 };
147
148 /* fips_sig_lengths is fips_sig with a non-minimally encoded length. */
149 static const uint8_t fips_sig_bad_length[] = {
150 0x30, 0x81, 0x2d, 0x02, 0x15, 0x00, 0x8b, 0xac, 0x1a, 0xb6, 0x64,
151 0x10, 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c,
152 0x92, 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f,
153 0x56, 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d,
154 0xb6, 0xdc, 0xd8, 0xc8, 0x00,
155 };
156
157 /* fips_sig_bad_r is fips_sig with a bad r value. */
158 static const uint8_t fips_sig_bad_r[] = {
159 0x30, 0x2d, 0x02, 0x15, 0x00, 0x8c, 0xac, 0x1a, 0xb6, 0x64, 0x10,
160 0x43, 0x5c, 0xb7, 0x18, 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92,
161 0xb3, 0x41, 0xc0, 0x02, 0x14, 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56,
162 0xdf, 0x24, 0x58, 0xf4, 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6,
163 0xdc, 0xd8, 0xc8,
164 };
165
get_fips_dsa(void)166 static DSA *get_fips_dsa(void) {
167 DSA *dsa = DSA_new();
168 if (!dsa) {
169 return NULL;
170 }
171 dsa->p = BN_bin2bn(fips_p, sizeof(fips_p), NULL);
172 dsa->q = BN_bin2bn(fips_q, sizeof(fips_q), NULL);
173 dsa->g = BN_bin2bn(fips_g, sizeof(fips_g), NULL);
174 dsa->pub_key = BN_bin2bn(fips_y, sizeof(fips_y), NULL);
175 dsa->priv_key = BN_bin2bn(fips_x, sizeof(fips_x), NULL);
176 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL ||
177 dsa->pub_key == NULL || dsa->priv_key == NULL) {
178 DSA_free(dsa);
179 return NULL;
180 }
181 return dsa;
182 }
183
test_generate(FILE * out)184 static int test_generate(FILE *out) {
185 BN_GENCB cb;
186 DSA *dsa = NULL;
187 int counter, ok = 0, i, j;
188 uint8_t buf[256];
189 unsigned long h;
190 uint8_t sig[256];
191 unsigned int siglen;
192
193 fprintf(out, "test generation of DSA parameters\n");
194
195 BN_GENCB_set(&cb, dsa_cb, out);
196 dsa = DSA_new();
197 if (dsa == NULL ||
198 !DSA_generate_parameters_ex(dsa, 512, seed, 20, &counter, &h, &cb)) {
199 goto end;
200 }
201
202 fprintf(out, "seed\n");
203 for (i = 0; i < 20; i += 4) {
204 fprintf(out, "%02X%02X%02X%02X ", seed[i], seed[i + 1], seed[i + 2],
205 seed[i + 3]);
206 }
207 fprintf(out, "\ncounter=%d h=%ld\n", counter, h);
208
209 if (counter != 105) {
210 fprintf(stderr, "counter should be 105\n");
211 goto end;
212 }
213 if (h != 2) {
214 fprintf(stderr, "h should be 2\n");
215 goto end;
216 }
217
218 i = BN_bn2bin(dsa->q, buf);
219 j = sizeof(fips_q);
220 if (i != j || memcmp(buf, fips_q, i) != 0) {
221 fprintf(stderr, "q value is wrong\n");
222 goto end;
223 }
224
225 i = BN_bn2bin(dsa->p, buf);
226 j = sizeof(fips_p);
227 if (i != j || memcmp(buf, fips_p, i) != 0) {
228 fprintf(stderr, "p value is wrong\n");
229 goto end;
230 }
231
232 i = BN_bn2bin(dsa->g, buf);
233 j = sizeof(fips_g);
234 if (i != j || memcmp(buf, fips_g, i) != 0) {
235 fprintf(stderr, "g value is wrong\n");
236 goto end;
237 }
238
239 if (!DSA_generate_key(dsa) ||
240 !DSA_sign(0, fips_digest, sizeof(fips_digest), sig, &siglen, dsa)) {
241 goto end;
242 }
243 if (DSA_verify(0, fips_digest, sizeof(fips_digest), sig, siglen, dsa) == 1) {
244 ok = 1;
245 } else {
246 fprintf(stderr, "verification failure\n");
247 }
248
249 end:
250 DSA_free(dsa);
251
252 return ok;
253 }
254
test_verify(const uint8_t * sig,size_t sig_len,int expect)255 static int test_verify(const uint8_t *sig, size_t sig_len, int expect) {
256 int ok = 0;
257 DSA *dsa = get_fips_dsa();
258 if (dsa == NULL) {
259 goto end;
260 }
261
262 int ret = DSA_verify(0, fips_digest, sizeof(fips_digest), sig, sig_len, dsa);
263 if (ret != expect) {
264 fprintf(stderr, "DSA_verify returned %d, want %d\n", ret, expect);
265 goto end;
266 }
267 ok = 1;
268 /* Clear any errorrs from a test with expected failure. */
269 ERR_clear_error();
270
271 end:
272 DSA_free(dsa);
273
274 return ok;
275 }
276
main(int argc,char ** argv)277 int main(int argc, char **argv) {
278 CRYPTO_library_init();
279
280 if (!test_generate(stdout) ||
281 !test_verify(fips_sig, sizeof(fips_sig), 1) ||
282 !test_verify(fips_sig_negative, sizeof(fips_sig_negative), -1) ||
283 !test_verify(fips_sig_extra, sizeof(fips_sig_extra), -1) ||
284 !test_verify(fips_sig_bad_length, sizeof(fips_sig_bad_length), -1) ||
285 !test_verify(fips_sig_bad_r, sizeof(fips_sig_bad_r), 0)) {
286 ERR_print_errors_fp(stderr);
287 return 1;
288 }
289
290 printf("PASS\n");
291 return 0;
292 }
293
dsa_cb(int p,int n,BN_GENCB * arg)294 static int dsa_cb(int p, int n, BN_GENCB *arg) {
295 char c = '*';
296 static int ok = 0, num = 0;
297
298 switch (p) {
299 case 0:
300 c = '.';
301 num++;
302 break;
303 case 1:
304 c = '+';
305 break;
306 case 2:
307 c = '*';
308 ok++;
309 break;
310 case 3:
311 c = '\n';
312 }
313
314 fputc(c, arg->arg);
315 fflush(arg->arg);
316
317 if (!ok && p == 0 && num > 1) {
318 fprintf(stderr, "error in dsatest\n");
319 return 0;
320 }
321
322 return 1;
323 }
324