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