]> Cypherpunks.ru repositories - gostls13.git/commitdiff
crypto/ecdh: add boringcrypto support
authorRuss Cox <rsc@golang.org>
Tue, 16 Aug 2022 14:37:49 +0000 (10:37 -0400)
committerGopher Robot <gobot@golang.org>
Fri, 11 Nov 2022 01:42:03 +0000 (01:42 +0000)
Update crypto/ecdh to use boringcrypto when enabled.

Change-Id: Idd0ce06a22b1a62289b383c46893800621c7d97b
Reviewed-on: https://go-review.googlesource.com/c/go/+/423363
Run-TryBot: Russ Cox <rsc@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/crypto/ecdh/ecdh.go
src/crypto/ecdh/ecdh_test.go
src/crypto/ecdh/nist.go
src/crypto/internal/boring/boring.go
src/crypto/internal/boring/build-goboring.sh
src/crypto/internal/boring/ecdh.go [new file with mode: 0644]
src/crypto/internal/boring/goboringcrypto.h
src/crypto/internal/boring/notboring.go
src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso
src/go/build/deps_test.go

index 74e198222c54f8f313ddd0893bb48dfadbdd3ca3..73a5c68d506aea08983a9784806fd1c2f4066250 100644 (file)
@@ -8,6 +8,7 @@ package ecdh
 
 import (
        "crypto"
+       "crypto/internal/boring"
        "crypto/subtle"
        "io"
        "sync"
@@ -64,6 +65,7 @@ type Curve interface {
 type PublicKey struct {
        curve     Curve
        publicKey []byte
+       boring    *boring.PublicKeyECDH
 }
 
 // Bytes returns a copy of the encoding of the public key.
@@ -98,6 +100,7 @@ func (k *PublicKey) Curve() Curve {
 type PrivateKey struct {
        curve      Curve
        privateKey []byte
+       boring     *boring.PrivateKeyECDH
        // publicKey is set under publicKeyOnce, to allow loading private keys with
        // NewPrivateKey without having to perform a scalar multiplication.
        publicKey     *PublicKey
@@ -134,7 +137,23 @@ func (k *PrivateKey) Curve() Curve {
 
 func (k *PrivateKey) PublicKey() *PublicKey {
        k.publicKeyOnce.Do(func() {
-               k.publicKey = k.curve.privateKeyToPublicKey(k)
+               if k.boring != nil {
+                       // Because we already checked in NewPrivateKey that the key is valid,
+                       // there should not be any possible errors from BoringCrypto,
+                       // so we turn the error into a panic.
+                       // (We can't return it anyhow.)
+                       kpub, err := k.boring.PublicKey()
+                       if err != nil {
+                               panic("boringcrypto: " + err.Error())
+                       }
+                       k.publicKey = &PublicKey{
+                               curve:     k.curve,
+                               publicKey: kpub.Bytes(),
+                               boring:    kpub,
+                       }
+               } else {
+                       k.publicKey = k.curve.privateKeyToPublicKey(k)
+               }
        })
        return k.publicKey
 }
index 947eef1ef1645fd476e25f62cb09a00176801896..0846268c45287752dfef4532c83bb8100a686500 100644 (file)
@@ -10,6 +10,7 @@ import (
        "crypto/cipher"
        "crypto/ecdh"
        "crypto/rand"
+       "crypto/sha256"
        "encoding/hex"
        "fmt"
        "internal/testenv"
@@ -173,7 +174,8 @@ func TestVectors(t *testing.T) {
                        t.Fatal(err)
                }
                if !bytes.Equal(secret, hexDecode(t, v.SharedSecret)) {
-                       t.Error("shared secret does not match")
+                       t.Errorf("shared secret does not match: %x %x %s %x", secret, sha256.Sum256(secret), v.SharedSecret,
+                               sha256.Sum256(hexDecode(t, v.SharedSecret)))
                }
        })
 }
@@ -285,6 +287,8 @@ func TestNewPrivateKey(t *testing.T) {
                                t.Errorf("unexpectedly accepted %q", input)
                        } else if k != nil {
                                t.Error("PrivateKey was not nil on error")
+                       } else if strings.Contains(err.Error(), "boringcrypto") {
+                               t.Errorf("boringcrypto error leaked out: %v", err)
                        }
                }
        })
