101
101
/* Clear and free the memory used by a public or private key */
102
102
void dss_key_free(dropbear_dss_key *key) {
104
TRACE(("enter dsa_key_free"))
104
TRACE2(("enter dsa_key_free"))
105
105
if (key == NULL) {
106
TRACE(("enter dsa_key_free: key == NULL"))
106
TRACE2(("enter dsa_key_free: key == NULL"))
259
259
#endif /* DROPBEAR_SIGNKEY_VERIFY */
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,
265
static unsigned char* mptobytes(mp_int *mp, int *len) {
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");
282
261
/* Sign the data presented with key, writing the signature contents
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:
290
* proto_k = SHA512 ( SHA512(x) || SHA160(message) )
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
263
void buf_put_dss_sign(buffer* buf, dropbear_dss_key *key, const unsigned char* data,
296
264
unsigned int len) {
298
266
unsigned char msghash[SHA1_HASH_SIZE];
299
267
unsigned int writelen;
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);
307
269
DEF_MP_INT(dss_k);
308
270
DEF_MP_INT(dss_m);
309
271
DEF_MP_INT(dss_temp1);
323
285
m_mp_init_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s,
326
/* hash the privkey */
327
privkeytmp = mptobytes(key->x, &i);
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);
335
/* calculate proto_k */
337
sha512_process(&hs, privkeyhash, SHA512_HASH_SIZE);
338
sha512_process(&hs, msghash, SHA1_HASH_SIZE);
339
sha512_done(&hs, proto_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");
347
mp_clear(&dss_protok);
348
m_burn(proto_k, SHA512_HASH_SIZE);
349
#else /* DSS_PROTOK not defined*/
287
/* the random number generator's input has included the private key which
288
* avoids DSS's problem of private key exposure due to low entropy */
350
289
gen_random_mpint(key->q, &dss_k);
353
291
/* now generate the actual signature */
354
292
bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE);