simon-git: putty (main): Simon Tatham

Commits to Tartarus hosted VCS tartarus-commits at lists.tartarus.org
Thu Dec 19 09:03:03 GMT 2024


TL;DR:
  c2077f88 Fix compile warnings in tree234 tests.
  98200d1b Arm: turn on PSTATE.DIT if available and needed.

Repository:     https://git.tartarus.org/simon/putty.git
On the web:     https://git.tartarus.org/?p=simon/putty.git
Branch updated: main
Committer:      Simon Tatham <anakin at pobox.com>
Date:           2024-12-19 09:03:03

commit c2077f888c4076c7a872477dbfe4dafcc92d978a
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=c2077f888c4076c7a872477dbfe4dafcc92d978a;hp=27550b02e26c71a9638ff25aeaeff32183ca5a3f
Author: Simon Tatham <anakin at pobox.com>
Date:   Thu Dec 19 08:30:07 2024 +0000

    Fix compile warnings in tree234 tests.
    
    I'm not sure why these have never bothered me before, but a test build
    I just made for a completely different reason complained about them!
    
    findtest() did a binary search using a while loop, and then used
    variables set in the loop body, which gcc objected to on the grounds
    that the body might have run 0 times and not initialised those
    variables. Also in the same function gcc objected to the idea that
    findrelpos234() might have returned NULL and not set 'index'. I think
    neither of these things can actually have _happened_, but let's stop
    the compiler complaining anyway.

 utils/tree234.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

