aboutsummaryrefslogtreecommitdiff
path: root/metadata/policy_test.go
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-12-15 19:31:39 -0800
committerEric Biggers <ebiggers@google.com>2020-01-05 10:02:13 -0800
commit2b25de6d445faefc28629603dd754aec9f744e60 (patch)
treec2e4dd53a2ed370be5b0699ede59538d508d347d /metadata/policy_test.go
parentd0ac36dcea341ff000aca983dd80e7bef9fc30ec (diff)
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.
Diffstat (limited to 'metadata/policy_test.go')
-rw-r--r--metadata/policy_test.go63
1 files changed, 54 insertions, 9 deletions
diff --git a/metadata/policy_test.go b/metadata/policy_test.go
index ad9dd80..3c0704a 100644
--- a/metadata/policy_test.go
+++ b/metadata/policy_test.go
@@ -26,17 +26,30 @@ import (
"testing"
"github.com/golang/protobuf/proto"
+ "golang.org/x/sys/unix"
"github.com/google/fscrypt/util"
)
-const goodDescriptor = "0123456789abcdef"
+const goodV1Descriptor = "0123456789abcdef"
-var goodPolicy = &PolicyData{
- KeyDescriptor: goodDescriptor,
+var goodV1Policy = &PolicyData{
+ KeyDescriptor: goodV1Descriptor,
Options: DefaultOptions,
}
+var goodV2EncryptionOptions = &EncryptionOptions{
+ Padding: 32,
+ Contents: EncryptionOptions_AES_256_XTS,
+ Filenames: EncryptionOptions_AES_256_CTS,
+ PolicyVersion: 2,
+}
+
+var goodV2Policy = &PolicyData{
+ KeyDescriptor: "0123456789abcdef0123456789abcdef",
+ Options: goodV2EncryptionOptions,
+}
+
// Creates a temporary directory for testing.
func createTestDirectory(t *testing.T) (directory string, err error) {
baseDirectory, err := util.TestRoot()
@@ -83,7 +96,7 @@ func TestSetPolicyEmptyDirectory(t *testing.T) {
}
defer os.RemoveAll(directory)
- if err = SetPolicy(directory, goodPolicy); err != nil {
+ if err = SetPolicy(directory, goodV1Policy); err != nil {
t.Error(err)
}
}
@@ -96,7 +109,7 @@ func TestSetPolicyNonemptyDirectory(t *testing.T) {
}
defer os.RemoveAll(directory)
- if err = SetPolicy(directory, goodPolicy); err == nil {
+ if err = SetPolicy(directory, goodV1Policy); err == nil {
t.Error("should have failed to set policy on a nonempty directory")
}
}
@@ -109,7 +122,7 @@ func TestSetPolicyFile(t *testing.T) {
}
defer os.RemoveAll(directory)
- if err = SetPolicy(file, goodPolicy); err == nil {
+ if err = SetPolicy(file, goodV1Policy); err == nil {
t.Error("should have failed to set policy on a file")
}
}
@@ -141,15 +154,15 @@ func TestGetPolicyEmptyDirectory(t *testing.T) {
defer os.RemoveAll(directory)
var actualPolicy *PolicyData
- if err = SetPolicy(directory, goodPolicy); err != nil {
+ if err = SetPolicy(directory, goodV1Policy); err != nil {
t.Fatal(err)
}
if actualPolicy, err = GetPolicy(directory); err != nil {
t.Fatal(err)
}
- if !proto.Equal(actualPolicy, goodPolicy) {
- t.Errorf("policy %+v does not equal expected policy %+v", actualPolicy, goodPolicy)
+ if !proto.Equal(actualPolicy, goodV1Policy) {
+ t.Errorf("policy %+v does not equal expected policy %+v", actualPolicy, goodV1Policy)
}
}
@@ -165,3 +178,35 @@ func TestGetPolicyUnencrypted(t *testing.T) {
t.Error("should have failed to set policy on a file")
}
}
+
+func requireV2PolicySupport(t *testing.T, directory string) {
+ file, err := os.Open(directory)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer file.Close()
+
+ err = policyIoctl(file, unix.FS_IOC_GET_ENCRYPTION_POLICY_EX, nil)
+ if err == ErrEncryptionNotSupported {
+ t.Skip("No support for v2 encryption policies, skipping test")
+ }
+}
+
+// Tests that a non-root user cannot set a v2 encryption policy unless the key
+// has been added.
+func TestSetV2PolicyNoKey(t *testing.T) {
+ if util.IsUserRoot() {
+ t.Skip("This test cannot be run as root")
+ }
+ directory, err := createTestDirectory(t)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(directory)
+ requireV2PolicySupport(t, directory)
+
+ err = SetPolicy(directory, goodV2Policy)
+ if err == nil {
+ t.Error("shouldn't have been able to set v2 policy without key added")
+ }
+}