From: Herbert Xu <herbert@gondor.apana.org.au> Date: Wed, 27 Aug 2008 10:18:38 +1000 Subject: [CRYPTO] api: Add fips_enable flag Message-id: E1KY8kA-0002Ht-00@gondolin.me.apana.org.au O-Subject: [PATCH 16/19] crypto: api - Add fips_enable flag Bugzilla: 444634 RHEL5 bugzilla #444634 crypto: api - Add fips_enable flag Add the ability to turn FIPS-compliant mode on or off at boot In order to be FIPS compliant, several check may need to be preformed that may be construed as unusefull in a non-compliant mode. This patch allows us to set a kernel flag incating that we are running in a fips-compliant mode from boot up. It also exports that mode information to user space via a sysctl (/proc/sys/crypto/fips_enabled). Tested successfully by me. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> diff --git a/crypto/Kconfig b/crypto/Kconfig index c194304..499e1db 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -15,6 +15,14 @@ config CRYPTO_API help This option provides the (backported) core Cryptographic API. +config CRYPTO_FIPS + bool "FIPS 200 compliance" + help + This options enables the fips boot option which is + required if you want to system to operate in a FIPS 200 + certification. You should say no unless you know what + this is. + config CRYPTO_ALGAPI tristate depends on CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index 2e20c06..9ec2d1b 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -7,6 +7,8 @@ proc-crypto-$(CONFIG_PROC_FS) = proc.o obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o \ testmgr_digest.o $(proc-crypto-y) +obj-$(CONFIG_CRYPTO_FIPS) += fips.o + crypto_algapi-objs := algapi.o ncipher.o nscatterwalk.o obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o diff --git a/crypto/fips.c b/crypto/fips.c new file mode 100644 index 0000000..5539700 --- /dev/null +++ b/crypto/fips.c @@ -0,0 +1,27 @@ +/* + * FIPS 200 support. + * + * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#include "internal.h" + +int fips_enabled; +EXPORT_SYMBOL_GPL(fips_enabled); + +/* Process kernel command-line parameter at boot time. fips=0 or fips=1 */ +static int fips_enable(char *str) +{ + fips_enabled = !!simple_strtol(str, NULL, 0); + printk(KERN_INFO "fips mode: %s\n", + fips_enabled ? "enabled" : "disabled"); + return 1; +} + +__setup("fips=", fips_enable); diff --git a/crypto/internal.h b/crypto/internal.h index c7c68f4..205d635 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -24,6 +24,12 @@ #include <linux/slab.h> #include <asm/kmap_types.h> +#ifdef CONFIG_CRYPTO_FIPS +extern int fips_enabled; +#else +#define fips_enabled 0 +#endif + /* Crypto notification events. */ enum { CRYPTO_MSG_ALG_REQUEST, diff --git a/crypto/proc.c b/crypto/proc.c index c0a5dd7..7542646 100644 --- a/crypto/proc.c +++ b/crypto/proc.c @@ -17,8 +17,46 @@ #include <linux/rwsem.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/sysctl.h> #include "internal.h" +#ifdef CONFIG_CRYPTO_FIPS +static struct ctl_table crypto_sysctl_table[] = { + { + .ctl_name = CRYPTO_FIPS, + .procname = "fips_enabled", + .data = &fips_enabled, + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = &proc_dointvec + }, + { + .ctl_name = 0, + }, +}; + +static struct ctl_table crypto_dir_table[] = { + { + .ctl_name = CTL_CRYPTO, + .procname = "crypto", + .mode = 0555, + .child = crypto_sysctl_table + }, + { + .ctl_name = 0, + }, +}; + +static struct ctl_table_header *crypto_sysctls; + +static void crypto_proc_fips_init(void) +{ + crypto_sysctls = register_sysctl_table(crypto_dir_table, 0); +} +#else +#define crypto_proc_fips_init() +#endif + static void *c_start(struct seq_file *m, loff_t *pos) { struct list_head *v; @@ -109,4 +147,5 @@ void __init crypto_init_proc(void) proc = create_proc_entry("crypto", 0, NULL); if (proc) proc->proc_fops = &proc_crypto_ops; + crypto_proc_fips_init(); } diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 0b6258f..24d477b 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -61,7 +61,8 @@ enum CTL_DEV=7, /* Devices */ CTL_BUS=8, /* Busses */ CTL_ABI=9, /* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ + CTL_CPU=10, /* CPU stuff (speed scaling, etc) */ + CTL_CRYPTO=11, /* Crypto API */ }; /* CTL_BUS names: */ @@ -260,6 +261,13 @@ enum BUS_ISA_PORT_SHIFT=3 }; +/* /proc/sys/crypto */ + +enum +{ + CRYPTO_FIPS=1, +}; + /* /proc/sys/net/core */ enum {