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