Coverage Report

Created: 2024-05-20 06:23

/src/nss/lib/freebl/ecl/ecp_secp384r1_wrap.c
Line
Count
Source (jump to first uncovered line)
1
/*-
2
 * MIT License
3
 * -
4
 * Copyright (c) 2020 Luis Rivera-Zamarripa, Jesús-Javier Chi-Domínguez, Billy Bob Brumley
5
 * -
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 * -
13
 * The above copyright notice and this permission notice shall be included in all
14
 * copies or substantial portions of the Software.
15
 * -
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 * SOFTWARE.
23
 */
24
25
#undef RADIX
26
#include "ecp.h"
27
#include "ecp_secp384r1.h"
28
#include "mpi-priv.h"
29
#include "mplogic.h"
30
31
/*-
32
 * reverse bytes -- total hack
33
 */
34
#define MP_BE2LE(a)            \
35
110k
    do {                       \
36
110k
        unsigned char z_bswap; \
37
110k
        z_bswap = a[0];        \
38
110k
        a[0] = a[47];          \
39
110k
        a[47] = z_bswap;       \
40
110k
        z_bswap = a[1];        \
41
110k
        a[1] = a[46];          \
42
110k
        a[46] = z_bswap;       \
43
110k
        z_bswap = a[2];        \
44
110k
        a[2] = a[45];          \
45
110k
        a[45] = z_bswap;       \
46
110k
        z_bswap = a[3];        \
47
110k
        a[3] = a[44];          \
48
110k
        a[44] = z_bswap;       \
49
110k
        z_bswap = a[4];        \
50
110k
        a[4] = a[43];          \
51
110k
        a[43] = z_bswap;       \
52
110k
        z_bswap = a[5];        \
53
110k
        a[5] = a[42];          \
54
110k
        a[42] = z_bswap;       \
55
110k
        z_bswap = a[6];        \
56
110k
        a[6] = a[41];          \
57
110k
        a[41] = z_bswap;       \
58
110k
        z_bswap = a[7];        \
59
110k
        a[7] = a[40];          \
60
110k
        a[40] = z_bswap;       \
61
110k
        z_bswap = a[8];        \
62
110k
        a[8] = a[39];          \
63
110k
        a[39] = z_bswap;       \
64
110k
        z_bswap = a[9];        \
65
110k
        a[9] = a[38];          \
66
110k
        a[38] = z_bswap;       \
67
110k
        z_bswap = a[10];       \
68
110k
        a[10] = a[37];         \
69
110k
        a[37] = z_bswap;       \
70
110k
        z_bswap = a[11];       \
71
110k
        a[11] = a[36];         \
72
110k
        a[36] = z_bswap;       \
73
110k
        z_bswap = a[12];       \
74
110k
        a[12] = a[35];         \
75
110k
        a[35] = z_bswap;       \
76
110k
        z_bswap = a[13];       \
77
110k
        a[13] = a[34];         \
78
110k
        a[34] = z_bswap;       \
79
110k
        z_bswap = a[14];       \
80
110k
        a[14] = a[33];         \
81
110k
        a[33] = z_bswap;       \
82
110k
        z_bswap = a[15];       \
83
110k
        a[15] = a[32];         \
84
110k
        a[32] = z_bswap;       \
85
110k
        z_bswap = a[16];       \
86
110k
        a[16] = a[31];         \
87
110k
        a[31] = z_bswap;       \
88
110k
        z_bswap = a[17];       \
89
110k
        a[17] = a[30];         \
90
110k
        a[30] = z_bswap;       \
91
110k
        z_bswap = a[18];       \
92
110k
        a[18] = a[29];         \
93
110k
        a[29] = z_bswap;       \
94
110k
        z_bswap = a[19];       \
95
110k
        a[19] = a[28];         \
96
110k
        a[28] = z_bswap;       \
97
110k
        z_bswap = a[20];       \
98
110k
        a[20] = a[27];         \
99
110k
        a[27] = z_bswap;       \
100
110k
        z_bswap = a[21];       \
101
110k
        a[21] = a[26];         \
102
110k
        a[26] = z_bswap;       \
103
110k
        z_bswap = a[22];       \
104
110k
        a[22] = a[25];         \
105
110k
        a[25] = z_bswap;       \
106
110k
        z_bswap = a[23];       \
107
110k
        a[23] = a[24];         \
108
110k
        a[24] = z_bswap;       \
109
110k
    } while (0)
110
111
static mp_err
112
point_mul_g_secp384r1_wrap(const mp_int *n, mp_int *out_x,
113
                           mp_int *out_y, const ECGroup *group)
114
5.51k
{
115
5.51k
    unsigned char b_x[48];
116
5.51k
    unsigned char b_y[48];
117
5.51k
    unsigned char b_n[48];
118
5.51k
    mp_err res;
119
120
5.51k
    ARGCHK(n != NULL && out_x != NULL && out_y != NULL, MP_BADARG);
121
122
    /* fail on out of range scalars */
123
5.51k
    if (mpl_significant_bits(n) > 384 || mp_cmp_z(n) != MP_GT)
124
0
        return MP_RANGE;
125
126
5.51k
    MP_CHECKOK(mp_to_fixlen_octets(n, b_n, 48));
127
5.51k
    MP_BE2LE(b_n);
128
5.51k
    point_mul_g_secp384r1(b_x, b_y, b_n);
129
5.51k
    MP_BE2LE(b_x);
130
5.51k
    MP_BE2LE(b_y);
131
5.51k
    MP_CHECKOK(mp_read_unsigned_octets(out_x, b_x, 48));
132
5.51k
    MP_CHECKOK(mp_read_unsigned_octets(out_y, b_y, 48));
133
134
5.51k
CLEANUP:
135
5.51k
    return res;
136
5.51k
}
137
138
static mp_err
139
point_mul_secp384r1_wrap(const mp_int *n, const mp_int *in_x,
140
                         const mp_int *in_y, mp_int *out_x,
141
                         mp_int *out_y, const ECGroup *group)
