Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7e607bf authored by Gilad Ben-Yossef's avatar Gilad Ben-Yossef Committed by Greg Kroah-Hartman
Browse files

staging: ccree: move FIPS support to kernel infrastructure



The ccree driver had its own FIPS support, complete with
a test harness comparable to crypto testmgr and an
implementation which disables crypto functionality on
FIPS test error detection, either in Linux or from TEE.

This patch removes the duplication, while reimplementing
the handling of TEE reported FIPS errors according to the
kernel policy of inducing a panic in such an event.

Signed-off-by: default avatarGilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 07642a07
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -23,12 +23,3 @@ config CRYPTO_DEV_CCREE
	  Choose this if you wish to use hardware acceleration of
	  cryptographic operations on the system REE.
	  If unsure say Y.

config CCREE_FIPS_SUPPORT
	bool "Turn on CryptoCell 7XX REE FIPS mode support"
	depends on CRYPTO_DEV_CCREE
	default n
	help
	  Say 'Y' to enable support for FIPS compliant mode by the
	  CCREE driver.
	  If unsure say N.
+1 −1
Original line number Diff line number Diff line
obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o
ccree-y := ssi_driver.o ssi_sysfs.o ssi_buffer_mgr.o ssi_request_mgr.o ssi_cipher.o ssi_hash.o ssi_aead.o ssi_ivgen.o ssi_sram_mgr.o ssi_pm.o
ccree-$(CCREE_FIPS_SUPPORT) += ssi_fips.o ssi_fips_ll.o ssi_fips_ext.o ssi_fips_local.o
ccree-$(CONFIG_CRYPTO_FIPS) += ssi_fips.o
+0 −6
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@
#include "ssi_hash.h"
#include "ssi_sysfs.h"
#include "ssi_sram_mgr.h"
#include "ssi_fips_local.h"

#define template_aead	template_u.aead

@@ -146,8 +145,6 @@ static int ssi_aead_init(struct crypto_aead *tfm)
			container_of(alg, struct ssi_crypto_alg, aead_alg);
	SSI_LOG_DEBUG("Initializing context @%p for %s\n", ctx, crypto_tfm_alg_name(&(tfm->base)));

	CHECK_AND_RETURN_UPON_FIPS_ERROR();

	/* Initialize modes in instance */
	ctx->cipher_mode = ssi_alg->cipher_mode;
	ctx->flow_mode = ssi_alg->flow_mode;
