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

5436 Коммитов

Автор SHA1 Сообщение Дата
Simon Tatham 5087792440 Label random-noise sources with an enum of ids.
The upcoming PRNG revamp will want to tell noise sources apart, so
that it can treat them all fairly. So I've added an extra parameter to
noise_ultralight and random_add_noise, which takes values in an
enumeration covering all the vague classes of entropy source I'm
collecting. In this commit, though, it's simply ignored.
2019-01-23 22:36:17 +00:00
Simon Tatham 628e794832 Replace random_byte() with random_read().
This is in preparation for a PRNG revamp which will want to have a
well defined boundary for any given request-for-randomness, so that it
can destroy the evidence afterwards. So no more looping round calling
random_byte() and then stopping when we feel like it: now you say up
front how many random bytes you want, and call random_read() which
gives you that many in one go.

Most of the call sites that had to be fixed are fairly mechanical, and
quite a few ended up more concise afterwards. A few became more
cumbersome, such as mp_random_bits, in which the new API doesn't let
me load the random bytes directly into the target integer without
triggering undefined behaviour, so instead I have to allocate a
separate temporary buffer.

The _most_ interesting call site was in the PKCS#1 v1.5 padding code
in sshrsa.c (used in SSH-1), in which you need a stream of _nonzero_
random bytes. The previous code just looped on random_byte, retrying
if it got a zero. Now I'm doing a much more interesting thing with an
mpint, essentially scaling a binary fraction repeatedly to extract a
number in the range [0,255) and then adding 1 to it.
2019-01-23 22:36:17 +00:00
Simon Tatham 76aa3f6f7a Add more random-number noise collection calls.
Mostly on the Unix side: there are lots of places the Windows code was
collecting noise that the corresponding Unix/GTK code wasn't bothering
to, such as mouse movements, keystrokes and various network events.
Also, both platforms had forgotten to collect noise when reading data
from a pipe to a local proxy process, even though in that
configuration that's morally equivalent to the network packet timings
that we'd normally be collecting from.
2019-01-23 22:36:17 +00:00
Simon Tatham c0de1cbbad sshhmac: reorganise, and fix crash when used with CBC.
I'd forgotten that the SSH-2 BPP uses a defensive measure of
generating the MAC for successive prefixes of an incoming packet,
which means that ssh_mac_genresult needs to be nondestructive.