commit 98200d1bfec13397cf81b1d5b28a1ab90962dcde
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=98200d1bfec13397cf81b1d5b28a1ab90962dcde;hp=c2077f888c4076c7a872477dbfe4dafcc92d978a
Author: Simon Tatham <anakin at pobox.com>
Date:   Thu Dec 19 08:47:08 2024 +0000

    Arm: turn on PSTATE.DIT if available and needed.
    
    DIT, for 'Data-Independent Timing', is a bit you can set in the
    processor state on sufficiently new Arm CPUs, which promises that a
    long list of instructions will deliberately avoid varying their timing
    based on the input register values. Just what you want for keeping
    your constant-time crypto primitives constant-time.
    
    As far as I'm aware, no CPU has _yet_ implemented any data-dependent
    optimisations, so DIT is a safety precaution against them doing so in
    future. It would be embarrassing to be caught without it if a future
    CPU does do that, so we now turn on DIT in the PuTTY process state.
    
    I've put a call to the new enable_dit() function at the start of every
    main() and WinMain() belonging to a program that might do
    cryptography (even testcrypt, in case someone uses it for something!),
    and in case I missed one there, also added a second call at the first
    moment that any cryptography-using part of the code looks as if it
    might become active: when an instance of the SSH protocol object is
    configured, when the system PRNG is initialised, and when selecting
    any cryptographic authentication protocol in an HTTP or SOCKS proxy
    connection. With any luck those precautions between them should ensure
    it's on whenever we need it.
    
    Arm's own recommendation is that you should carefully choose the
    granularity at which you enable and disable DIT: there's a potential
    time cost to turning it on and off (I'm not sure what, but plausibly
    something of the order of a pipeline flush), so it's a performance hit
    to do it _inside_ each individual crypto function, but if CPUs start
    supporting significant data-dependent optimisation in future, then it
    will also become a noticeable performance hit to just leave it on
    across the whole process. So you'd like to do it somewhere in the
    middle: for example, you might turn on DIT once around the whole
    process of verifying and decrypting an SSH packet, instead of once for
    decryption and once for MAC.
    
    With all respect to that recommendation as a strategy for maximum
    performance, I'm not following it here. I turn on DIT at the start of
    the PuTTY process, and then leave it on. Rationale:
    
     1. PuTTY is not otherwise a performance-critical application: it's
        not likely to max out your CPU for any purpose _other_ than
        cryptography. The most CPU-intensive non-cryptographic thing I can
        imagine a PuTTY process doing is the complicated computation of
        font rendering in the terminal, and that will normally be cached
        (you don't recompute each glyph from its outline and hints for
        every time you display it).
    
     2. I think a bigger risk lies in accidental side channels from having
        DIT turned off when it should have been on. I can imagine lots of
        causes for that. Missing a crypto operation in some unswept corner
        of the code; confusing control flow (like my coroutine macros)
        jumping with DIT clear into the middle of a region of code that
        expected DIT to have been set at the beginning; having a reference
        counter of DIT requests and getting it out of sync.
    
    In a more sophisticated programming language, it might be possible to
    avoid the risk in #2 by cleverness with the type system. For example,
    in Rust, you could have a zero-sized type that acts as a proof token
    for DIT being enabled (it would be constructed by a function that also
    sets DIT, have a Drop implementation that clears DIT, and be !Send so
    you couldn't use it in a thread other than the one where DIT was set),
    and then you could require all the actual crypto functions to take a
    DitToken as an extra parameter, at zero runtime cost. Then "oops I
    forgot to set DIT around this piece of crypto" would become a compile
    error. Even so, you'd have to take some care with coroutine-structured
    code (what happens if a Rust async function yields while holding a DIT
    token?) and with nesting (if you have two DIT tokens, you don't want
    dropping the inner one to clear DIT while the outer one is still there
    to wrongly convince callees that it's set). Maybe in Rust you could
    get this all to work reliably. But not in C!
    
    DIT is an optional feature of the Arm architecture, so we must first
    test to see if it's supported. This is done the same way as we already
    do for the various Arm crypto accelerators: on ELF-based systems,
    check the appropriate bit in the 'hwcap' words in the ELF aux vector;
    on Mac, look for an appropriate sysctl flag.
    
    On Windows I don't know of a way to query the DIT feature, _or_ of a
    way to write the necessary enabling instruction in an MSVC-compatible
    way. I've _heard_ that it might not be necessary, because Windows
    might just turn on DIT unconditionally and leave it on, in an even
    more extreme version of my own strategy. I don't have a source for
    that - I heard it by word of mouth - but I _hope_ it's true, because
    that would suit me very well! Certainly I can't write code to enable
    DIT without knowing (a) how to do it, (b) how to know if it's safe.
    Nonetheless, I've put the enable_dit() call in all the right places in
    the Windows main programs as well as the Unix and cross-platform code,
    so that if I later find out that I _can_ put in an explicit enable of
    DIT in some way, I'll only have to arrange to set HAVE_ARM_DIT and
    compile the enable_dit() function appropriately.

 cmake/cmake.h.in                 |  1 +
 cmdgen.c                         |  2 ++
 crypto/CMakeLists.txt            |  7 +++++++
 crypto/enable_dit.c              | 24 ++++++++++++++++++++++++
 proxy/cproxy.c                   |  3 +++
 pscp.c                           |  1 +
 psftp.c                          |  1 +
 ssh.h                            | 11 +++++++++++
 ssh/ssh.c                        |  2 ++
 sshrand.c                        |  4 +++-
 stubs/no-dit.c                   | 15 +++++++++++++++
 test/testcrypt.c                 |  2 ++
 test/testsc.c                    |  5 +++++
 unix/CMakeLists.txt              |  3 +++
 unix/askpass.c                   |  2 ++
 unix/main-gtk-application.c      |  3 +++
 unix/main-gtk-simple.c           |  2 ++
 unix/pageant.c                   |  2 ++
 unix/plink.c                     |  2 ++
 unix/psusan.c                    |  2 ++
 unix/putty.c                     |  1 +
 unix/sftp.c                      |  1 +
 unix/uppity.c                    |  2 ++
 unix/utils/arm_arch_queries.c    | 15 +++++++++++++++
 windows/CMakeLists.txt           |  2 ++
 windows/pageant.c                |  1 +
 windows/plink.c                  |  1 +
 windows/puttygen.c               |  1 +
 windows/sftp.c                   |  1 +
 windows/utils/arm_arch_queries.c |  8 ++++++++
 windows/window.c                 |  1 +
 31 files changed, 127 insertions(+), 1 deletion(-)



More information about the tartarus-commits mailing list