]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.boringcrypto] crypto/..., go/build: align deps test with standard rules
authorRuss Cox <rsc@golang.org>
Wed, 27 Apr 2022 13:02:53 +0000 (09:02 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 29 Apr 2022 14:23:28 +0000 (14:23 +0000)
One annoying difference between dev.boringcrypto and master is that
there is not a clear separation between low-level (math/big-free)
crypto and high-level crypto, because crypto/internal/boring imports
both encoding/asn1 and math/big.

This CL removes both those problematic imports and aligns the
dependency rules in the go/build test with the ones in the main
branch.

To remove encoding/asn1, the crypto/internal/boring APIs change to
accepting and returning encoded ASN.1, leaving crypto/ecdsa to do the
marshaling and unmarshaling, which it already contains code to do.

To remove math/big, the crypto/internal/boring package defines
type BigInt []uint, which is the same representation as a big.Int's
internal storage. The new package crypto/internal/boring/bbig provides
conversions between BigInt and *big.Int. The boring package can then
be in the low-level crypto set, and any package needing to use bignum
APIs (necessarily in the high-level crypto set) can import bbig to
convert.

To simplify everything we hide from the test the fact that
crypto/internal/boring imports cgo. Better to pretend it doesn't and
keep the prohibitions that other packages like crypto/aes must not use
cgo (outside of BoringCrypto).

$ git diff origin/master src/go/build/deps_test.go
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index 6ce872e297..a63979cc93 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -402,9 +402,13 @@ var depsRules = `
  NET, log
  < net/mail;

+ NONE < crypto/internal/boring/sig;
+ sync/atomic < crypto/internal/boring/fipstls;
+ crypto/internal/boring/sig, crypto/internal/boring/fipstls < crypto/tls/fipsonly;
+
  # CRYPTO is core crypto algorithms - no cgo, fmt, net.
  # Unfortunately, stuck with reflect via encoding/binary.
- encoding/binary, golang.org/x/sys/cpu, hash
+ crypto/internal/boring/sig, encoding/binary, golang.org/x/sys/cpu, hash
  < crypto
  < crypto/subtle
  < crypto/internal/subtle
@@ -413,6 +417,8 @@ var depsRules = `
  < crypto/ed25519/internal/edwards25519/field, golang.org/x/crypto/curve25519/internal/field
  < crypto/ed25519/internal/edwards25519
  < crypto/cipher
+ < crypto/internal/boring
+ < crypto/boring
  < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
    crypto/sha1, crypto/sha256, crypto/sha512
  < CRYPTO;
@@ -421,6 +427,7 @@ var depsRules = `

  # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok.
  CRYPTO, FMT, math/big, embed
+ < crypto/internal/boring/bbig
  < crypto/rand
  < crypto/internal/randutil
  < crypto/ed25519
@@ -443,7 +450,8 @@ var depsRules = `
  < golang.org/x/crypto/hkdf
  < crypto/x509/internal/macos
  < crypto/x509/pkix
- < crypto/x509
+ < crypto/x509;
+ crypto/internal/boring/fipstls, crypto/x509
  < crypto/tls;

  # crypto-aware packages
@@ -653,6 +661,9 @@ func findImports(pkg string) ([]string, error) {
  }
  var imports []string
  var haveImport = map[string]bool{}
+ if pkg == "crypto/internal/boring" {
+ haveImport["C"] = true // kludge: prevent C from appearing in crypto/internal/boring imports
+ }
  fset := token.NewFileSet()
  for _, file := range files {
  name := file.Name()

For #51940.

Change-Id: I26fc752484310d77d22adb06495120a361568d04
Reviewed-on: https://go-review.googlesource.com/c/go/+/395877
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>

src/crypto/ecdsa/boring.go
src/crypto/ecdsa/ecdsa.go
src/crypto/internal/boring/bbig/big.go [new file with mode: 0644]
src/crypto/internal/boring/boring.go
src/crypto/internal/boring/doc.go
src/crypto/internal/boring/ecdsa.go
src/crypto/internal/boring/notboring.go
src/crypto/internal/boring/rsa.go
src/crypto/rsa/boring.go
src/crypto/rsa/rsa.go
src/go/build/deps_test.go

index d7de5c96e5387759f89e0c3332c4531ac8c74476..1529de3f2bc2a43715c7fc929555283dabedc95e 100644 (file)
@@ -8,6 +8,7 @@ package ecdsa
 
 import (
        "crypto/internal/boring"
+       "crypto/internal/boring/bbig"
        "math/big"
        "sync/atomic"
        "unsafe"
@@ -43,7 +44,7 @@ func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
 
        b = new(boringPub)
        b.orig = copyPublicKey(pub)
-       key, err := boring.NewPublicKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y)
+       key, err := boring.NewPublicKeyECDSA(b.orig.Curve.Params().Name, bbig.Enc(b.orig.X), bbig.Enc(b.orig.Y))
        if err != nil {
                return nil, err
        }
@@ -65,7 +66,7 @@ func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
 
        b = new(boringPriv)
        b.orig = copyPrivateKey(priv)
-       key, err := boring.NewPrivateKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y, b.orig.D)
+       key, err := boring.NewPrivateKeyECDSA(b.orig.Curve.Params().Name, bbig.Enc(b.orig.X), bbig.Enc(b.orig.Y), bbig.Enc(b.orig.D))
        if err != nil {
                return nil, err
        }
index d3ae456b844a4f75ecb5effd64d7bb5511906c1f..efc5dd506737c069e32c1fc1a442c0876e10b26d 100644 (file)
@@ -24,6 +24,7 @@ import (
        "crypto/aes"
        "crypto/cipher"
        "crypto/elliptic"
+       "crypto/internal/boring/bbig"
        "crypto/internal/randutil"
        "crypto/sha512"
        "errors"
@@ -166,7 +167,7 @@ func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
                if err != nil {
                        return nil, err
                }
-               return &PrivateKey{PublicKey: PublicKey{Curve: c, X: x, Y: y}, D: d}, nil
+               return &PrivateKey{PublicKey: PublicKey{Curve: c, X: bbig.Dec(x), Y: bbig.Dec(y)}, D: bbig.Dec(d)}, nil
        }
        boring.UnreachableExceptTests()
 
@@ -226,7 +227,21 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
                if err != nil {
                        return nil, nil, err
                }
-               return boring.SignECDSA(b, hash)
+               sig, err := boring.SignMarshalECDSA(b, hash)
+               if err != nil {
+                       return nil, nil, err
+               }
+               var r, s big.Int
+               var inner cryptobyte.String
+               input := cryptobyte.String(sig)
+               if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
+                       !input.Empty() ||
+                       !inner.ReadASN1Integer(&r) ||
+                       !inner.ReadASN1Integer(&s) ||
+                       !inner.Empty() {
+                       return nil, nil, errors.New("invalid ASN.1 from boringcrypto")
+               }
+               return &r, &s, nil
        }
        boring.UnreachableExceptTests()
 
