dss_sign(): fix a theoretically possible overflow.

I computed hash + x*r by first computing x*r, and then using
mp_add_into to add the hash to it in the same bignum. But if the
result of x*r had been allocated an mp_int only just large enough to
contain it, then the addition of the hash might have made it overflow
and generated a bogus signature.

I've never seen that happen, and for all I know word sizes may make it
completely impossible. But it's a theoretical possibility, and easy to
fix now that I've happened to spot it in passing.
This commit is contained in:
Simon Tatham 2019-02-10 08:08:50 +00:00
Родитель f659614272
Коммит 40843b432a
1 изменённых файлов: 3 добавлений и 2 удалений

Просмотреть файл

@ -434,10 +434,11 @@ static void dss_sign(ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs)
mp_free(gkp);
mp_int *hash = mp_from_bytes_be(make_ptrlen(digest, 20));
mp_int *hxr = mp_mul(dss->x, r);
mp_add_into(hxr, hxr, hash); /* hash + x*r */
mp_int *xr = mp_mul(dss->x, r);
mp_int *hxr = mp_add(xr, hash); /* hash + x*r */
mp_int *s = mp_modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash+x*r) mod q */
mp_free(hxr);
mp_free(xr);
mp_free(kinv);
mp_free(k);
mp_free(hash);