1 /*
2 * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "mbedtls/build_info.h"
8
9 #if defined(MBEDTLS_ECDSA_C)
10
11 #include "mbedtls/ecdsa.h"
12 #include "cc_ecc_internal.h"
13 #include "mbedtls_common.h"
14 #include "ecp_common.h"
15 #include "cc_pal_types.h"
16 #include "cc_pal_mem.h"
17 #include "cc_pal_abort.h"
18 #include "cc_common.h"
19 #include "cc_ecpki_error.h"
20 #include "ec_edw.h"
21
22 #include "cc_ec_edw_api.h"
23 #include "ec_edw_local.h"
24 #include "cc_ecpki_domain.h"
25 #if defined(MBEDTLS_PLATFORM_C)
26 #include "mbedtls/platform.h"
27 #else
28 #include <stdlib.h>
29 #include <stdio.h>
30 #define mbedtls_printf printf
31 #define mbedtls_calloc calloc
32 #define mbedtls_free free
33 #endif
34
35 #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
36
ecdsa_export_mpi_to_buff(const mbedtls_mpi * mpi,size_t * outBuffSize,unsigned char * buf,size_t buffSize)37 static int ecdsa_export_mpi_to_buff(const mbedtls_mpi *mpi, size_t *outBuffSize, unsigned char *buf, size_t buffSize)
38 {
39 int ret;
40 uint32_t i = 0;
41 uint32_t actSize;
42 uint32_t zeroFill;
43
44 actSize = mbedtls_mpi_size(mpi);
45 zeroFill = buffSize - actSize;
46 i = 0;
47 while (zeroFill) {
48 buf[i] = 0;
49 zeroFill--;
50 i++;
51 }
52 ret = mbedtls_mpi_write_binary(mpi, &buf[i], actSize);
53 if (ret != 0)
54 {
55 CC_PAL_LOG_ERR("Error - failed mbedtls_mpi_write_binary 0x%x\n", ret);
56 return ret;
57 }
58 *outBuffSize = buffSize;
59 return CC_OK;
60
61 }
62
63 /*
64 * Generate key pair for Edwards ed25519 curve
65 */
mbedtls_ecdsa_genkey_edwards(mbedtls_ecdsa_context * ctx,mbedtls_ecp_group_id gid,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)66 int mbedtls_ecdsa_genkey_edwards( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
67 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
68 {
69 mbedtls_ecp_group *grp;
70 mbedtls_mpi *d;
71 mbedtls_ecp_point *Q;
72 int ret = 0;
73 CCError_t rc = 0;
74 const CCEcEdwDomain_t *pDomain;
75 uint32_t *pFuncTemp;
76 uint32_t ecEdwOrderSizeBytes;
77 uint8_t *pPrivKey; // size is 2*ecEdwOrderSizeBytes
78 uint32_t privKeySizeBytes;
79 uint8_t *pPublicKey; // size is ecEdwOrderSizeBytes
80 uint32_t pubKeySizeBytes;
81 CCEcEdwTempBuff_t *pTempBuff = NULL; // size is 3*ecEdwOrderSizeBytes
82 uint8_t *pSeed;
83
84 /* Verify inputs */
85 if ((ctx == NULL ) ||
86 (f_rng == NULL) ||
87 (p_rng == NULL) ||
88 (gid != MBEDTLS_ECP_DP_CURVE25519 ))
89 {
90 CC_PAL_LOG_ERR("Failed check params");
91 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
92 }
93
94 grp = &ctx->MBEDTLS_PRIVATE(grp);
95 d = &ctx->MBEDTLS_PRIVATE(d);
96 Q = &ctx->MBEDTLS_PRIVATE(Q);
97
98 pDomain = EcEdwGetDomain25519();
99 if (NULL == pDomain)
100 {
101 CC_PAL_LOG_ERR("Failed invalid domain");
102 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
103 }
104
105 ecEdwOrderSizeBytes = CALC_FULL_BYTES(pDomain->ecOrdSizeInBits);
106 privKeySizeBytes = 2*ecEdwOrderSizeBytes;
107 pubKeySizeBytes = CALC_FULL_BYTES(pDomain->ecModSizeInBits);
108 pTempBuff = mbedtls_calloc(1, ((ecEdwOrderSizeBytes + sizeof(CCEcEdwTempBuff_t) + privKeySizeBytes + pubKeySizeBytes)));
109 if (NULL == pTempBuff)
110 {
111 CC_PAL_LOG_ERR("Error - failed to allocate memory for temporary buffer\n");
112 return MBEDTLS_ERR_ECP_ALLOC_FAILED;
113 }
114
115 pSeed = (uint8_t*)pTempBuff;
116 pFuncTemp = (uint32_t*)pTempBuff + CALC_32BIT_WORDS_FROM_BYTES(ecEdwOrderSizeBytes);
117 pPrivKey = (uint8_t*)pFuncTemp + sizeof( CCEcEdwTempBuff_t );
118 pPublicKey = pPrivKey + privKeySizeBytes;
119
120 /* generate random seed */
121 rc = f_rng((void *)p_rng, (unsigned char *)pSeed, (size_t)ecEdwOrderSizeBytes);
122 if (rc) {
123 ret = error_mapping_cc_to_mbedtls_ecc(rc);
124 CC_PAL_LOG_ERR("Failed to generate random seed");
125 goto END;
126 }
127
128 /* generate key pair */
129 rc = EcEdwSeedKeyPair(pPublicKey, pPrivKey,
130 pSeed, pDomain,
131 (uint32_t*)pFuncTemp);
132 if (rc != CC_SUCCESS)
133 {
134 CC_PAL_LOG_ERR("Error - Key generation ended with result: 0x%x\n", rc);
135 ret = error_mapping_cc_to_mbedtls_ecc(rc);
136 goto END;
137 }
138 ret = mbedtls_mpi_read_binary(&Q->MBEDTLS_PRIVATE(Y), pPublicKey, CALC_FULL_BYTES(pDomain->ecModSizeInBits));
139 if (ret != 0)
140 {
141 CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
142 goto END;
143 }
144 Q->MBEDTLS_PRIVATE(Y).MBEDTLS_PRIVATE(s) = 1; /*unsigned*/
145
146 ret = mbedtls_mpi_read_binary(d, pPrivKey, CALC_FULL_BYTES(2*pDomain->ecModSizeInBits));
147 if (ret != 0)
148 {
149 CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
150 goto END;
151 }
152 d->MBEDTLS_PRIVATE(s) = 1; /*unsigned*/
153
154
155 /* Set the group curve order used by sign & verify functions */
156 grp->nbits = pDomain->ecModSizeInBits; // 253
157 ret = (0);
158 goto SUCCESS;
159
160 END:
161
162 mbedtls_ecp_point_free(Q);
163 mbedtls_mpi_free(d);
164 SUCCESS:
165 mbedtls_zeroize_internal(pTempBuff, (ecEdwOrderSizeBytes + sizeof(CCEcEdwTempBuff_t) + privKeySizeBytes + pubKeySizeBytes));
166 mbedtls_free(pTempBuff);
167 return ret;
168
169 }
170
171
mbedtls_ecdsa_sign_edwards(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen)172 int mbedtls_ecdsa_sign_edwards( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
173 const mbedtls_mpi *d, const unsigned char *buf, size_t blen)
174 {
175 int ret;
176 CCEcEdwTempBuff_t *cc_temp_buff;
177 uint8_t temp_buf[ (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*sizeof(uint32_t) ] = {0};
178 const CCEcEdwDomain_t* pDomain;
179 size_t signature_size;
180 uint8_t * pSignature;
181 size_t key_size, order_size;
182 uint32_t status;
183
184 CC_UNUSED_PARAM(grp);
185 /* Verify inputs */
186 if ((r == NULL) ||
187 (s == NULL) ||
188 (d == NULL) ||
189 ((buf == NULL) ^ (blen == 0)))
190 {
191 CC_PAL_LOG_ERR("Failed check params");
192 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
193 }
194
195 pDomain = EcEdwGetDomain25519();
196 if (NULL == pDomain)
197 {
198 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
199 }
200
201 order_size = CALC_FULL_BYTES (pDomain->ecModSizeInBits);
202 signature_size = order_size * 2 ;
203
204 cc_temp_buff = (CCEcEdwTempBuff_t *)mbedtls_calloc(1, sizeof(CCEcEdwTempBuff_t) + signature_size );
205 if ( cc_temp_buff == NULL )
206 {
207 CC_PAL_LOG_ERR("Error - failed to alloc memory for the cc_temp_buff\n");
208 return MBEDTLS_ERR_ECP_ALLOC_FAILED;
209 }
210 mbedtls_zeroize_internal(cc_temp_buff, signature_size + sizeof(CCEcEdwTempBuff_t));
211
212 pSignature = (uint8_t *)(cc_temp_buff + 1);
213
214 ret = ecdsa_export_mpi_to_buff(d, &key_size, temp_buf, order_size * 2);
215
216 if (ret !=0 )
217 {
218 CC_PAL_LOG_ERR("Error - failed to convert d to binary\n");
219 goto end;
220 }
221
222 status = CC_EcEdwSign(pSignature,
223 &signature_size,
224 (uint8_t*)buf,
225 blen,
226 temp_buf,
227 key_size,
228 cc_temp_buff);
229 if (( status != CC_OK ) ||
230 (signature_size != order_size * 2))
231 {
232 CC_PAL_LOG_ERR("Error - Edwards signing failed, return code is: %d\n", status);
233 ret = error_mapping_cc_to_mbedtls_ecc(status);
234 goto end;
235 }
236
237 ret = mbedtls_mpi_read_binary( r, pSignature, order_size );
238 if ( ret != 0 )
239 {
240 CC_PAL_LOG_ERR("Error - failed to convert r\n");
241 goto end;
242 }
243
244 ret = mbedtls_mpi_read_binary( s, pSignature + order_size, order_size );
245 if ( ret != 0 )
246 {
247 CC_PAL_LOG_ERR("Error - failed to convert s\n");
248 goto end;
249 }
250
251 end:
252
253 mbedtls_zeroize_internal(cc_temp_buff, signature_size + sizeof(CCEcEdwTempBuff_t) );
254 mbedtls_free( cc_temp_buff );
255
256 return ret;
257 }
258
259
mbedtls_ecdsa_verify_edwards(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s)260 int mbedtls_ecdsa_verify_edwards(mbedtls_ecp_group *grp, const unsigned char *buf, size_t blen,
261 const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
262 {
263 const CCEcEdwDomain_t* pDomain;
264 CCEcEdwTempBuff_t* p_cc_temp_buf;
265 size_t pub_key_size;
266 uint8_t pub_key_buf[ (2*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*CC_32BIT_WORD_SIZE ] = {0};
267 uint8_t * p_signature;
268 int ret;
269 CCError_t status;
270
271 size_t order_size = 0;
272 size_t tmp_size = 0;
273 uint32_t signature_size = 0 ;
274
275 CC_UNUSED_PARAM(grp);
276
277 /* Verify inputs */
278 if (((buf == NULL) ^ (blen == 0)) ||
279 (Q == NULL) ||
280 (r == NULL) ||
281 (s == NULL))
282 {
283 CC_PAL_LOG_ERR("Failed check params");
284 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
285 }
286
287 pDomain = EcEdwGetDomain25519();
288 if (NULL == pDomain)
289 {
290 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
291 }
292
293 order_size = CALC_FULL_BYTES (pDomain->ecModSizeInBits);
294 signature_size = order_size*2 ;
295
296 /* Only the Y coordinate is required */
297 pub_key_size = order_size;
298 ret = ecdsa_export_mpi_to_buff( &Q->MBEDTLS_PRIVATE(Y), &pub_key_size, pub_key_buf, order_size );
299 if ((ret != 0) ||
300 (pub_key_size != order_size))
301 {
302 CC_PAL_LOG_ERR("Error - converting Q\n");
303 return ret;
304 }
305
306 p_cc_temp_buf = (CCEcEdwTempBuff_t*)mbedtls_calloc( 1, sizeof(CCEcEdwTempBuff_t) + signature_size );
307 if ( p_cc_temp_buf == NULL )
308 {
309 CC_PAL_LOG_ERR("Error - cant allocate memory for CC temp buf\n");
310 return MBEDTLS_ERR_ECP_ALLOC_FAILED;
311 }
312
313 p_signature = (uint8_t *)(p_cc_temp_buf + 1);
314 tmp_size = order_size;
315
316 ret = ecdsa_export_mpi_to_buff( r, &tmp_size, p_signature, order_size );
317 if ((ret != 0) ||
318 (tmp_size != order_size))
319 {
320 CC_PAL_LOG_ERR("Error - converting r\n");
321 goto end;
322 }
323
324 ret = ecdsa_export_mpi_to_buff( s, &tmp_size, p_signature + order_size, order_size );
325 if ((ret != 0) ||
326 (tmp_size != order_size))
327 {
328 CC_PAL_LOG_ERR("Error - converting s\n");
329 goto end;
330 }
331
332
333 status = CC_EcEdwVerify ( p_signature,
334 signature_size,
335 pub_key_buf,
336 pub_key_size,
337 (uint8_t*)buf,
338 blen,
339 p_cc_temp_buf);
340
341 if ( status != CC_OK )
342 {
343 ret = error_mapping_cc_to_mbedtls_ecc(status);
344 CC_PAL_LOG_ERR("Error - verification failed with return code 0x%08x\n", status);
345 }
346
347 end:
348 mbedtls_zeroize_internal(p_cc_temp_buf, sizeof(CCEcEdwTempBuff_t) + signature_size);
349 mbedtls_free( p_cc_temp_buf );
350 return ret;
351 }
352
353
mbedtls_ecdsa_public_key_read_edwards(mbedtls_ecp_point * Q,unsigned char * buf,size_t blen)354 int mbedtls_ecdsa_public_key_read_edwards( mbedtls_ecp_point *Q,
355 unsigned char *buf, size_t blen )
356 {
357 const CCEcEdwDomain_t *pDomain;
358 int ret;
359
360 if ((Q == NULL) ||
361 (buf == NULL) ||
362 (blen == 0)) {
363 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
364 }
365 pDomain = EcEdwGetDomain25519();
366 if (NULL == pDomain) {
367 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
368 }
369
370 if (blen != CALC_FULL_BYTES(pDomain->ecModSizeInBits)) {
371 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
372 }
373
374 ret = mbedtls_mpi_read_binary(&Q->MBEDTLS_PRIVATE(Y), buf, blen);
375 if (ret != 0)
376 {
377 CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
378 return ret;
379 }
380 Q->MBEDTLS_PRIVATE(Y).MBEDTLS_PRIVATE(s) = 1; /*unsigned*/
381
382 return CC_OK;
383
384 }
385
386
mbedtls_ecdsa_public_key_write_edwards(const mbedtls_ecp_point * Q,size_t * olen,unsigned char * buf,size_t blen)387 int mbedtls_ecdsa_public_key_write_edwards( const mbedtls_ecp_point *Q,
388 size_t *olen,
389 unsigned char *buf, size_t blen )
390 {
391 int ret;
392 uint32_t keySize;
393 const CCEcEdwDomain_t *pDomain;
394
395 if ((Q == NULL) ||
396 (olen == NULL) ||
397 (buf == NULL) ||
398 (blen == 0)) {
399 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
400 }
401 pDomain = EcEdwGetDomain25519();
402 if (NULL == pDomain) {
403 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
404 }
405 keySize = CALC_FULL_BYTES(pDomain->ecModSizeInBits);
406 if (blen < keySize)
407 {
408 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
409 }
410 ret = ecdsa_export_mpi_to_buff(&Q->MBEDTLS_PRIVATE(Y), olen, buf, keySize);
411 if (ret != 0)
412 {
413 CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
414 return ret;
415 }
416
417 return CC_OK;
418 }
419
420
421 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
422 #endif /* defined(MBEDTLS_ECDSA_C) */
423