aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2017-08-18 09:11:40 -0400
committerRuss Cox <rsc@golang.org>2017-08-26 00:52:31 +0000
commit775b2384e7db6b2be0a753450f2a8305179c3a89 (patch)
treed3240995612cc93501c0e592545387e776d9fab5
parentfb11572dfd21068a7333cd650c5c82a1ba310b8d (diff)
downloadgo-775b2384e7db6b2be0a753450f2a8305179c3a89.tar.gz
go-775b2384e7db6b2be0a753450f2a8305179c3a89.zip
[dev.boringcrypto.go1.8] crypto/ecdsa: use unsafe.Pointer instead of atomic.Value
Using atomic.Value causes vet errors in code copying PublicKey or PrivateKey structures. I don't think the errors are accurate, but it's easier to work around them than to change vet or change atomic.Value. See #21504. Change-Id: I3a3435c1fc664cc5166c81674f6f7c58dab35f21 Reviewed-on: https://go-review.googlesource.com/56671 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Adam Langley <agl@golang.org> Reviewed-on: https://go-review.googlesource.com/57941
-rw-r--r--src/crypto/ecdsa/boring.go49
-rw-r--r--src/crypto/ecdsa/ecdsa.go6
2 files changed, 23 insertions, 32 deletions
diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go
index 3e59f76a14..fa15ecb850 100644
--- a/src/crypto/ecdsa/boring.go
+++ b/src/crypto/ecdsa/boring.go
@@ -5,9 +5,10 @@
package ecdsa
import (
- "crypto/elliptic"
"crypto/internal/boring"
"math/big"
+ "sync/atomic"
+ "unsafe"
)
// Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
@@ -29,81 +30,71 @@ import (
type boringPub struct {
key *boring.PublicKeyECDSA
- orig publicKey
-}
-
-// copy of PublicKey without the atomic.Value field, to placate vet.
-type publicKey struct {
- elliptic.Curve
- X, Y *big.Int
+ orig PublicKey
}
func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
- b, _ := pub.boring.Load().(boringPub)
- if publicKeyEqual(&b.orig, pub) {
+ b := (*boringPub)(atomic.LoadPointer(&pub.boring))
+ if b != nil && publicKeyEqual(&b.orig, pub) {
return b.key, nil
}
+ b = new(boringPub)
b.orig = copyPublicKey(pub)
key, err := boring.NewPublicKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y)
if err != nil {
return nil, err
}
b.key = key
- pub.boring.Store(b)
+ atomic.StorePointer(&pub.boring, unsafe.Pointer(b))
return key, nil
}
type boringPriv struct {
key *boring.PrivateKeyECDSA
- orig privateKey
-}
-
-// copy of PrivateKey without the atomic.Value field, to placate vet.
-type privateKey struct {
- publicKey
- D *big.Int
+ orig PrivateKey
}
func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
- b, _ := priv.boring.Load().(boringPriv)
- if privateKeyEqual(&b.orig, priv) {
+ b := (*boringPriv)(atomic.LoadPointer(&priv.boring))
+ if b != nil && privateKeyEqual(&b.orig, priv) {
return b.key, nil
}
+ 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)
if err != nil {
return nil, err
}
b.key = key
- priv.boring.Store(b)
+ atomic.StorePointer(&priv.boring, unsafe.Pointer(b))
return key, nil
}
-func publicKeyEqual(k1 *publicKey, k2 *PublicKey) bool {
+func publicKeyEqual(k1, k2 *PublicKey) bool {
return k1.X != nil &&
k1.Curve.Params() == k2.Curve.Params() &&
k1.X.Cmp(k2.X) == 0 &&
k1.Y.Cmp(k2.Y) == 0
}
-func privateKeyEqual(k1 *privateKey, k2 *PrivateKey) bool {
- return publicKeyEqual(&k1.publicKey, &k2.PublicKey) &&
+func privateKeyEqual(k1, k2 *PrivateKey) bool {
+ return publicKeyEqual(&k1.PublicKey, &k2.PublicKey) &&
k1.D.Cmp(k2.D) == 0
}
-func copyPublicKey(k *PublicKey) publicKey {
- return publicKey{
+func copyPublicKey(k *PublicKey) PublicKey {
+ return PublicKey{
Curve: k.Curve,
X: new(big.Int).Set(k.X),
Y: new(big.Int).Set(k.Y),
}
}
-func copyPrivateKey(k *PrivateKey) privateKey {
- return privateKey{
- publicKey: copyPublicKey(&k.PublicKey),
+func copyPrivateKey(k *PrivateKey) PrivateKey {
+ return PrivateKey{
+ PublicKey: copyPublicKey(&k.PublicKey),
D: new(big.Int).Set(k.D),
}
}
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index a3fa743e66..3fe1dda660 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -27,7 +27,7 @@ import (
"errors"
"io"
"math/big"
- "sync/atomic"
+ "unsafe"
)
// A invertible implements fast inverse mod Curve.Params().N
@@ -50,7 +50,7 @@ type PublicKey struct {
elliptic.Curve
X, Y *big.Int
- boring atomic.Value
+ boring unsafe.Pointer
}
// PrivateKey represents a ECDSA private key.
@@ -58,7 +58,7 @@ type PrivateKey struct {
PublicKey
D *big.Int
- boring atomic.Value
+ boring unsafe.Pointer
}
type ecdsaSignature struct {