summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ecdh
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ecdh')
-rw-r--r--src/lib/libcrypto/ecdh/Makefile121
-rw-r--r--src/lib/libcrypto/ecdh/ecdhtest.c368
-rw-r--r--src/lib/libcrypto/ecdh/ech_ossl.c213
3 files changed, 702 insertions, 0 deletions
diff --git a/src/lib/libcrypto/ecdh/Makefile b/src/lib/libcrypto/ecdh/Makefile
new file mode 100644
index 0000000000..65d8904ee8
--- /dev/null
+++ b/src/lib/libcrypto/ecdh/Makefile
@@ -0,0 +1,121 @@
1#
2# crypto/ecdh/Makefile
3#
4
5DIR= ecdh
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g -Wall
10MAKEFILE= Makefile
11AR= ar r
12
13CFLAGS= $(INCLUDES) $(CFLAG)
14
15GENERAL=Makefile
16TEST=ecdhtest.c
17APPS=
18
19LIB=$(TOP)/libcrypto.a
20LIBSRC= ech_lib.c ech_ossl.c ech_key.c ech_err.c
21
22LIBOBJ= ech_lib.o ech_ossl.o ech_key.o ech_err.o
23
24SRC= $(LIBSRC)
25
26EXHEADER= ecdh.h
27HEADER= ech_locl.h $(EXHEADER)
28
29ALL= $(GENERAL) $(SRC) $(HEADER)
30
31top:
32 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
33
34all: lib
35
36lib: $(LIBOBJ)
37 $(AR) $(LIB) $(LIBOBJ)
38 $(RANLIB) $(LIB) || echo Never mind.
39 @touch lib
40
41files:
42 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
43
44links:
45 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
46 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
47 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
48
49install:
50 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
51 @headerlist="$(EXHEADER)"; for i in $$headerlist; \
52 do \
53 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
54 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
55 done;
56
57tags:
58 ctags $(SRC)
59
60tests:
61
62lint:
63 lint -DLINT $(INCLUDES) $(SRC)>fluff
64
65depend:
66 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
67 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
68
69dclean:
70 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
71 mv -f Makefile.new $(MAKEFILE)
72
73clean:
74 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
75
76# DO NOT DELETE THIS LINE -- make depend depends on it.
77
78ech_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
79ech_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
80ech_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
81ech_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
82ech_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
83ech_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
84ech_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
85ech_err.o: ech_err.c
86ech_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
87ech_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
88ech_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
89ech_key.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
90ech_key.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
91ech_key.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
92ech_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
93ech_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
94ech_key.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
95ech_key.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
96ech_key.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
97ech_key.o: ../../include/openssl/x509_vfy.h ech_key.c ech_locl.h
98ech_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
99ech_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
100ech_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
101ech_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
102ech_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
103ech_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
104ech_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
105ech_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
106ech_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
107ech_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
108ech_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
109ech_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
110ech_lib.o: ech_lib.c ech_locl.h
111ech_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
112ech_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
113ech_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
114ech_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
115ech_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/err.h
116ech_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
117ech_ossl.o: ../../include/openssl/opensslconf.h
118ech_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
119ech_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
120ech_ossl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
121ech_ossl.o: ../cryptlib.h ech_locl.h ech_ossl.c
diff --git a/src/lib/libcrypto/ecdh/ecdhtest.c b/src/lib/libcrypto/ecdh/ecdhtest.c
new file mode 100644
index 0000000000..212a87efa4
--- /dev/null
+++ b/src/lib/libcrypto/ecdh/ecdhtest.c
@@ -0,0 +1,368 @@
1/* crypto/ecdh/ecdhtest.c */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The ECDH software is originally written by Douglas Stebila of
13 * Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * openssl-core@openssl.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
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> /* for OPENSSL_NO_ECDH */
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
86int 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
102static void MS_CALLBACK cb(int p, int n, void *arg);
103#endif
104
105static const char rnd_seed[] = "string to make the random number generator think it has entropy";
106
107
108static const int KDF1_SHA1_len = 20;
109static 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
123static 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 }
285err:
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
299int 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 /* NIST PRIME CURVES TESTS */
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 /* NIST BINARY CURVES TESTS */
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
341err:
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_thread_state(NULL);
347 CRYPTO_mem_leaks_fp(stderr);
348 EXIT(ret);
349 return(ret);
350 }
351
352#if 0
353static 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
diff --git a/src/lib/libcrypto/ecdh/ech_ossl.c b/src/lib/libcrypto/ecdh/ech_ossl.c
new file mode 100644
index 0000000000..2a40ff12df
--- /dev/null
+++ b/src/lib/libcrypto/ecdh/ech_ossl.c
@@ -0,0 +1,213 @@
1/* crypto/ecdh/ech_ossl.c */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The ECDH software is originally written by Douglas Stebila of
13 * Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * openssl-core@OpenSSL.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70
71#include <string.h>
72#include <limits.h>
73
74#include "cryptlib.h"
75
76#include "ech_locl.h"
77#include <openssl/err.h>
78#include <openssl/sha.h>
79#include <openssl/obj_mac.h>
80#include <openssl/bn.h>
81
82static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key,
83 EC_KEY *ecdh,
84 void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
85
86static ECDH_METHOD openssl_ecdh_meth = {
87 "OpenSSL ECDH method",
88 ecdh_compute_key,
89#if 0
90 NULL, /* init */
91 NULL, /* finish */
92#endif
93 0, /* flags */
94 NULL /* app_data */
95};
96
97const ECDH_METHOD *ECDH_OpenSSL(void)
98 {
99 return &openssl_ecdh_meth;
100 }
101
102
103/* This implementation is based on the following primitives in the IEEE 1363 standard:
104 * - ECKAS-DH1
105 * - ECSVDP-DH
106 * Finally an optional KDF is applied.
107 */
108static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
109 EC_KEY *ecdh,
110 void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
111 {
112 BN_CTX *ctx;
113 EC_POINT *tmp=NULL;
114 BIGNUM *x=NULL, *y=NULL;
115 const BIGNUM *priv_key;
116 const EC_GROUP* group;
117 int ret= -1;
118 size_t buflen, len;
119 unsigned char *buf=NULL;
120
121 if (outlen > INT_MAX)
122 {
123 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
124 return -1;
125 }
126
127 if ((ctx = BN_CTX_new()) == NULL) goto err;
128 BN_CTX_start(ctx);
129 x = BN_CTX_get(ctx);
130 y = BN_CTX_get(ctx);
131
132 priv_key = EC_KEY_get0_private_key(ecdh);
133 if (priv_key == NULL)
134 {
135 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
136 goto err;
137 }
138
139 group = EC_KEY_get0_group(ecdh);
140 if ((tmp=EC_POINT_new(group)) == NULL)
141 {
142 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
143 goto err;
144 }
145
146 if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx))
147 {
148 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
149 goto err;
150 }
151
152 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
153 {
154 if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx))
155 {
156 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
157 goto err;
158 }
159 }
160 else
161 {
162 if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx))
163 {
164 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
165 goto err;
166 }
167 }
168
169 buflen = (EC_GROUP_get_degree(group) + 7)/8;
170 len = BN_num_bytes(x);
171 if (len > buflen)
172 {
173 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
174 goto err;
175 }
176 if ((buf = OPENSSL_malloc(buflen)) == NULL)
177 {
178 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
179 goto err;
180 }
181
182 memset(buf, 0, buflen - len);
183 if (len != (size_t)BN_bn2bin(x, buf + buflen - len))
184 {
185 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
186 goto err;
187 }
188
189 if (KDF != 0)
190 {
191 if (KDF(buf, buflen, out, &outlen) == NULL)
192 {
193 ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_KDF_FAILED);
194 goto err;
195 }
196 ret = outlen;
197 }
198 else
199 {
200 /* no KDF, just copy as much as we can */
201 if (outlen > buflen)
202 outlen = buflen;
203 memcpy(out, buf, outlen);
204 ret = outlen;
205 }
206
207err:
208 if (tmp) EC_POINT_free(tmp);
209 if (ctx) BN_CTX_end(ctx);
210 if (ctx) BN_CTX_free(ctx);
211 if (buf) OPENSSL_free(buf);
212 return(ret);
213 }