Граф коммитов

77 Коммитов

Автор SHA1 Сообщение Дата
Tim Kosse 1bfde9dc52 Fix memory leak in bignum_from_decimal
Intermediate result values were not freed.
2017-01-28 14:03:09 +00:00
Simon Tatham daeeca55a4 Promote 'testbn' to a binary built by the makefiles.
This makes it easier to compile in multiple debugging modes, or on
Windows, without having to constantly paste annoying test-compile
commands out of comments in sshbn.c.

The new binary is compiled into the build directory, but not shipped
by 'make install', just like fuzzterm. Unlike fuzzterm, though, testbn
is also compiled on Windows, for which we didn't already have a
mechanism for building unshipped binaries; I've done the very simplest
thing for the moment, of providing a target in Makefile.vc to delete
them.

In order to comply with the PuTTY makefile system's constraint of
never compiling the same object multiple times with different ifdefs,
I've also moved testbn's main() out into its own source file.
2015-12-16 15:26:31 +00:00
Simon Tatham c2ec13c7e9 Relegate BignumDblInt to an implementation detail of sshbn.h.
As I mentioned in the previous commit, I'm going to want PuTTY to be
able to run sensibly when compiled with 64-bit Visual Studio,
including handling bignums in 64-bit chunks for speed. Unfortunately,
64-bit VS does not provide any type we can use as BignumDblInt in that
situation (unlike 64-bit gcc and clang, which give us __uint128_t).
The only facilities it provides are compiler intrinsics to access an
add-with-carry operation and a 64x64->128 multiplication (the latter
delivering its product in two separate 64-bit output chunks).

Hence, here's a substantial rework of the bignum code to make it
implement everything in terms of _those_ primitives, rather than
depending throughout on having BignumDblInt available to use ad-hoc.
BignumDblInt does still exist, for the moment, but now it's an
internal implementation detail of sshbn.h, only declared inside a new
set of macros implementing arithmetic primitives, and not accessible
to any code outside sshbn.h (which confirms that I really did catch
all uses of it and remove them).

The resulting code is surprisingly nice-looking, actually. You'd
expect more hassle and roundabout circumlocutions when you drop down
to using a more basic set of primitive operations, but actually, in
many cases it's turned out shorter to write things in terms of the new
BignumADC and BignumMUL macros - because almost all my uses of
BignumDblInt were implementing those operations anyway, taking several
lines at a time, and now they can do each thing in just one line.

The biggest headache was Poly1305: I wasn't able to find any sensible
way to adapt the existing Python script that generates the various
per-int-size implementations of arithmetic mod 2^130-5, and so I had
to rewrite it from scratch instead, with nothing in common with the
old version beyond a handful of comments. But even that seems to have
worked out nicely: the new version has much more legible descriptions
of the high-level algorithms, by virtue of having a 'Multiprecision'
type which wraps up the division into words, and yet Multiprecision's
range analysis allows it to automatically drop out special cases such
as multiplication by 5 being much easier than multiplication by
another multi-word integer.
2015-12-16 14:13:21 +00:00
Simon Tatham 482b4ab872 Rewrite the core divide function to not use DIVMOD_WORD.
DIVMOD_WORD is a portability hazard, because implementing it requires
either a way to get direct access to the x86 DIV instruction or
equivalent (be it inline assembler or a compiler intrinsic), or else
an integer type we can use as BignumDblInt. But I'm starting to think
about porting to 64-bit Visual Studio with a 64-bit BignumInt, and in
that situation neither of those options will be available.

I could write a piece of _out_-of-line x86-64 assembler in a separate
source file and put a function call in DIVMOD_WORD, but instead I've
decided to solve the problem in a more futureproof way: remove
DIVMOD_WORD totally and write a division function that doesn't need it
at all, solving not only today's porting headache but all future ones
in this area.

The new implementation works by precomputing (a good enough
approximation to) the leading word of the reciprocal of the modulus,
and then getting each word of quotient by multiplying by that
reciprocal, where we previously used DIVMOD_WORD to divide by the
leading word of the actual modulus. The reciprocal itself is computed
outside internal_mod() and passed in as a parameter, allowing me to
save time by only computing it once when I'm about to do a modpow.

To some extent this complicates the implementation: the advantage of
DIVMOD_WORD was that it yielded a full word q of quotient every time
it was used, so the subtraction of q*m from the input could be done in
a nicely word-aligned way. But the reciprocal multiply approach yields
_almost_ a full word of quotient, because you have to make the
reciprocal a bit short to avoid overflow at multiplication time. For a
start, this means we have to do fractionally more iterations of the
main loop; but more painfully, we can no longer depend on the
subtraction of q*m at every step being word-aligned, and instead we
have to be prepared to do it at any bit shift.

