Modify Sun copyright to follow OpenSSL style
[openssl.git] / test / ecdsatest.c
1 /*
2  * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4  *
5  * Licensed under the OpenSSL license (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <openssl/opensslconf.h> /* To see if OPENSSL_NO_EC is defined */
16
17 #ifdef OPENSSL_NO_EC
18 int main(int argc, char *argv[])
19 {
20     puts("Elliptic curves are disabled.");
21     return 0;
22 }
23 #else
24
25 # include <openssl/crypto.h>
26 # include <openssl/bio.h>
27 # include <openssl/evp.h>
28 # include <openssl/bn.h>
29 # include <openssl/ec.h>
30 # ifndef OPENSSL_NO_ENGINE
31 #  include <openssl/engine.h>
32 # endif
33 # include <openssl/err.h>
34 # include <openssl/rand.h>
35 # include "testutil.h"
36
37 static const char rnd_seed[] = "string to make the random number generator "
38     "think it has entropy";
39
40
41 /* functions to change the RAND_METHOD */
42 static int fbytes(unsigned char *buf, int num);
43
44 static RAND_METHOD fake_rand;
45 static const RAND_METHOD *old_rand;
46
47 static int change_rand(void)
48 {
49     /* save old rand method */
50     if (!TEST_ptr(old_rand = RAND_get_rand_method()))
51         return 0;
52
53     fake_rand = *old_rand;
54     /* use own random function */
55     fake_rand.bytes = fbytes;
56     /* set new RAND_METHOD */
57     if (!TEST_true(RAND_set_rand_method(&fake_rand)))
58         return 0;
59     return 1;
60 }
61
62 static int restore_rand(void)
63 {
64     if (!TEST_true(RAND_set_rand_method(old_rand)))
65         return 0;
66     return 1;
67 }
68
69 static int fbytes_counter = 0, use_fake = 0;
70 static const char *numbers[8] = {
71     "651056770906015076056810763456358567190100156695615665659",
72     "6140507067065001063065065565667405560006161556565665656654",
73     "8763001015071075675010661307616710783570106710677817767166"
74         "71676178726717",
75     "7000000175690566466555057817571571075705015757757057795755"
76         "55657156756655",
77     "1275552191113212300012030439187146164646146646466749494799",
78     "1542725565216523985789236956265265265235675811949404040041",
79     "1456427555219115346513212300075341203043918714616464614664"
80         "64667494947990",
81     "1712787255652165239672857892369562652652652356758119494040"
82         "40041670216363"
83 };
84
85 static int fbytes(unsigned char *buf, int num)
86 {
87     int ret = 0;
88     BIGNUM *tmp = NULL;
89
90     if (use_fake == 0)
91         return old_rand->bytes(buf, num);
92
93     use_fake = 0;
94
95     if (fbytes_counter >= 8)
96         return 0;
97     if (!TEST_ptr(tmp = BN_new()))
98         return 0;
99     if (!TEST_true(BN_dec2bn(&tmp, numbers[fbytes_counter]))) {
100         BN_free(tmp);
101         return 0;
102     }
103     fbytes_counter++;
104     if (TEST_int_eq(BN_num_bytes(tmp), num)
105             && TEST_true(BN_bn2bin(tmp, buf)))
106         ret = 1;
107     BN_free(tmp);
108     return ret;
109 }
110
111 /* some tests from the X9.62 draft */
112 static int x9_62_test_internal(int nid, const char *r_in, const char *s_in)
113 {
114     int ret = 0;
115     const char message[] = "abc";
116     unsigned char digest[20];
117     unsigned int dgst_len = 0;
118     EVP_MD_CTX *md_ctx;
119     EC_KEY *key = NULL;
120     ECDSA_SIG *signature = NULL;
121     BIGNUM *r = NULL, *s = NULL;
122     BIGNUM *kinv = NULL, *rp = NULL;
123     const BIGNUM *sig_r, *sig_s;
124
125     if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()))
126         goto x962_int_err;
127
128     /* get the message digest */
129     if (!TEST_true(EVP_DigestInit(md_ctx, EVP_sha1()))
130         || !TEST_true(EVP_DigestUpdate(md_ctx, (const void *)message, 3))
131         || !TEST_true(EVP_DigestFinal(md_ctx, digest, &dgst_len)))
132         goto x962_int_err;
133
134     TEST_info("testing %s", OBJ_nid2sn(nid));
135
136     /* create the key */
137     if (!TEST_ptr(key = EC_KEY_new_by_curve_name(nid)))
138         goto x962_int_err;
139     use_fake = 1;
140     if (!TEST_true(EC_KEY_generate_key(key)))
141         goto x962_int_err;
142
143     /* create the signature */
144     use_fake = 1;
145     /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */
146     if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp)))
147         goto x962_int_err;
148     if (!TEST_ptr(signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key)))
149         goto x962_int_err;
150
151     /* compare the created signature with the expected signature */
152     if (!TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new()))
153         goto x962_int_err;
154     if (!TEST_true(BN_dec2bn(&r, r_in)) || !TEST_true(BN_dec2bn(&s, s_in)))
155         goto x962_int_err;
156     ECDSA_SIG_get0(signature, &sig_r, &sig_s);
157     if (!TEST_BN_eq(sig_r, r)
158             || !TEST_BN_eq(sig_s, s))
159         goto x962_int_err;
160
161     /* verify the signature */
162     if (!TEST_int_eq(ECDSA_do_verify(digest, 20, signature, key), 1))
163         goto x962_int_err;
164
165     ret = 1;
166
167  x962_int_err:
168     EC_KEY_free(key);
169     ECDSA_SIG_free(signature);
170     BN_free(r);
171     BN_free(s);
172     EVP_MD_CTX_free(md_ctx);
173     BN_clear_free(kinv);
174     BN_clear_free(rp);
175     return ret;
176 }
177
178 static int x9_62_tests()
179 {
180     int ret = 0;
181
182     /* set own rand method */
183     if (!change_rand())
184         goto x962_err;
185
186     if (!TEST_true(x9_62_test_internal(NID_X9_62_prime192v1,
187                  "3342403536405981729393488334694600415596881826869351677613",
188                  "5735822328888155254683894997897571951568553642892029982342")))
189         goto x962_err;
190     if (!TEST_true(x9_62_test_internal(NID_X9_62_prime239v1,
191                  "3086361431751678114926225473006680188549593787585317781474"
192                              "62058306432176",
193                  "3238135532097973577080787768312505059318910517550078427819"
194                              "78505179448783")))
195         goto x962_err;
196
197 # ifndef OPENSSL_NO_EC2M
198     if (!TEST_true(x9_62_test_internal(NID_X9_62_c2tnb191v1,
199                  "87194383164871543355722284926904419997237591535066528048",
200                  "308992691965804947361541664549085895292153777025772063598")))
201         goto x962_err;
202     if (!TEST_true(x9_62_test_internal(NID_X9_62_c2tnb239v1,
203                  "2159633321041961198501834003903461262881815148684178964245"
204                              "5876922391552",
205                  "1970303740007316867383349976549972270528498040721988191026"
206                              "49413465737174")))
207         goto x962_err;
208 # endif
209     ret = 1;
210
211  x962_err:
212     if (!TEST_true(restore_rand()))
213         ret = 0;
214     return ret;
215 }
216
217 static int test_builtin(void)
218 {
219     EC_builtin_curve *curves = NULL;
220     size_t crv_len = 0, n = 0;
221     EC_KEY *eckey = NULL, *wrong_eckey = NULL;
222     EC_GROUP *group;
223     ECDSA_SIG *ecdsa_sig = NULL, *modified_sig = NULL;
224     unsigned char digest[20], wrong_digest[20];
225     unsigned char *signature = NULL;
226     const unsigned char *sig_ptr;
227     unsigned char *sig_ptr2;
228     unsigned char *raw_buf = NULL;
229     const BIGNUM *sig_r, *sig_s;
230     BIGNUM *modified_r = NULL, *modified_s = NULL;
231     BIGNUM *unmodified_r = NULL, *unmodified_s = NULL;
232     unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
233     int nid, ret = 0;
234
235     /* fill digest values with some random data */
236     if (!TEST_true(RAND_bytes(digest, 20))
237             || !TEST_true(RAND_bytes(wrong_digest, 20)))
238         goto builtin_err;
239
240     /* create and verify a ecdsa signature with every available curve */
241     /* get a list of all internal curves */
242     crv_len = EC_get_builtin_curves(NULL, 0);
243     if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
244             || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
245         goto builtin_err;
246
247     /* now create and verify a signature for every curve */
248     for (n = 0; n < crv_len; n++) {
249         unsigned char dirt, offset;
250
251         nid = curves[n].nid;
252         if (nid == NID_ipsec4 || nid == NID_X25519)
253             continue;
254         /* create new ecdsa key (== EC_KEY) */
255         if (!TEST_ptr(eckey = EC_KEY_new())
256                 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
257                 || !TEST_true(EC_KEY_set_group(eckey, group)))
258             goto builtin_err;
259         EC_GROUP_free(group);
260         degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
261         if (degree < 160) {
262             /* drop the curve */
263             EC_KEY_free(eckey);
264             eckey = NULL;
265             continue;
266         }
267         TEST_info("testing %s", OBJ_nid2sn(nid));
268
269         /* create key */
270         if (!TEST_true(EC_KEY_generate_key(eckey)))
271             goto builtin_err;
272         /* create second key */
273         if (!TEST_ptr(wrong_eckey = EC_KEY_new())
274                 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
275                 || !TEST_true(EC_KEY_set_group(wrong_eckey, group)))
276             goto builtin_err;
277         EC_GROUP_free(group);
278         if (!TEST_true(EC_KEY_generate_key(wrong_eckey)))
279             goto builtin_err;
280
281         /* check key */
282         if (!TEST_true(EC_KEY_check_key(eckey)))
283             goto builtin_err;
284
285         /* create signature */
286         sig_len = ECDSA_size(eckey);
287         if (!TEST_ptr(signature = OPENSSL_malloc(sig_len))
288                 || !TEST_true(ECDSA_sign(0, digest, 20, signature, &sig_len,
289                                          eckey)))
290             goto builtin_err;
291
292         /* verify signature */
293         if (!TEST_int_eq(ECDSA_verify(0, digest, 20, signature, sig_len,
294                                       eckey), 1))
295             goto builtin_err;
296
297         /* verify signature with the wrong key */
298         if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, sig_len,
299                                       wrong_eckey), 1))
300             goto builtin_err;
301
302         /* wrong digest */
303         if (!TEST_int_ne(ECDSA_verify(0, wrong_digest, 20, signature,
304                                       sig_len, eckey), 1))
305             goto builtin_err;
306
307         /* wrong length */
308         if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature,
309                                       sig_len - 1, eckey), 1))
310             goto builtin_err;
311
312         /*
313          * Modify a single byte of the signature: to ensure we don't garble
314          * the ASN1 structure, we read the raw signature and modify a byte in
315          * one of the bignums directly.
316          */
317         sig_ptr = signature;
318         if (!TEST_ptr(ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)))
319             goto builtin_err;
320
321         ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s);
322
323         /* Store the two BIGNUMs in raw_buf. */
324         r_len = BN_num_bytes(sig_r);
325         s_len = BN_num_bytes(sig_s);
326         bn_len = (degree + 7) / 8;
327         if (!TEST_false(r_len > bn_len)
328                 || !TEST_false(s_len > bn_len))
329             goto builtin_err;
330         buf_len = 2 * bn_len;
331         if (!TEST_ptr(raw_buf = OPENSSL_zalloc(buf_len)))
332             goto builtin_err;
333         BN_bn2bin(sig_r, raw_buf + bn_len - r_len);
334         BN_bn2bin(sig_s, raw_buf + buf_len - s_len);
335
336         /* Modify a single byte in the buffer. */
337         offset = raw_buf[10] % buf_len;
338         dirt = raw_buf[11] ? raw_buf[11] : 1;
339         raw_buf[offset] ^= dirt;
340
341         /* Now read the BIGNUMs back in from raw_buf. */
342         if (!TEST_ptr(modified_sig = ECDSA_SIG_new()))
343             goto builtin_err;
344         if (!TEST_ptr(modified_r = BN_bin2bn(raw_buf, bn_len, NULL))
345                 || !TEST_ptr(modified_s = BN_bin2bn(raw_buf + bn_len,
346                                                     bn_len, NULL))
347                 || !TEST_true(ECDSA_SIG_set0(modified_sig,
348                                              modified_r, modified_s))) {
349             BN_free(modified_r);
350             BN_free(modified_s);
351             goto builtin_err;
352         }
353         sig_ptr2 = signature;
354         sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);
355         if (!TEST_false(ECDSA_verify(0, digest, 20, signature, sig_len, eckey)))
356             goto builtin_err;
357
358         /* Sanity check: undo the modification and verify signature. */
359         raw_buf[offset] ^= dirt;
360         if (!TEST_ptr(unmodified_r = BN_bin2bn(raw_buf, bn_len, NULL))
361                 || !TEST_ptr(unmodified_s = BN_bin2bn(raw_buf + bn_len,
362                                                        bn_len, NULL))
363                 || !TEST_true(ECDSA_SIG_set0(modified_sig, unmodified_r,
364                                              unmodified_s))) {
365             BN_free(unmodified_r);
366             BN_free(unmodified_s);
367             goto builtin_err;
368         }
369
370         sig_ptr2 = signature;
371         sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);
372         if (!TEST_true(ECDSA_verify(0, digest, 20, signature, sig_len, eckey)))
373             goto builtin_err;
374
375         /* cleanup */
376         ERR_clear_error();
377         OPENSSL_free(signature);
378         signature = NULL;
379         EC_KEY_free(eckey);
380         eckey = NULL;
381         EC_KEY_free(wrong_eckey);
382         wrong_eckey = NULL;
383         ECDSA_SIG_free(ecdsa_sig);
384         ecdsa_sig = NULL;
385         ECDSA_SIG_free(modified_sig);
386         modified_sig = NULL;
387         OPENSSL_free(raw_buf);
388         raw_buf = NULL;
389     }
390
391     ret = 1;
392  builtin_err:
393     EC_KEY_free(eckey);
394     EC_KEY_free(wrong_eckey);
395     ECDSA_SIG_free(ecdsa_sig);
396     ECDSA_SIG_free(modified_sig);
397     OPENSSL_free(signature);
398     OPENSSL_free(raw_buf);
399     OPENSSL_free(curves);
400
401     return ret;
402 }
403
404 void register_tests(void)
405 {
406     /* initialize the prng */
407     RAND_seed(rnd_seed, sizeof(rnd_seed));
408     ADD_TEST(x9_62_tests);
409     ADD_TEST(test_builtin);
410 }
411 #endif