1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 #include "tomcrypt_private.h"
5
6 #ifdef LTC_MDH
7
8 /**
9 Import a DH key from a binary packet
10 @param in The packet to read
11 @param inlen The length of the input packet
12 @param key [out] Where to import the key to
13 @return CRYPT_OK if successful, on error all allocated memory is freed automatically
14 */
dh_import(const unsigned char * in,unsigned long inlen,dh_key * key)15 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
16 {
17 unsigned char flags[1];
18 int err;
19 unsigned long version;
20
21 LTC_ARGCHK(in != NULL);
22 LTC_ARGCHK(key != NULL);
23
24 /* init */
25 if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
26 return err;
27 }
28
29 /* find out what type of key it is */
30 err = der_decode_sequence_multi(in, inlen,
31 LTC_ASN1_SHORT_INTEGER, 1UL, &version,
32 LTC_ASN1_BIT_STRING, 1UL, &flags,
33 LTC_ASN1_EOL, 0UL, NULL);
34 if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
35 goto error;
36 }
37
38 if (version == 0) {
39 if (flags[0] == 1) {
40 key->type = PK_PRIVATE;
41 if ((err = der_decode_sequence_multi(in, inlen,
42 LTC_ASN1_SHORT_INTEGER, 1UL, &version,
43 LTC_ASN1_BIT_STRING, 1UL, flags,
44 LTC_ASN1_INTEGER, 1UL, key->prime,
45 LTC_ASN1_INTEGER, 1UL, key->base,
46 LTC_ASN1_INTEGER, 1UL, key->x,
47 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
48 goto error;
49 }
50 /* compute public key: y = (base ^ x) mod prime */
51 if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) {
52 goto error;
53 }
54 }
55 else if (flags[0] == 0) {
56 key->type = PK_PUBLIC;
57 if ((err = der_decode_sequence_multi(in, inlen,
58 LTC_ASN1_SHORT_INTEGER, 1UL, &version,
59 LTC_ASN1_BIT_STRING, 1UL, flags,
60 LTC_ASN1_INTEGER, 1UL, key->prime,
61 LTC_ASN1_INTEGER, 1UL, key->base,
62 LTC_ASN1_INTEGER, 1UL, key->y,
63 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
64 goto error;
65 }
66 }
67 else {
68 err = CRYPT_INVALID_PACKET;
69 goto error;
70 }
71 }
72 else {
73 err = CRYPT_INVALID_PACKET;
74 goto error;
75 }
76
77 /* check public key */
78 if ((err = dh_check_pubkey(key)) != CRYPT_OK) {
79 goto error;
80 }
81
82 return CRYPT_OK;
83
84 error:
85 dh_free(key);
86 return err;
87 }
88
89 #endif /* LTC_MDH */
90