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

41 Коммитов

Автор SHA1 Сообщение Дата
Simon Tatham b54147de4b Remove some redundant variables and assignments.
This fixes a batch of clang-analyzer warnings of the form 'you
declared / assigned this variable and then never use it'. It doesn't
fix _all_ of them - some are there so that when I add code in the
future _it_ can use the variable without me having to remember to
start setting it - but these are the ones I thought it would make the
code better instead of worse to fix.
2018-12-01 17:00:01 +00:00
Simon Tatham 898cb8835a Make ssh_key and ssh{2,1}_cipher into structs.
In commit 884a7df94 I claimed that all my trait-like vtable systems
now had the generic object type being a struct rather than a bare
vtable pointer (e.g. instead of 'Socket' being a typedef for a pointer
to a const Socket_vtable, it's a typedef for a struct _containing_ a
vtable pointer).

In fact, I missed a few. This commit converts ssh_key, ssh2_cipher and
ssh1_cipher into the same form as the rest.
2018-11-26 21:02:28 +00:00
Simon Tatham 3214563d8e Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.

PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.

I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!

To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.

In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
 - the 'multisel' field in dialog.h's list box structure, for which
   the GTK front end in particular recognises a difference between 1
   and 2 but nearly everything else treats as boolean
 - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
   something about the specific location of the urgent pointer, but
   most clients only care about 0 vs 'something nonzero'
 - the return value of wc_match, where -1 indicates a syntax error in
   the wildcard.
 - the return values from SSH-1 RSA-key loading functions, which use
   -1 for 'wrong passphrase' and 0 for all other failures (so any
   caller which already knows it's not loading an _encrypted private_
   key can treat them as boolean)
 - term->esc_query, and the 'query' parameter in toggle_mode in
   terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
   but can also hold -1 for some other intervening character that we
   don't support.

In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
 - the return value of plug_accepting uses the POSIXish convention of
   0=success and nonzero=error; I think if I made it bool then I'd
   also want to reverse its sense, and that's a job for a separate
   piece of work.
 - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
   represent the default and alternate screens. There's no obvious
   reason why one of those should be considered 'true' or 'positive'
   or 'success' - they're just indices - so I've left it as int.

ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.

In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.

Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-03 13:45:00 +00:00
Simon Tatham a647f2ba11 Adopt C99 <stdint.h> integer types.
The annoying int64.h is completely retired, since C99 guarantees a
64-bit integer type that you can actually treat like an ordinary
integer. Also, I've replaced the local typedefs uint32 and word32
(scattered through different parts of the crypto code) with the
standard uint32_t.
2018-11-03 13:25:50 +00:00
Simon Tatham 9396fcc9f7 Rename FROMFIELD to 'container_of'.
Ian Jackson points out that the Linux kernel has a macro of this name
with the same purpose, and suggests that it's a good idea to use the
same name as they do, so that at least some people reading one code
base might recognise it from the other.

I never really thought very hard about what order FROMFIELD's
parameters should go in, and therefore I'm pleasantly surprised to
find that my order agrees with the kernel's, so I don't have to
permute every call site as part of making this change :-)
2018-10-06 07:28:51 +01:00
Simon Tatham e1b52ae721 Remove duplicate typedef of AESContext.
Pavel Kryukov points out that ssh.h has this typedef, so sshaes.c
doesn't have to have it too, and in C89 mode it's an error to have it
twice.
2018-09-20 23:46:45 +01:00
Simon Tatham 91a624fb70 sshaes.c: add some missing clang target attributes.
The helper functions mm_shuffle_pd_i0 and mm_shuffle_pd_i1 need the
FUNC_ISA macro (which expands to __attribute__((target("sse4.1,aes")))
when building with clang) in order to avoid a build error complaining
that their use of the _mm_shuffle_pd intrinsic is illegal without at
least sse2.

