1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 #include "tomcrypt_private.h"
5 
6 /**
7   @file ecc_import.c
8   ECC Crypto, Tom St Denis
9 */
10 
11 #ifdef LTC_MECC
12 
13 /**
14   Import an ECC key from a binary packet
15   @param in      The packet to import
16   @param inlen   The length of the packet
17   @param key     [out] The destination of the import
18   @return CRYPT_OK if successful, upon error all allocated memory will be freed
19 */
ecc_import(const unsigned char * in,unsigned long inlen,ecc_key * key)20 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
21 {
22    return ecc_import_ex(in, inlen, key, NULL);
23 }
24 
25 /**
26   Import an ECC key from a binary packet, using user supplied domain params rather than one of the NIST ones
27   @param in      The packet to import
28   @param inlen   The length of the packet
29   @param key     [out] The destination of the import
30   @param cu      pointer to user supplied params; must be the same as the params used when exporting
31   @return CRYPT_OK if successful, upon error all allocated memory will be freed
32 */
ecc_import_ex(const unsigned char * in,unsigned long inlen,ecc_key * key,const ltc_ecc_curve * cu)33 int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu)
34 {
35    unsigned long key_size;
36    unsigned char flags[1];
37    int           err;
38 
39    LTC_ARGCHK(in  != NULL);
40    LTC_ARGCHK(key != NULL);
41    LTC_ARGCHK(ltc_mp.name != NULL);
42 
43    /* find out what type of key it is */
44    err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING,    1UL, flags,
45                                               LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
46                                               LTC_ASN1_EOL,           0UL, NULL);
47    if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
48       return err;
49    }
50 
51    /* allocate & initialize the key */
52    if (cu == NULL) {
53       if ((err = ecc_set_curve_by_size(key_size, key)) != CRYPT_OK) { goto done; }
54    } else {
55       if ((err = ecc_set_curve(cu, key)) != CRYPT_OK)               { goto done; }
56    }
57 
58    if (flags[0] == 1) {
59       /* private key */
60       key->type = PK_PRIVATE;
61       if ((err = der_decode_sequence_multi(in, inlen,
62                                      LTC_ASN1_BIT_STRING,      1UL, flags,
63                                      LTC_ASN1_SHORT_INTEGER,   1UL, &key_size,
64                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.x,
65                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.y,
66                                      LTC_ASN1_INTEGER,         1UL, key->k,
67                                      LTC_ASN1_EOL,             0UL, NULL)) != CRYPT_OK) {
68          goto done;
69       }
70    } else if (flags[0] == 0) {
71       /* public key */
72       key->type = PK_PUBLIC;
73       if ((err = der_decode_sequence_multi(in, inlen,
74                                      LTC_ASN1_BIT_STRING,      1UL, flags,
75                                      LTC_ASN1_SHORT_INTEGER,   1UL, &key_size,
76                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.x,
77                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.y,
78                                      LTC_ASN1_EOL,             0UL, NULL)) != CRYPT_OK) {
79          goto done;
80       }
81    }
82    else {
83       err = CRYPT_INVALID_PACKET;
84       goto done;
85    }
86 
87    /* set z */
88    if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; }
89 
90    /* point on the curve + other checks */
91    if ((err = ltc_ecc_verify_key(key)) != CRYPT_OK)  { goto done; }
92 
93    /* we're good */
94    return CRYPT_OK;
95 
96 done:
97    ecc_free(key);
98    return err;
99 }
100 #endif
101