1 /*
2  * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * References:
9  *
10  * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
11  */
12 
13 #include "mbedtls/build_info.h"
14 
15 #if defined(MBEDTLS_ECDSA_C)
16 
17 #include "mbedtls/ecdsa.h"
18 #include "mbedtls/asn1write.h"
19 
20 #include "cc_ecc_internal.h"
21 
22 
23 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) ||   \
24     defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) ||   \
25     defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ||   \
26     defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) ||   \
27     defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) ||   \
28     defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)   ||   \
29     defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)   ||   \
30     defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)   ||   \
31     defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||   \
32     defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||   \
33     defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
34 #define ECP_SHORTWEIERSTRASS
35 #endif
36 
37 #include "mbedtls_common.h"
38 #include "ecp_common.h"
39 #include "cc_pal_types.h"
40 #include "cc_pal_mem.h"
41 #include "cc_pal_abort.h"
42 #include "cc_common.h"
43 #include "cc_ecpki_error.h"
44 
45 #if defined (ECP_SHORTWEIERSTRASS)
46 
47 #include "cc_ecpki_ecdsa.h"
48 #include "cc_ecpki_build.h"
49 
50 #endif
51 #include "cc_ecpki_domain.h"
52 #if defined(MBEDTLS_PLATFORM_C)
53 #include "mbedtls/platform.h"
54 #else
55 #include <stdlib.h>
56 #include <stdio.h>
57 #define mbedtls_printf     printf
58 #define mbedtls_calloc    calloc
59 #define mbedtls_free       free
60 #endif
61 
62 #if defined(MBEDTLS_ECDSA_VERIFY_ALT) || defined (MBEDTLS_ECDSA_SIGN_ALT)
message_size_to_hash_mode(size_t bytelen)63 static CCEcpkiHashOpMode_t message_size_to_hash_mode( size_t bytelen )
64 {
65     CCEcpkiHashOpMode_t hash_mode;
66     size_t wordlen = (bytelen / sizeof(uint32_t));
67 
68     switch( wordlen )
69     {
70         case CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS:
71             hash_mode = CC_ECPKI_AFTER_HASH_SHA1_mode;
72             break;
73         case CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS:
74             hash_mode = CC_ECPKI_AFTER_HASH_SHA224_mode;
75             break;
76         case CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS:
77             hash_mode = CC_ECPKI_AFTER_HASH_SHA256_mode;
78             break;
79         case CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS:
80             hash_mode = CC_ECPKI_AFTER_HASH_SHA384_mode;
81             break;
82         case CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS:
83             hash_mode = CC_ECPKI_AFTER_HASH_SHA512_mode;
84             break;
85         default:
86             hash_mode = CC_ECPKI_AFTER_HASH_SHA512_mode;//use default value, to avoid checking the hash
87     }
88 
89     return hash_mode;
90 }
91 #endif
92 
93 #if defined(MBEDTLS_ECDSA_SIGN_ALT)
94 #if defined(ECP_SHORTWEIERSTRASS)
95 
ecdsa_wrst_sign(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)96 static int ecdsa_wrst_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
97                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
98                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
99 {
100     int ret;
101     CCEcpkiDomainID_t domainId;
102     CCEcdsaSignUserContext_t* temp_context;
103     CCRndContext_t      rnd_ctx;
104     uint8_t temp_buf[ (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*sizeof(uint32_t) ] = {0};
105     CCEcpkiUserPrivKey_t* priv_key;
106     const CCEcpkiDomain_t*  pDomain;
107     CCEcpkiHashOpMode_t hash_mode;
108     size_t signature_size;
109     uint8_t * pSignature;
110     size_t key_size, order_size;
111     uint32_t status;
112 
113     ret = ecp_grp_id_to_domain_id( grp->id, &domainId );
114     if (ret != 0)
115     {
116         return ret;
117     }
118     pDomain =  CC_EcpkiGetEcDomain( domainId );
119 
120     if (NULL == pDomain)
121     {
122         CC_PAL_LOG_ERR( "Error - domain id: %d is not supported\n",domainId );
123         return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
124     }
125 
126     rnd_ctx.rndGenerateVectFunc = f_rng;
127     rnd_ctx.rndState = p_rng;
128 
129     order_size = CALC_FULL_BYTES ( grp->nbits );
130     signature_size =  order_size*2;
131 
132     temp_context = (CCEcdsaSignUserContext_t *)mbedtls_calloc( 1, sizeof( CCEcdsaSignUserContext_t ) + signature_size + sizeof( CCEcpkiUserPrivKey_t ) );
133     if ( temp_context == NULL )
134     {
135         CC_PAL_LOG_ERR( "Error - failed to alloc memory for the temp context\n" );
136         return MBEDTLS_ERR_ECP_ALLOC_FAILED;
137     }
138     mbedtls_zeroize_internal( temp_context, signature_size + sizeof( CCEcdsaSignUserContext_t ) + sizeof( CCEcpkiUserPrivKey_t ) );
139 
140     key_size = mbedtls_mpi_size( d );
141 
142     hash_mode = message_size_to_hash_mode( blen );
143 
144     priv_key = (CCEcpkiUserPrivKey_t *)(temp_context + 1);
145 
146     pSignature = (uint8_t *)(priv_key + 1);
147 
148     ret = mbedtls_mpi_write_binary( d, temp_buf, key_size );
149 
150     if (ret !=0 )
151     {
152         CC_PAL_LOG_ERR( "Error - failed to convert d to binary\n" );
153         goto end;
154     }
155     status = CC_EcpkiPrivKeyBuild( pDomain,
156                              temp_buf,
157                              mbedtls_mpi_size( d ),
158                              priv_key );
159     if ( status != CC_OK )
160     {
161         CC_PAL_LOG_ERR( "Error - failed to build private key, return code is: %d\n", status );
162         ret = error_mapping_cc_to_mbedtls_ecc( status );
163          goto end;
164     }
165 
166     status =  CC_EcdsaSign( &rnd_ctx,
167                          temp_context,
168                          priv_key,
169                          hash_mode,
170                          (uint8_t*)buf,
171                          blen,
172                          pSignature,
173                          &signature_size );
174 
175     if ( status != CC_OK )
176     {
177         CC_PAL_LOG_ERR( "Error - signing failed, return code is: %d\n", status );
178         ret = error_mapping_cc_to_mbedtls_ecc( status );
179         goto end;
180     }
181 
182     ret = mbedtls_mpi_read_binary( r, pSignature, order_size );
183     if ( ret != 0 )
184     {
185         CC_PAL_LOG_ERR( "Error - failed to convert r\n" );
186         goto end;
187     }
188     ret = mbedtls_mpi_read_binary( s, pSignature + order_size , order_size );
189     if ( ret != 0 )
190     {
191         CC_PAL_LOG_ERR( "Error - failed to convert s\n" );
192         goto end;
193     }
194 
195 end:
196 
197        mbedtls_zeroize_internal( temp_context, signature_size + sizeof( CCEcdsaSignUserContext_t ) + sizeof( CCEcpkiUserPrivKey_t ) );
198        mbedtls_free( temp_context );
199 
200        return ret;
201 }
202 
203 #endif /*(ECP_SHORTWEIERSTRASS)*/
204 
205 /*
206  * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
207  * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
208  * The only exception is for curve 25519-Edwareds where we do hash
209  */
mbedtls_ecdsa_sign(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)210 int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
211                 const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
212                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
213 {
214 
215     /* Input parameters validation */
216     if (NULL == grp || NULL == r || NULL == s || NULL == d || NULL == buf)
217     {
218         CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
219         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
220 
221     }
222 
223 #if defined(ECP_SHORTWEIERSTRASS)
224 
225     if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
226     {
227         if(NULL == f_rng) /* Check only f_rng as mbedtls_psa_get_random does not need p_rng to be non-NULL */
228         {
229             CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
230             return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
231         }
232         return ecdsa_wrst_sign(grp, r, s, d, buf, blen, f_rng, p_rng);
233     }
234 #endif /* ECP_SHORTWEIERSTRASS */
235     return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
236 }
237 #endif /* MBEDTLS_ECDSA_SIGN_ALT */
238 
239 #if defined(MBEDTLS_ECDSA_VERIFY_ALT)
240 #if defined(ECP_SHORTWEIERSTRASS)
241 
ecdsa_wrst_verify(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s)242 static int ecdsa_wrst_verify( mbedtls_ecp_group *grp,
243                   const unsigned char *buf, size_t blen,
244                   const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
245 {
246     CCEcpkiHashOpMode_t hash_mode;
247     CCEcdsaVerifyUserContext_t* pTemp_context;
248     CCEcpkiUserPublKey_t* pPub_key;
249     size_t temp_size, order_size;
250     uint8_t pTemp_buf[ (2*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*sizeof(uint32_t) ] = {0};
251     uint8_t * pSignature;
252     CCEcpkiDomainID_t domainId;
253     const CCEcpkiDomain_t*  pDomain;
254     int ret;
255     CCError_t status;
256     uint32_t signature_size;
257 
258     order_size = CALC_FULL_BYTES ( grp->nbits );
259     signature_size = order_size *2;
260 
261 
262     hash_mode = message_size_to_hash_mode( blen );
263 
264     ret = ecp_grp_id_to_domain_id( grp->id, &domainId );
265     if (ret != 0)
266     {
267         return ret;
268     }
269     pDomain =  CC_EcpkiGetEcDomain(domainId);
270 
271     if (NULL == pDomain)
272     {
273         CC_PAL_LOG_ERR("Error - domain id %d is not supported\n",domainId);
274         return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
275     }
276 
277 
278     ret = mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
279                                            &temp_size, pTemp_buf, sizeof(pTemp_buf) );
280 
281     if (ret != 0)
282     {
283         CC_PAL_LOG_ERR("Error - converting Q\n");
284         return ret;
285     }
286 
287     pPub_key = (CCEcpkiUserPublKey_t*)mbedtls_calloc( 1, sizeof(CCEcpkiUserPublKey_t) + sizeof(CCEcdsaVerifyUserContext_t) + signature_size );
288     if ( pPub_key == NULL )
289     {
290         CC_PAL_LOG_ERR("Error - cant allocate memory for pPub_key\n");
291         return MBEDTLS_ERR_ECP_ALLOC_FAILED;
292     }
293     pTemp_context = (CCEcdsaVerifyUserContext_t*)(pPub_key + 1);
294     pSignature = (uint8_t *)(pTemp_context + 1);
295 
296     status = CC_EcpkiPubKeyBuild(pDomain, pTemp_buf, temp_size, pPub_key);
297     if (status != CC_OK)
298     {
299         ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
300         CC_PAL_LOG_ERR("Error - building public key failed with return code 0x%08x\n", status);
301         goto end;
302     }
303 
304     ret = mbedtls_mpi_write_binary( r, pSignature, order_size );
305     if ( ret != 0 )
306     {
307         CC_PAL_LOG_ERR("Error - converting r\n");
308         goto end;
309     }
310 
311     ret = mbedtls_mpi_write_binary( s, pSignature + order_size, order_size );
312     if ( ret != 0 )
313     {
314         CC_PAL_LOG_ERR("Error - converting s\n");
315         goto end;
316     }
317 
318 
319     status =  CC_EcdsaVerify ( pTemp_context,
320                                pPub_key,
321                                hash_mode,
322                                pSignature,
323                                signature_size,
324                                (uint8_t*)buf,
325                                blen );
326 
327     if ( status != CC_OK )
328     {
329         ret = error_mapping_cc_to_mbedtls_ecc(status);
330         CC_PAL_LOG_ERR("Error - verification failed with return code 0x%08x\n", status);
331     }
332 
333 end:
334     mbedtls_zeroize_internal(pPub_key, sizeof(CCEcpkiUserPublKey_t) + sizeof(CCEcdsaVerifyUserContext_t) + signature_size);
335     mbedtls_free( pPub_key );
336     return ret;
337 }
338 #endif /* ECP_SHORTWEIERSTRASS */
339 
340 
341 
342 /*
343  * Verify ECDSA signature of hashed message (SEC1 4.1.4)
344  * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
345  * The only exception is for curve 25519-Edwareds where we do hash
346  */
mbedtls_ecdsa_verify(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s)347 int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
348                   const unsigned char *buf, size_t blen,
349                   const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
350 {
351         /* Input parameters validation */
352     if (NULL == grp || NULL == r || NULL == s || NULL == Q || buf == NULL)
353     {
354         CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
355         return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
356 
357     }
358 
359 #if defined(ECP_SHORTWEIERSTRASS)
360 
361     if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
362     {
363         return ecdsa_wrst_verify(grp, buf, blen, Q, r, s);
364     }
365 #endif /* ECP_SHORTWEIERSTRASS */
366     return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
367 }
368 #endif /* MBEDTLS_ECDSA_VERIFY_ALT */
369 
370 #if defined(MBEDTLS_ECDSA_GENKEY_ALT)
371 /*
372  * Generate key pair
373  */
mbedtls_ecdsa_genkey(mbedtls_ecdsa_context * ctx,mbedtls_ecp_group_id gid,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)374 int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
375                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
376 {
377     return( mbedtls_ecp_group_load( &ctx->MBEDTLS_PRIVATE(grp), gid ) ||
378             cc_ecp_gen_keypair( &ctx->MBEDTLS_PRIVATE(grp), &ctx->MBEDTLS_PRIVATE(d), &ctx->MBEDTLS_PRIVATE(Q), f_rng, p_rng ) );
379 }
380 #endif /* MBEDTLS_ECDSA_GENKEY_ALT */
381 
382 #endif /* defined(MBEDTLS_ECDSA_C) */
383