comparison common-kex.c @ 762:a78a38e402d1 ecc

- Fix various hardcoded uses of SHA1 - rename curves to nistp256 etc - fix svr-auth.c TRACE problem
author Matt Johnston <matt@ucc.asn.au>
date Mon, 08 Apr 2013 00:10:57 +0800
parents ac2158e3e403
children f744321ac048
comparison
equal deleted inserted replaced
761:ac2158e3e403 762:a78a38e402d1
83 #ifndef DISABLE_ZLIB 83 #ifndef DISABLE_ZLIB
84 static void gen_new_zstreams(); 84 static void gen_new_zstreams();
85 #endif 85 #endif
86 static void read_kex_algos(); 86 static void read_kex_algos();
87 /* helper function for gen_new_keys */ 87 /* helper function for gen_new_keys */
88 static void hashkeys(unsigned char *out, int outlen, 88 static void hashkeys(unsigned char *out, unsigned int outlen,
89 const hash_state * hs, unsigned const char X); 89 const hash_state * hs, const unsigned char X);
90 static void finish_kexhashbuf(void); 90 static void finish_kexhashbuf(void);
91 91
92 92
93 /* Send our list of algorithms we can use */ 93 /* Send our list of algorithms we can use */
94 void send_msg_kexinit() { 94 void send_msg_kexinit() {
249 * already initialised hash_state hs, which should already have processed 249 * already initialised hash_state hs, which should already have processed
250 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. 250 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
251 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. 251 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
252 * 252 *
253 * See Section 7.2 of rfc4253 (ssh transport) for details */ 253 * See Section 7.2 of rfc4253 (ssh transport) for details */
254 static void hashkeys(unsigned char *out, int outlen, 254 static void hashkeys(unsigned char *out, unsigned int outlen,
255 const hash_state * hs, const unsigned char X) { 255 const hash_state * hs, const unsigned char X) {
256 256
257 const struct ltc_hash_descriptor *hashdesc = ses.newkeys->algo_kex->hashdesc;
257 hash_state hs2; 258 hash_state hs2;
258 int offset; 259 unsigned int offset;
260 unsigned char tmpout[hashdesc->hashsize];
259 261
260 memcpy(&hs2, hs, sizeof(hash_state)); 262 memcpy(&hs2, hs, sizeof(hash_state));
261 sha1_process(&hs2, &X, 1); 263 hashdesc->process(&hs2, &X, 1);
262 sha1_process(&hs2, ses.session_id->data, ses.session_id->len); 264 hashdesc->process(&hs2, ses.session_id->data, ses.session_id->len);
263 sha1_done(&hs2, out); 265 hashdesc->done(&hs2, tmpout);
264 for (offset = SHA1_HASH_SIZE; 266 memcpy(out, tmpout, MIN(hashdesc->hashsize, outlen));
267 for (offset = hashdesc->hashsize;
265 offset < outlen; 268 offset < outlen;
266 offset += SHA1_HASH_SIZE) 269 offset += hashdesc->hashsize)
267 { 270 {
268 /* need to extend */ 271 /* need to extend */
269 unsigned char k2[SHA1_HASH_SIZE];
270 memcpy(&hs2, hs, sizeof(hash_state)); 272 memcpy(&hs2, hs, sizeof(hash_state));
271 sha1_process(&hs2, out, offset); 273 hashdesc->process(&hs2, out, offset);
272 sha1_done(&hs2, k2); 274 hashdesc->done(&hs2, tmpout);
273 memcpy(&out[offset], k2, MIN(outlen - offset, SHA1_HASH_SIZE)); 275 memcpy(&out[offset], tmpout, MIN(outlen - offset, hashdesc->hashsize));
274 } 276 }
275 } 277 }
276 278
277 /* Generate the actual encryption/integrity keys, using the results of the 279 /* Generate the actual encryption/integrity keys, using the results of the
278 * key exchange, as specified in section 7.2 of the transport rfc 4253. 280 * key exchange, as specified in section 7.2 of the transport rfc 4253.
290 unsigned char S2C_key[MAX_KEY_LEN]; 292 unsigned char S2C_key[MAX_KEY_LEN];
291 /* unsigned char key[MAX_KEY_LEN]; */ 293 /* unsigned char key[MAX_KEY_LEN]; */
292 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key; 294 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
293 295
294 hash_state hs; 296 hash_state hs;
295 unsigned int C2S_keysize, S2C_keysize; 297 const struct ltc_hash_descriptor *hashdesc = ses.newkeys->algo_kex->hashdesc;
296 char mactransletter, macrecvletter; /* Client or server specific */ 298 char mactransletter, macrecvletter; /* Client or server specific */
297 299
298 TRACE(("enter gen_new_keys")) 300 TRACE(("enter gen_new_keys"))
299 /* the dh_K and hash are the start of all hashes, we make use of that */ 301 /* the dh_K and hash are the start of all hashes, we make use of that */
300 302
301 sha1_init(&hs); 303 hashdesc->init(&hs);
302 sha1_process_mp(&hs, ses.dh_K); 304 hash_process_mp(hashdesc, &hs, ses.dh_K);
303 mp_clear(ses.dh_K); 305 mp_clear(ses.dh_K);
304 m_free(ses.dh_K); 306 m_free(ses.dh_K);
305 sha1_process(&hs, ses.hash->data, ses.hash->len); 307 sha1_process(&hs, ses.hash->data, ses.hash->len);
306 buf_burn(ses.hash); 308 buf_burn(ses.hash);
307 buf_free(ses.hash); 309 buf_free(ses.hash);
310 if (IS_DROPBEAR_CLIENT) { 312 if (IS_DROPBEAR_CLIENT) {
311 trans_IV = C2S_IV; 313 trans_IV = C2S_IV;
312 recv_IV = S2C_IV; 314 recv_IV = S2C_IV;
313 trans_key = C2S_key; 315 trans_key = C2S_key;
314 recv_key = S2C_key; 316 recv_key = S2C_key;
315 C2S_keysize = ses.newkeys->trans.algo_crypt->keysize;
316 S2C_keysize = ses.newkeys->recv.algo_crypt->keysize;
317 mactransletter = 'E'; 317 mactransletter = 'E';
318 macrecvletter = 'F'; 318 macrecvletter = 'F';
319 } else { 319 } else {
320 trans_IV = S2C_IV; 320 trans_IV = S2C_IV;
321 recv_IV = C2S_IV; 321 recv_IV = C2S_IV;
322 trans_key = S2C_key; 322 trans_key = S2C_key;
323 recv_key = C2S_key; 323 recv_key = C2S_key;
324 C2S_keysize = ses.newkeys->recv.algo_crypt->keysize;
325 S2C_keysize = ses.newkeys->trans.algo_crypt->keysize;
326 mactransletter = 'F'; 324 mactransletter = 'F';
327 macrecvletter = 'E'; 325 macrecvletter = 'E';
328 } 326 }
329 327
330 hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); 328 hashkeys(C2S_IV, sizeof(C2S_IV), &hs, 'A');
331 hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); 329 hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B');
332 hashkeys(C2S_key, C2S_keysize, &hs, 'C'); 330 hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C');
333 hashkeys(S2C_key, S2C_keysize, &hs, 'D'); 331 hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D');
334 332
335 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { 333 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
336 int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); 334 int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
337 if (recv_cipher < 0) 335 if (recv_cipher < 0)
338 dropbear_exit("Crypto error"); 336 dropbear_exit("Crypto error");