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    @file dsa_export.c
14    DSA implementation, export key, Tom St Denis
15 */
16 
17 #ifdef LTC_MDSA
18 
19 /**
20   Export a DSA key to a binary packet
21   @param out    [out] Where to store the packet
22   @param outlen [in/out] The max size and resulting size of the packet
23   @param type   The type of key to export (PK_PRIVATE or PK_PUBLIC)
24   @param key    The key to export
25   @return CRYPT_OK if successful
26 */
dsa_export(unsigned char * out,unsigned long * outlen,int type,const dsa_key * key)27 int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_key *key)
28 {
29    unsigned long zero=0;
30    unsigned char flags[1];
31    int err, std;
32 
33    LTC_ARGCHK(out    != NULL);
34    LTC_ARGCHK(outlen != NULL);
35    LTC_ARGCHK(key    != NULL);
36 
37    std = type & PK_STD;
38    type &= ~PK_STD;
39 
40    if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
41       return CRYPT_PK_TYPE_MISMATCH;
42    }
43 
44    if (type == PK_PRIVATE) {
45       if (std) {
46           return der_encode_sequence_multi(out, outlen,
47                                          LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
48                                          LTC_ASN1_INTEGER,      1UL, key->p,
49                                          LTC_ASN1_INTEGER,      1UL, key->q,
50                                          LTC_ASN1_INTEGER,      1UL, key->g,
51                                          LTC_ASN1_INTEGER,      1UL, key->y,
52                                          LTC_ASN1_INTEGER,      1UL, key->x,
53                                          LTC_ASN1_EOL,          0UL, NULL);
54       }
55       flags[0] = 1;
56       return der_encode_sequence_multi(out, outlen,
57                                          LTC_ASN1_BIT_STRING,   1UL, flags,
58                                          LTC_ASN1_INTEGER,      1UL, key->g,
59                                          LTC_ASN1_INTEGER,      1UL, key->p,
60                                          LTC_ASN1_INTEGER,      1UL, key->q,
61                                          LTC_ASN1_INTEGER,      1UL, key->y,
62                                          LTC_ASN1_INTEGER,      1UL, key->x,
63                                          LTC_ASN1_EOL,          0UL, NULL);
64    }
65 
66    if (type == PK_PUBLIC) {
67       if (std) {
68           unsigned long tmplen = (unsigned long)(mp_count_bits(key->y) / 8) + 8;
69           unsigned char* tmp = XMALLOC(tmplen);
70           ltc_asn1_list int_list[3];
71 
72           if (tmp == NULL) {
73               return CRYPT_MEM;
74           }
75 
76           err = der_encode_integer(key->y, tmp, &tmplen);
77           if (err != CRYPT_OK) {
78               goto error;
79           }
80 
81           LTC_SET_ASN1(int_list, 0, LTC_ASN1_INTEGER, key->p, 1UL);
82           LTC_SET_ASN1(int_list, 1, LTC_ASN1_INTEGER, key->q, 1UL);
83           LTC_SET_ASN1(int_list, 2, LTC_ASN1_INTEGER, key->g, 1UL);
84 
85           err = x509_encode_subject_public_key_info(out, outlen, PKA_DSA, tmp,
86               tmplen, LTC_ASN1_SEQUENCE, int_list,
87               sizeof(int_list) / sizeof(int_list[0]));
88 
89 error:
90           XFREE(tmp);
91           return err;
92       }
93       flags[0] = 0;
94       return der_encode_sequence_multi(out, outlen,
95                                      LTC_ASN1_BIT_STRING,   1UL, flags,
96                                      LTC_ASN1_INTEGER,      1UL, key->g,
97                                      LTC_ASN1_INTEGER,      1UL, key->p,
98                                      LTC_ASN1_INTEGER,      1UL, key->q,
99                                      LTC_ASN1_INTEGER,      1UL, key->y,
100                                      LTC_ASN1_EOL,          0UL, NULL);
101    }
102 
103    return CRYPT_INVALID_ARG;
104 }
105 
106 #endif
107 
108 
109 /* ref:         $Format:%D$ */
110 /* git commit:  $Format:%H$ */
111 /* commit time: $Format:%ai$ */
112