go.crypto/bcrypt: add Cost function
Extracts the cost used to generate a bcrypt hash from the hash itself.
R=agl, agl, dchest
CC=golang-dev
https://golang.org/cl/6810051
diff --git a/bcrypt/bcrypt.go b/bcrypt/bcrypt.go
index 35f0d8b..b71fc41 100644
--- a/bcrypt/bcrypt.go
+++ b/bcrypt/bcrypt.go
@@ -76,7 +76,7 @@
type hashed struct {
hash []byte
salt []byte
- cost uint32 // allowed range is MinCost to MaxCost
+ cost int // allowed range is MinCost to MaxCost
major byte
minor byte
}
@@ -94,8 +94,7 @@
}
// CompareHashAndPassword compares a bcrypt hashed password with its possible
-// plaintext equivalent. Note: Using bytes.Equal for this job is
-// insecure. Returns nil on success, or an error on failure.
+// plaintext equivalent. Returns nil on success, or an error on failure.
func CompareHashAndPassword(hashedPassword, password []byte) error {
p, err := newFromHash(hashedPassword)
if err != nil {
@@ -115,6 +114,18 @@
return ErrMismatchedHashAndPassword
}
+// Cost returns the hashing cost used to create the given hashed
+// password. When, in the future, the hashing cost of a password system needs
+// to be increased in order to adjust for greater computational power, this
+// function allows one to establish which passwords need to be updated.
+func Cost(hashedPassword []byte) (int, error) {
+ p, err := newFromHash(hashedPassword)
+ if err != nil {
+ return 0, err
+ }
+ return p.cost, nil
+}
+
func newFromPassword(password []byte, cost int) (*hashed, error) {
if cost < MinCost {
cost = DefaultCost
@@ -127,7 +138,7 @@
if err != nil {
return nil, err
}
- p.cost = uint32(cost)
+ p.cost = cost
unencodedSalt := make([]byte, maxSaltSize)
_, err = io.ReadFull(rand.Reader, unencodedSalt)
@@ -172,11 +183,11 @@
return p, nil
}
-func bcrypt(password []byte, cost uint32, salt []byte) ([]byte, error) {
+func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
cipherData := make([]byte, len(magicCipherData))
copy(cipherData, magicCipherData)
- c, err := expensiveBlowfishSetup(password, cost, salt)
+ c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
if err != nil {
return nil, err
}
@@ -266,7 +277,7 @@
if err != nil {
return -1, err
}
- p.cost = uint32(cost)
+ p.cost = cost
return 3, nil
}