[mirror] Go supplementary cryptography libraries
Перейти к файлу
Filippo Valsorda 4d399097f0 ssh: fix diffie-hellman-group-exchange g and K bounds checks
The previous code

	if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {

deobfuscates to the classic mistake

    if g <= 1 && g >= p - 1 {

which is never true.

What the code actually intended to do is

	if gex.g.Cmp(one) != 1 || gex.g.Cmp(pMinusOne) != -1 {

or more readably and consistently with the diffieHellman method

	if gex.g.Cmp(one) <= 0 || gex.g.Cmp(pMinusOne) >= 0 {

Now, is this a security issue? The incorrect checks apply to g and k,
but not what we call Y and the spec calls f. RFC 4419 says:

   Either side MUST NOT send or accept e or f values that are not in the
   range [1, p-1].  If this condition is violated, the key exchange
   fails.  To prevent confinement attacks, they MUST accept the shared
   secret K only if 1 < K < p - 1.

Note that RFC 8268, Section 4 updates the equivalent RFC 4253 statement
(although not the RFC 4419 one) about e and f, but we are already doing
the correct full check there.

      DH Public Key values MUST be checked and both conditions:

         1 < e < p-1

         1 < f < p-1

      MUST be true.  Values not within these bounds MUST NOT be sent or
      accepted by either side.  If either one of these conditions is
      violated, then the key exchange fails.

   This simple check ensures that:

   o  The remote peer behaves properly.

   o  The local system is not forced into the two-element subgroup.

The check on K seems like a proxy for checking a number of ways to fix
the DH output (for example by manipulating g) to one of 0, 1, or -1.
This should not be meaningful to security for two reasons:

   - all parameters end up in the "transcript" hash that will get signed
     by the server's host key, and if the attacker controls the host
     key's signature, they have the ability to MitM without resorting to
     confinement attacks

   - the client secret is ephemeral, so leaking bits of it by forcing it
     into small sub-groups does not gain the attacker anything, as the
     secret does not get reused

Indeed, this is the same explanation of why it's ok not to check that p
is indeed a (safe) prime, which even OpenSSH omits. Building an
equivalent attack by manipulating p instead of g is left as an exercise
to the reader.

For the future, this is a case study in why we should not add complexity
even when it looks easy enough to do. CL 174257 added the
diffie-hellman-group-exchange kex. That introduced a data race (arguably
a security issue), which was fixed in CL 222078. Then it was too slow,
which led to CL 252337 that removed the primalty check, which required a
full analysis of whether it's safe to skip it, and checking against
other implementations. Now we find there's a bug and we have to do
another security analysis that not even the RFC bothered to do in order
to decide if it's a security issue. My decision in
https://github.com/golang/go/issues/17230#issuecomment-489163656
does not look like the right one in hindsight.

While at it, clean up the code some

   - drop useless bit size bounds logic in the server stub that get
     ignored by the rest of the function

   - make p and g local variables instead of method fields, since they
     are not persistent state (this was originally a data race which was
     fixed in CL 222078 by making Client not a pointer receiver)

Updates golang/go#17230

Change-Id: I4b1c68537109f627ccd75ec381dcfab57ce1768c
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392015
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-03-14 23:46:39 +00:00
acme acme/autocert: skip renewal tests broken on windows/arm64 2022-02-14 20:07:02 +00:00
argon2 all: add //go:build lines to assembly files 2021-05-13 12:29:33 +00:00
bcrypt bcrypt: benchmark defaults 2018-10-30 02:28:21 +00:00
blake2b all: add //go:build lines to assembly files 2021-05-13 12:29:33 +00:00
blake2s all: add //go:build lines to assembly files 2021-05-13 12:29:33 +00:00
blowfish all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
bn256 bn256: fix String methods when g.p == nil 2019-02-22 23:45:11 +00:00
cast5 all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
chacha20 all: add //go:build lines to assembly files 2021-05-13 12:29:33 +00:00
chacha20poly1305 poly1305: deprecate public package 2021-09-15 21:47:49 +00:00
cryptobyte cryptobyte: fix parsing of large ASN.1 OIDs 2021-12-15 15:39:01 +00:00
curve25519 curve25519/internal/field: fix generator module reference to x/crypto 2021-05-13 16:48:29 +00:00
ed25519 ed25519: drop Go 1.12 compatibility 2022-02-08 05:03:32 +00:00
hkdf hkdf: add Extract and Expand 2018-10-25 21:37:31 +00:00
internal internal/wycheproof: skip on builders with flaky network connections 2021-12-09 19:36:57 +00:00
md4 all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
nacl poly1305: deprecate public package 2021-09-15 21:47:49 +00:00
ocsp ocsp: fix typo 2022-02-08 23:39:18 +00:00
openpgp openpgp: fix deprecation message 2021-08-13 21:11:28 +00:00
otr all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
pbkdf2 pbkdf2: add benchmarks 2017-12-19 04:11:29 +00:00
pkcs12 pkcs12: drop PKCS#12 attributes with unknown OIDs 2020-07-09 23:00:13 +00:00
poly1305 poly1305: deprecate public package 2021-09-15 21:47:49 +00:00
ripemd160 all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
salsa20 all: add //go:build lines to assembly files 2021-05-13 12:29:33 +00:00
scrypt scrypt: use encoding/binary to simplify smix 2021-03-17 15:28:58 +00:00
sha3 acme, sha3, ssh: fix the typos 2022-02-09 15:53:12 +00:00
ssh ssh: fix diffie-hellman-group-exchange g and K bounds checks 2022-03-14 23:46:39 +00:00
tea all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
twofish all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
xtea all: deprecate broken and legacy packages 2019-02-22 23:25:34 +00:00
xts xts: reduce tweak allocations 2019-02-22 23:57:06 +00:00
.gitattributes crypto: copying .gitattributes to all subrepositories 2014-12-23 06:54:52 +00:00
.gitignore gitignore: remove obsolete reference to .hgignore in comment 2020-03-20 18:11:02 +00:00
AUTHORS all: use HTTPS for links that support it 2017-06-29 04:21:55 +00:00
CONTRIBUTING.md CONTRIBUTING.md: remove note about not accepting Pull Requests 2018-03-14 18:02:59 +00:00
CONTRIBUTORS all: use HTTPS for links that support it 2017-06-29 04:21:55 +00:00
LICENSE LICENSE: add 2012-03-17 15:19:30 +11:00
PATENTS go.crypto: add PATENTS file to the subrepo. 2012-04-16 11:25:08 +10:00
README.md README.md: add badge to pkg.go.dev 2020-12-08 17:14:46 +00:00
codereview.cfg crypto: add codereview.cfg 2015-03-18 17:04:25 +00:00
go.mod all: upgrade x/net to latest 2021-11-17 18:39:48 +00:00
go.sum all: upgrade x/net to latest 2021-11-17 18:39:48 +00:00

README.md

Go Cryptography

Go Reference

This repository holds supplementary Go cryptography libraries.

Download/Install

The easiest way to install is to run go get -u golang.org/x/crypto/.... You can also manually git clone the repository to $GOPATH/src/golang.org/x/crypto.

Report Issues / Send Patches

This repository uses Gerrit for code changes. To learn how to submit changes to this repository, see https://golang.org/doc/contribute.html.

The main issue tracker for the crypto repository is located at https://github.com/golang/go/issues. Prefix your issue with "x/crypto:" in the subject line, so it is easy to find.

Note that contributions to the cryptography package receive additional scrutiny due to their sensitive nature. Patches may take longer than normal to receive feedback.