1 /***************************************************************************//**
2 * \file cy_crypto_core_ecc_nist_p.c
3 * \version 2.120
4 *
5 * \brief
6 *  This file provides Elliptic Curve (EC) Scalar Multiplication using (X,Y)-only,
7 *  Co-Z arithmetic in the Crypto driver.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright (c) (2020-2022), 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_ecc_nist_p.h"
33 
34 #if defined(__cplusplus)
35 extern "C" {
36 #endif
37 
38 #if defined (CY_CRYPTO_CFG_ECP_C)
39 
40 #include "cy_crypto_core_vu.h"
41 
42 /*******************************************************************************
43 * Elliptic Curve (EC) Scalar Multiplication using (X,Y)-only, Co-Z arithmetic
44 *
45 * Theoretic and algorithmic references:
46 * Algorithms and Co-Z arithmetic theory: 'Fast and Regular Algorithms for Scalar
47 * Multiplication over Elliptic Curves', Matthieu Rivain NIST P-curves
48 * (parameters and curve-specific modular reduction):
49 * 'RECOMMENDED ELLIPTIC CURVES FOR FEDERAL GOVERNMENT USE', NIST, 1999
50 *
51 * Useful resources:
52 * Large number calculator and converter:
53 * - http://www.mobilefish.com/services/big_number/big_number.php
54 * - https://www.mobilefish.com/services/big_number_equation/big_number_equation.php
55 *
56 * - ECC curves and test vectors: http://point-at-infinity.org/ecc/nisttv
57 *
58 * Valid values for scalar multiplier, 2 < d < (order-1)
59 *
60 *******************************************************************************/
61 
62 
63 /***************************************************************
64 *                   Global Variables
65 ***************************************************************/
66 static cy_en_crypto_ecc_curve_id_t eccMode;
67 
68 static cy_en_crypto_ecc_red_mul_algs_t mul_red_alg_select = CY_CRYPTO_NIST_P_BARRETT_RED_ALG;
69 
70 /***************************************************************
71 * Collection of multiplication reduction algorithms
72 * Method 1: (Crypto_EC_CS_MUL_Red_Pxxx): curve specific
73 *           reduction as proposed by NIST
74 * Method 2: (Crypto_EC_SM_MUL_Red_Pxxx): curve specific
75 *           reduction based on Mersenne prime reduction approach
76 * Method 3: generic Barrett reduction
77 ***************************************************************/
78 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
79 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x);
80 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x);
81 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
82 
83 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
84 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x);
85 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x);
86 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
87 
88 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
89 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x);
90 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x);
91 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
92 
93 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
94 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x);
95 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x);
96 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
97 
98 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
99 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x);
100 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x);
101 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
102 
103 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size);
104 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size);
105 static cy_en_crypto_status_t Cy_Crypto_Core_EC_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size);
106 
107 
108 /***************************************************************
109 *    Curve-specific multiplication reduction algorithms
110 ***************************************************************/
111 
112 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
113 /*******************************************************************************
114 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P192
115 ****************************************************************************//**
116 *
117 * Curve-specific multiplication modular reduction for P192.
118 * 0 <= a, b < P192
119 * a5..a0 * b5..b0 % P192 = t11..t0 % P192
120 * P192 = 2^192-2^64-1
121 * t11..t0 % 2^192-2^64-1
122 * t11..t6 * 2^192 + t5..t0 % 2^192-2^64-1
123 * t11..t6 * 2^192-2^64-1 + t11..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
124 * t11..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
125 * t11..t10 * 2^192 + t9..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
126 * t11..t10 * 2^192-2^64-1 + t11..t10 * 2^64 + t11..t10 + t9..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
127 * t11..t10 * 2^64 + t11..t10 + t9..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
128 *
129 * \param base
130 * The pointer to a Crypto instance.
131 *
132 * \param z
133 * Product = a*b [2*192 bits].
134 *
135 * \param x
136 * Result = x mod P = a*b mod P [192 bits].
137 *
138 * \return status code. See \ref cy_en_crypto_status_t.
139 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P192(CRYPTO_Type * base,uint32_t z,uint32_t x)140 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x)
141 {
142    uint32_t sh   = 0u;
143    uint32_t t1   = 2u;     /* 128 */
144    uint32_t t2   = 3u;     /* 192 */
145    uint32_t my_z = 4u;
146    uint32_t my_x = 5u;
147    cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
148 
149    CY_CRYPTO_VU_PUSH_REG (base);
150 
151    CY_CRYPTO_VU_LD_REG (base, my_z, z);
152    CY_CRYPTO_VU_LD_REG (base, my_x, x);
153 
154    tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, 128u);
155    if(CY_CRYPTO_SUCCESS != tmpResult)
156    {
157        return tmpResult;
158    }
159 
160    tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, 192u);
161    if(CY_CRYPTO_SUCCESS != tmpResult)
162    {
163        return tmpResult;
164    }
165 
166    CY_CRYPTO_VU_SET_REG (base, sh, 192u, 1u);
167    CY_CRYPTO_VU_LSR (base, my_z, my_x, sh);     /* t11..t6 */
168 
169    CY_CRYPTO_VU_SET_REG (base, sh, 128u, 1u);
170    CY_CRYPTO_VU_LSR (base, t1, my_z, sh);       /* t11..t10 */
171    CY_CRYPTO_VU_SET_REG (base, sh, 64u, 1u);
172    CY_CRYPTO_VU_LSL (base, t2, my_z, sh);       /* t9..t6 * 2^64 */
173 
174 
175    CY_CRYPTO_VU_ADD (base, my_z, my_z, my_x);   /* t11..t6 + t5..t0 */
176    CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);  /* C = (z >= VR_P) */
177    CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
178 
179    CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);     /* t9..t6 * 2^64 + t11..t6 + t5..t0 */
180    CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);  /* C = (z >= VR_P) */
181    CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
182 
183    CY_CRYPTO_VU_LSL (base, t2, t1, sh);         /* t11..t10 * 2^64 */
184    CY_CRYPTO_VU_OR (base, t1, t1, t2);          /* t11..t10 * 2^64 + t11..t10 */
185 
186    CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);     /* t11..t10 * 2^64 + t11..t10 + t9..t6 * 2^64 + t11..t6 + t5..t0 */
187    CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);  /* C = (z >= VR_P) */
188    CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
189 
190    CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2));
191    CY_CRYPTO_VU_POP_REG (base);
192 
193    return CY_CRYPTO_SUCCESS;
194 }
195 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
196 
197 
198 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
199 /*******************************************************************************
200 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P224
201 ****************************************************************************//**
202 *
203 * Curve-specific multiplication modular reduction for P224.
204 * 0 <= a, b < P224
205 * a6..a0 * b6..b0 % P224 = t13..t0 % P224
206 * P224 = 2^224 - 2^96 - 1
207 * t6..t0 + t10..t7*2^96 + t13..t11*2^96 - t13..t7 - t13..t11 % 2^224 - 2^96 - 1
208 * t13..t11*2^96 + t6..t0 - t13..t7 - t13..t11 + t10..t7*2^96 % 2^224 - 2^96 - 1
209 *
210 * \param base
211 * The pointer to a Crypto instance.
212 *
213 * \param z
214 * Result = x mod P = a*b mod P [224 bits].
215 *
216 * \param x
217 * Product = a*b [2*224 bits].
218 *
219 *
220 * \return status code. See \ref cy_en_crypto_status_t.
221 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P224(CRYPTO_Type * base,uint32_t z,uint32_t x)222 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x)
223 {
224    uint32_t sh   = 0u;
225    uint32_t t1   = 1u;     /* 224 */
226    uint32_t t2   = 2u;     /* 224 */
227    uint32_t t3   = 3u;     /* 224 */
228    uint32_t my_z = 4u;
229    uint32_t my_x = 5u;
230    cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
231 
232    CY_CRYPTO_VU_PUSH_REG (base);
233 
234    CY_CRYPTO_VU_LD_REG (base, my_z, z);
235    CY_CRYPTO_VU_LD_REG (base, my_x, x);
236 
237    tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, CY_CRYPTO_ECC_P224_SIZE);  /* 224 */
238    if(CY_CRYPTO_SUCCESS != tmpResult)
239    {
240         return tmpResult;
241    }
242 
243    tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, CY_CRYPTO_ECC_P224_SIZE);  /* 224 */
244    if(CY_CRYPTO_SUCCESS != tmpResult)
245    {
246         return tmpResult;
247    }
248 
249    tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, CY_CRYPTO_ECC_P224_SIZE);  /* 224 */
250    if(CY_CRYPTO_SUCCESS != tmpResult)
251    {
252         return tmpResult;
253    }
254 
255    CY_CRYPTO_VU_SET_REG (base, sh, CY_CRYPTO_ECC_P224_SIZE, 1u); /* sh   = 224 */
256    CY_CRYPTO_VU_LSR (base, my_z, my_x, sh); /* z = t13..t7 */
257 
258    CY_CRYPTO_VU_SET_REG (base, sh, 128u, 1u);
259    CY_CRYPTO_VU_LSR (base, t1, my_z, sh);   /* t1 = t13..t11 */
260 
261    CY_CRYPTO_VU_SET_REG (base, sh, 96u, 1u);
262    CY_CRYPTO_VU_LSL (base, t2, t1, sh);     /* t2 = t13..t11*2^96 */
263 
264    CY_CRYPTO_VU_SET_REG (base, sh, 96u, 1u);
265    CY_CRYPTO_VU_LSL (base, t3, my_z, sh);   /* t3 = t10..t7*2^96 */
266 
267    CY_CRYPTO_VU_ADD (base, t2, t2, my_x);   /* t2 = t13..t11*2^96 + t6..t0 */
268    CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, t2, VR_P);    /* C    = (t2 >= VR_P) */
269    CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, t2, t2, VR_P);    /* t2 = t2 - p, if C==1 (Carry is set) */
270 
271    CY_CRYPTO_VU_SUB (base, t2, t2, my_z);   /* t2 = (t13..t11*2^96 + t6..t0) - t13..t7 */
272    CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, t2, t2, VR_P);    /* t2 = t2 + p, if C==0 (Carry is clear) */
273 
274    CY_CRYPTO_VU_SUB (base, t2, t2, t1);     /* t2 = (t13..t11*2^96 + t6..t0 - t13..t7) - t13..t11 */
275    CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, t2, t2, VR_P);    /* t2 = t2 + p, if C==0 (Carry is clear) */
276 
277    CY_CRYPTO_VU_ADD (base, my_z, t2, t3);   /* z = (t13..t11*2^96 + t6..t0 - t13..t7 - t13..t11) + t10..t7*2^96 */
278    CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);  /* C    = (z >= VR_P) */
279    CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);    /* z = z - p, if C==1 (Carry is set) */
280 
281    CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2) | CY_CRYPTO_VU_REG_BIT(t3));
282 
283    CY_CRYPTO_VU_POP_REG (base);
284 
285    return CY_CRYPTO_SUCCESS;
286 }
287 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
288 
289 
290 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
291 /*******************************************************************************
292 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P256
293 ****************************************************************************//**
294 *
295 * Curve-specific multiplication modular reduction for P256.
296 * 0 <= a, b < P256
297 * a7..a0 * b7..b0 % P256 = t15..t0 % P256
298 * P224 = 2^256 - 2^224 + 2^192 + 2^96 - 1
299 * t7..t0 + 2*t15..t11*2^96 + 2*t15..t12*2^96 + (t15..t14*2^192 + t10..t8)
300 * + (t8*2^224 + t13*2^192 + t15..t9) - (t10*2^224 + t8*2^192 + t13..t11)
301 * - (t11*2^224 + t9*2^192 + t15..t12) - (t12*2^224 + t10..t8*2^96 + t15..t13)
302 * - (t13*2^224 + t11..t9*2^96 + t15..t14) % 2^256 - 2^224 + 2^192 + 2^96 - 1
303 *
304 * \param base
305 * The pointer to a Crypto instance.
306 *
307 * \param z
308 * Result = x mod P = a*b mod P [256 bits].
309 *
310 * \param x
311 * Product = a*b [2*256 bits].
312 *
313 * \return status code. See \ref cy_en_crypto_status_t.
314 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P256(CRYPTO_Type * base,uint32_t z,uint32_t x)315 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x)
316 {
317     uint32_t sh     = 0u;   /* Variable values */
318     uint32_t sh32   = 1u;
319     uint32_t sh96   = 2u;
320     uint32_t sh192  = 3u;
321     uint32_t sh224  = 4u;
322     uint32_t t0     = 5u;   /* 256 */
323     uint32_t t1     = 6u;   /* 256 */
324     uint32_t t2     = 7u;   /* 256 */
325     uint32_t t3     = 8u;   /* 32 */
326     uint32_t t4     = 9u;   /* 96 */
327     uint32_t my_z   = 10u;
328     uint32_t my_x   = 11u;
329     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
330 
331     CY_CRYPTO_VU_PUSH_REG (base);
332 
333     CY_CRYPTO_VU_LD_REG (base, my_z, z);
334     CY_CRYPTO_VU_LD_REG (base, my_x, x);
335 
336     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P256_SIZE); /* 256 */
337     if(CY_CRYPTO_SUCCESS != tmpResult)
338     {
339         return tmpResult;
340     }
341 
342     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, CY_CRYPTO_ECC_P256_SIZE); /* 256 */
343     if(CY_CRYPTO_SUCCESS != tmpResult)
344     {
345         return tmpResult;
346     }
347 
348     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, CY_CRYPTO_ECC_P256_SIZE); /* 256 */
349     if(CY_CRYPTO_SUCCESS != tmpResult)
350     {
351         return tmpResult;
352     }
353 
354     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, 32u);      /* 32 */
355     if(CY_CRYPTO_SUCCESS != tmpResult)
356     {
357         return tmpResult;
358     }
359 
360     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t4, 96u);      /* 96 */
361     if(CY_CRYPTO_SUCCESS != tmpResult)
362     {
363         return tmpResult;
364     }
365 
366     CY_CRYPTO_VU_SET_REG (base, sh, CY_CRYPTO_ECC_P256_SIZE, 1u);    /* sh = 256 */
367     CY_CRYPTO_VU_SET_REG (base, sh32, 32u, 1u);   /* sh = 32 */
368     CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u);   /* sh = 96 */
369     CY_CRYPTO_VU_SET_REG (base, sh192, 192u, 1u); /* sh = 192 */
370     CY_CRYPTO_VU_SET_REG (base, sh224, 224u, 1u); /* sh = 224 */
371 
372     CY_CRYPTO_VU_LSR (base, t0, my_x, sh);      /* t0 = t15..t8 */
373     CY_CRYPTO_VU_LSR (base, my_z, t0, sh96);    /* z = t15..t11 */
374     CY_CRYPTO_VU_LSR (base, t1, my_z, sh32);    /* t1 = t15..t12 */
375     CY_CRYPTO_VU_LSR (base, t3, my_z, sh32);    /* t3 = t12 */
376 
377     /* 2*S1 -- 2*t15..t11*2^96 */
378     CY_CRYPTO_VU_LSL (base, my_z, my_z, sh96);  /* z = t15..t11*2^96 */
379     CY_CRYPTO_VU_ADD (base, my_z, my_z, my_z);  /* z = 2*t15..t11*2^96 */
380     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
381     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
382 
383     /* D3 (a) -- t12*2^224 */
384     CY_CRYPTO_VU_LSL (base, t2, t3, sh224);     /* t2 = t12*2^224 */
385     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t12*2^224 */
386     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
387 
388     /* 2*S2 -- 2*t15..t12*2^96 */
389     CY_CRYPTO_VU_LSL (base, t2, t1, sh96);      /* t2 = t15..t12*2^96 */
390 
391     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + t15..t12*2^96 */
392     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
393     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
394 
395     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + 2*t15..t12*2^96 */
396     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
397     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
398 
399     /* D4 (c) -- t15..t14 */
400     CY_CRYPTO_VU_LSR (base, t2, t0, sh192);     /* t2 = t15..t14 */
401     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t15..t14 */
402     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
403 
404     /* S3 (a) -- t15..t14*2^192 */
405     CY_CRYPTO_VU_LSL (base, t2, t2, sh192);     /* t2 = t15..t14*2^192 */
406     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + t15..t14*2^192 */
407     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
408     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
409 
410     /* D2 (c) -- t15..t12 */
411     CY_CRYPTO_VU_SUB (base, my_z, my_z, t1);    /* z = z - t15..t12 */
412     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
413 
414     /* S4 (b) -- t13*2^192 */
415     CY_CRYPTO_VU_LSR (base, t3, t1, sh32);      /* t3 = t13 */
416     CY_CRYPTO_VU_LSL (base, t2, t3, sh192);     /* t2 = t13*2^192 */
417     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + t13*2^192 */
418     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
419     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
420 
421     /* D4 (a) -- t13*2^224 */
422     CY_CRYPTO_VU_LSL (base, t2, t2, sh32);      /* t2 = t13*2^224 */
423     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t13*2^224 */
424     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
425 
426     /* D3 (c) -- t15..t13 */
427     CY_CRYPTO_VU_LSR (base, t1, t1, sh32);      /* t1 = t15..t13 */
428     CY_CRYPTO_VU_SUB (base, my_z, my_z, t1);    /* z = z - t15..t13 */
429     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
430 
431     /* S4 (c) -- t15..t13*2^96 */
432     CY_CRYPTO_VU_LSL (base, t2, t1, sh96);      /* t2 = t15..t13*2^96 */
433     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + t15..t13*2^96 */
434     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
435     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
436 
437     /* D2 (a) -- t11*2^224 */
438     CY_CRYPTO_VU_LSR (base, t3, t0, sh96);      /* t3 = t11 */
439     CY_CRYPTO_VU_LSL (base, t2, t3, sh224);     /* t2 = t11*2^224 */
440     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t11*2^224 */
441     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
442 
443     /* D2 (b) -- t9*2^192 */
444     CY_CRYPTO_VU_LSR (base, t3, t0, sh32);      /* t3 = t9 */
445     CY_CRYPTO_VU_LSL (base, t2, t3, sh192);     /* t2 = t9*2^192 */
446     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t9*2^192 */
447     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
448 
449     /* D1 (c) -- t13..t11 */
450     CY_CRYPTO_VU_LSR (base, t4, t0, sh96);      /* t4 = t13..t11 */
451     CY_CRYPTO_VU_SUB (base, my_z, my_z, t4);    /* z = z - t13..t11 */
452     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
453 
454     /* S4 (d) -- t11..t9 */
455     CY_CRYPTO_VU_LSR (base, t4, t0, sh32);      /* t4 = t11..t9 */
456     CY_CRYPTO_VU_ADD (base, my_z, my_z, t4);    /* z = z + t11..t9 */
457     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
458     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
459 
460     /* D1 (a) -- t10*2^224 */
461     CY_CRYPTO_VU_LSR (base, t3, t4, sh32);      /* t3 = t10 */
462     CY_CRYPTO_VU_LSL (base, t2, t3, sh224);     /* t2 = t10*2^224 */
463     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t10*2^224 */
464     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
465 
466 
467     /* D4 (b) -- t11..t9*2^96 */
468     CY_CRYPTO_VU_LSL (base, t2, t4, sh96);      /* t2 = t11..t9*2^96 */
469     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t11..t9*2^96 */
470     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
471 
472     CY_CRYPTO_VU_SET_REG (base, sh, 0u, 1u);      /* sh = 0; */
473 
474     /* S3 (b) -- t10..t8 */
475     CY_CRYPTO_VU_LSR (base, t4, t0, sh);        /* t4 = t10..t8 */
476     CY_CRYPTO_VU_ADD (base, my_z, my_z, t4);    /* z = z + t10..t8 */
477     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
478     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
479 
480     /* D3 (b) -- t10..t8*2^96 */
481     CY_CRYPTO_VU_LSL (base, t2, t4, sh96);      /* t4 = t10..t8*2^96 */
482     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t10..t8*2^96 */
483     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
484 
485     /* S4 (a) -- t8*2^224 */
486     CY_CRYPTO_VU_LSL (base, t2, t0, sh224);     /* t2 = t8*2^224 */
487     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + t8*2^224 */
488     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
489     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
490 
491     /* D1 (b) -- t8*2^192 */
492     CY_CRYPTO_VU_LSR (base, t2, t2, sh32);      /* t2 = t8*2^192 */
493     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t8*2^192 */
494     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
495 
496     /* T -- t7..t0 */
497     CY_CRYPTO_VU_LSR (base, t2, my_x, sh);      /* t2 = t8*2^192 */
498     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + t7..t0 */
499     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
500     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
501 
502     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0) | CY_CRYPTO_VU_REG_BIT(t1) |
503                                  CY_CRYPTO_VU_REG_BIT(t2) | CY_CRYPTO_VU_REG_BIT(t3) | CY_CRYPTO_VU_REG_BIT(t4));
504     CY_CRYPTO_VU_POP_REG (base);
505 
506     return CY_CRYPTO_SUCCESS;
507 }
508 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
509 
510 
511 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
512 /*******************************************************************************
513 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P384
514 ****************************************************************************//**
515 *
516 * Curve-specific multiplication modular reduction for P384.
517 * 0 <= a, b < P384
518 * a11..a0 * b11..b0 % P384 = t23..t0 % P384
519 * P384 = 2^384 - 2^128 - 2*96 + 2*32 - 1
520 * t11..t0 + 2*t23..t21*2^128 + t23..t12 + (t20..t12*2^96 + t23..t21)
521 * + (t19..t12*2^128 + t20*2^96 +t23*2^32) + t23..t20*2^128 + (t23..t21*2^96 + t20)
522 * - (t22..t12*2^32 + t23) - t23..t20*2^32 - (t23*2^128 + t23*2^96) % P384
523 *
524 * \param base
525 * The pointer to a Crypto instance.
526 *
527 * \param z
528 * Result = x mod P = a*b mod P [384 bits]
529 *
530 * \param x
531 * Product = a*b [2*384 bits]
532 *
533 * \return status code. See \ref cy_en_crypto_status_t.
534 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P384(CRYPTO_Type * base,uint32_t z,uint32_t x)535 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x)
536 {
537     uint32_t sh32   = 0u;
538     uint32_t sh64   = 1u;
539     uint32_t sh96   = 2u;
540     uint32_t sh128  = 3u;
541     uint32_t sh256  = 4u;
542     uint32_t sh384  = 5u;
543     uint32_t t0     = 6u;   /* 384 */
544     uint32_t t1     = 7u;   /* 384 */
545     uint32_t t2     = 8u;   /*  32 */
546     uint32_t my_z   = 9u;
547     uint32_t my_x   = 10u;
548     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
549 
550     CY_CRYPTO_VU_PUSH_REG (base);
551 
552     CY_CRYPTO_VU_LD_REG (base, my_z, z);
553     CY_CRYPTO_VU_LD_REG (base, my_x, x);
554 
555     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P384_SIZE); /* 384 */
556     if(CY_CRYPTO_SUCCESS != tmpResult)
557     {
558         return tmpResult;
559     }
560 
561     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, CY_CRYPTO_ECC_P384_SIZE); /* 384 */
562     if(CY_CRYPTO_SUCCESS != tmpResult)
563     {
564         return tmpResult;
565     }
566     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, 32u);  /* 32 */
567     if(CY_CRYPTO_SUCCESS != tmpResult)
568     {
569         return tmpResult;
570     }
571 
572     CY_CRYPTO_VU_SET_REG (base, sh32, 32u, 1u);   /* sh32  = 32 */
573     CY_CRYPTO_VU_SET_REG (base, sh64, 64u, 1u);   /* sh64  = 64 */
574     CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u);   /* sh96  = 96 */
575     CY_CRYPTO_VU_SET_REG (base, sh128, 128u, 1u); /* sh128 = 128 */
576     CY_CRYPTO_VU_SET_REG (base, sh256, 256u, 1u); /* sh256 = 256 */
577     CY_CRYPTO_VU_SET_REG (base, sh384, CY_CRYPTO_ECC_P384_SIZE, 1u);         /* sh384 = 384 */
578 
579     CY_CRYPTO_VU_LSR (base, t0, my_x, sh384);   /* t0 = t23..t12 */
580 
581     /* T + S2 -- t11..t0 + t23..t12 */
582     CY_CRYPTO_VU_ADD (base, my_z, t0, my_x);    /* z = t23..t12 + t11..t0 */
583     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
584     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
585 
586     /* S6 (b) -- t_20 */
587     CY_CRYPTO_VU_LSR (base, t2, t0, sh256);     /* t2 = t20 */
588     CY_CRYPTO_VU_ADD (base, my_z, my_z, t2);    /* z = z + t20 */
589     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
590     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
591 
592     /* S4 (b) -- t20*2^96 */
593     CY_CRYPTO_VU_LSL (base, t1, t2, sh96);      /* t1 = t20*2^96 */
594     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t20*2^96 */
595     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
596     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
597 
598     /* S5 -- t23..t20*2^128 */
599     CY_CRYPTO_VU_LSR (base, t1, t0, sh256);     /* t1 = t23..t20 */
600     CY_CRYPTO_VU_LSL (base, t1, t1, sh128);     /* t1 = t23..t20*2^128 */
601     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t23..t20*2^128 */
602     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
603     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
604 
605     /* D2 -- t23..t20*2^32 */
606     CY_CRYPTO_VU_LSR (base, t1, t1, sh96);      /* t1 = t23..t20*2^32 */
607     CY_CRYPTO_VU_SUB (base, my_z, my_z, t1);    /* z = z - t23..t20*2^32 */
608     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
609 
610     /* S3 (b) -- t23..t21 */
611     CY_CRYPTO_VU_LSR (base, t1, t1, sh64);      /* t1 = t23..t21 */
612     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t23..t21 */
613     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
614     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
615 
616     /* D1 (b) -- t23 */
617     CY_CRYPTO_VU_LSR (base, t2, t1, sh64);      /* t2 = t23 */
618     CY_CRYPTO_VU_SUB (base, my_z, my_z, t2);    /* z = z - t23 */
619     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
620 
621     /* S6 (a) -- t23..t21*2^96 */
622     CY_CRYPTO_VU_LSL (base, t1, t1, sh96);      /* t1 = t23..t21*2^96 */
623     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t23..t21*2^96 */
624     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
625     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
626 
627     /* 2*S1 -- 2*t23..t21*2^128 */
628     CY_CRYPTO_VU_LSL (base, t1, t1, sh32);      /* t1 = t23..t21*2^128 */
629     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t23..t21*2^128 */
630     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
631     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
632     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t20..t12*2^128 */
633     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
634     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
635 
636     /* S4 (c) -- t23*2^32 */
637     CY_CRYPTO_VU_LSL (base, t1, t2, sh32);      /* t1 = t23*2^32 */
638     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t23*2^32 */
639     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
640     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
641 
642     /* D3 (b) -- t23*2^96 */
643     CY_CRYPTO_VU_LSL (base, t1, t1, sh64);      /* t1 = t23*2^96 */
644     CY_CRYPTO_VU_SUB (base, my_z, my_z, t1);    /* z = z - t23*2^96 */
645     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
646 
647     /* D3 (a) -- t23*2^128 */
648     CY_CRYPTO_VU_LSL (base, t1, t1, sh32);      /* t1 = t23*2^128 */
649     CY_CRYPTO_VU_SUB (base, my_z, my_z, t1);    /* z = z - t23*2^128 */
650     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
651 
652     /* D1 (a) -- t22..t12*2^32 */
653     CY_CRYPTO_VU_LSL (base, t1, t0, sh32);      /* t1 = t22..t12*2^32 */
654     CY_CRYPTO_VU_SUB (base, my_z, my_z, t1);    /* z = z - t22..t12*2^32 */
655     CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P);   /* z = z + p, if C==0 (Carry is clear) */
656 
657     /* S3 (a) -- t20..t12*2^96 */
658     CY_CRYPTO_VU_LSL (base, t1, t1, sh64);      /* t1 = t20..t12*2^96 */
659     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t20..t12*2^96 */
660     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
661     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
662 
663     /* S4 (a) -- t19..t12*2^128 */
664     CY_CRYPTO_VU_LSL (base, t1, t1, sh32);      /* t1 = t19..t12*2^128 */
665     CY_CRYPTO_VU_ADD (base, my_z, my_z, t1);    /* z = z + t19..t12*2^128 */
666     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (z >= VR_P) */
667     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* z = z - p, if C==1 (Carry is set) */
668 
669     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0) | CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2));
670     CY_CRYPTO_VU_POP_REG (base);
671 
672     return CY_CRYPTO_SUCCESS;
673 }
674 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
675 
676 
677 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
678 /*******************************************************************************
679 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P521
680 ****************************************************************************//**
681 *
682 * Curve-specific multiplication modular reduction for P521.
683 * 0 <= a, b < P521
684 * P521 = 2^521 - 1
685 * a*b = T = T1*2^521 + T0
686 * T1 = t1041..t521
687 * T0 = t520..t0
688 * T mod p521 = T0 + T1 mod P521
689 *
690 * \param base
691 * The pointer to a Crypto instance.
692 *
693 * \param z
694 * Result = x mod P = a*b mod P [521 bits]
695 *
696 * \param x
697 * Product = a*b [2*521 bits]
698 *
699 * \return status code. See \ref cy_en_crypto_status_t.
700 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P521(CRYPTO_Type * base,uint32_t z,uint32_t x)701 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x)
702 {
703     uint32_t sh521   = 0u;
704     uint32_t t0      = 1u;
705     uint32_t my_z    = 2u;
706     uint32_t my_x    = 3u;
707     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
708 
709     CY_CRYPTO_VU_PUSH_REG (base);
710 
711     CY_CRYPTO_VU_LD_REG (base, my_z, z);
712     CY_CRYPTO_VU_LD_REG (base, my_x, x);
713 
714     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P521_SIZE); /* 521 */
715     if(CY_CRYPTO_SUCCESS != tmpResult)
716     {
717         return tmpResult;
718     }
719     CY_CRYPTO_VU_SET_REG (base, sh521, 521u, 1u);                 /* sh521  = 521 */
720 
721     CY_CRYPTO_VU_LSR (base, my_z, my_x, sh521);                 /* z = T1 */
722 
723     CY_CRYPTO_VU_ADD (base, my_z, my_z, my_x);                  /* z = T1 + T0 */
724 
725     /* T0 + T1 mod p */
726     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (t2 >= VR_P) */
727     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* t2 = t2 - p, if C==1 (Carry is set) */
728 
729     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0));
730 
731     CY_CRYPTO_VU_POP_REG (base);
732 
733     return CY_CRYPTO_SUCCESS;
734 }
735 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
736 
737 
738 /*******************************************************************************
739 * Function Name: Cy_Crypto_Core_EC_CS_MulRed
740 ****************************************************************************//**
741 *
742 * \param base
743 * The pointer to a Crypto instance.
744 *
745 * \param z
746 * Result.
747 *
748 * \param x
749 * Product.
750 *
751 * \param size
752 * Size.
753 *
754 * \return status code. See \ref cy_en_crypto_status_t.
755 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)756 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size)
757 {
758     (void)size; /* Suppress warning */
759     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
760 
761     switch (eccMode)
762     {
763     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
764         case CY_CRYPTO_ECC_ECP_SECP192R1:
765             tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P192(base, z, x);
766             break;
767     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
768     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
769         case CY_CRYPTO_ECC_ECP_SECP224R1:
770             tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P224(base, z, x);
771             break;
772     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
773     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
774         case CY_CRYPTO_ECC_ECP_SECP256R1:
775             tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P256(base, z, x);
776             break;
777     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
778     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
779         case CY_CRYPTO_ECC_ECP_SECP384R1:
780             tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P384(base, z, x);
781             break;
782     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
783     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
784         case CY_CRYPTO_ECC_ECP_SECP521R1:
785             tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P521(base, z, x);
786             break;
787     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
788         default:
789         /* Unsupported Eliptic Curve ID */
790             break;
791     }
792 
793     return tmpResult;
794 }
795 
796 
797 /**********************************************************************
798 *  Shift-multiply, curve-specific multiplication reduction algorithms
799 **********************************************************************/
800 
801 
802 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
803 /*******************************************************************************
804 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P192
805 ****************************************************************************//**
806 *
807 * Shift-multiply multiplication modular reduction for P192.
808 * a[CURVE_SIZE-1:0] * b[CURVE_SIZE-1:0] mod p[CURVE_SIZE-1:0]
809 *
810 * \param base
811 * The pointer to a Crypto instance.
812 *
813 * \param z
814 * Result = x mod P = a*b mod P [192 bits].
815 *
816 * \param x
817 * Product = a*b [2*192 bits].
818 *
819 *
820 * \return status code. See \ref cy_en_crypto_status_t.
821 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P192(CRYPTO_Type * base,uint32_t z,uint32_t x)822 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x)
823 {
824    /* Setup */
825    uint32_t partial  = 0u;
826    uint32_t hi       = 1u;
827    uint32_t sh64     = 2u;
828    uint32_t sh192    = 3u;
829    uint32_t my_z     = 4u;
830    uint32_t my_x     = 5u;
831    cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
832 
833    CY_CRYPTO_VU_PUSH_REG (base);
834 
835    CY_CRYPTO_VU_LD_REG (base, my_z, z);
836    CY_CRYPTO_VU_LD_REG (base, my_x, x);
837 
838    tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P192_SIZE + 65u);
839    if(CY_CRYPTO_SUCCESS != tmpResult)
840    {
841        return tmpResult;
842    }
843 
844    tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P192_SIZE + 64u);
845    if(CY_CRYPTO_SUCCESS != tmpResult)
846    {
847        return tmpResult;
848    }
849    CY_CRYPTO_VU_SET_REG (base, sh64, 64u, 1u);
850    CY_CRYPTO_VU_SET_REG (base, sh192, 192u, 1u);
851 
852    /* Step 2: 1st round of shift-multiply
853     * (Separate hi and lo (LSR hi>>CURVE_SIZE), multiply hi (LSL hi and add 1) and add shifted hi to lo)
854     * hi * (2^{64} + 1) + lo
855     */
856    CY_CRYPTO_VU_LSR (base, hi, my_x, sh192);    /* hi = prod >> CURVE_SIZE = prod[383:192] */
857    CY_CRYPTO_VU_MOV (base, my_z, my_x);         /* z == lo = prod[191:0] */
858 
859    CY_CRYPTO_VU_ADD (base, partial, hi, my_z);  /* partial = (hi*1) + lo */
860 
861    CY_CRYPTO_VU_LSL (base, hi, hi, sh64);       /* hi = hi << 64 = hi*2^{64} */
862 
863    CY_CRYPTO_VU_ADD (base, partial, partial, hi);   /* partial = hi*(2^{64}+1) + lo */
864 
865    /* Step 3: 2nd round of shift-multiply */
866    CY_CRYPTO_VU_LSR (base, hi, partial, sh192); /* hi = partial >> CURVE_SIZE = partial[383:192] */
867 
868    CY_CRYPTO_VU_ADD (base, my_z, hi, partial);  /* z = (hi*1) + lo (Note: partial == lo, since it will be cut to CURVE_SIZE since z = CURVE_SIZE) */
869 
870    CY_CRYPTO_VU_LSL (base, hi, hi, sh64);       /* hi = hi << 64 = hi*2^{64} */
871 
872    CY_CRYPTO_VU_ADD (base, my_z, my_z, hi);     /* z = hi*(2^{64}+1) + lo */
873 
874    /* Step 4: Final reduction (compare to P-192 and reduce if necessary, based on CARRY flag) */
875    CY_CRYPTO_VU_CMP_SUB (base, my_z, VR_P);     /* C = (z >= VR_P) */
876    CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
877 
878    CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi));
879    CY_CRYPTO_VU_POP_REG (base);
880 
881    return CY_CRYPTO_SUCCESS;
882 }
883 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
884 
885 
886 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
887 /*******************************************************************************
888 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P224
889 ****************************************************************************//**
890 *
891 * Curve-specific multiplication modular reduction for P224.
892 *  0 <= a, b < P224
893 *
894 * \param base
895 * The pointer to a Crypto instance.
896 *
897 * \param z
898 * Result = x mod P = a*b mod P [224 bits].
899 *
900 * \param x
901 * Product = a*b [2*224 bits].
902 *
903 * \return status code. See \ref cy_en_crypto_status_t.
904 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P224(CRYPTO_Type * base,uint32_t z,uint32_t x)905 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x)
906 {
907 
908     /* Setup */
909     uint32_t partial = 0u;
910     uint32_t hi      = 1u;
911     uint32_t sh96    = 2u;
912     uint32_t sh224   = 3u;
913     uint32_t my_z    = 4u;
914     uint32_t my_x    = 5u;
915     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
916 
917     CY_CRYPTO_VU_PUSH_REG (base);
918 
919     CY_CRYPTO_VU_LD_REG (base, my_z, z);
920     CY_CRYPTO_VU_LD_REG (base, my_x, x);
921 
922     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P224_SIZE + 97u);
923     if(CY_CRYPTO_SUCCESS != tmpResult)
924     {
925         return tmpResult;
926     }
927 
928     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P224_SIZE + 96u);
929     if(CY_CRYPTO_SUCCESS != tmpResult)
930     {
931         return tmpResult;
932     }
933 
934     CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u);
935     CY_CRYPTO_VU_SET_REG (base, sh224, 224u, 1u);
936 
937     /* Step 2: 1st round of shift-multiply
938      * (Separate hi and lo (LSR hi>>CURVE_SIZE), multiply hi (LSL hi<<96 and subtract 1) and add shifted hi to lo)
939      * hi * (2^{96} + 1) + lo
940      */
941     CY_CRYPTO_VU_LSR (base, hi, my_x, sh224);       /* hi = prod >> CURVE_SIZE = prod[447:224] */
942     CY_CRYPTO_VU_MOV (base, my_z, my_x);            /* z == lo = prod[223:0] */
943 
944     CY_CRYPTO_VU_SUB (base, partial, my_z, hi);     /* partial = lo - (hi*1) */
945 
946     CY_CRYPTO_VU_LSL (base, hi, hi, sh96);          /* hi = hi << 96 = hi*2^{96} */
947 
948     CY_CRYPTO_VU_ADD (base, partial, partial, hi);  /* partial = hi*(2^{96}-1) + lo */
949 
950     /* Step 3: 2nd round of shift-multiply */
951     CY_CRYPTO_VU_LSR (base, hi, partial, sh224);    /* hi = partial>>CURVE_SIZE = partial[447:224] */
952 
953     CY_CRYPTO_VU_SUB (base, my_z, partial, hi);     /* z = lo - (hi*1) (Note: partial == lo, since it will be cut to CURVE_SIZE since z = CURVE_SIZE) */
954 
955     CY_CRYPTO_VU_LSL (base, hi, hi, sh96);          /* hi = hi<<96 = hi*2^{96} */
956 
957     CY_CRYPTO_VU_ADD (base, my_z, my_z, hi);        /* z = hi*(2^{96}-1) + lo */
958 
959     /* Step 4: Final reduction (compare to P-224 and reduce if necessary, based on CARRY flag) */
960     CY_CRYPTO_VU_CMP_SUB (base, my_z, VR_P);        /* C = (z >= VR_P) */
961     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
962 
963     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi));
964     CY_CRYPTO_VU_POP_REG (base);
965 
966     return CY_CRYPTO_SUCCESS;
967 
968 }
969 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
970 
971 
972 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
973 /*******************************************************************************
974 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P256
975 ****************************************************************************//**
976 *
977 * Shift-multiply modular reduction algorithm.
978 * a*b mod p
979 * 0 <= a, b < P256
980 *
981 * \param base
982 * The pointer to a Crypto instance.
983 *
984 * \param z
985 * Result.
986 *
987 * \param x
988 * Product.
989 *
990 * \return status code. See \ref cy_en_crypto_status_t.
991 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P256(CRYPTO_Type * base,uint32_t z,uint32_t x)992 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x)
993 {
994     /* Pre-computed coefficient for shift-multiply modular reduction for P256 */
995     const uint8_t P256_ShMul_COEFF[] = {
996         0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
997         0x00u, 0x00u, 0x00u, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
998         0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
999         0xFEu, 0xFFu, 0xFFu, 0xFFu
1000     };
1001 
1002     /* Setup */
1003     uint32_t partial = 0u;
1004     uint32_t hi      = 1u;
1005     uint32_t sh256   = 2u;
1006     uint32_t my_z    = 3u;
1007     uint32_t my_x    = 4u;
1008     uint32_t coeff   = 5u;
1009     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1010 
1011     CY_CRYPTO_VU_PUSH_REG (base);
1012 
1013     CY_CRYPTO_VU_LD_REG (base, my_z, z);
1014     CY_CRYPTO_VU_LD_REG (base, my_x, x);
1015 
1016     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, coeff, 224u);
1017     if(CY_CRYPTO_SUCCESS != tmpResult)
1018     {
1019         return tmpResult;
1020     }
1021 
1022     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P256_SIZE + 224u);
1023     if(CY_CRYPTO_SUCCESS != tmpResult)
1024     {
1025         return tmpResult;
1026     }
1027 
1028     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P256_SIZE);
1029     if(CY_CRYPTO_SUCCESS != tmpResult)
1030     {
1031         return tmpResult;
1032     }
1033 
1034     CY_CRYPTO_VU_SET_REG (base, sh256, 256u, 1u);
1035 
1036     Cy_Crypto_Core_Vu_SetMemValue (base, coeff, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(P256_ShMul_COEFF), 224u);
1037 
1038     /* Step 2: 1st round of shift-multiply:
1039      * - separate hi and lo (LSR hi >> CURVE_SIZE),
1040      * - multiply hi * coeff,
1041      * - add hi * coeff + lo
1042      */
1043     CY_CRYPTO_VU_LSR  (base, hi, my_x, sh256);           /* hi = prod >> CURVE_SIZE = prod[511:256] */
1044     CY_CRYPTO_VU_MOV  (base, my_z, my_x);                /* z == lo = prod[255:0] */
1045 
1046     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1047     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* partial = hi * coeff + lo */
1048 
1049     /* Step 3: 2nd round of shift-multiply */
1050     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1051     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1052 
1053     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1054     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* z = hi * coeff + lo  */
1055 
1056     /* Step 4: 3rd round of shift-multiply */
1057     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1058     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1059 
1060     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1061     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* z = hi * coeff + lo  */
1062 
1063     /* Step 5: 4th round of shift-multiply */
1064     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1065     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1066 
1067     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1068     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* z = hi * coeff + lo  */
1069 
1070     /* Step 6: 5th round of shift-multiply */
1071     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1072     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1073 
1074     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1075     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* z = hi * coeff + lo  */
1076 
1077     /* Step 7: 6th round of shift-multiply */
1078     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1079     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1080 
1081     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1082     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* z = hi * coeff + lo  */
1083 
1084     /* Step 8: 7th round of shift-multiply */
1085     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1086     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1087 
1088     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1089     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* z = hi * coeff + lo  */
1090 
1091     /* Step 9: 8th round of shift-multiply */
1092     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1093     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1094 
1095     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1096     CY_CRYPTO_VU_ADD  (base, partial, partial, my_z);    /* z = hi * coeff + lo  */
1097 
1098     /* Step 10: 9th round of shift-multiply */
1099     CY_CRYPTO_VU_LSR  (base, hi, partial, sh256);        /* hi = partial >> CURVE_SIZE = partial[511:256] */
1100     CY_CRYPTO_VU_MOV  (base, my_z, partial);             /* z == lo = partial[255:0] */
1101 
1102     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);        /* partial = hi * coeff */
1103     CY_CRYPTO_VU_ADD  (base, my_z, partial, my_z);       /* z = hi * coeff + lo  */
1104 
1105     /* Step 11: Final reduction (compare to P-256 and reduce if necessary, based on CARRY flag) */
1106     CY_CRYPTO_VU_CMP_SUB  (base, my_z, VR_P);            /* C = (z >= VR_P) */
1107     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
1108 
1109     CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi) | CY_CRYPTO_VU_REG_BIT(coeff));
1110     CY_CRYPTO_VU_POP_REG(base);
1111 
1112     return CY_CRYPTO_SUCCESS;
1113 
1114 }
1115 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
1116 
1117 
1118 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
1119 /*******************************************************************************
1120 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P384
1121 ****************************************************************************//**
1122 *
1123 * Shift-multiply modular reduction algorithm.
1124 * a*b mod p
1125 * 0 <= a, b < P384
1126 *
1127 * \param base
1128 * The pointer to a Crypto instance.
1129 *
1130 * \param z
1131 * Result.
1132 *
1133 * \param x
1134 * Product.
1135 *
1136 * \return status code. See \ref cy_en_crypto_status_t.
1137 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P384(CRYPTO_Type * base,uint32_t z,uint32_t x)1138 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x)
1139 {
1140     /* Pre-computed coefficient for shift-multiply modular reduction for P384 */
1141     const uint8_t P384_ShMul_COEFF[] = {
1142         0x01u, 0x00u, 0x00u, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
1143         0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u,
1144         0x01u
1145     };
1146 
1147     /* Setup */
1148     uint32_t partial = 0u;
1149     uint32_t hi      = 1u;
1150     uint32_t sh96    = 2u;
1151     uint32_t sh384   = 3u;
1152     uint32_t my_z    = 4u;
1153     uint32_t my_x    = 5u;
1154     uint32_t coeff   = 6u;
1155     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1156 
1157     CY_CRYPTO_VU_PUSH_REG (base);
1158 
1159     CY_CRYPTO_VU_LD_REG (base, my_z, z);
1160     CY_CRYPTO_VU_LD_REG (base, my_x, x);
1161 
1162     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P384_SIZE + 129u);
1163     if(CY_CRYPTO_SUCCESS != tmpResult)
1164     {
1165         return tmpResult;
1166     }
1167 
1168     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P384_SIZE + 96u);
1169     if(CY_CRYPTO_SUCCESS != tmpResult)
1170     {
1171         return tmpResult;
1172     }
1173 
1174     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, coeff, 129u);
1175     if(CY_CRYPTO_SUCCESS != tmpResult)
1176     {
1177         return tmpResult;
1178     }
1179 
1180     CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u);
1181     CY_CRYPTO_VU_SET_REG (base, sh384, 384u, 1u);
1182 
1183     Cy_Crypto_Core_Vu_SetMemValue (base, coeff, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(P384_ShMul_COEFF), 129u);
1184 
1185     /* Step 2: 1st round of shift-multiply
1186     * (Separate hi and lo (LSR hi>>CURVE_SIZE), multiply hi*c and add hi*coeff + lo)
1187     * hi*coeff + lo
1188     */
1189     CY_CRYPTO_VU_LSR (base, hi, my_x, sh384);           /* hi = prod >> CURVE_SIZE = prod[767:384] */
1190     CY_CRYPTO_VU_MOV (base, my_z, my_x);                /* z == lo = prod[383:0] */
1191 
1192     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);       /* partial = hi*coeff */
1193     CY_CRYPTO_VU_ADD (base, partial, partial, my_z);    /* partial = hi*coeff + lo */
1194 
1195     /* Step 3: 2nd round of shift-multiply */
1196     CY_CRYPTO_VU_LSR (base, hi, partial, sh384);        /* hi = partial>>CURVE_SIZE = partial[767:384] */
1197     CY_CRYPTO_VU_MOV (base, my_z, partial);             /* z == lo = partial[383:0] */
1198 
1199     CY_CRYPTO_VU_UMUL (base, partial, hi, coeff);       /* partial = hi*coeff */
1200     CY_CRYPTO_VU_ADD (base, my_z, partial, my_z);       /* z = hi*coeff + lo */
1201 
1202     /* Step 4: Final reduction (compare to P-384 and reduce if necessary, based on CARRY flag) */
1203     CY_CRYPTO_VU_CMP_SUB  (base, my_z, VR_P);           /* C = (z >= VR_P) */
1204     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
1205 
1206     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi) | CY_CRYPTO_VU_REG_BIT(coeff));
1207     CY_CRYPTO_VU_POP_REG (base);
1208 
1209    return CY_CRYPTO_SUCCESS;
1210 
1211 }
1212 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
1213 
1214 
1215 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
1216 /*******************************************************************************
1217 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P521
1218 ****************************************************************************//**
1219 *
1220 * Curve-specific multiplication modular reduction for P521; equivalent to shift-multiply method for P521.
1221 * 0 <= a, b < P521
1222 * P521 = 2^521 - 1
1223 * a*b = T = T1*2^521 + T0
1224 * T1 = t1041..t521
1225 * T0 = t520..t0
1226 * T mod p521 = T0 + T1 mod P521
1227 *
1228 * \param base
1229 * The pointer to a Crypto instance.
1230 *
1231 * \param z
1232 * Result = x mod P = a*b mod P [521 bits].
1233 *
1234 * \param x
1235 * Product = a*b [2*521 bits].
1236 *
1237 * \return status code. See \ref cy_en_crypto_status_t.
1238 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P521(CRYPTO_Type * base,uint32_t z,uint32_t x)1239 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x)
1240 {
1241     uint32_t sh521   = 0u;
1242     uint32_t t0      = 1u;
1243     uint32_t my_z    = 2u;
1244     uint32_t my_x    = 3u;
1245     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1246 
1247     CY_CRYPTO_VU_PUSH_REG (base);
1248 
1249     CY_CRYPTO_VU_LD_REG (base, my_z, z);
1250     CY_CRYPTO_VU_LD_REG (base, my_x, x);
1251 
1252     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P521_SIZE);     /* 521 */
1253     if(CY_CRYPTO_SUCCESS != tmpResult)
1254     {
1255         return tmpResult;
1256     }
1257     CY_CRYPTO_VU_SET_REG (base, sh521, 521u, 1u);       /* sh521  = 521 */
1258 
1259     CY_CRYPTO_VU_LSR (base, my_z, my_x, sh521);         /* z = T1 */
1260 
1261     CY_CRYPTO_VU_ADD (base, my_z, my_z, my_x);          /* z = T1 + T0 */
1262 
1263     /* T0 + T1 mod p */
1264     CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P);     /* C = (t2 >= VR_P) */
1265     CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);   /* t2 = t2 - p, if C==1 (Carry is set) */
1266 
1267     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0));
1268     CY_CRYPTO_VU_POP_REG (base);
1269 
1270     return CY_CRYPTO_SUCCESS;
1271 }
1272 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
1273 
1274 
1275 /*******************************************************************************
1276 * Function Name: Cy_Crypto_Core_EC_SM_MulRed
1277 ****************************************************************************//**
1278 *
1279 *
1280 *
1281 * \param base
1282 * The pointer to a Crypto instance.
1283 *
1284 * \param z
1285 * Result.
1286 *
1287 * \param x
1288 * Product.
1289 *
1290 * \param size
1291 * Size.
1292 *
1293 * \return status code. See \ref cy_en_crypto_status_t.
1294 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)1295 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size)
1296 {
1297     (void)size; /* Suppress warning */
1298     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1299 
1300     switch (eccMode)
1301     {
1302     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
1303         case CY_CRYPTO_ECC_ECP_SECP192R1:
1304             tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P192(base, z, x);
1305             break;
1306     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
1307     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
1308         case CY_CRYPTO_ECC_ECP_SECP224R1:
1309             tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P224(base, z, x);
1310             break;
1311     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
1312     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
1313         case CY_CRYPTO_ECC_ECP_SECP256R1:
1314             tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P256(base, z, x);
1315             break;
1316     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
1317     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
1318         case CY_CRYPTO_ECC_ECP_SECP384R1:
1319             tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P384(base, z, x);
1320             break;
1321     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
1322     #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
1323         case CY_CRYPTO_ECC_ECP_SECP521R1:
1324             tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P521(base, z, x);
1325             break;
1326     #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
1327         default:
1328         /* Unsupported Eliptic Curve ID */
1329             break;
1330     }
1331 
1332     return tmpResult;
1333 
1334 }
1335 
1336 
1337 /***************************************************************
1338 *           Generic Barrett modular reduction
1339 ***************************************************************/
1340 
1341 
1342 /*******************************************************************************
1343 * Function Name: Cy_Crypto_Core_EC_Bar_MulRed
1344 ****************************************************************************//**
1345 *
1346 * Barrett multiplication modular reduction.
1347 * t[b-1:0] = z_double >> size
1348 * t = t * VR_BARRETT
1349 * t = t + ((z_double >> size) << size)  - for leading '1' Barrett bit.
1350 * t = t >> size
1351 * t = t * mod                           - r2 (not reduced)
1352 * u = z_double - t                      - r = r1 - r2 (not reduced)
1353 *
1354 * u = IF (u >= mod) u = u - mod         - reduce r using mod
1355 * u = IF (u >= mod) u = u - mod
1356 *
1357 * z = a_double % mod
1358 *
1359 * Leaf function.
1360 *
1361 * \param base
1362 * The pointer to a Crypto instance.
1363 *
1364 * \param z
1365 * Register index for Barrett reduced value.
1366 *
1367 * \param x
1368 * Register index for non reduced value.
1369 *
1370 * \param size
1371 * Bit size.
1372 *
1373 * \return status code. See \ref cy_en_crypto_status_t.
1374 *******************************************************************************/
Cy_Crypto_Core_EC_Bar_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)1375 cy_en_crypto_status_t Cy_Crypto_Core_EC_Bar_MulRed(CRYPTO_Type *base,
1376     uint32_t z,
1377     uint32_t x,
1378     uint32_t size)
1379 {
1380 
1381     uint32_t sh          = 0u;
1382     uint32_t t1          = 1u;
1383     uint32_t t1_plus2    = 1u;
1384     uint32_t t2_plus2    = 0u;
1385     uint32_t t_double    = 2u;
1386     uint32_t z_double    = 3u;
1387     uint32_t my_z        = 4u;
1388     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1389 
1390     CY_CRYPTO_VU_PUSH_REG (base);
1391 
1392     CY_CRYPTO_VU_LD_REG (base, my_z, z);
1393     CY_CRYPTO_VU_LD_REG (base, z_double, x);
1394 
1395     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t_double, 2u * size);
1396     if(CY_CRYPTO_SUCCESS != tmpResult)
1397     {
1398         return tmpResult;
1399     }
1400 
1401     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
1402     if(CY_CRYPTO_SUCCESS != tmpResult)
1403     {
1404         return tmpResult;
1405     }
1406     CY_CRYPTO_VU_SET_REG (base, sh, size, 1u);              /* sh = k (k \equiv size) */
1407     CY_CRYPTO_VU_LSR (base, my_z, z_double, sh);            /* a/b^{k} (q1*b) */
1408 
1409     CY_CRYPTO_VU_UMUL (base, t_double, my_z, VR_BARRETT);   /* a/b^{k}*VR_BARRETT (q2*b) */
1410     CY_CRYPTO_VU_LSR (base, t1, t_double, sh);              /* q2*b/b^{k} = q2/b^{k-1} */
1411 
1412     CY_CRYPTO_VU_UMUL (base, t_double, t1, VR_P);
1413 
1414     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1));
1415 
1416     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1_plus2, size + 2u);
1417     if(CY_CRYPTO_SUCCESS != tmpResult)
1418     {
1419         return tmpResult;
1420     }
1421 
1422     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2_plus2, size + 2u);
1423     if(CY_CRYPTO_SUCCESS != tmpResult)
1424     {
1425         return tmpResult;
1426     }
1427     CY_CRYPTO_VU_SUB (base, t2_plus2, z_double, t_double);
1428 
1429     CY_CRYPTO_VU_SUB (base, t1_plus2, t2_plus2, VR_P);
1430     CY_CRYPTO_VU_COND_SWAP_REG (base, CY_CRYPTO_VU_COND_CC, t1_plus2, t2_plus2);
1431 
1432     CY_CRYPTO_VU_SUB (base, t2_plus2, t1_plus2, VR_P);
1433     CY_CRYPTO_VU_COND_MOV (base, CY_CRYPTO_VU_COND_CC, my_z, t1_plus2);
1434     CY_CRYPTO_VU_COND_MOV (base, CY_CRYPTO_VU_COND_CS, my_z, t2_plus2);
1435 
1436     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t2_plus2) |
1437                                  CY_CRYPTO_VU_REG_BIT(t1_plus2) |
1438                                  CY_CRYPTO_VU_REG_BIT(t_double));
1439     CY_CRYPTO_VU_POP_REG (base);
1440 
1441     return CY_CRYPTO_SUCCESS;
1442 }
1443 
1444 
1445 /***************************************************************
1446 *       Multiplication reduction algorithm select
1447 ***************************************************************/
1448 
1449 
1450 /*******************************************************************************
1451 * Function Name: Cy_Crypto_Core_EC_MulRed
1452 ****************************************************************************//**
1453 *
1454 * \param base
1455 * The pointer to a Crypto instance.
1456 *
1457 * \param z
1458 * Result = x mod P = a*b mod P [224 bits].
1459 *
1460 * \param x
1461 * Product = a*b [2*224 bits].
1462 *
1463 * \param size
1464 * Bit size.
1465 *
1466 * \return status code. See \ref cy_en_crypto_status_t.
1467 *******************************************************************************/
Cy_Crypto_Core_EC_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)1468 static cy_en_crypto_status_t Cy_Crypto_Core_EC_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size)
1469 {
1470     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1471 
1472     switch (mul_red_alg_select)
1473     {
1474         case CY_CRYPTO_NIST_P_CURVE_SPECIFIC_RED_ALG:
1475                 /* Curve-specific multiplication reduction algorithms */
1476                 tmpResult = Cy_Crypto_Core_EC_CS_MulRed(base, z, x, size);
1477             break;
1478         case CY_CRYPTO_NIST_P_SHIFT_MUL_RED_ALG:
1479                 /* Shift-multiply, curve-specific multiplication reduction algorithms */
1480                 tmpResult = Cy_Crypto_Core_EC_SM_MulRed(base, z, x, size);
1481             break;
1482         default:
1483                 /* Generic Barrett modular reduction */
1484                 tmpResult = Cy_Crypto_Core_EC_Bar_MulRed(base, z, x, size);
1485             break;
1486     }
1487 
1488     return tmpResult;
1489 }
1490 
1491 
1492 /*******************************************************************************
1493 * Function Name: Cy_Crypto_Core_EC_MulMod
1494 ****************************************************************************//**
1495 *
1496 * Modular multiplication in GF(VR_P).
1497 * Leaf function.
1498 *
1499 * \param base
1500 * The pointer to a Crypto instance.
1501 *
1502 * \param z
1503 * Result = a * b % mod. Register index for product value.
1504 *
1505 * \param a
1506 * Register index for multiplicand value.
1507 *
1508 * \param b
1509 * Register index for multiplier value.
1510 *
1511 * \param size
1512 * Bit size.
1513 *
1514 * \return status code. See \ref cy_en_crypto_status_t.
1515 *******************************************************************************/
Cy_Crypto_Core_EC_MulMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b,uint32_t size)1516 cy_en_crypto_status_t Cy_Crypto_Core_EC_MulMod( CRYPTO_Type *base,
1517     uint32_t z,
1518     uint32_t a,
1519     uint32_t b,
1520     uint32_t size)
1521 {
1522     uint32_t ab_double       = 0u;
1523     uint32_t my_z            = 1u;
1524     uint32_t my_a            = 2u;
1525     uint32_t my_b            = 3u;
1526     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1527 
1528     CY_CRYPTO_VU_PUSH_REG (base);
1529 
1530     CY_CRYPTO_VU_LD_REG(base, my_z, z);
1531     CY_CRYPTO_VU_LD_REG(base, my_a, a);
1532     CY_CRYPTO_VU_LD_REG(base, my_b, b);
1533 
1534     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, ab_double, 2u * size);
1535     if(CY_CRYPTO_SUCCESS != tmpResult)
1536     {
1537         return tmpResult;
1538     }
1539     CY_CRYPTO_VU_UMUL (base, ab_double, my_a, my_b);
1540     Cy_Crypto_Core_Vu_WaitForComplete(base);
1541 
1542     /* Modular Reduction: Barrett reduction or curve-specific or shift-multiply */
1543     tmpResult = Cy_Crypto_Core_EC_MulRed(base, my_z, ab_double, size);
1544     if(CY_CRYPTO_SUCCESS != tmpResult)
1545     {
1546         return tmpResult;
1547     }
1548     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(ab_double));
1549 
1550     CY_CRYPTO_VU_POP_REG (base);
1551 
1552     return CY_CRYPTO_SUCCESS;
1553 }
1554 
1555 
1556 /*******************************************************************************
1557 * Function Name: Cy_Crypto_Core_EC_AddMod
1558 ****************************************************************************//**
1559 *
1560 * Modular addition in GF(VR_P).
1561 *
1562 * \param base
1563 * The pointer to a Crypto instance.
1564 *
1565 * \param z
1566 * Result = a + b % mod. Register index for sum value
1567 *
1568 * \param a
1569 * Register index for augend a value.
1570 *
1571 * \param b
1572 * Register index for addend b value.
1573 *
1574 *******************************************************************************/
Cy_Crypto_Core_EC_AddMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b)1575 void Cy_Crypto_Core_EC_AddMod( CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t b)
1576 {
1577    CY_CRYPTO_VU_ADD (base, z, a, b);                                /* C = (sum >= 2^n) */
1578    CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, z, VR_P); /* C = (sum >= mod) */
1579    CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, z, z, VR_P);
1580 }
1581 
1582 
1583 /*******************************************************************************
1584 * Function Name: Cy_Crypto_Core_EC_SubMod
1585 ****************************************************************************//**
1586 *
1587 * Modular subtraction in GF(VR_P).
1588 *
1589 * \param base
1590 * The pointer to a Crypto instance.
1591 *
1592 * \param z
1593 * Result = a - b % mod. Register index for difference value.
1594 *
1595 * \param a
1596 * Register index for minuend a value.
1597 *
1598 * \param b
1599 * RRegister index for subtrahend b value.
1600 *
1601 *******************************************************************************/
Cy_Crypto_Core_EC_SubMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b)1602 void Cy_Crypto_Core_EC_SubMod( CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t b)
1603 {
1604    CY_CRYPTO_VU_SUB (base, z, a, b);       /* C = (a >= b) */
1605    CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, z, z, VR_P);
1606 }
1607 
1608 
1609 /*******************************************************************************
1610 * Function Name: Cy_Crypto_Core_EC_HalfMod
1611 ****************************************************************************//**
1612 *
1613 * Modular halving in GF(VR_P).
1614 * Leaf function.
1615 *
1616 * \param base
1617 * The pointer to a Crypto instance.
1618 *
1619 * \param z
1620 * Result = a / 2 % mod. Register index for result value.
1621 *
1622 * \param a
1623 * Register index for value to be halved.
1624 *
1625 *******************************************************************************/
Cy_Crypto_Core_EC_HalfMod(CRYPTO_Type * base,uint32_t z,uint32_t a)1626 void Cy_Crypto_Core_EC_HalfMod( CRYPTO_Type *base, uint32_t z, uint32_t a)
1627 {
1628    CY_CRYPTO_VU_TST (base, a);
1629    CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_ODD, a, a, VR_P);
1630    CY_CRYPTO_VU_LSR1_WITH_CARRY (base, z, a);
1631 }
1632 
1633 
1634 /*******************************************************************************
1635 * Function Name: Cy_Crypto_Core_EC_SquareMod
1636 ****************************************************************************//**
1637 *
1638 * Modular squaring in GF(VR_P).
1639 *
1640 * \param base
1641 * The pointer to a Crypto instance.
1642 *
1643 * \param z
1644 * Result = a * a % mod. Register index for product value.
1645 *
1646 * \param a
1647 * Register index for multiplicand and multiplier value.
1648 *
1649 * \param size
1650 * Bit size.
1651 *
1652 * \return status code. See \ref cy_en_crypto_status_t.
1653 *******************************************************************************/
Cy_Crypto_Core_EC_SquareMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t size)1654 cy_en_crypto_status_t Cy_Crypto_Core_EC_SquareMod( CRYPTO_Type *base,
1655     uint32_t z,
1656     uint32_t a,
1657     uint32_t size)
1658 {
1659     return Cy_Crypto_Core_EC_MulMod( base, z, a, a, size);
1660 }
1661 
1662 
1663 /*******************************************************************************
1664 * Function Name: Cy_Crypto_Core_EC_DivMod
1665 ****************************************************************************//**
1666 *
1667 * Modular division in GF(VR_P).
1668 * This algorithm works when "dividend" and "divisor" are relatively prime,
1669 * Reference: "From Euclid's GCD to Montgomery Multiplication to the Great Divide",
1670 * S.C. Schantz
1671 *
1672 * \param base
1673 * The pointer to a Crypto instance.
1674 *
1675 * \param z
1676 * Result = a / b % mod. Register index for quotient value.
1677 *
1678 * \param a
1679 * Register index for dividend value.
1680 *
1681 * \param b
1682 * Register index for divisor value.
1683 *
1684 * \param size
1685 * Bit size.
1686 *
1687 * \return status code. See \ref cy_en_crypto_status_t.
1688 *******************************************************************************/
Cy_Crypto_Core_EC_DivMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b,uint32_t size)1689 cy_en_crypto_status_t Cy_Crypto_Core_EC_DivMod( CRYPTO_Type *base,
1690     uint32_t z,
1691     uint32_t a,
1692     uint32_t b,
1693     uint32_t size)
1694 {
1695     uint32_t my_dividend = 7u;
1696     uint32_t my_divisor  = 8u;
1697     uint32_t my_a        = 9u;
1698     uint32_t my_b        = 10u;
1699     uint32_t my_u        = 11u;
1700     uint32_t my_v        = 12u;
1701     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1702 
1703     uint32_t zero;
1704     uint32_t carry;
1705     uint32_t a_even;
1706     uint32_t b_even;
1707 
1708     uint32_t status0;
1709     uint32_t status1;
1710     uint32_t status2;
1711 
1712     CY_CRYPTO_VU_PUSH_REG (base);
1713 
1714     CY_CRYPTO_VU_LD_REG(base, my_dividend, a);
1715     CY_CRYPTO_VU_LD_REG(base, my_divisor, b);
1716     CY_CRYPTO_VU_LD_REG(base, my_u, z);
1717 
1718     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_a, size);
1719     if(CY_CRYPTO_SUCCESS != tmpResult)
1720     {
1721         return tmpResult;
1722     }
1723 
1724     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_b, size);
1725     if(CY_CRYPTO_SUCCESS != tmpResult)
1726     {
1727         return tmpResult;
1728     }
1729 
1730     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_v, size);
1731     if(CY_CRYPTO_SUCCESS != tmpResult)
1732     {
1733         return tmpResult;
1734     }
1735 
1736     CY_CRYPTO_VU_MOV (base, my_a, my_divisor);
1737     CY_CRYPTO_VU_MOV (base, my_b, VR_P);
1738     CY_CRYPTO_VU_MOV (base, my_u, my_dividend);
1739 
1740     CY_CRYPTO_VU_SET_TO_ZERO (base, my_v);
1741 
1742     while (true)
1743     {
1744         CY_CRYPTO_VU_CMP_SUB (base, my_a, my_b);
1745         status0 = Cy_Crypto_Core_Vu_StatusRead(base);
1746 
1747         CY_CRYPTO_VU_TST (base, my_a);
1748         status1 = Cy_Crypto_Core_Vu_StatusRead(base);
1749 
1750         CY_CRYPTO_VU_TST (base, my_b);
1751         status2 = Cy_Crypto_Core_Vu_StatusRead(base);
1752 
1753         zero    = status0 & CY_CRYPTO_VU_STATUS_ZERO_BIT;  /* a == b */
1754         carry   = status0 & CY_CRYPTO_VU_STATUS_CARRY_BIT; /* a >= b */
1755         a_even  = status1 & CY_CRYPTO_VU_STATUS_EVEN_BIT;
1756         b_even  = status2 & CY_CRYPTO_VU_STATUS_EVEN_BIT;
1757 
1758         if (0u != zero)
1759         {
1760             break;
1761         }
1762 
1763         if (0u != a_even)
1764         {
1765             CY_CRYPTO_VU_LSR1 (base, my_a, my_a);
1766             Cy_Crypto_Core_EC_HalfMod( base, my_u, my_u);
1767         }
1768         else if (0u != b_even)
1769         {
1770             CY_CRYPTO_VU_LSR1 (base, my_b, my_b);
1771             Cy_Crypto_Core_EC_HalfMod( base, my_v, my_v);
1772         }
1773         else if (0u != carry)
1774         { /* (a >= b) */
1775             CY_CRYPTO_VU_SUB  (base, my_a, my_a, my_b);
1776             CY_CRYPTO_VU_LSR1 (base, my_a, my_a);
1777 
1778             Cy_Crypto_Core_EC_SubMod(  base, my_u, my_u, my_v);
1779             Cy_Crypto_Core_EC_HalfMod( base, my_u, my_u);
1780         }
1781         else
1782         {
1783             CY_CRYPTO_VU_SUB  (base, my_b, my_b, my_a);
1784             CY_CRYPTO_VU_LSR1 (base, my_b, my_b);
1785 
1786             Cy_Crypto_Core_EC_SubMod(  base, my_v, my_v, my_u);
1787             Cy_Crypto_Core_EC_HalfMod( base, my_v, my_v);
1788         }
1789     }
1790 
1791     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(my_a) | CY_CRYPTO_VU_REG_BIT(my_b) | CY_CRYPTO_VU_REG_BIT(my_v));
1792 
1793     CY_CRYPTO_VU_POP_REG (base);
1794 
1795     return CY_CRYPTO_SUCCESS;
1796 }
1797 
1798 
1799 /*******************************************************************************
1800 * Function Name: Cy_Crypto_Core_JacobianTransform
1801 ****************************************************************************//**
1802 *
1803 * Transformation from affine coordinates to Jacobian projective coordinates in GF(VR_P).
1804 *
1805 * \param base
1806 * The pointer to a Crypto instance.
1807 *
1808 * \param s_x
1809 * Register index for affine X coordinate and Jacobian projective X coordinate.
1810 *
1811 * \param s_y
1812 * Register index for affine Y coordinate and Jacobian projective Y coordinate.
1813 *
1814 * \param s_z
1815 * Register index for Jacobian projective Z coordinate.
1816 *
1817 *******************************************************************************/
Cy_Crypto_Core_JacobianTransform(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z)1818 void Cy_Crypto_Core_JacobianTransform(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t s_z)
1819 {
1820     (void)s_x; /* Suppress warning */
1821     (void)s_y; /* Suppress warning */
1822     CY_CRYPTO_VU_SET_TO_ONE (base, s_z);
1823 }
1824 
1825 
1826 /*******************************************************************************
1827 * Function Name: Cy_Crypto_Core_JacobianInvTransform
1828 ****************************************************************************//**
1829 *
1830 * Transformation from Jacobian projective coordinates to affine coordinates in GF(VR_P).
1831 * (s_x, s_y, s_z) -> (p_x, p_y), where p_x = s_x/s_z^2, p_y = s_y/s_z^3
1832 *
1833 * \param base
1834 * The pointer to a Crypto instance.
1835 *
1836 * \param s_x
1837 * Register index for affine X coordinate and Jacobian projective X coordinate.
1838 *
1839 * \param s_y
1840 * Register index for affine Y coordinate and Jacobian projective Y coordinate.
1841 *
1842 * \param s_z
1843 * Register index for Jacobian projective Z coordinate.
1844 *
1845 * \param size
1846 * Bit size.
1847 *
1848 * \return status code. See \ref cy_en_crypto_status_t.
1849 *******************************************************************************/
Cy_Crypto_Core_JacobianInvTransform(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t size)1850 cy_en_crypto_status_t Cy_Crypto_Core_JacobianInvTransform(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t s_z, uint32_t size)
1851 {
1852 
1853     uint32_t t1     = 7u;
1854     uint32_t t2     = 8u;
1855     uint32_t t3     = 9u;
1856     uint32_t my_s_x = 10u;
1857     uint32_t my_s_y = 11u;
1858     uint32_t my_s_z = 12u;
1859     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1860 
1861     CY_CRYPTO_VU_PUSH_REG (base);
1862 
1863     CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
1864     CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
1865     CY_CRYPTO_VU_LD_REG(base, my_s_z, s_z);
1866 
1867     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
1868     if(CY_CRYPTO_SUCCESS != tmpResult)
1869     {
1870         return tmpResult;
1871     }
1872 
1873     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, size);
1874     if(CY_CRYPTO_SUCCESS != tmpResult)
1875     {
1876         return tmpResult;
1877     }
1878 
1879     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, size);
1880     if(CY_CRYPTO_SUCCESS != tmpResult)
1881     {
1882         return tmpResult;
1883     }
1884 
1885     CY_CRYPTO_VU_SET_TO_ONE (base, t1);                     /* t1 = 1 */
1886 
1887     tmpResult = Cy_Crypto_Core_EC_DivMod( base, t2, t1, my_s_z, size);  /* t2 = 1/Z */
1888     if(CY_CRYPTO_SUCCESS != tmpResult)
1889     {
1890         return tmpResult;
1891     }
1892 
1893     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t1, t2, size);       /* t1 = 1/Z^2 */
1894     if(CY_CRYPTO_SUCCESS != tmpResult)
1895     {
1896         return tmpResult;
1897     }
1898 
1899     tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_x, my_s_x, t1, size);  /* my_s_x = X/Z^2 */
1900     if(CY_CRYPTO_SUCCESS != tmpResult)
1901     {
1902         return tmpResult;
1903     }
1904 
1905     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t3, my_s_y, t1, size);  /* t3 = Y/Z^2 */
1906     if(CY_CRYPTO_SUCCESS != tmpResult)
1907     {
1908         return tmpResult;
1909     }
1910 
1911     tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_y, t3, t2, size);  /* my_s_y = Y/Z^3 */
1912     if(CY_CRYPTO_SUCCESS != tmpResult)
1913     {
1914         return tmpResult;
1915     }
1916 
1917     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2) | CY_CRYPTO_VU_REG_BIT(t3));
1918 
1919     CY_CRYPTO_VU_POP_REG (base);
1920 
1921     return CY_CRYPTO_SUCCESS;
1922 }
1923 
1924 
1925 /*******************************************************************************
1926 * Function Name: Cy_Crypto_Core_JacobianEcAdd
1927 ****************************************************************************//**
1928 *
1929 * Elliptic curve point addition on mixed Jacobian projective (s) / affine (t) coordinates in GF(VR_P).
1930 * Reference: "fast and regular algorithms for scalar multiplication over elliptic curves", M. Rivain.
1931 * Upper case register variables refer to Jacobian projective coordinate values.
1932 * Lower case register variables refer to affine coordinate values.
1933 *
1934 * \param base
1935 * The pointer to a Crypto instance.
1936 *
1937 * \param s_x
1938 * Register index for Jacobian projective X coordinate.
1939 *
1940 * \param s_y
1941 * Register index for Jacobian projective Y coordinate.
1942 *
1943 * \param s_z
1944 * Register index for Jacobian projective Z coordinate.
1945 *
1946 * \param t_x
1947 * Register index for affine X coordinate.
1948 *
1949 * \param t_y
1950 * Register index for affine Y coordinate.
1951 *
1952 * \param size
1953 * Bit size.
1954 *
1955 * \return status code. See \ref cy_en_crypto_status_t.
1956 *******************************************************************************/
Cy_Crypto_Core_JacobianEcAdd(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t t_x,uint32_t t_y,uint32_t size)1957 cy_en_crypto_status_t Cy_Crypto_Core_JacobianEcAdd(CRYPTO_Type *base,
1958     uint32_t s_x,
1959     uint32_t s_y,
1960     uint32_t s_z,
1961     uint32_t t_x,
1962     uint32_t t_y,
1963     uint32_t size
1964 )
1965 {
1966 
1967     uint32_t t6     = 4u;
1968     uint32_t t7     = 5u;
1969     uint32_t t8     = 6u;
1970     uint32_t t9     = 7u;
1971     uint32_t my_s_x = 8u;
1972     uint32_t my_s_y = 9u;
1973     uint32_t my_s_z = 10u;
1974     uint32_t my_t_x = 11u;
1975     uint32_t my_t_y = 12u;
1976     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1977 
1978     CY_CRYPTO_VU_PUSH_REG (base);
1979 
1980     CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
1981     CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
1982     CY_CRYPTO_VU_LD_REG(base, my_s_z, s_z);
1983     CY_CRYPTO_VU_LD_REG(base, my_t_x, t_x);
1984     CY_CRYPTO_VU_LD_REG(base, my_t_y, t_y);
1985 
1986     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t6, size);
1987     if(CY_CRYPTO_SUCCESS != tmpResult)
1988     {
1989         return tmpResult;
1990     }
1991 
1992     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t7, size);
1993     if(CY_CRYPTO_SUCCESS != tmpResult)
1994     {
1995         return tmpResult;
1996     }
1997 
1998     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t8, size);
1999     if(CY_CRYPTO_SUCCESS != tmpResult)
2000     {
2001         return tmpResult;
2002     }
2003 
2004     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t9, size);
2005     if(CY_CRYPTO_SUCCESS != tmpResult)
2006     {
2007         return tmpResult;
2008     }
2009 
2010     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t6, my_s_z, size);       /* t6 = ZZ */
2011     if(CY_CRYPTO_SUCCESS != tmpResult)
2012     {
2013         return tmpResult;
2014     }
2015 
2016     tmpResult =Cy_Crypto_Core_EC_MulMod( base, t8, my_t_x, t6, size);      /* t8 = xZZ = B */
2017     if(CY_CRYPTO_SUCCESS != tmpResult)
2018     {
2019         return tmpResult;
2020     }
2021 
2022     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t7, my_t_y, my_s_z, size);  /* t7 = yZ */
2023     if(CY_CRYPTO_SUCCESS != tmpResult)
2024     {
2025         return tmpResult;
2026     }
2027     Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, t8);        /* my_s_x = X - B = E */
2028 
2029     tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_z, my_s_x, my_s_z, size);  /* my_s_z = E*Z = Z3 */
2030     if(CY_CRYPTO_SUCCESS != tmpResult)
2031     {
2032         return tmpResult;
2033     }
2034 
2035     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t9, t7, t6, size);          /* t9 = yZZZ = D */
2036     if(CY_CRYPTO_SUCCESS != tmpResult)
2037     {
2038         return tmpResult;
2039     }
2040 
2041     Cy_Crypto_Core_EC_SubMod( base, my_s_y, my_s_y, t9);        /* my_s_y = Y - D = F */
2042     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t6, my_s_x, size);       /* t6 = EE */
2043     if(CY_CRYPTO_SUCCESS != tmpResult)
2044     {
2045         return tmpResult;
2046     }
2047 
2048     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t7, t8, t6, size);          /* t7 = B*EE */
2049     if(CY_CRYPTO_SUCCESS != tmpResult)
2050     {
2051         return tmpResult;
2052     }
2053 
2054     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t8, t6, my_s_x, size);      /* t8 = EEE */
2055     if(CY_CRYPTO_SUCCESS != tmpResult)
2056     {
2057         return tmpResult;
2058     }
2059 
2060     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t6, t9, t8, size);          /* t6 = D*EEE */
2061     if(CY_CRYPTO_SUCCESS != tmpResult)
2062     {
2063         return tmpResult;
2064     }
2065 
2066     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, my_s_x, my_s_y, size);   /* my_s_x = FF */
2067     if(CY_CRYPTO_SUCCESS != tmpResult)
2068     {
2069         return tmpResult;
2070     }
2071     Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, t8);        /* my_s_x = FF - EEE */
2072     Cy_Crypto_Core_EC_AddMod( base, t9, t7, t7);                /* t9 = 2*B*EE */
2073     Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, t9);        /* my_s_x = FF - EEE - 2*B*EE = X3 */
2074     Cy_Crypto_Core_EC_SubMod( base, t7, t7, my_s_x);            /* t7 = B*EE - X3 */
2075     tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_y, my_s_y, t7, size);  /* my_s_y = F*(B*EE - X3) */
2076     if(CY_CRYPTO_SUCCESS != tmpResult)
2077     {
2078         return tmpResult;
2079     }
2080 
2081     Cy_Crypto_Core_EC_SubMod( base, my_s_y, my_s_y, t6);        /* my_s_y = F*(3*B*EE - FF + EEE) - D*EEE = Y3 */
2082 
2083     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t6) | CY_CRYPTO_VU_REG_BIT(t7) |
2084                                  CY_CRYPTO_VU_REG_BIT(t8) | CY_CRYPTO_VU_REG_BIT(t9));
2085 
2086     CY_CRYPTO_VU_POP_REG (base);
2087 
2088     return CY_CRYPTO_SUCCESS;
2089 }
2090 
2091 
2092 /*******************************************************************************
2093 * Function Name: Cy_Crypto_Core_JacobianEcDouble
2094 ****************************************************************************//**
2095 *
2096 * Elliptic curve point doubling on Jacobian projective coordinates in GF(VR_P).
2097 *
2098 * \param base
2099 * The pointer to a Crypto instance.
2100 *
2101 * \param s_x
2102 * Register index for Jacobian projective X coordinate.
2103 *
2104 * \param s_y
2105 * Register index for Jacobian projective Y coordinate.
2106 *
2107 * \param s_z
2108 * Register index for Jacobian projective Z coordinate.
2109 *
2110 * \param size
2111 * Bit size.
2112 *
2113 * \return status code. See \ref cy_en_crypto_status_t.
2114 *******************************************************************************/
Cy_Crypto_Core_JacobianEcDouble(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t size)2115 cy_en_crypto_status_t Cy_Crypto_Core_JacobianEcDouble(CRYPTO_Type *base,
2116     uint32_t s_x,
2117     uint32_t s_y,
2118     uint32_t s_z,
2119     uint32_t size
2120 )
2121 /* 4M + 4S + 10A */
2122 {
2123     uint32_t t1     = 1u;
2124     uint32_t t2     = 2u;
2125     uint32_t t3     = 3u;
2126     uint32_t t4     = 4u;
2127     uint32_t my_s_x = 5u;
2128     uint32_t my_s_y = 6u;
2129     uint32_t my_s_z = 7u;
2130     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
2131 
2132     CY_CRYPTO_VU_PUSH_REG (base);
2133 
2134     CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
2135     CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
2136     CY_CRYPTO_VU_LD_REG(base, my_s_z, s_z);
2137 
2138     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
2139     if(CY_CRYPTO_SUCCESS != tmpResult)
2140     {
2141         return tmpResult;
2142     }
2143 
2144     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, size);
2145     if(CY_CRYPTO_SUCCESS != tmpResult)
2146     {
2147         return tmpResult;
2148     }
2149 
2150     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, size);
2151     if(CY_CRYPTO_SUCCESS != tmpResult)
2152     {
2153         return tmpResult;
2154     }
2155 
2156     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t4, size);
2157     if(CY_CRYPTO_SUCCESS != tmpResult)
2158     {
2159         return tmpResult;
2160     }
2161 
2162     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t4, my_s_y, size);       /* t4 = Y^2 */
2163     if(CY_CRYPTO_SUCCESS != tmpResult)
2164     {
2165         return tmpResult;
2166     }
2167 
2168     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t3, my_s_z, size);       /* t3 = Z^2 */
2169     if(CY_CRYPTO_SUCCESS != tmpResult)
2170     {
2171         return tmpResult;
2172     }
2173 
2174     tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_z, my_s_y, my_s_z, size);  /* my_s_z = Y*Z */
2175     if(CY_CRYPTO_SUCCESS != tmpResult)
2176     {
2177         return tmpResult;
2178     }
2179 
2180     tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_y, my_s_x, t4, size);  /* my_s_y = X*Y^2 = A */
2181     if(CY_CRYPTO_SUCCESS != tmpResult)
2182     {
2183         return tmpResult;
2184     }
2185     Cy_Crypto_Core_EC_AddMod( base, my_s_x, my_s_x, t3);        /* my_s_x = X + Z^2 */
2186     Cy_Crypto_Core_EC_AddMod( base, t3, t3, t3);                /* t3 = 2*Z^2 */
2187     Cy_Crypto_Core_EC_SubMod( base, t3, my_s_x, t3);            /* t3 = (X + Z^2) - 2*Z^2 = X - Z^2 */
2188 
2189     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t1, my_s_x, t3, size);      /* t1 = (X + Z^2) * (X - Z^2) = X^2 - Z^4 */
2190     if(CY_CRYPTO_SUCCESS != tmpResult)
2191     {
2192         return tmpResult;
2193     }
2194 
2195     Cy_Crypto_Core_EC_AddMod( base, t3, t1, t1);                /* t3 = 2*(X^2 - Z^4) */
2196     Cy_Crypto_Core_EC_AddMod( base, t1, t1, t3);                /* t1 = 3*(X^2 - Z^4) */
2197     Cy_Crypto_Core_EC_HalfMod( base, t1, t1);                   /* t1 = 3/2*(X^2 - Z^4) = B */
2198     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t3, t1, size);           /* t3 = 9/4*(X^2 - Z^4) = B^2 */
2199     if(CY_CRYPTO_SUCCESS != tmpResult)
2200     {
2201         return tmpResult;
2202     }
2203 
2204     Cy_Crypto_Core_EC_SubMod( base, t3, t3, my_s_y);            /* t3 = B^2 - A */
2205     Cy_Crypto_Core_EC_SubMod( base, my_s_x, t3, my_s_y);        /* my_s_x =  B^2 - 2*A */
2206     Cy_Crypto_Core_EC_SubMod( base, my_s_y, my_s_y, my_s_x);    /* my_s_y = A - (B^2 - 2*A) = 3*A - B^2 */
2207 
2208     tmpResult = Cy_Crypto_Core_EC_MulMod( base, t2, t1, my_s_y, size);      /* t2 = B*(3*A - B^2) */
2209     if(CY_CRYPTO_SUCCESS != tmpResult)
2210     {
2211         return tmpResult;
2212     }
2213 
2214     tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t1, t4, size);           /* t1 = Y^4 */
2215     if(CY_CRYPTO_SUCCESS != tmpResult)
2216     {
2217         return tmpResult;
2218     }
2219 
2220     Cy_Crypto_Core_EC_SubMod( base, my_s_y, t2, t1);            /* my_s_y = B*(3*A - B^2) - Y^4 */
2221 
2222     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2) |
2223                                  CY_CRYPTO_VU_REG_BIT(t3) | CY_CRYPTO_VU_REG_BIT(t4));
2224     CY_CRYPTO_VU_POP_REG (base);
2225 
2226 
2227     return CY_CRYPTO_SUCCESS;
2228 }
2229 
2230 
2231 /*******************************************************************************
2232 * Function Name: Cy_Crypto_Core_JacobianEcScalarMul
2233 ****************************************************************************//**
2234 *
2235 * Elliptic curve point multiplication on Jacobian projective coordinates in GF(VR_P).
2236 *
2237 * \param base
2238 * The pointer to a Crypto instance.
2239 *
2240 * \param s_x
2241 * Register index for affine X coordinate.
2242 *
2243 * \param s_y
2244 * Register index for affine Y coordinate.
2245 *
2246 * \param d
2247 * Register index for multiplication/exponentiation value.
2248 *
2249 * \param size
2250 * Bit size.
2251 *
2252 * \return status code. See \ref cy_en_crypto_status_t.
2253 *******************************************************************************/
Cy_Crypto_Core_JacobianEcScalarMul(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t d,uint32_t size)2254 cy_en_crypto_status_t Cy_Crypto_Core_JacobianEcScalarMul(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t d, uint32_t size)
2255 {
2256     int32_t i;
2257     uint32_t status;
2258     uint32_t carry;
2259     uint16_t clsame;
2260 
2261     uint32_t clr     = 5u;
2262     uint32_t t       = 6u;
2263     uint32_t my_s_x  = 7u;
2264     uint32_t my_s_y  = 8u;
2265     uint32_t my_s_z  = 9u;
2266     uint32_t my_t_x  = 10u;
2267     uint32_t my_t_y  = 11u;
2268     uint32_t my_d    = 12u;
2269     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
2270 
2271     CY_CRYPTO_VU_PUSH_REG (base);
2272 
2273     CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
2274     CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
2275     CY_CRYPTO_VU_LD_REG(base, my_d, d);
2276 
2277     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, clr, size);
2278     if(CY_CRYPTO_SUCCESS != tmpResult)
2279     {
2280         return tmpResult;
2281     }
2282 
2283     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t, size);
2284     if(CY_CRYPTO_SUCCESS != tmpResult)
2285     {
2286         return tmpResult;
2287     }
2288 
2289     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_s_z, size);
2290     if(CY_CRYPTO_SUCCESS != tmpResult)
2291     {
2292         return tmpResult;
2293     }
2294 
2295     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_t_x, size);
2296     if(CY_CRYPTO_SUCCESS != tmpResult)
2297     {
2298         return tmpResult;
2299     }
2300 
2301     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_t_y, size);
2302     if(CY_CRYPTO_SUCCESS != tmpResult)
2303     {
2304         return tmpResult;
2305     }
2306 
2307     /* my_t_x has the same initial value of my_s_x, but does not point to the
2308     * same address in memory as my_s_x, i.e. different value after point doubling
2309     * my_t_x and my_t_y do not change from (original Jacobian projective coordinates of)
2310     * original base point
2311     */
2312     CY_CRYPTO_VU_MOV (base, my_t_x, my_s_x);
2313     CY_CRYPTO_VU_MOV (base, my_t_y, my_s_y);
2314 
2315     /* Affine-to-Jacobian Transform. */
2316     CY_CRYPTO_VU_SET_TO_ONE (base, my_s_z);
2317 
2318     /* EC scalar multiplication (irregular) operation. */
2319     CY_CRYPTO_VU_SET_TO_ZERO (base, clr);
2320     CY_CRYPTO_VU_CLSAME (base, t, my_d, clr);
2321 
2322     /* This is needed, otherwise clsame is wrong */
2323     Cy_Crypto_Core_Vu_WaitForComplete(base);
2324 
2325     clsame = Cy_Crypto_Core_Vu_RegDataPtrRead (base, t);
2326 
2327     CY_CRYPTO_VU_LSL  (base, my_d, my_d, t); /* Get rid of leading '0's */
2328     CY_CRYPTO_VU_LSL1 (base, my_d, my_d);    /* Get rid of leading '1' */
2329 
2330     /* Binary left-to-right algorithm
2331     * Perform point addition and point doubling to implement scalar multiplication
2332     * Scan the bits of the scalar from left to right; perform point doubling for each bit,
2333     * and perform point addition when the bit is set.
2334     * Carry set if current bit is equal to 1 (hence, perform point addition - point
2335     * doubling is always performed)
2336     */
2337     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t because result of composite expression can be negative');
2338     for (i = 0; i < ((int32_t)(size - clsame - 1u)); i++)
2339     {
2340         /* Carry set if current bit is equal to 1 (hence, perform point addition - point
2341         * doubling is always performed)
2342         */
2343         CY_CRYPTO_VU_LSL1 (base, my_d, my_d);
2344         status = Cy_Crypto_Core_Vu_StatusRead(base);
2345 
2346         carry = status & CY_CRYPTO_VU_STATUS_CARRY_BIT;
2347 
2348         tmpResult = Cy_Crypto_Core_JacobianEcDouble (base, my_s_x, my_s_y, my_s_z, size);
2349 
2350         if(CY_CRYPTO_SUCCESS != tmpResult)
2351         {
2352             return tmpResult;
2353         }
2354 
2355         if (carry != 0U)
2356         {
2357             tmpResult = Cy_Crypto_Core_JacobianEcAdd (base, my_s_x, my_s_y, my_s_z, my_t_x, my_t_y, size);
2358 
2359             if(CY_CRYPTO_SUCCESS != tmpResult)
2360             {
2361                 return tmpResult;
2362             }
2363         }
2364     }
2365 
2366     /* Inverse transform */
2367     tmpResult = Cy_Crypto_Core_JacobianInvTransform(base, my_s_x, my_s_y, my_s_z, size);
2368     if(CY_CRYPTO_SUCCESS != tmpResult)
2369     {
2370         return tmpResult;
2371     }
2372 
2373     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(my_s_z) |
2374                                  CY_CRYPTO_VU_REG_BIT(my_t_x) | CY_CRYPTO_VU_REG_BIT(my_t_y) |
2375                                  CY_CRYPTO_VU_REG_BIT(clr)    | CY_CRYPTO_VU_REG_BIT(t));
2376 
2377     CY_CRYPTO_VU_POP_REG (base);
2378    return CY_CRYPTO_SUCCESS;
2379 }
2380 
2381 /***************************************************************
2382 *                   Test methods
2383 ***************************************************************/
2384 
2385 
2386 /*******************************************************************************
2387 * Function Name: Cy_Crypto_Core_EC_NistP_SetMode
2388 ****************************************************************************//**
2389 *
2390 * Enable some curve specific features.
2391 *
2392 * \param bitsize
2393 * bitsize of the used NIST P curve.
2394 *
2395 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_SetMode(uint32_t bitsize)2396 void Cy_Crypto_Core_EC_NistP_SetMode(uint32_t bitsize)
2397 {
2398     switch (bitsize)
2399     {
2400 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
2401         case CY_CRYPTO_ECC_P192_SIZE:
2402             eccMode = CY_CRYPTO_ECC_ECP_SECP192R1;
2403             break;
2404 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
2405 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
2406         case CY_CRYPTO_ECC_P224_SIZE:
2407             eccMode = CY_CRYPTO_ECC_ECP_SECP224R1;
2408             break;
2409 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
2410 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
2411         case CY_CRYPTO_ECC_P256_SIZE:
2412             eccMode = CY_CRYPTO_ECC_ECP_SECP256R1;
2413             break;
2414 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
2415 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
2416         case CY_CRYPTO_ECC_P384_SIZE:
2417             eccMode = CY_CRYPTO_ECC_ECP_SECP384R1;
2418             break;
2419 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
2420 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
2421         case CY_CRYPTO_ECC_P521_SIZE:
2422             eccMode = CY_CRYPTO_ECC_ECP_SECP521R1;
2423             break;
2424 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
2425         default:
2426             eccMode = CY_CRYPTO_ECC_ECP_NONE;
2427             break;
2428     }
2429 }
2430 
2431 
2432 /*******************************************************************************
2433 * Function Name: Cy_Crypto_Core_EC_NistP_SetRedAlg
2434 ****************************************************************************//**
2435 *
2436 * Select which reduction algorithm has to be used.
2437 *
2438 * \param alg
2439 * one of {CURVE_SPECIFIC_RED_ALG, SHIFT_MUL_RED_ALG, BARRETT_RED_ALG}.
2440 * See \ref cy_en_crypto_ecc_red_mul_algs_t.
2441 *
2442 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_SetRedAlg(cy_en_crypto_ecc_red_mul_algs_t alg)2443 void Cy_Crypto_Core_EC_NistP_SetRedAlg(cy_en_crypto_ecc_red_mul_algs_t alg)
2444 {
2445     mul_red_alg_select = alg;
2446 }
2447 
2448 
2449 /*******************************************************************************
2450 * Function Name: Cy_Crypto_Core_EC_NistP_PointMul
2451 ****************************************************************************//**
2452 *
2453 * Elliptic curve point multiplication in GF(p).
2454 *
2455 * \param base
2456 * The pointer to a Crypto instance.
2457 *
2458 * \param p_x
2459 * Register index for affine X coordinate of base point.
2460 *
2461 * \param p_y
2462 * Register index for affine Y coordinate of base point.
2463 *
2464 * \param p_d
2465 * Register index for multiplication value.
2466 *
2467 * \param p_order
2468 * Register index for order value..
2469 *
2470 * \param bitsize
2471 * Bit size of the used curve.
2472 *
2473 * \return status code. See \ref cy_en_crypto_status_t.
2474 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_PointMul(CRYPTO_Type * base,uint32_t p_x,uint32_t p_y,uint32_t p_d,uint32_t p_order,uint32_t bitsize)2475 cy_en_crypto_status_t Cy_Crypto_Core_EC_NistP_PointMul(CRYPTO_Type *base, uint32_t p_x, uint32_t p_y, uint32_t p_d, uint32_t p_order, uint32_t bitsize)
2476 {
2477     (void)p_order; /* Suppress warning */
2478     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
2479 
2480     tmpResult = Cy_Crypto_Core_JacobianEcScalarMul (base, p_x, p_y, p_d, bitsize);
2481     Cy_Crypto_Core_Vu_WaitForComplete(base);
2482 
2483     return tmpResult;
2484 }
2485 
2486 
2487 /*******************************************************************************
2488 * Function Name: Cy_Crypto_Core_EC_NistP_PointMultiplication
2489 ****************************************************************************//**
2490 *
2491 * Elliptic curve point multiplication in GF(p).
2492 *
2493 * For CAT1C & CAT1D devices when D-Cache is enabled parameter ecpGX, ecpGY, ecpD, ecpQX & ecpQY must align and end in 32 byte boundary.
2494 *
2495 * \param base
2496 * The pointer to a Crypto instance.
2497 *
2498 * \param curveID
2499 * See \ref cy_en_crypto_ecc_curve_id_t.
2500 *
2501 * \param ecpGX
2502 * Register index for affine X coordinate of base point.
2503 *
2504 * \param ecpGY
2505 * Register index for affine Y coordinate of base point.
2506 *
2507 * \param ecpD
2508 * Register index for multiplication value.
2509 *
2510 * \param ecpQX
2511 * Register index for affine X coordinate of result point.
2512 *
2513 * \param ecpQY
2514 * Register index for affine Y coordinate of result point.
2515 *
2516 * \return status code. See \ref cy_en_crypto_status_t.
2517 *
2518 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_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)2519 cy_en_crypto_status_t Cy_Crypto_Core_EC_NistP_PointMultiplication(CRYPTO_Type *base,
2520     cy_en_crypto_ecc_curve_id_t curveID,
2521     const uint8_t *ecpGX,
2522     const uint8_t *ecpGY,
2523     const uint8_t *ecpD,
2524     uint8_t *ecpQX,
2525     uint8_t *ecpQY)
2526 {
2527     /* N.b. If using test vectors from "http://point-at-infinity.org/ecc/nisttv",
2528      * the 'k' values on the website are in decimal form, while the (x,y) result
2529      * coordinates are in hexadecimal form
2530      * Input format for 'd' scalar multiplier in this test is in hexadecimal form.
2531      * Hence, convert k_{dec} to d_{hex} for comparison of test values
2532      */
2533 
2534     /* Setup additional registers */
2535     uint32_t VR_ORDER = 9u;
2536 
2537     const uint8_t *p_polynomial = NULL;
2538     const uint8_t *p_barrett = NULL;
2539 
2540     cy_stc_crypto_ecc_dp_type *eccDp = Cy_Crypto_Core_ECC_GetCurveParams(curveID);
2541 
2542     cy_en_crypto_status_t tmpResult = CY_CRYPTO_NOT_SUPPORTED;
2543 
2544     if (eccDp != NULL)
2545     {
2546         /* Setup curve specific parameters depending on mode */
2547         uint32_t bitsize;
2548 
2549         p_polynomial = (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(eccDp->prime);
2550         p_barrett    = (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(eccDp->barrett_p);
2551         bitsize      = eccDp->size;
2552 
2553         /* use Barrett reduction algorithm for operations modulo n (order of the base point) */
2554         Cy_Crypto_Core_EC_NistP_SetRedAlg(eccDp->algo);
2555         Cy_Crypto_Core_EC_NistP_SetMode(eccDp->size);
2556 
2557         tmpResult = CY_CRYPTO_BAD_PARAMS;
2558 
2559         if ((NULL != ecpGX) && (NULL != ecpGY) && (NULL != ecpD) && (NULL != ecpQX) && (NULL != ecpQY))
2560         {
2561 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
2562             /* Flush the cache */
2563             SCB_CleanDCache_by_Addr((volatile void *)ecpGX, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2564             SCB_CleanDCache_by_Addr((volatile void *)ecpGY, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2565             SCB_CleanDCache_by_Addr((volatile void *)ecpD, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2566 #endif
2567             /* Public parameters and characteristics of elliptic curve */
2568             tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_D, bitsize);        /* Scalar factor */
2569             if(CY_CRYPTO_SUCCESS != tmpResult)
2570             {
2571                 return tmpResult;
2572             }
2573 
2574             tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_X, bitsize);
2575             if(CY_CRYPTO_SUCCESS != tmpResult)
2576             {
2577                 return tmpResult;
2578             }
2579 
2580             tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_Y, bitsize);
2581             if(CY_CRYPTO_SUCCESS != tmpResult)
2582             {
2583                 return tmpResult;
2584             }
2585 
2586             tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_P, bitsize);
2587             if(CY_CRYPTO_SUCCESS != tmpResult)
2588             {
2589                 return tmpResult;
2590             }
2591 
2592             tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_BARRETT, bitsize + 1u);
2593             if(CY_CRYPTO_SUCCESS != tmpResult)
2594             {
2595                 return tmpResult;
2596             }
2597 
2598             tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_ORDER, bitsize);
2599             if(CY_CRYPTO_SUCCESS != tmpResult)
2600             {
2601                 return tmpResult;
2602             }
2603 
2604             Cy_Crypto_Core_Vu_SetMemValue (base, VR_P, p_polynomial, bitsize);
2605 
2606             /* Preparation (either use precalculated or calculated). */
2607             Cy_Crypto_Core_Vu_SetMemValue (base, VR_BARRETT, p_barrett, bitsize + 1u);
2608 
2609             Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_X, ecpGX, bitsize);
2610             Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_Y, ecpGY, bitsize);
2611             Cy_Crypto_Core_Vu_SetMemValue (base, VR_D, ecpD, bitsize);
2612 
2613             /* ECC calculation: d * G mod p */
2614             tmpResult = Cy_Crypto_Core_EC_NistP_PointMul(base, VR_S_X, VR_S_Y, VR_D, VR_ORDER, bitsize);
2615 
2616             if(CY_CRYPTO_SUCCESS != tmpResult)
2617             {
2618                 return tmpResult;
2619             }
2620             /* Get result P = (X,Y) = d.G from EC scalar multiplication */
2621             Cy_Crypto_Core_Vu_GetMemValue (base, ecpQX, VR_S_X, bitsize);
2622             Cy_Crypto_Core_Vu_GetMemValue (base, ecpQY, VR_S_Y, bitsize);
2623 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
2624             SCB_InvalidateDCache_by_Addr(ecpQX, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2625             SCB_InvalidateDCache_by_Addr(ecpQY, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2626 #endif
2627             /* Free memory */
2628             CY_CRYPTO_VU_FREE_MEM (base,
2629                                     CY_CRYPTO_VU_REG_BIT(VR_ORDER) |
2630                                     CY_CRYPTO_VU_REG_BIT(VR_BARRETT) |
2631                                     CY_CRYPTO_VU_REG_BIT(VR_P) |
2632                                     CY_CRYPTO_VU_REG_BIT(VR_S_Y) |
2633                                     CY_CRYPTO_VU_REG_BIT(VR_S_X) |
2634                                     CY_CRYPTO_VU_REG_BIT(VR_D));
2635 
2636             tmpResult = CY_CRYPTO_SUCCESS;
2637         }
2638     }
2639 
2640     return tmpResult;
2641 }
2642 
2643 #endif /* defined (CY_CRYPTO_CFG_ECP_C) */
2644 
2645 #if defined(__cplusplus)
2646 }
2647 #endif
2648 
2649 #endif /* CY_IP_MXCRYPTO */
2650 
2651 
2652 /* [] END OF FILE */
2653