380
|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis |
|
2 * |
|
3 * LibTomCrypt is a library that provides various cryptographic |
|
4 * algorithms in a highly modular and flexible manner. |
|
5 * |
|
6 * The library is free for all purposes without any express |
|
7 * guarantee it works. |
|
8 * |
|
9 * Tom St Denis, [email protected], http://libtomcrypt.com |
|
10 */ |
|
11 #include "tomcrypt.h" |
|
12 |
|
13 /** |
|
14 @file dsa_encrypt_key.c |
|
15 DSA Crypto, Tom St Denis |
|
16 */ |
|
17 |
|
18 #ifdef MDSA |
|
19 |
|
20 /** |
|
21 Encrypt a symmetric key with DSA |
|
22 @param in The symmetric key you want to encrypt |
|
23 @param inlen The length of the key to encrypt (octets) |
|
24 @param out [out] The destination for the ciphertext |
|
25 @param outlen [in/out] The max size and resulting size of the ciphertext |
|
26 @param prng An active PRNG state |
|
27 @param wprng The index of the PRNG you wish to use |
|
28 @param hash The index of the hash you want to use |
|
29 @param key The DSA key you want to encrypt to |
|
30 @return CRYPT_OK if successful |
|
31 */ |
|
32 int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, |
|
33 unsigned char *out, unsigned long *outlen, |
|
34 prng_state *prng, int wprng, int hash, |
|
35 dsa_key *key) |
|
36 { |
|
37 unsigned char *expt, *skey; |
|
38 void *g_pub, *g_priv; |
|
39 unsigned long x, y; |
|
40 int err; |
|
41 |
|
42 LTC_ARGCHK(in != NULL); |
|
43 LTC_ARGCHK(out != NULL); |
|
44 LTC_ARGCHK(outlen != NULL); |
|
45 LTC_ARGCHK(key != NULL); |
|
46 |
|
47 /* check that wprng/cipher/hash are not invalid */ |
|
48 if ((err = prng_is_valid(wprng)) != CRYPT_OK) { |
|
49 return err; |
|
50 } |
|
51 |
|
52 if ((err = hash_is_valid(hash)) != CRYPT_OK) { |
|
53 return err; |
|
54 } |
|
55 |
|
56 if (inlen > hash_descriptor[hash].hashsize) { |
|
57 return CRYPT_INVALID_HASH; |
|
58 } |
|
59 |
|
60 /* make a random key and export the public copy */ |
|
61 if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) { |
|
62 return err; |
|
63 } |
|
64 |
|
65 expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); |
|
66 skey = XMALLOC(MAXBLOCKSIZE); |
|
67 if (expt == NULL || skey == NULL) { |
|
68 if (expt != NULL) { |
|
69 XFREE(expt); |
|
70 } |
|
71 if (skey != NULL) { |
|
72 XFREE(skey); |
|
73 } |
|
74 mp_clear_multi(g_pub, g_priv, NULL); |
|
75 return CRYPT_MEM; |
|
76 } |
|
77 |
|
78 /* make a random x, g^x pair */ |
|
79 x = mp_unsigned_bin_size(key->q); |
|
80 if (prng_descriptor[wprng].read(expt, x, prng) != x) { |
|
81 err = CRYPT_ERROR_READPRNG; |
|
82 goto LBL_ERR; |
|
83 } |
|
84 |
|
85 /* load x */ |
|
86 if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) { |
|
87 goto LBL_ERR; |
|
88 } |
|
89 |
|
90 /* compute y */ |
|
91 if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) { |
|
92 goto LBL_ERR; |
|
93 } |
|
94 |
|
95 /* make random key */ |
|
96 x = mp_unsigned_bin_size(key->p) + 1; |
|
97 if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) { |
|
98 goto LBL_ERR; |
|
99 } |
|
100 |
|
101 y = MAXBLOCKSIZE; |
|
102 if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) { |
|
103 goto LBL_ERR; |
|
104 } |
|
105 |
|
106 /* Encrypt key */ |
|
107 for (x = 0; x < inlen; x++) { |
|
108 skey[x] ^= in[x]; |
|
109 } |
|
110 |
|
111 err = der_encode_sequence_multi(out, outlen, |
|
112 LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, |
|
113 LTC_ASN1_INTEGER, 1UL, g_pub, |
|
114 LTC_ASN1_OCTET_STRING, inlen, skey, |
|
115 LTC_ASN1_EOL, 0UL, NULL); |
|
116 |
|
117 LBL_ERR: |
|
118 #ifdef LTC_CLEAN_STACK |
|
119 /* clean up */ |
|
120 zeromem(expt, mp_unsigned_bin_size(key->p) + 1); |
|
121 zeromem(skey, MAXBLOCKSIZE); |
|
122 #endif |
|
123 |
|
124 XFREE(skey); |
|
125 XFREE(expt); |
|
126 |
|
127 mp_clear_multi(g_pub, g_priv, NULL); |
|
128 return err; |
|
129 } |
|
130 |
|
131 #endif |
|
132 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_encrypt_key.c,v $ */ |
|
133 /* $Revision: 1.7 $ */ |
|
134 /* $Date: 2006/12/04 03:18:43 $ */ |
|
135 |