mirror of
https://github.com/golang/go
synced 2024-11-26 19:41:19 -07:00
crypto/ed25519,crypto/rsa: make Equal methods constant time
Fixes #53849 Updates #57752 Change-Id: I055564f31a47c79565b82bf9844fcf626989b295 Reviewed-on: https://go-review.googlesource.com/c/go/+/492955 Auto-Submit: Russ Cox <rsc@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
b7e767b022
commit
bf8571c5d6
@ -18,6 +18,7 @@ import (
|
||||
"crypto/internal/edwards25519"
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/sha512"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"io"
|
||||
"strconv"
|
||||
@ -46,7 +47,7 @@ func (pub PublicKey) Equal(x crypto.PublicKey) bool {
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(pub, xx)
|
||||
return subtle.ConstantTimeCompare(pub, xx) == 1
|
||||
}
|
||||
|
||||
// PrivateKey is the type of Ed25519 private keys. It implements [crypto.Signer].
|
||||
@ -65,7 +66,7 @@ func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(priv, xx)
|
||||
return subtle.ConstantTimeCompare(priv, xx) == 1
|
||||
}
|
||||
|
||||
// Seed returns the private key seed corresponding to priv. It is provided for
|
||||
|
@ -64,7 +64,7 @@ func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return pub.N.Cmp(xx.N) == 0 && pub.E == xx.E
|
||||
return bigIntEqual(pub.N, xx.N) && pub.E == xx.E
|
||||
}
|
||||
|
||||
// OAEPOptions is an interface for passing options to OAEP decryption using the
|
||||
@ -130,20 +130,26 @@ func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !priv.PublicKey.Equal(&xx.PublicKey) || priv.D.Cmp(xx.D) != 0 {
|
||||
if !priv.PublicKey.Equal(&xx.PublicKey) || !bigIntEqual(priv.D, xx.D) {
|
||||
return false
|
||||
}
|
||||
if len(priv.Primes) != len(xx.Primes) {
|
||||
return false
|
||||
}
|
||||
for i := range priv.Primes {
|
||||
if priv.Primes[i].Cmp(xx.Primes[i]) != 0 {
|
||||
if !bigIntEqual(priv.Primes[i], xx.Primes[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// bigIntEqual reports whether a and b are equal leaking only their bit length
|
||||
// through timing side-channels.
|
||||
func bigIntEqual(a, b *big.Int) bool {
|
||||
return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
|
||||
}
|
||||
|
||||
// Sign signs digest with priv, reading randomness from rand. If opts is a
|
||||
// *PSSOptions then the PSS algorithm will be used, otherwise PKCS #1 v1.5 will
|
||||
// be used. digest must be the result of hashing the input message using
|
||||
|
Loading…
Reference in New Issue
Block a user