But the flip side is that once we've implemented that, the rest of the
algorithm becomes a lot less full of horrible special cases: in
particular, we can now completely throw away the horribleness at all
the call sites where we shift the modulus up by a fractional word to
set its top bit, and then have to do a little dance to get the last
few bits of quotient involving a second call to internal_mod.

So there are points both for and against the new implementation in
simplicity terms; but I think on balance it's more comprehensible than
the old one, and a quick timing test suggests it also ends up a touch
faster overall - the new testbn gets through the output of
testdata/bignum.py in 4.034s where the old one took 4.392s.
2015-12-13 14:48:39 +00:00
Simon Tatham 984792e9f4 Add direct tests of division/modulus to testbn.
I'm about to rewrite the division code, so it'll be useful to have a
way to test it directly, particularly one which exercises difficult
cases such as extreme values of the leading word and remainders just
above and below zero.
2015-12-13 14:46:43 +00:00
Simon Tatham 90c7b1562c Fix copy-and-paste error in testbn main program.
I called a 'pow' test line 'mul' in an error message.
2015-12-13 14:46:42 +00:00
Ben Harris b94a076955 Since we have bn_restore_invariant, we may as well use it more. 2015-10-28 22:08:32 +00:00
Ben Harris 4f34059902 bignum_set_bit: Don't abort if asked to clear an inaccessible bit
All those bits are clear anyway.

Bug found with the help of afl-fuzz.
2015-10-28 22:08:32 +00:00
Simon Tatham e28b35b0a3 Improve integer-type hygiene in bignum code.
In many places I was using an 'unsigned int', or an implicit int by
virtue of writing an undecorated integer literal, where what was
really wanted was a BignumInt. In particular, this substitution breaks
in any situation where BignumInt is _larger_ than unsigned - which it
is shortly about to be.
2015-06-08 19:23:48 +01:00
Simon Tatham 0aa92c8fa2 Provide a stub random_byte() to make 'testbn' compile again.
The function bignum_random_in_range() is new to sshbn.c since I last
tried to run the bignum test code.
2015-06-08 19:22:55 +01:00
Simon Tatham 2c60070aad Move BignumInt definitions into a header file.
This allows files other than sshbn.c to work with the primitives
necessary to build multi-word arithmetic functions satisfying all of
PuTTY's portability constraints.
2015-06-07 13:50:05 +01:00
Simon Tatham 8dab2c2440 Remove pointless NULL checks in the ECC code.
snew(), and most of the bignum functions, are deliberately written to
fail an assertion and terminate the program rather than return NULL,
so there's no point carefully checking their every return value for
NULL. This removes a huge amount of pointless error-checking code, and
makes the elliptic curve arithmetic almost legible in places :-)

I've kept error checks after modinv(), because that can return NULL if
asked to invert zero. bigsub() can also fail in principle, because our
bignums are non-negative only, but in the couple of cases where it's
used there's a preceding compare that should prevent it, so I've just
added assertions.
2015-05-15 13:35:23 +01:00
Simon Tatham 89da2ddf56 Giant const-correctness patch of doom!
Having found a lot of unfixed constness issues in recent development,
I thought perhaps it was time to get proactive, so I compiled the
whole codebase with -Wwrite-strings. That turned up a huge load of
const problems, which I've fixed in this commit: the Unix build now
goes cleanly through with -Wwrite-strings, and the Windows build is as
close as I could get it (there are some lingering issues due to
occasional Windows API functions like AcquireCredentialsHandle not
having the right constness).

Notable fallout beyond the purely mechanical changing of types:
 - the stuff saved by cmdline_save_param() is now explicitly
   dupstr()ed, and freed in cmdline_run_saved.
 - I couldn't make both string arguments to cmdline_process_param()
   const, because it intentionally writes to one of them in the case
   where it's the argument to -pw (in the vain hope of being at least
   slightly friendly to 'ps'), so elsewhere I had to temporarily
   dupstr() something for the sake of passing it to that function
 - I had to invent a silly parallel version of const_cmp() so I could
   pass const string literals in to lookup functions.
 - stripslashes() in pscp.c and psftp.c has the annoying strchr nature
2015-05-15 12:47:44 +01:00
Simon Tatham 9971da40c3 Utility function: bignum_from_decimal. 2015-05-12 12:14:45 +01:00
Chris Staite 7d6bf4a6ca Provide a little-endian version of bignum_from_bytes(). 2015-05-09 15:02:50 +01:00
Simon Tatham ae4986a433 Do an smemclr(bytes) in bignum_random_in_range.
It's used for sensitive data, so we shouldn't leave it lying around
after free.
2014-12-20 18:51:42 +00:00
Simon Tatham c46da2f079 Fix memory management in bignum_random_in_range.
We were allocating a new array in which to make up a random number
every time we went round the loop, and not freeing any of them. Now we
allocate a single array to use for all loop iterations, and clear and
free it properly afterwards.

