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