From b60123a036d3117d8046aa2b9311d48eb31008f5 Mon Sep 17 00:00:00 2001 From: madhu-pillai Date: Wed, 29 May 2024 22:31:54 +0530 Subject: [PATCH 1/2] add: Support LUKS encryption using IBM CEX secure keys on s390x --- base/v0_6_exp/schema.go | 5 ++ config/common/errors.go | 1 + config/fcos/v1_6_exp/schema.go | 1 + config/fcos/v1_6_exp/translate.go | 74 ++++++++++++++++++++------- config/fcos/v1_6_exp/validate.go | 29 ++++++++--- config/fcos/v1_6_exp/validate_test.go | 12 +++++ docs/config-fcos-v1_6-exp.md | 3 ++ docs/config-flatcar-v1_2-exp.md | 2 + docs/config-openshift-v4_17-exp.md | 3 ++ docs/examples.md | 13 +++++ internal/doc/butane.yaml | 10 ++++ 11 files changed, 126 insertions(+), 27 deletions(-) diff --git a/base/v0_6_exp/schema.go b/base/v0_6_exp/schema.go index 67e7b95c..1104198f 100644 --- a/base/v0_6_exp/schema.go +++ b/base/v0_6_exp/schema.go @@ -14,6 +14,10 @@ package v0_6_exp +type Cex struct { + Enabled *bool `yaml:"enabled"` +} + type Clevis struct { Custom ClevisCustom `yaml:"custom"` Tang []Tang `yaml:"tang"` @@ -119,6 +123,7 @@ type Link struct { } type Luks struct { + Cex Cex `yaml:"cex"` Clevis Clevis `yaml:"clevis"` Device *string `yaml:"device"` Discard *bool `yaml:"discard"` diff --git a/config/common/errors.go b/config/common/errors.go index 922111ab..8c016b96 100644 --- a/config/common/errors.go +++ b/config/common/errors.go @@ -59,6 +59,7 @@ var ( ErrNoLuksBootDevice = errors.New("device is required for layouts: s390x-eckd, s390x-zfcp") ErrMirrorNotSupport = errors.New("mirroring not supported on layouts: s390x-eckd, s390x-zfcp, s390x-virt") ErrLuksBootDeviceBadName = errors.New("device name must start with /dev/dasd on s390x-eckd layout or /dev/sd on s390x-zfcp layout") + ErrCexUnSupportArch = errors.New("cex does not supported architectures other than s390x") // partition ErrReuseByLabel = errors.New("partitions cannot be reused by label; number must be specified except on boot disk (/dev/disk/by-id/coreos-boot-disk) or when wipe_table is true") diff --git a/config/fcos/v1_6_exp/schema.go b/config/fcos/v1_6_exp/schema.go index 52cdfb43..73457dbb 100644 --- a/config/fcos/v1_6_exp/schema.go +++ b/config/fcos/v1_6_exp/schema.go @@ -33,6 +33,7 @@ type BootDevice struct { type BootDeviceLuks struct { Discard *bool `yaml:"discard"` Device *string `yaml:"device"` + Enabled *bool `yaml:"enabled"` Tang []base.Tang `yaml:"tang"` Threshold *int `yaml:"threshold"` Tpm2 *bool `yaml:"tpm2"` diff --git a/config/fcos/v1_6_exp/translate.go b/config/fcos/v1_6_exp/translate.go index a7c0a679..9faacaa3 100644 --- a/config/fcos/v1_6_exp/translate.go +++ b/config/fcos/v1_6_exp/translate.go @@ -114,7 +114,7 @@ func (c Config) processBootDevice(config *types.Config, ts *translate.Translatio var r report.Report // check for high-level features - wantLuks := util.IsTrue(c.BootDevice.Luks.Tpm2) || len(c.BootDevice.Luks.Tang) > 0 + wantLuks := util.IsTrue(c.BootDevice.Luks.Tpm2) || len(c.BootDevice.Luks.Tang) > 0 || util.IsTrue(c.BootDevice.Luks.Enabled) wantMirror := len(c.BootDevice.Mirror.Devices) > 0 if !wantLuks && !wantMirror { return r @@ -252,25 +252,47 @@ func (c Config) processBootDevice(config *types.Config, ts *translate.Translatio default: luksDevice = "/dev/disk/by-partlabel/root" } - clevis, ts2, r2 := translateBootDeviceLuks(c.BootDevice.Luks, options) - rendered.Storage.Luks = []types.Luks{{ - Clevis: clevis, - Device: &luksDevice, - Discard: c.BootDevice.Luks.Discard, - Label: util.StrToPtr("luks-root"), - Name: "root", - WipeVolume: util.BoolToPtr(true), - }} - lpath := path.New("yaml", "boot_device", "luks") - rpath := path.New("json", "storage", "luks", 0) - renderedTranslations.Merge(ts2.PrefixPaths(lpath, rpath.Append("clevis"))) - renderedTranslations.AddTranslation(lpath.Append("discard"), rpath.Append("discard")) - for _, f := range []string{"device", "label", "name", "wipeVolume"} { - renderedTranslations.AddTranslation(lpath, rpath.Append(f)) + if util.IsTrue(c.BootDevice.Luks.Enabled) { + cex, ts2, r2 := translateBootDeviceLuksCex(c.BootDevice.Luks, options) + rendered.Storage.Luks = []types.Luks{{ + Cex: cex, + Device: &luksDevice, + Discard: c.BootDevice.Luks.Discard, + Label: util.StrToPtr("luks-root"), + Name: "root", + WipeVolume: util.BoolToPtr(true), + }} + lpath := path.New("yaml", "boot_device", "luks") + rpath := path.New("json", "storage", "luks", 0) + renderedTranslations.Merge(ts2.PrefixPaths(lpath, rpath.Append("cex"))) + renderedTranslations.AddTranslation(lpath.Append("discard"), rpath.Append("discard")) + for _, f := range []string{"device", "label", "name", "wipeVolume"} { + renderedTranslations.AddTranslation(lpath, rpath.Append(f)) + } + renderedTranslations.AddTranslation(lpath, rpath) + renderedTranslations.AddTranslation(lpath, path.New("json", "storage", "luks")) + r.Merge(r2) + } else { + clevis, ts2, r2 := translateBootDeviceLuks(c.BootDevice.Luks, options) + rendered.Storage.Luks = []types.Luks{{ + Clevis: clevis, + Device: &luksDevice, + Discard: c.BootDevice.Luks.Discard, + Label: util.StrToPtr("luks-root"), + Name: "root", + WipeVolume: util.BoolToPtr(true), + }} + lpath := path.New("yaml", "boot_device", "luks") + rpath := path.New("json", "storage", "luks", 0) + renderedTranslations.Merge(ts2.PrefixPaths(lpath, rpath.Append("clevis"))) + renderedTranslations.AddTranslation(lpath.Append("discard"), rpath.Append("discard")) + for _, f := range []string{"device", "label", "name", "wipeVolume"} { + renderedTranslations.AddTranslation(lpath, rpath.Append(f)) + } + renderedTranslations.AddTranslation(lpath, rpath) + renderedTranslations.AddTranslation(lpath, path.New("json", "storage", "luks")) + r.Merge(r2) } - renderedTranslations.AddTranslation(lpath, rpath) - renderedTranslations.AddTranslation(lpath, path.New("json", "storage", "luks")) - r.Merge(r2) } // create root filesystem @@ -317,6 +339,20 @@ func translateBootDeviceLuks(from BootDeviceLuks, options common.TranslateOption return } +func translateBootDeviceLuksCex(from BootDeviceLuks, options common.TranslateOptions) (to types.Cex, tm translate.TranslationSet, r report.Report) { + tr := translate.NewTranslator("yaml", "json", options) + // Discard field is handled by the caller because it doesn't go + // into types.Cex + tm, r = translate.Prefixed(tr, "enabled", &from.Enabled, &to.Enabled) + //translate.MergeP(tr, tm, &r, "threshold", &from.Threshold, &to.Threshold) + translate.MergeP(tr, tm, &r, "enabled", &from.Enabled, &to.Enabled) + // we're being called manually, not via the translate package's + // custom translator mechanism, so we have to add the base + // translation ourselves + tm.AddTranslation(path.New("yaml"), path.New("json")) + return +} + func (c Config) handleUserGrubCfg(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { rendered := types.Config{} ts := translate.NewTranslationSet("yaml", "json") diff --git a/config/fcos/v1_6_exp/validate.go b/config/fcos/v1_6_exp/validate.go index 481e3d84..24065d09 100644 --- a/config/fcos/v1_6_exp/validate.go +++ b/config/fcos/v1_6_exp/validate.go @@ -18,6 +18,7 @@ import ( "regexp" "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/shared/errors" "github.com/coreos/ignition/v2/config/util" "github.com/coreos/vcontext/path" @@ -51,31 +52,43 @@ func (conf Config) Validate(c path.ContextPath) (r report.Report) { } func (d BootDevice) Validate(c path.ContextPath) (r report.Report) { - if d.Layout != nil { - switch *d.Layout { + var layout = d.Layout + if layout != nil { + switch *layout { case "aarch64", "ppc64le", "x86_64": + if util.IsTrue(d.Luks.Enabled) { + r.AddOnError(c.Append(*layout), common.ErrCexUnSupportArch) + } case "s390x-eckd": if util.NilOrEmpty(d.Luks.Device) { - r.AddOnError(c.Append(*d.Layout), common.ErrNoLuksBootDevice) + r.AddOnError(c.Append(*layout), common.ErrNoLuksBootDevice) } else if !dasdRe.MatchString(*d.Luks.Device) { - r.AddOnError(c.Append(*d.Layout), common.ErrLuksBootDeviceBadName) + r.AddOnError(c.Append(*layout), common.ErrLuksBootDeviceBadName) } case "s390x-zfcp": if util.NilOrEmpty(d.Luks.Device) { - r.AddOnError(c.Append(*d.Layout), common.ErrNoLuksBootDevice) + r.AddOnError(c.Append(*layout), common.ErrNoLuksBootDevice) } else if !sdRe.MatchString(*d.Luks.Device) { - r.AddOnError(c.Append(*d.Layout), common.ErrLuksBootDeviceBadName) + r.AddOnError(c.Append(*layout), common.ErrLuksBootDeviceBadName) } case "s390x-virt": default: r.AddOnError(c.Append("layout"), common.ErrUnknownBootDeviceLayout) } - if *d.Layout == "s390x-eckd" || *d.Layout == "s390x-zfcp" || *d.Layout == "s390x-virt" { + if *layout == "s390x-eckd" || *layout == "s390x-zfcp" || *layout == "s390x-virt" { if len(d.Mirror.Devices) > 0 { - r.AddOnError(c.Append(*d.Layout), common.ErrMirrorNotSupport) + r.AddOnError(c.Append(*layout), common.ErrMirrorNotSupport) } } + + if util.IsTrue(d.Luks.Enabled) && (len(d.Luks.Tang) > 0 || util.IsTrue(d.Luks.Tpm2)) { + r.AddOnError(c.Append("luks"), errors.ErrCexWithClevis) + } + } + + if layout == nil && util.IsTrue(d.Luks.Enabled) { + r.AddOnError(c.Append("cex"), common.ErrCexUnSupportArch) } r.Merge(d.Mirror.Validate(c.Append("mirror"))) return diff --git a/config/fcos/v1_6_exp/validate_test.go b/config/fcos/v1_6_exp/validate_test.go index 2c850580..258f1d3a 100644 --- a/config/fcos/v1_6_exp/validate_test.go +++ b/config/fcos/v1_6_exp/validate_test.go @@ -161,6 +161,18 @@ func TestValidateBootDevice(t *testing.T) { nil, path.New("yaml"), }, + // complete config with cex + { + BootDevice{ + Layout: util.StrToPtr("s390x-eckd"), + Luks: BootDeviceLuks{ + Device: util.StrToPtr("/dev/dasda"), + Enabled: util.BoolToPtr(true), + }, + }, + nil, + path.New("yaml"), + }, // invalid layout { BootDevice{ diff --git a/docs/config-fcos-v1_6-exp.md b/docs/config-fcos-v1_6-exp.md index 6f8a4d1c..0d4ce78a 100644 --- a/docs/config-fcos-v1_6-exp.md +++ b/docs/config-fcos-v1_6-exp.md @@ -168,6 +168,8 @@ The Fedora CoreOS configuration is a YAML document conforming to the following s * **pin** (string): the clevis pin. * **config** (string): the clevis configuration JSON. * **_needs_network_** (boolean): whether or not the device requires networking. + * **_cex_** (object): describes the IBM Crypto Express (CEX) card configuration for the luks device. + * **_enabled_** (boolean): whether or not to use a CEX secure key to encrypt the luks device. * **_trees_** (list of objects): a list of local directory trees to be embedded in the config. Ownership is not preserved. File modes are set to 0755 if the local file is executable or 0644 otherwise. Attributes of files, directories, and symlinks can be overridden by creating a corresponding entry in the `files`, `directories`, or `links` section; such `files` entries must omit `contents` and such `links` entries must omit `target`. * **local** (string): the base of the local directory tree, relative to the directory specified by the `--files-dir` command-line argument. * **_path_** (string): the path of the tree within the target system. Defaults to `/`. @@ -219,6 +221,7 @@ The Fedora CoreOS configuration is a YAML document conforming to the following s * **_tpm2_** (boolean): whether or not to use a tpm2 device. * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. + * **_enabled_** (boolean): UnSupported * **_mirror_** (object): describes mirroring of the boot disk for fault tolerance. * **_devices_** (list of strings): the list of whole-disk devices (not partitions) to include in the disk array, referenced by their absolute path. At least two devices must be specified. * **_grub_** (object): describes the desired GRUB bootloader configuration. diff --git a/docs/config-flatcar-v1_2-exp.md b/docs/config-flatcar-v1_2-exp.md index 22a907e6..c6650360 100644 --- a/docs/config-flatcar-v1_2-exp.md +++ b/docs/config-flatcar-v1_2-exp.md @@ -168,6 +168,8 @@ The Flatcar configuration is a YAML document conforming to the following specifi * **pin** (string): the clevis pin. * **config** (string): the clevis configuration JSON. * **_needs_network_** (boolean): whether or not the device requires networking. + * **_cex_** (object): describes the IBM Crypto Express (CEX) card configuration for the luks device. + * **_enabled_** (boolean): whether or not to use a CEX secure key to encrypt the luks device. * **_trees_** (list of objects): a list of local directory trees to be embedded in the config. Ownership is not preserved. File modes are set to 0755 if the local file is executable or 0644 otherwise. Attributes of files, directories, and symlinks can be overridden by creating a corresponding entry in the `files`, `directories`, or `links` section; such `files` entries must omit `contents` and such `links` entries must omit `target`. * **local** (string): the base of the local directory tree, relative to the directory specified by the `--files-dir` command-line argument. * **_path_** (string): the path of the tree within the target system. Defaults to `/`. diff --git a/docs/config-openshift-v4_17-exp.md b/docs/config-openshift-v4_17-exp.md index 99a4e3f5..a6cdbb66 100644 --- a/docs/config-openshift-v4_17-exp.md +++ b/docs/config-openshift-v4_17-exp.md @@ -137,6 +137,8 @@ The OpenShift configuration is a YAML document conforming to the following speci * **pin** (string): the clevis pin. * **config** (string): the clevis configuration JSON. * **_needs_network_** (boolean): whether or not the device requires networking. + * **_cex_** (object): describes the IBM Crypto Express (CEX) card configuration for the luks device. + * **_enabled_** (boolean): whether or not to use a CEX secure key to encrypt the luks device. * **_trees_** (list of objects): a list of local directory trees to be embedded in the config. Symlinks must not be present. Ownership is not preserved. File modes are set to 0755 if the local file is executable or 0644 otherwise. File attributes can be overridden by creating a corresponding entry in the `files` section; such entries must omit `contents`. * **local** (string): the base of the local directory tree, relative to the directory specified by the `--files-dir` command-line argument. * **_path_** (string): the path of the tree within the target system. Defaults to `/`. @@ -168,6 +170,7 @@ The OpenShift configuration is a YAML document conforming to the following speci * **_tpm2_** (boolean): whether or not to use a tpm2 device. * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. + * **_enabled_** (boolean): UnSupported * **_mirror_** (object): describes mirroring of the boot disk for fault tolerance. * **_devices_** (list of strings): the list of whole-disk devices (not partitions) to include in the disk array, referenced by their absolute path. At least two devices must be specified. * **_grub_** (object): describes the desired GRUB bootloader configuration. diff --git a/docs/examples.md b/docs/examples.md index ee62c41c..fb29a1b3 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -340,6 +340,19 @@ boot_device: thumbprint: REPLACE-THIS-WITH-YOUR-TANG-THUMBPRINT ``` +This example uses the shortcut `boot_device` syntax to configure an encrypted root filesystem in s390x on the `dasda` DASD device unlocked with a CEX card. + + +```yaml +variant: fcos +version: 1.6.0-experimental +boot_device: + layout: s390x-eckd + luks: + device: /dev/dasda + enabled: true +``` + ### Mirrored boot disk This example replicates all default partitions on the boot disk across multiple disks, allowing the system to survive disk failure. diff --git a/internal/doc/butane.yaml b/internal/doc/butane.yaml index 8b37492d..64e1ad49 100644 --- a/internal/doc/butane.yaml +++ b/internal/doc/butane.yaml @@ -344,6 +344,16 @@ root: desc: sets the minimum number of pieces required to decrypt the device. Default is 1. - name: discard desc: whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. + - name: enabled + desc: whether or not to use a cex device. + transforms: + - regex: ".*" + replacement: "UnSupported" + if: + - variant: fcos + min: 1.6.0-experimental + - variant: openshift + min: 4.16.0-experimental - name: mirror desc: describes mirroring of the boot disk for fault tolerance. children: From 3ec0f5c35e48cc7b8783c4226c5598e8357e45f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 13:12:06 +0000 Subject: [PATCH 2/2] build(deps): bump github.com/coreos/ignition/v2 from 2.18.0 to 2.19.0 Bumps [github.com/coreos/ignition/v2](https://github.com/coreos/ignition) from 2.18.0 to 2.19.0. - [Release notes](https://github.com/coreos/ignition/releases) - [Changelog](https://github.com/coreos/ignition/blob/main/docs/release-notes.md) - [Commits](https://github.com/coreos/ignition/compare/v2.18.0...v2.19.0) --- updated-dependencies: - dependency-name: github.com/coreos/ignition/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- config/common/errors.go | 3 +- config/fcos/v1_6_exp/schema.go | 2 +- config/fcos/v1_6_exp/translate.go | 9 +++-- config/fcos/v1_6_exp/validate.go | 10 +++--- config/fcos/v1_6_exp/validate_test.go | 6 ++-- config/flatcar/v1_2_exp/translate.go | 8 ++++- docs/config-fcos-v1_6-exp.md | 3 +- docs/config-flatcar-v1_2-exp.md | 2 -- docs/config-openshift-v4_17-exp.md | 3 +- docs/examples.md | 3 +- docs/release-notes.md | 17 ++++++++++ go.mod | 4 +-- go.sum | 8 ++--- internal/doc/butane.yaml | 15 +++------ .../ignition/v2/config/doc/ignition.yaml | 5 +++ .../v2/config/shared/errors/errors.go | 2 ++ .../v2/config/v3_5_experimental/types/cex.go | 33 +++++++++++++++++++ .../v2/config/v3_5_experimental/types/luks.go | 11 +++++++ .../config/v3_5_experimental/types/schema.go | 5 +++ vendor/modules.txt | 4 +-- 20 files changed, 115 insertions(+), 38 deletions(-) create mode 100644 vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/cex.go diff --git a/config/common/errors.go b/config/common/errors.go index 8c016b96..71f3c0d2 100644 --- a/config/common/errors.go +++ b/config/common/errors.go @@ -59,7 +59,8 @@ var ( ErrNoLuksBootDevice = errors.New("device is required for layouts: s390x-eckd, s390x-zfcp") ErrMirrorNotSupport = errors.New("mirroring not supported on layouts: s390x-eckd, s390x-zfcp, s390x-virt") ErrLuksBootDeviceBadName = errors.New("device name must start with /dev/dasd on s390x-eckd layout or /dev/sd on s390x-zfcp layout") - ErrCexUnSupportArch = errors.New("cex does not supported architectures other than s390x") + ErrCexArchitectureMismatch = errors.New("when using cex the targeted architecture must match s390x") + ErrCexNotSupported = errors.New("cex is not currently supported on the target platform") // partition ErrReuseByLabel = errors.New("partitions cannot be reused by label; number must be specified except on boot disk (/dev/disk/by-id/coreos-boot-disk) or when wipe_table is true") diff --git a/config/fcos/v1_6_exp/schema.go b/config/fcos/v1_6_exp/schema.go index 73457dbb..c72795ca 100644 --- a/config/fcos/v1_6_exp/schema.go +++ b/config/fcos/v1_6_exp/schema.go @@ -31,9 +31,9 @@ type BootDevice struct { } type BootDeviceLuks struct { + Cex base.Cex `yaml:"cex"` Discard *bool `yaml:"discard"` Device *string `yaml:"device"` - Enabled *bool `yaml:"enabled"` Tang []base.Tang `yaml:"tang"` Threshold *int `yaml:"threshold"` Tpm2 *bool `yaml:"tpm2"` diff --git a/config/fcos/v1_6_exp/translate.go b/config/fcos/v1_6_exp/translate.go index 9faacaa3..e9a7ae2e 100644 --- a/config/fcos/v1_6_exp/translate.go +++ b/config/fcos/v1_6_exp/translate.go @@ -114,7 +114,7 @@ func (c Config) processBootDevice(config *types.Config, ts *translate.Translatio var r report.Report // check for high-level features - wantLuks := util.IsTrue(c.BootDevice.Luks.Tpm2) || len(c.BootDevice.Luks.Tang) > 0 || util.IsTrue(c.BootDevice.Luks.Enabled) + wantLuks := util.IsTrue(c.BootDevice.Luks.Tpm2) || len(c.BootDevice.Luks.Tang) > 0 || util.IsTrue(c.BootDevice.Luks.Cex.Enabled) wantMirror := len(c.BootDevice.Mirror.Devices) > 0 if !wantLuks && !wantMirror { return r @@ -252,7 +252,7 @@ func (c Config) processBootDevice(config *types.Config, ts *translate.Translatio default: luksDevice = "/dev/disk/by-partlabel/root" } - if util.IsTrue(c.BootDevice.Luks.Enabled) { + if util.IsTrue(c.BootDevice.Luks.Cex.Enabled) { cex, ts2, r2 := translateBootDeviceLuksCex(c.BootDevice.Luks, options) rendered.Storage.Luks = []types.Luks{{ Cex: cex, @@ -343,9 +343,8 @@ func translateBootDeviceLuksCex(from BootDeviceLuks, options common.TranslateOpt tr := translate.NewTranslator("yaml", "json", options) // Discard field is handled by the caller because it doesn't go // into types.Cex - tm, r = translate.Prefixed(tr, "enabled", &from.Enabled, &to.Enabled) - //translate.MergeP(tr, tm, &r, "threshold", &from.Threshold, &to.Threshold) - translate.MergeP(tr, tm, &r, "enabled", &from.Enabled, &to.Enabled) + tm, r = translate.Prefixed(tr, "enabled", &from.Cex.Enabled, &to.Enabled) + translate.MergeP(tr, tm, &r, "enabled", &from.Cex.Enabled, &to.Enabled) // we're being called manually, not via the translate package's // custom translator mechanism, so we have to add the base // translation ourselves diff --git a/config/fcos/v1_6_exp/validate.go b/config/fcos/v1_6_exp/validate.go index 24065d09..e9a7c2b6 100644 --- a/config/fcos/v1_6_exp/validate.go +++ b/config/fcos/v1_6_exp/validate.go @@ -56,8 +56,8 @@ func (d BootDevice) Validate(c path.ContextPath) (r report.Report) { if layout != nil { switch *layout { case "aarch64", "ppc64le", "x86_64": - if util.IsTrue(d.Luks.Enabled) { - r.AddOnError(c.Append(*layout), common.ErrCexUnSupportArch) + if util.IsTrue(d.Luks.Cex.Enabled) { + r.AddOnError(c.Append(*layout), common.ErrCexArchitectureMismatch) } case "s390x-eckd": if util.NilOrEmpty(d.Luks.Device) { @@ -82,13 +82,13 @@ func (d BootDevice) Validate(c path.ContextPath) (r report.Report) { } } - if util.IsTrue(d.Luks.Enabled) && (len(d.Luks.Tang) > 0 || util.IsTrue(d.Luks.Tpm2)) { + if util.IsTrue(d.Luks.Cex.Enabled) && (len(d.Luks.Tang) > 0 || util.IsTrue(d.Luks.Tpm2)) { r.AddOnError(c.Append("luks"), errors.ErrCexWithClevis) } } - if layout == nil && util.IsTrue(d.Luks.Enabled) { - r.AddOnError(c.Append("cex"), common.ErrCexUnSupportArch) + if layout == nil && util.IsTrue(d.Luks.Cex.Enabled) { + r.AddOnError(c.Append("cex"), common.ErrCexArchitectureMismatch) } r.Merge(d.Mirror.Validate(c.Append("mirror"))) return diff --git a/config/fcos/v1_6_exp/validate_test.go b/config/fcos/v1_6_exp/validate_test.go index 258f1d3a..6c8df2a7 100644 --- a/config/fcos/v1_6_exp/validate_test.go +++ b/config/fcos/v1_6_exp/validate_test.go @@ -166,8 +166,10 @@ func TestValidateBootDevice(t *testing.T) { BootDevice{ Layout: util.StrToPtr("s390x-eckd"), Luks: BootDeviceLuks{ - Device: util.StrToPtr("/dev/dasda"), - Enabled: util.BoolToPtr(true), + Device: util.StrToPtr("/dev/dasda"), + Cex: base.Cex{ + Enabled: util.BoolToPtr(true), + }, }, }, nil, diff --git a/config/flatcar/v1_2_exp/translate.go b/config/flatcar/v1_2_exp/translate.go index e74b6f40..e712d00d 100644 --- a/config/flatcar/v1_2_exp/translate.go +++ b/config/flatcar/v1_2_exp/translate.go @@ -22,9 +22,15 @@ import ( "github.com/coreos/vcontext/report" ) +var ( + fieldFilters = cutil.NewFilters(types.Config{}, cutil.FilterMap{ + "storage.luks.cex": common.ErrCexNotSupported, + }) +) + // Return FieldFilters for this spec. func (c Config) FieldFilters() *cutil.FieldFilters { - return nil + return &fieldFilters } // ToIgn3_5 translates the config to an Ignition config. It returns a diff --git a/docs/config-fcos-v1_6-exp.md b/docs/config-fcos-v1_6-exp.md index 0d4ce78a..41c695c2 100644 --- a/docs/config-fcos-v1_6-exp.md +++ b/docs/config-fcos-v1_6-exp.md @@ -221,7 +221,8 @@ The Fedora CoreOS configuration is a YAML document conforming to the following s * **_tpm2_** (boolean): whether or not to use a tpm2 device. * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. - * **_enabled_** (boolean): UnSupported + * **_cex_** (object): describes the IBM Crypto Express (CEX) card configuration for the luks device. + * **_enabled_** (boolean): whether or not to enable cex compatibility for luks. If omitted, defaults to false. * **_mirror_** (object): describes mirroring of the boot disk for fault tolerance. * **_devices_** (list of strings): the list of whole-disk devices (not partitions) to include in the disk array, referenced by their absolute path. At least two devices must be specified. * **_grub_** (object): describes the desired GRUB bootloader configuration. diff --git a/docs/config-flatcar-v1_2-exp.md b/docs/config-flatcar-v1_2-exp.md index c6650360..22a907e6 100644 --- a/docs/config-flatcar-v1_2-exp.md +++ b/docs/config-flatcar-v1_2-exp.md @@ -168,8 +168,6 @@ The Flatcar configuration is a YAML document conforming to the following specifi * **pin** (string): the clevis pin. * **config** (string): the clevis configuration JSON. * **_needs_network_** (boolean): whether or not the device requires networking. - * **_cex_** (object): describes the IBM Crypto Express (CEX) card configuration for the luks device. - * **_enabled_** (boolean): whether or not to use a CEX secure key to encrypt the luks device. * **_trees_** (list of objects): a list of local directory trees to be embedded in the config. Ownership is not preserved. File modes are set to 0755 if the local file is executable or 0644 otherwise. Attributes of files, directories, and symlinks can be overridden by creating a corresponding entry in the `files`, `directories`, or `links` section; such `files` entries must omit `contents` and such `links` entries must omit `target`. * **local** (string): the base of the local directory tree, relative to the directory specified by the `--files-dir` command-line argument. * **_path_** (string): the path of the tree within the target system. Defaults to `/`. diff --git a/docs/config-openshift-v4_17-exp.md b/docs/config-openshift-v4_17-exp.md index a6cdbb66..05c1d046 100644 --- a/docs/config-openshift-v4_17-exp.md +++ b/docs/config-openshift-v4_17-exp.md @@ -170,7 +170,8 @@ The OpenShift configuration is a YAML document conforming to the following speci * **_tpm2_** (boolean): whether or not to use a tpm2 device. * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. - * **_enabled_** (boolean): UnSupported + * **_cex_** (object): describes the IBM Crypto Express (CEX) card configuration for the luks device. + * **_enabled_** (boolean): whether or not to enable cex compatibility for luks. If omitted, defaults to false. * **_mirror_** (object): describes mirroring of the boot disk for fault tolerance. * **_devices_** (list of strings): the list of whole-disk devices (not partitions) to include in the disk array, referenced by their absolute path. At least two devices must be specified. * **_grub_** (object): describes the desired GRUB bootloader configuration. diff --git a/docs/examples.md b/docs/examples.md index fb29a1b3..b6061633 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -350,7 +350,8 @@ boot_device: layout: s390x-eckd luks: device: /dev/dasda - enabled: true + cex: + enabled: true ``` ### Mirrored boot disk diff --git a/docs/release-notes.md b/docs/release-notes.md index 5a205b3e..9100010c 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -7,6 +7,23 @@ nav_order: 9 ## Upcoming Butane 0.22.0 (unreleased) +### Breaking changes + + +### Features + +- Support LUKS encryption using IBM CEX secure keys on s390x + +### Bug fixes + + +## Misc. changes + + +### Docs changes + + + ## Butane 0.21.0 (2024-06-06) Starting with this release, Butane binaries are signed with the [Fedora 40 diff --git a/go.mod b/go.mod index ba543c6b..a343b14a 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/clarketm/json v1.17.1 github.com/coreos/go-semver v0.3.1 github.com/coreos/go-systemd/v22 v22.5.0 - github.com/coreos/ignition/v2 v2.18.0 + github.com/coreos/ignition/v2 v2.19.0 github.com/coreos/vcontext v0.0.0-20230201181013-d72178a18687 github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace github.com/stretchr/testify v1.9.0 @@ -15,7 +15,7 @@ require ( ) require ( - github.com/aws/aws-sdk-go v1.50.25 // indirect + github.com/aws/aws-sdk-go v1.53.5 // indirect github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/go.sum b/go.sum index 666538ab..3412ab2b 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/aws/aws-sdk-go v1.50.25 h1:vhiHtLYybv1Nhx3Kv18BBC6L0aPJHaG9aeEsr92W99c= -github.com/aws/aws-sdk-go v1.50.25/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.5 h1:1OcVWMjGlwt7EU5OWmmEEXqaYfmX581EK317QJZXItM= +github.com/aws/aws-sdk-go v1.53.5/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/clarketm/json v1.17.1 h1:U1IxjqJkJ7bRK4L6dyphmoO840P6bdhPdbbLySourqI= github.com/clarketm/json v1.17.1/go.mod h1:ynr2LRfb0fQU34l07csRNBTcivjySLLiY1YzQqKVfdo= github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb h1:rmqyI19j3Z/74bIRhuC59RB442rXUazKNueVpfJPxg4= @@ -8,8 +8,8 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/ignition/v2 v2.18.0 h1:sPSGGsxaCuFMpKOMBQ71I9RIR20SIF4dWnoTomcPEYQ= -github.com/coreos/ignition/v2 v2.18.0/go.mod h1:TURPHDqWUWTmej8c+CEMBENMU3N/Lt6GfreHJuoDMbA= +github.com/coreos/ignition/v2 v2.19.0 h1:ek200E31M1NCVyvL22Bd40kOJp7yt1gdHAb3xwqTi8Y= +github.com/coreos/ignition/v2 v2.19.0/go.mod h1:ydb815SaH9A4304wIUoCS5IHyKRHWEp7dfJH8cQW2gA= github.com/coreos/vcontext v0.0.0-20230201181013-d72178a18687 h1:uSmlDgJGbUB0bwQBcZomBTottKwEDF5fF8UjSwKSzWM= github.com/coreos/vcontext v0.0.0-20230201181013-d72178a18687/go.mod h1:Salmysdw7DAVuobBW/LwsKKgpyCPHUhjyJoMJD+ZJiI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= diff --git a/internal/doc/butane.yaml b/internal/doc/butane.yaml index 64e1ad49..1a21993a 100644 --- a/internal/doc/butane.yaml +++ b/internal/doc/butane.yaml @@ -344,16 +344,11 @@ root: desc: sets the minimum number of pieces required to decrypt the device. Default is 1. - name: discard desc: whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. - - name: enabled - desc: whether or not to use a cex device. - transforms: - - regex: ".*" - replacement: "UnSupported" - if: - - variant: fcos - min: 1.6.0-experimental - - variant: openshift - min: 4.16.0-experimental + - name: cex + desc: describes the IBM Crypto Express (CEX) card configuration for the luks device. + children: + - name: enabled + desc: whether or not to enable cex compatibility for luks. If omitted, defaults to false. - name: mirror desc: describes mirroring of the boot disk for fault tolerance. children: diff --git a/vendor/github.com/coreos/ignition/v2/config/doc/ignition.yaml b/vendor/github.com/coreos/ignition/v2/config/doc/ignition.yaml index a15b2097..6f39c255 100644 --- a/vendor/github.com/coreos/ignition/v2/config/doc/ignition.yaml +++ b/vendor/github.com/coreos/ignition/v2/config/doc/ignition.yaml @@ -380,6 +380,11 @@ root: required: true - name: needsNetwork desc: whether or not the device requires networking. + - name: cex + desc: describes the IBM Crypto Express (CEX) card configuration for the luks device. + children: + - name: enabled + desc: whether or not to use a CEX secure key to encrypt the luks device. - name: systemd desc: describes the desired state of the systemd units. children: diff --git a/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go b/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go index 8e2d24d5..13742ab0 100644 --- a/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go +++ b/vendor/github.com/coreos/ignition/v2/config/shared/errors/errors.go @@ -85,6 +85,8 @@ var ( ErrInvalidProxy = errors.New("proxies must be http(s)") ErrInsecureProxy = errors.New("insecure plaintext HTTP proxy specified for HTTPS resources") ErrPathConflictsSystemd = errors.New("path conflicts with systemd unit or dropin") + ErrCexWithClevis = errors.New("cannot use cex with clevis") + ErrCexWithKeyFile = errors.New("cannot use key file with cex") // Systemd section errors ErrInvalidSystemdExt = errors.New("invalid systemd unit extension") diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/cex.go b/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/cex.go new file mode 100644 index 00000000..b34f5f52 --- /dev/null +++ b/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/cex.go @@ -0,0 +1,33 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (cm Cex) IsPresent() bool { + return util.IsTrue(cm.Enabled) +} + +func (cx Cex) Validate(c path.ContextPath) (r report.Report) { + if !util.IsTrue(cx.Enabled) { + return + } + return +} diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/luks.go b/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/luks.go index 90d72387..e4c1d681 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/luks.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/luks.go @@ -53,6 +53,17 @@ func (l Luks) Validate(c path.ContextPath) (r report.Report) { if err := validateURLNilOK(l.KeyFile.Source); err != nil { r.AddOnError(c.Append("keys"), errors.ErrInvalidLuksKeyFile) } + + // fail if Cex use with Clevis + if l.Clevis.IsPresent() && l.Cex.IsPresent() { + r.AddOnError(c.Append("cex"), errors.ErrCexWithClevis) + } + + // fail if key file is provided along with Cex + if l.Cex.IsPresent() && util.NotEmpty(l.KeyFile.Source) { + r.AddOnError(c.Append("cex"), errors.ErrCexWithKeyFile) + } + return } diff --git a/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/schema.go b/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/schema.go index 27fe5b5b..82957838 100644 --- a/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/schema.go +++ b/vendor/github.com/coreos/ignition/v2/config/v3_5_experimental/types/schema.go @@ -2,6 +2,10 @@ package types // generated by "schematyper --package=types config/v3_5_experimental/schema/ignition.json -o config/v3_5_experimental/types/schema.go --root-type=Config" -- DO NOT EDIT +type Cex struct { + Enabled *bool `json:"enabled,omitempty"` +} + type Clevis struct { Custom ClevisCustom `json:"custom,omitempty"` Tang []Tang `json:"tang,omitempty"` @@ -109,6 +113,7 @@ type LinkEmbedded1 struct { } type Luks struct { + Cex Cex `json:"cex,omitempty"` Clevis Clevis `json:"clevis,omitempty"` Device *string `json:"device,omitempty"` Discard *bool `json:"discard,omitempty"` diff --git a/vendor/modules.txt b/vendor/modules.txt index c7dd39e6..fe49a332 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/aws/aws-sdk-go v1.50.25 +# github.com/aws/aws-sdk-go v1.53.5 ## explicit; go 1.19 github.com/aws/aws-sdk-go/aws/arn # github.com/clarketm/json v1.17.1 @@ -13,7 +13,7 @@ github.com/coreos/go-semver/semver # github.com/coreos/go-systemd/v22 v22.5.0 ## explicit; go 1.12 github.com/coreos/go-systemd/v22/unit -# github.com/coreos/ignition/v2 v2.18.0 +# github.com/coreos/ignition/v2 v2.19.0 ## explicit; go 1.20 github.com/coreos/ignition/v2/config/doc github.com/coreos/ignition/v2/config/merge