File Coverage

src/rsa/rsa_i62_pub.c
Criterion Covered Total %
statement 21 26 80.7
branch 7 12 58.3
condition n/a
subroutine n/a
pod n/a
total 28 38 73.6


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2016 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             #if BR_INT128 || BR_UMUL128
28              
29             /*
30             * As a strict minimum, we need four buffers that can hold a
31             * modular integer. But TLEN is expressed in 64-bit words.
32             */
33             #define TLEN (2 * (2 + ((BR_MAX_RSA_SIZE + 30) / 31)))
34              
35             /* see bearssl_rsa.h */
36             uint32_t
37 3           br_rsa_i62_public(unsigned char *x, size_t xlen,
38             const br_rsa_public_key *pk)
39             {
40             const unsigned char *n;
41             size_t nlen;
42             uint64_t tmp[TLEN];
43             uint32_t *m, *a;
44             size_t fwlen;
45             long z;
46             uint32_t m0i, r;
47              
48             /*
49             * Get the actual length of the modulus, and see if it fits within
50             * our stack buffer. We also check that the length of x[] is valid.
51             */
52 3           n = pk->n;
53 3           nlen = pk->nlen;
54 3 50         while (nlen > 0 && *n == 0) {
    50          
55 0           n ++;
56 0           nlen --;
57             }
58 3 50         if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) {
    50          
    50          
59 0           return 0;
60             }
61 3           z = (long)nlen << 3;
62 3           fwlen = 1;
63 138 100         while (z > 0) {
64 135           z -= 31;
65 135           fwlen ++;
66             }
67             /*
68             * Convert fwlen to a count in 62-bit words.
69             */
70 3           fwlen = (fwlen + 1) >> 1;
71              
72             /*
73             * The modulus gets decoded into m[].
74             * The value to exponentiate goes into a[].
75             */
76 3           m = (uint32_t *)tmp;
77 3           a = (uint32_t *)(tmp + fwlen);
78              
79             /*
80             * Decode the modulus.
81             */
82 3           br_i31_decode(m, n, nlen);
83 3           m0i = br_i31_ninv31(m[1]);
84              
85             /*
86             * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be
87             * an odd integer.
88             */
89 3           r = m0i & 1;
90              
91             /*
92             * Decode x[] into a[]; we also check that its value is proper.
93             */
94 3           r &= br_i31_decode_mod(a, x, xlen, m);
95              
96             /*
97             * Compute the modular exponentiation.
98             */
99 3           br_i62_modpow_opt(a, pk->e, pk->elen, m, m0i,
100 3           tmp + 2 * fwlen, TLEN - 2 * fwlen);
101              
102             /*
103             * Encode the result.
104             */
105 3           br_i31_encode(x, xlen, a);
106 3           return r;
107             }
108              
109             /* see bearssl_rsa.h */
110             br_rsa_public
111 0           br_rsa_i62_public_get(void)
112             {
113 0           return &br_rsa_i62_public;
114             }
115              
116             #else
117              
118             /* see bearssl_rsa.h */
119             br_rsa_public
120             br_rsa_i62_public_get(void)
121             {
122             return 0;
123             }
124              
125             #endif