From 462d166d5355d33a05271d24de4d52f30dd62f67 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 15 Dec 2019 19:31:39 -0800 Subject: Add keyring package In preparation for introducing support for the new filesystem-level keyrings, move the existing user keyring management code from security/keyring.go and crypto/crypto.go into a new package, 'keyring'. This package provides functions AddEncryptionKey, RemoveEncryptionKey, and GetEncryptionKeyStatus which delegate to either the filesystem keyring (added by a later patch) or to the user keyring. This provides a common interface to both types of keyrings, to the extent possible. --- crypto/crypto_test.go | 54 ++++----------------------------------------------- 1 file changed, 4 insertions(+), 50 deletions(-) (limited to 'crypto/crypto_test.go') diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 6f973ef..d0cef82 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -30,11 +30,7 @@ import ( "os" "testing" - "golang.org/x/sys/unix" - "github.com/google/fscrypt/metadata" - "github.com/google/fscrypt/security" - "github.com/google/fscrypt/util" ) // Reader that always returns the same byte @@ -53,16 +49,11 @@ func makeKey(b byte, n int) (*Key, error) { } var ( - fakeValidDescriptor = "0123456789abcdef" - fakeSalt = bytes.Repeat([]byte{'a'}, metadata.SaltLen) - fakePassword = []byte("password") - defaultService = unix.FSCRYPT_KEY_DESC_PREFIX - - fakeValidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen) - fakeInvalidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen-1) - fakeWrappingKey, _ = makeKey(17, metadata.InternalKeyLen) + fakeSalt = bytes.Repeat([]byte{'a'}, metadata.SaltLen) + fakePassword = []byte("password") - testUser, _ = util.EffectiveUser() + fakeValidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen) + fakeWrappingKey, _ = makeKey(17, metadata.InternalKeyLen) ) // As the passphrase hashing function clears the passphrase, we need to make @@ -242,43 +233,6 @@ func TestKeyLargeResize(t *testing.T) { } } -// Adds and removes a key with various services. -func TestAddRemoveKeys(t *testing.T) { - for _, service := range []string{defaultService, "ext4:", "f2fs:"} { - validDescription := service + fakeValidDescriptor - if err := InsertPolicyKey(fakeValidPolicyKey, validDescription, testUser); err != nil { - t.Error(err) - } - if err := security.RemoveKey(validDescription, testUser); err != nil { - t.Error(err) - } - } -} - -// Adds a key twice (both should succeed) -func TestAddTwice(t *testing.T) { - validDescription := defaultService + fakeValidDescriptor - InsertPolicyKey(fakeValidPolicyKey, validDescription, testUser) - if InsertPolicyKey(fakeValidPolicyKey, validDescription, testUser) != nil { - t.Error("InsertPolicyKey should not fail if key already exists") - } - security.RemoveKey(validDescription, testUser) -} - -// Makes sure a key fails with bad policy or service -func TestBadAddKeys(t *testing.T) { - validDescription := defaultService + fakeValidDescriptor - if InsertPolicyKey(fakeInvalidPolicyKey, validDescription, testUser) == nil { - security.RemoveKey(validDescription, testUser) - t.Error("InsertPolicyKey should fail with bad policy key") - } - invalidDescription := "ext4" + fakeValidDescriptor - if InsertPolicyKey(fakeValidPolicyKey, invalidDescription, testUser) == nil { - security.RemoveKey(invalidDescription, testUser) - t.Error("InsertPolicyKey should fail with bad service") - } -} - // Check that we can create random keys. All this test does to test the // "randomness" is generate a page of random bytes and attempts compression. // If the data can be compressed it is probably not very random. This isn't -- cgit v1.2.3 From 2b25de6d445faefc28629603dd754aec9f744e60 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 15 Dec 2019 19:31:39 -0800 Subject: Metadata support for v2 encryption policies Linux v5.4 and later supports v2 encryption policies. These have several advantages over v1 encryption policies: - Their encryption keys can be added/removed to/from the filesystem by non-root users, thus gaining the benefits of the filesystem keyring while also retaining support for non-root use. - They use a more standard, secure, and flexible key derivation function. Because of this, some future kernel-level fscrypt features will be implemented for v2 policies only. - They prevent a denial-of-service attack where a user could associate the wrong key with another user's encrypted files. Prepare the fscrypt tool to support v2 encryption policies by: - Adding a policy_version field to the EncryptionOptions, i.e. to the config file and to the policy metadata files. - Using the kernel-specified algorithm to compute the key descriptor for v2 policies. - Handling setting and getting v2 policies. Actually adding/removing the keys for v2 policies to/from the kernel is left for the next patch. --- crypto/crypto_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'crypto/crypto_test.go') diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index d0cef82..6eb0b02 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -464,6 +464,33 @@ func TestUnwrapWrongData(t *testing.T) { } } +func TestComputeKeyDescriptorV1(t *testing.T) { + descriptor, err := ComputeKeyDescriptor(fakeValidPolicyKey, 1) + if err != nil { + t.Fatal(err) + } + if descriptor != "8290608a029c5aae" { + t.Errorf("wrong v1 descriptor: %s", descriptor) + } +} + +func TestComputeKeyDescriptorV2(t *testing.T) { + descriptor, err := ComputeKeyDescriptor(fakeValidPolicyKey, 2) + if err != nil { + t.Fatal(err) + } + if descriptor != "2139f52bf8386ee99845818ac7e91c4a" { + t.Errorf("wrong v2 descriptor: %s", descriptor) + } +} + +func TestComputeKeyDescriptorBadVersion(t *testing.T) { + _, err := ComputeKeyDescriptor(fakeValidPolicyKey, 0) + if err == nil { + t.Error("computing key descriptor with bad version should fail") + } +} + // Run our test cases for passphrase hashing func TestPassphraseHashing(t *testing.T) { for i, testCase := range hashTestCases { -- cgit v1.2.3