1 /***************************************************************************//**
2 * \file cy_crypto_core_ecc_eddsa.c
3 * \version 2.120
4 *
5 * \brief
6 * This file provides constant and parameters for the API for the ECC EDDSA
7 * in the Crypto driver.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright (c) (2020-2024), Cypress Semiconductor Corporation (an Infineon company) or
12 * an affiliate of Cypress Semiconductor Corporation.
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #include "cy_device.h"
29
30 #if defined (CY_IP_MXCRYPTO)
31
32 #include "cy_crypto_core_sha.h"
33 #include "cy_crypto_core_ecc.h"
34
35 #if defined(__cplusplus)
36 extern "C" {
37 #endif
38
39 #if defined(CY_CRYPTO_CFG_EDDSA_C)
40
41 #include "cy_crypto_core_ecc_nist_p.h"
42 #include "cy_crypto_core_mem.h"
43 #include "cy_crypto_core_vu.h"
44
45 cy_en_crypto_status_t Cy_Crypto_Core_EDDSA_Bar_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size);
46 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_MulMod( CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t b, uint32_t size);
47 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_SquareMod( CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t size);
48 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_ExpMod(CRYPTO_Type *base, uint32_t p_x, uint32_t p_y, uint32_t p_e, uint32_t bitsize);
49 cy_en_crypto_status_t Cy_Crypto_Core_ED25519Add(CRYPTO_Type *base, cy_stc_crypto_edw_dp_type *edwDp, uint32_t s_x,
50 uint32_t s_y, uint32_t s_z,
51 uint32_t t_x, uint32_t t_y,
52 uint32_t size);
53 cy_en_crypto_status_t Cy_Crypto_Core_ED25519Double(CRYPTO_Type *base, cy_stc_crypto_edw_dp_type *edwDp, uint32_t s_x,
54 uint32_t s_y, uint32_t s_z,
55 uint32_t size);
56 cy_en_crypto_status_t Cy_Crypto_Core_ED25519InvTransform(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t s_z, uint32_t size);
57 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_PointMul(CRYPTO_Type *base, cy_stc_crypto_edw_dp_type *edwDp, uint32_t p_x, uint32_t p_y,
58 uint32_t p_d, uint32_t bitsize);
59 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_PointMulAdd(CRYPTO_Type *base, cy_stc_crypto_edw_dp_type *edwDp,
60 uint32_t p_x, uint32_t p_y, uint32_t s,
61 uint32_t q_x, uint32_t q_y, uint32_t h,
62 uint32_t bitsize);
63
64
65 #define CY_ED25519SIG_VERIFY_PASS (0xA1A1A1A1u)
66 #define CY_ED25519SIG_VERIFY_FAIL (0x00BADBADu)
67
Cy_Crypto_Core_ED25519_dom2_ctx(CRYPTO_Type * base,cy_en_eddsa_sig_type_t sigType,const uint8_t * ctx,uint32_t ctx_len,cy_stc_crypto_sha_state_t * shaState)68 static void Cy_Crypto_Core_ED25519_dom2_ctx( CRYPTO_Type *base, cy_en_eddsa_sig_type_t sigType, const uint8_t *ctx,
69 uint32_t ctx_len, cy_stc_crypto_sha_state_t *shaState )
70 {
71 uint8_t ct_init_string[] = "SigEd25519 no Ed25519 collisions";
72 uint8_t ct_flag;
73 uint8_t ct_ctx_len = (uint8_t)(ctx_len & 0xffu);
74
75 ct_flag = (sigType == CY_CRYPTO_EDDSA_CTX)? (uint8_t)0: (uint8_t)1;
76 /*Note: Can merge to one update call*/
77 (void)Cy_Crypto_Core_Sha_Update(base, shaState, (uint8_t const*)ct_init_string, 32u);
78 (void)Cy_Crypto_Core_Sha_Update(base, shaState, (uint8_t const*)&ct_flag, 1u);
79 (void)Cy_Crypto_Core_Sha_Update(base, shaState, (uint8_t const*)&ct_ctx_len, 1u);
80
81 if( ctx != NULL && ctx_len > 0u)
82 {
83 (void)Cy_Crypto_Core_Sha_Update(base, shaState, ctx, ctx_len );
84
85 }
86 }
87
88 /*******************************************************************************
89 * Function Name: Cy_Crypto_Core_EDDSA_Bar_MulRed
90 ****************************************************************************//**
91 *
92 * Barrett multiplication modular reduction.
93 * r = t mod p for known value of p
94 * r = t - (floor[t * 1/p]*p)
95 * VR_BARRET = | (1 << 2*bitsize)/ p |
96 * q = floor([t * VR_BARRETT] >> 2*bitsize)
97 * r = t - p*q
98 *
99 * r = IF (r >= p) r = r - p - reduce r using mod
100 * r = IF (r >= p) r = r - p
101 *
102 * \param base
103 * The pointer to a Crypto instance.
104 *
105 * \param z
106 * Register index for Barrett reduced value.
107 *
108 * \param x
109 * Register index for non reduced value.
110 *
111 * \param size
112 * Bit size.
113 *
114 * \return status code. See \ref cy_en_crypto_status_t.
115 *******************************************************************************/
Cy_Crypto_Core_EDDSA_Bar_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)116 cy_en_crypto_status_t Cy_Crypto_Core_EDDSA_Bar_MulRed(CRYPTO_Type *base,
117 uint32_t z,
118 uint32_t x,
119 uint32_t size)
120 {
121
122 uint32_t sh = 0u;
123 uint32_t t1 = 1u;
124 uint32_t t1_plus2 = 3u;
125 uint32_t t2_plus2 = 4u;
126 uint32_t t_double = 5u;
127 uint32_t z_double = 6u;
128 uint32_t my_z = 7u;
129 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
130
131 CY_CRYPTO_VU_PUSH_REG (base);
132
133 CY_CRYPTO_VU_LD_REG (base, my_z, z);
134 CY_CRYPTO_VU_LD_REG (base, z_double, x);
135
136 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t_double, (3u * size) + 7u);
137 if(CY_CRYPTO_SUCCESS != tmpResult)
138 {
139 return tmpResult;
140 }
141
142 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size+4u);
143 if(CY_CRYPTO_SUCCESS != tmpResult)
144 {
145 return tmpResult;
146 }
147
148 CY_CRYPTO_VU_UMUL (base, t_double, z_double, VR_BARRETT);
149 CY_CRYPTO_VU_SET_REG (base, sh, 512u, 2u);
150 CY_CRYPTO_VU_LSR (base, t1, t_double, sh);
151 CY_CRYPTO_VU_UMUL (base, t_double, t1, VR_P);
152 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1));
153
154 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1_plus2, size + 2u);
155 if(CY_CRYPTO_SUCCESS != tmpResult)
156 {
157 return tmpResult;
158 }
159
160 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2_plus2, size + 2u);
161 if(CY_CRYPTO_SUCCESS != tmpResult)
162 {
163 return tmpResult;
164 }
165 CY_CRYPTO_VU_SUB (base, t2_plus2, z_double, t_double);
166 CY_CRYPTO_VU_SUB (base, t1_plus2, t2_plus2, VR_P);
167 CY_CRYPTO_VU_COND_SWAP_REG (base, CY_CRYPTO_VU_COND_CC, t1_plus2, t2_plus2);
168 CY_CRYPTO_VU_SUB (base, t2_plus2, t1_plus2, VR_P);
169 CY_CRYPTO_VU_COND_MOV (base, CY_CRYPTO_VU_COND_CC, my_z, t1_plus2);
170 CY_CRYPTO_VU_COND_MOV (base, CY_CRYPTO_VU_COND_CS, my_z, t2_plus2);
171
172 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t2_plus2) |
173 CY_CRYPTO_VU_REG_BIT(t1_plus2) |
174 CY_CRYPTO_VU_REG_BIT(t_double));
175 CY_CRYPTO_VU_POP_REG (base);
176
177 return CY_CRYPTO_SUCCESS;
178 }
179
180 /*******************************************************************************
181 * Function Name: Cy_Crypto_Core_ED25519_MulMod
182 ****************************************************************************//**
183 *
184 * Modular multiplication in GF(VR_P).
185 * Leaf function.
186 *
187 * \param base
188 * The pointer to a Crypto instance.
189 *
190 * \param z
191 * Result = a * b % mod. Register index for product value.
192 *
193 * \param a
194 * Register index for multiplicand value.
195 *
196 * \param b
197 * Register index for multiplier value.
198 *
199 * \param size
200 * Bit size.
201 *
202 * \return status code. See \ref cy_en_crypto_status_t.
203 *******************************************************************************/
Cy_Crypto_Core_ED25519_MulMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b,uint32_t size)204 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_MulMod( CRYPTO_Type *base,
205 uint32_t z,
206 uint32_t a,
207 uint32_t b,
208 uint32_t size)
209 {
210 uint32_t ab_double = 0u;
211 uint32_t my_z = 1u;
212 uint32_t my_a = 2u;
213 uint32_t my_b = 3u;
214 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
215
216 CY_CRYPTO_VU_PUSH_REG (base);
217
218 CY_CRYPTO_VU_LD_REG(base, my_z, z);
219 CY_CRYPTO_VU_LD_REG(base, my_a, a);
220 CY_CRYPTO_VU_LD_REG(base, my_b, b);
221
222 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, ab_double, 2u * size);
223 if(CY_CRYPTO_SUCCESS != tmpResult)
224 {
225 return tmpResult;
226 }
227 CY_CRYPTO_VU_UMUL (base, ab_double, my_a, my_b);
228
229 /* Barrett reduction */
230 tmpResult = Cy_Crypto_Core_EDDSA_Bar_MulRed(base, my_z, ab_double, size);
231 if(CY_CRYPTO_SUCCESS != tmpResult)
232 {
233 return tmpResult;
234 }
235 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(ab_double));
236
237 CY_CRYPTO_VU_POP_REG (base);
238
239 return CY_CRYPTO_SUCCESS;
240 }
241
242 /*******************************************************************************
243 * Function Name: Cy_Crypto_Core_ED25519_SquareMod
244 ****************************************************************************//**
245 *
246 * Modular squaring in GF(VR_P).
247 *
248 * \param base
249 * The pointer to a Crypto instance.
250 *
251 * \param z
252 * Result = a * a % mod. Register index for product value.
253 *
254 * \param a
255 * Register index for multiplicand and multiplier value.
256 *
257 * \param size
258 * Bit size.
259 *
260 * \return status code. See \ref cy_en_crypto_status_t.
261 *******************************************************************************/
Cy_Crypto_Core_ED25519_SquareMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t size)262 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_SquareMod( CRYPTO_Type *base,
263 uint32_t z,
264 uint32_t a,
265 uint32_t size)
266 {
267 return Cy_Crypto_Core_ED25519_MulMod( base, z, a, a, size);
268 }
269
270 /*******************************************************************************
271 * Function Name: Cy_Crypto_Core_ED25519Add
272 ****************************************************************************//**
273 * ED25519 (Edwards and Twisted Edwards) point add on projective coordinates in GF(VR_P).
274 *
275 * Add for: R = P + Q
276 *
277 * https://hyperelliptic.org/EFD/g1p/auto-code/twisted/projective/addition/add-2008-bbjlp.op3
278 * with
279 * P = (X1, Z1)
280 * Q = (X2, Z2)
281 * R = (X3, Z3)
282 * and eliminating temporary variables t0, t3, ..., t9.
283 *
284 * Cost: 10M + 1S
285 *
286 * \param base
287 * The pointer to a Crypto instance.
288 *
289 * \param s_x
290 * Register index for projective X coordinate.
291 *
292 * \param s_y
293 * Register index for projective Y coordinate.
294 *
295 * \param s_z
296 * Register index for projective Z coordinate.
297 *
298 * \param t_x
299 * Register index for affine X coordinate.
300 *
301 * \param t_y
302 * Register index for affine Y coordinate.
303 *
304 * \param size
305 * Bit size.
306 *
307 * \return status code. See \ref cy_en_crypto_status_t.
308 *******************************************************************************/
Cy_Crypto_Core_ED25519Add(CRYPTO_Type * base,cy_stc_crypto_edw_dp_type * edwDp,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t t_x,uint32_t t_y,uint32_t size)309 cy_en_crypto_status_t Cy_Crypto_Core_ED25519Add(CRYPTO_Type *base,
310 cy_stc_crypto_edw_dp_type *edwDp,
311 uint32_t s_x,
312 uint32_t s_y,
313 uint32_t s_z,
314 uint32_t t_x,
315 uint32_t t_y,
316 uint32_t size
317 )
318 {
319 uint32_t t1 = 1u;
320 uint32_t b = 0u;
321 uint32_t c = 3u;
322 uint32_t d = 4u;
323 uint32_t e = 5u;
324 uint32_t f = 6u;
325 uint32_t g = 7u;
326 uint32_t my_s_x = 8u;
327 uint32_t my_s_y = 9u;
328 uint32_t my_s_z = 10u;
329 uint32_t my_t_x = 11u;
330 uint32_t my_t_y = 12u;
331 uint32_t t2;
332 uint32_t r_s_x, r_s_y, r_s_z, r_t_x, r_t_y;
333
334 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
335
336 CY_CRYPTO_VU_PUSH_REG (base);
337
338 CY_CRYPTO_VU_SAVE_REG(base, s_x, &r_s_x);
339 CY_CRYPTO_VU_SAVE_REG(base, s_y, &r_s_y);
340 CY_CRYPTO_VU_SAVE_REG(base, s_z, &r_s_z);
341 CY_CRYPTO_VU_SAVE_REG(base, t_x, &r_t_x);
342 CY_CRYPTO_VU_SAVE_REG(base, t_y, &r_t_y);
343
344 CY_CRYPTO_VU_RESTORE_REG(base, my_s_x, r_s_x);
345 CY_CRYPTO_VU_RESTORE_REG(base, my_s_y, r_s_y);
346 CY_CRYPTO_VU_RESTORE_REG(base, my_s_z, r_s_z);
347 CY_CRYPTO_VU_RESTORE_REG(base, my_t_x, r_t_x);
348 CY_CRYPTO_VU_RESTORE_REG(base, my_t_y, r_t_y);
349
350 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
351 if(CY_CRYPTO_SUCCESS != tmpResult)
352 {
353 return tmpResult;
354 }
355
356 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, b, size);
357 if(CY_CRYPTO_SUCCESS != tmpResult)
358 {
359 return tmpResult;
360 }
361
362 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, c, size);
363 if(CY_CRYPTO_SUCCESS != tmpResult)
364 {
365 return tmpResult;
366 }
367
368 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, d, size);
369 if(CY_CRYPTO_SUCCESS != tmpResult)
370 {
371 return tmpResult;
372 }
373
374 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, e, size);
375 if(CY_CRYPTO_SUCCESS != tmpResult)
376 {
377 return tmpResult;
378 }
379
380 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, f, size);
381 if(CY_CRYPTO_SUCCESS != tmpResult)
382 {
383 return tmpResult;
384 }
385
386 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, g, size);
387 if(CY_CRYPTO_SUCCESS != tmpResult)
388 {
389 return tmpResult;
390 }
391
392 /* A = Z1*Z2 */
393 /* Z2 = 1 skip first step
394 Note: Revisit if we randomize the base points*/
395 /* B = A^2 */
396 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, b, my_s_z, size);
397 if(CY_CRYPTO_SUCCESS != tmpResult)
398 {
399 return tmpResult;
400 }
401 /* C = X1*X2 */
402 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, c, my_s_x, my_t_x, size);
403 if(CY_CRYPTO_SUCCESS != tmpResult)
404 {
405 return tmpResult;
406 }
407 /* D = Y1*Y2 */
408 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, d, my_s_y, my_t_y, size);
409 if(CY_CRYPTO_SUCCESS != tmpResult)
410 {
411 return tmpResult;
412 }
413 /* E = d*C*D */
414 Cy_Crypto_Core_Vu_SetMemValue (base, t1, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->d), size);
415 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, f, c, d, size);
416 if(CY_CRYPTO_SUCCESS != tmpResult)
417 {
418 return tmpResult;
419 }
420
421 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, e, f, t1, size);
422 if(CY_CRYPTO_SUCCESS != tmpResult)
423 {
424 return tmpResult;
425 }
426 /* F = B-E */
427 Cy_Crypto_Core_EC_SubMod( base, f, b, e);
428 /* G = B+E */
429 Cy_Crypto_Core_EC_AddMod( base, g, b, e);
430 /* X3 = A*F*((X1+Y1)*(X2+Y2)-C-D) */
431 t2 = b;
432 Cy_Crypto_Core_EC_AddMod( base, t1, my_s_x, my_s_y);
433 Cy_Crypto_Core_EC_AddMod( base, t2, my_t_x, my_t_y);
434
435 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, my_s_x, t1, t2, size);
436 if(CY_CRYPTO_SUCCESS != tmpResult)
437 {
438 return tmpResult;
439 }
440
441 Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, c);
442 Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, d);
443
444 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, t1, my_s_z, f, size);
445 if(CY_CRYPTO_SUCCESS != tmpResult)
446 {
447 return tmpResult;
448 }
449
450 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, my_s_x, my_s_x, t1, size);
451 if(CY_CRYPTO_SUCCESS != tmpResult)
452 {
453 return tmpResult;
454 }
455
456 /* Y3 = A*G*(D-a*C) */
457 Cy_Crypto_Core_Vu_SetMemValue (base, t1, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->a), size);
458 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, t2, my_s_z, g, size);
459 if(CY_CRYPTO_SUCCESS != tmpResult)
460 {
461 return tmpResult;
462 }
463
464 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, t1, t1, c, size);
465 if(CY_CRYPTO_SUCCESS != tmpResult)
466 {
467 return tmpResult;
468 }
469
470 Cy_Crypto_Core_EC_SubMod( base, my_s_y, d, t1);
471 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, my_s_y, my_s_y, t2, size);
472 if(CY_CRYPTO_SUCCESS != tmpResult)
473 {
474 return tmpResult;
475 }
476
477 /* Z3 = F*G */
478 tmpResult =Cy_Crypto_Core_ED25519_MulMod( base, my_s_z, f, g, size);
479 if(CY_CRYPTO_SUCCESS != tmpResult)
480 {
481 return tmpResult;
482 }
483
484 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(b) |
485 CY_CRYPTO_VU_REG_BIT(c) | CY_CRYPTO_VU_REG_BIT(d) |
486 CY_CRYPTO_VU_REG_BIT(e) | CY_CRYPTO_VU_REG_BIT(f) |
487 CY_CRYPTO_VU_REG_BIT(g));
488
489 CY_CRYPTO_VU_POP_REG (base);
490
491 return CY_CRYPTO_SUCCESS;
492 }
493
494
495 /*******************************************************************************
496 * Function Name: Cy_Crypto_Core_ED25519Double
497 ****************************************************************************//**
498 *
499 * ED25519 (Edwards and Twisted Edwards) point doubling on projective coordinates in GF(VR_P).
500 *
501 * Double for: R = 2 * P for both Edwards and Twisted Edwards curves in projective
502 * coordinates.
503 *
504 * https://hyperelliptic.org/EFD/g1p/auto-code/twisted/projective/doubling/dbl-2008-bbjlp.op3
505 * with
506 * P = (X1, Z1)
507 * R = (X3, Z3)
508 * and eliminating H and temporary variables t0, ..., t4.
509 *
510 * Cost: 3M + 4S
511 *
512 * \param base
513 * The pointer to a Crypto instance.
514 *
515 * \param s_x
516 * Register index for projective X coordinate.
517 *
518 * \param s_y
519 * Register index for projective Y coordinate.
520 *
521 * \param s_z
522 * Register index for projective Z coordinate.
523 *
524 * \param size
525 * Bit size.
526 *
527 * \return status code. See \ref cy_en_crypto_status_t.
528 *******************************************************************************/
Cy_Crypto_Core_ED25519Double(CRYPTO_Type * base,cy_stc_crypto_edw_dp_type * edwDp,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t size)529 cy_en_crypto_status_t Cy_Crypto_Core_ED25519Double(CRYPTO_Type *base,
530 cy_stc_crypto_edw_dp_type *edwDp,
531 uint32_t s_x,
532 uint32_t s_y,
533 uint32_t s_z,
534 uint32_t size
535 )
536 /* 3M + 4S */
537 {
538 uint32_t b = 1u;
539 uint32_t c = 0u;
540 uint32_t d = 3u;
541 uint32_t e = 4u;
542 uint32_t f = 5u;
543 uint32_t j = 6u;
544 uint32_t my_s_x = 7u;
545 uint32_t my_s_y = 8u;
546 uint32_t my_s_z = 9u;
547 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
548
549 CY_CRYPTO_VU_PUSH_REG (base);
550
551 CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
552 CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
553 CY_CRYPTO_VU_LD_REG(base, my_s_z, s_z);
554
555 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, b, size);
556 if(CY_CRYPTO_SUCCESS != tmpResult)
557 {
558 return tmpResult;
559 }
560
561 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, c, size);
562 if(CY_CRYPTO_SUCCESS != tmpResult)
563 {
564 return tmpResult;
565 }
566
567 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, d, size);
568 if(CY_CRYPTO_SUCCESS != tmpResult)
569 {
570 return tmpResult;
571 }
572
573 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, e, size);
574 if(CY_CRYPTO_SUCCESS != tmpResult)
575 {
576 return tmpResult;
577 }
578
579 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, f, size);
580 if(CY_CRYPTO_SUCCESS != tmpResult)
581 {
582 return tmpResult;
583 }
584 Cy_Crypto_Core_Vu_SetMemValue (base, f, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->a), size);
585
586 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, j, size+1u);
587 if(CY_CRYPTO_SUCCESS != tmpResult)
588 {
589 return tmpResult;
590 }
591
592 /* B = (X1 + Y1)^2 */
593 Cy_Crypto_Core_EC_AddMod( base, b, my_s_x, my_s_y);
594 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, b, b, size);
595 if(CY_CRYPTO_SUCCESS != tmpResult)
596 {
597 return tmpResult;
598 }
599 /* C = X1^2 */
600 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, c, my_s_x, size);
601 if(CY_CRYPTO_SUCCESS != tmpResult)
602 {
603 return tmpResult;
604 }
605 /* D = Y1^2 */
606 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, d, my_s_y, size);
607 if(CY_CRYPTO_SUCCESS != tmpResult)
608 {
609 return tmpResult;
610 }
611 /* E = eddp->a*C */
612 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, e, f, c, size);
613 if(CY_CRYPTO_SUCCESS != tmpResult)
614 {
615 return tmpResult;
616 }
617 /* F = E+D */
618 Cy_Crypto_Core_EC_AddMod( base, f, e, d);
619 /* J = F - 2*(Z1^2) */
620 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, j, my_s_z, size);
621 if(CY_CRYPTO_SUCCESS != tmpResult)
622 {
623 return tmpResult;
624 }
625 /*2*(Z1^2) mod p*/
626 Cy_Crypto_Core_EC_AddMod( base, j, j, j);
627 Cy_Crypto_Core_EC_SubMod (base, j, f, j);
628 /* X3 = (B-C-D)*J */
629 Cy_Crypto_Core_EC_SubMod (base, b, b, c);
630 Cy_Crypto_Core_EC_SubMod (base, b, b, d);
631 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, my_s_x, b, j, size);
632 if(CY_CRYPTO_SUCCESS != tmpResult)
633 {
634 return tmpResult;
635 }
636 /* Y3 = F*(E-D) */
637 Cy_Crypto_Core_EC_SubMod (base, e, e, d);
638 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, my_s_y, f, e, size);
639 if(CY_CRYPTO_SUCCESS != tmpResult)
640 {
641 return tmpResult;
642 }
643 /* Z3 = F*J */
644 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, my_s_z, f, j, size);
645 if(CY_CRYPTO_SUCCESS != tmpResult)
646 {
647 return tmpResult;
648 }
649
650 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(b) | CY_CRYPTO_VU_REG_BIT(c) |
651 CY_CRYPTO_VU_REG_BIT(d) | CY_CRYPTO_VU_REG_BIT(e) |
652 CY_CRYPTO_VU_REG_BIT(f) | CY_CRYPTO_VU_REG_BIT(j) );
653 CY_CRYPTO_VU_POP_REG (base);
654
655 return CY_CRYPTO_SUCCESS;
656 }
657
658 /*******************************************************************************
659 * Function Name: Cy_Crypto_Core_ED25519InvTransform
660 ****************************************************************************//**
661 *
662 * Transformation from projective coordinates to affine coordinates in GF(VR_P).
663 * (s_x, s_y, s_z) -> (p_x, p_y), where p_x = s_x/s_z, p_y = s_y/s_z
664 *
665 * \param base
666 * The pointer to a Crypto instance.
667 *
668 * \param s_x
669 * Register index for affine X coordinate and projective X coordinate.
670 *
671 * \param s_y
672 * Register index for affine Y coordinate and projective Y coordinate.
673 *
674 * \param s_z
675 * Register index for projective Z coordinate.
676 *
677 * \param size
678 * Bit size.
679 *
680 * \return status code. See \ref cy_en_crypto_status_t.
681 *******************************************************************************/
Cy_Crypto_Core_ED25519InvTransform(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t size)682 cy_en_crypto_status_t Cy_Crypto_Core_ED25519InvTransform(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t s_z, uint32_t size)
683 {
684
685 uint32_t t1 = 7u;
686 uint32_t t2 = 8u;
687 uint32_t my_s_x = 9u;
688 uint32_t my_s_y = 10u;
689 uint32_t my_s_z = 11u;
690 uint32_t r_s_x, r_s_y, r_s_z;
691 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
692
693 CY_CRYPTO_VU_PUSH_REG (base);
694
695 CY_CRYPTO_VU_SAVE_REG(base, s_x, &r_s_x);
696 CY_CRYPTO_VU_SAVE_REG(base, s_y, &r_s_y);
697 CY_CRYPTO_VU_SAVE_REG(base, s_z, &r_s_z);
698
699 CY_CRYPTO_VU_RESTORE_REG(base, my_s_x, r_s_x);
700 CY_CRYPTO_VU_RESTORE_REG(base, my_s_y, r_s_y);
701 CY_CRYPTO_VU_RESTORE_REG(base, my_s_z, r_s_z);
702
703 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
704 if(CY_CRYPTO_SUCCESS != tmpResult)
705 {
706 return tmpResult;
707 }
708
709 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, size);
710 if(CY_CRYPTO_SUCCESS != tmpResult)
711 {
712 return tmpResult;
713 }
714
715 CY_CRYPTO_VU_SET_TO_ONE (base, t1); /* t1 = 1 */
716
717 tmpResult = Cy_Crypto_Core_EC_DivMod( base, t2, t1, my_s_z, size); /* t2 = 1/Z */
718 if(CY_CRYPTO_SUCCESS != tmpResult)
719 {
720 return tmpResult;
721 }
722
723 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, my_s_x, my_s_x, t2, size); /* my_s_x = X/Z */
724 if(CY_CRYPTO_SUCCESS != tmpResult)
725 {
726 return tmpResult;
727 }
728
729 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, my_s_y, my_s_y, t2, size); /* t3 = Y/Z */
730 if(CY_CRYPTO_SUCCESS != tmpResult)
731 {
732 return tmpResult;
733 }
734
735 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2));
736
737 CY_CRYPTO_VU_POP_REG (base);
738
739 return CY_CRYPTO_SUCCESS;
740 }
741
742 /*******************************************************************************
743 * Function Name: Cy_Crypto_Core_ED25519_PointMulAdd
744 ****************************************************************************//**
745 *
746 * Edward 25519 Elliptic curve point multiply-Add in GF(p).
747 *
748 * R = s*P + h*Q
749 *
750 * \param base
751 * The pointer to a Crypto instance.
752 *
753 * \param p_x
754 * Register index for affine X coordinate of point.
755 *
756 * \param p_y
757 * Register index for affine Y coordinate of point.
758 *
759 * \param s
760 * Register index for multiplication value.
761 *
762 * \param q_x
763 * Register index for affine X coordinate of point.
764 *
765 * \param q_y
766 * Register index for affine Y coordinate of point.
767 *
768 * \param h
769 * Register index for multiplication value.
770 *
771 * \param bitsize
772 * Bit size of the used curve.
773 *
774 * \return status code. See \ref cy_en_crypto_status_t.
775 *******************************************************************************/
Cy_Crypto_Core_ED25519_PointMulAdd(CRYPTO_Type * base,cy_stc_crypto_edw_dp_type * edwDp,uint32_t p_x,uint32_t p_y,uint32_t s,uint32_t q_x,uint32_t q_y,uint32_t h,uint32_t bitsize)776 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_PointMulAdd(CRYPTO_Type *base, cy_stc_crypto_edw_dp_type *edwDp,
777 uint32_t p_x, uint32_t p_y, uint32_t s,
778 uint32_t q_x, uint32_t q_y, uint32_t h,
779 uint32_t bitsize)
780 {
781 /* Note: Pre conditions 0 < (px,py)(qx,qy) < N-1 */
782 /* Do not use all arg REG (5,7,8,9,11,12), also on V1 reg2 is modified by mem ops */
783 uint32_t p_z = 1u;
784 uint32_t my_s = 3u;
785 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
786
787 CY_CRYPTO_VU_PUSH_REG (base);
788
789 CY_CRYPTO_VU_LD_REG(base, my_s, s);
790
791 /* load prime defining the curve as well as the barrett coefficient. */
792 /* VR_P and VR_BARRETT_U are "globally" defined in cy_crypto_core_ecc.h */
793 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_P, bitsize);
794 if(CY_CRYPTO_SUCCESS != tmpResult)
795 {
796 return tmpResult;
797 }
798 Cy_Crypto_Core_Vu_SetMemValue (base, VR_P, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->prime), bitsize);
799
800 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_BARRETT, edwDp->barret_psize);
801 if(CY_CRYPTO_SUCCESS != tmpResult)
802 {
803 return tmpResult;
804 }
805 Cy_Crypto_Core_Vu_SetMemValue (base, VR_BARRETT, (uint8_t const*)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->barrett_p), edwDp->barret_psize);
806
807
808 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_z, bitsize);
809 if(CY_CRYPTO_SUCCESS != tmpResult)
810 {
811 return tmpResult;
812 }
813 /* init point->z to 1. */
814 CY_CRYPTO_VU_SET_TO_ONE (base, p_z);
815
816 /*sB = point_mul(s, G)*/
817 tmpResult = Cy_Crypto_Core_ED25519_PointMul(base, edwDp, p_x, p_y, my_s, bitsize);
818 if(CY_CRYPTO_SUCCESS != tmpResult)
819 {
820 return tmpResult;
821 }
822 /*hA = point_mul(h, A)*/
823 tmpResult = Cy_Crypto_Core_ED25519_PointMul(base, edwDp, q_x, q_y, h, bitsize);
824 if(CY_CRYPTO_SUCCESS != tmpResult)
825 {
826 return tmpResult;
827 }
828 /* R = point_add(sB, hA) */
829 /* RFC Sec 5.1.7 Check the group equation [S]B = R + [k]A'. It's sufficient.
830 We perform fast single-signature verification by computing R = [s]B + [-k]A'. compressing 'R' and comparing with Sig[R] without
831 decompressing it.
832 */
833 tmpResult = Cy_Crypto_Core_ED25519Add (base, edwDp, p_x, p_y, p_z, q_x, q_y, bitsize);
834 if(CY_CRYPTO_SUCCESS != tmpResult)
835 {
836 return tmpResult;
837 }
838 /* Inverse transform */
839 tmpResult = Cy_Crypto_Core_ED25519InvTransform(base, p_x, p_y, p_z, bitsize);
840 if(CY_CRYPTO_SUCCESS != tmpResult)
841 {
842 return tmpResult;
843 }
844
845 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(p_z)|CY_CRYPTO_VU_REG_BIT(VR_P)|CY_CRYPTO_VU_REG_BIT(VR_BARRETT));
846
847 Cy_Crypto_Core_Vu_WaitForComplete(base);
848 CY_CRYPTO_VU_POP_REG (base);
849
850 return tmpResult;
851 }
852
853 /*******************************************************************************
854 * Function Name: Cy_Crypto_Core_ED25519_PointMul
855 ****************************************************************************//**
856 *
857 * Edward 25519 Elliptic curve point multiplication in GF(p).
858 *
859 * \param base
860 * The pointer to a Crypto instance.
861 *
862 * \param p_x
863 * Register index for affine X coordinate of base point.
864 *
865 * \param p_y
866 * Register index for affine Y coordinate of base point.
867 *
868 * \param p_d
869 * Register index for multiplication value.
870 *
871 * \param bitsize
872 * Bit size of the used curve.
873 *
874 * \return status code. See \ref cy_en_crypto_status_t.
875 *******************************************************************************/
Cy_Crypto_Core_ED25519_PointMul(CRYPTO_Type * base,cy_stc_crypto_edw_dp_type * edwDp,uint32_t p_x,uint32_t p_y,uint32_t p_d,uint32_t bitsize)876 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_PointMul(CRYPTO_Type *base, cy_stc_crypto_edw_dp_type *edwDp, uint32_t p_x, uint32_t p_y, uint32_t p_d, uint32_t bitsize)
877 {
878 /* Note: Pre conditions 0 < px, py < p-1 (consider randomizing the base point)*/
879
880 uint32_t i;
881 uint32_t status;
882 uint32_t carry;
883 uint16_t clsame;
884 uint32_t loop;
885
886 uint32_t clr = 5u;
887 uint32_t t = 6u;
888 uint32_t my_s_x = 7u;
889 uint32_t my_s_y = 8u;
890 uint32_t my_s_z = 9u;
891 uint32_t my_t_x = 10u;
892 uint32_t my_t_y = 11u;
893 uint32_t my_d = 12u;
894 uint32_t r_p_x, r_p_y, r_p_d;
895
896 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
897
898 CY_CRYPTO_VU_PUSH_REG (base);
899
900 CY_CRYPTO_VU_SAVE_REG(base, p_x, &r_p_x);
901 CY_CRYPTO_VU_SAVE_REG(base, p_y, &r_p_y);
902 CY_CRYPTO_VU_SAVE_REG(base, p_d, &r_p_d);
903
904 CY_CRYPTO_VU_RESTORE_REG(base, my_s_x, r_p_x);
905 CY_CRYPTO_VU_RESTORE_REG(base, my_s_y, r_p_y);
906 CY_CRYPTO_VU_RESTORE_REG(base, my_d, r_p_d);
907
908 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, clr, bitsize+1u);
909 if(CY_CRYPTO_SUCCESS != tmpResult)
910 {
911 return tmpResult;
912 }
913
914 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t, bitsize);
915 if(CY_CRYPTO_SUCCESS != tmpResult)
916 {
917 return tmpResult;
918 }
919
920 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_s_z, bitsize);
921 if(CY_CRYPTO_SUCCESS != tmpResult)
922 {
923 return tmpResult;
924 }
925
926 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_t_x, bitsize);
927 if(CY_CRYPTO_SUCCESS != tmpResult)
928 {
929 return tmpResult;
930 }
931
932 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_t_y, bitsize);
933 if(CY_CRYPTO_SUCCESS != tmpResult)
934 {
935 return tmpResult;
936 }
937 /* load prime defining the curve as well as the barrett coefficient. */
938 /* VR_P and VR_BARRETT_U are "globally" defined in cy_crypto_core_ecc.h */
939 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_P, bitsize);
940 if(CY_CRYPTO_SUCCESS != tmpResult)
941 {
942 return tmpResult;
943 }
944 Cy_Crypto_Core_Vu_SetMemValue (base, VR_P, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->prime), bitsize);
945
946 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_BARRETT, edwDp->barret_psize);
947 if(CY_CRYPTO_SUCCESS != tmpResult)
948 {
949 return tmpResult;
950 }
951 Cy_Crypto_Core_Vu_SetMemValue (base, VR_BARRETT, (uint8_t const*)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->barrett_p), edwDp->barret_psize);
952
953
954 CY_CRYPTO_VU_MOV (base, my_t_x, my_s_x);
955 CY_CRYPTO_VU_MOV (base, my_t_y, my_s_y);
956
957 /* init point->z to 1. */
958 CY_CRYPTO_VU_SET_TO_ONE (base, my_s_z);
959
960 /* EC scalar multiplication (irregular) operation. */
961 CY_CRYPTO_VU_SET_TO_ZERO (base, clr);
962 CY_CRYPTO_VU_CLSAME (base, t, my_d, clr);
963
964 /* This is needed, otherwise clsame is wrong */
965 Cy_Crypto_Core_Vu_WaitForComplete(base);
966
967 clsame = Cy_Crypto_Core_Vu_RegDataPtrRead (base, t);
968
969 CY_CRYPTO_VU_LSL (base, my_d, my_d, t); /* Get rid of leading '0's */
970 CY_CRYPTO_VU_LSL1 (base, my_d, my_d); /* Get rid of leading '1' */
971
972 /* Binary left-to-right algorithm
973 * Perform point addition and point doubling to implement scalar multiplication
974 * Scan the bits of the scalar from left to right; perform point doubling for each bit,
975 * and perform point addition when the bit is set.
976 * Carry set if current bit is equal to 1 (hence, perform point addition - point
977 * doubling is always performed)
978 */
979 if( bitsize >= clsame)
980 {
981 loop = (uint32_t)(bitsize - clsame);
982 }
983 else
984 {
985 return CY_CRYPTO_HW_ERROR;
986 }
987
988 for (i = 0; i < (loop); i++)
989 {
990 /* Carry set if current bit is equal to 1 (hence, perform point addition - point
991 * doubling is always performed)
992 */
993 CY_CRYPTO_VU_LSL1 (base, my_d, my_d);
994 status = Cy_Crypto_Core_Vu_StatusRead(base);
995
996 carry = status & CY_CRYPTO_VU_STATUS_CARRY_BIT;
997
998 tmpResult = Cy_Crypto_Core_ED25519Double (base, edwDp, my_s_x, my_s_y, my_s_z, bitsize);
999
1000 if(CY_CRYPTO_SUCCESS != tmpResult)
1001 {
1002 return tmpResult;
1003 }
1004
1005 if (carry != 0u)
1006 {
1007 tmpResult = Cy_Crypto_Core_ED25519Add (base, edwDp, my_s_x, my_s_y, my_s_z, my_t_x, my_t_y, bitsize);
1008
1009 if(CY_CRYPTO_SUCCESS != tmpResult)
1010 {
1011 return tmpResult;
1012 }
1013 }
1014 }
1015
1016 /* Inverse transform */
1017 tmpResult = Cy_Crypto_Core_ED25519InvTransform(base, my_s_x, my_s_y, my_s_z, bitsize);
1018 if(CY_CRYPTO_SUCCESS != tmpResult)
1019 {
1020 return tmpResult;
1021 }
1022
1023 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(my_s_z) | CY_CRYPTO_VU_REG_BIT(my_t_x) |
1024 CY_CRYPTO_VU_REG_BIT(my_t_y) | CY_CRYPTO_VU_REG_BIT(t) |
1025 CY_CRYPTO_VU_REG_BIT(VR_P) | CY_CRYPTO_VU_REG_BIT(VR_BARRETT) |
1026 CY_CRYPTO_VU_REG_BIT(clr) );
1027
1028 Cy_Crypto_Core_Vu_WaitForComplete(base);
1029 CY_CRYPTO_VU_POP_REG (base);
1030
1031 return tmpResult;
1032 }
1033
1034 /*******************************************************************************
1035 * Function Name: Cy_Crypto_Core_ED25519_PointMultiplication
1036 ****************************************************************************//**
1037 *
1038 * Edwards 25519 elliptic curve point multiplication in GF(p).
1039 *
1040 * For CAT1C & CAT1D devices with DCache enabled this API is not supported.
1041 *
1042 * \param base
1043 * The pointer to a Crypto instance.
1044 *
1045 * \param curveID
1046 * See \ref cy_en_crypto_ecc_curve_id_t.
1047 *
1048 * \param ecpGX
1049 * X coordinate of base point.
1050 *
1051 * \param ecpGY
1052 * Y coordinate of base point.
1053 *
1054 * \param ecpD
1055 * multiplication scalar value.
1056 *
1057 * \param ecpQX
1058 * X coordinate of result point.
1059 *
1060 * \param ecpQY
1061 * Y coordinate of result point.
1062 *
1063 * \return status code. See \ref cy_en_crypto_status_t.
1064 *
1065 *******************************************************************************/
Cy_Crypto_Core_ED25519_PointMultiplication(CRYPTO_Type * base,cy_en_crypto_ecc_curve_id_t curveID,const uint8_t * ecpGX,const uint8_t * ecpGY,const uint8_t * ecpD,uint8_t * ecpQX,uint8_t * ecpQY)1066 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_PointMultiplication(CRYPTO_Type *base,
1067 cy_en_crypto_ecc_curve_id_t curveID,
1068 const uint8_t *ecpGX,
1069 const uint8_t *ecpGY,
1070 const uint8_t *ecpD,
1071 uint8_t *ecpQX,
1072 uint8_t *ecpQY)
1073 {
1074 cy_stc_crypto_edw_dp_type edw_Dp;
1075 cy_stc_crypto_edw_dp_type *edwDp = &edw_Dp;
1076
1077 cy_en_crypto_status_t tmpResult = CY_CRYPTO_NOT_SUPPORTED;
1078
1079 if(CY_CRYPTO_SUCCESS == Cy_Crypto_Core_EDW_GetCurveParams(edwDp, curveID))
1080 {
1081 uint32_t bitsize;
1082
1083 bitsize = edwDp->size;
1084 tmpResult = CY_CRYPTO_BAD_PARAMS;
1085
1086 if ((NULL != ecpGX) && (NULL != ecpGY) && (NULL != ecpD) && (NULL != ecpQX) && (NULL != ecpQY))
1087 {
1088 uint8_t *ecpGXRemap;
1089 uint8_t *ecpGYRemap;
1090 uint8_t *ecpDRemap;
1091 uint8_t *ecpQXRemap;
1092 uint8_t *ecpQYRemap;
1093
1094 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1095 /* Flush the cache */
1096 SCB_CleanDCache_by_Addr((volatile void *)ecpGX, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1097 SCB_CleanDCache_by_Addr((volatile void *)ecpGY, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1098 SCB_CleanDCache_by_Addr((volatile void *)ecpD, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1099 #endif
1100 ecpGXRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(ecpGX);
1101 ecpGYRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(ecpGY);
1102 ecpDRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(ecpD);
1103 ecpQXRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(ecpQX);
1104 ecpQYRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(ecpQY);
1105
1106 /* Public parameters and characteristics of elliptic curve */
1107 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_D, bitsize+1u); /* Scalar factor */
1108 if(CY_CRYPTO_SUCCESS != tmpResult)
1109 {
1110 return tmpResult;
1111 }
1112
1113 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_X, bitsize);
1114 if(CY_CRYPTO_SUCCESS != tmpResult)
1115 {
1116 return tmpResult;
1117 }
1118
1119 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_Y, bitsize);
1120 if(CY_CRYPTO_SUCCESS != tmpResult)
1121 {
1122 return tmpResult;
1123 }
1124
1125 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_X, ecpGXRemap, bitsize);
1126 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_Y, ecpGYRemap, bitsize);
1127 Cy_Crypto_Core_Vu_SetMemValue (base, VR_D, ecpDRemap, bitsize+1u);
1128
1129 /* ECC calculation: d * G mod p */
1130 tmpResult = Cy_Crypto_Core_ED25519_PointMul(base, edwDp, VR_S_X, VR_S_Y, VR_D, bitsize);
1131
1132 if(CY_CRYPTO_SUCCESS != tmpResult)
1133 {
1134 return tmpResult;
1135 }
1136
1137 /* Get result P = (X,Y) = d.G from Ed25519 scalar multiplication */
1138 Cy_Crypto_Core_Vu_GetMemValue (base, ecpQXRemap, VR_S_X, bitsize);
1139 Cy_Crypto_Core_Vu_GetMemValue (base, ecpQYRemap, VR_S_Y, bitsize);
1140 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1141 SCB_InvalidateDCache_by_Addr(ecpQX, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1142 SCB_InvalidateDCache_by_Addr(ecpQY, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1143 #endif
1144 /* Free memory */
1145 CY_CRYPTO_VU_FREE_MEM (base,
1146 CY_CRYPTO_VU_REG_BIT(VR_S_Y) |
1147 CY_CRYPTO_VU_REG_BIT(VR_S_X) |
1148 CY_CRYPTO_VU_REG_BIT(VR_D));
1149
1150 tmpResult = CY_CRYPTO_SUCCESS;
1151 }
1152 }
1153
1154 return tmpResult;
1155 }
1156
1157 #if defined (CY_CRYPTO_CFG_EDDSA_GENKEY_C)
1158 /*******************************************************************************
1159 * Function Name: Cy_Crypto_Core_ED25519_MakePublicKey
1160 ****************************************************************************//**
1161 *
1162 * Make a new ED25519 public key
1163 *
1164 * For CAT1C & CAT1D devices with DCache enabled this API is not supported.
1165 *
1166 * \param base
1167 * The pointer to a Crypto instance.
1168 *
1169 * \param curveID
1170 * See \ref cy_en_crypto_ecc_curve_id_t.
1171 *
1172 * \param privateKey
1173 * [in] Private key.
1174 *
1175 * \param publicKey
1176 * [out] Newly created Public key.
1177 * See \ref cy_stc_crypto_ecc_key.
1178 *
1179 * \return status code. See \ref cy_en_crypto_status_t.
1180 *
1181 *******************************************************************************/
Cy_Crypto_Core_ED25519_MakePublicKey(CRYPTO_Type * base,cy_en_crypto_ecc_curve_id_t curveID,const uint8_t * privateKey,cy_stc_crypto_ecc_key * publicKey)1182 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_MakePublicKey(CRYPTO_Type *base,
1183 cy_en_crypto_ecc_curve_id_t curveID,
1184 const uint8_t *privateKey,
1185 cy_stc_crypto_ecc_key *publicKey)
1186 {
1187 cy_en_crypto_status_t tmpResult = CY_CRYPTO_NOT_SUPPORTED;
1188
1189 cy_stc_crypto_edw_dp_type edw_Dp;
1190 cy_stc_crypto_edw_dp_type *edwDp = &edw_Dp;
1191 uint8_t *privateKeyRemap;
1192 uint8_t *publicKeyXRemap;
1193 uint8_t *publicKeyYRemap;
1194 uint8_t *digest;
1195
1196 if(CY_CRYPTO_SUCCESS == Cy_Crypto_Core_EDW_GetCurveParams(edwDp, curveID))
1197 {
1198 if ((privateKey != NULL) && (publicKey != NULL) &&
1199 (publicKey->pubkey.x != NULL) && (publicKey->pubkey.y != NULL))
1200 {
1201 #if (CY_IP_MXCRYPTO_VERSION == 1u)
1202 static cy_stc_crypto_v1_sha512_buffers_t shaBuffers;
1203 #else
1204 static cy_stc_crypto_v2_sha512_buffers_t shaBuffers;
1205 #endif
1206 static cy_stc_crypto_sha_state_t shaHashState;
1207 uint32_t bitsize = edwDp->size;
1208 uint32_t bytesize = CY_CRYPTO_BYTE_SIZE_OF_BITS(edwDp->size);
1209
1210 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1211 /* Flush the cache */
1212 SCB_CleanDCache_by_Addr((volatile void *)privateKey,(int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1213 #endif
1214 privateKeyRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(privateKey);
1215 publicKeyXRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(publicKey->pubkey.x);
1216 publicKeyYRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(publicKey->pubkey.y);
1217
1218 uint32_t p_d = 10u; /* private key */
1219 uint32_t p_x = 11u; /* x coordinate */
1220 uint32_t p_y = 12u; /* y coordinate */
1221 uint32_t p_sha = 4u; /* digest */
1222
1223 tmpResult = Cy_Crypto_Core_Sha_Init(base, &shaHashState, (cy_en_crypto_sha_mode_t)CY_CRYPTO_MODE_SHA512, (void *)&shaBuffers);
1224 if (CY_CRYPTO_SUCCESS == tmpResult)
1225 {
1226 tmpResult = Cy_Crypto_Core_Sha_Start(base, &shaHashState);
1227 if(CY_CRYPTO_SUCCESS != tmpResult)
1228 {
1229 return tmpResult;
1230 }
1231 }
1232 else
1233 {
1234 return tmpResult;
1235 }
1236
1237 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_x, bitsize);
1238 if(CY_CRYPTO_SUCCESS != tmpResult)
1239 {
1240 return tmpResult;
1241 }
1242
1243 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_y, bitsize);
1244 if(CY_CRYPTO_SUCCESS != tmpResult)
1245 {
1246 return tmpResult;
1247 }
1248
1249 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_sha, (CY_CRYPTO_SHA512_HASH_SIZE*8u));
1250 if(CY_CRYPTO_SUCCESS != tmpResult)
1251 {
1252 return tmpResult;
1253 }
1254 digest = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_sha);
1255 /*Base Point, G = (p_x, p_y) */
1256 Cy_Crypto_Core_Vu_SetMemValue (base, p_x, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gx), bitsize);
1257 Cy_Crypto_Core_Vu_SetMemValue (base, p_y, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gy), bitsize);
1258
1259 /* Load private key */
1260 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_d, bitsize+1u);
1261 if(CY_CRYPTO_SUCCESS != tmpResult)
1262 {
1263 return tmpResult;
1264 }
1265
1266 /*step1: Compute secret scalar 's' and prefix*/
1267 /*SHA expects big-endian input*/
1268 tmpResult = Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)privateKeyRemap, bytesize);
1269 if(CY_CRYPTO_SUCCESS == tmpResult)
1270 {
1271 tmpResult = Cy_Crypto_Core_Sha_Finish(base, &shaHashState, digest);
1272 }
1273 if(CY_CRYPTO_SUCCESS != tmpResult)
1274 {
1275 return tmpResult;
1276 }
1277
1278 /*Prune the buffer: The lowest three bits of the first octet are cleared, the highest bit of the last octet is cleared,
1279 and the second highest bit of the last octet is set.*/
1280 digest[0] &= ~((uint8_t)0x7);
1281 digest[31] &= ~((uint8_t)0x80);
1282 digest[31] |= (uint8_t)0x40;
1283
1284 /*s = digest[0-31] prefix = digest[32-63]*/
1285 Cy_Crypto_Core_Vu_SetMemValue(base, p_d, (uint8_t *)&digest[0], bitsize+1u);
1286 /* make the public key
1287 * ED25519 scalar point multiplication - X,Y-only co-Z arithmetic
1288 */
1289 tmpResult = Cy_Crypto_Core_ED25519_PointMul(base, edwDp, p_x, p_y, p_d, bitsize);
1290 if(CY_CRYPTO_SUCCESS != tmpResult)
1291 {
1292 return tmpResult;
1293 }
1294
1295 Cy_Crypto_Core_Vu_GetMemValue(base, (uint8_t *)publicKeyXRemap, p_x, bitsize);
1296 Cy_Crypto_Core_Vu_GetMemValue(base, (uint8_t *)publicKeyYRemap, p_y, bitsize);
1297 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1298 SCB_InvalidateDCache_by_Addr(publicKey->pubkey.x, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1299 SCB_InvalidateDCache_by_Addr(publicKey->pubkey.y, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1300 #endif
1301 publicKey->type = PK_PUBLIC;
1302 publicKey->curveID = curveID;
1303
1304 CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(p_x) | CY_CRYPTO_VU_REG_BIT(p_y) |
1305 CY_CRYPTO_VU_REG_BIT(p_sha) | CY_CRYPTO_VU_REG_BIT(p_d));
1306 /* free sha context*/
1307 (void)Cy_Crypto_Core_Sha_Free(base, &shaHashState);
1308 tmpResult = CY_CRYPTO_SUCCESS;
1309 Cy_Crypto_Core_Vu_WaitForComplete(base);
1310 }
1311 }
1312
1313 return (tmpResult);
1314 }
1315 #endif /* defined (CY_CRYPTO_CFG_EDDSA_GENKEY_C)*/
1316
1317 #if defined(CY_CRYPTO_CFG_EDDSA_SIGN_C)
1318 /*******************************************************************************
1319 * Function Name: Cy_Crypto_Core_ED25519_Sign
1320 ****************************************************************************//**
1321 *
1322 * Sign a message.
1323 *
1324 * For CAT1C & CAT1D devices with DCache enabled this API is not supported.
1325 *
1326 * \param base
1327 * The pointer to a Crypto instance.
1328 *
1329 * \param hash
1330 * The message to sign. Provided as is in data buffer. This is usually the hash of
1331 * the original data to be signed.
1332 *
1333 * \param hashlen
1334 * The length of the message in bytes.
1335 *
1336 * \param sig
1337 * [out] The destination for the signature, 'r' followed by 's'.
1338 *
1339 * \param key
1340 * Key used for signature generation. See \ref cy_stc_crypto_ecc_key.
1341 *
1342 * \param sigType
1343 * signature Type. CY_CRYPTO_EDDSA_PURE,CY_CRYPTO_EDDSA_CTX or CY_CRYPTO_EDDSA_PREHASH
1344 *
1345 * \param sigctx
1346 * signature context. can be NULL if EDDSA_PURE is used or if no context is provided.
1347 *
1348 * \param sigctx_len
1349 * The length of the signature context
1350 *
1351 * \return status code. See \ref cy_en_crypto_status_t.
1352 *
1353 *******************************************************************************/
Cy_Crypto_Core_ED25519_Sign(CRYPTO_Type * base,const uint8_t * hash,uint32_t hashlen,uint8_t * sig,const cy_stc_crypto_ecc_key * key,cy_en_eddsa_sig_type_t sigType,const uint8_t * sigctx,uint32_t sigctx_len)1354 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_Sign(CRYPTO_Type *base, const uint8_t *hash, uint32_t hashlen, uint8_t *sig,
1355 const cy_stc_crypto_ecc_key *key, cy_en_eddsa_sig_type_t sigType,const uint8_t *sigctx, uint32_t sigctx_len)
1356 {
1357 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1358
1359 uint8_t *sigPtrRemap;
1360 uint8_t *hashPtrRemap;
1361 uint8_t *keyKRemap;
1362 uint32_t mallocMask = 0u;
1363
1364 cy_stc_crypto_edw_dp_type edwDp_t;
1365 cy_stc_crypto_edw_dp_type *edwDp = &edwDp_t;
1366
1367 /* input param validation */
1368 if ( hash == NULL && 0u != hashlen )
1369 {
1370 return CY_CRYPTO_BAD_PARAMS;
1371 }
1372 /*
1373 Value of context is set by the signer and verifier (maximum of 255
1374 octets; the default is empty string, except for Ed25519, which can't
1375 have context) and has to match octet by octet for verification to be
1376 successful.
1377 */
1378 if(sigType != CY_CRYPTO_EDDSA_PURE)
1379 {
1380 if(sigType == CY_CRYPTO_EDDSA_CTX)
1381 {
1382 if( sigctx == NULL || sigctx_len == 0u || sigctx_len > 255u)
1383 {
1384 return CY_CRYPTO_BAD_PARAMS;
1385 }
1386 }
1387 else
1388 {
1389 if (sigType == CY_CRYPTO_EDDSA_PREHASH && hashlen != CY_CRYPTO_SHA512_HASH_SIZE)
1390 {
1391 return CY_CRYPTO_BAD_PARAMS;
1392 }
1393 }
1394 }
1395
1396 if ((sig != NULL) && (key != NULL) && (sigType < CY_CRYPTO_EDDSA_NONE))
1397 {
1398 tmpResult = CY_CRYPTO_NOT_SUPPORTED;
1399
1400 hashPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(hash);
1401 sigPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(sig);
1402 keyKRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->k);
1403
1404 if(CY_CRYPTO_SUCCESS == Cy_Crypto_Core_EDW_GetCurveParams(edwDp, key->curveID))
1405 {
1406 #if (CY_IP_MXCRYPTO_VERSION == 1u)
1407 static cy_stc_crypto_v1_sha512_buffers_t shaBuffers;
1408 #else
1409 static cy_stc_crypto_v2_sha512_buffers_t shaBuffers;
1410 #endif
1411 static cy_stc_crypto_sha_state_t shaHashState;
1412 uint32_t bitsize = edwDp->size;
1413 uint32_t bytesize = CY_CRYPTO_BYTE_SIZE_OF_BITS(edwDp->size);
1414
1415 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1416 /* Flush the cache */
1417 SCB_CleanDCache_by_Addr((volatile void *)hash,(int32_t)hashlen);
1418 SCB_CleanDCache_by_Addr((volatile void *)key->k, (int32_t)bytesize);
1419 /* sigctx is managed by the SHA functions */
1420 #endif
1421
1422 tmpResult = Cy_Crypto_Core_Sha_Init(base, &shaHashState, (cy_en_crypto_sha_mode_t)CY_CRYPTO_MODE_SHA512, (void *)&shaBuffers);
1423 if (CY_CRYPTO_SUCCESS == tmpResult)
1424 {
1425 tmpResult = Cy_Crypto_Core_Sha_Start(base, &shaHashState);
1426 }
1427
1428 if (CY_CRYPTO_SUCCESS == tmpResult)
1429 {
1430 uint32_t p_sha = 4u;
1431 uint32_t p_temp = 5u;
1432 uint32_t p_r = 6u;
1433 uint32_t p_s = 7u;
1434 uint32_t p_x = 8u;
1435 uint32_t p_y = 9u;
1436
1437 uint8_t *digest;
1438 uint8_t *scalar;
1439 uint8_t *prefix;
1440 uint8_t *pubkey_x;
1441 uint8_t *pubkey_y;
1442 uint8_t *r_x;
1443 uint8_t *r_y;
1444 uint32_t pr[8u];
1445
1446 /*Curve Order*/
1447 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_P, bitsize);
1448 if(CY_CRYPTO_SUCCESS != tmpResult)
1449 {
1450 return tmpResult;
1451 }
1452 Cy_Crypto_Core_Vu_SetMemValue (base, VR_P, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->order), bitsize);
1453 /* Barret coef for Order*/
1454 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_BARRETT, edwDp->barret_osize);
1455 if(CY_CRYPTO_SUCCESS != tmpResult)
1456 {
1457 return tmpResult;
1458 }
1459 Cy_Crypto_Core_Vu_SetMemValue (base, VR_BARRETT, (uint8_t const*)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->barrett_o), edwDp->barret_osize);
1460 /* Gx co-ordinate */
1461 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_X, bitsize);
1462 if(CY_CRYPTO_SUCCESS != tmpResult)
1463 {
1464 return tmpResult;
1465 }
1466 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_X, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gx), bitsize);
1467 /* Gy co-ordinate */
1468 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_Y, bitsize+1u);
1469 if(CY_CRYPTO_SUCCESS != tmpResult)
1470 {
1471 return tmpResult;
1472 }
1473 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_Y, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gy), bitsize+1u);
1474
1475 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_r, bitsize+1u);
1476 if(CY_CRYPTO_SUCCESS != tmpResult)
1477 {
1478 return tmpResult;
1479 }
1480 Cy_Crypto_Core_MemSet(base, (void*)Cy_Crypto_Core_Vu_RegMemPointer(base, p_r), (uint8_t)0, (uint16_t)bytesize);
1481
1482 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_s, bitsize+1u);
1483 if(CY_CRYPTO_SUCCESS != tmpResult)
1484 {
1485 return tmpResult;
1486 }
1487
1488 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_sha, (CY_CRYPTO_SHA512_HASH_SIZE*8u));
1489 if(CY_CRYPTO_SUCCESS != tmpResult)
1490 {
1491 return tmpResult;
1492 }
1493 digest = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_sha);
1494
1495 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_temp, bitsize);
1496 if(CY_CRYPTO_SUCCESS != tmpResult)
1497 {
1498 return tmpResult;
1499 }
1500
1501 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_x, bitsize);
1502 if(CY_CRYPTO_SUCCESS != tmpResult)
1503 {
1504 return tmpResult;
1505 }
1506 Cy_Crypto_Core_Vu_SetMemValue (base, p_x, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gx), bitsize);
1507
1508 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_y, bitsize+1u);
1509 if(CY_CRYPTO_SUCCESS != tmpResult)
1510 {
1511 return tmpResult;
1512 }
1513 Cy_Crypto_Core_Vu_SetMemValue (base, p_y, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gy), bitsize+1u);
1514
1515 mallocMask = CY_CRYPTO_VU_REG_BIT(VR_P) | CY_CRYPTO_VU_REG_BIT(VR_BARRETT) |
1516 CY_CRYPTO_VU_REG_BIT(VR_S_X) | CY_CRYPTO_VU_REG_BIT(VR_S_Y) |
1517 CY_CRYPTO_VU_REG_BIT(p_r) | CY_CRYPTO_VU_REG_BIT(p_s) |
1518 CY_CRYPTO_VU_REG_BIT(p_x) | CY_CRYPTO_VU_REG_BIT(p_y) |
1519 CY_CRYPTO_VU_REG_BIT(p_sha) | CY_CRYPTO_VU_REG_BIT(p_temp);
1520
1521 /*step1: Compute secret scalar 's' and prefix*/
1522 /*SHA expects big-endian*/
1523 tmpResult = Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)keyKRemap, bytesize);
1524 if(CY_CRYPTO_SUCCESS == tmpResult)
1525 {
1526 tmpResult = Cy_Crypto_Core_Sha_Finish(base, &shaHashState, digest);
1527 }
1528 if(CY_CRYPTO_SUCCESS != tmpResult)
1529 {
1530 return tmpResult;
1531 }
1532 /*Prune the buffer: The lowest three bits of the first octet are cleared, the highest bit of the last octet is cleared,
1533 and the second highest bit of the last octet is set.*/
1534 digest[0] &= ~((uint8_t)0x7);
1535 digest[31] &= ~((uint8_t)0x80);
1536 digest[31] |= (uint8_t)0x40;
1537
1538 /*s = digest[0-31] prefix = digest[32-63]*/
1539 scalar = &digest[0];
1540 prefix = &digest[32];
1541 /* Note: Point mul does in-place use for p_s which clears it, REG use needs to be re-looked to optimize*/
1542 Cy_Crypto_Core_Vu_SetMemValue (base, p_s, (uint8_t const*)scalar, ((CY_CRYPTO_SHA512_HASH_SIZE*8u) >> 1u));
1543 /* generate pubKey A = [s]B */
1544 tmpResult = Cy_Crypto_Core_ED25519_PointMul(base, edwDp, VR_S_X, VR_S_Y, p_s, bitsize);
1545 if(CY_CRYPTO_SUCCESS != tmpResult)
1546 {
1547 return tmpResult;
1548 }
1549 Cy_Crypto_Core_Vu_SetMemValue (base, p_s, (uint8_t const*)scalar, ((CY_CRYPTO_SHA512_HASH_SIZE*8u) >> 1u));
1550
1551 pubkey_x = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, VR_S_X);
1552 pubkey_y = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, VR_S_Y);
1553
1554 /* step2: 'r' computation */
1555 (void)Cy_Crypto_Core_Sha_Start(base, &shaHashState);
1556 /* EDDSA sig mode as per 5.1 RFC 8032 */
1557 if(sigType != CY_CRYPTO_EDDSA_PURE)
1558 {
1559 Cy_Crypto_Core_ED25519_dom2_ctx( base, sigType, sigctx, sigctx_len, &shaHashState);
1560 }
1561
1562 /*update prefix and input hash */
1563 (void)Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)prefix, (CY_CRYPTO_SHA512_HASH_SIZE >> 1u));
1564 (void)Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)hashPtrRemap, hashlen);
1565 (void)Cy_Crypto_Core_Sha_Finish(base, &shaHashState, digest);
1566
1567 /* Mod reduction modulo n (order of the base point in VR_P and barret_o in VR_BARRET) */
1568 if ( CY_CRYPTO_SUCCESS != Cy_Crypto_Core_EDDSA_Bar_MulRed(base, p_r, p_sha, bitsize) )
1569 {
1570 return CY_CRYPTO_BAD_PARAMS;
1571 }
1572 /* Note: Point mul does in-place use for p_r which clears it, REG use needs to be re-looked to optimize*/
1573 Cy_Crypto_Core_Vu_GetMemValue (base, (uint8_t*)pr, p_r, bitsize);
1574 /* Step 3 */
1575 tmpResult = Cy_Crypto_Core_ED25519_PointMul(base, edwDp, p_x, p_y, p_r, bitsize);
1576 if(CY_CRYPTO_SUCCESS != tmpResult)
1577 {
1578 return tmpResult;
1579 }
1580 Cy_Crypto_Core_Vu_SetMemValue (base, p_r, (uint8_t const*)pr, ((CY_CRYPTO_SHA512_HASH_SIZE*8u) >> 1u));
1581
1582 /*Note: key encode/decode can be a separate function helps verify */
1583 /* encode point: From RFC 5.1.2, we shall copy LSB of x to the MSB of y */
1584 /* Test p_x for odd */
1585 r_x = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_x);
1586 r_y = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_y);
1587 if((bool)(((uint8_t*)r_x)[0] & (uint8_t)0x01))
1588 {
1589 ((uint8_t*)r_y)[31] = ((uint8_t*)r_y)[31] | (uint8_t)0x80;
1590 }
1591
1592 /* Copy r to sig result */
1593 Cy_Crypto_Core_Vu_GetMemValue (base, &sigPtrRemap[0], p_y, bitsize);
1594
1595 /* Step4: 's' computation */
1596 (void)Cy_Crypto_Core_Sha_Start(base, &shaHashState);
1597 /* EDDSA sig mode as per 5.1 RFC 8032 */
1598 if(sigType != CY_CRYPTO_EDDSA_PURE)
1599 {
1600 Cy_Crypto_Core_ED25519_dom2_ctx( base, sigType, sigctx, sigctx_len, &shaHashState);
1601 }
1602
1603 (void)Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)r_y, bytesize);
1604 /*Note: key encode/decode can be a separate function */
1605 /* encode point: From RFC 5.1.2, we shall copy LSB of x to the MSB of y */
1606 if((bool)(((uint8_t*)pubkey_x)[0] & (uint8_t)0x01))
1607 {
1608 ((uint8_t*)pubkey_y)[31] = ((uint8_t*)pubkey_y)[31] | (uint8_t)0x80;
1609 }
1610
1611 (void)Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)pubkey_y, bytesize);
1612 (void)Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)hashPtrRemap, hashlen);
1613 (void)Cy_Crypto_Core_Sha_Finish(base, &shaHashState, digest);
1614
1615 /* step5 */
1616 /* Mod reduction modulo n (order of the base point in VR_P and barret_o in VR_BARRET) */
1617 if ( CY_CRYPTO_SUCCESS != Cy_Crypto_Core_EDDSA_Bar_MulRed(base, p_temp, p_sha, bitsize) )
1618 {
1619 return CY_CRYPTO_BAD_PARAMS;
1620 }
1621
1622 CY_CRYPTO_VU_UMUL(base, p_sha, p_temp, p_s);
1623 CY_CRYPTO_VU_ADD(base, p_sha, p_sha, p_r);
1624
1625 /* Mod reduction modulo n (order of the base point in VR_P and barret_o in VR_BARRET) */
1626 if ( CY_CRYPTO_SUCCESS != Cy_Crypto_Core_EDDSA_Bar_MulRed(base, p_s, p_sha, bitsize))
1627 {
1628 return CY_CRYPTO_HW_ERROR;
1629 }
1630
1631 /* copy s to sig buffer*/
1632 if (!Cy_Crypto_Core_Vu_IsRegZero(base, p_s))
1633 {
1634 /* S is not zero!!! */
1635 Cy_Crypto_Core_Vu_GetMemValue (base, &sigPtrRemap[bytesize], p_s, bitsize);
1636 }
1637 else
1638 {
1639 tmpResult = CY_CRYPTO_HW_ERROR;
1640 }
1641
1642 /* Free all mem allocations */
1643 CY_CRYPTO_VU_FREE_MEM(base, mallocMask);
1644 (void)Cy_Crypto_Core_Sha_Free(base, &shaHashState);
1645 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1646 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t.');
1647 SCB_InvalidateDCache_by_Addr(sig, (int32_t)(bytesize*2U));
1648 #endif
1649 }
1650 }
1651 }
1652
1653 return (tmpResult);
1654 }
1655 #endif /* defined(CY_CRYPTO_CFG_EDDSA_SIGN_C) */
1656
1657 /*******************************************************************************
1658 * Function Name: Cy_Crypto_Core_ED25519_ExpMod
1659 ****************************************************************************//**
1660 *
1661 * Modular exponentiation x = y^e mod p.
1662 *
1663 * \param base
1664 * The pointer to a Crypto instance.
1665 *
1666 * \param p_x
1667 * Register index for result X .
1668 *
1669 * \param p_y
1670 * Register index for input integer Y.
1671 *
1672 * \param p_e
1673 * Register index for exponent.
1674 *
1675 * \param bitsize
1676 * Bit size of the input Y.
1677 *
1678 * \return status code. See \ref cy_en_crypto_status_t.
1679 *******************************************************************************/
Cy_Crypto_Core_ED25519_ExpMod(CRYPTO_Type * base,uint32_t p_x,uint32_t p_y,uint32_t p_e,uint32_t bitsize)1680 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_ExpMod(CRYPTO_Type *base, uint32_t p_x,
1681 uint32_t p_y, uint32_t p_e,
1682 uint32_t bitsize)
1683 {
1684 uint32_t i;
1685 uint32_t status;
1686 uint32_t carry;
1687 uint16_t clsame;
1688 uint32_t loop;
1689
1690 uint32_t clr = 5u;
1691 uint32_t t = 6u;
1692 uint32_t my_s_x = 7u;
1693 uint32_t my_s_y = 8u;
1694 uint32_t my_e = 9u;
1695 uint32_t r_p_x, r_p_y, r_p_e;
1696
1697 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1698
1699 CY_CRYPTO_VU_PUSH_REG (base);
1700
1701 CY_CRYPTO_VU_SAVE_REG(base, p_x, &r_p_x);
1702 CY_CRYPTO_VU_SAVE_REG(base, p_y, &r_p_y);
1703 CY_CRYPTO_VU_SAVE_REG(base, p_e, &r_p_e);
1704
1705 CY_CRYPTO_VU_RESTORE_REG(base, my_s_x, r_p_x);
1706 CY_CRYPTO_VU_RESTORE_REG(base, my_s_y, r_p_y);
1707 CY_CRYPTO_VU_RESTORE_REG(base, my_e, r_p_e);
1708
1709 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, clr, bitsize);
1710 if(CY_CRYPTO_SUCCESS != tmpResult)
1711 {
1712 return tmpResult;
1713 }
1714
1715 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t, bitsize);
1716 if(CY_CRYPTO_SUCCESS != tmpResult)
1717 {
1718 return tmpResult;
1719 }
1720
1721 /* normalize exp */
1722 CY_CRYPTO_VU_MOV (base, my_s_x, my_s_y);
1723 CY_CRYPTO_VU_SET_TO_ZERO (base, clr);
1724 CY_CRYPTO_VU_CLSAME (base, t, my_e, clr);
1725 /* This is needed, otherwise clsame is wrong */
1726 Cy_Crypto_Core_Vu_WaitForComplete(base);
1727 clsame = Cy_Crypto_Core_Vu_RegDataPtrRead (base, t);
1728
1729 CY_CRYPTO_VU_LSL (base, my_e, my_e, t); /* Get rid of leading '0's */
1730 CY_CRYPTO_VU_LSL1 (base, my_e, my_e); /* Get rid of leading '1' */
1731
1732 /* Binary left-to-right algorithm
1733 * Perform mul and squaring to implement exponential mod multiplication
1734 * Scan the bits of the exponent from left to right; perform squaring for each bit,
1735 * and perform mul when the bit is set. Carry set if current bit is equal to 1
1736 * (hence perform mul, squaring is always performed)
1737 */
1738 if( bitsize >= clsame)
1739 {
1740 loop = (uint32_t)(bitsize - clsame - 1u);
1741 }
1742 else
1743 {
1744 return CY_CRYPTO_HW_ERROR;
1745 }
1746
1747 for (i = 0; i < (loop); i++)
1748 {
1749 /* Carry set if current bit is equal to 1 (hence, perform multiply,
1750 * squaring is always performed)
1751 */
1752 CY_CRYPTO_VU_LSL1 (base, my_e, my_e);
1753 status = Cy_Crypto_Core_Vu_StatusRead(base);
1754
1755 carry = status & CY_CRYPTO_VU_STATUS_CARRY_BIT;
1756
1757 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, my_s_x, my_s_x, bitsize);
1758
1759 if(CY_CRYPTO_SUCCESS != tmpResult)
1760 {
1761 return tmpResult;
1762 }
1763
1764 if (carry != 0u)
1765 {
1766 (void)Cy_Crypto_Core_ED25519_MulMod (base, my_s_x, my_s_x, my_s_y, bitsize);
1767 }
1768 }
1769 /* free memory */
1770 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t) | CY_CRYPTO_VU_REG_BIT(clr));
1771
1772 Cy_Crypto_Core_Vu_WaitForComplete(base);
1773 CY_CRYPTO_VU_POP_REG (base);
1774
1775 return tmpResult;
1776 }
1777
1778 #if defined(CY_CRYPTO_CFG_EDDSA_VERIFY_C)
1779 /** \cond INTERNAL */
1780 /*******************************************************************************
1781 * Function Name: Cy_Crypto_Core_ED25519_PointDecode
1782 ****************************************************************************//**
1783 *
1784 * Decode ED25519 encoded public key in to x and y
1785 *
1786 * For CAT1C & CAT1D devices with DCache enabled this API is not supported.
1787 *
1788 * \param base
1789 * The pointer to a Crypto instance.
1790 *
1791 * \param curveID
1792 * See \ref cy_en_crypto_ecc_curve_id_t.
1793 *
1794 * \param publicKey
1795 * [in] encoded 32 byte Public key.
1796 *
1797 * \param pubKey_x
1798 * [out] Decoded 32 bytes Public key x in little-endian format.
1799 *
1800 * \param pubKey_y
1801 * [out] Decoded 32 bytes Public key y in little-endian format.
1802 *
1803 * \return status code. See \ref cy_en_crypto_status_t.
1804 *
1805 * \note This is a preliminary implementation and should not be used in production code.
1806 *
1807 *******************************************************************************/
Cy_Crypto_Core_ED25519_PointDecode(CRYPTO_Type * base,cy_en_crypto_ecc_curve_id_t curveID,const uint8_t * publicKey,uint8_t * pubKey_x,uint8_t * pubKey_y)1808 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_PointDecode(CRYPTO_Type *base,
1809 cy_en_crypto_ecc_curve_id_t curveID,
1810 const uint8_t *publicKey,
1811 uint8_t *pubKey_x, uint8_t *pubKey_y)
1812 {
1813 cy_en_crypto_status_t tmpResult = CY_CRYPTO_NOT_SUPPORTED;
1814
1815 cy_stc_crypto_edw_dp_type edw_Dp;
1816 cy_stc_crypto_edw_dp_type *edwDp = &edw_Dp;
1817 uint8_t *publicKeyRemap;
1818 uint8_t *publicKeyXRemap;
1819 uint8_t *publicKeyYRemap;
1820 uint8_t x_0;
1821
1822 /* (p-5)/8 */
1823 CY_ALIGN(4) static const uint8_t ed25519_pb8_exp[CY_CRYPTO_ECC_ED25519_BYTE_SIZE] =
1824 {
1825 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1826 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1827 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f
1828 };
1829 /* 2^((p-1)/4) */
1830 CY_ALIGN(4)static const uint8_t ed25519_sqrt_m1[] =
1831 {
1832 0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD,
1833 0x06, 0x18, 0x43, 0x2F, 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B,
1834 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B
1835 };
1836
1837 CY_CRYPTO_VU_PUSH_REG (base);
1838
1839 if(CY_CRYPTO_SUCCESS == Cy_Crypto_Core_EDW_GetCurveParams(edwDp, curveID))
1840 {
1841 if ((publicKey != NULL) && (pubKey_x != NULL) && (pubKey_y != NULL))
1842 {
1843 uint32_t bitsize = edwDp->size;
1844 uint32_t bytesize = CY_CRYPTO_BYTE_SIZE_OF_BITS(edwDp->size);
1845
1846 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1847 /* Flush the cache */
1848 SCB_CleanDCache_by_Addr((volatile void *)publicKey,(int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
1849 #endif
1850 publicKeyRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(publicKey);
1851 publicKeyXRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(pubKey_x);
1852 publicKeyYRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(pubKey_y);
1853
1854 uint32_t p_a = 7u; /* grp->A */
1855 uint32_t p_d = 6u; /* grp->D */
1856 uint32_t p_x = 3u; /* pub x coordinate */
1857 uint32_t p_y = 4u; /* pub y coordinate */
1858 uint32_t p_uv = 5u; /* (u*v) RFC 8032 sec 5.1.3 */
1859
1860 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_x, bitsize);
1861 if(CY_CRYPTO_SUCCESS != tmpResult)
1862 {
1863 return tmpResult;
1864 }
1865
1866 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_y, bitsize);
1867 if(CY_CRYPTO_SUCCESS != tmpResult)
1868 {
1869 return tmpResult;
1870 }
1871
1872 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_a, bitsize);
1873 if(CY_CRYPTO_SUCCESS != tmpResult)
1874 {
1875 return tmpResult;
1876 }
1877 Cy_Crypto_Core_Vu_SetMemValue (base, p_a, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->a), bitsize);
1878
1879 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_d, bitsize);
1880 if(CY_CRYPTO_SUCCESS != tmpResult)
1881 {
1882 return tmpResult;
1883 }
1884 Cy_Crypto_Core_Vu_SetMemValue (base, p_d, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->d), bitsize);
1885
1886 tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, p_uv, bitsize);
1887 if(CY_CRYPTO_SUCCESS != tmpResult)
1888 {
1889 return tmpResult;
1890 }
1891
1892 /* load prime defining the curve as well as the barrett coefficient. */
1893 /* VR_P and VR_BARRETT_U are "globally" defined in cy_crypto_core_ecc.h */
1894 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_P, bitsize);
1895 if(CY_CRYPTO_SUCCESS != tmpResult)
1896 {
1897 return tmpResult;
1898 }
1899 Cy_Crypto_Core_Vu_SetMemValue (base, VR_P, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->prime), bitsize);
1900
1901 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_BARRETT, edwDp->barret_psize);
1902 if(CY_CRYPTO_SUCCESS != tmpResult)
1903 {
1904 return tmpResult;
1905 }
1906 Cy_Crypto_Core_Vu_SetMemValue (base, VR_BARRETT, (uint8_t const*)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->barrett_p), edwDp->barret_psize);
1907
1908 /* Recover x_0 and generate p_y*/
1909 Cy_Crypto_Core_MemCpy(base, (void*)publicKeyYRemap, (void const *)publicKeyRemap, (uint16_t)bytesize);
1910 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1911 SCB_InvalidateDCache_by_Addr((void *)publicKeyYRemap,(int32_t)bytesize);
1912 #endif
1913 x_0 = publicKeyYRemap[31] & (uint8_t)0x01;
1914 publicKeyYRemap[31] &= (uint8_t)0x7F;
1915 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1916 SCB_CleanDCache_by_Addr((void *)publicKeyYRemap,(int32_t)bytesize);
1917 #endif
1918 /* If the resulting y >= grp->P, decoding fails. */
1919 Cy_Crypto_Core_Vu_SetMemValue (base, p_y, (uint8_t const *)publicKeyYRemap, bitsize);
1920 if (!Cy_Crypto_Core_Vu_IsRegLess(base, p_y, VR_P))
1921 {
1922 /* p_y is not less than P!!! */
1923 tmpResult = CY_CRYPTO_BAD_PARAMS;
1924 }
1925
1926 /*
1927 To recover the x-coordinates, the curve equation implies x^2 = (y^2 - 1) / (d y^2 - a) (mod p).
1928 The denominator is always non-zero mod p. Let u = y^2 - 1 and v = d y^2 - a.
1929 We compute the square root of (u/v) depending on p (mod 8),for ED25519 its 5. The candidate root is
1930 x = sqrt(u/v) = u (u v)^((p-5)/8)
1931 */
1932 if (CY_CRYPTO_SUCCESS == tmpResult)
1933 {
1934 /*y^2*/
1935 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, p_y, p_y, bitsize);
1936 if(CY_CRYPTO_SUCCESS != tmpResult)
1937 {
1938 return tmpResult;
1939 }
1940 /* dy^2*/
1941 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, p_d, p_d, p_y, bitsize);
1942 if(CY_CRYPTO_SUCCESS != tmpResult)
1943 {
1944 return tmpResult;
1945 }
1946 /* v = (dy^2 - a) */
1947 Cy_Crypto_Core_EC_SubMod (base, p_d, p_d, p_a);
1948 /* u = y^2 - 1 */
1949 CY_CRYPTO_VU_SET_TO_ONE(base, p_x);
1950 CY_CRYPTO_VU_SUB(base, p_y, p_y, p_x);
1951 /* compute u*((uv)^((p-5)/8)) mod p */
1952 Cy_Crypto_Core_Vu_SetMemValue (base, p_x, (uint8_t const *)ed25519_pb8_exp, bitsize);
1953 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, p_a, p_d, p_y, bitsize);
1954 if(CY_CRYPTO_SUCCESS != tmpResult)
1955 {
1956 return tmpResult;
1957 }
1958 tmpResult = Cy_Crypto_Core_ED25519_ExpMod( base, p_uv, p_a, p_x, bitsize);
1959 if(CY_CRYPTO_SUCCESS != tmpResult)
1960 {
1961 return tmpResult;
1962 }
1963
1964 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, p_uv, p_uv, p_y, bitsize);
1965 if(CY_CRYPTO_SUCCESS != tmpResult)
1966 {
1967 return tmpResult;
1968 }
1969 /* If v * x^2 = u (mod p), x is a square root. */
1970 tmpResult = Cy_Crypto_Core_ED25519_SquareMod( base, p_x, p_uv, bitsize);
1971 if(CY_CRYPTO_SUCCESS != tmpResult)
1972 {
1973 return tmpResult;
1974 }
1975 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, p_x, p_x, p_d, bitsize);
1976 if(CY_CRYPTO_SUCCESS != tmpResult)
1977 {
1978 return tmpResult;
1979 }
1980 if (Cy_Crypto_Core_Vu_IsRegEqual(base, p_x, p_y) != true)
1981 {
1982 /* Otherwise if v x^2 = -u (mod p), x * 2^((p-1)/4) is a square
1983 * root. */
1984 Cy_Crypto_Core_EC_SubMod(base, p_x, VR_P, p_x);
1985 if (Cy_Crypto_Core_Vu_IsRegEqual(base, p_x, p_y) != true)
1986 {
1987 return CY_CRYPTO_BAD_PARAMS;
1988 }
1989 /* x *= 2^((p-1)/4) */
1990 Cy_Crypto_Core_Vu_SetMemValue (base, p_y, (uint8_t const *)ed25519_sqrt_m1, bitsize);
1991 tmpResult = Cy_Crypto_Core_ED25519_MulMod( base, p_x, p_uv, p_y, bitsize);
1992 if(CY_CRYPTO_SUCCESS != tmpResult)
1993 {
1994 return tmpResult;
1995 }
1996 }
1997 /* Use the x_0 bit to select the right square root. */
1998 if (Cy_Crypto_Core_Vu_IsRegZero(base, p_x) && x_0 == 1u)
1999 {
2000 return CY_CRYPTO_BAD_PARAMS;
2001 }
2002 else
2003 {
2004 uint8_t *x = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_x);
2005
2006 if( (x[0] & 0x1u) != x_0)
2007 {
2008 Cy_Crypto_Core_EC_SubMod(base, p_x, VR_P, p_x);
2009 }
2010 }
2011
2012 Cy_Crypto_Core_Vu_GetMemValue (base, publicKeyXRemap, p_x, bitsize);
2013 }
2014 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
2015 SCB_InvalidateDCache_by_Addr(pubKey_x, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2016 SCB_InvalidateDCache_by_Addr(pubKey_y, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2017 #endif
2018 CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(p_x) | CY_CRYPTO_VU_REG_BIT(p_y) |
2019 CY_CRYPTO_VU_REG_BIT(p_a) | CY_CRYPTO_VU_REG_BIT(p_d) |
2020 CY_CRYPTO_VU_REG_BIT(VR_P)| CY_CRYPTO_VU_REG_BIT(p_uv)|
2021 CY_CRYPTO_VU_REG_BIT(VR_BARRETT));
2022
2023 Cy_Crypto_Core_Vu_WaitForComplete(base);
2024 CY_CRYPTO_VU_POP_REG (base);
2025 }
2026 }
2027 return (tmpResult);
2028 }
2029 /** \endcond */
2030 /*******************************************************************************
2031 * Function Name: Cy_Crypto_Core_ED25519_Verify
2032 ****************************************************************************//**
2033 *
2034 * Verify ED25519 signed message.
2035 *
2036 * For CAT1C & CAT1D devices with DCache enabled this API is not supported.
2037 *
2038 * \param base
2039 * The pointer to a Crypto instance.
2040 *
2041 * \param sig
2042 * The signature to verify, 'R' followed by 'S'.
2043 *
2044 * \param hash
2045 * The hash or message that was signed.
2046 *
2047 * \param hashlen
2048 * The length of the hash or message (octets).
2049 *
2050 * \param stat
2051 * Result of signature verification, 0xA1A1A1A1==valid, 0x00BADBAD==invalid.
2052 *
2053 * \param key
2054 * The corresponding uncompressed public key to use (little-endian). See \ref cy_stc_crypto_ecc_key.
2055 *
2056 * \param sigType
2057 * signature Type. CY_CRYPTO_EDDSA_PURE,CY_CRYPTO_EDDSA_CTX or CY_CRYPTO_EDDSA_PREHASH
2058 *
2059 * \param sigctx
2060 * signature context. can be NULL if EDDSA_PURE is used or if no context is provided.
2061 *
2062 * \param sigctx_len
2063 * The length of the signature context
2064 *
2065 * \return status code. See \ref cy_en_crypto_status_t.
2066 *
2067 *******************************************************************************/
Cy_Crypto_Core_ED25519_Verify(CRYPTO_Type * base,uint8_t * sig,const uint8_t * hash,uint32_t hashlen,const cy_stc_crypto_ecc_key * key,uint32_t * stat,cy_en_eddsa_sig_type_t sigType,const uint8_t * sigctx,uint32_t sigctx_len)2068 cy_en_crypto_status_t Cy_Crypto_Core_ED25519_Verify(CRYPTO_Type *base, uint8_t *sig, const uint8_t *hash, uint32_t hashlen,
2069 const cy_stc_crypto_ecc_key *key, uint32_t *stat, cy_en_eddsa_sig_type_t sigType,const uint8_t *sigctx, uint32_t sigctx_len)
2070 {
2071 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
2072
2073 uint8_t *sigPtrRemap;
2074 uint8_t *hashPtrRemap;
2075 uint8_t *pubKeyXRemap;
2076 uint8_t *pubKeyYRemap;
2077 uint32_t mallocMask = 0u;
2078
2079 cy_stc_crypto_edw_dp_type edwDp_t;
2080 cy_stc_crypto_edw_dp_type *edwDp = &edwDp_t;
2081
2082 /*
2083 Value of context is set by the signer and verifier (maximum of 255
2084 octets; the default is empty string, except for Ed25519, which can't
2085 have context) and has to match octet by octet for verification to be
2086 successful.
2087 */
2088 if(sigType == CY_CRYPTO_EDDSA_CTX)
2089 {
2090 if( sigctx == NULL || sigctx_len == 0u || sigctx_len > 255u)
2091 {
2092 return CY_CRYPTO_BAD_PARAMS;
2093 }
2094 }
2095
2096 /* input param validation */
2097 if ((hash == NULL) && (0u != hashlen))
2098 {
2099 return CY_CRYPTO_BAD_PARAMS;
2100 }
2101
2102 if ((sig != NULL) && (stat != NULL) && (sigType < CY_CRYPTO_EDDSA_NONE))
2103 {
2104 tmpResult = CY_CRYPTO_NOT_SUPPORTED;
2105 *stat = CY_ED25519SIG_VERIFY_FAIL;
2106
2107 hashPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(hash);
2108 sigPtrRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(sig);
2109 pubKeyXRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->pubkey.x);
2110 pubKeyYRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->pubkey.y);
2111
2112 if(CY_CRYPTO_SUCCESS == Cy_Crypto_Core_EDW_GetCurveParams(edwDp, key->curveID))
2113 {
2114 #if (CY_IP_MXCRYPTO_VERSION == 1u)
2115 static cy_stc_crypto_v1_sha512_buffers_t shaBuffers;
2116 #else
2117 static cy_stc_crypto_v2_sha512_buffers_t shaBuffers;
2118 #endif
2119 static cy_stc_crypto_sha_state_t shaHashState;
2120 uint32_t bitsize = edwDp->size;
2121 uint32_t bytesize = CY_CRYPTO_BYTE_SIZE_OF_BITS(edwDp->size);
2122
2123 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
2124 /* Flush the cache */
2125 SCB_CleanDCache_by_Addr((volatile void *)hash,(int32_t)hashlen);
2126 SCB_CleanDCache_by_Addr((volatile void *)key->pubkey.x, (int32_t)bytesize);
2127 SCB_CleanDCache_by_Addr((volatile void *)key->pubkey.y, (int32_t)bytesize);
2128 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t.');
2129 SCB_CleanDCache_by_Addr((volatile void *)sig,(int32_t)(2u*bytesize));
2130 SCB_CleanDCache_by_Addr((volatile void *)edwDp->order,(int32_t)bytesize);
2131 SCB_CleanDCache_by_Addr((volatile void *)edwDp->Gx,(int32_t)bytesize);
2132 SCB_CleanDCache_by_Addr((volatile void *)edwDp->Gy,(int32_t)bytesize);
2133 SCB_CleanDCache_by_Addr((volatile void *)edwDp->prime,(int32_t)bytesize);
2134 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t.');
2135 SCB_CleanDCache_by_Addr((volatile void *)edwDp->barrett_o,(int32_t)edwDp->barret_osize);
2136 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t.');
2137 SCB_CleanDCache_by_Addr((volatile void *)edwDp->barrett_p,(int32_t)edwDp->barret_psize);
2138 /* sigctx is managed by the SHA functions */
2139 #endif
2140 tmpResult = Cy_Crypto_Core_Sha_Init(base, &shaHashState, (cy_en_crypto_sha_mode_t)CY_CRYPTO_MODE_SHA512, (void *)&shaBuffers);
2141 if (CY_CRYPTO_SUCCESS == tmpResult)
2142 {
2143 tmpResult = Cy_Crypto_Core_Sha_Start(base, &shaHashState);
2144 }
2145
2146 if (CY_CRYPTO_SUCCESS == tmpResult)
2147 {
2148 uint32_t p_sha = 4u;
2149 uint32_t p_temp = 5u;
2150 uint32_t p_r = 6u;
2151 uint32_t p_s = 7u;
2152 uint32_t p_x = 8u;
2153 uint32_t p_y = 9u;
2154
2155 uint8_t *digest;
2156 uint8_t *pubkey_x;
2157 uint8_t *pubkey_y;
2158 uint8_t *sig_r;
2159 uint8_t *sig_s;
2160
2161 sig_r = &sigPtrRemap[0];
2162 sig_s = &sigPtrRemap[bytesize];
2163 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_r, bitsize+1u);
2164 if(CY_CRYPTO_SUCCESS != tmpResult)
2165 {
2166 return tmpResult;
2167 }
2168 Cy_Crypto_Core_Vu_SetMemValue(base, p_r, (uint8_t const *)sig_r, bitsize+1u);
2169
2170 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_s, bitsize+1u);
2171 if(CY_CRYPTO_SUCCESS != tmpResult)
2172 {
2173 return tmpResult;
2174 }
2175 Cy_Crypto_Core_Vu_SetMemValue(base, p_s, (uint8_t const *)sig_s, bitsize+1u);
2176
2177 /*Curve Order*/
2178 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_P, bitsize);
2179 if(CY_CRYPTO_SUCCESS != tmpResult)
2180 {
2181 return tmpResult;
2182 }
2183 Cy_Crypto_Core_Vu_SetMemValue (base, VR_P, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->order), bitsize);
2184
2185 /* Check R and S range */
2186 if (Cy_Crypto_Core_Vu_IsRegZero(base, p_r))
2187 {
2188 /* R is zero!!! */
2189 return CY_CRYPTO_BAD_PARAMS;
2190 }
2191 if (Cy_Crypto_Core_Vu_IsRegZero(base, p_s))
2192 {
2193 /* S is zero!!! */
2194 return CY_CRYPTO_BAD_PARAMS;
2195 }
2196
2197 /* Barret coef for Order*/
2198 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_BARRETT, edwDp->barret_osize);
2199 if(CY_CRYPTO_SUCCESS != tmpResult)
2200 {
2201 return tmpResult;
2202 }
2203 Cy_Crypto_Core_Vu_SetMemValue (base, VR_BARRETT, (uint8_t const*)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->barrett_o), edwDp->barret_osize);
2204 /* Gx co-ordinate */
2205 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_X, bitsize);
2206 if(CY_CRYPTO_SUCCESS != tmpResult)
2207 {
2208 return tmpResult;
2209 }
2210 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_X, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gx), bitsize);
2211 /* Gy co-ordinate */
2212 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_Y, bitsize+1u);
2213 if(CY_CRYPTO_SUCCESS != tmpResult)
2214 {
2215 return tmpResult;
2216 }
2217 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_Y, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(edwDp->Gy), bitsize+1u);
2218
2219 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_sha, (CY_CRYPTO_SHA512_HASH_SIZE*8u));
2220 if(CY_CRYPTO_SUCCESS != tmpResult)
2221 {
2222 return tmpResult;
2223 }
2224 digest = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_sha);
2225
2226 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_temp, bitsize+1u);
2227 if(CY_CRYPTO_SUCCESS != tmpResult)
2228 {
2229 return tmpResult;
2230 }
2231
2232 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_x, bitsize+1u);
2233 if(CY_CRYPTO_SUCCESS != tmpResult)
2234 {
2235 return tmpResult;
2236 }
2237 Cy_Crypto_Core_Vu_SetMemValue (base, p_x, (uint8_t const *)pubKeyXRemap, bitsize+1u);
2238
2239 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, p_y, bitsize+1u);
2240 if(CY_CRYPTO_SUCCESS != tmpResult)
2241 {
2242 return tmpResult;
2243 }
2244 Cy_Crypto_Core_Vu_SetMemValue (base, p_y, (uint8_t const *)pubKeyYRemap, bitsize+1u);
2245
2246 mallocMask = CY_CRYPTO_VU_REG_BIT(VR_P) | CY_CRYPTO_VU_REG_BIT(VR_BARRETT) |
2247 CY_CRYPTO_VU_REG_BIT(VR_S_X) | CY_CRYPTO_VU_REG_BIT(VR_S_Y) |
2248 CY_CRYPTO_VU_REG_BIT(p_r) | CY_CRYPTO_VU_REG_BIT(p_s) |
2249 CY_CRYPTO_VU_REG_BIT(p_x) | CY_CRYPTO_VU_REG_BIT(p_y) |
2250 CY_CRYPTO_VU_REG_BIT(p_sha) | CY_CRYPTO_VU_REG_BIT(p_temp);
2251
2252 /* step1 */
2253 /*SHA expects big-endian*/
2254 if(sigType != CY_CRYPTO_EDDSA_PURE)
2255 {
2256 Cy_Crypto_Core_Vu_WaitForComplete(base);
2257 Cy_Crypto_Core_ED25519_dom2_ctx( base, sigType, sigctx, sigctx_len, &shaHashState);
2258 }
2259
2260 /* step2: h = sha512(Rs + public + msg) mod N */
2261 (void)Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)sig_r, bytesize);
2262 /* compress public key */
2263 pubkey_x = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_x);
2264 pubkey_y = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, p_y);
2265
2266 if((bool)(((uint8_t*)pubkey_x)[0] & (uint8_t)0x01))
2267 {
2268 ((uint8_t*)pubkey_y)[31] |= (uint8_t)0x80;
2269 }
2270 /* interpret as little-endian */
2271 (void)Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)pubkey_y, bytesize);
2272 /* For EDDSA_PREHASH, buf should contain the SHA512 hash. It contains the whole message otherwise */
2273 tmpResult = Cy_Crypto_Core_Sha_Update(base, &shaHashState, (uint8_t const*)hashPtrRemap, hashlen);
2274 if(CY_CRYPTO_SUCCESS == tmpResult)
2275 {
2276 tmpResult = Cy_Crypto_Core_Sha_Finish(base, &shaHashState, digest);
2277 if(CY_CRYPTO_SUCCESS != tmpResult)
2278 {
2279 return tmpResult;
2280 }
2281 }
2282
2283 /* Mod reduction modulo n (order of the base point in VR_P and barret_o in VR_BARRET) */
2284 if ( CY_CRYPTO_SUCCESS != Cy_Crypto_Core_EDDSA_Bar_MulRed(base, p_temp, p_sha, bitsize) )
2285 {
2286 return CY_CRYPTO_BAD_PARAMS;
2287 }
2288 /* Step 3 */
2289 /* We perform fast single-signature verification by compressing sB-hA and comparing with r without decompressing it */
2290 ((uint8_t*)pubkey_y)[31] &= (uint8_t)0x7F;
2291
2292 CY_CRYPTO_VU_SUB (base, p_temp, VR_P, p_temp);
2293 /* R = sG + hA */
2294 tmpResult = Cy_Crypto_Core_ED25519_PointMulAdd(base, edwDp, VR_S_X, VR_S_Y, p_s, p_x, p_y, p_temp, bitsize);
2295 if(CY_CRYPTO_SUCCESS != tmpResult)
2296 {
2297 return tmpResult;
2298 }
2299
2300 /* Compress R (we re-use pubkey_x & y)*/
2301 pubkey_x = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, VR_S_X);
2302 pubkey_y = (uint8_t *)Cy_Crypto_Core_Vu_RegMemPointer(base, VR_S_Y);
2303 if((bool)(((uint8_t*)pubkey_x)[0] & (uint8_t)0x01))
2304 {
2305 ((uint8_t*)pubkey_y)[31] |= (uint8_t)0x80;
2306 }
2307 /* since its compressed we are free to compare with r without decompressing it */
2308 if (Cy_Crypto_Core_Vu_IsRegEqual(base, VR_S_Y, p_r))
2309 {
2310 *stat = CY_ED25519SIG_VERIFY_PASS;
2311 }
2312 else
2313 {
2314 *stat = CY_ED25519SIG_VERIFY_FAIL;
2315 }
2316 /* Free all mem allocations */
2317 CY_CRYPTO_VU_FREE_MEM(base, mallocMask);
2318 (void)Cy_Crypto_Core_Sha_Free(base, &shaHashState);
2319 }
2320 }
2321 }
2322
2323 return (tmpResult);
2324 }
2325 #endif /* defined(CY_CRYPTO_CFG_EDDSA_VERIFY_C) */
2326 #endif /* defined(CY_CRYPTO_CFG_EDDSA_C) */
2327
2328 #if defined(__cplusplus)
2329 }
2330 #endif
2331
2332 #endif /* CY_IP_MXCRYPTO */
2333
2334 /* [] END OF FILE */
2335