@@ -344,6 +348,8 @@ func TestNewPublicKey(t *testing.T) {
                                t.Errorf("unexpectedly accepted %q", input)
                        } else if k != nil {
                                t.Error("PublicKey was not nil on error")
+                       } else if strings.Contains(err.Error(), "boringcrypto") {
+                               t.Errorf("boringcrypto error leaked out: %v", err)
                        }
                }
        })
index c5d37b5fb2599e9074dbae7e4beab499e8f09800..6d30b7bbb2bd9c9bd18d205df3ae544ac2489c3c 100644 (file)
@@ -5,6 +5,7 @@
 package ecdh
 
 import (
+       "crypto/internal/boring"
        "crypto/internal/nistec"
        "crypto/internal/randutil"
        "encoding/binary"
@@ -35,6 +36,14 @@ func (c *nistCurve[Point]) String() string {
 var errInvalidPrivateKey = errors.New("crypto/ecdh: invalid private key")
 
 func (c *nistCurve[Point]) GenerateKey(rand io.Reader) (*PrivateKey, error) {
+       if boring.Enabled && rand == boring.RandReader {
+               key, bytes, err := boring.GenerateKeyECDH(c.name)
+               if err != nil {
+                       return nil, err
+               }
+               return newBoringPrivateKey(c, key, bytes)
+       }
+
        key := make([]byte, len(c.scalarOrder))
        randutil.MaybeReadByte(rand)
        for {
@@ -70,13 +79,31 @@ func (c *nistCurve[Point]) NewPrivateKey(key []byte) (*PrivateKey, error) {
        if isZero(key) || !isLess(key, c.scalarOrder) {
                return nil, errInvalidPrivateKey
        }
-       return &PrivateKey{
+       if boring.Enabled {
+               bk, err := boring.NewPrivateKeyECDH(c.name, key)
+               if err != nil {
+                       return nil, err
+               }
+               return newBoringPrivateKey(c, bk, key)
+       }
+       k := &PrivateKey{
                curve:      c,
                privateKey: append([]byte{}, key...),
-       }, nil
+       }
+       return k, nil
+}
+
+func newBoringPrivateKey(c Curve, bk *boring.PrivateKeyECDH, privateKey []byte) (*PrivateKey, error) {
+       k := &PrivateKey{
+               curve:      c,
+               boring:     bk,
+               privateKey: append([]byte(nil), privateKey...),
+       }
+       return k, nil
 }
 
 func (c *nistCurve[Point]) privateKeyToPublicKey(key *PrivateKey) *PublicKey {
+       boring.Unreachable()
        if key.curve != c {
                panic("crypto/ecdh: internal error: converting the wrong key type")
        }
@@ -142,15 +169,23 @@ func (c *nistCurve[Point]) NewPublicKey(key []byte) (*PublicKey, error) {
        if len(key) == 0 || key[0] != 4 {
                return nil, errors.New("crypto/ecdh: invalid public key")
        }
-       // SetBytes also checks that the point is on the curve.
-       if _, err := c.newPoint().SetBytes(key); err != nil {
-               return nil, err
-       }
-
-       return &PublicKey{
+       k := &PublicKey{
                curve:     c,
                publicKey: append([]byte{}, key...),
-       }, nil
+       }
+       if boring.Enabled {
+               bk, err := boring.NewPublicKeyECDH(c.name, k.publicKey)
+               if err != nil {
+                       return nil, err
+               }
+               k.boring = bk
+       } else {
+               // SetBytes also checks that the point is on the curve.
+               if _, err := c.newPoint().SetBytes(key); err != nil {
+                       return nil, err
+               }
+       }
+       return k, nil
 }
 
 func (c *nistCurve[Point]) ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error) {
@@ -160,6 +195,12 @@ func (c *nistCurve[Point]) ECDH(local *PrivateKey, remote *PublicKey) ([]byte, e
        // at infinity, but in a prime order group such as the NIST curves that can
        // only be the result of a scalar multiplication if one of the inputs is the
        // zero scalar or the point at infinity.
+
+       if boring.Enabled {
+               return boring.ECDH(local.boring, remote.boring)
+       }
+
+       boring.Unreachable()
        p, err := c.newPoint().SetBytes(remote.publicKey)
        if err != nil {
                return nil, err
index d6b8e37b726e157ac0a5dc584576067a341d1f08..7ea438d3a7ad75a8685f40b5e7ebfee17072625b 100644 (file)
@@ -71,6 +71,10 @@ func bigToBN(x BigInt) *C.GO_BIGNUM {
        return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil)
 }
 
+func bytesToBN(x []byte) *C.GO_BIGNUM {
+       return C._goboringcrypto_BN_bin2bn((*C.uint8_t)(&x[0]), C.size_t(len(x)), nil)
+}
+
 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 {
index 5c0b74e0747765364ab9f5b2381fa7d183864389..4938b5eac33a57cb8d6dc52bc81c281cf50e3580 100755 (executable)
@@ -55,7 +55,7 @@ BEGIN {
 /\/\*unchecked/ { next }
 
 # Check enum values.
-!enum && $1 == "enum" && $NF == "{" {
+!enum && ($1 == "enum" || $2 == "enum") && $NF == "{" {
        enum = 1
        next
 }
@@ -63,6 +63,10 @@ enum && $1 == "};" {
        enum = 0
        next
 }
+enum && /^}.*;$/ {
+       enum = 0
+       next
+}
 enum && NF == 3 && $2 == "=" {
        name = $1
        sub(/^GO_/, "", name)
@@ -111,7 +115,7 @@ EOF
 cat >boringh.awk <<'EOF'
 /^\/\/ #include/ {sub(/\/\//, ""); print > "goboringcrypto0.h"; next}
 /typedef struct|enum ([a-z_]+ )?{|^[ \t]/ {print >"goboringcrypto1.h";next}
-{gsub(/GO_/, ""); gsub(/enum go_/, "enum "); print >"goboringcrypto1.h"}
+{gsub(/GO_/, ""); gsub(/enum go_/, "enum "); gsub(/go_point_conv/, "point_conv"); print >"goboringcrypto1.h"}
 EOF
 
 awk -f boringx.awk goboringcrypto.h # writes goboringcrypto.x
diff --git a/src/crypto/internal/boring/ecdh.go b/src/crypto/internal/boring/ecdh.go
new file mode 100644 (file)
index 0000000..8f46d81
--- /dev/null
@@ -0,0 +1,224 @@
+// 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.
+
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import (
+       "errors"
+       "runtime"
+       "unsafe"
+)
+
+type PublicKeyECDH struct {
+       curve string
+       key   *C.GO_EC_POINT
+       group *C.GO_EC_GROUP
+       bytes []byte
+}
+
+func (k *PublicKeyECDH) finalize() {
+       C._goboringcrypto_EC_POINT_free(k.key)
+}
+
+type PrivateKeyECDH struct {
+       curve string
+       key   *C.GO_EC_KEY
+}
+
+func (k *PrivateKeyECDH) finalize() {
+       C._goboringcrypto_EC_KEY_free(k.key)
+}
+
+func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) {
+       if len(bytes) < 1 {
+               return nil, errors.New("NewPublicKeyECDH: missing key")
+       }
+
+       nid, err := curveNID(curve)
+       if err != nil {
+               return nil, err
+       }
+
+       group := C._goboringcrypto_EC_GROUP_new_by_curve_name(nid)
+       if group == nil {
+               return nil, fail("EC_GROUP_new_by_curve_name")
+       }
+       defer C._goboringcrypto_EC_GROUP_free(group)
+       key := C._goboringcrypto_EC_POINT_new(group)
+       if key == nil {
+               return nil, fail("EC_POINT_new")
+       }
+       ok := C._goboringcrypto_EC_POINT_oct2point(group, key, (*C.uint8_t)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes)), nil) != 0
+       if !ok {
+               C._goboringcrypto_EC_POINT_free(key)
+               return nil, errors.New("point not on curve")
+       }
+
+       k := &PublicKeyECDH{curve, key, group, append([]byte(nil), bytes...)}
+       // Note: Because of the finalizer, any time k.key is passed to cgo,
+       // that call must be followed by a call to runtime.KeepAlive(k),
+       // to make sure k is not collected (and finalized) before the cgo
+       // call returns.
+       runtime.SetFinalizer(k, (*PublicKeyECDH).finalize)
+       return k, nil
+}
+
+func (k *PublicKeyECDH) Bytes() []byte { return k.bytes }
+
+func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) {
+       nid, err := curveNID(curve)
+       if err != nil {
+               return nil, err
+       }
+       key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
+       if key == nil {
+               return nil, fail("EC_KEY_new_by_curve_name")
+       }
+       b := bytesToBN(bytes)
+       ok := b != nil && C._goboringcrypto_EC_KEY_set_private_key(key, b) != 0
+       if b != nil {
+               C._goboringcrypto_BN_free(b)
+       }
+       if !ok {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, fail("EC_KEY_set_private_key")
+       }
+       k := &PrivateKeyECDH{curve, key}
+       // Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive.
+       runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize)
+       return k, nil
+}
+
+func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) {
+       defer runtime.KeepAlive(k)
+
+       group := C._goboringcrypto_EC_KEY_get0_group(k.key)
+       if group == nil {
+               return nil, fail("EC_KEY_get0_group")
+       }
+       kbig := C._goboringcrypto_EC_KEY_get0_private_key(k.key)
+       if kbig == nil {
+               return nil, fail("EC_KEY_get0_private_key")
+       }
+       pt := C._goboringcrypto_EC_POINT_new(group)
+       if pt == nil {
+               return nil, fail("EC_POINT_new")
+       }
+       if C._goboringcrypto_EC_POINT_mul(group, pt, kbig, nil, nil, nil) == 0 {
+               C._goboringcrypto_EC_POINT_free(pt)
+               return nil, fail("EC_POINT_mul")
+       }
+       bytes, err := pointBytesECDH(k.curve, group, pt)
+       if err != nil {
+               C._goboringcrypto_EC_POINT_free(pt)
+               return nil, err
+       }
+       pub := &PublicKeyECDH{k.curve, pt, group, bytes}
+       // Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive.
+       runtime.SetFinalizer(pub, (*PublicKeyECDH).finalize)
+       return pub, nil
+}
+
+func pointBytesECDH(curve string, group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]byte, error) {
+       out := make([]byte, 1+2*curveSize(curve))
+       n := C._goboringcrypto_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, (*C.uint8_t)(unsafe.Pointer(&out[0])), C.size_t(len(out)), nil)
+       if int(n) != len(out) {
+               return nil, fail("EC_POINT_point2oct")
+       }
+       return out, nil
+}
+
+func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) {
+       group := C._goboringcrypto_EC_KEY_get0_group(priv.key)
+       if group == nil {
+               return nil, fail("EC_KEY_get0_group")
+       }
+       privBig := C._goboringcrypto_EC_KEY_get0_private_key(priv.key)
+       if privBig == nil {
+               return nil, fail("EC_KEY_get0_private_key")
+       }
+       pt := C._goboringcrypto_EC_POINT_new(group)
+       if pt == nil {
+               return nil, fail("EC_POINT_new")
+       }
+       defer C._goboringcrypto_EC_POINT_free(pt)
+       if C._goboringcrypto_EC_POINT_mul(group, pt, nil, pub.key, privBig, nil) == 0 {
+               return nil, fail("EC_POINT_mul")
+       }
+       out, err := xCoordBytesECDH(priv.curve, group, pt)
+       if err != nil {
+               return nil, err
+       }
+       return out, nil
+}
+
+func xCoordBytesECDH(curve string, group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]byte, error) {
+       big := C._goboringcrypto_BN_new()
+       defer C._goboringcrypto_BN_free(big)
+       if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, big, nil, nil) == 0 {
+               return nil, fail("EC_POINT_get_affine_coordinates_GFp")
+       }
+       return bigBytesECDH(curve, big)
+}
+
+func bigBytesECDH(curve string, big *C.GO_BIGNUM) ([]byte, error) {
+       out := make([]byte, curveSize(curve))
+       if C._goboringcrypto_BN_bn2bin_padded((*C.uint8_t)(&out[0]), C.size_t(len(out)), big) == 0 {
+               return nil, fail("BN_bn2bin_padded")
+       }
+       return out, nil
+}
+
+func curveSize(curve string) int {
+       switch curve {
+       default:
+               panic("crypto/internal/boring: unknown curve " + curve)
+       case "P-256":
+               return 256 / 8
+       case "P-384":
+               return 384 / 8
+       case "P-521":
+               return (521 + 7) / 8
+       }
+}
+
+func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) {
+       nid, err := curveNID(curve)
+       if err != nil {
+               return nil, nil, err
+       }
+       key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
+       if key == nil {
+               return nil, nil, fail("EC_KEY_new_by_curve_name")
+       }
+       if C._goboringcrypto_EC_KEY_generate_key_fips(key) == 0 {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, nil, fail("EC_KEY_generate_key_fips")
+       }
+
+       group := C._goboringcrypto_EC_KEY_get0_group(key)
+       if group == nil {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, nil, fail("EC_KEY_get0_group")
+       }
+       b := C._goboringcrypto_EC_KEY_get0_private_key(key)
+       if b == nil {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, nil, fail("EC_KEY_get0_private_key")
+       }
+       bytes, err := bigBytesECDH(curve, b)
+       if err != nil {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, nil, err
+       }
+
+       k := &PrivateKeyECDH{curve, key}
+       // Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive.
+       runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize)
+       return k, bytes, nil
+}
index a5f4e0aac25986bf7db329e49a0ee028529e9ba0..2b11049728c5bb30b0616c1727df980067bd9284 100644 (file)
@@ -144,6 +144,7 @@ GO_BIGNUM* _goboringcrypto_BN_bin2bn(const uint8_t*, size_t, GO_BIGNUM*);
 GO_BIGNUM* _goboringcrypto_BN_le2bn(const uint8_t*, size_t, GO_BIGNUM*);
 size_t _goboringcrypto_BN_bn2bin(const GO_BIGNUM*, uint8_t*);
 int _goboringcrypto_BN_bn2le_padded(uint8_t*, size_t, const GO_BIGNUM*);
