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