ltc update
Karel Miko
5 years ago
70 | 70 | } |
71 | 71 | |
72 | 72 | #ifdef LTC_CLEAN_STACK |
73 | static int _md4_compress(hash_state *md, unsigned char *buf) | |
73 | static int _md4_compress(hash_state *md, const unsigned char *buf) | |
74 | 74 | #else |
75 | 75 | static int md4_compress(hash_state *md, const unsigned char *buf) |
76 | 76 | #endif |
154 | 154 | } |
155 | 155 | |
156 | 156 | #ifdef LTC_CLEAN_STACK |
157 | static int md4_compress(hash_state *md, unsigned char *buf) | |
157 | static int md4_compress(hash_state *md, const unsigned char *buf) | |
158 | 158 | { |
159 | 159 | int err; |
160 | 160 | err = _md4_compress(md, buf); |
95 | 95 | #endif |
96 | 96 | |
97 | 97 | #ifdef LTC_CLEAN_STACK |
98 | static int _md5_compress(hash_state *md, unsigned char *buf) | |
98 | static int _md5_compress(hash_state *md, const unsigned char *buf) | |
99 | 99 | #else |
100 | 100 | static int md5_compress(hash_state *md, const unsigned char *buf) |
101 | 101 | #endif |
213 | 213 | } |
214 | 214 | |
215 | 215 | #ifdef LTC_CLEAN_STACK |
216 | static int md5_compress(hash_state *md, unsigned char *buf) | |
216 | static int md5_compress(hash_state *md, const unsigned char *buf) | |
217 | 217 | { |
218 | 218 | int err; |
219 | 219 | err = _md5_compress(md, buf); |
78 | 78 | (a) = ROLc((a), (s)); |
79 | 79 | |
80 | 80 | #ifdef LTC_CLEAN_STACK |
81 | static int _rmd128_compress(hash_state *md, unsigned char *buf) | |
81 | static int _rmd128_compress(hash_state *md, const unsigned char *buf) | |
82 | 82 | #else |
83 | 83 | static int rmd128_compress(hash_state *md, const unsigned char *buf) |
84 | 84 | #endif |
252 | 252 | } |
253 | 253 | |
254 | 254 | #ifdef LTC_CLEAN_STACK |
255 | static int rmd128_compress(hash_state *md, unsigned char *buf) | |
255 | static int rmd128_compress(hash_state *md, const unsigned char *buf) | |
256 | 256 | { |
257 | 257 | int err; |
258 | 258 | err = _rmd128_compress(md, buf); |
98 | 98 | |
99 | 99 | |
100 | 100 | #ifdef LTC_CLEAN_STACK |
101 | static int _rmd160_compress(hash_state *md, unsigned char *buf) | |
101 | static int _rmd160_compress(hash_state *md, const unsigned char *buf) | |
102 | 102 | #else |
103 | 103 | static int rmd160_compress(hash_state *md, const unsigned char *buf) |
104 | 104 | #endif |
310 | 310 | } |
311 | 311 | |
312 | 312 | #ifdef LTC_CLEAN_STACK |
313 | static int rmd160_compress(hash_state *md, unsigned char *buf) | |
313 | static int rmd160_compress(hash_state *md, const unsigned char *buf) | |
314 | 314 | { |
315 | 315 | int err; |
316 | 316 | err = _rmd160_compress(md, buf); |
72 | 72 | (a) = ROLc((a), (s)); |
73 | 73 | |
74 | 74 | #ifdef LTC_CLEAN_STACK |
75 | static int _rmd256_compress(hash_state *md, unsigned char *buf) | |
75 | static int _rmd256_compress(hash_state *md, const unsigned char *buf) | |
76 | 76 | #else |
77 | 77 | static int rmd256_compress(hash_state *md, const unsigned char *buf) |
78 | 78 | #endif |
261 | 261 | } |
262 | 262 | |
263 | 263 | #ifdef LTC_CLEAN_STACK |
264 | static int rmd256_compress(hash_state *md, unsigned char *buf) | |
264 | static int rmd256_compress(hash_state *md, const unsigned char *buf) | |
265 | 265 | { |
266 | 266 | int err; |
267 | 267 | err = _rmd256_compress(md, buf); |
93 | 93 | |
94 | 94 | |
95 | 95 | #ifdef LTC_CLEAN_STACK |
96 | static int _rmd320_compress(hash_state *md, unsigned char *buf) | |
96 | static int _rmd320_compress(hash_state *md, const unsigned char *buf) | |
97 | 97 | #else |
98 | 98 | static int rmd320_compress(hash_state *md, const unsigned char *buf) |
99 | 99 | #endif |
324 | 324 | } |
325 | 325 | |
326 | 326 | #ifdef LTC_CLEAN_STACK |
327 | static int rmd320_compress(hash_state *md, unsigned char *buf) | |
327 | static int rmd320_compress(hash_state *md, const unsigned char *buf) | |
328 | 328 | { |
329 | 329 | int err; |
330 | 330 | err = _rmd320_compress(md, buf); |
39 | 39 | #define F3(x,y,z) (x ^ y ^ z) |
40 | 40 | |
41 | 41 | #ifdef LTC_CLEAN_STACK |
42 | static int _sha1_compress(hash_state *md, unsigned char *buf) | |
42 | static int _sha1_compress(hash_state *md, const unsigned char *buf) | |
43 | 43 | #else |
44 | 44 | static int sha1_compress(hash_state *md, const unsigned char *buf) |
45 | 45 | #endif |
145 | 145 | } |
146 | 146 | |
147 | 147 | #ifdef LTC_CLEAN_STACK |
148 | static int sha1_compress(hash_state *md, unsigned char *buf) | |
148 | static int sha1_compress(hash_state *md, const unsigned char *buf) | |
149 | 149 | { |
150 | 150 | int err; |
151 | 151 | err = _sha1_compress(md, buf); |
63 | 63 | |
64 | 64 | /* compress 512-bits */ |
65 | 65 | #ifdef LTC_CLEAN_STACK |
66 | static int _sha256_compress(hash_state * md, unsigned char *buf) | |
66 | static int _sha256_compress(hash_state * md, const unsigned char *buf) | |
67 | 67 | #else |
68 | 68 | static int sha256_compress(hash_state * md, const unsigned char *buf) |
69 | 69 | #endif |
186 | 186 | } |
187 | 187 | |
188 | 188 | #ifdef LTC_CLEAN_STACK |
189 | static int sha256_compress(hash_state * md, unsigned char *buf) | |
189 | static int sha256_compress(hash_state * md, const unsigned char *buf) | |
190 | 190 | { |
191 | 191 | int err; |
192 | 192 | err = _sha256_compress(md, buf); |
88 | 88 | |
89 | 89 | /* compress 1024-bits */ |
90 | 90 | #ifdef LTC_CLEAN_STACK |
91 | static int _sha512_compress(hash_state * md, unsigned char *buf) | |
91 | static int _sha512_compress(hash_state * md, const unsigned char *buf) | |
92 | 92 | #else |
93 | 93 | static int sha512_compress(hash_state * md, const unsigned char *buf) |
94 | 94 | #endif |
155 | 155 | |
156 | 156 | /* compress 1024-bits */ |
157 | 157 | #ifdef LTC_CLEAN_STACK |
158 | static int sha512_compress(hash_state * md, unsigned char *buf) | |
158 | static int sha512_compress(hash_state * md, const unsigned char *buf) | |
159 | 159 | { |
160 | 160 | int err; |
161 | 161 | err = _sha512_compress(md, buf); |
638 | 638 | } |
639 | 639 | |
640 | 640 | #ifdef LTC_CLEAN_STACK |
641 | static int tiger_compress(hash_state *md, unsigned char *buf) | |
641 | static int tiger_compress(hash_state *md, const unsigned char *buf) | |
642 | 642 | { |
643 | 643 | int err; |
644 | 644 | err = _tiger_compress(md, buf); |
108 | 108 | |
109 | 109 | |
110 | 110 | #ifdef LTC_CLEAN_STACK |
111 | static int whirlpool_compress(hash_state *md, unsigned char *buf) | |
111 | static int whirlpool_compress(hash_state *md, const unsigned char *buf) | |
112 | 112 | { |
113 | 113 | int err; |
114 | 114 | err = _whirlpool_compress(md, buf); |
527 | 527 | #define LTC_ECC_SECP256R1 |
528 | 528 | #define LTC_ECC_SECP384R1 |
529 | 529 | #define LTC_ECC_SECP521R1 |
530 | /* OLD deprecated (but still working) defines */ | |
531 | #define LTC_ECC112 | |
532 | #define LTC_ECC128 | |
533 | #define LTC_ECC160 | |
534 | #define LTC_ECC192 | |
535 | #define LTC_ECC224 | |
536 | #define LTC_ECC256 | |
537 | #define LTC_ECC384 | |
538 | #define LTC_ECC521 | |
539 | #endif | |
530 | #endif | |
531 | #endif | |
532 | ||
533 | #if defined(LTC_DER) | |
534 | #ifndef LTC_DER_MAX_RECURSION | |
535 | /* Maximum recursion limit when processing nested ASN.1 types. */ | |
536 | #define LTC_DER_MAX_RECURSION 30 | |
537 | #endif | |
540 | 538 | #endif |
541 | 539 | |
542 | 540 | #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT) |
645 | 643 | #endif |
646 | 644 | #endif |
647 | 645 | |
646 | /* ECC backwards compatibility */ | |
647 | #if !defined(LTC_ECC_SECP112R1) && defined(LTC_ECC112) | |
648 | #define LTC_ECC_SECP112R1 | |
649 | #undef LTC_ECC112 | |
650 | #endif | |
651 | #if !defined(LTC_ECC_SECP128R1) && defined(LTC_ECC128) | |
652 | #define LTC_ECC_SECP128R1 | |
653 | #undef LTC_ECC128 | |
654 | #endif | |
655 | #if !defined(LTC_ECC_SECP160R1) && defined(LTC_ECC160) | |
656 | #define LTC_ECC_SECP160R1 | |
657 | #undef LTC_ECC160 | |
658 | #endif | |
659 | #if !defined(LTC_ECC_SECP192R1) && defined(LTC_ECC192) | |
660 | #define LTC_ECC_SECP192R1 | |
661 | #undef LTC_ECC192 | |
662 | #endif | |
663 | #if !defined(LTC_ECC_SECP224R1) && defined(LTC_ECC224) | |
664 | #define LTC_ECC_SECP224R1 | |
665 | #undef LTC_ECC224 | |
666 | #endif | |
667 | #if !defined(LTC_ECC_SECP256R1) && defined(LTC_ECC256) | |
668 | #define LTC_ECC_SECP256R1 | |
669 | #undef LTC_ECC256 | |
670 | #endif | |
671 | #if !defined(LTC_ECC_SECP384R1) && defined(LTC_ECC384) | |
672 | #define LTC_ECC_SECP384R1 | |
673 | #undef LTC_ECC384 | |
674 | #endif | |
675 | #if !defined(LTC_ECC_SECP512R1) && defined(LTC_ECC521) | |
676 | #define LTC_ECC_SECP521R1 | |
677 | #undef LTC_ECC521 | |
678 | #endif | |
679 | ||
648 | 680 | /* ref: $Format:%D$ */ |
649 | 681 | /* git commit: $Format:%H$ */ |
650 | 682 | /* commit time: $Format:%ai$ */ |
522 | 522 | } \ |
523 | 523 | while (inlen > 0) { \ |
524 | 524 | if (md-> state_var .curlen == 0 && inlen >= block_size) { \ |
525 | if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ | |
525 | if ((err = compress_name (md, in)) != CRYPT_OK) { \ | |
526 | 526 | return err; \ |
527 | 527 | } \ |
528 | 528 | md-> state_var .length += block_size * 8; \ |
339 | 339 | |
340 | 340 | int ecc_test(void); |
341 | 341 | void ecc_sizes(int *low, int *high); |
342 | int ecc_get_size(ecc_key *key); | |
342 | int ecc_get_size(const ecc_key *key); | |
343 | 343 | |
344 | 344 | int ecc_get_curve(const char* name_or_oid, const ltc_ecc_curve** cu); |
345 | 345 | int ecc_set_dp(const ltc_ecc_curve *cu, ecc_key *key); |
346 | 346 | int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key); |
347 | 347 | int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key *key); |
348 | int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); | |
348 | int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key); | |
349 | 349 | |
350 | 350 | int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); |
351 | 351 | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_curve *cu); |
352 | 352 | void ecc_free(ecc_key *key); |
353 | 353 | |
354 | int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); | |
354 | int ecc_export(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key); | |
355 | 355 | int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); |
356 | 356 | int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu); |
357 | 357 | |
358 | int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); | |
358 | int ecc_ansi_x963_export(const ecc_key *key, unsigned char *out, unsigned long *outlen); | |
359 | 359 | int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); |
360 | 360 | int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu); |
361 | 361 | |
362 | int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); | |
362 | int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key); | |
363 | 363 | int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key); |
364 | 364 | int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key); |
365 | 365 | int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key); |
366 | 366 | |
367 | int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, | |
367 | int ecc_shared_secret(const ecc_key *private_key, const ecc_key *public_key, | |
368 | 368 | unsigned char *out, unsigned long *outlen); |
369 | 369 | |
370 | 370 | int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, |
371 | 371 | unsigned char *out, unsigned long *outlen, |
372 | 372 | prng_state *prng, int wprng, int hash, |
373 | ecc_key *key); | |
373 | const ecc_key *key); | |
374 | 374 | |
375 | 375 | int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, |
376 | 376 | unsigned char *out, unsigned long *outlen, |
377 | ecc_key *key); | |
377 | const ecc_key *key); | |
378 | 378 | |
379 | 379 | int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, |
380 | 380 | unsigned char *out, unsigned long *outlen, |
381 | prng_state *prng, int wprng, ecc_key *key); | |
381 | prng_state *prng, int wprng, const ecc_key *key); | |
382 | 382 | |
383 | 383 | int ecc_sign_hash(const unsigned char *in, unsigned long inlen, |
384 | 384 | unsigned char *out, unsigned long *outlen, |
385 | prng_state *prng, int wprng, ecc_key *key); | |
385 | prng_state *prng, int wprng, const ecc_key *key); | |
386 | 386 | |
387 | 387 | int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, |
388 | 388 | const unsigned char *hash, unsigned long hashlen, |
389 | int *stat, ecc_key *key); | |
389 | int *stat, const ecc_key *key); | |
390 | 390 | |
391 | 391 | int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, |
392 | 392 | const unsigned char *hash, unsigned long hashlen, |
393 | int *stat, ecc_key *key); | |
393 | int *stat, const ecc_key *key); | |
394 | 394 | |
395 | 395 | |
396 | 396 | #ifdef LTC_SOURCE |
409 | 409 | int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval); |
410 | 410 | int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y); |
411 | 411 | int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); |
412 | int ltc_ecc_verify_key(ecc_key *key); | |
412 | int ltc_ecc_verify_key(const ecc_key *key); | |
413 | 413 | |
414 | 414 | /* point ops (mp == montgomery digit) */ |
415 | 415 | #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) |
427 | 427 | #endif |
428 | 428 | #if defined(LTC_DER) |
429 | 429 | " DER " |
430 | " " NAME_VALUE(LTC_DER_MAX_RECURSION) " " | |
430 | 431 | #endif |
431 | 432 | #if defined(LTC_PKCS_1) |
432 | 433 | " PKCS#1 " |
125 | 125 | |
126 | 126 | #ifdef LTC_DER |
127 | 127 | /* DER handling */ |
128 | {"LTC_DER", 1}, | |
128 | 129 | _C_STRINGIFY(LTC_ASN1_EOL), |
129 | 130 | _C_STRINGIFY(LTC_ASN1_BOOLEAN), |
130 | 131 | _C_STRINGIFY(LTC_ASN1_INTEGER), |
145 | 146 | _C_STRINGIFY(LTC_ASN1_TELETEX_STRING), |
146 | 147 | _C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME), |
147 | 148 | _C_STRINGIFY(LTC_ASN1_CUSTOM_TYPE), |
149 | _C_STRINGIFY(LTC_DER_MAX_RECURSION), | |
150 | #else | |
151 | {"LTC_DER", 0}, | |
148 | 152 | #endif |
149 | 153 | |
150 | 154 | #ifdef LTC_CTR_MODE |
42 | 42 | */ |
43 | 43 | int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) |
44 | 44 | { |
45 | ltc_asn1_list *l; | |
45 | ltc_asn1_list *l, *t; | |
46 | 46 | unsigned long err, identifier, len, totlen, data_offset, id_len, len_len; |
47 | 47 | void *realloc_tmp; |
48 | 48 | |
462 | 462 | l->child->parent = l; |
463 | 463 | } |
464 | 464 | |
465 | t = l; | |
466 | len_len = 0; | |
467 | while((t != NULL) && (t->child != NULL)) { | |
468 | len_len++; | |
469 | t = t->child; | |
470 | } | |
471 | if (len_len > LTC_DER_MAX_RECURSION) { | |
472 | err = CRYPT_PK_ASN1_ERROR; | |
473 | goto error; | |
474 | } | |
475 | ||
465 | 476 | break; |
466 | 477 | |
467 | 478 | case 0x80: /* Context-specific */ |
23 | 23 | * - http://www.ecc-brainpool.org/download/Domain-parameters.pdf (named: BRAINPOOLP*) |
24 | 24 | */ |
25 | 25 | const ltc_ecc_curve ltc_ecc_curves[] = { |
26 | #if defined(LTC_ECC_SECP112R1) || defined(LTC_ECC112) | |
26 | #ifdef LTC_ECC_SECP112R1 | |
27 | 27 | { |
28 | 28 | /* prime */ "DB7C2ABF62E35E668076BEAD208B", |
29 | 29 | /* A */ "DB7C2ABF62E35E668076BEAD2088", |
47 | 47 | /* OID */ "1.3.132.0.7" |
48 | 48 | }, |
49 | 49 | #endif |
50 | #if defined(LTC_ECC_SECP128R1) || defined(LTC_ECC128) | |
50 | #ifdef LTC_ECC_SECP128R1 | |
51 | 51 | { |
52 | 52 | /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", |
53 | 53 | /* A */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", |
71 | 71 | /* OID */ "1.3.132.0.29" |
72 | 72 | }, |
73 | 73 | #endif |
74 | #if defined(LTC_ECC_SECP160R1) || defined(LTC_ECC160) | |
74 | #ifdef LTC_ECC_SECP160R1 | |
75 | 75 | { |
76 | 76 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", |
77 | 77 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", |
107 | 107 | /* OID */ "1.3.132.0.9" |
108 | 108 | }, |
109 | 109 | #endif |
110 | #if defined(LTC_ECC_SECP192R1) || defined(LTC_ECC192) | |
110 | #ifdef LTC_ECC_SECP192R1 | |
111 | 111 | { |
112 | 112 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", |
113 | 113 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", |
155 | 155 | /* OID */ "1.3.132.0.31" |
156 | 156 | }, |
157 | 157 | #endif |
158 | #if defined(LTC_ECC_SECP224R1) || defined(LTC_ECC224) | |
158 | #ifdef LTC_ECC_SECP224R1 | |
159 | 159 | { |
160 | 160 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", |
161 | 161 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", |
179 | 179 | /* OID */ "1.3.132.0.32" |
180 | 180 | }, |
181 | 181 | #endif |
182 | #if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256) | |
182 | #ifdef LTC_ECC_SECP256R1 | |
183 | 183 | { |
184 | 184 | /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", |
185 | 185 | /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", |
203 | 203 | /* OID */ "1.3.132.0.10" |
204 | 204 | }, |
205 | 205 | #endif |
206 | #if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384) | |
206 | #ifdef LTC_ECC_SECP384R1 | |
207 | 207 | { |
208 | 208 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", |
209 | 209 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", |
215 | 215 | /* OID */ "1.3.132.0.34" |
216 | 216 | }, |
217 | 217 | #endif |
218 | #if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521) | |
218 | #ifdef LTC_ECC_SECP521R1 | |
219 | 219 | { |
220 | 220 | /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", |
221 | 221 | /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", |
21 | 21 | @param outlen [in/out] Length of destination and final output size |
22 | 22 | Return CRYPT_OK on success |
23 | 23 | */ |
24 | int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen) | |
24 | int ecc_ansi_x963_export(const ecc_key *key, unsigned char *out, unsigned long *outlen) | |
25 | 25 | { |
26 | 26 | unsigned char buf[ECC_BUF_SIZE]; |
27 | 27 | unsigned long numlen, xlen, ylen; |
26 | 26 | */ |
27 | 27 | int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, |
28 | 28 | unsigned char *out, unsigned long *outlen, |
29 | ecc_key *key) | |
29 | const ecc_key *key) | |
30 | 30 | { |
31 | 31 | unsigned char *ecc_shared, *skey, *pub_expt; |
32 | 32 | unsigned long x, y; |
30 | 30 | int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, |
31 | 31 | unsigned char *out, unsigned long *outlen, |
32 | 32 | prng_state *prng, int wprng, int hash, |
33 | ecc_key *key) | |
33 | const ecc_key *key) | |
34 | 34 | { |
35 | 35 | unsigned char *pub_expt, *ecc_shared, *skey; |
36 | 36 | ecc_key pubkey; |
23 | 23 | @param key The key to export |
24 | 24 | @return CRYPT_OK if successful |
25 | 25 | */ |
26 | int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) | |
26 | int ecc_export(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key) | |
27 | 27 | { |
28 | 28 | int err; |
29 | 29 | unsigned char flags[1]; |
19 | 19 | @return CRYPT_OK if successful |
20 | 20 | */ |
21 | 21 | |
22 | int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) | |
22 | int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key) | |
23 | 23 | { |
24 | int err; | |
25 | void *prime, *order, *a, *b, *gx, *gy; | |
26 | unsigned char bin_a[256], bin_b[256], bin_k[256], bin_g[512], bin_xy[512]; | |
27 | unsigned long len_a, len_b, len_k, len_g, len_xy; | |
28 | unsigned long cofactor, one = 1; | |
29 | oid_st oid; | |
30 | ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4], pub_xy, ecparams; | |
31 | int flag_oid = type & PK_CURVEOID ? 1 : 0; | |
32 | int flag_com = type & PK_COMPRESSED ? 1 : 0; | |
33 | int flag_pri = type & PK_PRIVATE ? 1 : 0; | |
24 | int err; | |
25 | void *prime, *order, *a, *b, *gx, *gy; | |
26 | unsigned char bin_a[256], bin_b[256], bin_k[256], bin_g[512], bin_xy[512]; | |
27 | unsigned long len_a, len_b, len_k, len_g, len_xy; | |
28 | unsigned long cofactor, one = 1; | |
29 | oid_st oid; | |
30 | ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4], pub_xy, ecparams; | |
31 | int flag_oid = type & PK_CURVEOID ? 1 : 0; | |
32 | int flag_com = type & PK_COMPRESSED ? 1 : 0; | |
33 | int flag_pri = type & PK_PRIVATE ? 1 : 0; | |
34 | 34 | |
35 | LTC_ARGCHK(out != NULL); | |
36 | LTC_ARGCHK(outlen != NULL); | |
37 | LTC_ARGCHK(key != NULL); | |
35 | LTC_ARGCHK(out != NULL); | |
36 | LTC_ARGCHK(outlen != NULL); | |
37 | LTC_ARGCHK(key != NULL); | |
38 | 38 | |
39 | if (key->type != PK_PRIVATE && flag_pri) return CRYPT_PK_TYPE_MISMATCH; | |
39 | if (key->type != PK_PRIVATE && flag_pri) return CRYPT_PK_TYPE_MISMATCH; | |
40 | 40 | |
41 | prime = key->dp.prime; | |
42 | order = key->dp.order; | |
43 | b = key->dp.B; | |
44 | a = key->dp.A; | |
45 | gx = key->dp.base.x; | |
46 | gy = key->dp.base.y; | |
41 | prime = key->dp.prime; | |
42 | order = key->dp.order; | |
43 | b = key->dp.B; | |
44 | a = key->dp.A; | |
45 | gx = key->dp.base.x; | |
46 | gy = key->dp.base.y; | |
47 | 47 | |
48 | /* curve param a */ | |
49 | len_a = mp_unsigned_bin_size(a); | |
50 | if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } | |
51 | if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) goto error; | |
52 | if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* XXX-TODO hack to handle case a == 0 */ | |
48 | /* curve param a */ | |
49 | len_a = mp_unsigned_bin_size(a); | |
50 | if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } | |
51 | if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) { goto error; } | |
52 | if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* handle case a == 0 */ | |
53 | 53 | |
54 | /* curve param b */ | |
55 | len_b = mp_unsigned_bin_size(b); | |
56 | if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } | |
57 | if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) goto error; | |
58 | if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* XXX-TODO hack to handle case b == 0 */ | |
54 | /* curve param b */ | |
55 | len_b = mp_unsigned_bin_size(b); | |
56 | if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } | |
57 | if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) { goto error; } | |
58 | if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* handle case b == 0 */ | |
59 | 59 | |
60 | /* base point - (un)compressed based on flag_com */ | |
61 | len_g = sizeof(bin_g); | |
62 | if ((err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp.size, flag_com)) != CRYPT_OK) goto error; | |
60 | /* base point - (un)compressed based on flag_com */ | |
61 | len_g = sizeof(bin_g); | |
62 | err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp.size, flag_com); | |
63 | if (err != CRYPT_OK) { goto error; } | |
63 | 64 | |
64 | /* public key - (un)compressed based on flag_com */ | |
65 | len_xy = sizeof(bin_xy); | |
66 | if ((err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp.size, flag_com)) != CRYPT_OK) goto error; | |
65 | /* public key - (un)compressed based on flag_com */ | |
66 | len_xy = sizeof(bin_xy); | |
67 | err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp.size, flag_com); | |
68 | if (err != CRYPT_OK) { goto error; } | |
67 | 69 | |
68 | /* co-factor */ | |
69 | cofactor = key->dp.cofactor; | |
70 | /* co-factor */ | |
71 | cofactor = key->dp.cofactor; | |
70 | 72 | |
71 | /* we support only prime-field EC */ | |
72 | if ((err = pk_get_oid(PKA_EC_PRIMEF, &oid)) != CRYPT_OK) goto error; | |
73 | /* we support only prime-field EC */ | |
74 | if ((err = pk_get_oid(PKA_EC_PRIMEF, &oid)) != CRYPT_OK) { goto error; } | |
73 | 75 | |
74 | if (flag_oid) { | |
75 | /* from http://tools.ietf.org/html/rfc5912 | |
76 | ||
77 | ECParameters ::= CHOICE { | |
78 | namedCurve CURVE.&id({NamedCurve}) # OBJECT | |
79 | } | |
76 | if (flag_oid) { | |
77 | /* http://tools.ietf.org/html/rfc5912 | |
78 | ECParameters ::= CHOICE { | |
79 | namedCurve CURVE.&id({NamedCurve}) # OBJECT | |
80 | } | |
80 | 81 | */ |
81 | if (key->dp.oidlen == 0) { | |
82 | err = CRYPT_INVALID_ARG; | |
83 | goto error; | |
84 | } | |
82 | if (key->dp.oidlen == 0) { err = CRYPT_INVALID_ARG; goto error; } | |
85 | 83 | LTC_SET_ASN1(&ecparams, 0, LTC_ASN1_OBJECT_IDENTIFIER, key->dp.oid, key->dp.oidlen); |
86 | } | |
87 | else { | |
88 | /* from http://tools.ietf.org/html/rfc3279 | |
89 | ||
90 | ECParameters ::= SEQUENCE { # SEQUENCE | |
91 | version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01 | |
92 | FieldID ::= SEQUENCE { # SEQUENCE | |
93 | fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field | |
94 | parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER | |
95 | } | |
96 | Curve ::= SEQUENCE { # SEQUENCE | |
97 | a FieldElement ::= OCTET STRING # OCTET STRING | |
98 | b FieldElement ::= OCTET STRING # OCTET STRING | |
99 | seed BIT STRING OPTIONAL | |
100 | } | |
101 | base ECPoint ::= OCTET STRING # OCTET STRING | |
102 | order INTEGER, # INTEGER | |
103 | cofactor INTEGER OPTIONAL # INTEGER | |
104 | } | |
84 | } | |
85 | else { | |
86 | /* http://tools.ietf.org/html/rfc3279 | |
87 | ECParameters ::= SEQUENCE { # SEQUENCE | |
88 | version INTEGER { ecpVer1(1) } (ecpVer1) # INTEGER :01 | |
89 | FieldID ::= SEQUENCE { # SEQUENCE | |
90 | fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field | |
91 | parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER | |
92 | } | |
93 | Curve ::= SEQUENCE { # SEQUENCE | |
94 | a FieldElement ::= OCTET STRING # OCTET STRING | |
95 | b FieldElement ::= OCTET STRING # OCTET STRING | |
96 | seed BIT STRING OPTIONAL | |
97 | } | |
98 | base ECPoint ::= OCTET STRING # OCTET STRING | |
99 | order INTEGER, # INTEGER | |
100 | cofactor INTEGER OPTIONAL # INTEGER | |
101 | } | |
105 | 102 | */ |
106 | 103 | |
107 | 104 | /* FieldID SEQUENCE */ |
122 | 119 | |
123 | 120 | /* ECParameters used by ECPrivateKey or SubjectPublicKeyInfo below */ |
124 | 121 | LTC_SET_ASN1(&ecparams, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL); |
125 | } | |
122 | } | |
126 | 123 | |
127 | if (flag_pri) { | |
128 | /* private key format: http://tools.ietf.org/html/rfc5915 | |
129 | ||
130 | ECPrivateKey ::= SEQUENCE { # SEQUENCE | |
131 | version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # INTEGER :01 | |
132 | privateKey OCTET STRING, # OCTET STRING | |
133 | [0] ECParameters # see above | |
134 | [1] publicKey # BIT STRING | |
135 | } | |
124 | if (flag_pri) { | |
125 | /* http://tools.ietf.org/html/rfc5915 | |
126 | ECPrivateKey ::= SEQUENCE { # SEQUENCE | |
127 | version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1) # INTEGER :01 | |
128 | privateKey OCTET STRING, # OCTET STRING | |
129 | [0] ECParameters # see above | |
130 | [1] publicKey # BIT STRING | |
131 | } | |
136 | 132 | */ |
137 | 133 | |
138 | 134 | /* private key */ |
139 | 135 | len_k = mp_unsigned_bin_size(key->k); |
140 | if (len_k > sizeof(bin_k)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } | |
141 | if ((err = mp_to_unsigned_bin(key->k, bin_k)) != CRYPT_OK) goto error; | |
136 | if (len_k > sizeof(bin_k)) { err = CRYPT_BUFFER_OVERFLOW; goto error; } | |
137 | if ((err = mp_to_unsigned_bin(key->k, bin_k)) != CRYPT_OK) { goto error; } | |
142 | 138 | |
143 | LTC_SET_ASN1(&pub_xy, 0, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy); | |
144 | LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1); | |
145 | LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k); | |
139 | LTC_SET_ASN1(&pub_xy, 0, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy); | |
140 | LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1); | |
141 | LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k); | |
146 | 142 | LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, &ecparams); /* context specific 0 */ |
147 | 143 | LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, &pub_xy); /* context specific 1 */ |
148 | 144 | |
149 | 145 | err = der_encode_sequence(seq_priv, 4, out, outlen); |
150 | } | |
151 | else { | |
152 | /* public key format: http://tools.ietf.org/html/rfc5480 | |
153 | ||
154 | SubjectPublicKeyInfo ::= SEQUENCE { # SEQUENCE | |
155 | AlgorithmIdentifier ::= SEQUENCE { # SEQUENCE | |
156 | algorithm OBJECT IDENTIFIER # OBJECT :id-ecPublicKey | |
157 | ECParameters # see above | |
158 | } | |
159 | subjectPublicKey BIT STRING # BIT STRING | |
160 | } | |
146 | } | |
147 | else { | |
148 | /* http://tools.ietf.org/html/rfc5480 | |
149 | SubjectPublicKeyInfo ::= SEQUENCE { # SEQUENCE | |
150 | AlgorithmIdentifier ::= SEQUENCE { # SEQUENCE | |
151 | algorithm OBJECT IDENTIFIER # OBJECT :id-ecPublicKey | |
152 | ECParameters # see above | |
153 | } | |
154 | subjectPublicKey BIT STRING # BIT STRING | |
155 | } | |
161 | 156 | */ |
162 | err = x509_encode_subject_public_key_info( out, outlen, | |
163 | PKA_EC, bin_xy, len_xy, | |
164 | ecparams.type, ecparams.data, ecparams.size ); | |
165 | } | |
157 | err = x509_encode_subject_public_key_info( out, outlen, PKA_EC, bin_xy, len_xy, | |
158 | ecparams.type, ecparams.data, ecparams.size ); | |
159 | } | |
166 | 160 | |
167 | 161 | error: |
168 | return err; | |
162 | return err; | |
169 | 163 | } |
170 | 164 | |
171 | 165 | #endif |
10 | 10 | |
11 | 11 | #ifdef LTC_MECC |
12 | 12 | |
13 | const struct { | |
13 | static const struct { | |
14 | 14 | const char *OID; |
15 | 15 | const char *names[6]; |
16 | 16 | } _curve_names[] = { |
17 | #if defined(LTC_ECC_SECP112R1) || defined(LTC_ECC112) | |
17 | #ifdef LTC_ECC_SECP112R1 | |
18 | 18 | { |
19 | 19 | "1.3.132.0.6", { "SECP112R1", "ECC-112", NULL } |
20 | 20 | }, |
24 | 24 | "1.3.132.0.7", { "SECP112R2", NULL } |
25 | 25 | }, |
26 | 26 | #endif |
27 | #if defined(LTC_ECC_SECP128R1) || defined(LTC_ECC128) | |
27 | #ifdef LTC_ECC_SECP128R1 | |
28 | 28 | { |
29 | 29 | "1.3.132.0.28", { "SECP128R1", "ECC-128", NULL } |
30 | 30 | }, |
34 | 34 | "1.3.132.0.29", { "SECP128R2", NULL } |
35 | 35 | }, |
36 | 36 | #endif |
37 | #if defined(LTC_ECC_SECP160R1) || defined(LTC_ECC160) | |
37 | #ifdef LTC_ECC_SECP160R1 | |
38 | 38 | { |
39 | 39 | "1.3.132.0.8", { "SECP160R1", "ECC-160", NULL } |
40 | 40 | }, |
49 | 49 | "1.3.132.0.9", { "SECP160K1", NULL } |
50 | 50 | }, |
51 | 51 | #endif |
52 | #if defined(LTC_ECC_SECP192R1) || defined(LTC_ECC192) | |
52 | #ifdef LTC_ECC_SECP192R1 | |
53 | 53 | { |
54 | 54 | "1.2.840.10045.3.1.1", { "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", NULL } |
55 | 55 | }, |
69 | 69 | "1.3.132.0.31", { "SECP192K1", NULL } |
70 | 70 | }, |
71 | 71 | #endif |
72 | #if defined(LTC_ECC_SECP224R1) || defined(LTC_ECC224) | |
72 | #ifdef LTC_ECC_SECP224R1 | |
73 | 73 | { |
74 | 74 | "1.3.132.0.33", { "SECP224R1", "NISTP224", "ECC-224", "P-224", NULL } |
75 | 75 | }, |
79 | 79 | "1.3.132.0.32", { "SECP224K1", NULL } |
80 | 80 | }, |
81 | 81 | #endif |
82 | #if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256) | |
82 | #ifdef LTC_ECC_SECP256R1 | |
83 | 83 | { |
84 | 84 | "1.2.840.10045.3.1.7", { "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", NULL } |
85 | 85 | }, |
89 | 89 | "1.3.132.0.10", { "SECP256K1", NULL } |
90 | 90 | }, |
91 | 91 | #endif |
92 | #if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384) | |
92 | #ifdef LTC_ECC_SECP384R1 | |
93 | 93 | { |
94 | 94 | "1.3.132.0.34", { "SECP384R1", "NISTP384", "ECC-384", "P-384", NULL } |
95 | 95 | }, |
96 | 96 | #endif |
97 | #if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521) | |
97 | #ifdef LTC_ECC_SECP521R1 | |
98 | 98 | { |
99 | 99 | "1.3.132.0.35", { "SECP521R1", "NISTP521", "ECC-521", "P-521", NULL } |
100 | 100 | }, |
18 | 18 | Return CRYPT_OK on success |
19 | 19 | */ |
20 | 20 | |
21 | int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) | |
21 | int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key) | |
22 | 22 | { |
23 | 23 | unsigned long size, ksize; |
24 | 24 | int err, compressed; |
20 | 20 | @param key The key to get the size of |
21 | 21 | @return The size (octets) of the key or INT_MAX on error |
22 | 22 | */ |
23 | int ecc_get_size(ecc_key *key) | |
23 | int ecc_get_size(const ecc_key *key) | |
24 | 24 | { |
25 | 25 | if (key == NULL) { |
26 | 26 | return INT_MAX; |
14 | 14 | { |
15 | 15 | void *prime, *order, *a, *b, *gx, *gy; |
16 | 16 | ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], custom[2]; |
17 | unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; | |
17 | unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE]; | |
18 | unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128]; | |
18 | 19 | unsigned long len_a, len_b, len_k, len_g, len_xy, len_oid, len; |
19 | 20 | unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16], curveoid[16]; |
20 | 21 | char OID[256]; |
29 | 30 | |
30 | 31 | len_xy = sizeof(bin_xy); |
31 | 32 | len_oid = 16; |
32 | err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid); | |
33 | err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, | |
34 | LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid); | |
33 | 35 | if (err == CRYPT_OK) { |
34 | 36 | /* load curve parameters for given curve OID */ |
35 | 37 | len = sizeof(OID); |
44 | 46 | /* ### 2. try to load public key - curve parameters included */ |
45 | 47 | |
46 | 48 | /* ECParameters SEQUENCE */ |
47 | LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); | |
48 | LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); | |
49 | LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); | |
50 | LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); | |
51 | LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); | |
52 | LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); | |
49 | LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL); | |
50 | LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL); | |
51 | LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL); | |
52 | LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1); | |
53 | LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL); | |
54 | LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); | |
53 | 55 | seq_ecparams[5].optional = 1; |
54 | 56 | /* FieldID SEQUENCE */ |
55 | LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); | |
56 | LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); | |
57 | LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); | |
58 | LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); | |
57 | 59 | /* Curve SEQUENCE */ |
58 | LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); | |
59 | LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); | |
60 | LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); | |
60 | LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); | |
61 | LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); | |
62 | LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); | |
61 | 63 | seq_curve[2].optional = 1; |
62 | 64 | /* try to load public key */ |
63 | 65 | len_xy = sizeof(bin_xy); |
69 | 71 | len_b = seq_curve[1].size; |
70 | 72 | len_g = seq_ecparams[3].size; |
71 | 73 | /* create bignums */ |
72 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
73 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
74 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
74 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
75 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
76 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
75 | 77 | /* load curve parameters */ |
76 | 78 | if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } |
77 | 79 | /* load public key */ |
78 | if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } | |
80 | if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } | |
79 | 81 | goto success; |
80 | 82 | } |
81 | 83 | |
82 | 84 | /* ### 3. try to load private key - no curve parameters just curve OID */ |
83 | 85 | |
84 | 86 | /* ECPrivateKey SEQUENCE */ |
85 | LTC_SET_ASN1(custom, 0, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL); | |
86 | LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); | |
87 | LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); | |
88 | LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); | |
87 | LTC_SET_ASN1(custom, 0, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL); | |
88 | LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2)); | |
89 | LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL); | |
90 | LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE); | |
89 | 91 | LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */ |
90 | 92 | LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */ |
91 | 93 | |
120 | 122 | LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL); |
121 | 123 | seq_ecparams[5].optional = 1; |
122 | 124 | /* FieldID SEQUENCE */ |
123 | LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); | |
124 | LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); | |
125 | LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL); | |
126 | LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); | |
125 | 127 | /* Curve SEQUENCE */ |
126 | LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); | |
127 | LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); | |
128 | LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); | |
128 | LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE); | |
129 | LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE); | |
130 | LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128); | |
129 | 131 | seq_curve[2].optional = 1; |
130 | 132 | /* try to load private key */ |
131 | 133 | err = der_decode_sequence(in, inlen, seq_priv, 4); |
136 | 138 | len_b = seq_curve[1].size; |
137 | 139 | len_g = seq_ecparams[3].size; |
138 | 140 | /* create bignums */ |
139 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
140 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
141 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
141 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
142 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
143 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
142 | 144 | /* load curve parameters */ |
143 | 145 | if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } |
144 | 146 | /* load private+public key */ |
145 | if ((err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } | |
147 | if ((err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } | |
146 | 148 | goto success; |
147 | 149 | } |
148 | 150 | |
149 | 151 | /* ### 5. backward compatibility - try to load old-DER format */ |
150 | 152 | |
151 | if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; } | |
153 | if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; } | |
152 | 154 | |
153 | 155 | success: |
154 | 156 | err = CRYPT_OK; |
23 | 23 | @param outlen [in/out] The max size and resulting size of the shared secret |
24 | 24 | @return CRYPT_OK if successful |
25 | 25 | */ |
26 | int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, | |
26 | int ecc_shared_secret(const ecc_key *private_key, const ecc_key *public_key, | |
27 | 27 | unsigned char *out, unsigned long *outlen) |
28 | 28 | { |
29 | 29 | unsigned long x; |
17 | 17 | |
18 | 18 | static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, |
19 | 19 | unsigned char *out, unsigned long *outlen, |
20 | prng_state *prng, int wprng, ecc_key *key, int sigformat) | |
20 | prng_state *prng, int wprng, const ecc_key *key, int sigformat) | |
21 | 21 | { |
22 | 22 | ecc_key pubkey; |
23 | 23 | void *r, *s, *e, *p; |
131 | 131 | */ |
132 | 132 | int ecc_sign_hash(const unsigned char *in, unsigned long inlen, |
133 | 133 | unsigned char *out, unsigned long *outlen, |
134 | prng_state *prng, int wprng, ecc_key *key) | |
134 | prng_state *prng, int wprng, const ecc_key *key) | |
135 | 135 | { |
136 | 136 | return _ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key, 0); |
137 | 137 | } |
149 | 149 | */ |
150 | 150 | int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, |
151 | 151 | unsigned char *out, unsigned long *outlen, |
152 | prng_state *prng, int wprng, ecc_key *key) | |
152 | prng_state *prng, int wprng, const ecc_key *key) | |
153 | 153 | { |
154 | 154 | return _ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key, 1); |
155 | 155 | } |
17 | 17 | |
18 | 18 | static int _ecc_verify_hash(const unsigned char *sig, unsigned long siglen, |
19 | 19 | const unsigned char *hash, unsigned long hashlen, |
20 | int *stat, ecc_key *key, int sigformat) | |
20 | int *stat, const ecc_key *key, int sigformat) | |
21 | 21 | { |
22 | 22 | ecc_point *mG = NULL, *mQ = NULL; |
23 | 23 | void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a, *a_plus3 = NULL, *mu = NULL, *ma = NULL; |
36 | 36 | |
37 | 37 | /* allocate ints */ |
38 | 38 | if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &e, &a_plus3, NULL)) != CRYPT_OK) { |
39 | return CRYPT_MEM; | |
39 | return err; | |
40 | 40 | } |
41 | 41 | |
42 | 42 | p = key->dp.order; |
170 | 170 | */ |
171 | 171 | int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, |
172 | 172 | const unsigned char *hash, unsigned long hashlen, |
173 | int *stat, ecc_key *key) | |
173 | int *stat, const ecc_key *key) | |
174 | 174 | { |
175 | 175 | return _ecc_verify_hash(sig, siglen, hash, hashlen, stat, key, 0); |
176 | 176 | } |
187 | 187 | */ |
188 | 188 | int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, |
189 | 189 | const unsigned char *hash, unsigned long hashlen, |
190 | int *stat, ecc_key *key) | |
190 | int *stat, const ecc_key *key) | |
191 | 191 | { |
192 | 192 | return _ecc_verify_hash(sig, siglen, hash, hashlen, stat, key, 1); |
193 | 193 | } |
18 | 18 | @return CRYPT_OK if successful |
19 | 19 | */ |
20 | 20 | |
21 | int ltc_ecc_verify_key(ecc_key *key) | |
21 | int ltc_ecc_verify_key(const ecc_key *key) | |
22 | 22 | { |
23 | 23 | int err, inf; |
24 | void *prime = NULL; | |
25 | void *order = NULL; | |
26 | void *a = NULL; | |
27 | 24 | ecc_point *point; |
28 | ||
29 | prime = key->dp.prime; | |
30 | order = key->dp.order; | |
31 | a = key->dp.A; | |
25 | void *prime = key->dp.prime; | |
26 | void *order = key->dp.order; | |
27 | void *a = key->dp.A; | |
32 | 28 | |
33 | 29 | /* Test 1: Are the x and y points of the public key in the field? */ |
34 | 30 | if (ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) { |