+int _goboringcrypto_BN_bn2bin_padded(uint8_t*, size_t, const GO_BIGNUM*);
 
 // #include <openssl/ec.h>
 /*unchecked (opaque)*/ typedef struct GO_EC_GROUP { char data[1]; } GO_EC_GROUP;
@@ -152,9 +153,21 @@ void _goboringcrypto_EC_GROUP_free(GO_EC_GROUP*);
 
 /*unchecked (opaque)*/ typedef struct GO_EC_POINT { char data[1]; } GO_EC_POINT;
 GO_EC_POINT* _goboringcrypto_EC_POINT_new(const GO_EC_GROUP*);
+int _goboringcrypto_EC_POINT_mul(const GO_EC_GROUP*, GO_EC_POINT*, const GO_BIGNUM*, const GO_EC_POINT*, const GO_BIGNUM*, GO_BN_CTX*);
 void _goboringcrypto_EC_POINT_free(GO_EC_POINT*);
 int _goboringcrypto_EC_POINT_get_affine_coordinates_GFp(const GO_EC_GROUP*, const GO_EC_POINT*, GO_BIGNUM*, GO_BIGNUM*, GO_BN_CTX*);
 int _goboringcrypto_EC_POINT_set_affine_coordinates_GFp(const GO_EC_GROUP*, GO_EC_POINT*, const GO_BIGNUM*, const GO_BIGNUM*, GO_BN_CTX*);
