Mercurial > dropbear
comparison dss.c @ 695:94aa1203be1e
DSS_PROTOK is not necessary now that private keys are included
in the random generation input
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 23 Feb 2013 17:55:46 +0800 |
parents | a98a2138364a |
children | d6067dd60490 |
comparison
equal
deleted
inserted
replaced
694:c85bb68e1db6 | 695:94aa1203be1e |
---|---|
256 return ret; | 256 return ret; |
257 | 257 |
258 } | 258 } |
259 #endif /* DROPBEAR_SIGNKEY_VERIFY */ | 259 #endif /* DROPBEAR_SIGNKEY_VERIFY */ |
260 | 260 |
261 #ifdef DSS_PROTOK | |
262 /* convert an unsigned mp into an array of bytes, malloced. | |
263 * This array must be freed after use, len contains the length of the array, | |
264 * if len != NULL */ | |
265 static unsigned char* mptobytes(mp_int *mp, int *len) { | |
266 | |
267 unsigned char* ret; | |
268 int size; | |
269 | |
270 size = mp_unsigned_bin_size(mp); | |
271 ret = m_malloc(size); | |
272 if (mp_to_unsigned_bin(mp, ret) != MP_OKAY) { | |
273 dropbear_exit("Mem alloc error"); | |
274 } | |
275 if (len != NULL) { | |
276 *len = size; | |
277 } | |
278 return ret; | |
279 } | |
280 #endif | |
281 | |
282 /* Sign the data presented with key, writing the signature contents | 261 /* Sign the data presented with key, writing the signature contents |
283 * to the buffer | 262 * to the buffer */ |
284 * | 263 * |
285 * When DSS_PROTOK is #defined: | |
286 * The alternate k generation method is based on the method used in PuTTY. | |
287 * In particular to avoid being vulnerable to attacks using flaws in random | |
288 * generation of k, we use the following: | |
289 * | |
290 * proto_k = SHA512 ( SHA512(x) || SHA160(message) ) | |
291 * k = proto_k mod q | |
292 * | |
293 * Now we aren't relying on the random number generation to protect the private | |
294 * key x, which is a long term secret */ | |
295 void buf_put_dss_sign(buffer* buf, dropbear_dss_key *key, const unsigned char* data, | 264 void buf_put_dss_sign(buffer* buf, dropbear_dss_key *key, const unsigned char* data, |
296 unsigned int len) { | 265 unsigned int len) { |
297 | 266 |
298 unsigned char msghash[SHA1_HASH_SIZE]; | 267 unsigned char msghash[SHA1_HASH_SIZE]; |
299 unsigned int writelen; | 268 unsigned int writelen; |
300 unsigned int i; | 269 unsigned int i; |
301 #ifdef DSS_PROTOK | |
302 unsigned char privkeyhash[SHA512_HASH_SIZE]; | |
303 unsigned char *privkeytmp; | |
304 unsigned char proto_k[SHA512_HASH_SIZE]; | |
305 DEF_MP_INT(dss_protok); | |
306 #endif | |
307 DEF_MP_INT(dss_k); | 270 DEF_MP_INT(dss_k); |
308 DEF_MP_INT(dss_m); | 271 DEF_MP_INT(dss_m); |
309 DEF_MP_INT(dss_temp1); | 272 DEF_MP_INT(dss_temp1); |
310 DEF_MP_INT(dss_temp2); | 273 DEF_MP_INT(dss_temp2); |
311 DEF_MP_INT(dss_r); | 274 DEF_MP_INT(dss_r); |
320 sha1_process(&hs, data, len); | 283 sha1_process(&hs, data, len); |
321 sha1_done(&hs, msghash); | 284 sha1_done(&hs, msghash); |
322 | 285 |
323 m_mp_init_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s, | 286 m_mp_init_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s, |
324 &dss_m, NULL); | 287 &dss_m, NULL); |
325 #ifdef DSS_PROTOK | 288 /* the random number generator's input has included the private key which |
326 /* hash the privkey */ | 289 * avoids DSS's problem of private key exposure due to low entropy */ |
327 privkeytmp = mptobytes(key->x, &i); | |
328 sha512_init(&hs); | |
329 sha512_process(&hs, "the quick brown fox jumped over the lazy dog", 44); | |
330 sha512_process(&hs, privkeytmp, i); | |
331 sha512_done(&hs, privkeyhash); | |
332 m_burn(privkeytmp, i); | |
333 m_free(privkeytmp); | |
334 | |
335 /* calculate proto_k */ | |
336 sha512_init(&hs); | |
337 sha512_process(&hs, privkeyhash, SHA512_HASH_SIZE); | |
338 sha512_process(&hs, msghash, SHA1_HASH_SIZE); | |
339 sha512_done(&hs, proto_k); | |
340 | |
341 /* generate k */ | |
342 m_mp_init(&dss_protok); | |
343 bytes_to_mp(&dss_protok, proto_k, SHA512_HASH_SIZE); | |
344 if (mp_mod(&dss_protok, key->q, &dss_k) != MP_OKAY) { | |
345 dropbear_exit("DSS error"); | |
346 } | |
347 mp_clear(&dss_protok); | |
348 m_burn(proto_k, SHA512_HASH_SIZE); | |
349 #else /* DSS_PROTOK not defined*/ | |
350 gen_random_mpint(key->q, &dss_k); | 290 gen_random_mpint(key->q, &dss_k); |
351 #endif | |
352 | 291 |
353 /* now generate the actual signature */ | 292 /* now generate the actual signature */ |
354 bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE); | 293 bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE); |
355 | 294 |
356 /* g^k mod p */ | 295 /* g^k mod p */ |