cephfs: create a new blank key sized according to the passphrase

Padding a passphrase with null chars to arrive at a 32-byte length
later forces a user to also pass null chars via the term when
attempting to manually unlock a subvolume via the fscrypt cli tools.

This also had a side-effect of truncating any longer length passphrase
down to a shorter 32-byte length.

fixup for:
cfea8d7562
dd0e1988c0

Signed-off-by: Michael Fritch <mfritch@suse.com>
This commit is contained in:
Michael Fritch 2024-02-26 14:08:05 -07:00 committed by mergify[bot]
parent 2368df7e69
commit 3410687855

View File

@ -95,11 +95,12 @@ func getPassphrase(ctx context.Context, encryption util.VolumeEncryption, volID
} }
// createKeyFuncFromVolumeEncryption returns an fscrypt key function returning // createKeyFuncFromVolumeEncryption returns an fscrypt key function returning
// encryption keys form a VolumeEncryption struct. // encryption keys from a VolumeEncryption struct.
func createKeyFuncFromVolumeEncryption( func createKeyFuncFromVolumeEncryption(
ctx context.Context, ctx context.Context,
encryption util.VolumeEncryption, encryption util.VolumeEncryption,
volID string, volID string,
keySize int,
) (func(fscryptactions.ProtectorInfo, bool) (*fscryptcrypto.Key, error), error) { ) (func(fscryptactions.ProtectorInfo, bool) (*fscryptcrypto.Key, error), error) {
keyFunc := func(info fscryptactions.ProtectorInfo, retry bool) (*fscryptcrypto.Key, error) { keyFunc := func(info fscryptactions.ProtectorInfo, retry bool) (*fscryptcrypto.Key, error) {
if retry { if retry {
@ -111,7 +112,10 @@ func createKeyFuncFromVolumeEncryption(
return nil, err return nil, err
} }
key, err := fscryptcrypto.NewBlankKey(encryptionPassphraseSize / 2) if keySize < 0 {
keySize = len(passphrase)
}
key, err := fscryptcrypto.NewBlankKey(keySize)
copy(key.Data(), passphrase) copy(key.Data(), passphrase)
return key, err return key, err
@ -139,6 +143,8 @@ func unlockExisting(
ctx context.Context, ctx context.Context,
fscryptContext *fscryptactions.Context, fscryptContext *fscryptactions.Context,
encryptedPath string, protectorName string, encryptedPath string, protectorName string,
volEncryption *util.VolumeEncryption,
volID string,
keyFn func(fscryptactions.ProtectorInfo, bool) (*fscryptcrypto.Key, error), keyFn func(fscryptactions.ProtectorInfo, bool) (*fscryptcrypto.Key, error),
) error { ) error {
var err error var err error
@ -161,11 +167,24 @@ func unlockExisting(
} }
if err = policy.Unlock(optionFn, keyFn); err != nil { if err = policy.Unlock(optionFn, keyFn); err != nil {
log.ErrorLog(ctx, "fscrypt: unlock with protector error: %v", err) // try backward compat using the old style null padded passphrase
errMsg := fmt.Sprintf("fscrypt: unlock with protector error: %v", err)
log.ErrorLog(ctx, "%s, retry using a null padded passphrase", errMsg)
keyFn, err = createKeyFuncFromVolumeEncryption(ctx, *volEncryption, volID, encryptionPassphraseSize/2)
if err != nil {
log.ErrorLog(ctx, "fscrypt: could not create key function: %v", err)
return err return err
} }
if err = policy.Unlock(optionFn, keyFn); err != nil {
log.ErrorLog(ctx, errMsg)
return err
}
}
defer func() { defer func() {
err = policy.Lock() err = policy.Lock()
if err != nil { if err != nil {
@ -355,7 +374,7 @@ func Unlock(
stagingTargetPath string, volID string, stagingTargetPath string, volID string,
) error { ) error {
// Fetches keys from KMS. Do this first to catch KMS errors before setting up anything. // Fetches keys from KMS. Do this first to catch KMS errors before setting up anything.
keyFn, err := createKeyFuncFromVolumeEncryption(ctx, *volEncryption, volID) keyFn, err := createKeyFuncFromVolumeEncryption(ctx, *volEncryption, volID, -1)
if err != nil { if err != nil {
log.ErrorLog(ctx, "fscrypt: could not create key function: %v", err) log.ErrorLog(ctx, "fscrypt: could not create key function: %v", err)
@ -428,7 +447,7 @@ func Unlock(
if kernelPolicyExists && metadataDirExists { if kernelPolicyExists && metadataDirExists {
log.DebugLog(ctx, "fscrypt: Encrypted directory already set up, policy exists") log.DebugLog(ctx, "fscrypt: Encrypted directory already set up, policy exists")
return unlockExisting(ctx, fscryptContext, encryptedPath, protectorName, keyFn) return unlockExisting(ctx, fscryptContext, encryptedPath, protectorName, volEncryption, volID, keyFn)
} }
if !kernelPolicyExists && !metadataDirExists { if !kernelPolicyExists && !metadataDirExists {