aboutsummaryrefslogtreecommitdiff
path: root/metadata/checks.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/checks.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/checks.go')
-rw-r--r--metadata/checks.go35
1 files changed, 30 insertions, 5 deletions
diff --git a/metadata/checks.go b/metadata/checks.go
index 4fe4531..84fd208 100644
--- a/metadata/checks.go
+++ b/metadata/checks.go
@@ -119,7 +119,7 @@ func (p *ProtectorData) CheckValidity() error {
if err := p.WrappedKey.CheckValidity(); err != nil {
return errors.Wrap(err, "wrapped protector key")
}
- if err := util.CheckValidLength(DescriptorLen, len(p.ProtectorDescriptor)); err != nil {
+ if err := util.CheckValidLength(ProtectorDescriptorLen, len(p.ProtectorDescriptor)); err != nil {
return errors.Wrap(err, "protector descriptor")
}
@@ -138,7 +138,17 @@ func (e *EncryptionOptions) CheckValidity() error {
if err := e.Contents.CheckValidity(); err != nil {
return errors.Wrap(err, "contents encryption mode")
}
- return errors.Wrap(e.Filenames.CheckValidity(), "filenames encryption mode")
+ if err := e.Filenames.CheckValidity(); err != nil {
+ return errors.Wrap(err, "filenames encryption mode")
+ }
+ // If PolicyVersion is unset, treat it as 1.
+ if e.PolicyVersion == 0 {
+ e.PolicyVersion = 1
+ }
+ if e.PolicyVersion != 1 && e.PolicyVersion != 2 {
+ return errors.Errorf("policy version of %d is invalid", e.PolicyVersion)
+ }
+ return nil
}
// CheckValidity ensures the fields are valid and have the correct lengths.
@@ -152,7 +162,7 @@ func (w *WrappedPolicyKey) CheckValidity() error {
if err := util.CheckValidLength(PolicyKeyLen, len(w.WrappedKey.EncryptedKey)); err != nil {
return errors.Wrap(err, "encrypted key")
}
- err := util.CheckValidLength(DescriptorLen, len(w.ProtectorDescriptor))
+ err := util.CheckValidLength(ProtectorDescriptorLen, len(w.ProtectorDescriptor))
return errors.Wrap(err, "wrapping protector descriptor")
}
@@ -167,11 +177,26 @@ func (p *PolicyData) CheckValidity() error {
return errors.Wrapf(err, "policy key slot %d", i)
}
}
- if err := util.CheckValidLength(DescriptorLen, len(p.KeyDescriptor)); err != nil {
+
+ if err := p.Options.CheckValidity(); err != nil {
+ return errors.Wrap(err, "policy options")
+ }
+
+ var expectedLen int
+ switch p.Options.PolicyVersion {
+ case 1:
+ expectedLen = PolicyDescriptorLenV1
+ case 2:
+ expectedLen = PolicyDescriptorLenV2
+ default:
+ return errors.Errorf("policy version of %d is invalid", p.Options.PolicyVersion)
+ }
+
+ if err := util.CheckValidLength(expectedLen, len(p.KeyDescriptor)); err != nil {
return errors.Wrap(err, "policy key descriptor")
}
- return errors.Wrap(p.Options.CheckValidity(), "policy options")
+ return nil
}
// CheckValidity ensures the Config has all the necessary info for its Source.