142
17.7k
{
143
17.7k
    unsigned char b_x[48];
144
17.7k
    unsigned char b_y[48];
145
17.7k
    unsigned char b_n[48];
146
17.7k
    mp_err res;
147
148
17.7k
    ARGCHK(n != NULL && in_x != NULL && in_y != NULL && out_x != NULL &&
149
17.7k
               out_y != NULL,
150
17.7k
           MP_BADARG);
151
152
    /* fail on out of range scalars */
153
17.7k
    if (mpl_significant_bits(n) > 384 || mp_cmp_z(n) != MP_GT)
154
0
        return MP_RANGE;
155
156
17.7k
    MP_CHECKOK(mp_to_fixlen_octets(n, b_n, 48));
157
17.7k
    MP_CHECKOK(mp_to_fixlen_octets(in_x, b_x, 48));
158
17.7k
    MP_CHECKOK(mp_to_fixlen_octets(in_y, b_y, 48));
159
17.7k
    MP_BE2LE(b_x);
160
17.7k
    MP_BE2LE(b_y);
161
17.7k
    MP_BE2LE(b_n);
162
17.7k
    point_mul_secp384r1(b_x, b_y, b_n, b_x, b_y);
163
17.7k
    MP_BE2LE(b_x);
164
17.7k
    MP_BE2LE(b_y);
165
17.7k
    MP_CHECKOK(mp_read_unsigned_octets(out_x, b_x, 48));
166
17.7k
    MP_CHECKOK(mp_read_unsigned_octets(out_y, b_y, 48));
167
168
17.7k
CLEANUP:
169
17.7k
    return res;
170
17.7k
}
171
172
static mp_err
173
point_mul_two_secp384r1_wrap(const mp_int *n1, const mp_int *n2,
174
                             const mp_int *in_x,
175
                             const mp_int *in_y, mp_int *out_x,
176
                             mp_int *out_y,
177
                             const ECGroup *group)
178
12.0k
{
179
12.0k
    unsigned char b_x[48];
180
12.0k
    unsigned char b_y[48];
181
12.0k
    unsigned char b_n1[48];
182
12.0k
    unsigned char b_n2[48];
183
12.0k
    mp_err res;
184
185
    /* If n2 == NULL or 0, this is just a base-point multiplication. */
186
12.0k
    if (n2 == NULL || mp_cmp_z(n2) == MP_EQ)
187
5.51k
        return point_mul_g_secp384r1_wrap(n1, out_x, out_y, group);
188
189
    /* If n1 == NULL or 0, this is just an arbitary-point multiplication. */
190
6.58k
    if (n1 == NULL || mp_cmp_z(n1) == MP_EQ)
191
5.62k
        return point_mul_secp384r1_wrap(n2, in_x, in_y, out_x, out_y, group);
192
193
954
    ARGCHK(in_x != NULL && in_y != NULL && out_x != NULL && out_y != NULL,
194
954
           MP_BADARG);
195
196
    /* fail on out of range scalars */
197
954
    if (mpl_significant_bits(n1) > 384 || mp_cmp_z(n1) != MP_GT ||
198
954
        mpl_significant_bits(n2) > 384 || mp_cmp_z(n2) != MP_GT)
199
0
        return MP_RANGE;
200
201
954
    MP_CHECKOK(mp_to_fixlen_octets(n1, b_n1, 48));
202
954
    MP_CHECKOK(mp_to_fixlen_octets(n2, b_n2, 48));
203
954
    MP_CHECKOK(mp_to_fixlen_octets(in_x, b_x, 48));
204
954
    MP_CHECKOK(mp_to_fixlen_octets(in_y, b_y, 48));
205
954
    MP_BE2LE(b_x);
206
954
    MP_BE2LE(b_y);
207
954
    MP_BE2LE(b_n1);
208
954
    MP_BE2LE(b_n2);
209
954
    point_mul_two_secp384r1(b_x, b_y, b_n1, b_n2, b_x, b_y);
210
954
    MP_BE2LE(b_x);
211
954
    MP_BE2LE(b_y);
212
954
    MP_CHECKOK(mp_read_unsigned_octets(out_x, b_x, 48));
213
954
    MP_CHECKOK(mp_read_unsigned_octets(out_y, b_y, 48));
214
215
954
CLEANUP:
216
954
    return res;
217
954
}
218
219
mp_err
220
ec_group_set_secp384r1(ECGroup *group, ECCurveName name)
221
29.2k
{
222
29.2k
    if (name == ECCurve_NIST_P384) {
223
29.2k
        group->base_point_mul = &point_mul_g_secp384r1_wrap;
224
29.2k
        group->point_mul = &point_mul_secp384r1_wrap;
225
29.2k
        group->points_mul = &point_mul_two_secp384r1_wrap;
226
29.2k
    }
227
29.2k
    return MP_OKAY;
228
29.2k
}