aboutsummaryrefslogtreecommitdiff
path: root/crypto/crypto.go
diff options
context:
space:
mode:
authorJoe Richey joerichey@google.com <joerichey@google.com>2017-06-21 09:52:40 -0700
committerJoe Richey joerichey@google.com <joerichey@google.com>2017-06-28 14:06:52 -0700
commit77b226a90ef70b77ca556830528c013a23b01e57 (patch)
treeb351dbb427ed62550f2440b8d56249bdcbbca96a /crypto/crypto.go
parent07341f3966675e4875f8cad3c8d86ae502de6d4d (diff)
Change error handling to new package
This commit changes the error handing for the crypto, filesystem, metadata, pam, and util packages to use the error handling library github.com/pkg/errors. This means elimination of the FSError type, an increased use of wrapping errors (as opposed to logging), switching on the Cause() of an error (as opposed to its value), and improving our integration tests involving TEST_FILESYSTEM_ROOT. This commit also fixes a few bugs with the keyring code to ensure that our {Find|Remove|Insert}PolicyKey functions are always operating on the same keyring. The check for filesystem support has been moved from the filesystem package to the metadata package. Finally, the API for the filesystem package has been slightly modified: * filesystem.AllFilesystems() now returns all the filesystems in sorted order * certain path methods are now public O_SYNC is also removed for writing the metadata. We don't get that much from syncing the metadata, as the actual file data could also be corrupted by and IO error. The sync operation is also occasionally very slow (~3 seconds) and can be unfriendly to battery life. Change-Id: I392c2655141714b16dfdbc84ac09780072be2cf0
Diffstat (limited to 'crypto/crypto.go')
-rw-r--r--crypto/crypto.go46
1 files changed, 22 insertions, 24 deletions
diff --git a/crypto/crypto.go b/crypto/crypto.go
index c6d6619..967243d 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -46,9 +46,9 @@ import (
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
- "errors"
"unsafe"
+ "github.com/pkg/errors"
"golang.org/x/crypto/hkdf"
"fscrypt/metadata"
@@ -57,34 +57,29 @@ import (
// Crypto error values
var (
- ErrBadAuth = errors.New("key authentication check failed")
- ErrNegitiveLength = errors.New("negative length requested for key")
- ErrKeyAlloc = util.SystemError("could not allocate memory for key")
- ErrKeyFree = util.SystemError("could not free memory of key")
- ErrKeyringLocate = util.SystemError("could not locate the session keyring")
- ErrKeyringInsert = util.SystemError("could not insert key into the session keyring")
- ErrKeyringSearch = util.SystemError("could not find key in the session keyring")
- ErrKeyringDelete = util.SystemError("could not delete key from the session keyring")
- ErrRecoveryCode = errors.New("provided recovery code had incorrect format")
- ErrLowEntropy = util.SystemError("insufficient entropy in pool to generate random bytes")
- ErrRandNotSupported = util.SystemError("getrandom() not implemented; kernel must be v3.17 or later")
- ErrRandFailed = util.SystemError("cannot get random bytes")
+ ErrBadAuth = errors.New("key authentication check failed")
+ ErrNegitiveLength = errors.New("keys cannot have negative lengths")
+ ErrRecoveryCode = errors.New("invalid recovery code")
+ ErrGetrandomFail = util.SystemError("getrandom() failed")
+ ErrKeyAlloc = util.SystemError("could not allocate memory for key")
+ ErrKeyFree = util.SystemError("could not free memory of key")
+ ErrKeyringLocate = util.SystemError("could not locate the session keyring")
+ ErrKeyringInsert = util.SystemError("could not insert key into the session keyring")
+ ErrKeyringSearch = errors.New("could not find key with descriptor")
+ ErrKeyringDelete = util.SystemError("could not delete key from the session keyring")
)
// panicInputLength panics if "name" has invalid length (expected != actual)
func panicInputLength(name string, expected, actual int) {
- if expected != actual {
- util.NeverError(util.InvalidLengthError(name, expected, actual))
+ if err := util.CheckValidLength(expected, actual); err != nil {
+ panic(errors.Wrap(err, name))
}
}
// checkWrappingKey returns an error if the wrapping key has the wrong length
func checkWrappingKey(wrappingKey *Key) error {
- l := wrappingKey.Len()
- if l != metadata.InternalKeyLen {
- return util.InvalidLengthError("wrapping key", metadata.InternalKeyLen, l)
- }
- return nil
+ err := util.CheckValidLength(metadata.InternalKeyLen, wrappingKey.Len())
+ return errors.Wrap(err, "wrapping key")
}
// stretchKey stretches a key of length KeyLen using unsalted HKDF to make two
@@ -140,14 +135,14 @@ func getHMAC(key *Key, data ...[]byte) []byte {
// and an HMAC to verify the wrapping key was correct. All of this is included
// in the returned WrappedKeyData structure.
func Wrap(wrappingKey, secretKey *Key) (*metadata.WrappedKeyData, error) {
- err := checkWrappingKey(wrappingKey)
- if err != nil {
+ if err := checkWrappingKey(wrappingKey); err != nil {
return nil, err
}
data := &metadata.WrappedKeyData{EncryptedKey: make([]byte, secretKey.Len())}
// Get random IV
+ var err error
if data.IV, err = NewRandomBuffer(metadata.IVLen); err != nil {
return nil, err
}
@@ -251,8 +246,11 @@ use it in "id" mode to provide extra protection against side-channel
attacks. For more info see: https://github.com/P-H-C/phc-winner-argon2
*/
func PassphraseHash(passphrase *Key, salt []byte, costs *metadata.HashingCosts) (*Key, error) {
- if len(salt) != metadata.SaltLen {
- return nil, util.InvalidLengthError("salt", metadata.SaltLen, len(salt))
+ if err := util.CheckValidLength(metadata.SaltLen, len(salt)); err != nil {
+ return nil, errors.Wrap(err, "passphrase hashing salt")
+ }
+ if err := costs.CheckValidity(); err != nil {
+ return nil, errors.Wrap(err, "passphrase hashing costs")
}
// This key will hold the hashing output