+int _goboringcrypto_EC_POINT_oct2point(const GO_EC_GROUP*, GO_EC_POINT*, const uint8_t*, size_t, GO_BN_CTX*);
+GO_EC_POINT* _goboringcrypto_EC_POINT_dup(const GO_EC_POINT*, const GO_EC_GROUP*);
+int _goboringcrypto_EC_POINT_is_on_curve(const GO_EC_GROUP*, const GO_EC_POINT*, GO_BN_CTX*);
+#ifndef OPENSSL_HEADER_EC_H
+typedef enum {
+       GO_POINT_CONVERSION_COMPRESSED = 2,
+       GO_POINT_CONVERSION_UNCOMPRESSED = 4,
+       GO_POINT_CONVERSION_HYBRID = 6,
+} go_point_conversion_form_t;
+#endif
+size_t _goboringcrypto_EC_POINT_point2oct(const GO_EC_GROUP*, const GO_EC_POINT*, go_point_conversion_form_t, uint8_t*, size_t, GO_BN_CTX*);
 
 // #include <openssl/ec_key.h>
 /*unchecked (opaque)*/ typedef struct GO_EC_KEY { char data[1]; } GO_EC_KEY;
@@ -170,6 +183,9 @@ const GO_BIGNUM* _goboringcrypto_EC_KEY_get0_private_key(const GO_EC_KEY*);
 const GO_EC_POINT* _goboringcrypto_EC_KEY_get0_public_key(const GO_EC_KEY*);
 // TODO: EC_KEY_check_fips?
 
