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