-
Notifications
You must be signed in to change notification settings - Fork 360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SSHD-506] Add support for RFC 5647 #132
Conversation
This is a work in progress that does not work yet, and the API changes to Cipher/CipherInformation are still in flux. Signed-off-by: Matt Sicker <boards@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very promising - see a few minor comments. Please make sure you run the full mvn clean install
(I see there are some Checkstyle issues...)
sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
Outdated
Show resolved
Hide resolved
sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
Outdated
Show resolved
Hide resolved
sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
Outdated
Show resolved
Hide resolved
sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseGCMCipher.java
Outdated
Show resolved
Hide resolved
sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseGCMCipher.java
Outdated
Show resolved
Hide resolved
sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseGCMCipher.java
Outdated
Show resolved
Hide resolved
sshd-common/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
Outdated
Show resolved
Hide resolved
sshd-common/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
Show resolved
Hide resolved
Signed-off-by: Matt Sicker <boards@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we also add these ciphers to the default ones used by the client/server (see their respective builder(s)) ? If so, at which priority ?
sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseAEADCipher.java
Outdated
Show resolved
Hide resolved
Yes, these should be added as defaults once they're working. Based on how OpenSSH is distributed nowadays, these should the highest priority ciphers. I've seen ChaCha20 taking precedence as well, though that's not supported here yet (plus requires either Java 11 or Bouncycastle or some other library). |
Signed-off-by: Matt Sicker <boards@gmail.com>
So it seems I've created an incompatible implementation with OpenSSH at the moment, but it talks to itself. Still debugging this before this can move anywhere. |
This seems to match what OpenSSH is doing. I think.
protected AlgorithmParameterSpec getNextAlgorithmParameters() { | ||
Cipher cipher = getCipherInstance(); | ||
Buffer iv = new ByteArrayBuffer(cipher.getIV()); | ||
iv.rpos(Integer.BYTES); | ||
long ic = iv.getLong(); | ||
ic = (ic + 1) & 0x0ffffffffL; | ||
iv.wpos(Integer.BYTES); | ||
iv.putLong(ic); | ||
return new GCMParameterSpec(getAuthenticationTagSize() * Byte.SIZE, iv.array()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty expensive in memory - every time it is called (which is for every packet) a new byte[]
(cipher.getIv()
returns a clone), new Buffer
and new GCMParameterSpec
instance is created. Can we do something about it ?
Moreover, this code is exactly the same as initializeAlgorithmParameters
except it does +1
instead of -1
- perhaps we could use an internal (protected) updateAlgorithmParameters(byte[] iv, long delta)
and call it once with +1
and once with -1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we can avoid creating the Buffer
since all the code does is replace an 8-byte section of the IV at offset 4:
byte[] iv = cipher.getIV();
// Need to write decodeLong but it should be similar to decodeInt in the same class
// can use the code of Buffer#getLong as base
long ic = KeyEntryResolver.decodeLong(iv, Integer.BYTES, iv.length - Integer.BYTES);
ic = (ic + delta) & 0x0ffffffffL;
// Need to write it - can use the code of Buffer#putLong as base
KeyEntryResolver.encodeLong(iv, ic, Integer.BYTES, iv.length - Integer.BYTES);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh, nice find. Yes, we just need to update the 8-byte section of the buffer. The update algorithm parameters API idea sounds good to me; it's more in line with how OpenSSH is structured, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the GCMParameterSpec
based on this link we might be able to execute an ugly hack via reflection API and manipulate the internal IV data directly instead of creating a new instance every time... will need to think about it some more - but only after this code is working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I came up with a better idea: extend the class and don't clone the IV. Less safe, but doesn't continually create garbage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've mostly optimized away all the garbage here. I do an initial IV clone when calling the public init
method, but that's the only time. I don't see the IV being cloned further by the Cipher
classes that use GCMParameterSpec
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, I optimized it so much, both AES/GCM engines can't tell that the IV changes between invocations and throw an exception. Nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't figure out how to get the engine to consider the IV as different, so I still have some clone calls happening, but much less waste than before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into the internal implementation of the cipher engine, and it makes its own clone regardless of what we do, so this seems to be about as optimal as I can get it without digging into Bouncycastle internals or something similar.
Signed-off-by: Matt Sicker <boards@gmail.com>
Signed-off-by: Matt Sicker <boards@gmail.com>
Signed-off-by: Matt Sicker <boards@gmail.com>
Forgot about this Signed-off-by: Matt Sicker <boards@gmail.com>
The tests all pass on my machine. I'm not sure what's going on with the failing one on here. |
That's OK - if you feel the code is ready as far as you are concerned, let me know. Once I have examined it and successfully ran a full That being said, please run some tests with OpenSSH clients/servers that support these ciphers as well as some popular applications such as Putty, WinSCP, FileZilla |
sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseGCMCipher.java
Outdated
Show resolved
Hide resolved
I still need to do some manual integration testing. Thanks for the
suggestions since OpenSSH was the only thing I remembered exists.
This may be on hold for a week or so as I’m on vacation this week.
On Sun, May 24, 2020 at 11:11 Lyor Goldstein ***@***.***> wrote:
The tests all pass on my machine. I'm not sure what's going on with the
failing one on here.
That's OK - if you feel the code is ready as far as you are concerned, let
me know. Once I have examined it and successfully ran a full mvn clean
install on my machine I am willing to merge it. Our Travis builds are not
yet 100% stable so if they fail but the tests succeed on my machine I
usually consider the code safe to merge.
That being said, please run some tests with OpenSSH clients/servers that
support these ciphers as well as some popular applications such as *Putty,
WinSCP, FileZilla*
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#132 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGBF275RDGO6M5CYXBHUJLRTFBLFANCNFSM4NEHJDRQ>
.
--
Matt Sicker <boards@gmail.com>
|
Enjoy your vacation - no hurry - when you feel ready I will be happy to review... |
I merged the latest changes from master and did some basic smoketesting using the following: Server: OpenSSH_8.1p1, LibreSSL 2.7.3 I'll do some more testing in the opposite direction as well as some cleanups. |
Also tested with FileZilla so far. It even defaulted to selecting aes256-gcm! Seems to work. |
Signed-off-by: Matt Sicker <boards@gmail.com>
I can't seem to find any official documentation on what the RFC 5647 cipher names are supposed to be unless they meant to literally use Edit: neither FileZilla nor OpenSSH even reference RFC 5647. Is this the first implementation of the spec in 11 years? |
Based on what I'm finding online, it does seem like the RFC specifies the all caps version. I'm going to try adding that as well. |
This simplifies the new AEAD API a bit based on usage. Signed-off-by: Matt Sicker <boards@gmail.com>
Signed-off-by: Matt Sicker <boards@gmail.com>
I also tested this with dropbear so far, all good. Also tested with PuTTY (on macOS). Feel free to test in any other platforms you're concerned with, but I feel fairly confident with the patch. |
I will do so some time soon - does this mean that I can merge this patch if I am satisfied with it ? |
sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseGCMCipher.java
Outdated
Show resolved
Hide resolved
sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseGCMCipher.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Matt Sicker <boards@gmail.com>
Yes, I think so. I'm a little iffy on the |
We'll cross that bridge when we come to it - refactoring is not a dirty word in this project |
Tested on an RPi4 (arm64), works fine. |
Signed-off-by: Matt Sicker <boards@gmail.com>
Signed-off-by: Matt Sicker <boards@gmail.com>
While working on SSHD-1017, I discovered a couple refactoring improvements to add here. |
Seems like it is still work in progress - I will hold off testing it and merging into master branch for now |
Once I’ve figured out the ChaCha part, I think this PR will be ready to go.
I’ll add that cipher in a separate PR, but I’m trying to make the changes
required for both ciphers to be as similar and minimal as possible. I’ll
let you know once this is final again!
On Sat, Jun 27, 2020 at 01:12 Lyor Goldstein ***@***.***> wrote:
Seems like it is still work in progress - I will hold off testing it and
merging into master branch for now
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#132 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGBF23JQGPESOSGRSUTI6DRYWEV5ANCNFSM4NEHJDRQ>
.
--
Matt Sicker <boards@gmail.com>
|
Great - this contribution is very important so thank you for the effort... |
Sorry to bother you, but have you made any progress ? The reason I ask is that I would like to start deprecating unsafe settings (see SSHD-1004) - and that includes some ciphers. Since this may require some non-trivial changes, I would prefer to do it after having added these ciphers. If the work on ChaCha seems to take a short while (let's say another 1-2 weeks) then I can wait. Otherwise, I would rather incorporate the GCM code into the master branch. |
Oh hey, sorry about that. This branch is basically ready at this point as I got stuck trying to get ChaCha20-Poly1305 to work properly. From what I recall, I already updated the code in this branch to match the same style I was hoping to use for that cipher (particularly by making the ChaCha version of |
Thanks - then I'll start merging it and testing... |
Committed dc73e260f with many thanks - you can close the PR |
Thanks! |
* Implement AES-GCM cipher support Fixes #217. A port of AES-GCM cipher support from Apache MINA-SSHD, based on apache/mina-sshd#132. Included tests for decoding SSH packets sent from Apache MINA-SSHD and OpenSSH (Version 7.9p1 as used by Debian 10). Manual tests also done on OpenSSH server 7.9p1 running Debian 10 with its available ciphers, including 3des-cbc, aes128-cbc, aes192-cbc, aes256-cbc, aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com and aes256-gcm@openssh.com. * Changes per PR feedback - Fixed variable/statement whitespaces and add back missing braces per coding standard requirement - Moved Buffer.putLong() and Buffer.getLong() into GcmCipher.CounterGCMParameterSpec since it's the only user - Moved BaseCipher.authSize into GcmCipher since it is the only cipher that would return a non-zero. BaseCipher will keep return 0 instead - Made BaseCipher.cipher protected instead of making it publicly accessible - Combined the three decoding modes in Decoder.decode() into one single method, to reduce code duplication - Added integration test for the ciphers, along with the newly implemented AES-GCM ciphers
This is a work in progress that does not work yet, and the API changes to Cipher/CipherInformation are still in flux.
I've been testing this by changing
CoreTestSupportUtils
to set up clients and servers with only the AES/GCM cipher enabled. So far, I've had varying problems with getting this to work, and I've been using OpenSSH as a comparison to no further help. For reference, here are the relevant source files:EVP_
functions)