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