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