Patch due to Tim Kosse.
2014-12-20 18:51:42 +00:00
Chris Staite 7d1c30cd50 Some extra bignum functions: modsub, lshift, random_in_range. 2014-11-02 18:16:54 +00:00
Simon Tatham eac7e041f1 Add some missing invariants in bigdiv and bigmod.
The underlying function 'bigdivmod' does not ensure either of its
outputs is normalised, so its callers must do so.
2014-11-01 19:48:47 +00:00
Simon Tatham ead9081318 One more defensive assert, just to be sure.
[originally from svn r9997]
2013-08-06 16:45:49 +00:00
Simon Tatham a7cc906df0 The bignum code has two representations of zero, since
bn_restore_invariant (and the many loops that duplicate it) leaves a
single zero word in a bignum representing 0, whereas the constant
'Zero' does not have any data words at all. Cope with this in
bignum_cmp.

(It would be a better plan to decide on one representation and stick
with it, but this is the less disruptive fix for the moment.)

[originally from svn r9996]
2013-08-05 19:50:51 +00:00
Simon Tatham a7d13e284a Add some more precautionary assertions, just in case anything wildly
out of range manages to get past other recent fixes.

[originally from svn r9995]
2013-08-05 19:50:47 +00:00
Simon Tatham 97db2b6646 Fix memory leaks in the new error return from modinv.
[originally from svn r9992]
2013-08-04 22:33:50 +00:00
Simon Tatham cb1df53360 Make modinv able to return NULL if its inputs are not coprime, and
check for that return value everywhere it is used.

[originally from svn r9990]
2013-08-04 19:34:07 +00:00
Simon Tatham 5bcb8d6aac More consistently defend against division by zero with assertions. We
now check that all the modular functions (modpow, modinv, modmul,
bigdivmod) have nonzero moduli, and that modinv also has a nonzero
thing to try to invert.

[originally from svn r9987]
2013-08-04 19:33:53 +00:00
Simon Tatham 55e8a268ab Found a lot of places in sshbn.c where for-loops zeroing out memory
just before freeing it really ought to be smemclrs.

[originally from svn r9981]
2013-08-02 19:51:36 +00:00
Simon Tatham e01104f899 Fix an array-size bug in modmul, and add some tests for it.
[originally from svn r9977]
2013-08-02 06:27:54 +00:00
Simon Tatham 3c443bd2a5 Update the suggested compile command in sshbn.c's test rig.
[originally from svn r9732]
2012-12-22 18:10:08 +00:00
Simon Tatham f2bbeca400 Fix two gcc warnings about confused printf format strings in the
bignum code's test harness. Thanks to Sup Yut Sum for fixing this in
TortoisePlink and Sven Strickroth for bringing it to my attention.

[originally from svn r9731]
2012-12-22 18:09:02 +00:00
Simon Tatham aa5bae8916 Introduce a new utility function smemclr(), which memsets things to
zero but does it in such a way that over-clever compilers hopefully
won't helpfully optimise the call away if you do it just before
freeing something or letting it go out of scope. Use this for
(hopefully) every memset whose job is to destroy sensitive data that
might otherwise be left lying around in the process's memory.

[originally from svn r9586]
2012-07-22 19:51:50 +00:00
Simon Tatham 1fda4423e0 Fix Windows compile warnings by adding explicit casts.
[originally from svn r9200]
2011-07-12 18:09:46 +00:00
Simon Tatham 7957ca1153 Rejig the bottom-level loops in internal_mul_* to use pointers instead
of array indices. You'd hope that compilers could automatically turn
the one representation into the other if it was faster to do so, but
apparently not: even on gcc -O3, this source transformation gains over
15% performance.

[originally from svn r9105]
2011-02-22 19:09:27 +00:00
Simon Tatham 77180221bd Move the malloc and free of scratch space out of the internal_mul
routines into their callers, where they'll be done once for a whole
modpow rather than many times within each multiply. Doesn't save much
time as far as I can see - perhaps a couple of percent, one second in
the minute it takes to run the new bignum test suite - but seems like
a sensible idea anyway on general principles.

[originally from svn r9103]
2011-02-21 19:47:28 +00:00
Simon Tatham 15d7f8bb3e Add tests of modpow.
[originally from svn r9100]
2011-02-20 15:27:48 +00:00
Simon Tatham 1b47322c3b Nearly forgot. Reinstate the original unoptimised modpow, as a
fallback for when Montgomery is inapplicable.

