diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index d13a6cb89..045923872 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -144,7 +144,7 @@ func (cs *ControllerServer) parseVolCreateRequest(ctx context.Context, req *csi. func buildCreateVolumeResponse(ctx context.Context, req *csi.CreateVolumeRequest, rbdVol *rbdVolume) (*csi.CreateVolumeResponse, error) { if rbdVol.Encrypted { - err := rbdVol.ensureEncryptionMetadataSet(rbdImageRequiresEncryption) + err := rbdVol.setupEncryption(ctx) if err != nil { util.ErrorLog(ctx, err.Error()) return nil, status.Error(codes.Internal, err.Error()) @@ -507,10 +507,9 @@ func (cs *ControllerServer) createBackingImage(ctx context.Context, cr *util.Cre } } if rbdVol.Encrypted { - err = rbdVol.ensureEncryptionMetadataSet(rbdImageRequiresEncryption) + err = rbdVol.setupEncryption(ctx) if err != nil { - util.ErrorLog(ctx, "failed to save encryption status, deleting image %s: %s", - rbdVol, err) + util.ErrorLog(ctx, "failed to setup encroption for image %s: %v", rbdVol, err) return status.Error(codes.Internal, err.Error()) } } @@ -1138,3 +1137,24 @@ func (cs *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi NodeExpansionRequired: nodeExpansion, }, nil } + +// setupEncryption configures the metadata of the RBD image for encryption: +// - the Data-Encryption-Key (DEK) will be generated stored for use by the KMS; +// - the RBD image will be marked to support encryption in its metadata. +func (rv *rbdVolume) setupEncryption(ctx context.Context) error { + err := util.StoreNewCryptoPassphrase(rv.VolID, rv.KMS) + if err != nil { + util.ErrorLog(ctx, "failed to save encryption passphrase for "+ + "image %s: %s", rv.String(), err) + return err + } + + err = rv.ensureEncryptionMetadataSet(rbdImageRequiresEncryption) + if err != nil { + util.ErrorLog(ctx, "failed to save encryption status, deleting "+ + "image %s: %s", rv.String(), err) + return err + } + + return nil +} diff --git a/internal/rbd/nodeserver.go b/internal/rbd/nodeserver.go index b52c8b0b8..132672641 100644 --- a/internal/rbd/nodeserver.go +++ b/internal/rbd/nodeserver.go @@ -830,7 +830,7 @@ func (ns *NodeServer) processEncryptedDevice(ctx context.Context, volOptions *rb } func encryptDevice(ctx context.Context, rbdVol *rbdVolume, devicePath string) error { - passphrase, err := util.GetCryptoPassphrase(ctx, rbdVol.VolID, rbdVol.KMS) + passphrase, err := util.GetCryptoPassphrase(rbdVol.VolID, rbdVol.KMS) if err != nil { util.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v", rbdVol, err) @@ -853,7 +853,7 @@ func encryptDevice(ctx context.Context, rbdVol *rbdVolume, devicePath string) er } func openEncryptedDevice(ctx context.Context, volOptions *rbdVolume, devicePath string) (string, error) { - passphrase, err := util.GetCryptoPassphrase(ctx, volOptions.VolID, volOptions.KMS) + passphrase, err := util.GetCryptoPassphrase(volOptions.VolID, volOptions.KMS) if err != nil { util.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v", volOptions, err) diff --git a/internal/util/crypto.go b/internal/util/crypto.go index f98d2ff96..a4be18dc9 100644 --- a/internal/util/crypto.go +++ b/internal/util/crypto.go @@ -95,9 +95,10 @@ func (kms SecretsKMS) GetPassphrase(key string) (string, error) { return kms.passphrase, nil } -// SavePassphrase is not implemented. +// SavePassphrase does nothing, as there is no passphrase per key (volume), so +// no need to store is anywhere. func (kms SecretsKMS) SavePassphrase(key, value string) error { - return fmt.Errorf("save new passphrase is not implemented for Kubernetes secrets") + return nil } // DeletePassphrase is doing nothing as no new passphrases are saved with @@ -171,27 +172,26 @@ func GetKMS(tenant, kmsID string, secrets map[string]string) (EncryptionKMS, err return nil, fmt.Errorf("unknown encryption KMS type %s", kmsType) } +// StoreNewCryptoPassphrase generates a new passphrase and saves it in the KMS. +func StoreNewCryptoPassphrase(volumeID string, kms EncryptionKMS) error { + passphrase, err := generateNewEncryptionPassphrase() + if err != nil { + return fmt.Errorf("failed to generate passphrase for %s: %w", volumeID, err) + } + err = kms.SavePassphrase(volumeID, passphrase) + if err != nil { + return fmt.Errorf("failed to save the passphrase for %s: %w", volumeID, err) + } + return nil +} + // GetCryptoPassphrase Retrieves passphrase to encrypt volume. -func GetCryptoPassphrase(ctx context.Context, volumeID string, kms EncryptionKMS) (string, error) { +func GetCryptoPassphrase(volumeID string, kms EncryptionKMS) (string, error) { passphrase, err := kms.GetPassphrase(volumeID) - if err == nil { - return passphrase, nil + if err != nil { + return "", err } - if _, ok := err.(MissingPassphrase); ok { - DebugLog(ctx, "Encryption passphrase is missing for %s. Generating a new one", - volumeID) - passphrase, err = generateNewEncryptionPassphrase() - if err != nil { - return "", fmt.Errorf("failed to generate passphrase for %s: %w", volumeID, err) - } - err = kms.SavePassphrase(volumeID, passphrase) - if err != nil { - return "", fmt.Errorf("failed to save the passphrase for %s: %w", volumeID, err) - } - return passphrase, nil - } - ErrorLog(ctx, "failed to get encryption passphrase for %s: %s", volumeID, err) - return "", err + return passphrase, nil } // generateNewEncryptionPassphrase generates a random passphrase for encryption.