File Coverage

src/ec/ec_keygen.c
Criterion Covered Total %
statement 27 31 87.1
branch 13 22 59.0
condition n/a
subroutine n/a
pod n/a
total 40 53 75.4


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2018 Thomas Pornin
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 4           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 4 50         if (curve < 0 || curve >= 32
    50          
39 4 50         || ((impl->supported_curves >> curve) & 1) == 0)
40             {
41 0           return 0;
42             }
43 4           order = impl->order(curve, &len);
44 4 50         while (len > 0 && *order == 0) {
    50          
45 0           order ++;
46 0           len --;
47             }
48 4 100         if (kbuf == NULL || len == 0) {
    50          
49 2           return len;
50             }
51 2           mask = order[0];
52 2           mask |= (mask >> 1);
53 2           mask |= (mask >> 2);
54 2           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 2           buf = kbuf;
62 0           for (;;) {
63             size_t u;
64             unsigned cc, zz;
65              
66 2           (*rng_ctx)->generate(rng_ctx, buf, len);
67 2           buf[0] &= mask;
68 2           cc = 0;
69 2           u = len;
70 2           zz = 0;
71 66 100         while (u -- > 0) {
72 64           cc = ((unsigned)(buf[u] - order[u] - cc) >> 8) & 1;
73 64           zz |= buf[u];
74             }
75 2 50         if (cc != 0 && zz != 0) {
    50          
76 2           break;
77             }
78             }
79              
80 2 50         if (sk != NULL) {
81 2           sk->curve = curve;
82 2           sk->x = buf;
83 2           sk->xlen = len;
84             }
85 2           return len;
86             }