@@ -327,11 +342,20 @@ func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
 // use VerifyASN1 instead of dealing directly with r, s.
 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
        if boring.Enabled {
-               b, err := boringPublicKey(pub)
+               key, err := boringPublicKey(pub)
+               if err != nil {
+                       return false
+               }
+               var b cryptobyte.Builder
+               b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+                       b.AddASN1BigInt(r)
+                       b.AddASN1BigInt(s)
+               })
+               sig, err := b.Bytes()
                if err != nil {
                        return false
                }
-               return boring.VerifyECDSA(b, hash, r, s)
+               return boring.VerifyECDSA(key, hash, sig)
        }
        boring.UnreachableExceptTests()
 
diff --git a/src/crypto/internal/boring/bbig/big.go b/src/crypto/internal/boring/bbig/big.go
new file mode 100644 (file)
index 0000000..5ce4697
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bbig
+
+import (
+       "crypto/internal/boring"
+       "math/big"
+       "unsafe"
+)
+
+func Enc(b *big.Int) boring.BigInt {
+       if b == nil {
+               return nil
+       }
+       x := b.Bits()
+       if len(x) == 0 {
+               return boring.BigInt{}
+       }
+       return unsafe.Slice((*uint)(&x[0]), len(x))
+}
+
+func Dec(b boring.BigInt) *big.Int {
+       if b == nil {
+               return nil
+       }
+       if len(b) == 0 {
+               return new(big.Int)
+       }
+       x := unsafe.Slice((*big.Word)(&b[0]), len(b))
+       return new(big.Int).SetBits(x)
+}
index dd9eac569b84e587ba5e9df4259f4793d6825b2d..d46166e4e16e694020d1482e2e0a85a09186dfc9 100644 (file)
@@ -17,7 +17,6 @@ import "C"
 import (
        "crypto/internal/boring/sig"
        _ "crypto/internal/boring/syso"
-       "math/big"
        "math/bits"
        "unsafe"
 )
