Skip to content
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

supporting X25519 and X448 in the IES style. #205

Closed
wants to merge 18 commits into from

Conversation

kazu-yamamoto
Copy link
Collaborator

This implements #204.

First of all, sorry for the jumbo patch. I could not divide this into small pieces.

For the extension name:

  • RFC 4492 and bis use NamedCurve
  • TLS 1.3 uses NamedGroup since DH is integrated

I followed the TLS 1.3 way.

To remove duplicated NIST curves and support X25519 and X448:

  • Extension.EC is deleted
  • Extension is modified
  • Crypto.Types is introduced

To integrate NIST curves and X*:

  • Crypto.IES is introduced based on ECIES API of cryptonite
  • Other ECDH related modules uses the APIs defined in Crypto.IES

Note that DH remained as is.

@kazu-yamamoto
Copy link
Collaborator Author

I will try to divide this jumbo patch. Just a moment.

@kazu-yamamoto
Copy link
Collaborator Author

Sorry. I gave up. Everything is related and I cannot divide it into pieces.

@ocheron
Copy link
Contributor

ocheron commented Apr 7, 2017

Some first items I looked yesterday:

  • my feeling is that removing generateECDHE changes the entropy source from the TLS context to IO, if confirmed this should be reverted
  • groupGetShared should return a Maybe instead of calling error
  • function processClientKeyXchg should use throwCore instead of error
  • we may want to reorder availableGroups so that the head of intersection is the maximum strength like before

I'll try to continue reviewing during the week-end.

@kazu-yamamoto
Copy link
Collaborator Author

my feeling is that removing generateECDHE changes the entropy source from the TLS context to IO, if confirmed this should be reverted

If this is true, this is a fundamental problem between cryptonite and tls.
@vincenthz What do you think?

@kazu-yamamoto
Copy link
Collaborator Author

generateECDHE uses:

