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