/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 | } |