diff --git a/crypto/Kconfig b/crypto/Kconfig index 776f90d249a..a784c2dce57 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -21,6 +21,14 @@ if CRYPTO comment "Crypto core or helper" +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 help diff --git a/crypto/Makefile b/crypto/Makefile index 256e33e81e3..8a27b834ea7 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -5,6 +5,8 @@ obj-$(CONFIG_CRYPTO) += crypto.o crypto-objs := api.o cipher.o digest.o compress.o +obj-$(CONFIG_CRYPTO_FIPS) += fips.o + crypto_algapi-$(CONFIG_PROC_FS) += proc.o crypto_algapi-objs := algapi.o scatterwalk.o $(crypto_algapi-y) obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o diff --git a/crypto/fips.c b/crypto/fips.c new file mode 100644 index 00000000000..553970081c6 --- /dev/null +++ b/crypto/fips.c @@ -0,0 +1,27 @@ +/* + * FIPS 200 support. + * + * Copyright (c) 2008 Neil Horman + * + * 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 fc93743c5d3..8ef72d76092 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -26,6 +26,12 @@ #include #include +#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 1d616adead0..37a13d05636 100644 --- a/crypto/proc.c +++ b/crypto/proc.c @@ -19,8 +19,53 @@ #include #include #include +#include #include "internal.h" +#ifdef CONFIG_CRYPTO_FIPS +static struct ctl_table crypto_sysctl_table[] = { + { + .ctl_name = CTL_UNNUMBERED, + .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_UNNUMBERED, + .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); +} + +static void crypto_proc_fips_exit(void) +{ + if (crypto_sysctls) + unregister_sysctl_table(crypto_sysctls); +} +#else +#define crypto_proc_fips_init() +#define crypto_proc_fips_exit() +#endif + static void *c_start(struct seq_file *m, loff_t *pos) { down_read(&crypto_alg_sem); @@ -106,9 +151,11 @@ static const struct file_operations proc_crypto_ops = { void __init crypto_init_proc(void) { proc_create("crypto", 0, NULL, &proc_crypto_ops); + crypto_proc_fips_init(); } void __exit crypto_exit_proc(void) { + crypto_proc_fips_exit(); remove_proc_entry("crypto", NULL); }