Skip to content

Commit

Permalink
cephfs: create a new blank key sized according to the passphrase
Browse files Browse the repository at this point in the history
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:
cfea8d7
dd0e198

Signed-off-by: Michael Fritch <mfritch@suse.com>
  • Loading branch information
mgfritch committed Feb 27, 2024
1 parent 28265f2 commit aa4121b
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions internal/util/fscrypt/fscrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,12 @@ func getPassphrase(ctx context.Context, encryption util.VolumeEncryption, volID
}

// createKeyFuncFromVolumeEncryption returns an fscrypt key function returning
// encryption keys form a VolumeEncryption struct.
// encryption keys from a VolumeEncryption struct.
func createKeyFuncFromVolumeEncryption(
ctx context.Context,
encryption util.VolumeEncryption,
volID string,
keySize int,
) (func(fscryptactions.ProtectorInfo, bool) (*fscryptcrypto.Key, error), error) {
keyFunc := func(info fscryptactions.ProtectorInfo, retry bool) (*fscryptcrypto.Key, error) {
if retry {
Expand All @@ -111,7 +112,10 @@ func createKeyFuncFromVolumeEncryption(
return nil, err
}

key, err := fscryptcrypto.NewBlankKey(encryptionPassphraseSize / 2)
if keySize < 0 {
keySize = len(passphrase)
}
key, err := fscryptcrypto.NewBlankKey(keySize)
copy(key.Data(), passphrase)

return key, err
Expand Down Expand Up @@ -139,10 +143,10 @@ func unlockExisting(
ctx context.Context,
fscryptContext *fscryptactions.Context,
encryptedPath string, protectorName string,
volEncryption *util.VolumeEncryption,
volID string,
keyFn func(fscryptactions.ProtectorInfo, bool) (*fscryptcrypto.Key, error),
) error {
var err error

policy, err := fscryptactions.GetPolicyFromPath(fscryptContext, encryptedPath)
if err != nil {
log.ErrorLog(ctx, "fscrypt: policy get failed %v", err)
Expand All @@ -161,9 +165,22 @@ func unlockExisting(
}

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)

return err
keyFn, err := createKeyFuncFromVolumeEncryption(ctx, *volEncryption, volID, encryptionPassphraseSize/2)
if err != nil {
log.ErrorLog(ctx, "fscrypt: could not create key function: %v", err)

return err
}

if err = policy.Unlock(optionFn, keyFn); err != nil {
log.ErrorLog(ctx, errMsg)

return err
}
}

defer func() {
Expand Down Expand Up @@ -355,7 +372,7 @@ func Unlock(
stagingTargetPath string, volID string,
) error {
// 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 {
log.ErrorLog(ctx, "fscrypt: could not create key function: %v", err)

Expand Down Expand Up @@ -428,7 +445,7 @@ func Unlock(
if kernelPolicyExists && metadataDirExists {
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 {
Expand Down

0 comments on commit aa4121b

Please sign in to comment.