(I may also at some point switch to using it for small exponents, if
speed testing should reveal that there's a noticeable threshold beyond
which preparing the Montgomery setup is uneconomical.)

[originally from svn r9099]
2011-02-20 15:14:02 +00:00
Simon Tatham 260cee498e Fix bug in Karatsuba multiplication, which affected propagation of a
carry by more than one word. Now the current set of test cases all
pass again.

[originally from svn r9098]
2011-02-20 15:06:39 +00:00
Simon Tatham 01d365b626 Beginnings of a test suite for the bignum code. The output of
testdata/bignum.py is twice the size of the rest of the PuTTY source
put together, so I'm not checking it in.

This reveals bugs in the new multiplication code, which I have yet to
fix.

[originally from svn r9097]
2011-02-20 14:59:00 +00:00
Simon Tatham fa85085640 Implement the Chinese Remainder Theorem optimisation for speeding up
RSA private key operations by making use of the fact that we know the
factors of the modulus.

[originally from svn r9095]
2011-02-18 08:25:39 +00:00
Simon Tatham 61875b87e3 Implement the Montgomery technique for speeding up modular
exponentiation by replacing the modulo operation by a cleverly chosen
multiplication. This was not worth doing in the previous state of the
code (because my multiply was about as slow as my modulo), but now
that multiplication has been sped up by the Karatsuba optimisation,
Montgomery becomes worthwhile.

[originally from svn r9094]
2011-02-18 08:25:38 +00:00
Simon Tatham d9c3353176 Implement the Karatsuba technique for recursive divide-and-conquer
optimisation of large multiplies.

[originally from svn r9093]
2011-02-18 08:25:37 +00:00
Simon Tatham 8b4c50be45 Add some appropriate bignum typedefs for generic 64-bit systems,
setting BignumInt to 32 bits. gcc defines _LP64 on x86-64 and
presumably on other 64-bit architectures, so I've conditioned my
defines on that in the hope that they won't need redoing for the next
few such architectures.

I've also added a set for _LLP64, but it's untested as yet.

[originally from svn r9092]
2011-02-18 08:25:36 +00:00
Simon Tatham 42801b7e9e Get rid of all the MSVC warnings.
[originally from svn r7086]
2007-01-09 18:24:07 +00:00
Jacob Nevins d75ab2b509 Robert Evans spotted that bignum_decimal() failed to cope with being given
a zero input.
This shouldn't matter for PuTTY, as these routines are only used in PuTTYgen,
to output SSH-1 format public key exponents/moduli, which should be nonzero.

[originally from svn r6731]
2006-06-17 12:02:03 +00:00
Jacob Nevins d8b7de5435 Improvements from Spyros Blanas to the MSVC optimisations of r6469:
don't do a function call for each divmod, and don't rely on details of
the calling convention.
(This didn't actually make any measurable difference to runtime in any
of my tests, but we may as well keep it as it's neater.)
Also document some general caveats of the divmod macro.

[originally from svn r6475]
[r6469 == d72e4b718c]
2005-12-06 23:18:27 +00:00
Jacob Nevins d72e4b718c An MSVC version of the 16->32-bit bignum optimisation, derived from part of
a patch by Lionel Fourquaux. Seems to be about a factor of four improvement
(see wishlist item for details).
I don't claim to understand this in detail, so I can't vouch for its
correctness, but it didn't fall over immediately. It also produces some
compiler warnings, unfortunately.

[originally from svn r6469]
[this svn revision also touched putty-wishlist]
2005-11-23 21:26:05 +00:00
Jacob Nevins 5aa719d16e Consistently use a single notation to refer to SSH protocol versions, as
discussed. Use Barrett and Silverman's convention of "SSH-1" for SSH protocol
version 1 and "SSH-2" for protocol 2 ("SSH1"/"SSH2" refer to ssh.com
implementations in this scheme). <http://www.snailbook.com/terms.html>

[originally from svn r5480]
2005-03-10 16:36:05 +00:00
Simon Tatham ac61490a5b Fix divide overflow in internal_mod(). Thanks to William Petiot for
spotting a special case that the DIV instruction can't quite cover.

[originally from svn r5028]
2004-12-28 14:04:26 +00:00
Simon Tatham 4217269931 Merged SSH1 robustness changes from 0.55 release branch on to trunk.
[originally from svn r4379]
2004-08-01 12:07:11 +00:00
Simon Tatham 501997ab2b Improve robustness in modpow().
[originally from svn r4372]
2004-07-29 15:44:35 +00:00
Simon Tatham ee72bf04df Fix a casting bug with the length-independent sshbn code.
[originally from svn r3760]
2004-01-22 18:37:48 +00:00