This build error is new in the recently released clang 7.0.0, compared
to the svn trunk revision I was previously building with. But it
certainly seems plausible to me, so I assume there's been some
pre-release tightening up of the error reporting. In any case, those
helper functions are only ever called from other functions with the
same attribute, so it shouldn't cause trouble.
2018-09-20 16:58:43 +01:00
Simon Tatham 229af2b5bf Turn SSH-2 ciphers into a classoid.
This is more or less the same job as the SSH-1 case, only more
extensive, because we have a wider range of ciphers.

I'm a bit disappointed about the AES case, in particular, because I
feel as if it ought to have been possible to arrange to combine this
layer of vtable dispatch with the subsidiary one that selects between
hardware and software implementations of the underlying cipher. I may
come back later and have another try at that, in fact.
2018-09-19 23:08:07 +01:00
Pavel Kryukov f4ca28a0f4 Add a missing const
Dummy version of 'aes_setup_ni` function (for compilers that do not
support AES extenstions) must have same signature as actual function
2018-05-26 15:26:34 +01:00
Simon Tatham 7babe66a83 Make lots of generic data parameters into 'void *'.
This is a cleanup I started to notice a need for during the BinarySink
work. It removes a lot of faffing about casting things to char * or
unsigned char * so that some API will accept them, even though lots of
such APIs really take a plain 'block of raw binary data' argument and
don't care what C thinks the signedness of that data might be - they
may well reinterpret it back and forth internally.

So I've tried to arrange for all the function call APIs that ought to
have a void * (or const void *) to have one, and those that need to do
pointer arithmetic on the parameter internally can cast it back at the
top of the function. That saves endless ad-hoc casts at the call
sites.
2018-05-26 09:22:43 +01:00
Tim Kosse eaac8768e4 Support aes256-ctr encryption when imported OpenSSH keys.
OpenSSH 7.6 switched from aes256-cbc to aes256-ctr for encrypting
new-style private keys.
2018-04-11 22:35:40 +01:00
Simon Tatham d6338c22c3 Fix mishandling of IV in AES-NI CBC decryption.
A user reported that the new hardware AES implementation wasn't
working, and sent an event log suggesting that it was being run in CBC
mode - which is unusual enough these days that that may well have been
its first test.

I wasn't looking forward to debugging the actual AES intrinsics code,
but fortunately, I didn't have to, because an eyeball review spotted a
nice simple error in the CBC decrypt function in which the wrong local
variable was being stored into the IV variable on exit from the
function. Testing against a local CBC-only server reproduced the
reported failure and suggested that this fixed it.
2018-03-27 23:05:29 +01:00
Pavel I. Kryukov a27f55e819 Use correct way to detect new instructions in Clang
__clang_major__ and __clang_minor__ macros may be overriden
 in Apple and other compilers. Instead of them, we use
__has_attribute(target) to check whether Clang supports per-function
targeted build and __has_include() to check if there are intrinsic
header files
2018-03-14 20:36:31 +00:00
Simon Tatham 599bab84a1 Condition out AES-NI support if using a too-old clang.
A clang too old to have __attribute__((target)) will not manage to
compile the clang-style hardware-accelerated functions, so it
shouldn't try.
2017-12-20 10:12:28 +00:00
Pavel I. Kryukov 2d31305af9 Alternative AES routines, using x86 hardware support.
The new AES routines are compiled into the code on any platform where
the compiler can be made to generate the necessary AES-NI and SSE
instructions. But not every CPU will support those instructions, so
the pure-software routines haven't gone away: both sets of functions
sit side by side in the code, and at key setup time we check the CPUID
bitmap to decide which set to select.

(This reintroduces function pointers into AESContext, replacing the
ones that we managed to remove a few commits ago.)
2017-10-20 19:13:54 +01:00
Pavel I. Kryukov e8be7ea98a AES: 16-byte align the key schedule arrays.
This is going to be important in the next commit, when we start
accessing them using x86 SSE instructions.
2017-10-20 19:13:47 +01:00
Pavel I. Kryukov 0816e2b1a0 AES: fold the core and outer routines together.
The outer routines are the ones which handle the CBC encrypt, CBC
decrypt and SDCTR cipher modes. Previously each of those had to be
able to dispatch to one of the per-block-size core routines, which
made it worth dividing the system up into two layers. But now there's
only one set of core routines, they may as well be inlined into the
outer ones.

