1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file dsa_shared_secret.c
7 DSA Crypto, Tom St Denis
8 */
9
10 #ifdef LTC_MDSA
11
12 /**
13 Create a DSA shared secret between two keys
14 @param private_key The private DSA key (the exponent)
15 @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt)
16 @param public_key The public key
17 @param out [out] Destination of the shared secret
18 @param outlen [in/out] The max size and resulting size of the shared secret
19 @return CRYPT_OK if successful
20 */
dsa_shared_secret(void * private_key,void * base,const dsa_key * public_key,unsigned char * out,unsigned long * outlen)21 int dsa_shared_secret(void *private_key, void *base,
22 const dsa_key *public_key,
23 unsigned char *out, unsigned long *outlen)
24 {
25 unsigned long x;
26 void *res;
27 int err;
28
29 LTC_ARGCHK(private_key != NULL);
30 LTC_ARGCHK(public_key != NULL);
31 LTC_ARGCHK(out != NULL);
32 LTC_ARGCHK(outlen != NULL);
33
34 /* make new point */
35 if ((err = mp_init(&res)) != CRYPT_OK) {
36 return err;
37 }
38
39 if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) {
40 mp_clear(res);
41 return err;
42 }
43
44 x = (unsigned long)mp_unsigned_bin_size(res);
45 if (*outlen < x) {
46 *outlen = x;
47 err = CRYPT_BUFFER_OVERFLOW;
48 goto done;
49 }
50 zeromem(out, x);
51 if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; }
52
53 err = CRYPT_OK;
54 *outlen = x;
55 done:
56 mp_clear(res);
57 return err;
58 }
59
60 #endif
61