1 /***************************************************************************//**
2 * \file cy_cryptolite_ecc_key_gen.c
3 * \version 2.30
4 *
5 * \brief
6 *  This file provides API for generating ECC key.
7 *
8 ********************************************************************************
9 * Copyright 2023 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 *    http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24 #include "cy_device.h"
25 
26 #if defined (CY_IP_MXCRYPTOLITE)
27 
28 #if defined(__cplusplus)
29 extern "C" {
30 #endif
31 
32 #include "cy_cryptolite_ecc_key_gen.h"
33 #include "cy_cryptolite_trng.h"
34 
35 #if (CRYPTOLITE_VU_PRESENT == 1)
36 
37 #include "cy_cryptolite_utils.h"
38 #include "cy_cryptolite_nist_p.h"
39 
40 /*******************************************************************************
41 * Function Name: Cy_Cryptolite_ECC_MakeKeyPair
42 ****************************************************************************//*
43 *
44 * Generate a Private & Public Key pair.
45 *
46 * \param base
47 * The pointer to a Cryptolite instance.
48 *
49 * \param cfContext
50 * The pointer to the cy_stc_cryptolite_context_ecdsa_t.
51 *
52 * \param curveID
53 * The ECC curve id.
54 *
55 * \param key
56 * The ECC key. See \ref cy_stc_cryptolite_ecc_key.
57 *
58 * \param GetRandomDataFunc
59 * See \ref cy_func_get_random_data_t.
60 *
61 * \param randomDataInfo
62 *
63 * \return status code. See \ref cy_en_cryptolite_status_t.
64 *
65 *******************************************************************************/
Cy_Cryptolite_ECC_MakeKeyPair(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,cy_en_cryptolite_ecc_curve_id_t curveID,cy_stc_cryptolite_ecc_key * key,cy_func_get_random_data_t GetRandomDataFunc,void * randomDataInfo)66 cy_en_cryptolite_status_t Cy_Cryptolite_ECC_MakeKeyPair(CRYPTOLITE_Type *base,
67         cy_stc_cryptolite_context_ecdsa_t *cfContext,
68         cy_en_cryptolite_ecc_curve_id_t curveID,
69         cy_stc_cryptolite_ecc_key *key,
70         cy_func_get_random_data_t GetRandomDataFunc, void *randomDataInfo)
71 {
72     cy_en_cryptolite_status_t tmpResult = CY_CRYPTOLITE_BAD_PARAMS;
73 
74     if ((key != NULL) && (key->k != NULL) && (key->pubkey.x != NULL) && (key->pubkey.y != NULL))
75     {
76         tmpResult = Cy_Cryptolite_ECC_MakePrivateKey(base, cfContext, curveID, key->k, GetRandomDataFunc, randomDataInfo);
77     }
78 
79     if (CY_CRYPTOLITE_SUCCESS == tmpResult)
80     {
81         tmpResult = Cy_Cryptolite_ECC_MakePublicKey(base, cfContext, curveID, key->k, key);
82         key->type = PK_PRIVATE;
83     }
84 
85     return (tmpResult);
86 }
87 
88 /*******************************************************************************
89 * Function Name: Cy_Cryptolite_ECC_MakePrivateKey
90 ****************************************************************************//*
91 *
92 * Generate a Private key.
93 *
94 * \param base
95 * The pointer to a Cryptolite instance.
96 *
97 * \param cfContext
98 * The pointer to the cy_stc_cryptolite_context_ecdsa_t.
99 *
100 * \param curveID
101 * The ECC curve id.
102 *
103 * \param privateKey
104 * The pointer to the ECC private key.
105 *
106 * \param GetRandomDataFunc
107 * See \ref cy_func_get_random_data_t.
108 *
109 * \param randomDataInfo
110 *
111 * \return status code. See \ref cy_en_cryptolite_status_t.
112 *
113 *******************************************************************************/
Cy_Cryptolite_ECC_MakePrivateKey(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,cy_en_cryptolite_ecc_curve_id_t curveID,const uint8_t * privateKey,cy_func_get_random_data_t GetRandomDataFunc,void * randomDataInfo)114 cy_en_cryptolite_status_t Cy_Cryptolite_ECC_MakePrivateKey(CRYPTOLITE_Type *base,
115         cy_stc_cryptolite_context_ecdsa_t *cfContext,
116         cy_en_cryptolite_ecc_curve_id_t curveID,
117         const uint8_t *privateKey,
118         cy_func_get_random_data_t GetRandomDataFunc, void *randomDataInfo)
119 {
120     cy_en_cryptolite_status_t result = CY_CRYPTOLITE_BAD_PARAMS;
121     const cy_stc_cryptolite_ecc_dp_type *eccDp;
122     uint8_t *temp_ptr = NULL;
123 
124     /* NULL parameters checking */
125      if ((base != NULL) && (cfContext != NULL) && (privateKey != NULL))
126     {
127         result = CY_CRYPTOLITE_NOT_SUPPORTED;
128         eccDp = Cy_Cryptolite_ECC_GetCurveParams(curveID);
129 
130         if (eccDp != NULL)
131         {
132             uint8_t *p_u1 = cfContext->p_u1;
133             uint8_t *p_o = cfContext->p_o;
134             uint8_t *my_P = cfContext->my_P;
135             uint8_t *my_BARRETT_U = cfContext->my_BARRETT_U;
136             cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1];
137             cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0];
138             CY_ALIGN(4) uint8_t temp[VU_BITS_TO_BYTES(VU_TEST_EQUAL_LESS_SIZE+1U)]={0};
139             uint32_t bitsize  = eccDp->size;
140             uint32_t bytesize = VU_BITS_TO_BYTES(eccDp->size);
141             cfContext->bitsize = bitsize;
142 
143             // Initialize point multiplication
144             // load prime, order and barrett coefficient
145             Cy_Cryptolite_Setnumber(my_P, (uint8_t *) eccDp->prime, bytesize);
146             Cy_Cryptolite_Setnumber(p_o, (uint8_t *) eccDp->order, bytesize);
147             Cy_Cryptolite_Setnumber(my_BARRETT_U, (uint8_t *) eccDp->barrett_p, VU_BITS_TO_BYTES(bitsize+1U));
148 
149             if (GetRandomDataFunc != NULL)
150             {
151                 result = CY_CRYPTOLITE_HW_ERROR;
152                 if (GetRandomDataFunc( randomDataInfo, (uint8_t *)privateKey, bytesize ) == 0)
153                 {
154                     Cy_Cryptolite_Vu_memcpy ((void *)p_u1, privateKey, bytesize);
155                     result = CY_CRYPTOLITE_SUCCESS;
156                 }
157             }
158             else
159             {
160                 temp_ptr = p_u1;
161 
162                 #if (CRYPTOLITE_TRNG_PRESENT == 1) && defined(CY_CRYPTOLITE_CFG_TRNG_C)
163                 int32_t randomsize = (int32_t)bytesize;
164                 result = Cy_Cryptolite_Trng_Init(base, NULL);
165 
166                 if(CY_CRYPTOLITE_SUCCESS != result)
167                 {
168                     return result;
169                 }
170 
171                 result = Cy_Cryptolite_Trng_Enable(base);
172 
173                 while ((randomsize > 0) && (CY_CRYPTOLITE_SUCCESS == result))
174                 {
175                     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 11.3','Intentional pointer type conversion');
176                     result = Cy_Cryptolite_Trng_ReadData(base, (uint32_t *)temp_ptr);
177                     temp_ptr += 4u;
178                     randomsize -= 4;
179 
180                     if (CY_CRYPTOLITE_SUCCESS != result)
181                     {
182                         break;
183                     }
184                 }
185 
186                 Cy_Cryptolite_Vu_memcpy ((void *)privateKey, p_u1, bytesize);
187 
188                 (void)Cy_Cryptolite_Trng_Disable(base);
189                 (void)Cy_Cryptolite_Trng_DeInit(base);
190                 #else
191                 (void)temp_ptr;
192                 result = CY_CRYPTOLITE_NOT_SUPPORTED;
193                 #endif
194             }
195 
196             if(CY_CRYPTOLITE_SUCCESS == result)
197             {
198                 if (Cy_Cryptolite_Vu_test_less_than(base, vu_struct1, p_u1, p_o, (uint16_t)bitsize) == false)
199                 {
200                     (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, temp, VU_BITS_TO_WORDS(bitsize+1U), p_u1, VU_BITS_TO_WORDS(bitsize));
201                     Cy_Cryptolite_EC_Bar_MulRed( base, cfContext, p_u1, temp, bitsize);
202                 }
203                 Cy_Cryptolite_Setnumber((uint8_t *)privateKey, p_u1, bytesize);
204             }
205         }
206     }
207 
208     return result;
209 }
210 
211 /*******************************************************************************
212 * Function Name: Cy_Cryptolite_ECC_MakePublicKey
213 ****************************************************************************//*
214 *
215 * Generate a public key.
216 *
217 * \param base
218 * The pointer to a Cryptolite instance.
219 *
220 * \param cfContext
221 * The pointer to the cy_stc_cryptolite_context_ecdsa_t.
222 *
223 * \param curveID
224 * The ECC curve id.
225 *
226 * \param privateKey
227 * The pointer to the ECC private key.
228 *
229 * \param publicKey
230 * The generated public ECC key. See \ref cy_stc_cryptolite_ecc_key.
231 *
232 * \return status code. See \ref cy_en_cryptolite_status_t.
233 *
234 *******************************************************************************/
Cy_Cryptolite_ECC_MakePublicKey(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,cy_en_cryptolite_ecc_curve_id_t curveID,const uint8_t * privateKey,cy_stc_cryptolite_ecc_key * publicKey)235 cy_en_cryptolite_status_t Cy_Cryptolite_ECC_MakePublicKey(CRYPTOLITE_Type *base,
236         cy_stc_cryptolite_context_ecdsa_t *cfContext,
237         cy_en_cryptolite_ecc_curve_id_t curveID,
238         const uint8_t *privateKey,
239         cy_stc_cryptolite_ecc_key *publicKey)
240 {
241 
242     cy_en_cryptolite_status_t result = CY_CRYPTOLITE_BAD_PARAMS;
243     const cy_stc_cryptolite_ecc_dp_type *eccDp;
244 
245     /* NULL parameters checking */
246      if ((base != NULL) && (cfContext != NULL) && (privateKey != NULL) && (publicKey != NULL) &&
247         (publicKey->pubkey.x != NULL) && (publicKey->pubkey.y != NULL))
248     {
249 
250         result = CY_CRYPTOLITE_NOT_SUPPORTED;
251         eccDp = Cy_Cryptolite_ECC_GetCurveParams(curveID);
252 
253         if (eccDp != NULL)
254         {
255             uint8_t *p_u1 = cfContext->p_u1;
256             uint8_t *p_o = cfContext->p_o;
257             uint8_t *p_gx = cfContext->p_gx;
258             uint8_t *p_gy = cfContext->p_gy;
259             uint8_t *my_P = cfContext->my_P;
260             uint8_t *my_BARRETT_U = cfContext->my_BARRETT_U;
261 
262             uint32_t bitsize  = eccDp->size;
263             uint32_t bytesize = VU_BITS_TO_BYTES(eccDp->size);
264 
265             cfContext->bitsize = bitsize;
266 
267 
268             // Initialize point multiplication
269             // load prime, order and barrett coefficient
270             Cy_Cryptolite_Setnumber(my_P, (uint8_t *) eccDp->prime, bytesize);
271             Cy_Cryptolite_Setnumber(p_o, (uint8_t *) eccDp->order, bytesize);
272             Cy_Cryptolite_Setnumber(my_BARRETT_U, (uint8_t *) eccDp->barrett_p, VU_BITS_TO_BYTES(bitsize+1U));
273 
274             // load base Point G
275             Cy_Cryptolite_Setnumber(p_gx, (uint8_t *) eccDp->Gx, bytesize);
276             Cy_Cryptolite_Setnumber(p_gy, (uint8_t *) eccDp->Gy, bytesize);
277             Cy_Cryptolite_Setnumber(p_u1, (uint8_t *)privateKey, bytesize);
278 
279 
280             Cy_Cryptolite_EC_NistP_PointMul(base, cfContext, p_gx, p_gy, p_u1, p_o, (int)bitsize);
281 
282             Cy_Cryptolite_Setnumber((uint8_t *)publicKey->pubkey.x, (uint8_t *) p_gx, bytesize);
283             Cy_Cryptolite_Setnumber((uint8_t *)publicKey->pubkey.y, (uint8_t *) p_gy, bytesize);
284 
285             result = CY_CRYPTOLITE_SUCCESS;
286 
287         }
288         else
289         {
290             result = CY_CRYPTOLITE_NOT_SUPPORTED;
291         }
292     }
293     return result;
294 
295 }
296 
297 #endif /* #if (CPUSS_CRYPTOLITE_VU == 1) */
298 
299 #if defined(__cplusplus)
300 }
301 #endif
302 
303 #endif /* CY_IP_MXCRYPTOLITE */
304