+// #include <openssl/ecdh.h>
+int _goboringcrypto_ECDH_compute_key_fips(uint8_t*, size_t, const GO_EC_POINT*, const GO_EC_KEY*);
+
 // #include <openssl/ecdsa.h>
 typedef struct GO_ECDSA_SIG { char data[16]; } GO_ECDSA_SIG;
 GO_ECDSA_SIG* _goboringcrypto_ECDSA_SIG_new(void);
index 2fa5eaf30f7d2a5cbe1f9e1b391f411b930ced13..1c5e4c742d6a83a5386e108c5b7b1189d29493ce 100644 (file)
@@ -110,3 +110,13 @@ func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) err
 func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error {
        panic("boringcrypto: not available")
 }
+
+type PublicKeyECDH struct{}
+type PrivateKeyECDH struct{}
+
+func ECDH(*PrivateKeyECDH, *PublicKeyECDH) ([]byte, error)      { panic("boringcrypto: not available") }
+func GenerateKeyECDH(string) (*PrivateKeyECDH, []byte, error)   { panic("boringcrypto: not available") }
+func NewPrivateKeyECDH(string, []byte) (*PrivateKeyECDH, error) { panic("boringcrypto: not available") }
+func NewPublicKeyECDH(string, []byte) (*PublicKeyECDH, error)   { panic("boringcrypto: not available") }
+func (*PublicKeyECDH) Bytes() []byte                            { panic("boringcrypto: not available") }
+func (*PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error)      { panic("boringcrypto: not available") }
index fd982bff9ddd0e0c2b90e9770a4a05b116fb4f3e..6cea7893553abfee72af501a05a11ea09b396232 100644 (file)
Binary files a/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso and b/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso differ
index 46520b7592687cf3a9366b1f216ebd195f9a6732..9659aa1a5e4a48329a41738a452c92021a34469c 100644 (file)
Binary files a/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso and b/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso differ
index 25556ac04c6c55735c42aaa3f9c5b9ec930e6a59..dea9935c126a2f83e89aae4154d9ea42734a64b4 100644 (file)
@@ -395,19 +395,37 @@ var depsRules = `
        < crypto
        < crypto/subtle
        < crypto/internal/alias
-       < crypto/internal/randutil
-       < crypto/internal/nistec/fiat
-       < crypto/internal/nistec
-       < crypto/internal/edwards25519/field
-       < crypto/internal/edwards25519, crypto/ecdh
        < crypto/cipher;
 
        crypto/cipher,
        crypto/internal/boring/bcache
        < crypto/internal/boring
-       < crypto/boring
+       < crypto/boring;
+
+       crypto/internal/alias
+       < crypto/internal/randutil
+       < crypto/internal/nistec/fiat
+       < crypto/internal/nistec
+       < crypto/internal/edwards25519/field
+       < crypto/internal/edwards25519;
+
+       crypto/boring
        < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
-         crypto/sha1, crypto/sha256, crypto/sha512
+         crypto/sha1, crypto/sha256, crypto/sha512;
+
+       crypto/boring, crypto/internal/edwards25519/field
+       < crypto/ecdh;
+
+       crypto/aes,
+       crypto/des,
+       crypto/ecdh,
+       crypto/hmac,
+       crypto/internal/edwards25519,
+       crypto/md5,
+       crypto/rc4,
+       crypto/sha1,
+       crypto/sha256,
+       crypto/sha512
        < CRYPTO;
 
        CGO, fmt, net !< CRYPTO;