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