annotate dh_sys.c @ 143:5d99163f7e32 libtomcrypt-orig

import of libtomcrypt 0.99
author Matt Johnston <matt@ucc.asn.au>
date Sun, 19 Dec 2004 11:34:45 +0000
parents 7faae8f46238
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 * LibTomCrypt is a library that provides various cryptographic
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 * algorithms in a highly modular and flexible manner.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 * The library is free for all purposes without any express
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 * guarantee it works.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 * Tom St Denis, [email protected], http://libtomcrypt.org
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11 int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 unsigned char *out, unsigned long *len,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 prng_state *prng, int wprng, int hash,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 dh_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
16 unsigned char *pub_expt, *dh_shared, *skey;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 dh_key pubkey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 unsigned long x, y, z, hashsize, pubkeysize;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 _ARGCHK(inkey != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 _ARGCHK(out != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 _ARGCHK(len != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 /* check that wprng/hash are not invalid */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 if ((err = hash_is_valid(hash)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 if (keylen > hash_descriptor[hash].hashsize) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 return CRYPT_INVALID_HASH;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
39 /* allocate memory */
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
40 pub_expt = XMALLOC(DH_BUF_SIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
41 dh_shared = XMALLOC(DH_BUF_SIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
42 skey = XMALLOC(MAXBLOCKSIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
43 if (pub_expt == NULL || dh_shared == NULL || skey == NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
44 if (pub_expt != NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
45 XFREE(pub_expt);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
46 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
47 if (dh_shared != NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
48 XFREE(dh_shared);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
49 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
50 if (skey != NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
51 XFREE(skey);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
52 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
53 return CRYPT_MEM;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
55
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
56 /* make a random key and export the public copy */
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
57 if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
58 goto __ERR;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
59 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
60
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
61 pubkeysize = DH_BUF_SIZE;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
62 if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
63 dh_free(&pubkey);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
64 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
65 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
67 /* now check if the out buffer is big enough */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
68 if (*len < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + keylen)) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
69 dh_free(&pubkey);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
70 err = CRYPT_BUFFER_OVERFLOW;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
71 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
73
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
74 /* make random key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
75 hashsize = hash_descriptor[hash].hashsize;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
76
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
77 x = DH_BUF_SIZE;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
78 if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
79 dh_free(&pubkey);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
80 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
81 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
82 dh_free(&pubkey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
83
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
84 z = MAXBLOCKSIZE;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
85 if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
86 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
87 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
88
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
89 /* store header */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92 /* output header */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93 y = PACKET_SIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
94
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
95 /* size of hash name and the name itself */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
96 out[y++] = hash_descriptor[hash].ID;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
97
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
98 /* length of DH pubkey and the key itself */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
99 STORE32L(pubkeysize, out+y);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
100 y += 4;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
101 for (x = 0; x < pubkeysize; x++, y++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
102 out[y] = pub_expt[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
103 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
104
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
105 /* Store the encrypted key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
106 STORE32L(keylen, out+y);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
107 y += 4;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
109 for (x = 0; x < keylen; x++, y++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
110 out[y] = skey[x] ^ inkey[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
111 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
112 *len = y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
113
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
114 err = CRYPT_OK;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
115 __ERR:
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
116 #ifdef CLEAN_STACK
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117 /* clean up */
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
118 zeromem(pub_expt, DH_BUF_SIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
119 zeromem(dh_shared, DH_BUF_SIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
120 zeromem(skey, MAXBLOCKSIZE);
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121 #endif
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
122 XFREE(skey);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
123 XFREE(dh_shared);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
124 XFREE(pub_expt);
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
125
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
126 return err;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
127 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
128
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
129 int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
130 unsigned char *outkey, unsigned long *keylen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
131 dh_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
132 {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
133 unsigned char *shared_secret, *skey;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
134 unsigned long x, y, z,hashsize, keysize;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
135 int hash, err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
136 dh_key pubkey;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
137
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
138 _ARGCHK(in != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
139 _ARGCHK(outkey != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
140 _ARGCHK(keylen != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
141 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
142
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
143 /* right key type? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
144 if (key->type != PK_PRIVATE) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
145 return CRYPT_PK_NOT_PRIVATE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
146 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
147
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
148 /* allocate ram */
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
149 shared_secret = XMALLOC(DH_BUF_SIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
150 skey = XMALLOC(MAXBLOCKSIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
151 if (shared_secret == NULL || skey == NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
152 if (shared_secret != NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
153 XFREE(shared_secret);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
154 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
155 if (skey != NULL) {
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
156 XFREE(skey);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
157 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
158 return CRYPT_MEM;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
159 }
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
160
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
161 /* check if initial header should fit */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
162 if (inlen < PACKET_SIZE+1+4+4) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
163 err = CRYPT_INVALID_PACKET;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
164 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
165 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
166 inlen -= PACKET_SIZE+1+4+4;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
167 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
168
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
169 /* is header correct? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
170 if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
171 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
172 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
173
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
174 /* now lets get the hash name */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
175 y = PACKET_SIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
176 hash = find_hash_id(in[y++]);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
177 if (hash == -1) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
178 err = CRYPT_INVALID_HASH;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
179 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
180 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
181
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
182 /* common values */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
183 hashsize = hash_descriptor[hash].hashsize;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
184
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
185 /* get public key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
186 LOAD32L(x, in+y);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
187
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
188 /* now check if the imported key will fit */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
189 if (inlen < x) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
190 err = CRYPT_INVALID_PACKET;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
191 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
192 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
193 inlen -= x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
194 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
195
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
196 y += 4;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
197 if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
198 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
199 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
200 y += x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
201
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
202 /* make shared key */
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
203 x = DH_BUF_SIZE;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
204 if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
205 dh_free(&pubkey);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
206 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
207 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
208 dh_free(&pubkey);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
209
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
210 z = MAXBLOCKSIZE;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
211 if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
212 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
213 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
214
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
215 /* load in the encrypted key */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
216 LOAD32L(keysize, in+y);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
217
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
218 /* will the outkey fit as part of the input */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
219 if (inlen < keysize) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
220 err = CRYPT_INVALID_PACKET;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
221 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
222 } else {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
223 inlen -= keysize;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
224 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
225
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
226 if (keysize > *keylen) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
227 err = CRYPT_BUFFER_OVERFLOW;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
228 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
229 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
230 y += 4;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
231
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
232 *keylen = keysize;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
233
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
234 for (x = 0; x < keysize; x++, y++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
235 outkey[x] = skey[x] ^ in[y];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
236 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
237
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
238 err = CRYPT_OK;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
239 __ERR:
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
240 #ifdef CLEAN_STACK
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
241 zeromem(shared_secret, DH_BUF_SIZE);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
242 zeromem(skey, MAXBLOCKSIZE);
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
243 #endif
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
244
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
245 XFREE(skey);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
246 XFREE(shared_secret);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
247
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
248 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
249 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
250
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
251 /* perform an ElGamal Signature of a hash
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
252 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
253 * The math works as follows. x is the private key, M is the message to sign
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
254
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
255 1. pick a random k
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
256 2. compute a = g^k mod p
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
257 3. compute b = (M - xa)/k mod p
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
258 4. Send (a,b)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
259
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
260 Now to verify with y=g^x mod p, a and b
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
261
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
262 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
263 = g^(xa + (M - xa))
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
264 = g^M [all mod p]
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
265
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
266 2. Compare against g^M mod p [based on input hash].
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
267 3. If result of #2 == result of #1 then signature valid
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
268 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
269 int dh_sign_hash(const unsigned char *in, unsigned long inlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
270 unsigned char *out, unsigned long *outlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
271 prng_state *prng, int wprng, dh_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
272 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
273 mp_int a, b, k, m, g, p, p1, tmp;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
274 unsigned char *buf;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
275 unsigned long x, y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
276 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
277
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
278 _ARGCHK(in != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
279 _ARGCHK(out != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
280 _ARGCHK(outlen != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
281 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
282
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
283 /* check parameters */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
284 if (key->type != PK_PRIVATE) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
285 return CRYPT_PK_NOT_PRIVATE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
286 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
287
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
288 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
289 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
290 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
291
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
292 /* is the IDX valid ? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
293 if (is_valid_idx(key->idx) != 1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
294 return CRYPT_PK_INVALID_TYPE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
295 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
296
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
297 /* allocate ram for buf */
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
298 buf = XMALLOC(520);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
299
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
300 /* make up a random value k,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
301 * since the order of the group is prime
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
302 * we need not check if gcd(k, r) is 1
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
303 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
304 if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) !=
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
305 (unsigned long)(sets[key->idx].size)) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
306 err = CRYPT_ERROR_READPRNG;
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
307 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
308 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
309
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
310 /* init bignums */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
311 if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != MP_OKAY) {
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
312 err = mpi_to_ltc_error(err);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
313 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
314 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
315
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
316 /* load k and m */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
317 if ((err = mp_read_unsigned_bin(&m, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
318 #ifdef FAST_PK
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
319 if ((err = mp_read_unsigned_bin(&k, buf, MIN(32,sets[key->idx].size))) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
320 #else
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
321 if ((err = mp_read_unsigned_bin(&k, buf, sets[key->idx].size)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
322 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
323
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
324 /* load g, p and p1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
325 if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
326 if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
327 if ((err = mp_sub_d(&p, 1, &p1)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
328 if ((err = mp_div_2(&p1, &p1)) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
329
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
330 /* now get a = g^k mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
331 if ((err = mp_exptmod(&g, &k, &p, &a)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
332
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
333 /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
334 if ((err = mp_invmod(&k, &p1, &k)) != MP_OKAY) { goto error; } /* k = 1/k mod p1 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
335 if ((err = mp_mulmod(&a, &key->x, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = xa */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
336 if ((err = mp_submod(&m, &tmp, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = M - xa */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
337 if ((err = mp_mulmod(&k, &tmp, &p1, &b)) != MP_OKAY) { goto error; } /* b = (M - xa)/k */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
338
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
339 /* check for overflow */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
340 if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(&a) + mp_unsigned_bin_size(&b)) > *outlen) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
341 err = CRYPT_BUFFER_OVERFLOW;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
342 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
343 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
344
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
345 /* store header */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
346 y = PACKET_SIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
347
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
348 /* now store them both (a,b) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
349 x = (unsigned long)mp_unsigned_bin_size(&a);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
350 STORE32L(x, out+y); y += 4;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
351 if ((err = mp_to_unsigned_bin(&a, out+y)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
352 y += x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
353
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
354 x = (unsigned long)mp_unsigned_bin_size(&b);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
355 STORE32L(x, out+y); y += 4;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
356 if ((err = mp_to_unsigned_bin(&b, out+y)) != MP_OKAY) { goto error; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
357 y += x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
358
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
359 /* check if size too big */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
360 if (*outlen < y) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
361 err = CRYPT_BUFFER_OVERFLOW;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
362 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
363 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
364
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
365 /* store header */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
366 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
367 *outlen = y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
368
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
369 err = CRYPT_OK;
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
370 goto __ERR;
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
371 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
372 err = mpi_to_ltc_error(err);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
373 __ERR:
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
374 mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);
143
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
375
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
376 XFREE(buf);
5d99163f7e32 import of libtomcrypt 0.99
Matt Johnston <matt@ucc.asn.au>
parents: 3
diff changeset
377
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
378 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
379 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
380
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
381
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
382 /* verify the signature in sig of the given hash */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
383 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
384 const unsigned char *hash, unsigned long hashlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
385 int *stat, dh_key *key)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
386 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
387 mp_int a, b, p, g, m, tmp;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
388 unsigned long x, y;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
389 int err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
390
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
391 _ARGCHK(sig != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
392 _ARGCHK(hash != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
393 _ARGCHK(stat != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
394 _ARGCHK(key != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
395
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
396 /* default to invalid */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
397 *stat = 0;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
398
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
399 /* check initial input length */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
400 if (siglen < PACKET_SIZE+4+4) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
401 return CRYPT_INVALID_PACKET;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
402 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
403
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
404 /* header ok? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
405 if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
406 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
407 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
408
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
409 /* get hash out of packet */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
410 y = PACKET_SIZE;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
411
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
412 /* init all bignums */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
413 if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != MP_OKAY) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
414 return mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
415 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
416
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
417 /* load a and b */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
418 INPUT_BIGNUM(&a, sig, x, y, siglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
419 INPUT_BIGNUM(&b, sig, x, y, siglen);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
420
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
421 /* load p and g */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
422 if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error1; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
423 if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error1; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
424
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
425 /* load m */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
426 if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error1; }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
427
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
428 /* find g^m mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
429 if ((err = mp_exptmod(&g, &m, &p, &m)) != MP_OKAY) { goto error1; } /* m = g^m mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
430
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
431 /* find y^a * a^b */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
432 if ((err = mp_exptmod(&key->y, &a, &p, &tmp)) != MP_OKAY) { goto error1; } /* tmp = y^a mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
433 if ((err = mp_exptmod(&a, &b, &p, &a)) != MP_OKAY) { goto error1; } /* a = a^b mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
434 if ((err = mp_mulmod(&a, &tmp, &p, &a)) != MP_OKAY) { goto error1; } /* a = y^a * a^b mod p */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
435
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
436 /* y^a * a^b == g^m ??? */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
437 if (mp_cmp(&a, &m) == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
438 *stat = 1;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
439 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
440
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
441 /* clean up */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
442 err = CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
443 goto done;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
444 error1:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
445 err = mpi_to_ltc_error(err);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
446 error:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
447 done:
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
448 mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
449 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
450 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
451