@@ -60,7 +59,7 @@ type fail string
 
 func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }
 
-func wbase(b []big.Word) *C.uint8_t {
+func wbase(b BigInt) *C.uint8_t {
        if len(b) == 0 {
                return nil
        }
@@ -69,20 +68,19 @@ func wbase(b []big.Word) *C.uint8_t {
 
 const wordBytes = bits.UintSize / 8
 
-func bigToBN(x *big.Int) *C.GO_BIGNUM {
-       raw := x.Bits()
-       return C._goboringcrypto_BN_le2bn(wbase(raw), C.size_t(len(raw)*wordBytes), nil)
+func bigToBN(x BigInt) *C.GO_BIGNUM {
+       return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil)
 }
 
-func bnToBig(bn *C.GO_BIGNUM) *big.Int {
-       raw := make([]big.Word, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
-       if C._goboringcrypto_BN_bn2le_padded(wbase(raw), C.size_t(len(raw)*wordBytes), bn) == 0 {
+func bnToBig(bn *C.GO_BIGNUM) BigInt {
+       x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
+       if C._goboringcrypto_BN_bn2le_padded(wbase(x), C.size_t(len(x)*wordBytes), bn) == 0 {
                panic("boringcrypto: bignum conversion failed")
        }
-       return new(big.Int).SetBits(raw)
+       return x
 }
 
-func bigToBn(bnp **C.GO_BIGNUM, b *big.Int) bool {
+func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool {
        if *bnp != nil {
                C._goboringcrypto_BN_free(*bnp)
                *bnp = nil
index 64f41e3c823e8437e00629740022ea0ddd06ae01..6060fe5951afb53c9387381c95ef20000187f4d7 100644 (file)
@@ -12,3 +12,8 @@ package boring
 //
 // BoringCrypto is only available on linux/amd64 systems.
 const Enabled = available
+
+// A BigInt is the raw words from a BigInt.
+// This definition allows us to avoid importing math/big.
+// Conversion between BigInt and *big.Int is in crypto/internal/boring/bbig.
+type BigInt []uint
index 20612e6a2c042b12c26c59f831d618298dde3099..884c4b746d295824bda5f94c9237260e1b5295c7 100644 (file)
@@ -10,15 +10,13 @@ package boring
 // #include "goboringcrypto.h"
 import "C"
 import (
-       "encoding/asn1"
        "errors"
-       "math/big"
        "runtime"
        "unsafe"
 )
 
 type ecdsaSignature struct {
-       R, S *big.Int
+       R, S BigInt
 }
 
 type PrivateKeyECDSA struct {
@@ -53,7 +51,7 @@ func curveNID(curve string) (C.int, error) {
        return 0, errUnknownCurve
 }
 
-func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) {
+func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) {
        key, err := newECKey(curve, X, Y)
        if err != nil {
                return nil, err
@@ -67,7 +65,7 @@ func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) {
        return k, nil
 }
 
-func newECKey(curve string, X, Y *big.Int) (*C.GO_EC_KEY, error) {
+func newECKey(curve string, X, Y BigInt) (*C.GO_EC_KEY, error) {
        nid, err := curveNID(curve)
        if err != nil {
                return nil, err
@@ -100,7 +98,7 @@ func newECKey(curve string, X, Y *big.Int) (*C.GO_EC_KEY, error) {
        return key, nil
 }
 
-func NewPrivateKeyECDSA(curve string, X, Y *big.Int, D *big.Int) (*PrivateKeyECDSA, error) {
+func NewPrivateKeyECDSA(curve string, X, Y BigInt, D BigInt) (*PrivateKeyECDSA, error) {
        key, err := newECKey(curve, X, Y)
        if err != nil {
                return nil, err
@@ -123,22 +121,6 @@ func NewPrivateKeyECDSA(curve string, X, Y *big.Int, D *big.Int) (*PrivateKeyECD
        return k, nil
 }
 
-func SignECDSA(priv *PrivateKeyECDSA, hash []byte) (r, s *big.Int, err error) {
-       // We could use ECDSA_do_sign instead but would need to convert
-       // the resulting BIGNUMs to *big.Int form. If we're going to do a
-       // conversion, converting the ASN.1 form is more convenient and
-       // likely not much more expensive.
-       sig, err := SignMarshalECDSA(priv, hash)
-       if err != nil {
-               return nil, nil, err
-       }
-       var esig ecdsaSignature
-       if _, err := asn1.Unmarshal(sig, &esig); err != nil {
-               return nil, nil, err
-       }
-       return esig.R, esig.S, nil
-}
-
 func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
        size := C._goboringcrypto_ECDSA_size(priv.key)
        sig := make([]byte, size)
@@ -150,20 +132,13 @@ func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
        return sig[:sigLen], nil
 }
 
-func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool {
-       // We could use ECDSA_do_verify instead but would need to convert
-       // r and s to BIGNUM form. If we're going to do a conversion, marshaling
-       // to ASN.1 is more convenient and likely not much more expensive.
-       sig, err := asn1.Marshal(ecdsaSignature{r, s})
-       if err != nil {
-               return false
-       }
+func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool {
        ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.size_t(len(sig)), pub.key) != 0
        runtime.KeepAlive(pub)
        return ok
 }
 
-func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) {
+func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) {
        nid, err := curveNID(curve)
        if err != nil {
                return nil, nil, nil, err
index df165885849a4981f30d5791d98f58cc3ac0f465..bb88fb00048cddc40f507567c1d98ffb64432635 100644 (file)
@@ -12,7 +12,6 @@ import (
        "crypto/cipher"
        "crypto/internal/boring/sig"
        "hash"
-       "math/big"
 )
 
 const available = false
@@ -55,22 +54,19 @@ func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not a
 type PublicKeyECDSA struct{ _ int }
 type PrivateKeyECDSA struct{ _ int }
 
-func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) {
+func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) {
        panic("boringcrypto: not available")
 }
-func NewPrivateKeyECDSA(curve string, X, Y, D *big.Int) (*PrivateKeyECDSA, error) {
+func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error) {
        panic("boringcrypto: not available")
 }
-func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) {
-       panic("boringcrypto: not available")
-}
-func SignECDSA(priv *PrivateKeyECDSA, hash []byte) (r, s *big.Int, err error) {
+func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) {
        panic("boringcrypto: not available")
 }
 func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
        panic("boringcrypto: not available")
 }
-func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool {
+func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool {
        panic("boringcrypto: not available")
 }
 
@@ -95,13 +91,13 @@ func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
 func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
        panic("boringcrypto: not available")
 }
-func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) {
+func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) {
        panic("boringcrypto: not available")
 }
-func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) {
+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) {
        panic("boringcrypto: not available")
 }
-func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) { panic("boringcrypto: not available") }
+func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") }
 func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {
        panic("boringcrypto: not available")
 }
index 642287709e5c157046d0c6dc1ca37af891563de9..64c83c21c5bd041b7ff3cb2fac31d535e1a5ad00 100644 (file)
@@ -14,14 +14,13 @@ import (
        "crypto/subtle"
        "errors"
        "hash"
-       "math/big"
        "runtime"
        "strconv"
        "unsafe"
 )
 
-func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) {
-       bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) {
+func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) {
+       bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) {
                return nil, nil, nil, nil, nil, nil, nil, nil, e
        }
 
@@ -47,7 +46,7 @@ type PublicKeyRSA struct {
        _key *C.GO_RSA
 }
 
-func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) {
+func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) {
        key := C._goboringcrypto_RSA_new()
        if key == nil {
                return nil, fail("RSA_new")
@@ -78,7 +77,7 @@ type PrivateKeyRSA struct {
        _key *C.GO_RSA
 }
 
-func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) {
+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) {
        key := C._goboringcrypto_RSA_new()
        if key == nil {
                return nil, fail("RSA_new")
index 49a195f0f4e2634756e625035d63e3ecc26e74fe..362e9307f8608f2664aa07fe62cef7492531ca05 100644 (file)
@@ -8,6 +8,7 @@ package rsa
 
 import (
        "crypto/internal/boring"
+       "crypto/internal/boring/bbig"
        "math/big"
        "sync/atomic"
        "unsafe"
@@ -43,7 +44,7 @@ func boringPublicKey(pub *PublicKey) (*boring.PublicKeyRSA, error) {
 
        b = new(boringPub)
        b.orig = copyPublicKey(pub)
-       key, err := boring.NewPublicKeyRSA(b.orig.N, big.NewInt(int64(b.orig.E)))
+       key, err := boring.NewPublicKeyRSA(bbig.Enc(b.orig.N), bbig.Enc(big.NewInt(int64(b.orig.E))))
        if err != nil {
                return nil, err
        }
@@ -77,7 +78,7 @@ func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyRSA, error) {
                Dq = b.orig.Precomputed.Dq
                Qinv = b.orig.Precomputed.Qinv
        }
-       key, err := boring.NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv)
+       key, err := boring.NewPrivateKeyRSA(bbig.Enc(N), bbig.Enc(E), bbig.Enc(D), bbig.Enc(P), bbig.Enc(Q), bbig.Enc(Dp), bbig.Enc(Dq), bbig.Enc(Qinv))
        if err != nil {
                return nil, err
        }
index eef967f826ea1d99fafc04ff78a330184944b8a0..e084be15cc1b59a87db1d084e86ab959847f5b30 100644 (file)
@@ -24,6 +24,9 @@ package rsa
 
 import (
        "crypto"
+       "crypto/internal/boring"
+       "crypto/internal/boring/bbig"
+       "crypto/internal/randutil"
        "crypto/rand"
        "crypto/subtle"
        "errors"
@@ -31,12 +34,6 @@ import (
        "io"
        "math"
        "math/big"
-
-       "crypto/internal/randutil"
-)
-
-import (
-       "crypto/internal/boring"
        "unsafe"
 )
 
@@ -266,10 +263,18 @@ func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey
        randutil.MaybeReadByte(random)
 
        if boring.Enabled && random == boring.RandReader && nprimes == 2 && (bits == 2048 || bits == 3072) {
-               N, E, D, P, Q, Dp, Dq, Qinv, err := boring.GenerateKeyRSA(bits)
+               bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits)
                if err != nil {
                        return nil, err
                }
+               N := bbig.Dec(bN)
+               E := bbig.Dec(bE)
+               D := bbig.Dec(bD)
+               P := bbig.Dec(bP)
+               Q := bbig.Dec(bQ)
+               Dp := bbig.Dec(bDp)
+               Dq := bbig.Dec(bDq)
+               Qinv := bbig.Dec(bQinv)
                e64 := E.Int64()
                if !E.IsInt64() || int64(int(e64)) != e64 {
                        return nil, errors.New("crypto/rsa: generated key exponent too large")
index d955081869cc4f69263e8a6fb1b48b3e03b2e25f..91220a88bbad45164b6d280c81a4eb9269d7cc88 100644 (file)
@@ -334,7 +334,7 @@ var depsRules = `
 
        # Bulk of the standard library must not use cgo.
        # The prohibition stops at net and os/user.
-       C !< fmt, go/types;
+       C !< fmt, go/types, CRYPTO-MATH;
 
        CGO, OS
        < plugin;
@@ -399,10 +399,15 @@ var depsRules = `
 
        NONE < crypto/internal/boring/sig, crypto/internal/boring/syso;
        sync/atomic < crypto/internal/boring/fipstls;
-
-       encoding/binary, golang.org/x/sys/cpu, hash,
-       FMT, math/big, embed,
-       CGO, crypto/internal/boring/sig, crypto/internal/boring/fipstls, crypto/internal/boring/syso
+       crypto/internal/boring/sig, crypto/internal/boring/fipstls < crypto/tls/fipsonly;
+
+       # CRYPTO is core crypto algorithms - no cgo, fmt, net.
+       # Unfortunately, stuck with reflect via encoding/binary.
+       crypto/internal/boring/sig,
+       crypto/internal/boring/syso,
+       encoding/binary,
+       golang.org/x/sys/cpu,
+       hash
        < crypto
        < crypto/subtle
        < crypto/internal/subtle
@@ -411,43 +416,47 @@ var depsRules = `
        < crypto/ed25519/internal/edwards25519/field, golang.org/x/crypto/curve25519/internal/field
        < crypto/ed25519/internal/edwards25519
        < crypto/cipher
-       < encoding/asn1
        < crypto/internal/boring
+       < crypto/boring
        < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
          crypto/sha1, crypto/sha256, crypto/sha512
+       < CRYPTO;
+
+       CGO, fmt, net !< CRYPTO;
+
+       # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok.
+       CRYPTO, FMT, math/big, embed
+       < crypto/internal/boring/bbig
        < crypto/internal/randutil
        < crypto/rand
        < crypto/ed25519
+       < encoding/asn1
        < golang.org/x/crypto/cryptobyte/asn1
        < golang.org/x/crypto/cryptobyte
        < golang.org/x/crypto/curve25519
        < crypto/dsa, crypto/elliptic, crypto/rsa
        < crypto/ecdsa
-       < CRYPTO-BORING;
+       < CRYPTO-MATH;
 
-       net !< CRYPTO-BORING;
+       CGO, net !< CRYPTO-MATH;
 
        # TLS, Prince of Dependencies.
-       CRYPTO-BORING, NET, container/list, encoding/hex, encoding/pem
+       CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem
        < golang.org/x/crypto/internal/subtle
        < golang.org/x/crypto/chacha20
        < golang.org/x/crypto/internal/poly1305
        < golang.org/x/crypto/chacha20poly1305
        < golang.org/x/crypto/hkdf
        < crypto/x509/internal/macos
-       < crypto/x509/pkix
+       < crypto/x509/pkix;
+
+       crypto/internal/boring/fipstls, crypto/x509/pkix
        < crypto/x509
        < crypto/tls;
 
-       crypto/internal/boring/sig, crypto/internal/boring/fipstls
-       < crypto/tls/fipsonly;
-
-       crypto/internal/boring
-       < crypto/boring;
-
        # crypto-aware packages
 
-       CRYPTO-BORING, DEBUG, go/build, go/types, text/scanner
+       DEBUG, go/build, go/types, text/scanner, crypto/md5
        < internal/pkgbits
        < go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter
        < go/importer;
@@ -645,6 +654,9 @@ func findImports(pkg string) ([]string, error) {
        }
        var imports []string
        var haveImport = map[string]bool{}
+       if pkg == "crypto/internal/boring" {
+               haveImport["C"] = true // kludge: prevent C from appearing in crypto/internal/boring imports
+       }
        fset := token.NewFileSet()
        for _, file := range files {
                name := file.Name()