mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-25 02:48:21 +00:00
staging: ccree: add skcipher support
Add CryptoCell skcipher support Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
50cfbbb7e6
commit
302ef8ebb4
@ -3,11 +3,19 @@ config CRYPTO_DEV_CCREE
|
||||
depends on CRYPTO_HW && OF && HAS_DMA
|
||||
default n
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_DES
|
||||
select CRYPTO_AUTHENC
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_MD5
|
||||
select CRYPTO_SHA256
|
||||
select CRYPTO_SHA512
|
||||
select CRYPTO_HMAC
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_CBC
|
||||
select CRYPTO_ECB
|
||||
select CRYPTO_CTR
|
||||
select CRYPTO_XTS
|
||||
help
|
||||
Say 'Y' to enable a driver for the Arm TrustZone CryptoCell
|
||||
C7xx. Currently only the CryptoCell 712 REE is supported.
|
||||
|
@ -1,2 +1,2 @@
|
||||
obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o
|
||||
ccree-y := ssi_driver.o ssi_sysfs.o ssi_buffer_mgr.o ssi_request_mgr.o ssi_hash.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_sram_mgr.o ssi_pm.o ssi_pm_ext.o
|
||||
|
@ -242,6 +242,27 @@ struct drv_ctx_hmac {
|
||||
CC_DIGEST_SIZE_MAX - CC_HMAC_BLOCK_SIZE_MAX];
|
||||
};
|
||||
|
||||
struct drv_ctx_cipher {
|
||||
enum drv_crypto_alg alg; /* DRV_CRYPTO_ALG_AES */
|
||||
enum drv_cipher_mode mode;
|
||||
enum drv_crypto_direction direction;
|
||||
enum drv_crypto_key_type crypto_key_type;
|
||||
enum drv_crypto_padding_type padding_type;
|
||||
uint32_t key_size; /* numeric value in bytes */
|
||||
uint32_t data_unit_size; /* required for XTS */
|
||||
/* block_state is the AES engine block state.
|
||||
* It is used by the host to pass IV or counter at initialization.
|
||||
* It is used by SeP for intermediate block chaining state and for
|
||||
* returning MAC algorithms results. */
|
||||
uint8_t block_state[CC_AES_BLOCK_SIZE];
|
||||
uint8_t key[CC_AES_KEY_SIZE_MAX];
|
||||
uint8_t xex_key[CC_AES_KEY_SIZE_MAX];
|
||||
/* reserve to end of allocated context size */
|
||||
uint32_t reserved[CC_DRV_CTX_SIZE_WORDS - 7 -
|
||||
CC_AES_BLOCK_SIZE/sizeof(uint32_t) - 2 *
|
||||
(CC_AES_KEY_SIZE_MAX/sizeof(uint32_t))];
|
||||
};
|
||||
|
||||
/*******************************************************************/
|
||||
/***************** MESSAGE BASED CONTEXTS **************************/
|
||||
/*******************************************************************/
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "ssi_buffer_mgr.h"
|
||||
#include "cc_lli_defs.h"
|
||||
#include "ssi_cipher.h"
|
||||
#include "ssi_hash.h"
|
||||
|
||||
#define LLI_MAX_NUM_OF_DATA_ENTRIES 128
|
||||
@ -517,6 +518,152 @@ static inline int ssi_ahash_handle_curr_buf(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ssi_buffer_mgr_unmap_blkcipher_request(
|
||||
struct device *dev,
|
||||
void *ctx,
|
||||
unsigned int ivsize,
|
||||
struct scatterlist *src,
|
||||
struct scatterlist *dst)
|
||||
{
|
||||
struct blkcipher_req_ctx *req_ctx = (struct blkcipher_req_ctx *)ctx;
|
||||
|
||||
if (likely(req_ctx->gen_ctx.iv_dma_addr != 0)) {
|
||||
SSI_LOG_DEBUG("Unmapped iv: iv_dma_addr=0x%llX iv_size=%u\n",
|
||||
(unsigned long long)req_ctx->gen_ctx.iv_dma_addr,
|
||||
ivsize);
|
||||
SSI_RESTORE_DMA_ADDR_TO_48BIT(req_ctx->gen_ctx.iv_dma_addr);
|
||||
dma_unmap_single(dev, req_ctx->gen_ctx.iv_dma_addr,
|
||||
ivsize,
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
/* Release pool */
|
||||
if (req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI) {
|
||||
SSI_RESTORE_DMA_ADDR_TO_48BIT(req_ctx->mlli_params.mlli_dma_addr);
|
||||
dma_pool_free(req_ctx->mlli_params.curr_pool,
|
||||
req_ctx->mlli_params.mlli_virt_addr,
|
||||
req_ctx->mlli_params.mlli_dma_addr);
|
||||
}
|
||||
|
||||
SSI_RESTORE_DMA_ADDR_TO_48BIT(sg_dma_address(src));
|
||||
dma_unmap_sg(dev, src, req_ctx->in_nents,
|
||||
DMA_BIDIRECTIONAL);
|
||||
SSI_LOG_DEBUG("Unmapped req->src=%pK\n",
|
||||
sg_virt(src));
|
||||
|
||||
if (src != dst) {
|
||||
SSI_RESTORE_DMA_ADDR_TO_48BIT(sg_dma_address(dst));
|
||||
dma_unmap_sg(dev, dst, req_ctx->out_nents,
|
||||
DMA_BIDIRECTIONAL);
|
||||
SSI_LOG_DEBUG("Unmapped req->dst=%pK\n",
|
||||
sg_virt(dst));
|
||||
}
|
||||
}
|
||||
|
||||
int ssi_buffer_mgr_map_blkcipher_request(
|
||||
struct ssi_drvdata *drvdata,
|
||||
void *ctx,
|
||||
unsigned int ivsize,
|
||||
unsigned int nbytes,
|
||||
void *info,
|
||||
struct scatterlist *src,
|
||||
struct scatterlist *dst)
|
||||
{
|
||||
struct blkcipher_req_ctx *req_ctx = (struct blkcipher_req_ctx *)ctx;
|
||||
struct mlli_params *mlli_params = &req_ctx->mlli_params;
|
||||
struct buff_mgr_handle *buff_mgr = drvdata->buff_mgr_handle;
|
||||
struct device *dev = &drvdata->plat_dev->dev;
|
||||
struct buffer_array sg_data;
|
||||
uint32_t dummy = 0;
|
||||
int rc = 0;
|
||||
uint32_t mapped_nents = 0;
|
||||
|
||||
req_ctx->dma_buf_type = SSI_DMA_BUF_DLLI;
|
||||
mlli_params->curr_pool = NULL;
|
||||
sg_data.num_of_buffers = 0;
|
||||
|
||||
/* Map IV buffer */
|
||||
if (likely(ivsize != 0) ) {
|
||||
dump_byte_array("iv", (uint8_t *)info, ivsize);
|
||||
req_ctx->gen_ctx.iv_dma_addr =
|
||||
dma_map_single(dev, (void *)info,
|
||||
ivsize,
|
||||
DMA_TO_DEVICE);
|
||||
if (unlikely(dma_mapping_error(dev,
|
||||
req_ctx->gen_ctx.iv_dma_addr))) {
|
||||
SSI_LOG_ERR("Mapping iv %u B at va=%pK "
|
||||
"for DMA failed\n", ivsize, info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
SSI_UPDATE_DMA_ADDR_TO_48BIT(req_ctx->gen_ctx.iv_dma_addr,
|
||||
ivsize);
|
||||
SSI_LOG_DEBUG("Mapped iv %u B at va=%pK to dma=0x%llX\n",
|
||||
ivsize, info,
|
||||
(unsigned long long)req_ctx->gen_ctx.iv_dma_addr);
|
||||
} else
|
||||
req_ctx->gen_ctx.iv_dma_addr = 0;
|
||||
|
||||
/* Map the src SGL */
|
||||
rc = ssi_buffer_mgr_map_scatterlist(dev, src,
|
||||
nbytes, DMA_BIDIRECTIONAL, &req_ctx->in_nents,
|
||||
LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents);
|
||||
if (unlikely(rc != 0)) {
|
||||
rc = -ENOMEM;
|
||||
goto ablkcipher_exit;
|
||||
}
|
||||
if (mapped_nents > 1)
|
||||
req_ctx->dma_buf_type = SSI_DMA_BUF_MLLI;
|
||||
|
||||
if (unlikely(src == dst)) {
|
||||
/* Handle inplace operation */
|
||||
if (unlikely(req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI)) {
|
||||
req_ctx->out_nents = 0;
|
||||
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
|
||||
req_ctx->in_nents, src,
|
||||
nbytes, 0, true, &req_ctx->in_mlli_nents);
|
||||
}
|
||||
} else {
|
||||
/* Map the dst sg */
|
||||
if (unlikely(ssi_buffer_mgr_map_scatterlist(
|
||||
dev,dst, nbytes,
|
||||
DMA_BIDIRECTIONAL, &req_ctx->out_nents,
|
||||
LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy,
|
||||
&mapped_nents))){
|
||||
rc = -ENOMEM;
|
||||
goto ablkcipher_exit;
|
||||
}
|
||||
if (mapped_nents > 1)
|
||||
req_ctx->dma_buf_type = SSI_DMA_BUF_MLLI;
|
||||
|
||||
if (unlikely((req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI))) {
|
||||
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
|
||||
req_ctx->in_nents, src,
|
||||
nbytes, 0, true,
|
||||
&req_ctx->in_mlli_nents);
|
||||
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
|
||||
req_ctx->out_nents, dst,
|
||||
nbytes, 0, true,
|
||||
&req_ctx->out_mlli_nents);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI)) {
|
||||
mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
|
||||
rc = ssi_buffer_mgr_generate_mlli(dev, &sg_data, mlli_params);
|
||||
if (unlikely(rc!= 0))
|
||||
goto ablkcipher_exit;
|
||||
|
||||
}
|
||||
|
||||
SSI_LOG_DEBUG("areq_ctx->dma_buf_type = %s\n",
|
||||
GET_DMA_BUFFER_TYPE(req_ctx->dma_buf_type));
|
||||
|
||||
return 0;
|
||||
|
||||
ablkcipher_exit:
|
||||
ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ssi_buffer_mgr_map_hash_request_final(
|
||||
struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, bool do_update)
|
||||
{
|
||||
|
@ -55,6 +55,22 @@ int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata);
|
||||
|
||||
int ssi_buffer_mgr_fini(struct ssi_drvdata *drvdata);
|
||||
|
||||
int ssi_buffer_mgr_map_blkcipher_request(
|
||||
struct ssi_drvdata *drvdata,
|
||||
void *ctx,
|
||||
unsigned int ivsize,
|
||||
unsigned int nbytes,
|
||||
void *info,
|
||||
struct scatterlist *src,
|
||||
struct scatterlist *dst);
|
||||
|
||||
void ssi_buffer_mgr_unmap_blkcipher_request(
|
||||
struct device *dev,
|
||||
void *ctx,
|
||||
unsigned int ivsize,
|
||||
struct scatterlist *src,
|
||||
struct scatterlist *dst);
|
||||
|
||||
int ssi_buffer_mgr_map_hash_request_final(struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, bool do_update);
|
||||
|
||||
int ssi_buffer_mgr_map_hash_request_update(struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, unsigned int block_size);
|
||||
|
1440
drivers/staging/ccree/ssi_cipher.c
Normal file
1440
drivers/staging/ccree/ssi_cipher.c
Normal file
File diff suppressed because it is too large
Load Diff
88
drivers/staging/ccree/ssi_cipher.h
Normal file
88
drivers/staging/ccree/ssi_cipher.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* \file ssi_cipher.h
|
||||
ARM CryptoCell Cipher Crypto API
|
||||
*/
|
||||
|
||||
#ifndef __SSI_CIPHER_H__
|
||||
#define __SSI_CIPHER_H__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include "ssi_driver.h"
|
||||
#include "ssi_buffer_mgr.h"
|
||||
|
||||
|
||||
/* Crypto cipher flags */
|
||||
#define CC_CRYPTO_CIPHER_KEY_KFDE0 (1 << 0)
|
||||
#define CC_CRYPTO_CIPHER_KEY_KFDE1 (1 << 1)
|
||||
#define CC_CRYPTO_CIPHER_KEY_KFDE2 (1 << 2)
|
||||
#define CC_CRYPTO_CIPHER_KEY_KFDE3 (1 << 3)
|
||||
#define CC_CRYPTO_CIPHER_DU_SIZE_512B (1 << 4)
|
||||
|
||||
#define CC_CRYPTO_CIPHER_KEY_KFDE_MASK (CC_CRYPTO_CIPHER_KEY_KFDE0 | CC_CRYPTO_CIPHER_KEY_KFDE1 | CC_CRYPTO_CIPHER_KEY_KFDE2 | CC_CRYPTO_CIPHER_KEY_KFDE3)
|
||||
|
||||
|
||||
struct blkcipher_req_ctx {
|
||||
struct async_gen_req_ctx gen_ctx;
|
||||
enum ssi_req_dma_buf_type dma_buf_type;
|
||||
uint32_t in_nents;
|
||||
uint32_t in_mlli_nents;
|
||||
uint32_t out_nents;
|
||||
uint32_t out_mlli_nents;
|
||||
uint8_t *backup_info; /*store iv for generated IV flow*/
|
||||
struct mlli_params mlli_params;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata);
|
||||
|
||||
int ssi_ablkcipher_free(struct ssi_drvdata *drvdata);
|
||||
|
||||
#ifndef CRYPTO_ALG_BULK_MASK
|
||||
|
||||
#define CRYPTO_ALG_BULK_DU_512 0x00002000
|
||||
#define CRYPTO_ALG_BULK_DU_4096 0x00004000
|
||||
#define CRYPTO_ALG_BULK_MASK (CRYPTO_ALG_BULK_DU_512 |\
|
||||
CRYPTO_ALG_BULK_DU_4096)
|
||||
#endif /* CRYPTO_ALG_BULK_MASK */
|
||||
|
||||
|
||||
#ifdef CRYPTO_TFM_REQ_HW_KEY
|
||||
|
||||
static inline bool ssi_is_hw_key(struct crypto_tfm *tfm)
|
||||
{
|
||||
return (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_HW_KEY);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct arm_hw_key_info {
|
||||
int hw_key1;
|
||||
int hw_key2;
|
||||
};
|
||||
|
||||
static inline bool ssi_is_hw_key(struct crypto_tfm *tfm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CRYPTO_TFM_REQ_HW_KEY */
|
||||
|
||||
|
||||
#endif /*__SSI_CIPHER_H__*/
|
@ -23,6 +23,7 @@
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/authenc.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/moduleparam.h>
|
||||
@ -61,6 +62,7 @@
|
||||
#include "ssi_request_mgr.h"
|
||||
#include "ssi_buffer_mgr.h"
|
||||
#include "ssi_sysfs.h"
|
||||
#include "ssi_cipher.h"
|
||||
#include "ssi_hash.h"
|
||||
#include "ssi_sram_mgr.h"
|
||||
#include "ssi_pm.h"
|
||||
@ -219,6 +221,9 @@ static int init_cc_resources(struct platform_device *plat_dev)
|
||||
goto init_cc_res_err;
|
||||
}
|
||||
|
||||
/*Initialize inflight counter used in dx_ablkcipher_secure_complete used for count of BYSPASS blocks operations*/
|
||||
new_drvdata->inflight_counter = 0;
|
||||
|
||||
dev_set_drvdata(&plat_dev->dev, new_drvdata);
|
||||
/* Get device resources */
|
||||
/* First CC registers space */
|
||||
@ -343,6 +348,13 @@ static int init_cc_resources(struct platform_device *plat_dev)
|
||||
goto init_cc_res_err;
|
||||
}
|
||||
|
||||
/* Allocate crypto algs */
|
||||
rc = ssi_ablkcipher_alloc(new_drvdata);
|
||||
if (unlikely(rc != 0)) {
|
||||
SSI_LOG_ERR("ssi_ablkcipher_alloc failed\n");
|
||||
goto init_cc_res_err;
|
||||
}
|
||||
|
||||
rc = ssi_hash_alloc(new_drvdata);
|
||||
if (unlikely(rc != 0)) {
|
||||
SSI_LOG_ERR("ssi_hash_alloc failed\n");
|
||||
@ -356,6 +368,7 @@ init_cc_res_err:
|
||||
|
||||
if (new_drvdata != NULL) {
|
||||
ssi_hash_free(new_drvdata);
|
||||
ssi_ablkcipher_free(new_drvdata);
|
||||
ssi_power_mgr_fini(new_drvdata);
|
||||
ssi_buffer_mgr_fini(new_drvdata);
|
||||
request_mgr_fini(new_drvdata);
|
||||
@ -396,6 +409,7 @@ static void cleanup_cc_resources(struct platform_device *plat_dev)
|
||||
(struct ssi_drvdata *)dev_get_drvdata(&plat_dev->dev);
|
||||
|
||||
ssi_hash_free(drvdata);
|
||||
ssi_ablkcipher_free(drvdata);
|
||||
ssi_power_mgr_fini(drvdata);
|
||||
ssi_buffer_mgr_fini(drvdata);
|
||||
request_mgr_fini(drvdata);
|
||||
|
@ -29,6 +29,7 @@
|
||||
#endif
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/authenc.h>
|
||||
@ -141,15 +142,44 @@ struct ssi_drvdata {
|
||||
struct completion icache_setup_completion;
|
||||
void *buff_mgr_handle;
|
||||
void *hash_handle;
|
||||
void *blkcipher_handle;
|
||||
void *request_mgr_handle;
|
||||
void *sram_mgr_handle;
|
||||
|
||||
#ifdef ENABLE_CYCLE_COUNT
|
||||
cycles_t isr_exit_cycles; /* Save for isr-to-tasklet latency */
|
||||
#endif
|
||||
uint32_t inflight_counter;
|
||||
|
||||
};
|
||||
|
||||
struct ssi_crypto_alg {
|
||||
struct list_head entry;
|
||||
int cipher_mode;
|
||||
int flow_mode; /* Note: currently, refers to the cipher mode only. */
|
||||
int auth_mode;
|
||||
struct ssi_drvdata *drvdata;
|
||||
struct crypto_alg crypto_alg;
|
||||
};
|
||||
|
||||
struct ssi_alg_template {
|
||||
char name[CRYPTO_MAX_ALG_NAME];
|
||||
char driver_name[CRYPTO_MAX_ALG_NAME];
|
||||
unsigned int blocksize;
|
||||
u32 type;
|
||||
union {
|
||||
struct ablkcipher_alg ablkcipher;
|
||||
struct blkcipher_alg blkcipher;
|
||||
struct cipher_alg cipher;
|
||||
struct compress_alg compress;
|
||||
} template_u;
|
||||
int cipher_mode;
|
||||
int flow_mode; /* Note: currently, refers to the cipher mode only. */
|
||||
int auth_mode;
|
||||
bool synchronous;
|
||||
struct ssi_drvdata *drvdata;
|
||||
};
|
||||
|
||||
struct async_gen_req_ctx {
|
||||
dma_addr_t iv_dma_addr;
|
||||
enum drv_crypto_direction op_type;
|
||||
|
Loading…
Reference in New Issue
Block a user