1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <string.h>
12
13 #include <limits.h>
14
15 /* mbedtls lib */
16 #include "mbedtls/ecdsa.h"
17 #include "mbedtls/ecp.h"
18 #include "mbedtls/timing.h"
19 #include "mbedtls/bignum.h"
20 #include "mbedtls/ctr_drbg.h"
21 #include "mbedtls_cc_ecdsa_edwards.h"
22
23 /* local */
24 #include "run_integration_pal_log.h"
25 #include "run_integration_test.h"
26 #include "run_integration_helper.h"
27
28 #if defined MBEDTLS_ECDSA_C
29 /************************************************************
30 *
31 * defines
32 *
33 ************************************************************/
34 #define DIGEST_SIZE 64
35 #define ECP_GROUP_ID MBEDTLS_ECP_DP_SECP256R1
36 #define ECP_GROUP_ID_STR "DP_SECP256R1"
37 #define MD_TYPE_ID MBEDTLS_MD_SHA256
38 #define MD_TYPE_ID_STR "SHA256"
39
40 #define RUNIT_ECDSA_TEST_R521 0
41 /************************************************************
42 *
43 * static function prototypes
44 *
45 ************************************************************/
46 static RunItError_t runIt_ecdsaPrimRandomTest(void);
47 static RunItError_t runIt_ecdsaPrimVectorsTest(void);
48 static RunItError_t runIt_ecdsaDetVectorsTest(void);
49 static RunItError_t runIt_ecdsaWriteReadRandomTest(void);
50 static RunItError_t runIt_ecdsaPrimRandomEdwTest(void);
51
52 /************************************************************
53 *
54 * variables
55 *
56 ************************************************************/
57
58 /************************************************************
59 *
60 * static functions
61 *
62 ************************************************************/
runIt_ecdsaPrimRandomTest(void)63 static RunItError_t runIt_ecdsaPrimRandomTest(void)
64 {
65 RunItError_t rc = RUNIT_ERROR__OK;
66
67 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
68 mbedtls_ecp_group_id id = RUNIT_ECDSA_TEST_R521 ? MBEDTLS_ECP_DP_SECP521R1 : MBEDTLS_ECP_DP_SECP256R1;
69 mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
70 mbedtls_ecp_group *pGrp = NULL;
71 mbedtls_ecp_point *pQ = NULL;
72 mbedtls_mpi d, r, s;
73 unsigned char *pBuf = NULL;
74
75 RunItPtr grpPtr;
76 RunItPtr qPtr;
77 RunItPtr bufPtr;
78
79 const char* TEST_NAME = "ECDSA Primary Random";
80 RUNIT_SUB_TEST_START(TEST_NAME);
81
82 ALLOC(bufPtr, pBuf, DIGEST_SIZE);
83 ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
84 ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
85
86 mbedtls_ecp_group_init(pGrp);
87 mbedtls_ecp_point_init(pQ);
88 mbedtls_mpi_init(&d);
89 mbedtls_mpi_init(&r);
90 mbedtls_mpi_init(&s);
91 memset(pBuf, 0, DIGEST_SIZE);
92
93 RUNIT_ASSERT(mbedtls_ctr_drbg_random(pCtrDrbg, pBuf, DIGEST_SIZE) == 0);
94 RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, id) == 0);
95 RUNIT_ASSERT(mbedtls_ecp_gen_keypair(pGrp, &d, pQ, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
96 RUNIT_ASSERT_API(mbedtls_ecdsa_sign(pGrp, &r, &s, &d, pBuf, DIGEST_SIZE, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
97 RUNIT_ASSERT_API(mbedtls_ecdsa_verify(pGrp, pBuf, DIGEST_SIZE, pQ, &r, &s) == 0);
98
99 bail:
100 mbedtls_ecp_group_free(pGrp);
101 mbedtls_ecp_point_free(pQ);
102
103 mbedtls_mpi_free(&d);
104 mbedtls_mpi_free(&r);
105 mbedtls_mpi_free(&s);
106
107 FREE_IF_NOT_NULL(grpPtr);
108 FREE_IF_NOT_NULL(qPtr);
109 FREE_IF_NOT_NULL(bufPtr);
110
111 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s]", mbedtls_ecp_curve_info_from_grp_id(id)->name);
112 #endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) */
113 return rc;
114 }
115
runIt_ecdsaPrimRandomEdwTest(void)116 static RunItError_t runIt_ecdsaPrimRandomEdwTest(void)
117 {
118 RunItError_t rc = RUNIT_ERROR__OK;
119
120 size_t data_len = 200;
121
122 mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
123 mbedtls_ecdsa_context *pCtx = NULL;
124
125 unsigned char *pDataIn = NULL;
126
127 RunItPtr ctxPtr;
128 RunItPtr dataPtr;
129
130 mbedtls_mpi r, s;
131 const char* TEST_NAME = "ECDSA Random Edwards";
132 RUNIT_SUB_TEST_START(TEST_NAME);
133
134 mbedtls_mpi_init( &r );
135 mbedtls_mpi_init( &s );
136
137
138 ALLOC_STRUCT(mbedtls_ecdsa_context, ctxPtr, pCtx);
139 ALLOC(dataPtr, pDataIn, data_len);
140
141 RUNIT_API(mbedtls_ecdsa_init(pCtx));
142
143 /* prepare material for signature */
144 RUNIT_ASSERT_WITH_RESULT(mbedtls_ctr_drbg_random(pCtrDrbg, pDataIn, data_len), 0);
145
146 /* generate signing key */
147 RUNIT_ASSERT_WITH_RESULT( mbedtls_ecdsa_genkey_edwards(pCtx, MBEDTLS_ECP_DP_CURVE25519, mbedtls_ctr_drbg_random, pCtrDrbg), 0);
148 RUNIT_ASSERT_WITH_RESULT( mbedtls_ecdsa_sign_edwards( &pCtx->grp, &r, &s, &pCtx->d, pDataIn, data_len), 0 );
149 RUNIT_ASSERT_WITH_RESULT( mbedtls_ecdsa_verify_edwards(&pCtx->grp, pDataIn, data_len, &pCtx->Q, &r, &s), 0 );
150
151 bail:
152 RUNIT_API(mbedtls_ecdsa_free(pCtx));
153
154 FREE_IF_NOT_NULL(ctxPtr);
155 FREE_IF_NOT_NULL(dataPtr);
156
157 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[DP_CURVE25519] MD[%s]", MD_TYPE_ID_STR);
158 return rc;
159 }
160
runIt_ecdsaPrimVectorsTest(void)161 static RunItError_t runIt_ecdsaPrimVectorsTest(void)
162 {
163 RunItError_t rc = RUNIT_ERROR__OK;
164
165 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
166 static const char *d_str = "DC51D3866A15BACDE33D96F992FCA99DA7E6EF0934E7097559C27F1614C88A7F";
167 static const char *xQ_str = "2442A5CC0ECD015FA3CA31DC8E2BBC70BF42D60CBCA20085E0822CB04235E970";
168 static const char *yQ_str = "6FC98BD7E50211A4A27102FA3549DF79EBCB4BF246B80945CDDFE7D509BBFD7D";
169 static const char *k_str = "9E56F509196784D963D1C0A401510EE7ADA3DCC5DEE04B154BF61AF1D5A6DECE";
170 static const char *hash_str = "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD";
171 static const char *r_str = "CB28E0999B9C7715FD0A80D8E47A77079716CBBF917DD72E97566EA1C066957C";
172 static const char *s_str = "86FA3BB4E26CAD5BF90B7F81899256CE7594BB1EA0C89212748BFF3B3D5B0315";
173
174 mbedtls_ecp_group *pGrp = NULL;
175 mbedtls_ecp_point *pQ = NULL;
176 mbedtls_mpi d;
177 mbedtls_mpi r;
178 mbedtls_mpi s;
179 mbedtls_mpi rCheck;
180 mbedtls_mpi sCheck;
181 unsigned char *pHash = NULL;
182 unsigned char *pRndBuf = NULL;
183
184 RunItPtr grpPtr;
185 RunItPtr qPtr;
186 RunItPtr hashPtr;
187 RunItPtr rndBufPtr;
188
189 size_t hlen;
190 rnd_buf_info rnd_info;
191
192 const char* TEST_NAME = "ECDSA Primary Vector";
193 RUNIT_SUB_TEST_START(TEST_NAME);
194
195 ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
196 ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
197 ALLOC(hashPtr, pHash, 66);
198 ALLOC(rndBufPtr, pRndBuf, 66);
199
200 mbedtls_ecp_group_init(pGrp);
201 mbedtls_ecp_point_init(pQ);
202 mbedtls_mpi_init(&d);
203 mbedtls_mpi_init(&r);
204 mbedtls_mpi_init(&s);
205 mbedtls_mpi_init(&rCheck);
206 mbedtls_mpi_init(&sCheck);
207 memset(pHash, 0, 66);
208 memset(pRndBuf, 0, 66);
209
210 RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, ECP_GROUP_ID) == 0);
211 RUNIT_ASSERT(mbedtls_ecp_point_read_string(pQ, 16, xQ_str, yQ_str) == 0);
212
213 RUNIT_ASSERT(mbedtls_mpi_read_string(&d, 16, d_str) == 0);
214 RUNIT_ASSERT(mbedtls_mpi_read_string(&rCheck, 16, r_str) == 0);
215 RUNIT_ASSERT(mbedtls_mpi_read_string(&sCheck, 16, s_str) == 0);
216
217 hlen = runIt_unhexify(pHash, hash_str);
218
219 rnd_info.buf = pRndBuf;
220 rnd_info.length = runIt_unhexify(pRndBuf, k_str);
221
222 /* Fix pRndBuf by shifting it left if necessary */
223 if (pGrp->nbits % 8 != 0)
224 {
225 unsigned char shift = 8 - (pGrp->nbits % 8);
226 size_t i;
227
228 for (i = 0; i < rnd_info.length - 1; i++)
229 pRndBuf[i] = pRndBuf[i] << shift | pRndBuf[i + 1] >> (8 - shift);
230
231 pRndBuf[rnd_info.length - 1] <<= shift;
232 }
233
234 RUNIT_ASSERT_API(mbedtls_ecdsa_sign(pGrp, &r, &s, &d, pHash, hlen, runIt_rndBufferRand, &rnd_info) == 0);
235 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&r, &rCheck) == 0);
236 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&s, &sCheck) == 0);
237 RUNIT_ASSERT_API(mbedtls_ecdsa_verify(pGrp, pHash, hlen, pQ, &rCheck, &sCheck) == 0);
238
239 bail:
240 mbedtls_ecp_group_free(pGrp);
241 mbedtls_ecp_point_free(pQ);
242
243 mbedtls_mpi_free(&d);
244 mbedtls_mpi_free(&r);
245 mbedtls_mpi_free(&s);
246 mbedtls_mpi_free(&rCheck);
247 mbedtls_mpi_free(&sCheck);
248
249 FREE_IF_NOT_NULL(grpPtr);
250 FREE_IF_NOT_NULL(qPtr);
251 FREE_IF_NOT_NULL(hashPtr);
252 FREE_IF_NOT_NULL(rndBufPtr);
253
254 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s]", ECP_GROUP_ID_STR);
255 #endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) */
256 return rc;
257 }
258
runIt_ecdsaDetVectorsTest(void)259 static RunItError_t runIt_ecdsaDetVectorsTest(void)
260 {
261 RunItError_t rc = RUNIT_ERROR__OK;
262
263 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C)
264
265 #if RUNIT_ECDSA_TEST_R521
266 mbedtls_ecp_group_id id = MBEDTLS_ECP_DP_SECP521R1;
267 static const char *d_str = "0100085F47B8E1B8B11B7EB33028C0B2888E304BFC98501955B45BBA1478DC184EEEDF09B86A5F7C21994406072787205E69A63709FE35AA93BA333514B24F961722";
268 static const mbedtls_md_type_t md_alg = MBEDTLS_MD_SHA512;
269 static const char *msg = "Example of ECDSA with P-521";
270 static const char *r_str = "26B55806BC7F28FF38323A46DB837CCA018FE58B766577498AAC828A76E272D61657E3C386F2FA940CDEC5961F9A81800F1385D2AF365C88B4E341824C5203D0CD";
271 static const char *s_str = "01399C2DBA893C4296C9EB06C29E2B87114EE1A8AF7EFF2312737C147AAC69BF77EB4BE520406EADAB45AE2621970B175B0213526B939FCE6B780523C20693B33601";
272 #else
273 mbedtls_ecp_group_id id = ECP_GROUP_ID;
274 static const char *d_str = "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721";
275 static const mbedtls_md_type_t md_alg = MD_TYPE_ID;
276 static const char *msg = "sample";
277 static const char *r_str = "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716";
278 static const char *s_str = "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8";
279 #endif
280
281 size_t hlen;
282 const mbedtls_md_info_t *md_info;
283
284 unsigned char *pHash = NULL;
285 mbedtls_ecp_group *pGrp = NULL;
286 mbedtls_mpi *pD = NULL;
287 mbedtls_mpi *pR = NULL;
288 mbedtls_mpi *pS = NULL;
289 mbedtls_mpi *pRCheck = NULL;
290 mbedtls_mpi *pSCheck = NULL;
291
292 RunItPtr hashPtr;
293 RunItPtr grpPtr;
294 RunItPtr dPtr;
295 RunItPtr rPtr;
296 RunItPtr sPtr;
297 RunItPtr rCheckPtr;
298 RunItPtr sCheckPtr;
299
300 const char* TEST_NAME = "ECDSA Det Primary Vector";
301 RUNIT_SUB_TEST_START(TEST_NAME);
302
303 md_info = mbedtls_md_info_from_type(md_alg);
304 RUNIT_ASSERT(md_info != NULL);
305
306 ALLOC(hashPtr, pHash, MBEDTLS_MD_MAX_SIZE);
307 ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
308 ALLOC_STRUCT(mbedtls_mpi, dPtr, pD);
309 ALLOC_STRUCT(mbedtls_mpi, rPtr, pR);
310 ALLOC_STRUCT(mbedtls_mpi, sPtr, pS);
311 ALLOC_STRUCT(mbedtls_mpi, rCheckPtr, pRCheck);
312 ALLOC_STRUCT(mbedtls_mpi, sCheckPtr, pSCheck);
313
314 memset(pHash, 0, MBEDTLS_MD_MAX_SIZE);
315 mbedtls_ecp_group_init(pGrp);
316 mbedtls_mpi_init(pD);
317 mbedtls_mpi_init(pR);
318 mbedtls_mpi_init(pS);
319 mbedtls_mpi_init(pRCheck);
320 mbedtls_mpi_init(pSCheck);
321
322 RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, id) == 0);
323
324 RUNIT_ASSERT(mbedtls_mpi_read_string(pD, 16, d_str) == 0);
325 RUNIT_ASSERT(mbedtls_mpi_read_string(pRCheck, 16, r_str) == 0);
326 RUNIT_ASSERT(mbedtls_mpi_read_string(pSCheck, 16, s_str) == 0);
327
328 hlen = mbedtls_md_get_size(md_info);
329
330 RUNIT_ASSERT_API(mbedtls_md(md_info, (const unsigned char *) msg, strlen(msg), pHash) == 0);
331 RUNIT_ASSERT_API(mbedtls_ecdsa_sign_det(pGrp, pR, pS, pD, pHash, hlen, md_alg) == 0);
332
333 #if 0
334 {
335 char buff[300] = {0};
336 uint32_t len = 0;
337 RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pR, 16, buff, 299, &len), 0);
338 RUNIT_PRINT_DBG("pR[%s]\n", buff);
339 RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pRCheck, 16, buff, 299, &len), 0);
340 RUNIT_PRINT_DBG("pRCheck[%s]\n", buff);
341
342 RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pS, 16, buff, 299, &len), 0);
343 RUNIT_PRINT_DBG("pS[%s]\n", buff);
344 RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pSCheck, 16, buff, 299, &len), 0);
345 RUNIT_PRINT_DBG("pSCheck[%s]\n", buff);
346 }
347 #endif /* 0 */
348
349 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(pR, pRCheck) == 0);
350 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(pS, pSCheck) == 0);
351
352 bail:
353 mbedtls_ecp_group_free(pGrp);
354
355 mbedtls_mpi_free(pD);
356 mbedtls_mpi_free(pR);
357 mbedtls_mpi_free(pS);
358 mbedtls_mpi_free(pRCheck);
359 mbedtls_mpi_free(pSCheck);
360
361 FREE_IF_NOT_NULL(hashPtr);
362 FREE_IF_NOT_NULL(grpPtr);
363 FREE_IF_NOT_NULL(dPtr);
364 FREE_IF_NOT_NULL(rPtr);
365 FREE_IF_NOT_NULL(sPtr);
366 FREE_IF_NOT_NULL(rCheckPtr);
367 FREE_IF_NOT_NULL(sCheckPtr);
368
369 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] MD[%s]", (mbedtls_ecp_curve_info_from_grp_id(id)->name), mbedtls_md_get_name(md_info));
370 #endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C) */
371 return rc;
372 }
373
runIt_ecdsaWriteReadRandomTest(void)374 static RunItError_t runIt_ecdsaWriteReadRandomTest(void)
375 {
376 RunItError_t rc = RUNIT_ERROR__OK;
377
378 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C)
379 unsigned char hash[32];
380 size_t sig_len;
381
382 mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
383 mbedtls_ecdsa_context *pCtx = NULL;
384 unsigned char *pSig = NULL;
385
386 RunItPtr ctxPtr;
387 RunItPtr sigPtr;
388
389 const char* TEST_NAME = "ECDSA Write Read Random";
390 RUNIT_SUB_TEST_START(TEST_NAME);
391
392 ALLOC_STRUCT(mbedtls_ecdsa_context, ctxPtr, pCtx);
393 ALLOC(sigPtr, pSig, 200);
394
395 RUNIT_API(mbedtls_ecdsa_init(pCtx));
396 memset(hash, 0, sizeof(hash));
397 memset(pSig, 0, 200);
398
399 /* prepare material for signature */
400 RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtrDrbg, hash, sizeof(hash)) == 0);
401
402 /* generate signing key */
403 RUNIT_ASSERT_API(mbedtls_ecdsa_genkey(pCtx, ECP_GROUP_ID, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
404 RUNIT_ASSERT_API(mbedtls_ecdsa_write_signature(pCtx, MD_TYPE_ID, hash, sizeof(hash), pSig, &sig_len, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
405 RUNIT_ASSERT_API(mbedtls_ecdsa_read_signature(pCtx, hash, sizeof(hash), pSig, sig_len) == 0);
406
407 bail:
408 RUNIT_API(mbedtls_ecdsa_free(pCtx));
409
410 FREE_IF_NOT_NULL(ctxPtr);
411 FREE_IF_NOT_NULL(sigPtr);
412
413 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] MD[%s]", ECP_GROUP_ID_STR, MD_TYPE_ID_STR);
414 #endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C) */
415 return rc;
416 }
417
418 /************************************************************
419 *
420 * public functions
421 *
422 ************************************************************/
runIt_ecdsaTest(void)423 RunItError_t runIt_ecdsaTest(void)
424 {
425 RunItError_t rc = RUNIT_ERROR__OK;
426
427 const char* TEST_NAME = "ECDSA";
428 RUNIT_TEST_START(TEST_NAME);
429
430 RUNIT_ASSERT(runIt_ecdsaPrimRandomTest() == RUNIT_ERROR__OK);
431 RUNIT_ASSERT(runIt_ecdsaPrimVectorsTest() == RUNIT_ERROR__OK);
432 RUNIT_ASSERT(runIt_ecdsaDetVectorsTest() == RUNIT_ERROR__OK);
433 RUNIT_ASSERT(runIt_ecdsaWriteReadRandomTest() == RUNIT_ERROR__OK);
434 RUNIT_ASSERT(runIt_ecdsaPrimRandomEdwTest() == RUNIT_ERROR__OK);
435
436 bail:
437 RUNIT_TEST_RESULT(TEST_NAME);
438 return rc;
439 }
440 #endif /* MBEDTLS_ECDSA_C */
441