@@ -538,7 +535,6 @@ ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
	SSI_LOG_DEBUG("Setting key in context @%p for %s. key=%p keylen=%u\n",
		ctx, crypto_tfm_alg_name(crypto_aead_tfm(tfm)), key, keylen);

	CHECK_AND_RETURN_UPON_FIPS_ERROR();
	/* STAT_PHASE_0: Init and sanity checks */

	if (ctx->auth_mode != DRV_HASH_NULL) { /* authenc() alg. */
@@ -654,7 +650,6 @@ static int ssi_aead_setauthsize(
{
	struct ssi_aead_ctx *ctx = crypto_aead_ctx(authenc);

	CHECK_AND_RETURN_UPON_FIPS_ERROR();
	/* Unsupported auth. sizes */
	if ((authsize == 0) ||
	    (authsize > crypto_aead_maxauthsize(authenc))) {
@@ -1946,7 +1941,6 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction
	SSI_LOG_DEBUG("%s context=%p req=%p iv=%p src=%p src_ofs=%d dst=%p dst_ofs=%d cryptolen=%d\n",
		((direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Encrypt" : "Decrypt"), ctx, req, req->iv,
		sg_virt(req->src), req->src->offset, sg_virt(req->dst), req->dst->offset, req->cryptlen);
	CHECK_AND_RETURN_UPON_FIPS_ERROR();

	/* STAT_PHASE_0: Init and sanity checks */

+4 −26
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <crypto/aes.h>
#include <crypto/ctr.h>
#include <crypto/des.h>
#include <crypto/xts.h>

#include "ssi_config.h"
#include "ssi_driver.h"
@@ -31,7 +32,6 @@
#include "ssi_cipher.h"
#include "ssi_request_mgr.h"
#include "ssi_sysfs.h"
#include "ssi_fips_local.h"

#define MAX_ABLKCIPHER_SEQ_LEN 6

@@ -188,7 +188,6 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm)
	SSI_LOG_DEBUG("Initializing context @%p for %s\n", ctx_p,
						crypto_tfm_alg_name(tfm));

	CHECK_AND_RETURN_UPON_FIPS_ERROR();
	ctx_p->cipher_mode = ssi_alg->cipher_mode;
	ctx_p->flow_mode = ssi_alg->flow_mode;
	ctx_p->drvdata = ssi_alg->drvdata;
@@ -265,9 +264,8 @@ static const u8 zero_buff[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
				0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

/* The function verifies that tdes keys are not weak.*/
static int ssi_fips_verify_3des_keys(const u8 *key, unsigned int keylen)
static int ssi_verify_3des_keys(const u8 *key, unsigned int keylen)
{
#ifdef CCREE_FIPS_SUPPORT
	struct tdes_keys *tdes_key = (struct tdes_keys *)key;

	/* verify key1 != key2 and key3 != key2*/
@@ -275,21 +273,6 @@ static int ssi_fips_verify_3des_keys(const u8 *key, unsigned int keylen)
		      (memcmp((u8 *)tdes_key->key3, (u8 *)tdes_key->key2, sizeof(tdes_key->key3)) == 0))) {
		return -ENOEXEC;
	}
#endif /* CCREE_FIPS_SUPPORT */

	return 0;
}

/* The function verifies that xts keys are not weak.*/
static int ssi_fips_verify_xts_keys(const u8 *key, unsigned int keylen)
{
#ifdef CCREE_FIPS_SUPPORT
	/* Weak key is define as key that its first half (128/256 lsb) equals its second half (128/256 msb) */
	int singleKeySize = keylen >> 1;

	if (unlikely(memcmp(key, &key[singleKeySize], singleKeySize) == 0))
		return -ENOEXEC;
#endif /* CCREE_FIPS_SUPPORT */

	return 0;
}
@@ -322,8 +305,6 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
		ctx_p, crypto_tfm_alg_name(tfm), keylen);
	dump_byte_array("key", (u8 *)key, keylen);

	CHECK_AND_RETURN_UPON_FIPS_ERROR();

	SSI_LOG_DEBUG("ssi_blkcipher_setkey: after FIPS check");

	/* STAT_PHASE_0: Init and sanity checks */
@@ -385,13 +366,13 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
		}
	}
	if ((ctx_p->cipher_mode == DRV_CIPHER_XTS) &&
	    ssi_fips_verify_xts_keys(key, keylen) != 0) {
	    xts_check_key(tfm, key, keylen) != 0) {
		SSI_LOG_DEBUG("ssi_blkcipher_setkey: weak XTS key");
		return -EINVAL;
	}
	if ((ctx_p->flow_mode == S_DIN_to_DES) &&
	    (keylen == DES3_EDE_KEY_SIZE) &&
	    ssi_fips_verify_3des_keys(key, keylen) != 0) {
	    ssi_verify_3des_keys(key, keylen) != 0) {
		SSI_LOG_DEBUG("ssi_blkcipher_setkey: weak 3DES key");
		return -EINVAL;
	}
@@ -754,7 +735,6 @@ static int ssi_blkcipher_process(
		((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Encrypt" : "Decrypt"),
		     areq, info, nbytes);

	CHECK_AND_RETURN_UPON_FIPS_ERROR();
	/* STAT_PHASE_0: Init and sanity checks */

	/* TODO: check data length according to mode */
@@ -855,8 +835,6 @@ static void ssi_ablkcipher_complete(struct device *dev, void *ssi_req, void __io
	struct ssi_ablkcipher_ctx *ctx_p = crypto_ablkcipher_ctx(tfm);
	unsigned int ivsize = crypto_ablkcipher_ivsize(tfm);

	CHECK_AND_RETURN_VOID_UPON_FIPS_ERROR();

	ssi_blkcipher_complete(dev, ctx_p, req_ctx, areq->dst, areq->src,
			       ivsize, areq, cc_base);
}
+7 −1
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@
#include "ssi_ivgen.h"
#include "ssi_sram_mgr.h"
#include "ssi_pm.h"
#include "ssi_fips_local.h"
#include "ssi_fips.h"

#ifdef DX_DUMP_BYTES
void dump_byte_array(const char *name, const u8 *the_array, unsigned long size)
@@ -398,6 +398,12 @@ static int init_cc_resources(struct platform_device *plat_dev)
		goto init_cc_res_err;
	}

	/* If we got here and FIPS mode is enabled
	 * it means all FIPS test passed, so let TEE
	 * know we're good.
	 */
	cc_set_ree_fips_status(new_drvdata, true);

	return 0;

init_cc_res_err:
Loading