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: #include <stdio.h>
71: #include <stdlib.h>
72: #include <string.h>
73:
74: #include "../e_os.h"
75:
76: #include <openssl/opensslconf.h>
77: #include <openssl/crypto.h>
78: #include <openssl/bio.h>
79: #include <openssl/bn.h>
80: #include <openssl/objects.h>
81: #include <openssl/rand.h>
82: #include <openssl/sha.h>
83: #include <openssl/err.h>
84:
85: #ifdef OPENSSL_NO_ECDH
86: int main(int argc, char *argv[])
87: {
88: printf("No ECDH support\n");
89: return(0);
90: }
91: #else
92: #include <openssl/ec.h>
93: #include <openssl/ecdh.h>
94:
95: #ifdef OPENSSL_SYS_WIN16
96: #define MS_CALLBACK _far _loadds
97: #else
98: #define MS_CALLBACK
99: #endif
100:
101: #if 0
102: static void MS_CALLBACK cb(int p, int n, void *arg);
103: #endif
104:
105: static const char rnd_seed[] = "string to make the random number generator think it has entropy";
106:
107:
108: static const int KDF1_SHA1_len = 20;
109: static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
110: {
111: #ifndef OPENSSL_NO_SHA
112: if (*outlen < SHA_DIGEST_LENGTH)
113: return NULL;
114: else
115: *outlen = SHA_DIGEST_LENGTH;
116: return SHA1(in, inlen, out);
117: #else
118: return NULL;
119: #endif
120: }
121:
122:
123: static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
124: {
125: EC_KEY *a=NULL;
126: EC_KEY *b=NULL;
127: BIGNUM *x_a=NULL, *y_a=NULL,
128: *x_b=NULL, *y_b=NULL;
129: char buf[12];
130: unsigned char *abuf=NULL,*bbuf=NULL;
131: int i,alen,blen,aout,bout,ret=0;
132: const EC_GROUP *group;
133:
134: a = EC_KEY_new_by_curve_name(nid);
135: b = EC_KEY_new_by_curve_name(nid);
136: if (a == NULL || b == NULL)
137: goto err;
138:
139: group = EC_KEY_get0_group(a);
140:
141: if ((x_a=BN_new()) == NULL) goto err;
142: if ((y_a=BN_new()) == NULL) goto err;
143: if ((x_b=BN_new()) == NULL) goto err;
144: if ((y_b=BN_new()) == NULL) goto err;
145:
146: BIO_puts(out,"Testing key generation with ");
147: BIO_puts(out,text);
148: #ifdef NOISY
149: BIO_puts(out,"\n");
150: #else
151: (void)BIO_flush(out);
152: #endif
153:
154: if (!EC_KEY_generate_key(a)) goto err;
155:
156: if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
157: {
158: if (!EC_POINT_get_affine_coordinates_GFp(group,
159: EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
160: }
161: else
162: {
163: if (!EC_POINT_get_affine_coordinates_GF2m(group,
164: EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
165: }
166: #ifdef NOISY
167: BIO_puts(out," pri 1=");
168: BN_print(out,a->priv_key);
169: BIO_puts(out,"\n pub 1=");
170: BN_print(out,x_a);
171: BIO_puts(out,",");
172: BN_print(out,y_a);
173: BIO_puts(out,"\n");
174: #else
175: BIO_printf(out," .");
176: (void)BIO_flush(out);
177: #endif
178:
179: if (!EC_KEY_generate_key(b)) goto err;
180:
181: if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
182: {
183: if (!EC_POINT_get_affine_coordinates_GFp(group,
184: EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
185: }
186: else
187: {
188: if (!EC_POINT_get_affine_coordinates_GF2m(group,
189: EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
190: }
191:
192: #ifdef NOISY
193: BIO_puts(out," pri 2=");
194: BN_print(out,b->priv_key);
195: BIO_puts(out,"\n pub 2=");
196: BN_print(out,x_b);
197: BIO_puts(out,",");
198: BN_print(out,y_b);
199: BIO_puts(out,"\n");
200: #else
201: BIO_printf(out,".");
202: (void)BIO_flush(out);
203: #endif
204:
205: alen=KDF1_SHA1_len;
206: abuf=(unsigned char *)OPENSSL_malloc(alen);
207: aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1);
208:
209: #ifdef NOISY
210: BIO_puts(out," key1 =");
211: for (i=0; i<aout; i++)
212: {
213: sprintf(buf,"%02X",abuf[i]);
214: BIO_puts(out,buf);
215: }
216: BIO_puts(out,"\n");
217: #else
218: BIO_printf(out,".");
219: (void)BIO_flush(out);
220: #endif
221:
222: blen=KDF1_SHA1_len;
223: bbuf=(unsigned char *)OPENSSL_malloc(blen);
224: bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1);
225:
226: #ifdef NOISY
227: BIO_puts(out," key2 =");
228: for (i=0; i<bout; i++)
229: {
230: sprintf(buf,"%02X",bbuf[i]);
231: BIO_puts(out,buf);
232: }
233: BIO_puts(out,"\n");
234: #else
235: BIO_printf(out,".");
236: (void)BIO_flush(out);
237: #endif
238:
239: if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
240: {
241: #ifndef NOISY
242: BIO_printf(out, " failed\n\n");
243: BIO_printf(out, "key a:\n");
244: BIO_printf(out, "private key: ");
245: BN_print(out, EC_KEY_get0_private_key(a));
246: BIO_printf(out, "\n");
247: BIO_printf(out, "public key (x,y): ");
248: BN_print(out, x_a);
249: BIO_printf(out, ",");
250: BN_print(out, y_a);
251: BIO_printf(out, "\nkey b:\n");
252: BIO_printf(out, "private key: ");
253: BN_print(out, EC_KEY_get0_private_key(b));
254: BIO_printf(out, "\n");
255: BIO_printf(out, "public key (x,y): ");
256: BN_print(out, x_b);
257: BIO_printf(out, ",");
258: BN_print(out, y_b);
259: BIO_printf(out, "\n");
260: BIO_printf(out, "generated key a: ");
261: for (i=0; i<bout; i++)
262: {
263: sprintf(buf, "%02X", bbuf[i]);
264: BIO_puts(out, buf);
265: }
266: BIO_printf(out, "\n");
267: BIO_printf(out, "generated key b: ");
268: for (i=0; i<aout; i++)
269: {
270: sprintf(buf, "%02X", abuf[i]);
271: BIO_puts(out,buf);
272: }
273: BIO_printf(out, "\n");
274: #endif
275: fprintf(stderr,"Error in ECDH routines\n");
276: ret=0;
277: }
278: else
279: {
280: #ifndef NOISY
281: BIO_printf(out, " ok\n");
282: #endif
283: ret=1;
284: }
285: err:
286: ERR_print_errors_fp(stderr);
287:
288: if (abuf != NULL) OPENSSL_free(abuf);
289: if (bbuf != NULL) OPENSSL_free(bbuf);
290: if (x_a) BN_free(x_a);
291: if (y_a) BN_free(y_a);
292: if (x_b) BN_free(x_b);
293: if (y_b) BN_free(y_b);
294: if (b) EC_KEY_free(b);
295: if (a) EC_KEY_free(a);
296: return(ret);
297: }
298:
299: int main(int argc, char *argv[])
300: {
301: BN_CTX *ctx=NULL;
302: int ret=1;
303: BIO *out;
304:
305: CRYPTO_malloc_debug_init();
306: CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
307: CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
308:
309: #ifdef OPENSSL_SYS_WIN32
310: CRYPTO_malloc_init();
311: #endif
312:
313: RAND_seed(rnd_seed, sizeof rnd_seed);
314:
315: out=BIO_new(BIO_s_file());
316: if (out == NULL) EXIT(1);
317: BIO_set_fp(out,stdout,BIO_NOCLOSE);
318:
319: if ((ctx=BN_CTX_new()) == NULL) goto err;
320:
321:
322: if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) goto err;
323: if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) goto err;
324: if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
325: if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
326: if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
327:
328: if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
329: if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
330: if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) goto err;
331: if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) goto err;
332: if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) goto err;
333: if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) goto err;
334: if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) goto err;
335: if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
336: if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
337: if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;
338:
339: ret = 0;
340:
341: err:
342: ERR_print_errors_fp(stderr);
343: if (ctx) BN_CTX_free(ctx);
344: BIO_free(out);
345: CRYPTO_cleanup_all_ex_data();
346: ERR_remove_state(0);
347: CRYPTO_mem_leaks_fp(stderr);
348: EXIT(ret);
349: return(ret);
350: }
351:
352: #if 0
353: static void MS_CALLBACK cb(int p, int n, void *arg)
354: {
355: char c='*';
356:
357: if (p == 0) c='.';
358: if (p == 1) c='+';
359: if (p == 2) c='*';
360: if (p == 3) c='\n';
361: BIO_write((BIO *)arg,&c,1);
362: (void)BIO_flush((BIO *)arg);
363: #ifdef LINT
364: p=n;
365: #endif
366: }
367: #endif
368: #endif