Commit 16609980 authored by Gilad Ben-Yossef's avatar Gilad Ben-Yossef Committed by Greg Kroah-Hartman

staging: ccree: add FIPS support

Add FIPS mode support to CryptoCell driver
Signed-off-by: default avatarGilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fe0a1951
...@@ -24,6 +24,15 @@ config CRYPTO_DEV_CCREE ...@@ -24,6 +24,15 @@ config CRYPTO_DEV_CCREE
cryptographic operations on the system REE. cryptographic operations on the system REE.
If unsure say Y. 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.
config CCREE_DISABLE_COHERENT_DMA_OPS config CCREE_DISABLE_COHERENT_DMA_OPS
bool "Disable Coherent DMA operations for the CCREE driver" bool "Disable Coherent DMA operations for the CCREE driver"
depends on CRYPTO_DEV_CCREE depends on CRYPTO_DEV_CCREE
......
obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o 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 ssi_pm_ext.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 ssi_pm_ext.o
ccree-$(CCREE_FIPS_SUPPORT) += ssi_fips.o ssi_fips_ll.o ssi_fips_ext.o ssi_fips_local.o
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "ssi_hash.h" #include "ssi_hash.h"
#include "ssi_sysfs.h" #include "ssi_sysfs.h"
#include "ssi_sram_mgr.h" #include "ssi_sram_mgr.h"
#include "ssi_fips_local.h"
#define template_aead template_u.aead #define template_aead template_u.aead
...@@ -153,6 +154,8 @@ static int ssi_aead_init(struct crypto_aead *tfm) ...@@ -153,6 +154,8 @@ static int ssi_aead_init(struct crypto_aead *tfm)
container_of(alg, struct ssi_crypto_alg, aead_alg); 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))); 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 */ /* Initialize modes in instance */
ctx->cipher_mode = ssi_alg->cipher_mode; ctx->cipher_mode = ssi_alg->cipher_mode;
ctx->flow_mode = ssi_alg->flow_mode; ctx->flow_mode = ssi_alg->flow_mode;
...@@ -572,6 +575,7 @@ ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) ...@@ -572,6 +575,7 @@ 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", 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); ctx, crypto_tfm_alg_name(crypto_aead_tfm(tfm)), key, keylen);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
/* STAT_PHASE_0: Init and sanity checks */ /* STAT_PHASE_0: Init and sanity checks */
START_CYCLE_COUNT(); START_CYCLE_COUNT();
...@@ -699,6 +703,7 @@ static int ssi_aead_setauthsize( ...@@ -699,6 +703,7 @@ static int ssi_aead_setauthsize(
{ {
struct ssi_aead_ctx *ctx = crypto_aead_ctx(authenc); struct ssi_aead_ctx *ctx = crypto_aead_ctx(authenc);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
/* Unsupported auth. sizes */ /* Unsupported auth. sizes */
if ((authsize == 0) || if ((authsize == 0) ||
(authsize >crypto_aead_maxauthsize(authenc))) { (authsize >crypto_aead_maxauthsize(authenc))) {
...@@ -2006,6 +2011,7 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction ...@@ -2006,6 +2011,7 @@ 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", 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, ((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); 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 */ /* STAT_PHASE_0: Init and sanity checks */
START_CYCLE_COUNT(); START_CYCLE_COUNT();
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "ssi_cipher.h" #include "ssi_cipher.h"
#include "ssi_request_mgr.h" #include "ssi_request_mgr.h"
#include "ssi_sysfs.h" #include "ssi_sysfs.h"
#include "ssi_fips_local.h"
#define MAX_ABLKCIPHER_SEQ_LEN 6 #define MAX_ABLKCIPHER_SEQ_LEN 6
...@@ -191,6 +192,7 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm) ...@@ -191,6 +192,7 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm)
SSI_LOG_DEBUG("Initializing context @%p for %s\n", ctx_p, SSI_LOG_DEBUG("Initializing context @%p for %s\n", ctx_p,
crypto_tfm_alg_name(tfm)); crypto_tfm_alg_name(tfm));
CHECK_AND_RETURN_UPON_FIPS_ERROR();
ctx_p->cipher_mode = ssi_alg->cipher_mode; ctx_p->cipher_mode = ssi_alg->cipher_mode;
ctx_p->flow_mode = ssi_alg->flow_mode; ctx_p->flow_mode = ssi_alg->flow_mode;
ctx_p->drvdata = ssi_alg->drvdata; ctx_p->drvdata = ssi_alg->drvdata;
...@@ -269,6 +271,37 @@ static const u8 zero_buff[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...@@ -269,6 +271,37 @@ static const u8 zero_buff[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
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)
{
#ifdef CCREE_FIPS_SUPPORT
tdes_keys_t *tdes_key = (tdes_keys_t*)key;
/* verify key1 != key2 and key3 != key2*/
if (unlikely( (memcmp((u8*)tdes_key->key1, (u8*)tdes_key->key2, sizeof(tdes_key->key1)) == 0) ||
(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;
}
static enum HwCryptoKey hw_key_to_cc_hw_key(int slot_num) static enum HwCryptoKey hw_key_to_cc_hw_key(int slot_num)
{ {
switch (slot_num) { switch (slot_num) {
...@@ -298,6 +331,10 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm, ...@@ -298,6 +331,10 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
ctx_p, crypto_tfm_alg_name(tfm), keylen); ctx_p, crypto_tfm_alg_name(tfm), keylen);
dump_byte_array("key", (uint8_t *)key, keylen); dump_byte_array("key", (uint8_t *)key, keylen);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
SSI_LOG_DEBUG("ssi_blkcipher_setkey: after FIPS check");
/* STAT_PHASE_0: Init and sanity checks */ /* STAT_PHASE_0: Init and sanity checks */
START_CYCLE_COUNT(); START_CYCLE_COUNT();
...@@ -359,6 +396,18 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm, ...@@ -359,6 +396,18 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
return -EINVAL; return -EINVAL;
} }
} }
if ((ctx_p->cipher_mode == DRV_CIPHER_XTS) &&
ssi_fips_verify_xts_keys(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_LOG_DEBUG("ssi_blkcipher_setkey: weak 3DES key");
return -EINVAL;
}
END_CYCLE_COUNT(STAT_OP_TYPE_SETKEY, STAT_PHASE_0); END_CYCLE_COUNT(STAT_OP_TYPE_SETKEY, STAT_PHASE_0);
...@@ -744,6 +793,7 @@ static int ssi_blkcipher_process( ...@@ -744,6 +793,7 @@ static int ssi_blkcipher_process(
((direction==DRV_CRYPTO_DIRECTION_ENCRYPT)?"Encrypt":"Decrypt"), ((direction==DRV_CRYPTO_DIRECTION_ENCRYPT)?"Encrypt":"Decrypt"),
areq, info, nbytes); areq, info, nbytes);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
/* STAT_PHASE_0: Init and sanity checks */ /* STAT_PHASE_0: Init and sanity checks */
START_CYCLE_COUNT(); START_CYCLE_COUNT();
...@@ -864,6 +914,8 @@ static void ssi_ablkcipher_complete(struct device *dev, void *ssi_req, void __io ...@@ -864,6 +914,8 @@ static void ssi_ablkcipher_complete(struct device *dev, void *ssi_req, void __io
struct ssi_ablkcipher_ctx *ctx_p = crypto_ablkcipher_ctx(tfm); struct ssi_ablkcipher_ctx *ctx_p = crypto_ablkcipher_ctx(tfm);
unsigned int ivsize = crypto_ablkcipher_ivsize(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, areq->info, ivsize, areq, cc_base); ssi_blkcipher_complete(dev, ctx_p, req_ctx, areq->dst, areq->src, areq->info, ivsize, areq, cc_base);
} }
......
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
#include "ssi_ivgen.h" #include "ssi_ivgen.h"
#include "ssi_sram_mgr.h" #include "ssi_sram_mgr.h"
#include "ssi_pm.h" #include "ssi_pm.h"
#include "ssi_fips_local.h"
#ifdef DX_DUMP_BYTES #ifdef DX_DUMP_BYTES
...@@ -142,7 +143,15 @@ static irqreturn_t cc_isr(int irq, void *dev_id) ...@@ -142,7 +143,15 @@ static irqreturn_t cc_isr(int irq, void *dev_id)
irr &= ~SSI_COMP_IRQ_MASK; irr &= ~SSI_COMP_IRQ_MASK;
complete_request(drvdata); complete_request(drvdata);
} }
#ifdef CC_SUPPORT_FIPS
/* TEE FIPS interrupt */
if (likely((irr & SSI_GPR0_IRQ_MASK) != 0)) {
/* Mask interrupt - will be unmasked in Deferred service handler */
CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR), imr | SSI_GPR0_IRQ_MASK);
irr &= ~SSI_GPR0_IRQ_MASK;
fips_handler(drvdata);
}
#endif
/* AXI error interrupt */ /* AXI error interrupt */
if (unlikely((irr & SSI_AXI_ERR_IRQ_MASK) != 0)) { if (unlikely((irr & SSI_AXI_ERR_IRQ_MASK) != 0)) {
uint32_t axi_err; uint32_t axi_err;
...@@ -351,6 +360,12 @@ static int init_cc_resources(struct platform_device *plat_dev) ...@@ -351,6 +360,12 @@ static int init_cc_resources(struct platform_device *plat_dev)
goto init_cc_res_err; goto init_cc_res_err;
} }
rc = ssi_fips_init(new_drvdata);
if (unlikely(rc != 0)) {
SSI_LOG_ERR("SSI_FIPS_INIT failed 0x%x\n", rc);
goto init_cc_res_err;
}
rc = ssi_ivgen_init(new_drvdata); rc = ssi_ivgen_init(new_drvdata);
if (unlikely(rc != 0)) { if (unlikely(rc != 0)) {
SSI_LOG_ERR("ssi_ivgen_init failed\n"); SSI_LOG_ERR("ssi_ivgen_init failed\n");
...@@ -391,6 +406,7 @@ static int init_cc_resources(struct platform_device *plat_dev) ...@@ -391,6 +406,7 @@ static int init_cc_resources(struct platform_device *plat_dev)
ssi_buffer_mgr_fini(new_drvdata); ssi_buffer_mgr_fini(new_drvdata);
request_mgr_fini(new_drvdata); request_mgr_fini(new_drvdata);
ssi_sram_mgr_fini(new_drvdata); ssi_sram_mgr_fini(new_drvdata);
ssi_fips_fini(new_drvdata);
#ifdef ENABLE_CC_SYSFS #ifdef ENABLE_CC_SYSFS
ssi_sysfs_fini(); ssi_sysfs_fini();
#endif #endif
...@@ -434,6 +450,7 @@ static void cleanup_cc_resources(struct platform_device *plat_dev) ...@@ -434,6 +450,7 @@ static void cleanup_cc_resources(struct platform_device *plat_dev)
ssi_buffer_mgr_fini(drvdata); ssi_buffer_mgr_fini(drvdata);
request_mgr_fini(drvdata); request_mgr_fini(drvdata);
ssi_sram_mgr_fini(drvdata); ssi_sram_mgr_fini(drvdata);
ssi_fips_fini(drvdata);
#ifdef ENABLE_CC_SYSFS #ifdef ENABLE_CC_SYSFS
ssi_sysfs_fini(); ssi_sysfs_fini();
#endif #endif
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "cc_crypto_ctx.h" #include "cc_crypto_ctx.h"
#include "ssi_sysfs.h" #include "ssi_sysfs.h"
#include "hash_defs.h" #include "hash_defs.h"
#include "ssi_fips_local.h"
#define DRV_MODULE_VERSION "3.0" #define DRV_MODULE_VERSION "3.0"
...@@ -152,6 +153,7 @@ struct ssi_drvdata { ...@@ -152,6 +153,7 @@ struct ssi_drvdata {
void *aead_handle; void *aead_handle;
void *blkcipher_handle; void *blkcipher_handle;
void *request_mgr_handle; void *request_mgr_handle;
void *fips_handle;
void *ivgen_handle; void *ivgen_handle;
void *sram_mgr_handle; void *sram_mgr_handle;
......
/*
* Copyright (C) 2012-2017 ARM Limited or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/**************************************************************
This file defines the driver FIPS APIs *
***************************************************************/
#include <linux/module.h>
#include "ssi_fips.h"
extern int ssi_fips_ext_get_state(ssi_fips_state_t *p_state);
extern int ssi_fips_ext_get_error(ssi_fips_error_t *p_err);
/*
This function returns the REE FIPS state.
It should be called by kernel module.
*/
int ssi_fips_get_state(ssi_fips_state_t *p_state)
{
int rc = 0;
if (p_state == NULL) {
return -EINVAL;
}
rc = ssi_fips_ext_get_state(p_state);
return rc;
}
EXPORT_SYMBOL(ssi_fips_get_state);
/*
This function returns the REE FIPS error.
It should be called by kernel module.
*/
int ssi_fips_get_error(ssi_fips_error_t *p_err)
{
int rc = 0;
if (p_err == NULL) {
return -EINVAL;
}
rc = ssi_fips_ext_get_error(p_err);
return rc;
}
EXPORT_SYMBOL(ssi_fips_get_error);
/*
* Copyright (C) 2012-2017 ARM Limited or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SSI_FIPS_H__
#define __SSI_FIPS_H__
#ifndef INT32_MAX /* Missing in Linux kernel */
#define INT32_MAX 0x7FFFFFFFL
#endif
/*!
@file
@brief This file contains FIPS related defintions and APIs.
*/
typedef enum ssi_fips_state {
CC_FIPS_STATE_NOT_SUPPORTED = 0,
CC_FIPS_STATE_SUPPORTED,
CC_FIPS_STATE_ERROR,
CC_FIPS_STATE_RESERVE32B = INT32_MAX
} ssi_fips_state_t;
typedef enum ssi_fips_error {
CC_REE_FIPS_ERROR_OK = 0,
CC_REE_FIPS_ERROR_GENERAL,
CC_REE_FIPS_ERROR_FROM_TEE,
CC_REE_FIPS_ERROR_AES_ECB_PUT,
CC_REE_FIPS_ERROR_AES_CBC_PUT,
CC_REE_FIPS_ERROR_AES_OFB_PUT,
CC_REE_FIPS_ERROR_AES_CTR_PUT,
CC_REE_FIPS_ERROR_AES_CBC_CTS_PUT,
CC_REE_FIPS_ERROR_AES_XTS_PUT,
CC_REE_FIPS_ERROR_AES_CMAC_PUT,
CC_REE_FIPS_ERROR_AESCCM_PUT,
CC_REE_FIPS_ERROR_AESGCM_PUT,
CC_REE_FIPS_ERROR_DES_ECB_PUT,
CC_REE_FIPS_ERROR_DES_CBC_PUT,
CC_REE_FIPS_ERROR_SHA1_PUT,
CC_REE_FIPS_ERROR_SHA256_PUT,
CC_REE_FIPS_ERROR_SHA512_PUT,
CC_REE_FIPS_ERROR_HMAC_SHA1_PUT,
CC_REE_FIPS_ERROR_HMAC_SHA256_PUT,
CC_REE_FIPS_ERROR_HMAC_SHA512_PUT,
CC_REE_FIPS_ERROR_ROM_CHECKSUM,
CC_REE_FIPS_ERROR_RESERVE32B = INT32_MAX
} ssi_fips_error_t;
int ssi_fips_get_state(ssi_fips_state_t *p_state);
int ssi_fips_get_error(ssi_fips_error_t *p_err);
#endif /*__SSI_FIPS_H__*/
This diff is collapsed.
/*
* Copyright (C) 2012-2017 ARM Limited or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/**************************************************************
This file defines the driver FIPS functions that should be
implemented by the driver user. Current implementation is sample code only.
***************************************************************/
#include <linux/module.h>
#include "ssi_fips_local.h"
#include "ssi_driver.h"
static bool tee_error;
module_param(tee_error, bool, 0644);
MODULE_PARM_DESC(tee_error, "Simulate TEE library failure flag: 0 - no error (default), 1 - TEE error occured ");
static ssi_fips_state_t fips_state = CC_FIPS_STATE_NOT_SUPPORTED;
static ssi_fips_error_t fips_error = CC_REE_FIPS_ERROR_OK;
/*
This function returns the FIPS REE state.
The function should be implemented by the driver user, depends on where .
the state value is stored.
The reference code uses global variable.
*/
int ssi_fips_ext_get_state(ssi_fips_state_t *p_state)
{
int rc = 0;
if (p_state == NULL) {
return -EINVAL;
}
*p_state = fips_state;
return rc;
}
/*
This function returns the FIPS REE error.
The function should be implemented by the driver user, depends on where .
the error value is stored.
The reference code uses global variable.
*/
int ssi_fips_ext_get_error(ssi_fips_error_t *p_err)
{
int rc = 0;
if (p_err == NULL) {
return -EINVAL;
}
*p_err = fips_error;
return rc;
}
/*
This function sets the FIPS REE state.
The function should be implemented by the driver user, depends on where .
the state value is stored.
The reference code uses global variable.
*/
int ssi_fips_ext_set_state(ssi_fips_state_t state)
{
fips_state = state;
return 0;
}
/*
This function sets the FIPS REE error.
The function should be implemented by the driver user, depends on where .
the error value is stored.
The reference code uses global variable.
*/
int ssi_fips_ext_set_error(ssi_fips_error_t err)
{
fips_error = err;
return 0;
}
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2012-2017 ARM Limited or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SSI_FIPS_LOCAL_H__
#define __SSI_FIPS_LOCAL_H__
#ifdef CONFIG_CCX7REE_FIPS_SUPPORT
#include "ssi_fips.h"
struct ssi_drvdata;
// IG - how to make 1 file for TEE and REE
typedef enum CC_FipsSyncStatus{
CC_FIPS_SYNC_MODULE_OK = 0x0,
CC_FIPS_SYNC_MODULE_ERROR = 0x1,
CC_FIPS_SYNC_REE_STATUS = 0x4,
CC_FIPS_SYNC_TEE_STATUS = 0x8,
CC_FIPS_SYNC_STATUS_RESERVE32B = INT32_MAX
}CCFipsSyncStatus_t;
#define CHECK_AND_RETURN_UPON_FIPS_ERROR() {\
if (ssi_fips_check_fips_error() != 0) {\
return -ENOEXEC;\
}\
}
#define CHECK_AND_RETURN_VOID_UPON_FIPS_ERROR() {\
if (ssi_fips_check_fips_error() != 0) {\
return;\
}\
}
#define SSI_FIPS_INIT(p_drvData) (ssi_fips_init(p_drvData))
#define SSI_FIPS_FINI(p_drvData) (ssi_fips_fini(p_drvData))
#define FIPS_LOG(...) SSI_LOG(KERN_INFO, __VA_ARGS__)
#define FIPS_DBG(...) //SSI_LOG(KERN_INFO, __VA_ARGS__)
/* FIPS functions */
int ssi_fips_init(struct ssi_drvdata *p_drvdata);
void ssi_fips_fini(struct ssi_drvdata *drvdata);
int ssi_fips_check_fips_error(void);
int ssi_fips_set_error(struct ssi_drvdata *p_drvdata, ssi_fips_error_t err);
void fips_handler(struct ssi_drvdata *drvdata);
#else /* CONFIG_CC7XXREE_FIPS_SUPPORT */
#define CHECK_AND_RETURN_UPON_FIPS_ERROR()
#define CHECK_AND_RETURN_VOID_UPON_FIPS_ERROR()
static inline int ssi_fips_init(struct ssi_drvdata *p_drvdata)
{
return 0;
}
static inline void ssi_fips_fini(struct ssi_drvdata *drvdata) {}
void fips_handler(struct ssi_drvdata *drvdata);
#endif /* CONFIG_CC7XXREE_FIPS_SUPPORT */
#endif /*__SSI_FIPS_LOCAL_H__*/
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "ssi_sysfs.h" #include "ssi_sysfs.h"
#include "ssi_hash.h" #include "ssi_hash.h"
#include "ssi_sram_mgr.h" #include "ssi_sram_mgr.h"
#include "ssi_fips_local.h"
#define SSI_MAX_AHASH_SEQ_LEN 12 #define SSI_MAX_AHASH_SEQ_LEN 12
#define SSI_MAX_HASH_OPAD_TMP_KEYS_SIZE MAX(SSI_MAX_HASH_BLCK_SIZE, 3 * AES_BLOCK_SIZE) #define SSI_MAX_HASH_OPAD_TMP_KEYS_SIZE MAX(SSI_MAX_HASH_BLCK_SIZE, 3 * AES_BLOCK_SIZE)
...@@ -467,6 +468,8 @@ static int ssi_hash_digest(struct ahash_req_ctx *state, ...@@ -467,6 +468,8 @@ static int ssi_hash_digest(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-digest (%d) ====\n", is_hmac?"hmac":"hash", nbytes); SSI_LOG_DEBUG("===== %s-digest (%d) ====\n", is_hmac?"hmac":"hash", nbytes);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) { if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) {
SSI_LOG_ERR("map_ahash_source() failed\n"); SSI_LOG_ERR("map_ahash_source() failed\n");
return -ENOMEM; return -ENOMEM;
...@@ -623,6 +626,7 @@ static int ssi_hash_update(struct ahash_req_ctx *state, ...@@ -623,6 +626,7 @@ static int ssi_hash_update(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-update (%d) ====\n", ctx->is_hmac ? SSI_LOG_DEBUG("===== %s-update (%d) ====\n", ctx->is_hmac ?
"hmac":"hash", nbytes); "hmac":"hash", nbytes);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (nbytes == 0) { if (nbytes == 0) {
/* no real updates required */ /* no real updates required */
return 0; return 0;
...@@ -719,6 +723,8 @@ static int ssi_hash_finup(struct ahash_req_ctx *state, ...@@ -719,6 +723,8 @@ static int ssi_hash_finup(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-finup (%d) ====\n", is_hmac?"hmac":"hash", nbytes); SSI_LOG_DEBUG("===== %s-finup (%d) ====\n", is_hmac?"hmac":"hash", nbytes);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src , nbytes, 1) != 0)) { if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src , nbytes, 1) != 0)) {
SSI_LOG_ERR("map_ahash_request_final() failed\n"); SSI_LOG_ERR("map_ahash_request_final() failed\n");
return -ENOMEM; return -ENOMEM;
...@@ -848,6 +854,8 @@ static int ssi_hash_final(struct ahash_req_ctx *state, ...@@ -848,6 +854,8 @@ static int ssi_hash_final(struct ahash_req_ctx *state,
SSI_LOG_DEBUG("===== %s-final (%d) ====\n", is_hmac?"hmac":"hash", nbytes); SSI_LOG_DEBUG("===== %s-final (%d) ====\n", is_hmac?"hmac":"hash", nbytes);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src, nbytes, 0) != 0)) { if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src, nbytes, 0) != 0)) {
SSI_LOG_ERR("map_ahash_request_final() failed\n"); SSI_LOG_ERR("map_ahash_request_final() failed\n");
return -ENOMEM; return -ENOMEM;
...@@ -975,6 +983,7 @@ static int ssi_hash_init(struct ahash_req_ctx *state, struct ssi_hash_ctx *ctx) ...@@ -975,6 +983,7 @@ static int ssi_hash_init(struct ahash_req_ctx *state, struct ssi_hash_ctx *ctx)
struct device *dev = &ctx->drvdata->plat_dev->dev; struct device *dev = &ctx->drvdata->plat_dev->dev;
state->xcbc_count = 0; state->xcbc_count = 0;
CHECK_AND_RETURN_UPON_FIPS_ERROR();
ssi_hash_map_request(dev, state, ctx); ssi_hash_map_request(dev, state, ctx);
return 0; return 0;
...@@ -983,12 +992,14 @@ static int ssi_hash_init(struct ahash_req_ctx *state, struct ssi_hash_ctx *ctx) ...@@ -983,12 +992,14 @@ static int ssi_hash_init(struct ahash_req_ctx *state, struct ssi_hash_ctx *ctx)
#ifdef EXPORT_FIXED #ifdef EXPORT_FIXED
static int ssi_hash_export(struct ssi_hash_ctx *ctx, void *out) static int ssi_hash_export(struct ssi_hash_ctx *ctx, void *out)
{ {
CHECK_AND_RETURN_UPON_FIPS_ERROR();
memcpy(out, ctx, sizeof(struct ssi_hash_ctx)); memcpy(out, ctx, sizeof(struct ssi_hash_ctx));
return 0; return 0;
} }
static int ssi_hash_import(struct ssi_hash_ctx *ctx, const void *in) static int ssi_hash_import(struct ssi_hash_ctx *ctx, const void *in)
{ {
CHECK_AND_RETURN_UPON_FIPS_ERROR();
memcpy(ctx, in, sizeof(struct ssi_hash_ctx)); memcpy(ctx, in, sizeof(struct ssi_hash_ctx));
return 0; return 0;
} }
...@@ -1010,6 +1021,7 @@ static int ssi_hash_setkey(void *hash, ...@@ -1010,6 +1021,7 @@ static int ssi_hash_setkey(void *hash,
SSI_LOG_DEBUG("ssi_hash_setkey: start keylen: %d", keylen); SSI_LOG_DEBUG("ssi_hash_setkey: start keylen: %d", keylen);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (synchronize) { if (synchronize) {
ctx = crypto_shash_ctx(((struct crypto_shash *)hash)); ctx = crypto_shash_ctx(((struct crypto_shash *)hash));
blocksize = crypto_tfm_alg_blocksize(&((struct crypto_shash *)hash)->base); blocksize = crypto_tfm_alg_blocksize(&((struct crypto_shash *)hash)->base);
...@@ -1218,6 +1230,7 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash, ...@@ -1218,6 +1230,7 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash,
HwDesc_s desc[SSI_MAX_AHASH_SEQ_LEN]; HwDesc_s desc[SSI_MAX_AHASH_SEQ_LEN];
SSI_LOG_DEBUG("===== setkey (%d) ====\n", keylen); SSI_LOG_DEBUG("===== setkey (%d) ====\n", keylen);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
switch (keylen) { switch (keylen) {
case AES_KEYSIZE_128: case AES_KEYSIZE_128:
...@@ -1303,6 +1316,7 @@ static int ssi_cmac_setkey(struct crypto_ahash *ahash, ...@@ -1303,6 +1316,7 @@ static int ssi_cmac_setkey(struct crypto_ahash *ahash,
struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash);
DECL_CYCLE_COUNT_RESOURCES; DECL_CYCLE_COUNT_RESOURCES;
SSI_LOG_DEBUG("===== setkey (%d) ====\n", keylen); SSI_LOG_DEBUG("===== setkey (%d) ====\n", keylen);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
ctx->is_hmac = true; ctx->is_hmac = true;
...@@ -1418,6 +1432,7 @@ static int ssi_shash_cra_init(struct crypto_tfm *tfm) ...@@ -1418,6 +1432,7 @@ static int ssi_shash_cra_init(struct crypto_tfm *tfm)
struct ssi_hash_alg *ssi_alg = struct ssi_hash_alg *ssi_alg =
container_of(shash_alg, struct ssi_hash_alg, shash_alg); container_of(shash_alg, struct ssi_hash_alg, shash_alg);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
ctx->hash_mode = ssi_alg->hash_mode; ctx->hash_mode = ssi_alg->hash_mode;
ctx->hw_mode = ssi_alg->hw_mode; ctx->hw_mode = ssi_alg->hw_mode;
ctx->inter_digestsize = ssi_alg->inter_digestsize; ctx->inter_digestsize = ssi_alg->inter_digestsize;
...@@ -1437,6 +1452,7 @@ static int ssi_ahash_cra_init(struct crypto_tfm *tfm) ...@@ -1437,6 +1452,7 @@ static int ssi_ahash_cra_init(struct crypto_tfm *tfm)
container_of(ahash_alg, struct ssi_hash_alg, ahash_alg); container_of(ahash_alg, struct ssi_hash_alg, ahash_alg);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
sizeof(struct ahash_req_ctx)); sizeof(struct ahash_req_ctx));
...@@ -1468,6 +1484,7 @@ static int ssi_mac_update(struct ahash_request *req) ...@@ -1468,6 +1484,7 @@ static int ssi_mac_update(struct ahash_request *req)
int rc; int rc;
uint32_t idx = 0; uint32_t idx = 0;
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (req->nbytes == 0) { if (req->nbytes == 0) {
/* no real updates required */ /* no real updates required */
return 0; return 0;
...@@ -1535,6 +1552,7 @@ static int ssi_mac_final(struct ahash_request *req) ...@@ -1535,6 +1552,7 @@ static int ssi_mac_final(struct ahash_request *req)
state->buff0_cnt; state->buff0_cnt;
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) { if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) {
keySize = CC_AES_128_BIT_KEY_SIZE; keySize = CC_AES_128_BIT_KEY_SIZE;
keyLen = CC_AES_128_BIT_KEY_SIZE; keyLen = CC_AES_128_BIT_KEY_SIZE;
...@@ -1645,7 +1663,7 @@ static int ssi_mac_finup(struct ahash_request *req) ...@@ -1645,7 +1663,7 @@ static int ssi_mac_finup(struct ahash_request *req)
uint32_t digestsize = crypto_ahash_digestsize(tfm); uint32_t digestsize = crypto_ahash_digestsize(tfm);
SSI_LOG_DEBUG("===== finup xcbc(%d) ====\n", req->nbytes); SSI_LOG_DEBUG("===== finup xcbc(%d) ====\n", req->nbytes);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (state->xcbc_count > 0 && req->nbytes == 0) { if (state->xcbc_count > 0 && req->nbytes == 0) {
SSI_LOG_DEBUG("No data to update. Call to fdx_mac_final \n"); SSI_LOG_DEBUG("No data to update. Call to fdx_mac_final \n");
return ssi_mac_final(req); return ssi_mac_final(req);
...@@ -1718,6 +1736,7 @@ static int ssi_mac_digest(struct ahash_request *req) ...@@ -1718,6 +1736,7 @@ static int ssi_mac_digest(struct ahash_request *req)
int rc; int rc;
SSI_LOG_DEBUG("===== -digest mac (%d) ====\n", req->nbytes); SSI_LOG_DEBUG("===== -digest mac (%d) ====\n", req->nbytes);
CHECK_AND_RETURN_UPON_FIPS_ERROR();
if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) { if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) {
SSI_LOG_ERR("map_ahash_source() failed\n"); SSI_LOG_ERR("map_ahash_source() failed\n");
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "ssi_sysfs.h" #include "ssi_sysfs.h"
#include "ssi_ivgen.h" #include "ssi_ivgen.h"
#include "ssi_pm.h" #include "ssi_pm.h"
#include "ssi_fips.h"
#include "ssi_fips_local.h"
#define SSI_MAX_POLL_ITER 10 #define SSI_MAX_POLL_ITER 10
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment