1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 #include "tomcrypt_private.h"
5
6 #ifdef LTC_MECC
7
s_ecc_import_private_with_oid(const unsigned char * in,unsigned long inlen,ecc_key * key)8 static int s_ecc_import_private_with_oid(const unsigned char *in, unsigned long inlen, ecc_key *key)
9 {
10 ltc_asn1_list seq_priv[4], custom[2];
11 unsigned char bin_xy[2*ECC_MAXSIZE+2], bin_k[ECC_MAXSIZE];
12 unsigned long len, pkver = 0, curveoid[16];
13 char OID[256];
14 const ltc_ecc_curve *curve;
15 int err;
16
17 /* ### try to load private key - no curve parameters just curve OID */
18
19 /* ECPrivateKey SEQUENCE */
20 LTC_SET_ASN1(custom, 0, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL);
21 LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8UL*sizeof(bin_xy));
22 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
23 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k));
24 LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */
25 LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */
26
27 /* try to load private key */
28 err = der_decode_sequence(in, inlen, seq_priv, 4);
29 if (err == CRYPT_OK) {
30 /* load curve parameters for given curve OID */
31 len = sizeof(OID);
32 if ((err = pk_oid_num_to_str(curveoid, custom[0].size, OID, &len)) != CRYPT_OK) { goto error; }
33 if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; }
34 if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; }
35 /* load private+public key */
36 err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key);
37 }
38 error:
39 return err;
40 }
41
s_ecc_import_private_with_curve(const unsigned char * in,unsigned long inlen,ecc_key * key)42 static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned long inlen, ecc_key *key)
43 {
44 void *prime, *order, *a, *b, *gx, *gy;
45 ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], custom[2];
46 unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE];
47 unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
48 unsigned long len_a, len_b, len_k, len_g;
49 unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16];
50 int err;
51
52 if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, LTC_NULL)) != CRYPT_OK) {
53 return err;
54 }
55
56 /* ### try to load private key - curve parameters included */
57
58 /* ECPrivateKey SEQUENCE */
59 LTC_SET_ASN1(custom, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
60 LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8UL*sizeof(bin_xy));
61 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
62 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k));
63 LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */
64 LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */
65 /* ECParameters SEQUENCE */
66 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
67 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
68 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
69 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g));
70 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
71 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
72 seq_ecparams[5].optional = 1;
73 /* FieldID SEQUENCE */
74 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
75 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
76 /* Curve SEQUENCE */
77 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, sizeof(bin_a));
78 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, sizeof(bin_b));
79 LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, 8UL*sizeof(bin_seed));
80 seq_curve[2].optional = 1;
81 /* try to load private key */
82 err = der_decode_sequence(in, inlen, seq_priv, 4);
83 if (err == CRYPT_OK) {
84 len_k = seq_priv[1].size;
85 len_a = seq_curve[0].size;
86 len_b = seq_curve[1].size;
87 len_g = seq_ecparams[3].size;
88 /* create bignums */
89 if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
90 if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
91 if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
92 /* load curve parameters */
93 if ((err = ecc_set_curve_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; }
94 /* load private+public key */
95 err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key);
96 }
97 error:
98 mp_clear_multi(prime, order, a, b, gx, gy, LTC_NULL);
99 return err;
100 }
101
ecc_import_openssl(const unsigned char * in,unsigned long inlen,ecc_key * key)102 int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key)
103 {
104 int err;
105
106 if ((err = ecc_import_subject_public_key_info(in, inlen, key)) == CRYPT_OK) {
107 goto success;
108 }
109
110 if ((err = s_ecc_import_private_with_oid(in, inlen, key)) == CRYPT_OK) {
111 goto success;
112 }
113
114 err = s_ecc_import_private_with_curve(in, inlen, key);
115
116 success:
117 return err;
118 }
119
120 #endif
121