mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 01:02:24 +00:00
Fix construction of the output bignum in Curve25519 kex.
We were doing an endianness flip on the output elliptic-curve point. Endianness flips of bignums, of course, have to specify how many bytes they're imagining the value to have (that's how you decide whether to convert 0xA1A2 into 0xA2A1 or 0xA2A10000 or 0xA2A1000000000000 etc), and we had chosen our byte count based on the highest set bit in the _output value_ - but in fact we should have chosen it based on the size of the curve's modulus, leading to a failure about 1/256 of the time when the MSB happened to come out zero so the two byte counts differed. (Also added a missing smemclr, while I was there.)
This commit is contained in:
parent
a209b9044e
commit
686ce91905
19
sshecc.c
19
sshecc.c
@ -2690,15 +2690,30 @@ static Bignum ecdh_calculate(const Bignum private,
|
||||
p->x = NULL;
|
||||
|
||||
if (p->curve->type == EC_MONTGOMERY) {
|
||||
/* Do conversion in network byte order */
|
||||
/*
|
||||
* Endianness-swap. The Curve25519 algorithm definition
|
||||
* assumes you were doing your computation in arrays of 32
|
||||
* little-endian bytes, and now specifies that you take your
|
||||
* final one of those and convert it into a bignum in
|
||||
* _network_ byte order, i.e. big-endian.
|
||||
*
|
||||
* In particular, the spec says, you convert the _whole_ 32
|
||||
* bytes into a bignum. That is, on the rare occasions that
|
||||
* p->x has come out with the most significant 8 bits zero, we
|
||||
* have to imagine that being represented by a 32-byte string
|
||||
* with the last byte being zero, so that has to be converted
|
||||
* into an SSH-2 bignum with the _low_ byte zero, i.e. a
|
||||
* multiple of 256.
|
||||
*/
|
||||
int i;
|
||||
int bytes = (bignum_bitcount(ret)+7) / 8;
|
||||
int bytes = (p->curve->fieldBits+7) / 8;
|
||||
unsigned char *byteorder = snewn(bytes, unsigned char);
|
||||
for (i = 0; i < bytes; ++i) {
|
||||
byteorder[i] = bignum_byte(ret, i);
|
||||
}
|
||||
freebn(ret);
|
||||
ret = bignum_from_bytes(byteorder, bytes);
|
||||
smemclr(byteorder, bytes);
|
||||
sfree(byteorder);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user