withRNG :: MonadPseudoRandom StateRNG a -> TLSSt a
withRNG f = do
    st <- get
    let (a,rng') = withTLSRNG (stRandomGen st) f
    put (st { stRandomGen = rng' })
    return a

deriveEncrypt uses getEntropy:

getEntropy :: ByteArray byteArray => Int -> IO byteArray
getEntropy n = do
    backends <- catMaybes `fmap` sequence supportedBackends
    B.alloc n (replenish n backends)

@kazu-yamamoto
Copy link
Collaborator Author

we may want to reorder availableGroups so that the head of intersection is the maximum strength like before

In my TLS 1.3 branch, supportedGroups :: [Group] is already implemented. This variable controls the preference order.

If we define supportedEllipticCurves :: [NamedCurve], its value would be [SEC SEC_p256r1, SEC SEC_p384r1, SEC SEC_p521r1]. This is really strange to users. That's why I simplified NamedCurve to Group.

@ocheron
Copy link
Contributor

ocheron commented Apr 8, 2017

I don't see any fundamental problem other than the one we had a solution for. Upon closer inspection you removed the call to withRNG, so now the MonadRandom-based crypto runs directly in the IO monad instead of MonadPseudoRandom StateRNG like before. We don't want all concurrent TLS contexts to compete on the same global DRG.

I'm OK for not implementing supportedGroups in this PR, as today we don't have supportedEllipticCurves. We'll obviously want to implement only one, and after your PR that will be supportedGroups. Still for now the list intersection will favor the order from the first argument. So unless there is something I missed, your PR chooses the minimum strength. And that's a change of behavior easy to avoid by reversing the list.

@ocheron
Copy link
Contributor

ocheron commented Apr 8, 2017

Here's my last comment about the detailed implementation: you moved functions related to TLS protocol (toGroup, fromGroup) into the "Crypto" modules but this is not related to crypto and would be best elsewhere, like module Struct or Extension.

Some ideas for a naming more consistent, tell me what you think:

  • extensionID_NegotiatedGroups instead of extensionID_Groups ?
  • ClientGroupSuggest instead of ClientEllipticCurveSuggest ?
  • availableECDHGroups instead of availableGroups ?

I think that concludes my review.

@kazu-yamamoto
Copy link
Collaborator Author

extensionID_NegotiatedGroups instead of extensionID_Groups ?

Done.

ClientGroupSuggest instead of ClientEllipticCurveSuggest ?

Done.

@kazu-yamamoto
Copy link
Collaborator Author

availableECDHGroups instead of availableGroups ?

Group includes DH. So, I want to keep as is.

@kazu-yamamoto
Copy link
Collaborator Author

Here's my last comment about the detailed implementation: you moved functions related to TLS protocol (toGroup, fromGroup) into the "Crypto" modules but this is not related to crypto and would be best elsewhere, like module Struct or Extension.

Now, it is Extension.Group.

@kazu-yamamoto
Copy link
Collaborator Author

supportedGroups has been implemented.

@kazu-yamamoto
Copy link
Collaborator Author

I don't see any fundamental problem other than the one we had a solution for. Upon closer inspection you removed the call to withRNG, so now the MonadRandom-based crypto runs directly in the IO monad instead of MonadPseudoRandom StateRNG like before. We don't want all concurrent TLS contexts to compete on the same global DRG.

Thank you for letting me know this. I have implemented this.

@kazu-yamamoto
Copy link
Collaborator Author

@ocheron I believe that all issues have been resolved. Please review this PR again.

@kazu-yamamoto
Copy link
Collaborator Author

I noticed that cabal test sometimes fails.
I have created a minimum test case to reproduce this and try to fix it tomorrow.
Probably, it's relating to ECDHE.

@ocheron
Copy link
Contributor

ocheron commented Apr 10, 2017

About modules "Crypto" vs "Extension": I was referring only to functions fromGroup/toGroup.
The data type Group should stay in the crypto modules, possibly in Crypto.IES itself.

OK for adding supportedGroups. You didn't explain why you chose the minimum strength.
I see a reason (cryptonite P256 code) and also it's configurable, so that's fine.
But please note that we will still need:

  1. cipherAllowed checks to prevent the "no common groups" error from happening
  2. test cases with non-default supportedGroups

@ocheron
Copy link
Contributor

ocheron commented Apr 10, 2017

The test failure looks like a segmentation fault related to P256.

@kazu-yamamoto
Copy link
Collaborator Author

If I add trace to Crypto.PubKey.ECC.P256.pointDh, I cannot reproduce this problem.
There might be a race condition.
I suspect that the C backend of P256 is not thread-safe.

Cc: @vincenthz

@kazu-yamamoto
Copy link
Collaborator Author

Here is a small test to reproduce this: https://gist.github.com/kazu-yamamoto/25b7b4ee7884e30a93355e20f5efe0ac

@kazu-yamamoto
Copy link
Collaborator Author

It seems to me that scalarGenerate causes segfault.

@kazu-yamamoto
Copy link
Collaborator Author

getRandomBytes causes segufault.
Due to a lack of random source?

@kazu-yamamoto
Copy link
Collaborator Author

OK. I think that I have resolved all issues.

@ocheron
Copy link
Contributor

ocheron commented Apr 11, 2017

We're getting closer... but I see you tried to optimize things by storing the group in the TLS state.

I'd rather have the same two-step process than signature_algorithms (i.e. functions hashAndSignaturesInCommon and decideHash).

It's probably a bit slower, but more organized. The group is already stored in ServerECDHParams in handshake state. We don't want another copy in the TLS state, especially if it's used only for the duration of one message (ServerHello).

@ocheron
Copy link
Contributor

ocheron commented Apr 11, 2017

Also I believe the FIXME in handshakeServerWith has been addressed (or at least the "elliptic curve" part).

👍 for the test suite and the module structure.

@kazu-yamamoto
Copy link
Collaborator Author

I think I have done everything.

Copy link
Contributor

@ocheron ocheron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

kazu-yamamoto added a commit to kazu-yamamoto/hs-tls that referenced this pull request Apr 12, 2017
@kazu-yamamoto
Copy link
Collaborator Author

Thank you for your patient review.
I have merged this PR.

@kazu-yamamoto kazu-yamamoto deleted the group branch April 19, 2017 07:31
ocheron added a commit that referenced this pull request May 1, 2017
@kazu-yamamoto kazu-yamamoto mentioned this pull request May 26, 2017
15 tasks
@kazu-yamamoto kazu-yamamoto mentioned this pull request Sep 13, 2018
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants