Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/libecc/src/tests/ec_utils.c
2066 views
1
/*
2
* Copyright (C) 2017 - This file is part of libecc project
3
*
4
* Authors:
5
* Ryad BENADJILA <[email protected]>
6
* Arnaud EBALARD <[email protected]>
7
* Jean-Pierre FLORI <[email protected]>
8
*
9
* Contributors:
10
* Nicolas VIVET <[email protected]>
11
* Karim KHALFALLAH <[email protected]>
12
*
13
* This software is licensed under a dual BSD and GPL v2 license.
14
* See LICENSE file at the root folder of the project.
15
*/
16
17
#include <libecc/libsig.h>
18
19
#ifdef WITH_STDLIB
20
#include <string.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <errno.h>
24
#endif
25
26
#define HDR_MAGIC 0x34215609
27
28
typedef enum {
29
IMAGE_TYPE_UNKNOWN = 0,
30
IMAGE_TYPE0 = 1,
31
IMAGE_TYPE1 = 2,
32
IMAGE_TYPE2 = 3,
33
IMAGE_TYPE3 = 4,
34
/* Info: You can add more image header types */
35
} image_type;
36
37
/* Generic header to prepend data */
38
typedef struct {
39
u32 magic; /* header header */
40
u32 type; /* Type of the signed image */
41
u32 version; /* Version */
42
u32 len; /* length of data after header */
43
u32 siglen; /* length of sig (on header + data) */
44
} ATTRIBUTE_PACKED metadata_hdr;
45
46
/* Max stack working buffer size */
47
#define MAX_BUF_LEN 8192
48
49
typedef enum {
50
RAWBIN,
51
DOTH,
52
} export_file_type;
53
54
ATTRIBUTE_WARN_UNUSED_RET static int export_private_key(FILE * file, const char *name,
55
const ec_priv_key *priv_key,
56
export_file_type file_type)
57
{
58
u8 export_buf_size, priv_key_buf[EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE];
59
size_t written;
60
int ret;
61
u32 i;
62
63
MUST_HAVE(file != NULL, ret, err);
64
65
ret = priv_key_check_initialized(priv_key);
66
if (ret) {
67
printf("Error checking private key\n");
68
ret = -1;
69
goto err;
70
}
71
72
/* Serialize the private key to a buffer */
73
export_buf_size = EC_STRUCTURED_PRIV_KEY_EXPORT_SIZE(priv_key);
74
ret = ec_structured_priv_key_export_to_buf(priv_key, priv_key_buf,
75
export_buf_size);
76
if (ret) {
77
printf("Error exporting private key to buffer\n");
78
ret = -1;
79
goto err;
80
}
81
82
/* Export the private key to the file */
83
switch (file_type) {
84
case DOTH:
85
MUST_HAVE(name != NULL, ret, err);
86
fprintf(file, "const char %s[] = { ", name);
87
for (i = 0; i < export_buf_size; i++) {
88
fprintf(file, "0x%02x", priv_key_buf[i]);
89
fprintf(file, ", ");
90
}
91
fprintf(file, "};\n");
92
ret = 0;
93
break;
94
case RAWBIN:
95
written = fwrite(priv_key_buf, 1, export_buf_size, file);
96
if(written != export_buf_size){
97
ret = -1;
98
goto err;
99
}
100
ret = 0;
101
break;
102
default:
103
ret = -1;
104
}
105
106
err:
107
return ret;
108
}
109
110
ATTRIBUTE_WARN_UNUSED_RET static int export_public_key(FILE * file, const char *name,
111
const ec_pub_key *pub_key,
112
export_file_type file_type)
113
{
114
u8 pub_key_buf[EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE];
115
u8 export_buf_size;
116
int ret;
117
u32 i;
118
size_t written;
119
120
MUST_HAVE(file != NULL, ret, err);
121
ret = pub_key_check_initialized(pub_key);
122
if (ret) {
123
printf("Error checking public key\n");
124
ret = -1;
125
goto err;
126
}
127
128
/* Serialize the public key to a buffer */
129
export_buf_size = EC_STRUCTURED_PUB_KEY_EXPORT_SIZE(pub_key);
130
ret = ec_structured_pub_key_export_to_buf(pub_key, pub_key_buf,
131
export_buf_size);
132
if (ret) {
133
printf("Error exporting public key to buffer\n");
134
ret = -1;
135
goto err;
136
}
137
138
/* Export the public key to the file */
139
switch (file_type) {
140
case DOTH:
141
MUST_HAVE(name != NULL, ret, err);
142
fprintf(file, "const char %s[] = { ", name);
143
for (i = 0; i < export_buf_size; i++) {
144
fprintf(file, "0x%02x", pub_key_buf[i]);
145
if (i != export_buf_size) {
146
fprintf(file, ", ");
147
}
148
}
149
fprintf(file, "};\n");
150
ret = 0;
151
break;
152
case RAWBIN:
153
written = fwrite(pub_key_buf, 1, export_buf_size, file);
154
if(written != export_buf_size){
155
ret = -1;
156
goto err;
157
}
158
ret = 0;
159
break;
160
default:
161
ret = -1;
162
}
163
164
err:
165
return ret;
166
}
167
168
ATTRIBUTE_WARN_UNUSED_RET static int string_to_params(const char *ec_name, const char *ec_sig_name,
169
ec_alg_type * sig_type,
170
const ec_str_params ** ec_str_p,
171
const char *hash_name, hash_alg_type * hash_type)
172
{
173
const ec_str_params *curve_params;
174
const ec_sig_mapping *sm;
175
const hash_mapping *hm;
176
u32 curve_name_len;
177
int ret;
178
179
if (sig_type != NULL) {
180
/* Get sig type from signature alg name */
181
ret = get_sig_by_name(ec_sig_name, &sm);
182
if ((ret) || (!sm)) {
183
ret = -1;
184
printf("Error: signature type %s is unknown!\n",
185
ec_sig_name);
186
goto err;
187
}
188
*sig_type = sm->type;
189
}
190
191
if (ec_str_p != NULL) {
192
/* Get curve params from curve name */
193
ret = local_strlen((const char *)ec_name, &curve_name_len); EG(ret, err);
194
curve_name_len += 1;
195
if(curve_name_len > 255){
196
/* Sanity check */
197
ret = -1;
198
goto err;
199
}
200
ret = ec_get_curve_params_by_name((const u8 *)ec_name,
201
(u8)curve_name_len, &curve_params);
202
if ((ret) || (!curve_params)) {
203
ret = -1;
204
printf("Error: EC curve %s is unknown!\n", ec_name);
205
goto err;
206
}
207
*ec_str_p = curve_params;
208
}
209
210
if (hash_type != NULL) {
211
/* Get hash type from hash alg name */
212
ret = get_hash_by_name(hash_name, &hm);
213
if ((ret) || (!hm)) {
214
ret = -1;
215
printf("Error: hash function %s is unknown!\n",
216
hash_name);
217
goto err;
218
}
219
*hash_type = hm->type;
220
}
221
222
ret = 0;
223
224
err:
225
return ret;
226
}
227
228
ATTRIBUTE_WARN_UNUSED_RET static int generate_and_export_key_pair(const char *ec_name,
229
const char *ec_sig_name,
230
const char *fname_prefix)
231
{
232
const ec_str_params *ec_str_p;
233
char fname[MAX_BUF_LEN];
234
char kname[MAX_BUF_LEN];
235
const u16 fname_len = sizeof(fname);
236
const u16 kname_len = sizeof(kname);
237
u16 prefix_len;
238
u32 len;
239
ec_alg_type sig_type;
240
ec_params params;
241
ec_key_pair kp;
242
FILE *file = NULL;
243
int ret;
244
245
MUST_HAVE(ec_name != NULL, ret, err);
246
MUST_HAVE(fname_prefix != NULL, ret, err);
247
MUST_HAVE(ec_sig_name != NULL, ret, err);
248
249
/* Get parameters from pretty names */
250
ret = string_to_params(ec_name, ec_sig_name, &sig_type, &ec_str_p,
251
NULL, NULL);
252
if (ret) {
253
ret = -1;
254
printf("Error: error when importing params\n");
255
goto err;
256
}
257
258
/* Import the parameters */
259
ret = import_params(&params, ec_str_p); EG(ret, err);
260
261
/* Generate the key pair */
262
ret = ec_key_pair_gen(&kp, &params, sig_type); EG(ret, err);
263
264
/* Get the unique affine equivalent representation of the projective point for the public key.
265
* This avoids ambiguity when exporting the point, and is mostly here
266
* for compatibility with external libraries.
267
*/
268
ret = prj_pt_unique(&(kp.pub_key.y), &(kp.pub_key.y)); EG(ret, err);
269
270
/*************************/
271
272
/* Export the private key to the raw binary file */
273
ret = local_strnlen(fname_prefix, fname_len, &len); EG(ret, err);
274
MUST_HAVE(len <= 0xffff, ret, err);
275
prefix_len = (u16)len;
276
ret = local_memset(fname, 0, fname_len); EG(ret, err);
277
ret = local_memcpy(fname, fname_prefix, prefix_len); EG(ret, err);
278
ret = local_strncat(fname, "_private_key.bin", (u32)(fname_len - prefix_len)); EG(ret, err);
279
file = fopen(fname, "wb");
280
if (file == NULL) {
281
ret = -1;
282
printf("Error: file %s cannot be opened\n", fname);
283
goto err;
284
}
285
286
ret = export_private_key(file, NULL, &(kp.priv_key), RAWBIN);
287
if (ret) {
288
ret = -1;
289
printf("Error exporting the private key\n");
290
goto err;
291
}
292
ret = fclose(file); EG(ret, err);
293
file = NULL;
294
295
/* Export the private key to the .h file */
296
ret = local_memset(fname, 0, fname_len); EG(ret, err);
297
ret = local_memcpy(fname, fname_prefix, prefix_len); EG(ret, err);
298
ret = local_strncat(fname, "_private_key.h", (u32)(fname_len - prefix_len)); EG(ret, err);
299
file = fopen(fname, "w");
300
if (file == NULL) {
301
ret = -1;
302
printf("Error: file %s cannot be opened\n", fname);
303
goto err;
304
}
305
306
snprintf(kname, kname_len, "%s_%s_private_key", ec_name, ec_sig_name);
307
ret = export_private_key(file, kname, &(kp.priv_key), DOTH);
308
if (ret) {
309
ret = -1;
310
printf("Error: error exporting the private key\n");
311
goto err;
312
}
313
ret = fclose(file); EG(ret, err);
314
file = NULL;
315
316
/*************************/
317
318
/* Export the public key to the raw binary file */
319
ret = local_memset(fname, 0, fname_len); EG(ret, err);
320
ret = local_memcpy(fname, fname_prefix, prefix_len); EG(ret, err);
321
ret = local_strncat(fname, "_public_key.bin", (u32)(fname_len - prefix_len)); EG(ret, err);
322
file = fopen(fname, "wb");
323
if (file == NULL) {
324
ret = -1;
325
printf("Error: file %s cannot be opened\n", fname);
326
goto err;
327
}
328
ret = export_public_key(file, NULL, &(kp.pub_key), RAWBIN);
329
if (ret) {
330
ret = -1;
331
printf("Error exporting the public key\n");
332
goto err;
333
}
334
ret = fclose(file); EG(ret, err);
335
file = NULL;
336
337
/* Export the public key to the .h file */
338
ret = local_memset(fname, 0, fname_len); EG(ret, err);
339
ret = local_memcpy(fname, fname_prefix, prefix_len); EG(ret, err);
340
ret = local_strncat(fname, "_public_key.h", (u32)(fname_len - prefix_len)); EG(ret, err);
341
file = fopen(fname, "w");
342
if (file == NULL) {
343
ret = -1;
344
printf("Error: file %s cannot be opened\n", fname);
345
goto err;
346
}
347
348
snprintf(kname, kname_len, "%s_%s_public_key", ec_name, ec_sig_name);
349
ret = export_public_key(file, kname, &(kp.pub_key), DOTH);
350
if (ret) {
351
ret = -1;
352
printf("Error exporting the public key\n");
353
goto err;
354
}
355
ret = fclose(file); EG(ret, err);
356
file = NULL;
357
358
ret = 0;
359
360
err:
361
if(file != NULL){
362
if(fclose(file)){
363
ret = -1;
364
}
365
}
366
return ret;
367
}
368
369
370
ATTRIBUTE_WARN_UNUSED_RET static int store_sig(const char *in_fname, const char *out_fname,
371
const u8 *sig, u32 siglen,
372
ec_alg_type sig_type, hash_alg_type hash_type,
373
const u8 curve_name[MAX_CURVE_NAME_LEN],
374
metadata_hdr * hdr)
375
{
376
FILE *in_file = NULL, *out_file = NULL;
377
u8 buf[MAX_BUF_LEN];
378
size_t read, written;
379
int ret;
380
381
MUST_HAVE((in_fname != NULL), ret, err);
382
MUST_HAVE((out_fname != NULL), ret, err);
383
MUST_HAVE((sig != NULL), ret, err);
384
MUST_HAVE((curve_name != NULL), ret, err);
385
MUST_HAVE((hdr != NULL), ret, err);
386
#if (MAX_BUF_LEN <= 255)
387
/* No need to check this is sizeof(buf) exceeds 256.
388
* (avoids -Werror,-Wtautological-constant-out-of-range-compare)
389
*/
390
MUST_HAVE(EC_STRUCTURED_SIG_EXPORT_SIZE(siglen) <= sizeof(buf), ret, err);
391
#endif
392
/* Import the data from the input file */
393
in_file = fopen(in_fname, "rb");
394
if (in_file == NULL) {
395
ret = -1;
396
printf("Error: file %s cannot be opened\n", in_fname);
397
goto err;
398
}
399
out_file = fopen(out_fname, "wb");
400
if (out_file == NULL) {
401
ret = -1;
402
printf("Error: file %s cannot be opened\n", out_fname);
403
goto err;
404
}
405
if (hdr != NULL) {
406
/* Write the metadata header as a prepending information */
407
written = fwrite(hdr, 1, sizeof(metadata_hdr), out_file);
408
if (written != sizeof(metadata_hdr)) {
409
ret = -1;
410
goto err;
411
}
412
}
413
414
while (1) {
415
read = fread(buf, 1, sizeof(buf), in_file);
416
written = fwrite(buf, 1, read, out_file);
417
if (written != read) {
418
ret = -1;
419
printf("Error: error when writing to %s\n",
420
out_fname);
421
goto err;
422
}
423
if (read != sizeof(buf)) {
424
if (feof(in_file)) {
425
/* EOF */
426
break;
427
} else {
428
ret = -1;
429
printf("Error: error when reading from %s\n",
430
in_fname);
431
goto err;
432
}
433
}
434
435
}
436
437
/* Compute the structured signature */
438
ret = ec_structured_sig_export_to_buf(sig, siglen, buf, sizeof(buf),
439
sig_type, hash_type, curve_name);
440
if (ret) {
441
ret = -1;
442
printf("Error: error when exporting signature to structured buffer\n");
443
goto err;
444
}
445
/* Store the signature buffer */
446
written =
447
fwrite(buf, 1, EC_STRUCTURED_SIG_EXPORT_SIZE(siglen),
448
out_file);
449
if (written != EC_STRUCTURED_SIG_EXPORT_SIZE(siglen)) {
450
ret = -1;
451
printf("Error: error when writing to %s\n", out_fname);
452
goto err;
453
}
454
455
ret = 0;
456
457
err:
458
if(in_file != NULL){
459
if(fclose(in_file)){
460
ret = -1;
461
}
462
}
463
if(out_file != NULL){
464
if(fclose(out_file)){
465
ret = -1;
466
}
467
}
468
return ret;
469
}
470
471
/* Get the raw size of a file */
472
ATTRIBUTE_WARN_UNUSED_RET static int get_file_size(const char *in_fname, size_t *outsz)
473
{
474
FILE *in_file = NULL;
475
long size;
476
int ret;
477
478
MUST_HAVE(outsz != NULL, ret, err);
479
MUST_HAVE(in_fname != NULL, ret, err);
480
481
*outsz = 0;
482
483
in_file = fopen(in_fname, "rb");
484
if (in_file == NULL) {
485
ret = -1;
486
printf("Error: file %s cannot be opened\n", in_fname);
487
goto err;
488
}
489
/* Compute the size of the file */
490
if (fseek(in_file, 0L, SEEK_END)) {
491
ret = -1;
492
printf("Error: file %s cannot be seeked\n", in_fname);
493
goto err;
494
}
495
size = ftell(in_file);
496
if (size < 0) {
497
ret = -1;
498
printf("Error: cannot compute file %s size\n", in_fname);
499
goto err;
500
}
501
/* Check overflow */
502
if ((u64)size > (u64)(0xffffffff)) {
503
ret = -1;
504
printf("Error: file %s size %ld overflow (>= 2^32)\n",
505
in_fname, size);
506
goto err;
507
}
508
509
*outsz = (u32)size;
510
ret = 0;
511
512
err:
513
if(in_file != NULL){
514
if(fclose(in_file)){
515
ret = -1;
516
}
517
}
518
return ret;
519
}
520
521
/* Generate a proper handler from a given type and other information */
522
ATTRIBUTE_WARN_UNUSED_RET static int generate_metadata_hdr(metadata_hdr * hdr, const char *hdr_type,
523
const char *version, size_t len, u8 siglen)
524
{
525
unsigned long ver;
526
char *endptr; /* for strtoul() */
527
int ret, check;
528
529
MUST_HAVE((hdr != NULL), ret, err);
530
MUST_HAVE((hdr_type != NULL), ret, err);
531
MUST_HAVE((version != NULL), ret, err);
532
533
/* The magic value */
534
hdr->magic = HDR_MAGIC;
535
536
/* The given version */
537
#ifdef WITH_STDLIB
538
errno = 0;
539
#endif
540
ver = strtoul(version, &endptr, 0);
541
#ifdef WITH_STDLIB
542
if(errno){
543
ret = -1;
544
printf("Error: error in strtoul\n");
545
goto err;
546
}
547
#endif
548
if (*endptr != '\0') {
549
ret = -1;
550
printf("Error: error getting provided version %s\n", version);
551
goto err;
552
}
553
if ((ver & 0xffffffff) != ver) {
554
ret = -1;
555
printf("Error: provided version %s is too long!\n", version);
556
goto err;
557
}
558
hdr->version = (u32)ver;
559
560
/* The image type */
561
hdr->type = IMAGE_TYPE_UNKNOWN;
562
ret = are_str_equal(hdr_type, "IMAGE_TYPE0", &check); EG(ret, err);
563
if (check) {
564
hdr->type = IMAGE_TYPE0;
565
}
566
ret = are_str_equal(hdr_type, "IMAGE_TYPE1", &check); EG(ret, err);
567
if (check) {
568
hdr->type = IMAGE_TYPE1;
569
}
570
ret = are_str_equal(hdr_type, "IMAGE_TYPE2", &check); EG(ret, err);
571
if (check) {
572
hdr->type = IMAGE_TYPE2;
573
}
574
ret = are_str_equal(hdr_type, "IMAGE_TYPE3", &check); EG(ret, err);
575
if (check) {
576
hdr->type = IMAGE_TYPE3;
577
}
578
if (hdr->type == IMAGE_TYPE_UNKNOWN) {
579
ret = -1;
580
printf("Error: unknown header type %s\n", hdr_type);
581
goto err;
582
}
583
584
/* The length without the signature */
585
if ((len & 0xffffffff) != len) {
586
ret = -1;
587
printf("Error: provided length value %lu is too long!\n", (unsigned long)len);
588
goto err;
589
}
590
hdr->len = (u32)len;
591
592
/* The signature length */
593
hdr->siglen = siglen;
594
595
ret = 0;
596
597
err:
598
return ret;
599
}
600
601
/* Warn the user that the provided ancillary data won't be used
602
* if the algorithm does not need them.
603
*/
604
ATTRIBUTE_WARN_UNUSED_RET static int check_ancillary_data(const char *adata, ec_alg_type sig_type, const char *sig_name, int *check)
605
{
606
int ret;
607
608
MUST_HAVE(check != NULL, ret, err);
609
MUST_HAVE(adata != NULL, ret, err);
610
MUST_HAVE(sig_name != NULL, ret, err);
611
MUST_HAVE(sig_type != UNKNOWN_ALG, ret, err);
612
613
(*check) = 0;
614
615
#if defined(WITH_SIG_EDDSA25519)
616
if(sig_type == EDDSA25519CTX){
617
(*check) = 1;
618
}
619
#endif
620
#if defined(WITH_SIG_EDDSA448)
621
if(sig_type == EDDSA448){
622
(*check) = 1;
623
}
624
#endif
625
#if defined(WITH_SIG_SM2)
626
if(sig_type == SM2){
627
(*check) = 1;
628
}
629
#endif
630
if((*check) == 0){
631
printf("Warning: you have provided optional ancillary data "\
632
"with a signature algorithm %s that does not need it! "\
633
"This data is ignored.\n", sig_name);
634
}
635
636
ret = 0;
637
638
err:
639
return ret;
640
}
641
642
/*
643
* Sign data from file and append signature
644
*/
645
ATTRIBUTE_WARN_UNUSED_RET static int sign_bin_file(const char *ec_name, const char *ec_sig_name,
646
const char *hash_algorithm, const char *in_fname,
647
const char *in_key_fname,
648
const char *out_fname, const char *hdr_type,
649
const char *version, const char *adata, u16 adata_len)
650
{
651
u8 sig[EC_MAX_SIGLEN];
652
u8 buf[MAX_BUF_LEN];
653
u8 siglen;
654
FILE *in_file = NULL;
655
ec_key_pair key_pair;
656
FILE *in_key_file = NULL;
657
FILE *out_file = NULL;
658
const ec_str_params *ec_str_p;
659
ec_params params;
660
int ret, check;
661
ec_alg_type sig_type;
662
hash_alg_type hash_type;
663
u8 priv_key_buf[EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE];
664
u8 priv_key_buf_len;
665
size_t raw_data_len;
666
metadata_hdr hdr;
667
size_t read, to_read;
668
int eof;
669
u8 *allocated_buff = NULL;
670
struct ec_sign_context sig_ctx;
671
672
MUST_HAVE(ec_name != NULL, ret, err);
673
MUST_HAVE(ec_sig_name != NULL, ret, err);
674
MUST_HAVE(hash_algorithm != NULL, ret, err);
675
MUST_HAVE(in_fname != NULL, ret, err);
676
MUST_HAVE(in_key_fname != NULL, ret, err);
677
MUST_HAVE(out_fname != NULL, ret, err);
678
679
/************************************/
680
/* Get parameters from pretty names */
681
if (string_to_params
682
(ec_name, ec_sig_name, &sig_type, &ec_str_p, hash_algorithm,
683
&hash_type)) {
684
ret = -1;
685
goto err;
686
}
687
if(adata != NULL){
688
/* Check if ancillary data will be used */
689
ret = check_ancillary_data(adata, sig_type, ec_sig_name, &check); EG(ret, err);
690
}
691
/* Import the parameters */
692
ret = import_params(&params, ec_str_p); EG(ret, err);
693
694
/************************************/
695
/* Import the private key from the file */
696
in_key_file = fopen(in_key_fname, "rb");
697
if (in_key_file == NULL) {
698
ret = -1;
699
printf("Error: file %s cannot be opened\n", in_key_fname);
700
goto err;
701
}
702
priv_key_buf_len = (u8)fread(priv_key_buf, 1, sizeof(priv_key_buf),
703
in_key_file);
704
ret = ec_structured_key_pair_import_from_priv_key_buf(&key_pair,
705
&params,
706
priv_key_buf,
707
priv_key_buf_len,
708
sig_type);
709
if (ret) {
710
ret = -1;
711
printf("Error: error when importing key pair from %s\n",
712
in_key_fname);
713
goto err;
714
}
715
716
ret = get_file_size(in_fname, &raw_data_len);
717
if (ret) {
718
ret = -1;
719
printf("Error: cannot retrieve file %s size\n", in_fname);
720
goto err;
721
}
722
if(raw_data_len == 0){
723
ret = -1;
724
printf("Error: file %s seems to be empty!\n", in_fname);
725
goto err;
726
}
727
ret = ec_get_sig_len(&params, sig_type, hash_type, &siglen);
728
if (ret) {
729
ret = -1;
730
printf("Error getting effective signature length from %s\n",
731
(const char *)(ec_str_p->name->buf));
732
goto err;
733
}
734
735
/* Structured export case, we forge a header */
736
if((hdr_type != NULL) && (version != NULL)){
737
/************************************/
738
/* Forge the header */
739
ret = generate_metadata_hdr(&hdr, hdr_type, version, raw_data_len,
740
EC_STRUCTURED_SIG_EXPORT_SIZE(siglen));
741
742
if (ret) {
743
ret = -1;
744
printf("Error: error when generating metadata\n");
745
goto err;
746
}
747
}
748
749
/* Check if we support streaming */
750
ret = is_sign_streaming_mode_supported(sig_type, &check); EG(ret, err);
751
if(check){
752
/**** We support streaming mode ****/
753
/*
754
* Initialize signature context and start signature computation
755
* with generated metadata header.
756
*/
757
ret = ec_sign_init(&sig_ctx, &key_pair, sig_type, hash_type, (const u8*)adata, adata_len);
758
if (ret) {
759
ret = -1;
760
printf("Error: error when signing\n");
761
goto err;
762
}
763
764
/* Structured export case, we prepend the header in the signature */
765
if((hdr_type != NULL) && (version != NULL)){
766
ret = ec_sign_update(&sig_ctx, (const u8 *)&hdr, sizeof(metadata_hdr));
767
if (ret) {
768
ret = -1;
769
printf("Error: error when signing\n");
770
goto err;
771
}
772
}
773
774
/*
775
* Read file content chunk by chunk up to file length, passing each
776
* chunk to signature update function
777
*/
778
in_file = fopen(in_fname, "rb");
779
if (in_file == NULL) {
780
ret = -1;
781
printf("Error: file %s cannot be opened\n", in_fname);
782
goto err;
783
}
784
785
eof = 0;
786
clearerr(in_file);
787
while (raw_data_len && !eof) {
788
to_read =
789
(raw_data_len <
790
sizeof(buf)) ? raw_data_len : sizeof(buf);
791
memset(buf, 0, sizeof(buf));
792
read = fread(buf, 1, to_read, in_file);
793
if (read != to_read) {
794
/* Check if this was EOF */
795
ret = feof(in_file);
796
clearerr(in_file);
797
if (ret) {
798
eof = 1;
799
}
800
}
801
802
if (read > raw_data_len) {
803
/* we read more than expected: leave! */
804
break;
805
}
806
807
raw_data_len -= read;
808
809
ret = ec_sign_update(&sig_ctx, buf, (u32)read);
810
if (ret) {
811
break;
812
}
813
}
814
815
if (raw_data_len) {
816
ret = -1;
817
printf("Error: unable to read full file content\n");
818
goto err;
819
}
820
821
/* We can now complete signature generation */
822
ret = ec_sign_finalize(&sig_ctx, sig, siglen);
823
if (ret) {
824
ret = -1;
825
printf("Error: error when signing\n");
826
goto err;
827
}
828
}
829
else{
830
/**** We do not support streaming mode ****/
831
/* Since we don't support streaming mode, we unfortunately have to
832
* use a dynamic allocation here.
833
*/
834
size_t offset = 0;
835
allocated_buff = (u8*)malloc(1);
836
if(allocated_buff == NULL){
837
ret = -1;
838
printf("Error: allocation error\n");
839
goto err;
840
}
841
if((hdr_type != NULL) && (version != NULL)){
842
allocated_buff = (u8*)realloc(allocated_buff, sizeof(hdr));
843
if(allocated_buff == NULL){
844
ret = -1;
845
printf("Error: allocation error\n");
846
goto err;
847
}
848
memcpy(allocated_buff, &hdr, sizeof(hdr));
849
offset += sizeof(hdr);
850
}
851
in_file = fopen(in_fname, "rb");
852
if (in_file == NULL) {
853
ret = -1;
854
printf("Error: file %s cannot be opened\n", in_fname);
855
goto err;
856
}
857
858
eof = 0;
859
clearerr(in_file);
860
while (raw_data_len && !eof) {
861
to_read =
862
(raw_data_len <
863
sizeof(buf)) ? raw_data_len : sizeof(buf);
864
read = fread(buf, 1, to_read, in_file);
865
if (read != to_read) {
866
/* Check if this was EOF */
867
ret = feof(in_file);
868
clearerr(in_file);
869
if (ret) {
870
eof = 1;
871
}
872
}
873
874
if (read > raw_data_len) {
875
/* we read more than expected: leave! */
876
break;
877
}
878
879
raw_data_len -= read;
880
881
allocated_buff = (u8*)realloc(allocated_buff, offset + read);
882
if(allocated_buff == NULL){
883
ret = -1;
884
printf("Error: allocation error\n");
885
goto err;
886
}
887
memcpy(allocated_buff + offset, buf, read);
888
offset += read;
889
}
890
891
if (raw_data_len) {
892
ret = -1;
893
printf("Error: unable to read full file content\n");
894
goto err;
895
}
896
897
/* Sign */
898
ret = ec_sign(sig, siglen, &key_pair, allocated_buff, (u32)offset, sig_type, hash_type, (const u8*)adata, adata_len);
899
if(ret){
900
ret = -1;
901
printf("Error: error when signing\n");
902
goto err;
903
}
904
}
905
906
/* Structured export case, forge the full structured file
907
* with HEADER || raw_binary || signature
908
*/
909
if((hdr_type != NULL) && (version != NULL)){
910
/***********************************/
911
/* Store the header, the raw data of the file as well as the signature */
912
ret = store_sig(in_fname, out_fname, sig, siglen, sig_type,
913
hash_type, params.curve_name, &hdr);
914
if (ret) {
915
ret = -1;
916
printf("Error: error when storing signature to %s\n",
917
out_fname);
918
goto err;
919
}
920
}
921
else{
922
/* Store the raw binary signature in the output file */
923
size_t written;
924
925
out_file = fopen(out_fname, "wb");
926
if (out_file == NULL) {
927
ret = -1;
928
printf("Error: file %s cannot be opened\n", out_fname);
929
goto err;
930
}
931
written = fwrite(sig, 1, siglen, out_file);
932
if (written != siglen) {
933
ret = -1;
934
printf("Error: error when writing to %s\n",
935
out_fname);
936
goto err;
937
}
938
}
939
940
ret = 0;
941
942
err:
943
if(in_file != NULL){
944
if(fclose(in_file)){
945
ret = -1;
946
}
947
}
948
if(in_key_file != NULL){
949
if(fclose(in_key_file)){
950
ret = -1;
951
}
952
}
953
if(out_file != NULL){
954
if(fclose(out_file)){
955
ret = -1;
956
}
957
}
958
if(allocated_buff != NULL){
959
free(allocated_buff);
960
}
961
return ret;
962
}
963
964
/* Dump metadata header */
965
ATTRIBUTE_WARN_UNUSED_RET static int dump_hdr_info(const metadata_hdr * hdr)
966
{
967
int ret;
968
969
if (hdr == NULL) {
970
printf("Metadata header pointer is NULL!\n");
971
ret = -1;
972
goto err;
973
}
974
975
/* Dump the header */
976
printf("Metadata header info:\n");
977
printf(" magic = 0x%08" PRIx32 "\n", hdr->magic);
978
switch (hdr->type) {
979
case IMAGE_TYPE0:
980
printf(" type = IMAGE_TYPE0\n");
981
break;
982
case IMAGE_TYPE1:
983
printf(" type = IMAGE_TYPE1\n");
984
break;
985
case IMAGE_TYPE2:
986
printf(" type = IMAGE_TYPE2\n");
987
break;
988
case IMAGE_TYPE3:
989
printf(" type = IMAGE_TYPE3\n");
990
break;
991
default:
992
printf(" type %" PRIu32 " unknown!\n", hdr->type);
993
break;
994
}
995
printf(" version = 0x%08" PRIx32 "\n", hdr->version);
996
printf(" len = 0x%08" PRIx32 "\n", hdr->len);
997
printf(" siglen = 0x%08" PRIx32 "\n", hdr->siglen);
998
ret = 0;
999
1000
err:
1001
return ret;
1002
}
1003
1004
/*
1005
* Verify signature data from file with appended signature
1006
*/
1007
ATTRIBUTE_WARN_UNUSED_RET static int verify_bin_file(const char *ec_name, const char *ec_sig_name,
1008
const char *hash_algorithm,
1009
const char *in_fname,
1010
const char *in_key_fname, const char *in_sig_fname, const char *adata, u16 adata_len)
1011
{
1012
u8 st_sig[EC_STRUCTURED_SIG_EXPORT_SIZE(EC_MAX_SIGLEN)];
1013
u8 stored_curve_name[MAX_CURVE_NAME_LEN];
1014
u8 pub_key_buf[EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE];
1015
struct ec_verify_context verif_ctx;
1016
ec_alg_type stored_sig_type;
1017
hash_alg_type stored_hash_type;
1018
const ec_str_params *ec_str_p;
1019
ec_alg_type sig_type;
1020
hash_alg_type hash_type;
1021
u8 sig[EC_MAX_SIGLEN];
1022
u8 siglen, st_siglen;
1023
size_t read, to_read;
1024
u8 buf[MAX_BUF_LEN];
1025
u8 pub_key_buf_len;
1026
size_t raw_data_len;
1027
ec_pub_key pub_key;
1028
FILE *in_key_file = NULL;
1029
FILE *in_sig_file = NULL;
1030
ec_params params;
1031
metadata_hdr hdr;
1032
size_t exp_len;
1033
FILE *in_file = NULL;
1034
int ret, eof, check;
1035
u8 *allocated_buff = NULL;
1036
1037
MUST_HAVE(ec_name != NULL, ret, err);
1038
MUST_HAVE(ec_sig_name != NULL, ret, err);
1039
MUST_HAVE(hash_algorithm != NULL, ret, err);
1040
MUST_HAVE(in_fname != NULL, ret, err);
1041
MUST_HAVE(in_key_fname != NULL, ret, err);
1042
1043
/************************************/
1044
/* Get parameters from pretty names */
1045
ret = string_to_params(ec_name, ec_sig_name, &sig_type, &ec_str_p,
1046
hash_algorithm, &hash_type); EG(ret, err);
1047
if(adata != NULL){
1048
/* Check if ancillary data will be used */
1049
ret = check_ancillary_data(adata, sig_type, ec_sig_name, &check); EG(ret, err);
1050
}
1051
/* Import the parameters */
1052
ret = import_params(&params, ec_str_p); EG(ret, err);
1053
1054
ret = ec_get_sig_len(&params, sig_type, hash_type, &siglen);
1055
if (ret) {
1056
ret = -1;
1057
printf("Error getting effective signature length from %s\n",
1058
(const char *)(ec_str_p->name->buf));
1059
goto err;
1060
}
1061
1062
/************************************/
1063
/* Import the public key from the file */
1064
in_key_file = fopen(in_key_fname, "rb");
1065
if (in_key_file == NULL) {
1066
ret = -1;
1067
printf("Error: file %s cannot be opened\n", in_key_fname);
1068
goto err;
1069
}
1070
pub_key_buf_len =(u8)fread(pub_key_buf, 1, sizeof(pub_key_buf),
1071
in_key_file);
1072
ret = ec_structured_pub_key_import_from_buf(&pub_key, &params,
1073
pub_key_buf,
1074
pub_key_buf_len, sig_type);
1075
if (ret) {
1076
ret = -1;
1077
printf("Error: error when importing public key from %s\n",
1078
in_key_fname);
1079
goto err;
1080
}
1081
1082
/* Let's first get file size */
1083
ret = get_file_size(in_fname, &raw_data_len);
1084
if (ret) {
1085
ret = -1;
1086
printf("Error: cannot retrieve file %s size\n", in_fname);
1087
goto err;
1088
}
1089
if(raw_data_len == 0){
1090
ret = -1;
1091
printf("Error: file %s seems to be empty!\n", in_fname);
1092
goto err;
1093
}
1094
1095
/* Open main file to verify ... */
1096
in_file = fopen(in_fname, "rb");
1097
if (in_file == NULL) {
1098
ret = -1;
1099
printf("Error: file %s cannot be opened\n", in_fname);
1100
goto err;
1101
}
1102
1103
/*
1104
* We are in 'structured' mode, read the header and get the information
1105
* from it
1106
*/
1107
if (in_sig_fname == NULL) {
1108
/* ... and first read metadata header */
1109
read = fread(&hdr, 1, sizeof(hdr), in_file);
1110
if (read != sizeof(hdr)) {
1111
ret = -1;
1112
printf("Error: unable to read metadata header "
1113
"from file\n");
1114
goto err;
1115
}
1116
1117
/* Sanity checks on the header we get */
1118
if (hdr.magic != HDR_MAGIC) {
1119
ret = -1;
1120
printf("Error: got magic 0x%08" PRIx32 " instead of 0x%08x "
1121
"from metadata header\n", hdr.magic, (unsigned int)HDR_MAGIC);
1122
goto err;
1123
}
1124
1125
st_siglen = EC_STRUCTURED_SIG_EXPORT_SIZE(siglen);
1126
MUST_HAVE(raw_data_len > (sizeof(hdr) + st_siglen), ret, err);
1127
exp_len = raw_data_len - sizeof(hdr) - st_siglen;
1128
if (hdr.len != exp_len) {
1129
ret = -1;
1130
printf("Error: got raw size of %" PRIu32 " instead of %lu from "
1131
"metadata header\n", hdr.len,
1132
(unsigned long)exp_len);
1133
goto err;
1134
}
1135
1136
if (hdr.siglen != st_siglen) {
1137
ret = -1;
1138
printf("Error: got siglen %" PRIu32 " instead of %d from "
1139
"metadata header\n", hdr.siglen, siglen);
1140
goto err;
1141
}
1142
1143
/* Dump the header */
1144
ret = dump_hdr_info(&hdr); EG(ret, err);
1145
1146
/*
1147
* We now need to seek in file to get structured signature.
1148
* Before doing that, let's first check size is large enough.
1149
*/
1150
if (raw_data_len < (sizeof(hdr) + st_siglen)) {
1151
ret = -1;
1152
goto err;
1153
}
1154
1155
ret = fseek(in_file, (long)(raw_data_len - st_siglen),
1156
SEEK_SET);
1157
if (ret) {
1158
ret = -1;
1159
printf("Error: file %s cannot be seeked\n", in_fname);
1160
goto err;
1161
}
1162
read = fread(st_sig, 1, st_siglen, in_file);
1163
if (read != st_siglen) {
1164
ret = -1;
1165
printf("Error: unable to read structure sig from "
1166
"file\n");
1167
goto err;
1168
}
1169
/* Import the signature from the structured signature buffer */
1170
ret = ec_structured_sig_import_from_buf(sig, siglen,
1171
st_sig, st_siglen,
1172
&stored_sig_type,
1173
&stored_hash_type,
1174
stored_curve_name);
1175
if (ret) {
1176
ret = -1;
1177
printf("Error: error when importing signature "
1178
"from %s\n", in_fname);
1179
goto err;
1180
}
1181
if (stored_sig_type != sig_type) {
1182
ret = -1;
1183
printf("Error: signature type imported from signature "
1184
"mismatches with %s\n", ec_sig_name);
1185
goto err;
1186
}
1187
if (stored_hash_type != hash_type) {
1188
ret = -1;
1189
printf("Error: hash algorithm type imported from "
1190
"signature mismatches with %s\n",
1191
hash_algorithm);
1192
goto err;
1193
}
1194
ret = are_str_equal((char *)stored_curve_name, (char *)params.curve_name, &check); EG(ret, err);
1195
if (!check) {
1196
ret = -1;
1197
printf("Error: curve type '%s' imported from signature "
1198
"mismatches with '%s'\n", stored_curve_name,
1199
params.curve_name);
1200
goto err;
1201
}
1202
1203
/*
1204
* Get back to the beginning of file, at the beginning of header
1205
*/
1206
if (fseek(in_file, 0, SEEK_SET)) {
1207
ret = -1;
1208
printf("Error: file %s cannot be seeked\n", in_fname);
1209
goto err;
1210
}
1211
exp_len += sizeof(hdr);
1212
} else {
1213
/* Get the signature size */
1214
ret = get_file_size(in_sig_fname, &to_read);
1215
if (ret) {
1216
ret = -1;
1217
printf("Error: cannot retrieve file %s size\n",
1218
in_sig_fname);
1219
goto err;
1220
}
1221
if((to_read > EC_MAX_SIGLEN) || (to_read > 255) || (to_read == 0)){
1222
/* This is not an expected size, get out */
1223
ret = -1;
1224
printf("Error: size %d of signature in %s is > max "
1225
"signature size %d or > 255",
1226
(int)to_read, in_sig_fname, EC_MAX_SIGLEN);
1227
goto err;
1228
}
1229
siglen = (u8)to_read;
1230
/* Read the raw signature from the signature file */
1231
in_sig_file = fopen(in_sig_fname, "rb");
1232
if (in_sig_file == NULL) {
1233
ret = -1;
1234
printf("Error: file %s cannot be opened\n",
1235
in_sig_fname);
1236
goto err;
1237
}
1238
read = fread(&sig, 1, siglen, in_sig_file);
1239
if (read != siglen) {
1240
ret = -1;
1241
printf("Error: unable to read signature from %s\n",
1242
in_sig_fname);
1243
goto err;
1244
}
1245
exp_len = raw_data_len;
1246
}
1247
1248
/* Check if we support streaming */
1249
ret = is_verify_streaming_mode_supported(sig_type, &check); EG(ret, err);
1250
if(check){
1251
/**** We support streaming mode ****/
1252
/*
1253
* ... and read file content chunk by chunk to compute signature
1254
*/
1255
ret = ec_verify_init(&verif_ctx, &pub_key, sig, siglen,
1256
sig_type, hash_type, (const u8*)adata, adata_len);
1257
if (ret) {
1258
ret = -1;
1259
printf("Error: error when verifying ...\n");
1260
goto err;
1261
}
1262
1263
eof = 0;
1264
clearerr(in_file);
1265
while (exp_len && !eof) {
1266
to_read = (exp_len < sizeof(buf)) ? exp_len : sizeof(buf);
1267
read = fread(buf, 1, to_read, in_file);
1268
if (read != to_read) {
1269
/* Check if this was EOF */
1270
ret = feof(in_file);
1271
clearerr(in_file);
1272
if (ret) {
1273
eof = 1;
1274
}
1275
}
1276
1277
if (read > exp_len) {
1278
/* we read more than expected: leave! */
1279
break;
1280
}
1281
1282
exp_len -= read;
1283
1284
ret = ec_verify_update(&verif_ctx, buf, (u32)read);
1285
if(ret){
1286
ret = -1;
1287
printf("Error: error when verifying ...\n");
1288
goto err;
1289
}
1290
}
1291
if (exp_len) {
1292
ret = -1;
1293
printf("Error: unable to read full file content\n");
1294
goto err;
1295
}
1296
ret = ec_verify_finalize(&verif_ctx);
1297
if (ret) {
1298
ret = -1;
1299
goto err;
1300
}
1301
}
1302
else{
1303
/**** We do not support streaming mode ****/
1304
/* Since we don't support streaming mode, we unfortunately have to
1305
* use a dynamic allocation here.
1306
*/
1307
size_t offset = 0;
1308
allocated_buff = (u8*)malloc(1);
1309
1310
eof = 0;
1311
clearerr(in_file);
1312
while (exp_len && !eof) {
1313
to_read = (exp_len < sizeof(buf)) ? exp_len : sizeof(buf);
1314
read = fread(buf, 1, to_read, in_file);
1315
if (read != to_read) {
1316
/* Check if this was EOF */
1317
ret = feof(in_file);
1318
clearerr(in_file);
1319
if (ret) {
1320
eof = 1;
1321
}
1322
}
1323
1324
if (read > exp_len) {
1325
/* we read more than expected: leave! */
1326
break;
1327
}
1328
1329
exp_len -= read;
1330
1331
allocated_buff = (u8*)realloc(allocated_buff, offset + read);
1332
if(allocated_buff == NULL){
1333
ret = -1;
1334
printf("Error: allocation error\n");
1335
goto err;
1336
}
1337
memcpy(allocated_buff + offset, buf, read);
1338
offset += read;
1339
}
1340
if (exp_len) {
1341
ret = -1;
1342
printf("Error: unable to read full file content\n");
1343
goto err;
1344
}
1345
1346
ret = ec_verify(sig, siglen, &pub_key, allocated_buff, (u32)offset, sig_type, hash_type, (const u8*)adata, adata_len);
1347
if (ret) {
1348
ret = -1;
1349
goto err;
1350
}
1351
1352
}
1353
1354
ret = 0;
1355
1356
err:
1357
if(in_file != NULL){
1358
if(fclose(in_file)){
1359
ret = -1;
1360
}
1361
}
1362
if(in_key_file != NULL){
1363
if(fclose(in_key_file)){
1364
ret = -1;
1365
}
1366
}
1367
if(in_sig_file != NULL){
1368
if(fclose(in_sig_file)){
1369
ret = -1;
1370
}
1371
}
1372
if(allocated_buff != NULL){
1373
free(allocated_buff);
1374
}
1375
return ret;
1376
}
1377
1378
/* Compute 'scalar * Point' on the provided curve and prints
1379
* the result.
1380
*/
1381
ATTRIBUTE_WARN_UNUSED_RET static int ec_scalar_mult(const char *ec_name,
1382
const char *scalar_file,
1383
const char *point_file,
1384
const char *outfile_name)
1385
{
1386
const ec_str_params *ec_str_p;
1387
ec_params curve_params;
1388
int ret;
1389
u8 buf[MAX_BUF_LEN];
1390
size_t buf_len;
1391
FILE *in_file = NULL;
1392
FILE *out_file = NULL;
1393
u16 coord_len;
1394
1395
/* Scalar (natural number) to import */
1396
nn d;
1397
/* Point to import */
1398
prj_pt Q;
1399
d.magic = Q.magic = WORD(0);
1400
1401
MUST_HAVE(ec_name != NULL, ret, err);
1402
MUST_HAVE(scalar_file != NULL, ret, err);
1403
MUST_HAVE(point_file != NULL, ret, err);
1404
MUST_HAVE(outfile_name != NULL, ret, err);
1405
1406
/* Get parameters from pretty names */
1407
ret = string_to_params(ec_name, NULL, NULL, &ec_str_p,
1408
NULL, NULL); EG(ret, err);
1409
1410
/* Import the parameters */
1411
ret = import_params(&curve_params, ec_str_p); EG(ret, err);
1412
1413
/* Import the scalar in the local buffer from the file */
1414
/* Let's first get file size */
1415
ret = get_file_size(scalar_file, &buf_len);
1416
if(buf_len == 0){
1417
ret = -1;
1418
printf("Error: file %s seems to be empty!\n", scalar_file);
1419
goto err;
1420
}
1421
if (ret) {
1422
ret = -1;
1423
printf("Error: cannot retrieve file %s size\n", scalar_file);
1424
goto err;
1425
}
1426
if(buf_len > sizeof(buf)){
1427
ret = -1;
1428
printf("Error: file %s content too large for our local buffers\n", scalar_file);
1429
goto err;
1430
}
1431
/* Open main file to verify ... */
1432
in_file = fopen(scalar_file, "rb");
1433
if (in_file == NULL) {
1434
ret = -1;
1435
printf("Error: file %s cannot be opened\n", scalar_file);
1436
goto err;
1437
}
1438
/* Read the content of the file */
1439
if(fread(buf, 1, buf_len, in_file) != buf_len){
1440
ret = -1;
1441
printf("Error: error when reading in %s\n", scalar_file);
1442
goto err;
1443
}
1444
/* Import the scalar */
1445
ret = nn_init_from_buf(&d, buf, (u16)buf_len); EG(ret, err);
1446
1447
/* Import the point in the local buffer from the file */
1448
/* Let's first get file size */
1449
ret = get_file_size(point_file, &buf_len);
1450
if (ret) {
1451
ret = -1;
1452
printf("Error: cannot retrieve file %s size\n", point_file);
1453
goto err;
1454
}
1455
if(buf_len > sizeof(buf)){
1456
ret = -1;
1457
printf("Error: file %s content too large for our local buffers\n", point_file);
1458
goto err;
1459
}
1460
ret = fclose(in_file); EG(ret, err);
1461
in_file = NULL;
1462
/* Open main file to verify ... */
1463
in_file = fopen(point_file, "rb");
1464
if (in_file == NULL) {
1465
ret = -1;
1466
printf("Error: file %s cannot be opened\n", point_file);
1467
goto err;
1468
}
1469
/* Read the content of the file */
1470
if(fread(buf, 1, buf_len, in_file) != buf_len){
1471
ret = -1;
1472
printf("Error: error when reading in %s\n", point_file);
1473
goto err;
1474
}
1475
/* Import the point */
1476
if(prj_pt_import_from_buf(&Q, buf, (u16)buf_len, &(curve_params.ec_curve))){
1477
ret = -1;
1478
printf("Error: error when importing the projective point from %s\n", point_file);
1479
goto err;
1480
}
1481
1482
#ifdef USE_SIG_BLINDING
1483
/* NB: we use a blind scalar multiplication here since we do not want our
1484
* private d to leak ...
1485
*/
1486
ret = prj_pt_mul_blind(&Q, &d, &Q); EG(ret, err);
1487
#else
1488
ret = prj_pt_mul(&Q, &d, &Q); EG(ret, err);
1489
#endif
1490
/* Get the unique representation of the point */
1491
ret = prj_pt_unique(&Q, &Q); EG(ret, err);
1492
1493
/* Export the projective point in the local buffer */
1494
coord_len = (u16)(3 * BYTECEIL((Q.crv)->a.ctx->p_bitlen));
1495
if(coord_len > sizeof(buf)){
1496
ret = -1;
1497
printf("Error: error when exporting the point\n");
1498
goto err;
1499
}
1500
if(prj_pt_export_to_buf(&Q, buf, coord_len)){
1501
ret = -1;
1502
printf("Error: error when exporting the point\n");
1503
goto err;
1504
}
1505
/* Now save the coordinates in the output file */
1506
out_file = fopen(outfile_name, "wb");
1507
if (out_file == NULL) {
1508
ret = -1;
1509
printf("Error: file %s cannot be opened\n", outfile_name);
1510
goto err;
1511
}
1512
1513
/* Write in the file */
1514
if(fwrite(buf, 1, coord_len, out_file) != coord_len){
1515
ret = -1;
1516
printf("Error: error when writing to %s\n", outfile_name);
1517
goto err;
1518
}
1519
1520
ret = 0;
1521
1522
err:
1523
/* Uninit local variables */
1524
nn_uninit(&d);
1525
prj_pt_uninit(&Q);
1526
1527
if(in_file != NULL){
1528
if(fclose(in_file)){
1529
ret = -1;
1530
}
1531
}
1532
if(out_file != NULL){
1533
if(fclose(out_file)){
1534
ret = -1;
1535
}
1536
}
1537
return ret;
1538
}
1539
1540
1541
static void print_curves(void)
1542
{
1543
u8 i;
1544
1545
/* Print all the available curves */
1546
for (i = 0; i < EC_CURVES_NUM; i++) {
1547
printf("%s ", (const char *)(ec_maps[i].params->name->buf));
1548
}
1549
1550
return;
1551
}
1552
1553
static void print_hash_algs(void)
1554
{
1555
int i;
1556
1557
/* Print all the available hash functions */
1558
for (i = 0; hash_maps[i].type != UNKNOWN_HASH_ALG; i++) {
1559
printf("%s ", hash_maps[i].name);
1560
}
1561
1562
return;
1563
}
1564
1565
static void print_sig_algs(void)
1566
{
1567
int i;
1568
1569
/* Print all the available signature schemes */
1570
for (i = 0; ec_sig_maps[i].type != UNKNOWN_ALG; i++) {
1571
printf("%s ", ec_sig_maps[i].name);
1572
}
1573
1574
return;
1575
}
1576
1577
static void print_help(const char *prog_name)
1578
{
1579
printf("%s expects at least one argument\n", prog_name ? prog_name : "NULL");
1580
printf("\targ1 = 'gen_keys', 'sign', 'verify', 'struct_sign', 'struct_verify' or 'scalar_mult'\n");
1581
}
1582
1583
#ifdef __cplusplus
1584
/* In case of a C++ compiler, preserve our "main"
1585
* linkage.
1586
*/
1587
extern "C" {
1588
int main(int argc, char *argv[]);
1589
}
1590
#endif
1591
1592
int main(int argc, char *argv[])
1593
{
1594
int ret, check, found;
1595
u32 len;
1596
const char *adata = NULL;
1597
u16 adata_len = 0;
1598
1599
if (argc < 2) {
1600
ret = -1;
1601
print_help(argv[0]);
1602
goto err;
1603
}
1604
1605
found = 0;
1606
ret = are_str_equal(argv[1], "gen_keys", &check); EG(ret, err);
1607
if (check) {
1608
found = 1;
1609
/* Generate keys ---------------------------------
1610
*
1611
* arg1 = curve name ("frp256v1", ...)
1612
* arg2 = algorithm type ("ECDSA", "ECKCDSA", ...)
1613
* arg3 = file name prefix
1614
*/
1615
if (argc != 5){
1616
ret = -1;
1617
printf("Bad args number for %s %s:\n", argv[0],
1618
argv[1]);
1619
printf("\targ1 = curve name: ");
1620
print_curves();
1621
printf("\n");
1622
1623
printf("\targ2 = signature algorithm type: ");
1624
print_sig_algs();
1625
printf("\n");
1626
1627
printf("\targ3 = file name prefix\n");
1628
printf("\n");
1629
1630
goto err;
1631
}
1632
if(generate_and_export_key_pair(argv[2], argv[3], argv[4])){
1633
ret = -1;
1634
printf("gen_key error ...\n");
1635
goto err;
1636
}
1637
}
1638
ret = are_str_equal(argv[1], "sign", &check); EG(ret, err);
1639
if (check) {
1640
found = 1;
1641
/* Sign something --------------------------------
1642
* Signature is structured, i.e. the output is a self contained
1643
* data image
1644
* arg1 = curve name ("frp256v1", ...)
1645
* arg2 = signature algorithm type ("ECDSA", "ECKCDSA", ...)
1646
* arg3 = hash algorithm type ("SHA256", "SHA512", ...)
1647
* arg4 = input file to sign
1648
* arg5 = input file containing the private key
1649
* arg6 = output file containing the signature
1650
* arg7 (optional) = ancillary data to be used
1651
*/
1652
if ((argc != 8) && (argc != 9)) {
1653
ret = -1;
1654
printf("Bad args number for %s %s:\n", argv[0],
1655
argv[1]);
1656
printf("\targ1 = curve name: ");
1657
print_curves();
1658
printf("\n");
1659
1660
printf("\targ2 = signature algorithm type: ");
1661
print_sig_algs();
1662
printf("\n");
1663
1664
printf("\targ3 = hash algorithm type: ");
1665
print_hash_algs();
1666
printf("\n");
1667
1668
printf("\targ4 = input file to sign\n");
1669
printf("\targ5 = input file containing the private key (in raw binary format)\n");
1670
printf("\targ6 = output file containing the signature\n");
1671
printf("\t<arg7 (optional) = ancillary data to be used>\n");
1672
goto err;
1673
}
1674
if(argc == 9){
1675
adata = argv[8];
1676
ret = local_strlen(adata, &len); EG(ret, err);
1677
MUST_HAVE(len <= 0xffff, ret, err);
1678
adata_len = (u16)len;
1679
}
1680
if(sign_bin_file(argv[2], argv[3], argv[4], argv[5], argv[6],
1681
argv[7], NULL, NULL, adata, adata_len)){
1682
ret = -1;
1683
printf("sign error ...\n");
1684
goto err;
1685
}
1686
}
1687
ret = are_str_equal(argv[1], "verify", &check); EG(ret, err);
1688
if (check) {
1689
found = 1;
1690
/* Verify something ------------------------------
1691
*
1692
* arg1 = curve name ("frp256v1", ...)
1693
* arg2 = signature algorithm type ("ECDSA", "ECKCDSA", ...)
1694
* arg3 = hash algorithm type ("SHA256", "SHA512", ...)
1695
* arg = input file to verify
1696
* arg5 = input file with the public key
1697
* arg6 = input file containing the signature
1698
* arg7 (optional) = ancillary data to be used
1699
*/
1700
if ((argc != 8) && (argc != 9)) {
1701
ret = -1;
1702
printf("Bad args number for %s %s:\n", argv[0],
1703
argv[1]);
1704
printf("\targ1 = curve name: ");
1705
print_curves();
1706
printf("\n");
1707
1708
printf("\targ2 = signature algorithm type: ");
1709
print_sig_algs();
1710
printf("\n");
1711
1712
printf("\targ3 = hash algorithm type: ");
1713
print_hash_algs();
1714
printf("\n");
1715
1716
printf("\targ4 = input file to verify\n");
1717
printf("\targ5 = input file containing the public key (in raw binary format)\n");
1718
printf("\targ6 = input file containing the signature\n");
1719
printf("\t<arg7 (optional) = ancillary data to be used>\n");
1720
goto err;
1721
}
1722
if(argc == 9){
1723
adata = argv[8];
1724
ret = local_strlen(adata, &len); EG(ret, err);
1725
MUST_HAVE(len <= 0xffff, ret, err);
1726
adata_len = (u16)len;
1727
}
1728
if (verify_bin_file(argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], adata, adata_len)) {
1729
ret = -1;
1730
printf("Signature check of %s failed\n", argv[5]);
1731
goto err;
1732
} else {
1733
printf("Signature check of %s OK\n", argv[5]);
1734
}
1735
}
1736
ret = are_str_equal(argv[1], "struct_sign", &check); EG(ret, err);
1737
if (check) {
1738
found = 1;
1739
/* Sign something --------------------------------
1740
* Signature is structured, i.e. the output is a self contained
1741
* data image
1742
* arg1 = curve name ("frp256v1", ...)
1743
* arg2 = signature algorithm type ("ECDSA", "ECKCDSA", ...)
1744
* arg3 = hash algorithm type ("SHA256", "SHA512", ...)
1745
* arg4 = input file to sign
1746
* arg5 = input file with the private key
1747
* arg6 = output file containing the appended signature
1748
* arg7 = metadata header type
1749
* arg8 = version of the metadata header
1750
* arg9 (optional) = ancillary data to be used
1751
*/
1752
if ((argc != 10) && (argc != 11)) {
1753
ret = -1;
1754
printf("Bad args number for %s %s:\n", argv[0],
1755
argv[1]);
1756
printf("\targ1 = curve name: ");
1757
print_curves();
1758
printf("\n");
1759
1760
printf("\targ2 = signature algorithm type: ");
1761
print_sig_algs();
1762
printf("\n");
1763
1764
printf("\targ3 = hash algorithm type: ");
1765
print_hash_algs();
1766
printf("\n");
1767
1768
printf("\targ4 = input file to sign\n");
1769
printf("\targ5 = input file containing the private key (in raw binary format)\n");
1770
printf("\targ6 = output file containing the appended signature\n");
1771
printf("\targ7 = metadata header type (IMAGE_TYPE0, IMAGE_TYPE1, ...)\n");
1772
printf("\targ8 = version of the metadata header\n");
1773
printf("\t<arg9 (optional) = ancillary data to be used>\n");
1774
goto err;
1775
}
1776
if(argc == 11){
1777
adata = argv[10];
1778
ret = local_strlen(adata, &len); EG(ret, err);
1779
MUST_HAVE(len <= 0xffff, ret, err);
1780
adata_len = (u16)len;
1781
}
1782
if(sign_bin_file(argv[2], argv[3], argv[4], argv[5], argv[6],
1783
argv[7], argv[8], argv[9], adata, adata_len)){
1784
ret = -1;
1785
printf("struct_sign error ...\n");
1786
goto err;
1787
}
1788
}
1789
ret = are_str_equal(argv[1], "struct_verify", &check); EG(ret, err);
1790
if (check) {
1791
found = 1;
1792
/* Verify something ------------------------------
1793
*
1794
* arg1 = curve name ("frp256v1", ...)
1795
* arg2 = signature algorithm type ("ECDSA", "ECKCDSA", ...)
1796
* arg3 = hash algorithm type ("SHA256", "SHA512", ...)
1797
* arg4 = input file to verify
1798
* arg5 = input file containing the public key (in raw binary format)
1799
* arg6 (optional) = ancillary data to be used
1800
*/
1801
if ((argc != 7) && (argc != 8)) {
1802
ret = -1;
1803
printf("Bad args number for %s %s:\n", argv[0],
1804
argv[1]);
1805
printf("\targ1 = curve name: ");
1806
print_curves();
1807
printf("\n");
1808
1809
printf("\targ2 = signature algorithm type: ");
1810
print_sig_algs();
1811
printf("\n");
1812
1813
printf("\targ3 = hash algorithm type: ");
1814
print_hash_algs();
1815
printf("\n");
1816
1817
printf("\targ4 = input file to verify\n");
1818
printf("\targ5 = input file containing the public key (in raw binary format)\n");
1819
printf("\t<arg6 (optional) = ancillary data to be used>\n");
1820
goto err;
1821
}
1822
if(argc == 8){
1823
adata = argv[7];
1824
ret = local_strlen(adata, &len); EG(ret, err);
1825
MUST_HAVE(len <= 0xffff, ret, err);
1826
adata_len = (u16)len;
1827
}
1828
if (verify_bin_file(argv[2], argv[3], argv[4], argv[5], argv[6], NULL, adata, adata_len)) {
1829
ret = -1;
1830
printf("Signature check of %s failed\n", argv[5]);
1831
goto err;
1832
} else {
1833
printf("Signature check of %s OK\n", argv[5]);
1834
}
1835
}
1836
ret = are_str_equal(argv[1], "scalar_mult", &check); EG(ret, err);
1837
if (check) {
1838
found = 1;
1839
/* Point scalar multiplication --------------------
1840
*
1841
* arg1 = curve name ("frp256v1", ...)
1842
* arg2 = scalar
1843
* arg3 = point to multiply
1844
* arg4 = file name where to save the result
1845
*/
1846
if (argc != 6) {
1847
ret = -1;
1848
printf("Bad args number for %s %s:\n", argv[0],
1849
argv[1]);
1850
printf("\targ1 = curve name: ");
1851
print_curves();
1852
printf("\n");
1853
1854
printf("\targ2 = scalar bin file\n");
1855
printf("\targ3 = point to multiply bin file (projective coordinates)\n");
1856
printf("\targ4 = file name where to save the result\n");
1857
goto err;
1858
}
1859
if(ec_scalar_mult(argv[2], argv[3], argv[4], argv[5])){
1860
ret = -1;
1861
printf("Scalar multiplication failed\n");
1862
goto err;
1863
}
1864
}
1865
1866
if (found == 0) {
1867
/* Bad first argument, print help */
1868
ret = -1;
1869
printf("Bad first argument '%s'\n", argv[1]);
1870
print_help(argv[0]);
1871
goto err;
1872
}
1873
1874
ret = 0;
1875
1876
err:
1877
return ret;
1878
}
1879
1880