1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 
6 #ifdef LTC_MDSA
7 
8 /**
9   Import DSA's p, q & g from raw numbers
10   @param p       DSA's p  in binary representation
11   @param plen    The length of p
12   @param q       DSA's q  in binary representation
13   @param qlen    The length of q
14   @param g       DSA's g  in binary representation
15   @param glen    The length of g
16   @param key     [out] the destination for the imported key
17   @return CRYPT_OK if successful.
18 */
dsa_set_pqg(const unsigned char * p,unsigned long plen,const unsigned char * q,unsigned long qlen,const unsigned char * g,unsigned long glen,dsa_key * key)19 int dsa_set_pqg(const unsigned char *p,  unsigned long plen,
20                 const unsigned char *q,  unsigned long qlen,
21                 const unsigned char *g,  unsigned long glen,
22                 dsa_key *key)
23 {
24    int err, stat;
25 
26    LTC_ARGCHK(p           != NULL);
27    LTC_ARGCHK(q           != NULL);
28    LTC_ARGCHK(g           != NULL);
29    LTC_ARGCHK(key         != NULL);
30    LTC_ARGCHK(ltc_mp.name != NULL);
31 
32    /* init key */
33    err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL);
34    if (err != CRYPT_OK) return err;
35 
36    if ((err = mp_read_unsigned_bin(key->p, (unsigned char *)p , plen)) != CRYPT_OK) { goto LBL_ERR; }
37    if ((err = mp_read_unsigned_bin(key->g, (unsigned char *)g , glen)) != CRYPT_OK) { goto LBL_ERR; }
38    if ((err = mp_read_unsigned_bin(key->q, (unsigned char *)q , qlen)) != CRYPT_OK) { goto LBL_ERR; }
39 
40    key->qord = mp_unsigned_bin_size(key->q);
41 
42    /* do only a quick validation, without primality testing */
43    if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK)                        { goto LBL_ERR; }
44    if (stat == 0) {
45       err = CRYPT_INVALID_PACKET;
46       goto LBL_ERR;
47    }
48 
49    return CRYPT_OK;
50 
51 LBL_ERR:
52    dsa_free(key);
53    return err;
54 }
55 
56 /**
57   Import DSA public or private key-part from raw numbers
58 
59      NB: The p, q & g parts must be set beforehand
60 
61   @param in      The key-part to import, either public or private.
62   @param inlen   The key-part's length
63   @param type    Which type of key (PK_PRIVATE or PK_PUBLIC)
64   @param key     [out] the destination for the imported key
65   @return CRYPT_OK if successful.
66 */
dsa_set_key(const unsigned char * in,unsigned long inlen,int type,dsa_key * key)67 int dsa_set_key(const unsigned char *in, unsigned long inlen, int type, dsa_key *key)
68 {
69    int err, stat = 0;
70 
71    LTC_ARGCHK(key         != NULL);
72    LTC_ARGCHK(key->x      != NULL);
73    LTC_ARGCHK(key->y      != NULL);
74    LTC_ARGCHK(key->p      != NULL);
75    LTC_ARGCHK(key->g      != NULL);
76    LTC_ARGCHK(key->q      != NULL);
77    LTC_ARGCHK(ltc_mp.name != NULL);
78 
79    if (type == PK_PRIVATE) {
80       key->type = PK_PRIVATE;
81       if ((err = mp_read_unsigned_bin(key->x, (unsigned char *)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
82       if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK)               { goto LBL_ERR; }
83    }
84    else {
85       key->type = PK_PUBLIC;
86       if ((err = mp_read_unsigned_bin(key->y, (unsigned char *)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
87    }
88 
89    if ((err = dsa_int_validate_xy(key, &stat)) != CRYPT_OK)                             { goto LBL_ERR; }
90    if (stat == 0) {
91       err = CRYPT_INVALID_PACKET;
92       goto LBL_ERR;
93    }
94 
95    return CRYPT_OK;
96 
97 LBL_ERR:
98    dsa_free(key);
99    return err;
100 }
101 
102 #endif
103