From 13bc8a6a344c6bfbf685f9e6a3e55f87cef066e4 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 27 Nov 2019 11:28:14 -0800 Subject: [PATCH 1/2] Upgrade to latest golang.org/x/sys module Upgrade to get the new fscrypt declarations from Linux v5.4. --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8d2ff2f7..018ca1a0 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 golang.org/x/lint v0.0.0-20190930215403-16217165b5de - golang.org/x/sys v0.0.0-20190412213103-97732733099d + golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 golang.org/x/tools v0.0.0-20191025023517-2077df36852e honnef.co/go/tools v0.0.1-2019.2.3 ) diff --git a/go.sum b/go.sum index 1a7fcc49..bcd7ff61 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE= +golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= From 82d01438a66212ce802721397a62c18a0b71b7ea Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 27 Nov 2019 11:28:14 -0800 Subject: [PATCH 2/2] Use latest fscrypt declarations from sys/unix Use the new name for fscrypt constants and structures which have been given a new name. Also use the named constant for the DIRECT_KEY fscrypt policy flag. No change in behavior. This is just preparing for future work. --- actions/context.go | 2 +- crypto/crypto_test.go | 2 +- metadata/constants.go | 4 ++-- metadata/metadata.pb.go | 24 ++++++++++++------------ metadata/metadata.proto | 2 +- metadata/policy.go | 21 ++++++++++----------- 6 files changed, 27 insertions(+), 28 deletions(-) diff --git a/actions/context.go b/actions/context.go index 830ad038..894d941b 100644 --- a/actions/context.go +++ b/actions/context.go @@ -142,7 +142,7 @@ func (ctx *Context) getService() string { return ctx.Mount.FilesystemType + ":" } } - return unix.FS_KEY_DESC_PREFIX + return unix.FSCRYPT_KEY_DESC_PREFIX } // getProtectorOption returns the ProtectorOption for the protector on the diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index a8d98300..6f973ef3 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -56,7 +56,7 @@ var ( fakeValidDescriptor = "0123456789abcdef" fakeSalt = bytes.Repeat([]byte{'a'}, metadata.SaltLen) fakePassword = []byte("password") - defaultService = unix.FS_KEY_DESC_PREFIX + defaultService = unix.FSCRYPT_KEY_DESC_PREFIX fakeValidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen) fakeInvalidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen-1) diff --git a/metadata/constants.go b/metadata/constants.go index 344f955d..8855ae36 100644 --- a/metadata/constants.go +++ b/metadata/constants.go @@ -28,7 +28,7 @@ import ( // Lengths for our keys, buffers, and strings used in fscrypt. const ( // DescriptorLen is the length of all Protector and Policy descriptors. - DescriptorLen = 2 * unix.FS_KEY_DESCRIPTOR_SIZE + DescriptorLen = 2 * unix.FSCRYPT_KEY_DESCRIPTOR_SIZE // We always use 256-bit keys internally (compared to 512-bit policy keys). InternalKeyLen = 32 IVLen = 16 @@ -36,7 +36,7 @@ const ( // We use SHA256 for the HMAC, and len(HMAC) == len(hash size). HMACLen = sha256.Size // PolicyKeyLen is the length of all keys passed directly to the Keyring - PolicyKeyLen = unix.FS_MAX_KEY_SIZE + PolicyKeyLen = unix.FSCRYPT_MAX_KEY_SIZE ) var ( diff --git a/metadata/metadata.pb.go b/metadata/metadata.pb.go index 2b62a917..bd3ee2a4 100644 --- a/metadata/metadata.pb.go +++ b/metadata/metadata.pb.go @@ -45,10 +45,10 @@ func (x SourceType) String() string { return proto.EnumName(SourceType_name, int32(x)) } func (SourceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{0} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{0} } -// Type of encryption; should match declarations of unix.FS_ENCRYPTION_MODE +// Type of encryption; should match declarations of unix.FSCRYPT_MODE type EncryptionOptions_Mode int32 const ( @@ -87,7 +87,7 @@ func (x EncryptionOptions_Mode) String() string { return proto.EnumName(EncryptionOptions_Mode_name, int32(x)) } func (EncryptionOptions_Mode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{3, 0} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{3, 0} } // Cost parameters to be used in our hashing functions. @@ -104,7 +104,7 @@ func (m *HashingCosts) Reset() { *m = HashingCosts{} } func (m *HashingCosts) String() string { return proto.CompactTextString(m) } func (*HashingCosts) ProtoMessage() {} func (*HashingCosts) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{0} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{0} } func (m *HashingCosts) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_HashingCosts.Unmarshal(m, b) @@ -159,7 +159,7 @@ func (m *WrappedKeyData) Reset() { *m = WrappedKeyData{} } func (m *WrappedKeyData) String() string { return proto.CompactTextString(m) } func (*WrappedKeyData) ProtoMessage() {} func (*WrappedKeyData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{1} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{1} } func (m *WrappedKeyData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_WrappedKeyData.Unmarshal(m, b) @@ -219,7 +219,7 @@ func (m *ProtectorData) Reset() { *m = ProtectorData{} } func (m *ProtectorData) String() string { return proto.CompactTextString(m) } func (*ProtectorData) ProtoMessage() {} func (*ProtectorData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{2} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{2} } func (m *ProtectorData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ProtectorData.Unmarshal(m, b) @@ -302,7 +302,7 @@ func (m *EncryptionOptions) Reset() { *m = EncryptionOptions{} } func (m *EncryptionOptions) String() string { return proto.CompactTextString(m) } func (*EncryptionOptions) ProtoMessage() {} func (*EncryptionOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{3} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{3} } func (m *EncryptionOptions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EncryptionOptions.Unmarshal(m, b) @@ -355,7 +355,7 @@ func (m *WrappedPolicyKey) Reset() { *m = WrappedPolicyKey{} } func (m *WrappedPolicyKey) String() string { return proto.CompactTextString(m) } func (*WrappedPolicyKey) ProtoMessage() {} func (*WrappedPolicyKey) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{4} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{4} } func (m *WrappedPolicyKey) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_WrappedPolicyKey.Unmarshal(m, b) @@ -403,7 +403,7 @@ func (m *PolicyData) Reset() { *m = PolicyData{} } func (m *PolicyData) String() string { return proto.CompactTextString(m) } func (*PolicyData) ProtoMessage() {} func (*PolicyData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{5} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{5} } func (m *PolicyData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PolicyData.Unmarshal(m, b) @@ -459,7 +459,7 @@ func (m *Config) Reset() { *m = Config{} } func (m *Config) String() string { return proto.CompactTextString(m) } func (*Config) ProtoMessage() {} func (*Config) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_5e732a616277e389, []int{6} + return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{6} } func (m *Config) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Config.Unmarshal(m, b) @@ -519,9 +519,9 @@ func init() { proto.RegisterEnum("metadata.EncryptionOptions_Mode", EncryptionOptions_Mode_name, EncryptionOptions_Mode_value) } -func init() { proto.RegisterFile("metadata/metadata.proto", fileDescriptor_metadata_5e732a616277e389) } +func init() { proto.RegisterFile("metadata/metadata.proto", fileDescriptor_metadata_fa046c95c3cd6aa1) } -var fileDescriptor_metadata_5e732a616277e389 = []byte{ +var fileDescriptor_metadata_fa046c95c3cd6aa1 = []byte{ // 656 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xef, 0x6a, 0xdb, 0x3c, 0x14, 0xc6, 0x5f, 0xdb, 0x69, 0xd2, 0x9c, 0xfc, 0x79, 0x5d, 0xb5, 0x6f, 0x5f, 0xb3, 0x7d, 0x09, diff --git a/metadata/metadata.proto b/metadata/metadata.proto index 6fe0ad9e..735181e3 100644 --- a/metadata/metadata.proto +++ b/metadata/metadata.proto @@ -63,7 +63,7 @@ message ProtectorData { message EncryptionOptions { int64 padding = 1; - // Type of encryption; should match declarations of unix.FS_ENCRYPTION_MODE + // Type of encryption; should match declarations of unix.FSCRYPT_MODE enum Mode { default = 0; AES_256_XTS = 1; diff --git a/metadata/policy.go b/metadata/policy.go index 7926e9ed..f9af44a4 100644 --- a/metadata/policy.go +++ b/metadata/policy.go @@ -46,7 +46,7 @@ var ( // pointers and file descriptors to the IOCTL syscall. This function also takes // some of the unclear errors returned by the syscall and translates then into // more specific error strings. -func policyIoctl(file *os.File, request uintptr, policy *unix.FscryptPolicy) error { +func policyIoctl(file *os.File, request uintptr, policy *unix.FscryptPolicyV1) error { // The returned errno value can sometimes give strange errors, so we // return encryption specific errors. _, _, errno := unix.Syscall(unix.SYS_IOCTL, file.Fd(), request, uintptr(unsafe.Pointer(policy))) @@ -68,11 +68,11 @@ func policyIoctl(file *os.File, request uintptr, policy *unix.FscryptPolicy) err } } -// Maps EncryptionOptions.Padding <-> FscryptPolicy.Flags +// Maps EncryptionOptions.Padding <-> FSCRYPT_POLICY_FLAGS var ( paddingArray = []int64{4, 8, 16, 32} - flagsArray = []int64{unix.FS_POLICY_FLAGS_PAD_4, unix.FS_POLICY_FLAGS_PAD_8, - unix.FS_POLICY_FLAGS_PAD_16, unix.FS_POLICY_FLAGS_PAD_32} + flagsArray = []int64{unix.FSCRYPT_POLICY_FLAGS_PAD_4, unix.FSCRYPT_POLICY_FLAGS_PAD_8, + unix.FSCRYPT_POLICY_FLAGS_PAD_16, unix.FSCRYPT_POLICY_FLAGS_PAD_32} ) // GetPolicy returns the Policy data for the given directory or file (includes @@ -85,13 +85,13 @@ func GetPolicy(path string) (*PolicyData, error) { } defer file.Close() - var policy unix.FscryptPolicy + var policy unix.FscryptPolicyV1 if err = policyIoctl(file, unix.FS_IOC_GET_ENCRYPTION_POLICY, &policy); err != nil { return nil, errors.Wrapf(err, "get encryption policy %s", path) } // Convert the padding flag into an amount of padding - paddingFlag := int64(policy.Flags & unix.FS_POLICY_FLAGS_PAD_MASK) + paddingFlag := int64(policy.Flags & unix.FSCRYPT_POLICY_FLAGS_PAD_MASK) // This lookup should always succeed padding, ok := util.Lookup(paddingFlag, flagsArray, paddingArray) @@ -147,12 +147,11 @@ func SetPolicy(path string, data *PolicyData) error { } if shouldUseDirectKeyFlag(data.Options) { - // TODO: use unix.FS_POLICY_FLAG_DIRECT_KEY here once available - flags |= 0x4 + flags |= unix.FSCRYPT_POLICY_FLAG_DIRECT_KEY } - policy := unix.FscryptPolicy{ - Version: 0, // Version must always be zero + policy := unix.FscryptPolicyV1{ + Version: unix.FSCRYPT_POLICY_V1, Contents_encryption_mode: uint8(data.Options.Contents), Filenames_encryption_mode: uint8(data.Options.Filenames), Flags: uint8(flags), @@ -189,7 +188,7 @@ func CheckSupport(path string) error { defer file.Close() // On supported directories, giving a bad policy will return EINVAL - badPolicy := unix.FscryptPolicy{ + badPolicy := unix.FscryptPolicyV1{ Version: math.MaxUint8, Contents_encryption_mode: math.MaxUint8, Filenames_encryption_mode: math.MaxUint8,