While I'm at it, I've also made all of hmac's hash objects exist all
the time - they're created up front, destroyed unconditionally on
free, and in between, whenever one is destroyed at all it's
immediately recreated. I think this simplifies things in general, and
in particular, creating at least one hash object immediately will come
in useful when I add selector vtables in a few commits' time.
2019-01-23 22:36:17 +00:00
Simon Tatham 8ebdaf0b1d Fix memory leak when reading a public key.
Leak Sanitiser pointed out in passing that the blob read from the key
file wasn't being freed.
2019-01-23 22:32:02 +00:00
Simon Tatham a53559a0dc Expose blocklen in the ssh_hash structure.
Keeping that information alongside the hashes themselves seems more
sensible than having the HMAC code know that fact about everything it
can work with.
2019-01-23 22:32:02 +00:00
Simon Tatham de797aa40e Reinstate CBC flag in AES-CBC ciphers.
That flag was missing from all the CBC vtables' flags fields, because
my recent rewrite forgot to put it in. As a result the SSH_MSG_IGNORE
defence against CBC length oracle attacks was not being enabled.
2019-01-23 22:32:02 +00:00
Simon Tatham 891c2b9616 Uppity X forwarding: fix SockAddr use after free.
Another thing pointed out by ASan: new_unix_listener takes ownership
of the SockAddr you give it, so I shouldn't have been freeing it at
the end of platform_make_x11_server().
2019-01-23 21:19:26 +00:00
Simon Tatham e7edc6e7ba Uppity: fix an unterminated dupcat in X server setup.
Address Sanitiser pointed this out; I surely can't have run Uppity
under ASan before, or I'd have noticed this months ago.
2019-01-23 21:18:55 +00:00
Simon Tatham f8f96a2fec testcrypt: fix the hello-world request!
The single simplest request in the entire protocol - the command
'hello' which is supposed to respond 'hello, world\n' to demonstrate
to an interactive user that testcrypt has started up successfully -
was missing the trailing newline in the response. :-)
2019-01-23 21:04:51 +00:00
Simon Tatham 1a2fbc66ba testcrypt: include a dputs() function.
This allows me to compile testcrypt with -DDEBUG, even though it's not
linked against the usual collection of platform-specific modules that
normally provide dputs. I think the simplest possible dputs ('just
output to stderr') is actually better for testcrypt, because that
keeps it easy to compile for strange experimental platforms.
2019-01-23 21:04:48 +00:00
Simon Tatham baff23cdd6 Centralised HMAC implementation.
This replaces all the separate HMAC-implementing wrappers in the
various source files implementing the underlying hashes.

The new HMAC code also correctly handles the case of a key longer than
the underlying hash's block length, by replacing it with its own hash.
This means I can reinstate the test vectors in RFC 6234 which exercise
that case, which I didn't add to cryptsuite before because they'd have
failed.

It also allows me to remove the ad-hoc code at the call site in
cproxy.c which turns out to have been doing the same thing - I think
that must have been the only call site where the question came up
(since MAC keys invented by the main SSH-2 BPP are always shorter than
that).
2019-01-20 17:09:24 +00:00
Simon Tatham d73f692eea Add an 'extra' pointer field to ssh2_macalg.
Similar to the versions in ssh_cipheralg and ssh_keyalg, this allows a
set of vtables to share function pointers while providing varying
constant data that the shared function can use to vary its behaviour.

As an initial demonstration, I've used this to recombine the four
trivial text_name methods for the HMAC-SHA1 variants. I'm about to use
it for something more sensible, though.
2019-01-20 17:09:24 +00:00
Simon Tatham 1df39eb0a4 Turn ssh2_mac's text_name field into a method.
This allows a MAC implementation to construct its textual name at run
time. Nothing yet uses that flexibility, though.
2019-01-20 17:09:24 +00:00
Simon Tatham 836a75ba69 ssh1login: fix memory management when using the agent.
We were retaining a ptrlen 's->comment' into a past agent response
message, but that had been freed by the time it was actually printed
in a diagnostic. Also, agent_response_to_free was being freed twice,
because the variable 'ret' in the response-formatting code aliased it.
2019-01-20 17:09:24 +00:00
Simon Tatham 0d2d20aad0 Access all hashes and MACs through the standard API.
All the hash-specific state structures, and the functions that
directly accessed them, are now local to the source files implementing
the hashes themselves. Everywhere we previously used those types or
functions, we're now using the standard ssh_hash or ssh2_mac API.

The 'simple' functions (hmacmd5_simple, SHA_Simple etc) are now a pair
of wrappers in sshauxcrypt.c, each of which takes an algorithm
structure and can do the same conceptual thing regardless of what it
is.
2019-01-20 17:09:24 +00:00
Simon Tatham acdcf2bfaa Complete rewrite of sshdes.c.
DES was the next target in my ongoing programme of trying to make all
our crypto code constant-time. Unfortunately, DES is very hard to make
constant-time and still have any kind of performance: my early timing
tests suggest that the implementation I have here is about 4.5 times
slower than the implementation it's replacing. That's about the same
factor as the new AES code when it's not in parallel mode and not
superseded by hardware acceleration - but of course the difference is
that AES usually _is_ superseded by HW acceleration or (failing that)
in parallel mode. This DES implementation doesn't parallelise, and
there's no hardware alternative, so DES is going to be this slow all
the time, unless someone sends me code that does it better.

But hopefully that isn't too big a problem. The main use for DES these
days is legacy devices whose SSH servers haven't been updated to speak
anything more modern, so with any luck those devices will also be old
and slow enough that _their_ end will be the bottleneck in connection
speed!
2019-01-18 19:41:23 +00:00
Simon Tatham c6a8731b45 Add a consistency test for every ssh_cipheralg.
Like the recently added tests for the auxiliary encryption functions,
this new set of tests is not derived from any external source: the
expected results are simply whatever the current PuTTY code delivers
_now_ for the given operation. The aim is to protect me against
breakage during refactoring or rewrites.
2019-01-18 19:41:23 +00:00
Simon Tatham 07db7f89b2 Move all the auxiliary cipher functions into a new module.
All those functions like aes256_encrypt_pubkey and des_decrypt_xdmauth
previously lived in the same source files as the ciphers they were
based on, and provided an alternative API to the internals of that
cipher's implementation. But there was no _need_ for them to have that
privileged access to the internals, because they didn't do anything
you couldn't access through the standard API. It was just a historical
oddity with no real benefit, whose main effect is to make refactoring
painful.

So now all of those functions live in a new file sshauxcrypt.c, and
they all work through the same vtable system as all other cipher
clients, by making an instance of the right cipher and configuring it
in the appropriate way. This should make them completely independent
of any internal changes to the cipher implementations they're based
on.
2019-01-18 19:41:23 +00:00
Simon Tatham 986508a570 Merge the ssh1_cipher type into ssh2_cipher.
The aim of this reorganisation is to make it easier to test all the
ciphers in PuTTY in a uniform way. It was inconvenient that there were
two separate vtable systems for the ciphers used in SSH-1 and SSH-2
with different functionality.

Now there's only one type, called ssh_cipher. But really it's the old
ssh2_cipher, just renamed: I haven't made any changes to the API on
the SSH-2 side. Instead, I've removed ssh1_cipher completely, and
adapted the SSH-1 BPP to use the SSH-2 style API.

(The relevant differences are that ssh1_cipher encapsulated both the
sending and receiving directions in one object - so now ssh1bpp has to
make a separate cipher instance per direction - and that ssh1_cipher
automatically initialised the IV to all zeroes, which ssh1bpp now has
to do by hand.)

The previous ssh1_cipher vtable for single-DES has been removed
completely, because when converted into the new API it became
identical to the SSH-2 single-DES vtable; so now there's just one
vtable for DES-CBC which works in both protocols. The other two SSH-1
ciphers each had to stay separate, because 3DES is completely
different between SSH-1 and SSH-2 (three layers of CBC structure
versus one), and Blowfish varies in endianness and key length between
the two.

(Actually, while I'm here, I've only just noticed that the SSH-1
Blowfish cipher mis-describes itself in log messages as Blowfish-128.
In fact it passes the whole of the input key buffer, which has length
SSH1_SESSION_KEY_LENGTH == 32 bytes == 256 bits. So it's actually
Blowfish-256, and has been all along!)
2019-01-18 19:41:23 +00:00
Simon Tatham 20930e7d0c Add tests of auxiliary encryption functions.
All the things like des_encrypt_xdmauth and aes256_encrypt_pubkey are
at risk of changing their behaviour if I rewrite the underlying code,
so even if I don't have any externally verified test cases, I should
still have _something_ to keep me confident that they work the same
way today that they worked yesterday.
2019-01-18 19:18:20 +00:00
Simon Tatham eec6666ff9 cmdgen: fix double-free on exit.
Freeing ssh1key->comment before calling freersakey() on the whole of
ssh1key is redundant, and worse, because we also didn't null out the
freed pointer, causes a double-free.
2019-01-18 19:15:13 +00:00
Simon Tatham 6dc8860f8a Uppity: expect SSH1_CMSG_EXIT_CONFIRMATION.
I've only just noticed that the server-side SSH-1 connection layer had
no handler for that message, so when an SSH-1 connection terminates in
the normal way, Uppity's event log reports 'Unexpected packet
received, type 33 (SSH1_CMSG_EXIT_CONFIRMATION)', which is wrong in
that it _should_ be expected!
2019-01-18 19:14:41 +00:00
Simon Tatham bf743bf85c Uppity: properly support _POSIX_VDISABLE in tty modes.
The SSH wire protocol for tty modes corresponding to control
characters (e.g. configuring what Ctrl-Foo you can press to generate
SIGINT or SIGQUIT) specifies (RFC 4254 section 8, under VINTR, saying
'similarly for the other characters') that you should send the value
255 on the wire if you want _no_ character code to map to the action
in question.

But in the <termios.h> API, that's indicated by setting the
appropriate field of 'struct termios' to _POSIX_VDISABLE, which is a
platform-dependent value and varies between (at least) Linux and *BSD.

On the client side, Unix Plink has always known this: when it copies
the local termios settings into a struct ssh_ttymodes to be sent on
the wire, it checks for _POSIX_VDISABLE and replaces it with 255. But
uxpty.c, mapping ssh_ttymodes back to termios for Uppity's pty
sessions, wasn't making the reverse transformation.
2019-01-18 19:14:27 +00:00
Simon Tatham 53747ad3ab Support hardware AES on Arm platforms.
The refactored sshaes.c gives me a convenient slot to drop in a second
hardware-accelerated AES implementation, similar to the existing one
but using Arm NEON intrinsics in place of the x86 AES-NI ones.

This needed a minor structural change, because Arm systems are often
heterogeneous, containing more than one type of CPU which won't
necessarily all support the same set of architecture features. So you
can't test at run time for the presence of AES acceleration by
querying the CPU you're running on - even if you found a way to do it,
the answer wouldn't be reliable once the OS started migrating your
process between CPUs. Instead, you have to ask the OS itself, because
only that knows about _all_ the CPUs on the system. So that means the
aes_hw_available() mechanism has to extend a tentacle into each
platform subdirectory.

The trickiest part was the nest of ifdefs that tries to detect whether
the compiler can support the necessary parts. I had successful
test-compiles on several compilers, and was able to run the code
directly on an AArch64 tablet (so I know it passes cryptsuite), but
it's likely that at least some Arm platforms won't be able to build it
because of some path through the ifdefs that I haven't been able to
test yet.
2019-01-16 22:08:50 +00:00
Simon Tatham 1ce95c7ad8 cryptsuite: another Python 3 compatibility fix.
Ahem. Re-broke P3 compatibility later in the same batch of commits
that fixed it!
2019-01-16 22:07:09 +00:00
Simon Tatham 8d88cd21ef SSH-1 BPP: pass the IV to detect_attack.
In the course of writing the tests for detect_attack, I noticed that
it had a parameter where you can pass in the last cipher block of the
previous packet (or the CBC IV, of course, if there was no previous
packet), so that it can detect a pattern of repeated cipher blocks
even if one of them is just outside the current packet.

But the actual use of the attack detector in ssh1bpp wasn't using that
parameter. Now it is!
2019-01-16 06:35:31 +00:00
Simon Tatham 8611e2f035 Add tests of the CRC compensation detector.
I remembered the existence of that module while I was changing the API
of the CRC functions. It's still quite possibly the only code in PuTTY
not written specifically _for_ PuTTY, so it definitely deserves a bit
of a test suite.

In order to expose it through the ptrlen-centric testcrypt system,
I've added some missing 'const' in the detector module itself, but
otherwise I've left the detector code as it was.
2019-01-16 06:32:02 +00:00
Simon Tatham 2e866e1fb7 Rewrite CRC implementation to be constant-time.
In SSH-1, the CRC is used on sensitive data, because it takes the
place of what ought to be a MAC. This is of course hopelessly bad
security and one of the major reasons SSH-1 was replaced, but even so,
there's no need to add timing and cache side channels _as well_ as all
the other problems with it!

So I've removed the 256-entry lookup table that's the usual way to
implement CRC (in particular, the implementation given in the RFC 1662
appendix shows the same table in full). The new strategy folds in four
bits at a time, using a multiply+XOR technique to replicate the
outgoing four bits in all the right places.

In a crude timing test this gave about a factor of 2 slowdown, which
seemed surprisingly good to me - six multiplies replacing a single
table lookup? But the multiplications in each 4-bit fold are
independent of each other, so I suspect the CPU is managing to
parallelise them.
2019-01-16 06:22:49 +00:00
Simon Tatham c330156259 Expose CRC32 to testcrypt, and add tests for it.
Finding even semi-official test vectors for this CRC implementation
was hard, because it turns out not to _quite_ match any of the well
known ones catalogued on the web. Its _polynomial_ is well known, but
the combination of details that go alongside it (starting state,
post-hashing transformation) are not quite the same as any other hash
I know of.

After trawling catalogue websites for a while I finally worked out
that SSH-1's CRC and RFC 1662's CRC are basically the same except for
different choices of starting value and final adjustment. And RFC
1662's CRC is common enough that there _are_ test vectors.

So I've renamed the previous crc32_compute function to crc32_ssh1,
reflecting that it seems to be its own thing unlike any other CRC;
implemented the RFC 1662 CRC as well, as an alternative tiny wrapper
on the inner crc32_update function; and exposed all three functions to
testcrypt. That lets me run standard test vectors _and_ directed tests
of the internal update routine, plus one check that crc32_ssh1 itself
does what I expect.

While I'm here, I've also modernised the code to use uint32_t in place
of unsigned long, and ptrlen instead of separate pointer,length
arguments. And I've removed the general primer on CRC theory from the
header comment, in favour of the more specifically useful information
about _which_ CRC this is and how it matches up to anything else out
there.

(I've bowed to inevitability and put the directed CRC tests in the
'crypt' class in cryptsuite.py. Of course this is a misnomer, since
CRC isn't cryptography, but it falls into the same category in terms
of the role it plays in SSH-1, and I didn't feel like making a new
pointedly-named 'notreallycrypt' container class just for this :-)
2019-01-16 06:22:49 +00:00
Simon Tatham f71dce662e Add comprehensive DES test vectors.
I found some that look pretty good - in particular exercising every
entry in every S-box. These will come in useful when I finish writing
a replacement for the venerable current DES implementation.
2019-01-16 06:22:49 +00:00
Simon Tatham 9f530d8c55 Add another standard AES test vector.
The 128-bit example from Appendix A/B is a more useful first test case
for a new implementation than the Appendix C tests, because the
standard shows even more of the working (in particular the full set of
intermediate results from key setup).
2019-01-16 06:22:49 +00:00
Simon Tatham 5ac7cdb1cb Make the AES availability cache actually cache things!
Ahem. I went to all the effort of setting up a wrapper function that
would store the result of the first call to aes_hw_available(), and
managed to forget to make it set the flag that said it _had_ stored
the result. So the underlying query function was being called every
time.
2019-01-16 05:53:40 +00:00
Simon Tatham 85633ac4bd cryptsuite.py: Python 3 compatibility fixes.
I intended cryptsuite to be Python 2/3 agnostic when I first wrote it,
but of course since then I've been testing on whichever Python was
handy and not continuing to check that both actually worked.
2019-01-16 05:52:49 +00:00
Simon Tatham c9f673ac12 mpint_rshift_safe: stop using variable bit shifts.
I've decided not to trust register-controlled shift operations to be
time-constant after all. They're surely fine on nice fast machines
where everything simple takes one cycle, but stranger machines,
perhaps not. In which case, I should avoid using them in the mpint
shift operation that's supposed not to reveal the shift count.
2019-01-13 21:50:15 +00:00
Simon Tatham ced0f19118 Ensure our aes_ni_context is 16-byte aligned.
The 32-bit x86 Windows build can crash with an alignment fault the
first time it tries to write into the key schedule array, because it
turns out that the x86 VS C library's malloc doesn't guarantee 16-byte
alignment on the returned block even though there is a machine type
that needs it.

To avoid having to faff with non-portable library APIs, I solve the
problem locally in aes_hw_new, by over-allocating enough to guarantee
that an aligned block of the right size must exist somewhere in the
region.
2019-01-13 20:00:53 +00:00
Simon Tatham 2edae0d9d6 GTK: unregister dialog boxes before delivering the result.
When the user clicks 'yes' to a 'weak crypto primitive' warning, and
another such warning is pending next in line, we were failing an
assertion when ssh2transport called register_dialog() for the second
warning box, because the result callback in gtkdlg.c had not called
unregister_dialog() for the previous one yet. Now that's done before
rather than after delivering the result to the dialog's client.
2019-01-13 17:14:08 +00:00
Simon Tatham 637814544c cryptsuite: test parallel CBC decryption.
This was the most complicated one of the cipher modes to get right, so
I thought I'd add a test to make sure the IV is being written out
correctly after a decryption of any number of cipher blocks.
2019-01-13 14:31:58 +00:00
Simon Tatham c507e9c964 testcrypt: test both hardware and software AES.
The new explicit vtables for the hardware and software implementations
are now exposed by name in the testcrypt protocol, and cryptsuite.py
runs all the AES tests separately on both.

(When hardware AES is compiled out, ssh2_cipher_new("aes128_hw") and
similar calls will return None, and cryptsuite.py will respond by
skipping those tests.)
2019-01-13 14:31:58 +00:00
Simon Tatham dfdb73e103 Complete rewrite of the AES code.
sshaes.c is more or less completely changed by this commit.

Firstly, I've changed the top-level structure. In the old structure,
there were three levels of indirection controlling what an encryption
function would actually do: first the ssh2_cipher vtable, then a
subsidiary set of function pointers within that to select the software
or hardware implementation, and then inside the main encryption
function, a switch on the key length to jump into the right place in
the unrolled loop of cipher rounds.

That was all a bit untidy. So now _all_ of that is done by means of
just one selection system, namely the ssh2_cipher vtable. The software
and hardware implementations of a given SSH cipher each have their own
separate vtable, e.g. ssh2_aes256_sdctr_sw and ssh2_aes256_sdctr_hw;
this allows them to have their own completely different state
structures too, and not have to try to coexist awkwardly in the same
universal AESContext with workaround code to align things correctly.
The old implementation-agnostic vtables like ssh2_aes256_sdctr still
exist, but now they're mostly empty, containing only the constructor
function, which will decide whether AES-NI is currently available and
then choose one of the other _real_ vtables to instantiate.

As well as the cleaner data representation, this also means the
vtables can have different description strings, which means the Event
Log will indicate which AES implementation is actually in use; it
means the SW and HW vtables are available for testcrypt to use
(although actually using them is left for the next commit); and in
principle it would also make it easy to support a user override for
the automatic SW/HW selection (in case anyone turns out to want one).

The AES-NI implementation has been reorganised to fit into the new
framework. One thing I've done is to de-optimise the key expansion:
instead of having a separate blazingly fast loop-unrolled key setup
function for each key length, there's now just one, which uses AES
intrinsics for the actual transformations of individual key words, but
wraps them in a common loop structure for all the key lengths which
has a clear correspondence to the cipher spec. (Sorry to throw away
your work there, Pavel, but this isn't an application where key setup
really _needs_ to be hugely fast, and I decided I prefer a version I
can understand and debug.)

The software AES implementation is also completely replaced with one
that uses a bit-sliced representation, i.e. the cipher state is split
across eight integers in such a way that each logical byte of the
state occupies a single bit in each of those integers. The S-box
lookup is done by a long string of AND and XOR operations on the eight
bits (removing the potential cache side channel from a lookup table),
and this representation allows 64 S-box lookups to be done in parallel
simply by extending those AND/XOR operations to be bitwise ones on a
whole word. So now we can perform four AES encryptions or decryptions
in parallel, at least when the cipher mode permits it (which SDCTR and
CBC decryption both do).

The result is slower than the old implementation, but (a) not by as
much as you might think - those parallel S-boxes are surprisingly
competitive with 64 separate table lookups; (b) the compensation is
that now it should run in constant time with no data-dependent control
flow or memory addressing; and (c) in any case the really fast
hardware implementation will supersede it for most users.
2019-01-13 14:31:58 +00:00
Simon Tatham be5c0e6356 Rename the AES vtables.
The old names like ssh_aes128 and ssh_aes128_ctr reflect the SSH
protocol IDs, which is all very well, but I think a more important
principle is that it should be easy for me to remember which cipher
mode each one refers to. So I've renamed them so that they all end in
_cbc and _sdctr.

(I've left alone the string identifiers used by testcrypt, for the
moment. Perhaps I'll go back and change those later.)
2019-01-13 14:09:32 +00:00
Simon Tatham ee8025dd1c testcrypt: allow ssh2_cipher_new to return NULL.
No cipher construction function _currently_ returns NULL, but one's
about to start, so the testcrypt system will have to be able to cope.

This is the first time a function in the testcrypt API has had an
'opt' type as its return value rather than an argument. But it works
just the same in reverse: the wire protocol emits the special
identifer "NULL" when the optional return value is absent, and the
Python module catches that and rewrites it as Python 'None'.
2019-01-13 13:42:05 +00:00
Simon Tatham 9128454750 Localise AESContext into sshaes.c.
All access to AES throughout the code is now done via the ssh2_cipher
vtable interface. All code that previously made direct calls to the
underlying functions (for encrypting and decrypting private key files)
now does it by instantiating an ssh2_cipher.

This removes constraints on the AES module's internal structure, and
allows me to reorganise it as much as I like.
2019-01-13 13:37:14 +00:00
Pavel I. Kryukov a3e63c7079 Enable __USE_MINGW_ANSI_STDIO for MinGW builds.
testcrypt.exe uses %zu formatting which is not enabled by default in
MinGW environment, therefore we have to enable it manually.
2019-01-13 12:54:16 +00:00
Simon Tatham 80f2f6e7af Fix mp_mul_add_simple on Visual Studio.
I had forgotten that my VS implementation of BignumADC expected the
carry parameter to be a literal carry _flag_, i.e. a boolean, rather
than a full word of extra data to be added to the sum of the main
input BignumInts a,b. So in one place where I didn't need a separate
carry I had passed one of the data words in the carry slot, which
worked fine on gcc and clang, but VS normalised that argument to 1.

That looks like the only VS bug, though: now I get a clean run of
cryptsuite.py even if it's talking to a VS-built testcrypt.exe.
2019-01-12 08:29:05 +00:00
Simon Tatham fdc4800669 Build testcrypt on Windows.
The bulk of this commit is the changes necessary to make testcrypt
compile under Visual Studio. Unfortunately, I've had to remove my
fiddly clever uses of C99 variadic macros, because Visual Studio does
something unexpected when a variadic macro's expansion puts
__VA_ARGS__ in the argument list of a further macro invocation: the
commas don't separate further arguments. In other words, if you write

  #define INNER(x,y,z) some expansion involving x, y and z
  #define OUTER(...) INNER(__VA_ARGS__)
  OUTER(1,2,3)

then gcc and clang will translate OUTER(1,2,3) into INNER(1,2,3) in
the obvious way, and the inner macro will be expanded with x=1, y=2
and z=3. But try this in Visual Studio, and you'll get the macro
parameter x expanding to the entire string 1,2,3 and the other two
empty (with warnings complaining that INNER didn't get the number of
arguments it expected).

It's hard to cite chapter and verse of the standard to say which of
those is _definitely_ right, though my reading leans towards the
gcc/clang behaviour. But I do know I can't depend on it in code that
has to compile under both!

So I've removed the system that allowed me to declare everything in
testcrypt.h as FUNC(ret,fn,arg,arg,arg), and now I have to use a
different macro for each arity (FUNC0, FUNC1, FUNC2 etc). Also, the
WRAPPED_NAME system is gone (because that too depended on the use of a
comma to shift macro arguments along by one), and now I put a custom C
wrapper around a function by simply re-#defining that function's own
name (and therefore the subsequent code has to be a little more
careful to _not_ pass functions' names between several macros before
stringifying them).

That's all a bit tedious, and commits me to a small amount of ongoing
annoyance because now I'll have to add an explicit argument count
every time I add something to testcrypt.h. But then again, perhaps it
will make the code less incomprehensible to someone trying to
understand it!
2019-01-12 08:07:44 +00:00
Simon Tatham 2a365bb08a testcrypt: fix a technically illegal forward-typedef.
Every compiler that's so far seen testcrypt.c has tolerated me writing
'typedef enum ValueType ValueType' before actually saying what 'enum
ValueType' is, but one just pointed out that it's not actually legal
standard C to do that. Moved the typedef to after the enum.
2019-01-12 08:16:35 +00:00
Simon Tatham d4d89d51e9 Move some of winmisc.c into winmiscs.c.
That's a terrible name, but winutils.c was already taken. The new
source file is intended to be to winmisc.c as the new utils.c is to
misc.c: it contains all the parts that are basically safe to link into
_any_ Windows program (even standalone test things), without tying in
to the runtime infrastructure of the main tools, referring to any
other PuTTY source module, or introducing an extra Win32 API library
dependency.
2019-01-12 08:14:54 +00:00
Simon Tatham 47ca2e98a5 testcrypt.py: look past 'opt_' prefix on argument types.
When testcrypt.h lists a function argument as 'opt_val_foo', it means
that the argument is optional in the sense that the C function can
take a null pointer in place of a valid foo, and so the Python wrapper
module should accept None in the corresponding argument slot from the
client code and translate it into the special string "NULL" in the
wire protocol.

This works fine at argument translation time, but the code that reads
testcrypt.h wasn't looking at it, so if you said 'opt_val_foo_suffix'
in place of 'opt_val_foo' (indicating that that argument is optional
_and_ the C function expects it in a translated form), then the
initial pass over testcrypt.h wouldn't strip the _suffix, and would
set up data structures with mismatched type names.
2019-01-12 08:11:14 +00:00
Simon Tatham 5afefef798 testcrypt: remove underscores from value-type names.
The type names 'val_foo' used in testcrypt.h work on a system where a
further underscore suffix is treated as a qualifier indicating
something about how the C version of the API represents that type.
(For example, plain 'val_string' means a strbuf, but if I write
'val_string_asciz' or 'val_string_ptrlen' in testcrypt.h it will cause
the wrapper for that function to pass a char * or a ptrlen derived
from that strbuf.)

But I forgot about this when I named the type val_ssh2_cipher (and
ditto ssh1), with the effect that the testcrypt system has considered
them all along to really be called 'ssh2' and 'ssh1', and the 'cipher'
to be some irrelevant API-adaptor suffix.

This hasn't caused a bug because I didn't have any other type called
val_ssh2_something. But it was a latent one. Now renamed sensibly!
2019-01-12 08:07:44 +00:00