1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 *
4 * LibTomCrypt is a library that provides various cryptographic
5 * algorithms in a highly modular and flexible manner.
6 *
7 * The library is free for all purposes without any express
8 * guarantee it works.
9 */
10
11 #include "tomcrypt_private.h"
12
13 #ifdef LTC_MECC
14
_ecc_cmp_hex_bn(const char * left_hex,void * right_bn,void * tmp_bn)15 static int _ecc_cmp_hex_bn(const char *left_hex, void *right_bn, void *tmp_bn)
16 {
17 if (mp_read_radix(tmp_bn, left_hex, 16) != CRYPT_OK) return 0;
18 if (mp_cmp(tmp_bn, right_bn) != LTC_MP_EQ) return 0;
19 return 1;
20 }
21
_ecc_oid_lookup(ecc_key * key)22 static void _ecc_oid_lookup(ecc_key *key)
23 {
24 void *bn;
25 const ltc_ecc_curve *curve;
26
27 key->dp.oidlen = 0;
28 if (mp_init(&bn) != CRYPT_OK) return;
29 for (curve = ltc_ecc_curves; curve->prime != NULL; curve++) {
30 if (_ecc_cmp_hex_bn(curve->prime, key->dp.prime, bn) != 1) continue;
31 if (_ecc_cmp_hex_bn(curve->order, key->dp.order, bn) != 1) continue;
32 if (_ecc_cmp_hex_bn(curve->A, key->dp.A, bn) != 1) continue;
33 if (_ecc_cmp_hex_bn(curve->B, key->dp.B, bn) != 1) continue;
34 if (_ecc_cmp_hex_bn(curve->Gx, key->dp.base.x, bn) != 1) continue;
35 if (_ecc_cmp_hex_bn(curve->Gy, key->dp.base.y, bn) != 1) continue;
36 if (key->dp.cofactor != curve->cofactor) continue;
37 break; /* found */
38 }
39 mp_clear(bn);
40 if (curve->prime && curve->OID) {
41 key->dp.oidlen = 16; /* size of key->dp.oid */
42 pk_oid_str_to_num(curve->OID, key->dp.oid, &key->dp.oidlen);
43 }
44 }
45
ecc_copy_curve(const ecc_key * srckey,ecc_key * key)46 int ecc_copy_curve(const ecc_key *srckey, ecc_key *key)
47 {
48 unsigned long i;
49 int err;
50
51 LTC_ARGCHK(key != NULL);
52 LTC_ARGCHK(srckey != NULL);
53
54 if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B,
55 &key->dp.base.x, &key->dp.base.y, &key->dp.base.z,
56 &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k,
57 NULL)) != CRYPT_OK) {
58 return err;
59 }
60
61 /* A, B, order, prime, Gx, Gy */
62 if ((err = mp_copy(srckey->dp.prime, key->dp.prime )) != CRYPT_OK) { goto error; }
63 if ((err = mp_copy(srckey->dp.order, key->dp.order )) != CRYPT_OK) { goto error; }
64 if ((err = mp_copy(srckey->dp.A, key->dp.A )) != CRYPT_OK) { goto error; }
65 if ((err = mp_copy(srckey->dp.B, key->dp.B )) != CRYPT_OK) { goto error; }
66 if ((err = ltc_ecc_copy_point(&srckey->dp.base, &key->dp.base)) != CRYPT_OK) { goto error; }
67 /* cofactor & size */
68 key->dp.cofactor = srckey->dp.cofactor;
69 key->dp.size = srckey->dp.size;
70 /* OID */
71 if (srckey->dp.oidlen > 0) {
72 key->dp.oidlen = srckey->dp.oidlen;
73 for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = srckey->dp.oid[i];
74 }
75 else {
76 _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_curves */
77 }
78 /* success */
79 return CRYPT_OK;
80
81 error:
82 ecc_free(key);
83 return err;
84 }
85
ecc_set_curve_from_mpis(void * a,void * b,void * prime,void * order,void * gx,void * gy,unsigned long cofactor,ecc_key * key)86 int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key)
87 {
88 int err;
89
90 LTC_ARGCHK(key != NULL);
91 LTC_ARGCHK(a != NULL);
92 LTC_ARGCHK(b != NULL);
93 LTC_ARGCHK(prime != NULL);
94 LTC_ARGCHK(order != NULL);
95 LTC_ARGCHK(gx != NULL);
96 LTC_ARGCHK(gy != NULL);
97
98 if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B,
99 &key->dp.base.x, &key->dp.base.y, &key->dp.base.z,
100 &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k,
101 NULL)) != CRYPT_OK) {
102 return err;
103 }
104
105 /* A, B, order, prime, Gx, Gy */
106 if ((err = mp_copy(prime, key->dp.prime )) != CRYPT_OK) { goto error; }
107 if ((err = mp_copy(order, key->dp.order )) != CRYPT_OK) { goto error; }
108 if ((err = mp_copy(a, key->dp.A )) != CRYPT_OK) { goto error; }
109 if ((err = mp_copy(b, key->dp.B )) != CRYPT_OK) { goto error; }
110 if ((err = mp_copy(gx, key->dp.base.x)) != CRYPT_OK) { goto error; }
111 if ((err = mp_copy(gy, key->dp.base.y)) != CRYPT_OK) { goto error; }
112 if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; }
113 /* cofactor & size */
114 key->dp.cofactor = cofactor;
115 key->dp.size = mp_unsigned_bin_size(prime);
116 /* try to find OID in ltc_ecc_curves */
117 _ecc_oid_lookup(key);
118 /* success */
119 return CRYPT_OK;
120
121 error:
122 ecc_free(key);
123 return err;
124 }
125
126 #endif
127
128 /* ref: $Format:%D$ */
129 /* git commit: $Format:%H$ */
130 /* commit time: $Format:%ai$ */
131