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