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