Commit ccb778e1 authored by Neil Horman's avatar Neil Horman Committed by Herbert Xu
Browse files

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: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 5be5e667
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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

crypto/fips.c

0 → 100644
+27 −0
Original line number Diff line number Diff line
/*
 * 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);
+6 −0
Original line number Diff line number Diff line
@@ -26,6 +26,12 @@
#include <linux/rwsem.h>
#include <linux/slab.h>

#ifdef CONFIG_CRYPTO_FIPS
extern int fips_enabled;
#else
#define fips_enabled 0
#endif

/* Crypto notification events. */
enum {
	CRYPTO_MSG_ALG_REQUEST,
+47 −0
Original line number Diff line number Diff line
@@ -19,8 +19,53 @@
#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       = 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);
}