1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72: #include <stdio.h>
73: #include <stdlib.h>
74: #include <string.h>
75:
76: #include <openssl/opensslconf.h>
77:
78: #ifdef OPENSSL_NO_ECDSA
79: int main(int argc, char * argv[])
80: {
81: puts("Elliptic curves are disabled.");
82: return 0;
83: }
84: #else
85:
86: #include <openssl/crypto.h>
87: #include <openssl/bio.h>
88: #include <openssl/evp.h>
89: #include <openssl/bn.h>
90: #include <openssl/ecdsa.h>
91: #ifndef OPENSSL_NO_ENGINE
92: #include <openssl/engine.h>
93: #endif
94: #include <openssl/err.h>
95: #include <openssl/rand.h>
96:
97: static const char rnd_seed[] = "string to make the random number generator "
98: "think it has entropy";
99:
100:
101: int x9_62_tests(BIO *);
102: int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s);
103: int test_builtin(BIO *);
104:
105:
106: int change_rand(void);
107: int restore_rand(void);
108: int fbytes(unsigned char *buf, int num);
109:
110: RAND_METHOD fake_rand;
111: const RAND_METHOD *old_rand;
112:
113: int change_rand(void)
114: {
115:
116: if ((old_rand = RAND_get_rand_method()) == NULL)
117: return 0;
118:
119: fake_rand.seed = old_rand->seed;
120: fake_rand.cleanup = old_rand->cleanup;
121: fake_rand.add = old_rand->add;
122: fake_rand.status = old_rand->status;
123:
124: fake_rand.bytes = fbytes;
125: fake_rand.pseudorand = old_rand->bytes;
126:
127: if (!RAND_set_rand_method(&fake_rand))
128: return 0;
129: return 1;
130: }
131:
132: int restore_rand(void)
133: {
134: if (!RAND_set_rand_method(old_rand))
135: return 0;
136: else
137: return 1;
138: }
139:
140: static int fbytes_counter = 0;
141: static const char *numbers[8] = {
142: "651056770906015076056810763456358567190100156695615665659",
143: "6140507067065001063065065565667405560006161556565665656654",
144: "8763001015071075675010661307616710783570106710677817767166"
145: "71676178726717",
146: "7000000175690566466555057817571571075705015757757057795755"
147: "55657156756655",
148: "1275552191113212300012030439187146164646146646466749494799",
149: "1542725565216523985789236956265265265235675811949404040041",
150: "1456427555219115346513212300075341203043918714616464614664"
151: "64667494947990",
152: "1712787255652165239672857892369562652652652356758119494040"
153: "40041670216363"};
154:
155: int fbytes(unsigned char *buf, int num)
156: {
157: int ret;
158: BIGNUM *tmp = NULL;
159:
160: if (fbytes_counter >= 8)
161: return 0;
162: tmp = BN_new();
163: if (!tmp)
164: return 0;
165: if (!BN_dec2bn(&tmp, numbers[fbytes_counter]))
166: {
167: BN_free(tmp);
168: return 0;
169: }
170: fbytes_counter ++;
171: ret = BN_bn2bin(tmp, buf);
172: if (ret == 0 || ret != num)
173: ret = 0;
174: else
175: ret = 1;
176: if (tmp)
177: BN_free(tmp);
178: return ret;
179: }
180:
181:
182: int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
183: {
184: int ret = 0;
185: const char message[] = "abc";
186: unsigned char digest[20];
187: unsigned int dgst_len = 0;
188: EVP_MD_CTX md_ctx;
189: EC_KEY *key = NULL;
190: ECDSA_SIG *signature = NULL;
191: BIGNUM *r = NULL, *s = NULL;
192:
193: EVP_MD_CTX_init(&md_ctx);
194:
195: EVP_DigestInit(&md_ctx, EVP_ecdsa());
196: EVP_DigestUpdate(&md_ctx, (const void*)message, 3);
197: EVP_DigestFinal(&md_ctx, digest, &dgst_len);
198:
199: BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
200:
201: if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
202: goto x962_int_err;
203: if (!EC_KEY_generate_key(key))
204: goto x962_int_err;
205: BIO_printf(out, ".");
206: (void)BIO_flush(out);
207:
208: signature = ECDSA_do_sign(digest, 20, key);
209: if (signature == NULL)
210: goto x962_int_err;
211: BIO_printf(out, ".");
212: (void)BIO_flush(out);
213:
214: if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
215: goto x962_int_err;
216: if (!BN_dec2bn(&r, r_in) ||
217: !BN_dec2bn(&s, s_in))
218: goto x962_int_err;
219: if (BN_cmp(signature->r ,r) || BN_cmp(signature->s, s))
220: goto x962_int_err;
221: BIO_printf(out, ".");
222: (void)BIO_flush(out);
223:
224: if (ECDSA_do_verify(digest, 20, signature, key) != 1)
225: goto x962_int_err;
226: BIO_printf(out, ".");
227: (void)BIO_flush(out);
228:
229: BIO_printf(out, " ok\n");
230: ret = 1;
231: x962_int_err:
232: if (!ret)
233: BIO_printf(out, " failed\n");
234: if (key)
235: EC_KEY_free(key);
236: if (signature)
237: ECDSA_SIG_free(signature);
238: if (r)
239: BN_free(r);
240: if (s)
241: BN_free(s);
242: EVP_MD_CTX_cleanup(&md_ctx);
243: return ret;
244: }
245:
246: int x9_62_tests(BIO *out)
247: {
248: int ret = 0;
249:
250: BIO_printf(out, "some tests from X9.62:\n");
251:
252:
253: if (!change_rand())
254: goto x962_err;
255:
256: if (!x9_62_test_internal(out, NID_X9_62_prime192v1,
257: "3342403536405981729393488334694600415596881826869351677613",
258: "5735822328888155254683894997897571951568553642892029982342"))
259: goto x962_err;
260: if (!x9_62_test_internal(out, NID_X9_62_prime239v1,
261: "3086361431751678114926225473006680188549593787585317781474"
262: "62058306432176",
263: "3238135532097973577080787768312505059318910517550078427819"
264: "78505179448783"))
265: goto x962_err;
266: if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
267: "87194383164871543355722284926904419997237591535066528048",
268: "308992691965804947361541664549085895292153777025772063598"))
269: goto x962_err;
270: if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1,
271: "2159633321041961198501834003903461262881815148684178964245"
272: "5876922391552",
273: "1970303740007316867383349976549972270528498040721988191026"
274: "49413465737174"))
275: goto x962_err;
276:
277: ret = 1;
278: x962_err:
279: if (!restore_rand())
280: ret = 0;
281: return ret;
282: }
283:
284: int test_builtin(BIO *out)
285: {
286: EC_builtin_curve *curves = NULL;
287: size_t crv_len = 0, n = 0;
288: EC_KEY *eckey = NULL, *wrong_eckey = NULL;
289: EC_GROUP *group;
290: unsigned char digest[20], wrong_digest[20];
291: unsigned char *signature = NULL;
292: unsigned int sig_len;
293: int nid, ret = 0;
294:
295:
296: if (!RAND_pseudo_bytes(digest, 20) ||
297: !RAND_pseudo_bytes(wrong_digest, 20))
298: {
299: BIO_printf(out, "ERROR: unable to get random data\n");
300: goto builtin_err;
301: }
302:
303:
304:
305: BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
306: "with some internal curves:\n");
307:
308:
309: crv_len = EC_get_builtin_curves(NULL, 0);
310:
311: curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
312:
313: if (curves == NULL)
314: {
315: BIO_printf(out, "malloc error\n");
316: goto builtin_err;
317: }
318:
319: if (!EC_get_builtin_curves(curves, crv_len))
320: {
321: BIO_printf(out, "unable to get internal curves\n");
322: goto builtin_err;
323: }
324:
325:
326: for (n = 0; n < crv_len; n++)
327: {
328: unsigned char dirt, offset;
329:
330: nid = curves[n].nid;
331: if (nid == NID_ipsec4)
332: continue;
333:
334: if ((eckey = EC_KEY_new()) == NULL)
335: goto builtin_err;
336: group = EC_GROUP_new_by_curve_name(nid);
337: if (group == NULL)
338: goto builtin_err;
339: if (EC_KEY_set_group(eckey, group) == 0)
340: goto builtin_err;
341: EC_GROUP_free(group);
342: if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160)
343:
344: {
345: EC_KEY_free(eckey);
346: eckey = NULL;
347: continue;
348: }
349: BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
350:
351: if (!EC_KEY_generate_key(eckey))
352: {
353: BIO_printf(out, " failed\n");
354: goto builtin_err;
355: }
356:
357: if ((wrong_eckey = EC_KEY_new()) == NULL)
358: goto builtin_err;
359: group = EC_GROUP_new_by_curve_name(nid);
360: if (group == NULL)
361: goto builtin_err;
362: if (EC_KEY_set_group(wrong_eckey, group) == 0)
363: goto builtin_err;
364: EC_GROUP_free(group);
365: if (!EC_KEY_generate_key(wrong_eckey))
366: {
367: BIO_printf(out, " failed\n");
368: goto builtin_err;
369: }
370:
371: BIO_printf(out, ".");
372: (void)BIO_flush(out);
373:
374: if (!EC_KEY_check_key(eckey))
375: {
376: BIO_printf(out, " failed\n");
377: goto builtin_err;
378: }
379: BIO_printf(out, ".");
380: (void)BIO_flush(out);
381:
382: sig_len = ECDSA_size(eckey);
383: if ((signature = OPENSSL_malloc(sig_len)) == NULL)
384: goto builtin_err;
385: if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
386: {
387: BIO_printf(out, " failed\n");
388: goto builtin_err;
389: }
390: BIO_printf(out, ".");
391: (void)BIO_flush(out);
392:
393: if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
394: {
395: BIO_printf(out, " failed\n");
396: goto builtin_err;
397: }
398: BIO_printf(out, ".");
399: (void)BIO_flush(out);
400:
401: if (ECDSA_verify(0, digest, 20, signature, sig_len,
402: wrong_eckey) == 1)
403: {
404: BIO_printf(out, " failed\n");
405: goto builtin_err;
406: }
407: BIO_printf(out, ".");
408: (void)BIO_flush(out);
409:
410: if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
411: eckey) == 1)
412: {
413: BIO_printf(out, " failed\n");
414: goto builtin_err;
415: }
416: BIO_printf(out, ".");
417: (void)BIO_flush(out);
418:
419: offset = signature[10] % sig_len;
420: dirt = signature[11];
421: signature[offset] ^= dirt ? dirt : 1;
422: if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
423: {
424: BIO_printf(out, " failed\n");
425: goto builtin_err;
426: }
427: BIO_printf(out, ".");
428: (void)BIO_flush(out);
429:
430: BIO_printf(out, " ok\n");
431:
432: OPENSSL_free(signature);
433: signature = NULL;
434: EC_KEY_free(eckey);
435: eckey = NULL;
436: EC_KEY_free(wrong_eckey);
437: wrong_eckey = NULL;
438: }
439:
440: ret = 1;
441: builtin_err:
442: if (eckey)
443: EC_KEY_free(eckey);
444: if (wrong_eckey)
445: EC_KEY_free(wrong_eckey);
446: if (signature)
447: OPENSSL_free(signature);
448: if (curves)
449: OPENSSL_free(curves);
450:
451: return ret;
452: }
453:
454: int main(void)
455: {
456: int ret = 1;
457: BIO *out;
458:
459: out = BIO_new_fp(stdout, BIO_NOCLOSE);
460:
461:
462: if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) &&
463: (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
464: {
465: CRYPTO_malloc_debug_init();
466: CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
467: }
468: else
469: {
470:
471: CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
472: }
473: CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
474:
475: ERR_load_crypto_strings();
476:
477:
478: RAND_seed(rnd_seed, sizeof(rnd_seed));
479:
480:
481: if (!x9_62_tests(out)) goto err;
482: if (!test_builtin(out)) goto err;
483:
484: ret = 0;
485: err:
486: if (ret)
487: BIO_printf(out, "\nECDSA test failed\n");
488: else
489: BIO_printf(out, "\nECDSA test passed\n");
490: if (ret)
491: ERR_print_errors(out);
492: CRYPTO_cleanup_all_ex_data();
493: ERR_remove_state(0);
494: ERR_free_strings();
495: CRYPTO_mem_leaks(out);
496: if (out != NULL)
497: BIO_free(out);
498: return ret;
499: }
500: #endif