Also as part of this commit, the nasty undef/redef of MAKEWORD and
LASTWORD have been removed, and the different macro definitions now
have different macro _names_, to make it clearer which one is used
where.
2017-10-20 19:13:39 +01:00
Pavel I. Kryukov 5592312636 AES: remove support for block sizes other than 128 bits.
They're not really part of AES at all, in that they were part of the
Rijndael design but not part of the subset standardised by NIST. More
relevantly, they're not used by any SSH cipher definition, so they're
just adding complexity to the code which is about to get in the way of
refactoring it.

Removing them means there's only one pair of core encrypt/decrypt
functions, so the 'encrypt' and 'decrypt' function pointer fields can
be completely removed from AESContext.
2017-10-20 19:13:21 +01:00
Simon Tatham 4dfadcfb26 sshaes.c: remove completely unused #define MAX_NK. 2017-10-19 20:01:47 +01:00
Simon Tatham ea54259392 sshaes.c: fix file name in header comment.
Apparently I forgot to edit that when I originally imported this AES
implementation into PuTTY's SSH code from the more generically named
source file in which I'd originally developed it.
2017-10-19 20:00:54 +01:00
Simon Tatham 43be90e287 Split ssh2_cipher's keylen field into two.
The revamp of key generation in commit e460f3083 made the assumption
that you could decide how many bytes of key material to generate by
converting cipher->keylen from bits to bytes. This is a good
assumption for all ciphers except DES/3DES: since the SSH DES key
setup ignores one bit in every byte of key material it's given, you
need more bytes than its keylen field would have you believe. So
currently the DES ciphers aren't being keyed correctly.

The original keylen field is used for deciding how big a DH group to
request, and on that basis I think it still makes sense to keep it
reflecting the true entropy of a cipher key. So it turns out we need
two _separate_ key length fields per cipher - one for the real
entropy, and one for the much more obvious purpose of knowing how much
data to ask for from ssh2_mkkey.

A compensatory advantage, though, is that we can now measure the
latter directly in bytes rather than bits, so we no longer have to
faff about with dividing by 8 and rounding up.
2015-09-10 08:11:26 +01:00
Chris Staite 5d9a9a7bdf Allow a cipher to specify encryption of the packet length.
No cipher uses this facility yet, but one shortly will.
2015-06-07 13:42:31 +01:00
Chris Staite 705f159255 Allow a cipher to override the SSH KEX's choice of MAC.
No cipher uses this facility yet, but one shortly will.
2015-06-07 13:42:19 +01: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 108791e15c Support importing of new-style OpenSSH private keys (encrypted by
AES rather than 3DES).

[originally from svn r8916]
2010-04-12 10:55:31 +00:00
Ben Harris f2b0335c48 Now that we've got at least some SDCTR modes working (and aes256-ctr is our
default preferred cipher), add code to inject SSH_MSG_IGNOREs to randomise
the IV when using CBC-mode ciphers.  Each cipher has a flag to indicate
whether it needs this workaround, and the SSH packet output maze has gained
some extra complexity to implement it.

[originally from svn r5659]
2005-04-23 16:22:51 +00:00
Jacob Nevins 6eec320f0b Unify GET_32BIT()/PUT_32BIT() et al from numerous source files into misc.h.
I've done a bit of testing (not exhaustive), and I don't _think_ I've broken
anything...

[originally from svn r5632]
2005-04-12 20:04:56 +00:00
Ben Harris 91f9a3c6da Remove support for the "rijndael256-cbc", "rijndael192-cbc", and
"rijndael128-cbc" names for AES.  These are in the IANA namespace, but
never appeared in any secsh-transport draft, and no version of OpenSSH
has supported them without also supporting the aes*-cbc names.

"rijndael-cbc@lysator.liu.se" gets to live because it's in the private
namespace.

