Embedded SDK
Embedded SDK
cx_math.c
Go to the documentation of this file.
1 
2 /*******************************************************************************
3  * Ledger Nano S - Secure firmware
4  * (c) 2022 Ledger
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  ********************************************************************************/
18 
19 #ifdef HAVE_MATH
20 
21 #include "cx_math.h"
22 #include "cx_utils.h"
23 
24 cx_err_t cx_math_cmp_no_throw(const uint8_t *a, const uint8_t *b, size_t length, int *diff)
25 {
26  cx_err_t error;
27  cx_bn_t bn_a, bn_b;
28 
29  CX_CHECK(cx_bn_lock(length, 0));
30  CX_CHECK(cx_bn_alloc_init(&bn_a, length, a, length));
31  CX_CHECK(cx_bn_alloc_init(&bn_b, length, b, length));
32  CX_CHECK(cx_bn_cmp(bn_a, bn_b, diff));
33 
34 end:
35  cx_bn_unlock();
36  return error;
37 }
38 
39 cx_err_t cx_math_add_no_throw(uint8_t *r, const uint8_t *a, const uint8_t *b, size_t len)
40 {
41  cx_bn_t bn_a, bn_b, bn_r;
42  cx_err_t error;
43 
44  CX_CHECK(cx_bn_lock(len, 0));
45  CX_CHECK(cx_bn_alloc(&bn_r, len));
46  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
47  CX_CHECK(cx_bn_alloc_init(&bn_b, len, b, len));
48  CX_CHECK_IGNORE_CARRY(cx_bn_add(bn_r, bn_a, bn_b));
49  CX_CHECK(cx_bn_export(bn_r, r, len));
50 
51 end:
52  cx_bn_unlock();
53  return error;
54 }
55 
56 cx_err_t cx_math_sub_no_throw(uint8_t *r, const uint8_t *a, const uint8_t *b, size_t len)
57 {
58  cx_bn_t bn_a, bn_b, bn_r;
59  cx_err_t error;
60 
61  CX_CHECK(cx_bn_lock(len, 0));
62  CX_CHECK(cx_bn_alloc(&bn_r, len));
63  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
64  CX_CHECK(cx_bn_alloc_init(&bn_b, len, b, len));
65  CX_CHECK_IGNORE_CARRY(cx_bn_sub(bn_r, bn_a, bn_b));
66  CX_CHECK(cx_bn_export(bn_r, r, len));
67 
68 end:
69  cx_bn_unlock();
70  return error;
71 }
72 
73 cx_err_t cx_math_mult_no_throw(uint8_t *r, const uint8_t *a, const uint8_t *b, size_t len)
74 {
75  cx_bn_t bn_a, bn_b, bn_r;
76  cx_err_t error;
77 
78  CX_CHECK(cx_bn_lock(len, 0));
79  CX_CHECK(cx_bn_alloc(&bn_r, 2 * len));
80  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
81  CX_CHECK(cx_bn_alloc_init(&bn_b, len, b, len));
82  CX_CHECK(cx_bn_mul(bn_r, bn_a, bn_b));
83  CX_CHECK(cx_bn_export(bn_r, r, 2 * len));
84 
85 end:
86  cx_bn_unlock();
87  return error;
88 }
89 
90 cx_err_t cx_math_addm_no_throw(uint8_t *r,
91  const uint8_t *a,
92  const uint8_t *b,
93  const uint8_t *m,
94  size_t len)
95 {
96  cx_bn_t bn_a, bn_b, bn_m, bn_r;
97  cx_err_t error;
98 
99  CX_CHECK(cx_bn_lock(len, 0));
100  CX_CHECK(cx_bn_alloc(&bn_r, len));
101  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
102  CX_CHECK(cx_bn_alloc_init(&bn_b, len, b, len));
103  CX_CHECK(cx_bn_alloc_init(&bn_m, len, m, len));
104  CX_CHECK(cx_bn_mod_add(bn_r, bn_a, bn_b, bn_m));
105 #ifdef ST33K1M5
106  CX_CHECK(cx_bn_set_u32(bn_a, 0));
107  CX_CHECK(cx_bn_mod_sub(bn_r, bn_r, bn_a, bn_m));
108 #endif // ST33K1M5
109  CX_CHECK(cx_bn_export(bn_r, r, len));
110 
111 end:
112  cx_bn_unlock();
113  return error;
114 }
115 
116 cx_err_t cx_math_subm_no_throw(uint8_t *r,
117  const uint8_t *a,
118  const uint8_t *b,
119  const uint8_t *m,
120  size_t len)
121 {
122  cx_bn_t bn_a, bn_b, bn_m, bn_r;
123  cx_err_t error;
124 
125  CX_CHECK(cx_bn_lock(len, 0));
126  CX_CHECK(cx_bn_alloc(&bn_r, len));
127  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
128  CX_CHECK(cx_bn_alloc_init(&bn_b, len, b, len));
129  CX_CHECK(cx_bn_alloc_init(&bn_m, len, m, len));
130  CX_CHECK(cx_bn_mod_sub(bn_r, bn_a, bn_b, bn_m));
131  CX_CHECK(cx_bn_export(bn_r, r, len));
132 
133 end:
134  cx_bn_unlock();
135  return error;
136 }
137 
138 cx_err_t cx_math_multm_no_throw(uint8_t *r,
139  const uint8_t *a,
140  const uint8_t *b,
141  const uint8_t *m,
142  size_t len)
143 {
144  cx_bn_t bn_a, bn_b, bn_m, bn_r;
145  cx_err_t error;
146 
147  CX_CHECK(cx_bn_lock(len, 0));
148  CX_CHECK(cx_bn_alloc(&bn_r, len));
149  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
150  CX_CHECK(cx_bn_alloc_init(&bn_b, len, b, len));
151  CX_CHECK(cx_bn_alloc_init(&bn_m, len, m, len));
152  CX_CHECK(cx_bn_mod_mul(bn_r, bn_a, bn_b, bn_m));
153  CX_CHECK(cx_bn_export(bn_r, r, len));
154 
155 end:
156  cx_bn_unlock();
157  return error;
158 }
159 
160 cx_err_t cx_math_modm_no_throw(uint8_t *v, size_t len_v, const uint8_t *m, size_t len_m)
161 {
162  cx_bn_t bn_v, bn_m, bn_r;
163  cx_err_t error;
164 
165  CX_CHECK(cx_bn_lock(len_v, 0));
166  CX_CHECK(cx_bn_alloc(&bn_r, len_v));
167  CX_CHECK(cx_bn_alloc_init(&bn_v, len_v, v, len_v));
168  CX_CHECK(cx_bn_alloc_init(&bn_m, len_m, m, len_m));
169  CX_CHECK(cx_bn_reduce(bn_r, bn_v, bn_m));
170  CX_CHECK(cx_bn_export(bn_r, v, len_v));
171 
172 end:
173  cx_bn_unlock();
174  return error;
175 }
176 
177 cx_err_t cx_math_powm_no_throw(uint8_t *r,
178  const uint8_t *a,
179  const uint8_t *e,
180  size_t len_e,
181  const uint8_t *m,
182  size_t len)
183 {
184  cx_bn_t bn_a, bn_m, bn_r;
185  cx_err_t error;
186 
187  CX_CHECK(cx_bn_lock(len, 0));
188  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
189  CX_CHECK(cx_bn_alloc_init(&bn_m, len, m, len));
190  CX_CHECK(cx_bn_alloc(&bn_r, len));
191  CX_CHECK(cx_bn_mod_pow2(bn_r, bn_a, e, len_e, bn_m));
192  CX_CHECK(cx_bn_export(bn_r, r, len));
193 
194 end:
195  cx_bn_unlock();
196  return error;
197 }
198 
199 cx_err_t cx_math_invprimem_no_throw(uint8_t *r, const uint8_t *a, const uint8_t *m, size_t len)
200 {
201  cx_bn_t bn_a, bn_r, bn_m;
202  cx_err_t error;
203 
204  CX_CHECK(cx_bn_lock(len, 0));
205  CX_CHECK(cx_bn_alloc(&bn_r, len));
206  CX_CHECK(cx_bn_alloc_init(&bn_a, len, a, len));
207  CX_CHECK(cx_bn_alloc_init(&bn_m, len, m, len));
208  CX_CHECK(cx_bn_mod_invert_nprime(bn_r, bn_a, bn_m));
209  CX_CHECK(cx_bn_export(bn_r, r, len));
210 
211 end:
212  cx_bn_unlock();
213  return error;
214 }
215 
216 cx_err_t cx_math_invintm_no_throw(uint8_t *r, uint32_t a, const uint8_t *m, size_t len)
217 {
218  cx_bn_t bn_r, bn_m;
219  cx_err_t error;
220 
221  CX_CHECK(cx_bn_lock(len, 0));
222  CX_CHECK(cx_bn_alloc(&bn_r, len));
223  CX_CHECK(cx_bn_alloc_init(&bn_m, len, m, len));
224  CX_CHECK(cx_bn_mod_u32_invert(bn_r, a, bn_m));
225  CX_CHECK(cx_bn_export(bn_r, r, len));
226 
227 end:
228  cx_bn_unlock();
229  return error;
230 }
231 
232 cx_err_t cx_math_is_prime_no_throw(const uint8_t *r, size_t len, bool *prime)
233 {
234  cx_bn_t bn_r;
235  cx_err_t error;
236 
237  CX_CHECK(cx_bn_lock(len, 0));
238  CX_CHECK(cx_bn_alloc_init(&bn_r, len, r, len));
239  CX_CHECK(cx_bn_is_prime(bn_r, prime));
240 
241 end:
242  cx_bn_unlock();
243  return error;
244 }
245 
246 cx_err_t cx_math_next_prime_no_throw(uint8_t *r, uint32_t len)
247 {
248  cx_bn_t bn_r;
249  cx_err_t error;
250 
251  CX_CHECK(cx_bn_lock(len, 0));
252  CX_CHECK(cx_bn_alloc_init(&bn_r, len, r, len));
253  CX_CHECK(cx_bn_next_prime(bn_r));
254  CX_CHECK(cx_bn_export(bn_r, r, len));
255 
256 end:
257  cx_bn_unlock();
258  return error;
259 }
260 
261 #endif // HAVE_MATH
unsigned char uint8_t
Definition: usbd_conf.h:53