From 0bd41b9dbe691ed70fa8769089a4a8795a5d54c9 Mon Sep 17 00:00:00 2001 From: Archana Shinde Date: Thu, 7 Nov 2019 16:45:47 -0800 Subject: [PATCH] FIPS: Add support for starting VM in FIPS mode. FIPS are a set of security standards for encryption algorithms in user and kernel space among others. Have Kata support this by starting the VM for a container in FIPS mode on detecting that the host is running in FIPS mode. Depends-on: github.com/kata-containers/packaging#788 Fixes #2170 Signed-off-by: Archana Shinde --- pkg/katautils/create.go | 36 +++++++++++++++++++++++++++++++ pkg/katautils/create_test.go | 42 ++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/pkg/katautils/create.go b/pkg/katautils/create.go index facf273246..424d42ff34 100644 --- a/pkg/katautils/create.go +++ b/pkg/katautils/create.go @@ -9,6 +9,9 @@ package katautils import ( "context" "fmt" + "io/ioutil" + "strconv" + "strings" vc "github.com/kata-containers/runtime/virtcontainers" vf "github.com/kata-containers/runtime/virtcontainers/factory" @@ -115,6 +118,10 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeCo sandboxConfig.Stateful = true } + if err := checkForFIPS(&sandboxConfig); err != nil { + return nil, vc.Process{}, err + } + if !rootFs.Mounted && len(sandboxConfig.Containers) == 1 { if rootFs.Source != "" { realPath, err := ResolvePath(rootFs.Source) @@ -175,6 +182,35 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeCo return sandbox, containers[0].Process(), nil } +var procFIPS = "/proc/sys/crypto/fips_enabled" + +func checkForFIPS(sandboxConfig *vc.SandboxConfig) error { + content, err := ioutil.ReadFile(procFIPS) + if err != nil { + // In case file cannot be found or read, simply return + return nil + } + + enabled, err := strconv.Atoi(strings.Trim(string(content), "\n\t ")) + if err != nil { + // Unexpected format, ignore and simply return early + return nil + } + + if enabled == 1 { + param := vc.Param{ + Key: "fips", + Value: "1", + } + + if err := sandboxConfig.HypervisorConfig.AddKernelParam(param); err != nil { + return fmt.Errorf("Error enabling fips mode : %v", err) + } + } + + return nil +} + // CreateContainer create a container func CreateContainer(ctx context.Context, vci vc.VC, sandbox vc.VCSandbox, ociSpec specs.Spec, rootFs vc.RootFs, containerID, bundlePath, console string, disableOutput, builtIn bool) (vc.Process, error) { var c vc.VCContainer diff --git a/pkg/katautils/create_test.go b/pkg/katautils/create_test.go index 7c95003c88..3e5eb370dc 100644 --- a/pkg/katautils/create_test.go +++ b/pkg/katautils/create_test.go @@ -334,6 +334,48 @@ func TestCreateSandboxFail(t *testing.T) { assert.True(vcmock.IsMockError(err)) } +func TestCheckForFips(t *testing.T) { + assert := assert.New(t) + + path, err := ioutil.TempDir("", "") + assert.NoError(err) + defer os.RemoveAll(path) + + val := procFIPS + procFIPS = filepath.Join(path, "fips-enabled") + defer func() { + procFIPS = val + }() + + err = ioutil.WriteFile(procFIPS, []byte("1"), 0644) + assert.NoError(err) + + hconfig := vc.HypervisorConfig{ + KernelParams: []vc.Param{ + {Key: "init", Value: "/sys/init"}, + }, + } + config := vc.SandboxConfig{ + HypervisorConfig: hconfig, + } + assert.NoError(checkForFIPS(&config)) + + params := config.HypervisorConfig.KernelParams + assert.Equal(len(params), 2) + assert.Equal(params[1].Key, "fips") + assert.Equal(params[1].Value, "1") + + config.HypervisorConfig = hconfig + err = ioutil.WriteFile(procFIPS, []byte("unexpected contents"), 0644) + assert.NoError(err) + assert.NoError(checkForFIPS(&config)) + assert.Equal(config.HypervisorConfig, hconfig) + + assert.NoError(os.Remove(procFIPS)) + assert.NoError(checkForFIPS(&config)) + assert.Equal(config.HypervisorConfig, hconfig) +} + func TestCreateContainerContainerConfigFail(t *testing.T) { assert := assert.New(t)