Mercurial > dropbear
comparison ecc_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 |
comparison
equal
deleted
inserted
replaced
15:6362d3854bb4 | 143:5d99163f7e32 |
---|---|
11 int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen, | 11 int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen, |
12 unsigned char *out, unsigned long *len, | 12 unsigned char *out, unsigned long *len, |
13 prng_state *prng, int wprng, int hash, | 13 prng_state *prng, int wprng, int hash, |
14 ecc_key *key) | 14 ecc_key *key) |
15 { | 15 { |
16 unsigned char pub_expt[256], ecc_shared[256], skey[MAXBLOCKSIZE]; | 16 unsigned char *pub_expt, *ecc_shared, *skey; |
17 ecc_key pubkey; | 17 ecc_key pubkey; |
18 unsigned long x, y, z, hashsize, pubkeysize; | 18 unsigned long x, y, z, hashsize, pubkeysize; |
19 int err; | 19 int err; |
20 | 20 |
21 _ARGCHK(inkey != NULL); | 21 _ARGCHK(inkey != NULL); |
22 _ARGCHK(out != NULL); | 22 _ARGCHK(out != NULL); |
23 _ARGCHK(len != NULL); | 23 _ARGCHK(len != NULL); |
24 _ARGCHK(key != NULL); | 24 _ARGCHK(key != NULL); |
39 /* make a random key and export the public copy */ | 39 /* make a random key and export the public copy */ |
40 if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { | 40 if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { |
41 return err; | 41 return err; |
42 } | 42 } |
43 | 43 |
44 pubkeysize = (unsigned long)sizeof(pub_expt); | 44 pub_expt = XMALLOC(ECC_BUF_SIZE); |
45 ecc_shared = XMALLOC(ECC_BUF_SIZE); | |
46 skey = XMALLOC(MAXBLOCKSIZE); | |
47 if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { | |
48 if (pub_expt != NULL) { | |
49 XFREE(pub_expt); | |
50 } | |
51 if (ecc_shared != NULL) { | |
52 XFREE(ecc_shared); | |
53 } | |
54 if (skey != NULL) { | |
55 XFREE(skey); | |
56 } | |
57 ecc_free(&pubkey); | |
58 return CRYPT_MEM; | |
59 } | |
60 | |
61 pubkeysize = ECC_BUF_SIZE; | |
45 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { | 62 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { |
46 ecc_free(&pubkey); | 63 ecc_free(&pubkey); |
47 return err; | 64 goto __ERR; |
48 } | 65 } |
49 | 66 |
50 /* now check if the out buffer is big enough */ | 67 /* now check if the out buffer is big enough */ |
51 if (*len < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) { | 68 if (*len < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) { |
52 ecc_free(&pubkey); | 69 ecc_free(&pubkey); |
53 return CRYPT_BUFFER_OVERFLOW; | 70 err = CRYPT_BUFFER_OVERFLOW; |
71 goto __ERR; | |
54 } | 72 } |
55 | 73 |
56 /* make random key */ | 74 /* make random key */ |
57 hashsize = hash_descriptor[hash].hashsize; | 75 hashsize = hash_descriptor[hash].hashsize; |
58 x = (unsigned long)sizeof(ecc_shared); | 76 x = ECC_BUF_SIZE; |
59 if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { | 77 if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { |
60 ecc_free(&pubkey); | 78 ecc_free(&pubkey); |
61 return err; | 79 goto __ERR; |
62 } | 80 } |
63 ecc_free(&pubkey); | 81 ecc_free(&pubkey); |
64 z = (unsigned long)sizeof(skey); | 82 z = MAXBLOCKSIZE; |
65 if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) { | 83 if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) { |
66 return err; | 84 goto __ERR; |
67 } | 85 } |
68 | 86 |
69 /* store header */ | 87 /* store header */ |
70 packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY); | 88 packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY); |
71 | 89 |
90 for (x = 0; x < keylen; x++, y++) { | 108 for (x = 0; x < keylen; x++, y++) { |
91 out[y] = skey[x] ^ inkey[x]; | 109 out[y] = skey[x] ^ inkey[x]; |
92 } | 110 } |
93 *len = y; | 111 *len = y; |
94 | 112 |
113 err = CRYPT_OK; | |
114 __ERR: | |
95 #ifdef CLEAN_STACK | 115 #ifdef CLEAN_STACK |
96 /* clean up */ | 116 /* clean up */ |
97 zeromem(pub_expt, sizeof(pub_expt)); | 117 zeromem(pub_expt, ECC_BUF_SIZE); |
98 zeromem(ecc_shared, sizeof(ecc_shared)); | 118 zeromem(ecc_shared, ECC_BUF_SIZE); |
99 zeromem(skey, sizeof(skey)); | 119 zeromem(skey, MAXBLOCKSIZE); |
100 #endif | 120 #endif |
101 return CRYPT_OK; | 121 |
122 XFREE(skey); | |
123 XFREE(ecc_shared); | |
124 XFREE(pub_expt); | |
125 | |
126 return err; | |
102 } | 127 } |
103 | 128 |
104 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, | 129 int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, |
105 unsigned char *outkey, unsigned long *keylen, | 130 unsigned char *outkey, unsigned long *keylen, |
106 ecc_key *key) | 131 ecc_key *key) |
107 { | 132 { |
108 unsigned char shared_secret[256], skey[MAXBLOCKSIZE]; | 133 unsigned char *shared_secret, *skey; |
109 unsigned long x, y, z, hashsize, keysize; | 134 unsigned long x, y, z, hashsize, keysize; |
110 int hash, err; | 135 int hash, err; |
111 ecc_key pubkey; | 136 ecc_key pubkey; |
112 | 137 |
113 _ARGCHK(in != NULL); | 138 _ARGCHK(in != NULL); |
114 _ARGCHK(outkey != NULL); | 139 _ARGCHK(outkey != NULL); |
115 _ARGCHK(keylen != NULL); | 140 _ARGCHK(keylen != NULL); |
116 _ARGCHK(key != NULL); | 141 _ARGCHK(key != NULL); |
153 if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) { | 178 if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) { |
154 return err; | 179 return err; |
155 } | 180 } |
156 y += x; | 181 y += x; |
157 | 182 |
183 /* allocate memory */ | |
184 shared_secret = XMALLOC(ECC_BUF_SIZE); | |
185 skey = XMALLOC(MAXBLOCKSIZE); | |
186 if (shared_secret == NULL || skey == NULL) { | |
187 if (shared_secret != NULL) { | |
188 XFREE(shared_secret); | |
189 } | |
190 if (skey != NULL) { | |
191 XFREE(skey); | |
192 } | |
193 ecc_free(&pubkey); | |
194 return CRYPT_MEM; | |
195 } | |
196 | |
158 /* make shared key */ | 197 /* make shared key */ |
159 x = (unsigned long)sizeof(shared_secret); | 198 x = ECC_BUF_SIZE; |
160 if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { | 199 if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { |
161 ecc_free(&pubkey); | 200 ecc_free(&pubkey); |
162 return err; | 201 goto __ERR; |
163 } | 202 } |
164 ecc_free(&pubkey); | 203 ecc_free(&pubkey); |
165 | 204 |
166 z = (unsigned long)sizeof(skey); | 205 z = MAXBLOCKSIZE; |
167 if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { | 206 if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { |
168 return err; | 207 goto __ERR; |
169 } | 208 } |
170 | 209 |
171 LOAD32L(keysize, in+y); | 210 LOAD32L(keysize, in+y); |
172 if (inlen < keysize) { | 211 if (inlen < keysize) { |
173 return CRYPT_INVALID_PACKET; | 212 err = CRYPT_INVALID_PACKET; |
213 goto __ERR; | |
174 } else { | 214 } else { |
175 inlen -= keysize; | 215 inlen -= keysize; |
176 } | 216 } |
177 y += 4; | 217 y += 4; |
178 | 218 |
179 if (*keylen < keysize) { | 219 if (*keylen < keysize) { |
180 err = CRYPT_BUFFER_OVERFLOW; | 220 err = CRYPT_BUFFER_OVERFLOW; |
181 goto done; | 221 goto __ERR; |
182 } | 222 } |
183 | 223 |
184 /* Decrypt the key */ | 224 /* Decrypt the key */ |
185 for (x = 0; x < keysize; x++, y++) { | 225 for (x = 0; x < keysize; x++, y++) { |
186 outkey[x] = skey[x] ^ in[y]; | 226 outkey[x] = skey[x] ^ in[y]; |
187 } | 227 } |
188 | 228 |
189 *keylen = keysize; | 229 *keylen = keysize; |
190 | 230 |
191 err = CRYPT_OK; | 231 err = CRYPT_OK; |
192 done: | 232 __ERR: |
193 #ifdef CLEAN_STACK | 233 #ifdef CLEAN_STACK |
194 zeromem(shared_secret, sizeof(shared_secret)); | 234 zeromem(shared_secret, ECC_BUF_SIZE); |
195 zeromem(skey, sizeof(skey)); | 235 zeromem(skey, MAXBLOCKSIZE); |
196 #endif | 236 #endif |
237 | |
238 XFREE(skey); | |
239 XFREE(shared_secret); | |
240 | |
197 return err; | 241 return err; |
198 } | 242 } |
199 | 243 |
200 int ecc_sign_hash(const unsigned char *in, unsigned long inlen, | 244 int ecc_sign_hash(const unsigned char *in, unsigned long inlen, |
201 unsigned char *out, unsigned long *outlen, | 245 unsigned char *out, unsigned long *outlen, |
202 prng_state *prng, int wprng, ecc_key *key) | 246 prng_state *prng, int wprng, ecc_key *key) |
203 { | 247 { |
204 ecc_key pubkey; | 248 ecc_key pubkey; |
205 mp_int b, p; | 249 mp_int b, p; |
206 unsigned char epubkey[256], er[256]; | 250 unsigned char *epubkey, *er; |
207 unsigned long x, y, pubkeysize, rsize; | 251 unsigned long x, y, pubkeysize, rsize; |
208 int err; | 252 int err; |
209 | 253 |
210 _ARGCHK(in != NULL); | 254 _ARGCHK(in != NULL); |
211 _ARGCHK(out != NULL); | 255 _ARGCHK(out != NULL); |
212 _ARGCHK(outlen != NULL); | 256 _ARGCHK(outlen != NULL); |
213 _ARGCHK(key != NULL); | 257 _ARGCHK(key != NULL); |
229 /* make up a key and export the public copy */ | 273 /* make up a key and export the public copy */ |
230 if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { | 274 if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { |
231 return err; | 275 return err; |
232 } | 276 } |
233 | 277 |
234 pubkeysize = (unsigned long)sizeof(epubkey); | 278 /* allocate ram */ |
279 epubkey = XMALLOC(ECC_BUF_SIZE); | |
280 er = XMALLOC(ECC_BUF_SIZE); | |
281 if (epubkey == NULL || er == NULL) { | |
282 if (epubkey != NULL) { | |
283 XFREE(epubkey); | |
284 } | |
285 if (er != NULL) { | |
286 XFREE(er); | |
287 } | |
288 ecc_free(&pubkey); | |
289 return CRYPT_MEM; | |
290 } | |
291 | |
292 pubkeysize = ECC_BUF_SIZE; | |
235 if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { | 293 if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { |
236 ecc_free(&pubkey); | 294 ecc_free(&pubkey); |
237 return err; | 295 goto __ERR; |
238 } | 296 } |
239 | 297 |
240 /* get the hash and load it as a bignum into 'b' */ | 298 /* get the hash and load it as a bignum into 'b' */ |
241 /* init the bignums */ | 299 /* init the bignums */ |
242 if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) { | 300 if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) { |
243 ecc_free(&pubkey); | 301 ecc_free(&pubkey); |
244 return mpi_to_ltc_error(err); | 302 err = mpi_to_ltc_error(err); |
303 goto __ERR; | |
245 } | 304 } |
246 if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; } | 305 if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; } |
247 if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } | 306 if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } |
248 | 307 |
249 /* find b = (m - x)/k */ | 308 /* find b = (m - x)/k */ |
251 if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY) { goto error; } /* b = m - x */ | 310 if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY) { goto error; } /* b = m - x */ |
252 if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY) { goto error; } /* b = (m - x)/k */ | 311 if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY) { goto error; } /* b = (m - x)/k */ |
253 | 312 |
254 /* export it */ | 313 /* export it */ |
255 rsize = (unsigned long)mp_unsigned_bin_size(&b); | 314 rsize = (unsigned long)mp_unsigned_bin_size(&b); |
256 if (rsize > (unsigned long)sizeof(er)) { | 315 if (rsize > ECC_BUF_SIZE) { |
257 err = CRYPT_BUFFER_OVERFLOW; | 316 err = CRYPT_BUFFER_OVERFLOW; |
258 goto error; | 317 goto error; |
259 } | 318 } |
260 if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY) { goto error; } | 319 if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY) { goto error; } |
261 | 320 |
262 /* now lets check the outlen before we write */ | 321 /* now lets check the outlen before we write */ |
263 if (*outlen < (12 + rsize + pubkeysize)) { | 322 if (*outlen < (12 + rsize + pubkeysize)) { |
264 err = CRYPT_BUFFER_OVERFLOW; | 323 err = CRYPT_BUFFER_OVERFLOW; |
265 goto done; | 324 goto __ERR; |
266 } | 325 } |
267 | 326 |
268 /* lets output */ | 327 /* lets output */ |
269 y = PACKET_SIZE; | 328 y = PACKET_SIZE; |
270 | 329 |
286 out[y] = er[x]; | 345 out[y] = er[x]; |
287 } | 346 } |
288 | 347 |
289 /* store header */ | 348 /* store header */ |
290 packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED); | 349 packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED); |
291 | |
292 /* clear memory */ | |
293 *outlen = y; | 350 *outlen = y; |
351 | |
352 /* all ok */ | |
294 err = CRYPT_OK; | 353 err = CRYPT_OK; |
295 goto done; | 354 goto __ERR; |
296 error: | 355 error: |
297 err = mpi_to_ltc_error(err); | 356 err = mpi_to_ltc_error(err); |
298 done: | 357 __ERR: |
299 mp_clear_multi(&b, &p, NULL); | 358 mp_clear_multi(&b, &p, NULL); |
300 ecc_free(&pubkey); | 359 ecc_free(&pubkey); |
301 #ifdef CLEAN_STACK | 360 #ifdef CLEAN_STACK |
302 zeromem(er, sizeof(er)); | 361 zeromem(er, ECC_BUF_SIZE); |
303 zeromem(epubkey, sizeof(epubkey)); | 362 zeromem(epubkey, ECC_BUF_SIZE); |
304 #endif | 363 #endif |
364 | |
365 XFREE(epubkey); | |
366 XFREE(er); | |
367 | |
305 return err; | 368 return err; |
306 } | 369 } |
307 | 370 |
308 /* verify that mG = (bA + Y) | 371 /* verify that mG = (bA + Y) |
309 * | 372 * |
320 */ | 383 */ |
321 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, | 384 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, |
322 const unsigned char *hash, unsigned long inlen, | 385 const unsigned char *hash, unsigned long inlen, |
323 int *stat, ecc_key *key) | 386 int *stat, ecc_key *key) |
324 { | 387 { |
325 ecc_point *mG; | 388 ecc_point *mG; |
326 ecc_key pubkey; | 389 ecc_key pubkey; |
327 mp_int b, p, m, mu; | 390 mp_int b, p, m, mu; |
328 unsigned long x, y; | 391 unsigned long x, y; |
329 int err; | 392 int err; |
330 | 393 |
331 _ARGCHK(sig != NULL); | 394 _ARGCHK(sig != NULL); |
332 _ARGCHK(hash != NULL); | 395 _ARGCHK(hash != NULL); |
333 _ARGCHK(stat != NULL); | 396 _ARGCHK(stat != NULL); |
334 _ARGCHK(key != NULL); | 397 _ARGCHK(key != NULL); |