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 DH key parts p and g from raw numbers
10
11 @param p DH's p (prime)
12 @param plen DH's p's length
13 @param g DH's g (group)
14 @param glen DH's g's length
15 @param key [out] the destination for the imported key
16 @return CRYPT_OK if successful
17 */
dh_set_pg(const unsigned char * p,unsigned long plen,const unsigned char * g,unsigned long glen,dh_key * key)18 int dh_set_pg(const unsigned char *p, unsigned long plen,
19 const unsigned char *g, unsigned long glen,
20 dh_key *key)
21 {
22 int err;
23
24 LTC_ARGCHK(key != NULL);
25 LTC_ARGCHK(p != NULL);
26 LTC_ARGCHK(g != NULL);
27 LTC_ARGCHK(ltc_mp.name != NULL);
28
29 if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
30 return err;
31 }
32
33 if ((err = mp_read_unsigned_bin(key->base, (unsigned char*)g, glen)) != CRYPT_OK) { goto LBL_ERR; }
34 if ((err = mp_read_unsigned_bin(key->prime, (unsigned char*)p, plen)) != CRYPT_OK) { goto LBL_ERR; }
35
36 return CRYPT_OK;
37
38 LBL_ERR:
39 dh_free(key);
40 return err;
41 }
42
43 /**
44 Import DH key parts p and g from built-in DH groups
45
46 @param groupsize The size of the DH group to use
47 @param key [out] Where the newly created DH key will be stored
48 @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically.
49 */
dh_set_pg_groupsize(int groupsize,dh_key * key)50 int dh_set_pg_groupsize(int groupsize, dh_key *key)
51 {
52 int err, i;
53
54 LTC_ARGCHK(key != NULL);
55 LTC_ARGCHK(ltc_mp.name != NULL);
56 LTC_ARGCHK(groupsize > 0);
57
58 for (i = 0; (groupsize > ltc_dh_sets[i].size) && (ltc_dh_sets[i].size != 0); i++);
59 if (ltc_dh_sets[i].size == 0) return CRYPT_INVALID_KEYSIZE;
60
61 if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
62 return err;
63 }
64 if ((err = mp_read_radix(key->base, ltc_dh_sets[i].base, 16)) != CRYPT_OK) { goto LBL_ERR; }
65 if ((err = mp_read_radix(key->prime, ltc_dh_sets[i].prime, 16)) != CRYPT_OK) { goto LBL_ERR; }
66
67 return CRYPT_OK;
68
69 LBL_ERR:
70 dh_free(key);
71 return err;
72 }
73
74 /**
75 Import DH public or private key part from raw numbers
76
77 NB: The p & g parts must be set beforehand
78
79 @param in The key-part to import, either public or private.
80 @param inlen The key-part's length
81 @param type Which type of key (PK_PRIVATE or PK_PUBLIC)
82 @param key [out] the destination for the imported key
83 @return CRYPT_OK if successful
84 */
dh_set_key(const unsigned char * in,unsigned long inlen,int type,dh_key * key)85 int dh_set_key(const unsigned char *in, unsigned long inlen, int type, dh_key *key)
86 {
87 int err;
88
89 LTC_ARGCHK(key != NULL);
90 LTC_ARGCHK(ltc_mp.name != NULL);
91
92 if (type == PK_PRIVATE) {
93 key->type = PK_PRIVATE;
94 if ((err = mp_read_unsigned_bin(key->x, (unsigned char*)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
95 if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto LBL_ERR; }
96 }
97 else {
98 key->type = PK_PUBLIC;
99 if ((err = mp_read_unsigned_bin(key->y, (unsigned char*)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
100 }
101
102 /* check public key */
103 if ((err = dh_check_pubkey(key)) != CRYPT_OK) {
104 goto LBL_ERR;
105 }
106
107 return CRYPT_OK;
108
109 LBL_ERR:
110 dh_free(key);
111 return err;
112 }
113
114 #endif /* LTC_MDH */
115