]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bearssl/src/ec/ec_keygen.c
ena: Upgrade ena-com to freebsd v2.7.0
[FreeBSD/FreeBSD.git] / contrib / bearssl / src / ec / ec_keygen.c
1 /*
2  * Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining 
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be 
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 #include "inner.h"
26
27 /* see bearssl_ec.h */
28 size_t
29 br_ec_keygen(const br_prng_class **rng_ctx,
30         const br_ec_impl *impl, br_ec_private_key *sk,
31         void *kbuf, int curve)
32 {
33         const unsigned char *order;
34         unsigned char *buf;
35         size_t len;
36         unsigned mask;
37
38         if (curve < 0 || curve >= 32
39                 || ((impl->supported_curves >> curve) & 1) == 0)
40         {
41                 return 0;
42         }
43         order = impl->order(curve, &len);
44         while (len > 0 && *order == 0) {
45                 order ++;
46                 len --;
47         }
48         if (kbuf == NULL || len == 0) {
49                 return len;
50         }
51         mask = order[0];
52         mask |= (mask >> 1);
53         mask |= (mask >> 2);
54         mask |= (mask >> 4);
55
56         /*
57          * We generate sequences of random bits of the right size, until
58          * the value is strictly lower than the curve order (we also
59          * check for all-zero values, which are invalid).
60          */
61         buf = kbuf;
62         for (;;) {
63                 size_t u;
64                 unsigned cc, zz;
65
66                 (*rng_ctx)->generate(rng_ctx, buf, len);
67                 buf[0] &= mask;
68                 cc = 0;
69                 u = len;
70                 zz = 0;
71                 while (u -- > 0) {
72                         cc = ((unsigned)(buf[u] - order[u] - cc) >> 8) & 1;
73                         zz |= buf[u];
74                 }
75                 if (cc != 0 && zz != 0) {
76                         break;
77                 }
78         }
79
80         if (sk != NULL) {
81                 sk->curve = curve;
82                 sk->x = buf;
83                 sk->xlen = len;
84         }
85         return len;
86 }