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 */