[originally from svn r5607]
2005-04-06 23:40:30 +00:00
Ben Harris 6023b6c70b Implement SDCTR modes, as defined in the newmodes draft. This adds
aes128-ctr, aes192-ctr, and aes256-ctr.  blowfish-ctr and 3des-ctr are
present but disabled, since I haven't tested them yet.

In addition, change the user-visible names of ciphers (as displayed in the
Event Log) to include the mode name and, in Blowfish's case, the key size.

[originally from svn r5605]
2005-04-06 23:27:08 +00:00
Simon Tatham d36a4c3685 Introduced wrapper macros snew(), snewn() and sresize() for the
malloc functions, which automatically cast to the same type they're
allocating the size of. Should prevent any future errors involving
mallocing the size of the wrong structure type, and will also make
life easier if we ever need to turn the PuTTY core code from real C
into C++-friendly C. I haven't touched the Mac frontend in this
checkin because I couldn't compile or test it.

[originally from svn r3014]
2003-03-29 16:14:26 +00:00
Ben Harris a261492e70 Move the various big tables to the start of the file to save mucking about
with ifdefs for specific compilers.

[originally from svn r2491]
2003-01-07 20:47:53 +00:00
Ben Harris db9edaf8c9 It looks like Visual C (or whatever the Windows snapshots are built with)
objects to incomplete static array declarations, which I introduced to work
around a bug in SC/MrC.  Use #ifdefs to decide whether to enable the workaround
or not.

[originally from svn r2488]
2003-01-06 21:46:56 +00:00
Ben Harris 014a402b9d aes_setup() is unused outside this file. Make it static.
[originally from svn r2476]
2003-01-05 23:03:02 +00:00
Ben Harris 0e086031b5 SC (Apple's 68K C compiler) seems to treat tentative definitions of complete
arrya as full definitions, and hence gets upset when it finds a full definition
later.  This is a bug (see K&R2 A10.2), but an easy one to work around by
making the tentative definitions incomplete, so I've done that.

[originally from svn r2462]
2003-01-05 13:57:09 +00:00
Simon Tatham 9848062b86 SSH ciphers now use dynamically allocated contexts.
[originally from svn r2130]
2002-10-25 12:35:22 +00:00
Simon Tatham 286f1f5b1f Be more careful about destroying sensitive data after private key
load/store/import operations.

[originally from svn r1673]
2002-05-13 16:37:11 +00:00
Simon Tatham 3730ada5ce Run entire source base through GNU indent to tidy up the varying
coding styles of the various contributors! Woohoo!

[originally from svn r1098]
2001-05-06 14:35:20 +00:00
Simon Tatham 3f63cf7d88 Remove needless redeclaration of word32 (it was in ssh.h)
[originally from svn r1020]
2001-03-22 21:48:32 +00:00
Simon Tatham 28b1fc766c Preliminary support for RSA user authentication in SSH2! Most of the
error messages are currently wrong, and Pageant doesn't yet support
the new key type, and I haven't thoroughly tested that falling back
to password authentication and trying invalid keys etc all work. But
what I have here has successfully performed a public key
authentication, so it's working to at least some extent.

[originally from svn r973]
2001-03-03 11:54:34 +00:00
Simon Tatham b182356f99 Support for selecting AES from the GUI. In the process, I've had to
introduce another layer of abstraction in SSH2 ciphers, such that a
single `logical cipher' (as desired by a user) can equate to more
than one `physical cipher'. This is because AES comes in several key
lengths (PuTTY will pick the highest supported by the remote end)
and several different SSH2-protocol-level names (aes*-cbc,
rijndael*-cbc, and an unofficial one rijndael-cbc@lysator.liu.se).

[originally from svn r967]
2001-03-02 13:55:23 +00:00
Simon Tatham bf25fd405c Add AES support in SSH2. Not yet complete: there's no way to select
it in the GUI (or even in the registry).

[originally from svn r966]
2001-03-02 11:44:35 +00:00