1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 11:32:48 -05:00

Stop using mp_int in sshprng.c.

We keep an internal 128-bit counter that's used as part of the hash
preimages. There's no real need to import all the mp_int machinery in
order to implement that: we can do it by hand using a small fixed-size
array and a trivial use of BignumADC. This is another inter-module
dependency that's easy to remove and useful to spinoff programs.

This changes the hash preimage calculation in the PRNG, because we're
now formatting our 128-bit integer in the fixed-length representation
of 16 little-endian bytes instead of as an SSH-2 mpint. This is
harmless (perhaps even mildly beneficial, due to the length now not
depending on how long the PRNG has been running), but means I have to
update the PRNG tests as well.
This commit is contained in:
Simon Tatham
2020-09-13 08:42:54 +01:00
parent a058054253
commit 7003b43963
2 changed files with 18 additions and 10 deletions

View File

@ -89,6 +89,10 @@ def last(iterable):
pass
return toret
def le_integer(x, nbits):
assert nbits % 8 == 0
return bytes([0xFF & (x >> (8*n)) for n in range(nbits//8)])
@contextlib.contextmanager
def queued_random_data(nbytes, seed):
hashsize = 512 // 8
@ -1627,23 +1631,25 @@ class crypt(MyTestBase):
prng_add_entropy(pr, 0, entropy) # forces a reseed
data3 = prng_read(pr, 128)
le128 = lambda x: le_integer(x, 128)
key1 = hash_str(hashalg, b'R' + seed)
expected_data1 = b''.join(
hash_str(hashalg, key1 + b'G' + ssh2_mpint(counter))
hash_str(hashalg, key1 + b'G' + le128(counter))
for counter in range(4))
# After prng_read finishes, we expect the PRNG to have
# automatically reseeded itself, so that if its internal state
# is revealed then the previous output can't be reconstructed.
key2 = hash_str(hashalg, key1 + b'R')
expected_data2 = b''.join(
hash_str(hashalg, key2 + b'G' + ssh2_mpint(counter))
hash_str(hashalg, key2 + b'G' + le128(counter))
for counter in range(4,8))
# There will have been another reseed after the second
# prng_read, and then another due to the entropy.
key3 = hash_str(hashalg, key2 + b'R')
key4 = hash_str(hashalg, key3 + b'R' + hash_str(hashalg, entropy))
expected_data3 = b''.join(
hash_str(hashalg, key4 + b'G' + ssh2_mpint(counter))
hash_str(hashalg, key4 + b'G' + le128(counter))
for counter in range(8,12))
self.assertEqualBin(data1, expected_data1)