staging: ccree: add ahash support
Add CryptoCell async. hash and HMAC 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
abefd6741d
commit
50cfbbb7e6
@ -2,6 +2,12 @@ config CRYPTO_DEV_CCREE
|
||||
tristate "Support for ARM TrustZone CryptoCell C7XX family of Crypto accelerators"
|
||||
depends on CRYPTO_HW && OF && HAS_DMA
|
||||
default n
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_MD5
|
||||
select CRYPTO_SHA256
|
||||
select CRYPTO_SHA512
|
||||
select CRYPTO_HMAC
|
||||
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_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_hash.o ssi_sram_mgr.o ssi_pm.o ssi_pm_ext.o
|
||||
|
@ -220,6 +220,28 @@ struct drv_ctx_generic {
|
||||
} __attribute__((__may_alias__));
|
||||
|
||||
|
||||
struct drv_ctx_hash {
|
||||
enum drv_crypto_alg alg; /* DRV_CRYPTO_ALG_HASH */
|
||||
enum drv_hash_mode mode;
|
||||
uint8_t digest[CC_DIGEST_SIZE_MAX];
|
||||
/* reserve to end of allocated context size */
|
||||
uint8_t reserved[CC_CTX_SIZE - 2 * sizeof(uint32_t) -
|
||||
CC_DIGEST_SIZE_MAX];
|
||||
};
|
||||
|
||||
/* !!!! drv_ctx_hmac should have the same structure as drv_ctx_hash except
|
||||
k0, k0_size fields */
|
||||
struct drv_ctx_hmac {
|
||||
enum drv_crypto_alg alg; /* DRV_CRYPTO_ALG_HMAC */
|
||||
enum drv_hash_mode mode;
|
||||
uint8_t digest[CC_DIGEST_SIZE_MAX];
|
||||
uint32_t k0[CC_HMAC_BLOCK_SIZE_MAX/sizeof(uint32_t)];
|
||||
uint32_t k0_size;
|
||||
/* reserve to end of allocated context size */
|
||||
uint8_t reserved[CC_CTX_SIZE - 3 * sizeof(uint32_t) -
|
||||
CC_DIGEST_SIZE_MAX - CC_HMAC_BLOCK_SIZE_MAX];
|
||||
};
|
||||
|
||||
/*******************************************************************/
|
||||
/***************** MESSAGE BASED CONTEXTS **************************/
|
||||
/*******************************************************************/
|
||||
|
78
drivers/staging/ccree/hash_defs.h
Normal file
78
drivers/staging/ccree/hash_defs.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 _HASH_DEFS_H__
|
||||
#define _HASH_DEFS_H__
|
||||
|
||||
#include "cc_crypto_ctx.h"
|
||||
|
||||
/* this files provides definitions required for hash engine drivers */
|
||||
#ifndef CC_CONFIG_HASH_SHA_512_SUPPORTED
|
||||
#define SEP_HASH_LENGTH_WORDS 2
|
||||
#else
|
||||
#define SEP_HASH_LENGTH_WORDS 4
|
||||
#endif
|
||||
|
||||
#ifdef BIG__ENDIAN
|
||||
#define OPAD_CURRENT_LENGTH 0x40000000, 0x00000000 , 0x00000000, 0x00000000
|
||||
#define HASH_LARVAL_MD5 0x76543210, 0xFEDCBA98, 0x89ABCDEF, 0x01234567
|
||||
#define HASH_LARVAL_SHA1 0xF0E1D2C3, 0x76543210, 0xFEDCBA98, 0x89ABCDEF, 0x01234567
|
||||
#define HASH_LARVAL_SHA224 0XA44FFABE, 0XA78FF964, 0X11155868, 0X310BC0FF, 0X39590EF7, 0X17DD7030, 0X07D57C36, 0XD89E05C1
|
||||
#define HASH_LARVAL_SHA256 0X19CDE05B, 0XABD9831F, 0X8C68059B, 0X7F520E51, 0X3AF54FA5, 0X72F36E3C, 0X85AE67BB, 0X67E6096A
|
||||
#define HASH_LARVAL_SHA384 0X1D48B547, 0XA44FFABE, 0X0D2E0CDB, 0XA78FF964, 0X874AB48E, 0X11155868, 0X67263367, 0X310BC0FF, 0XD8EC2F15, 0X39590EF7, 0X5A015991, 0X17DD7030, 0X2A299A62, 0X07D57C36, 0X5D9DBBCB, 0XD89E05C1
|
||||
#define HASH_LARVAL_SHA512 0X19CDE05B, 0X79217E13, 0XABD9831F, 0X6BBD41FB, 0X8C68059B, 0X1F6C3E2B, 0X7F520E51, 0XD182E6AD, 0X3AF54FA5, 0XF1361D5F, 0X72F36E3C, 0X2BF894FE, 0X85AE67BB, 0X3BA7CA84, 0X67E6096A, 0X08C9BCF3
|
||||
#else
|
||||
#define OPAD_CURRENT_LENGTH 0x00000040, 0x00000000, 0x00000000, 0x00000000
|
||||
#define HASH_LARVAL_MD5 0x10325476, 0x98BADCFE, 0xEFCDAB89, 0x67452301
|
||||
#define HASH_LARVAL_SHA1 0xC3D2E1F0, 0x10325476, 0x98BADCFE, 0xEFCDAB89, 0x67452301
|
||||
#define HASH_LARVAL_SHA224 0xbefa4fa4, 0x64f98fa7, 0x68581511, 0xffc00b31, 0xf70e5939, 0x3070dd17, 0x367cd507, 0xc1059ed8
|
||||
#define HASH_LARVAL_SHA256 0x5be0cd19, 0x1f83d9ab, 0x9b05688c, 0x510e527f, 0xa54ff53a, 0x3c6ef372, 0xbb67ae85, 0x6a09e667
|
||||
#define HASH_LARVAL_SHA384 0X47B5481D, 0XBEFA4FA4, 0XDB0C2E0D, 0X64F98FA7, 0X8EB44A87, 0X68581511, 0X67332667, 0XFFC00B31, 0X152FECD8, 0XF70E5939, 0X9159015A, 0X3070DD17, 0X629A292A, 0X367CD507, 0XCBBB9D5D, 0XC1059ED8
|
||||
#define HASH_LARVAL_SHA512 0x5be0cd19, 0x137e2179, 0x1f83d9ab, 0xfb41bd6b, 0x9b05688c, 0x2b3e6c1f, 0x510e527f, 0xade682d1, 0xa54ff53a, 0x5f1d36f1, 0x3c6ef372, 0xfe94f82b, 0xbb67ae85, 0x84caa73b, 0x6a09e667, 0xf3bcc908
|
||||
#endif
|
||||
|
||||
enum HashConfig1Padding {
|
||||
HASH_PADDING_DISABLED = 0,
|
||||
HASH_PADDING_ENABLED = 1,
|
||||
HASH_DIGEST_RESULT_LITTLE_ENDIAN = 2,
|
||||
HASH_CONFIG1_PADDING_RESERVE32 = INT32_MAX,
|
||||
};
|
||||
|
||||
enum HashCipherDoPadding {
|
||||
DO_NOT_PAD = 0,
|
||||
DO_PAD = 1,
|
||||
HASH_CIPHER_DO_PADDING_RESERVE32 = INT32_MAX,
|
||||
};
|
||||
|
||||
typedef struct SepHashPrivateContext {
|
||||
/* The current length is placed at the end of the context buffer because the hash
|
||||
context is used for all HMAC operations as well. HMAC context includes a 64 bytes
|
||||
K0 field. The size of struct drv_ctx_hash reserved field is 88/184 bytes depend if t
|
||||
he SHA512 is supported ( in this case teh context size is 256 bytes).
|
||||
The size of struct drv_ctx_hash reseved field is 20 or 52 depend if the SHA512 is supported.
|
||||
This means that this structure size (without the reserved field can be up to 20 bytes ,
|
||||
in case sha512 is not suppported it is 20 bytes (SEP_HASH_LENGTH_WORDS define to 2 ) and in the other
|
||||
case it is 28 (SEP_HASH_LENGTH_WORDS define to 4) */
|
||||
uint32_t reserved[(sizeof(struct drv_ctx_hash)/sizeof(uint32_t)) - SEP_HASH_LENGTH_WORDS - 3];
|
||||
uint32_t CurrentDigestedLength[SEP_HASH_LENGTH_WORDS];
|
||||
uint32_t KeyType;
|
||||
uint32_t dataCompleted;
|
||||
uint32_t hmacFinalization;
|
||||
/* no space left */
|
||||
} SepHashPrivateContext_s;
|
||||
|
||||
#endif /*_HASH_DEFS_H__*/
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/version.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/authenc.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/dmapool.h>
|
||||
@ -27,6 +28,7 @@
|
||||
|
||||
#include "ssi_buffer_mgr.h"
|
||||
#include "cc_lli_defs.h"
|
||||
#include "ssi_hash.h"
|
||||
|
||||
#define LLI_MAX_NUM_OF_DATA_ENTRIES 128
|
||||
#define LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES 4
|
||||
@ -281,11 +283,6 @@ static inline int ssi_buffer_mgr_render_scatterlist_to_mlli(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssi_buffer_mgr_generate_mlli (
|
||||
struct device *dev,
|
||||
struct buffer_array *sg_data,
|
||||
struct mlli_params *mlli_params) __maybe_unused;
|
||||
|
||||
static int ssi_buffer_mgr_generate_mlli(
|
||||
struct device *dev,
|
||||
struct buffer_array *sg_data,
|
||||
@ -427,11 +424,6 @@ err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssi_buffer_mgr_map_scatterlist (struct device *dev,
|
||||
struct scatterlist *sg, unsigned int nbytes, int direction,
|
||||
uint32_t *nents, uint32_t max_sg_nents, uint32_t *lbytes,
|
||||
uint32_t *mapped_nents) __maybe_unused;
|
||||
|
||||
static int ssi_buffer_mgr_map_scatterlist(
|
||||
struct device *dev, struct scatterlist *sg,
|
||||
unsigned int nbytes, int direction,
|
||||
@ -493,6 +485,305 @@ static int ssi_buffer_mgr_map_scatterlist(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ssi_ahash_handle_curr_buf(struct device *dev,
|
||||
struct ahash_req_ctx *areq_ctx,
|
||||
uint8_t* curr_buff,
|
||||
uint32_t curr_buff_cnt,
|
||||
struct buffer_array *sg_data)
|
||||
{
|
||||
SSI_LOG_DEBUG(" handle curr buff %x set to DLLI \n", curr_buff_cnt);
|
||||
/* create sg for the current buffer */
|
||||
sg_init_one(areq_ctx->buff_sg,curr_buff, curr_buff_cnt);
|
||||
if (unlikely(dma_map_sg(dev, areq_ctx->buff_sg, 1,
|
||||
DMA_TO_DEVICE) != 1)) {
|
||||
SSI_LOG_ERR("dma_map_sg() "
|
||||
"src buffer failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
SSI_LOG_DEBUG("Mapped curr_buff: dma_address=0x%llX "
|
||||
"page_link=0x%08lX addr=%pK "
|
||||
"offset=%u length=%u\n",
|
||||
(unsigned long long)sg_dma_address(areq_ctx->buff_sg),
|
||||
areq_ctx->buff_sg->page_link,
|
||||
sg_virt(areq_ctx->buff_sg),
|
||||
areq_ctx->buff_sg->offset,
|
||||
areq_ctx->buff_sg->length);
|
||||
areq_ctx->data_dma_buf_type = SSI_DMA_BUF_DLLI;
|
||||
areq_ctx->curr_sg = areq_ctx->buff_sg;
|
||||
areq_ctx->in_nents = 0;
|
||||
/* prepare for case of MLLI */
|
||||
ssi_buffer_mgr_add_scatterlist_entry(sg_data, 1, areq_ctx->buff_sg,
|
||||
curr_buff_cnt, 0, false, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssi_buffer_mgr_map_hash_request_final(
|
||||
struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, bool do_update)
|
||||
{
|
||||
struct ahash_req_ctx *areq_ctx = (struct ahash_req_ctx *)ctx;
|
||||
struct device *dev = &drvdata->plat_dev->dev;
|
||||
uint8_t* curr_buff = areq_ctx->buff_index ? areq_ctx->buff1 :
|
||||
areq_ctx->buff0;
|
||||
uint32_t *curr_buff_cnt = areq_ctx->buff_index ? &areq_ctx->buff1_cnt :
|
||||
&areq_ctx->buff0_cnt;
|
||||
struct mlli_params *mlli_params = &areq_ctx->mlli_params;
|
||||
struct buffer_array sg_data;
|
||||
struct buff_mgr_handle *buff_mgr = drvdata->buff_mgr_handle;
|
||||
uint32_t dummy = 0;
|
||||
uint32_t mapped_nents = 0;
|
||||
|
||||
SSI_LOG_DEBUG(" final params : curr_buff=%pK "
|
||||
"curr_buff_cnt=0x%X nbytes = 0x%X "
|
||||
"src=%pK curr_index=%u\n",
|
||||
curr_buff, *curr_buff_cnt, nbytes,
|
||||
src, areq_ctx->buff_index);
|
||||
/* Init the type of the dma buffer */
|
||||
areq_ctx->data_dma_buf_type = SSI_DMA_BUF_NULL;
|
||||
mlli_params->curr_pool = NULL;
|
||||
sg_data.num_of_buffers = 0;
|
||||
areq_ctx->in_nents = 0;
|
||||
|
||||
if (unlikely(nbytes == 0 && *curr_buff_cnt == 0)) {
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*TODO: copy data in case that buffer is enough for operation */
|
||||
/* map the previous buffer */
|
||||
if (*curr_buff_cnt != 0 ) {
|
||||
if (ssi_ahash_handle_curr_buf(dev, areq_ctx, curr_buff,
|
||||
*curr_buff_cnt, &sg_data) != 0) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (src && (nbytes > 0) && do_update) {
|
||||
if ( unlikely( ssi_buffer_mgr_map_scatterlist( dev,src,
|
||||
nbytes,
|
||||
DMA_TO_DEVICE,
|
||||
&areq_ctx->in_nents,
|
||||
LLI_MAX_NUM_OF_DATA_ENTRIES,
|
||||
&dummy, &mapped_nents))){
|
||||
goto unmap_curr_buff;
|
||||
}
|
||||
if ( src && (mapped_nents == 1)
|
||||
&& (areq_ctx->data_dma_buf_type == SSI_DMA_BUF_NULL) ) {
|
||||
memcpy(areq_ctx->buff_sg,src,
|
||||
sizeof(struct scatterlist));
|
||||
areq_ctx->buff_sg->length = nbytes;
|
||||
areq_ctx->curr_sg = areq_ctx->buff_sg;
|
||||
areq_ctx->data_dma_buf_type = SSI_DMA_BUF_DLLI;
|
||||
} else {
|
||||
areq_ctx->data_dma_buf_type = SSI_DMA_BUF_MLLI;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*build mlli */
|
||||
if (unlikely(areq_ctx->data_dma_buf_type == SSI_DMA_BUF_MLLI)) {
|
||||
mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
|
||||
/* add the src data to the sg_data */
|
||||
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
|
||||
areq_ctx->in_nents,
|
||||
src,
|
||||
nbytes, 0,
|
||||
true, &areq_ctx->mlli_nents);
|
||||
if (unlikely(ssi_buffer_mgr_generate_mlli(dev, &sg_data,
|
||||
mlli_params) != 0)) {
|
||||
goto fail_unmap_din;
|
||||
}
|
||||
}
|
||||
/* change the buffer index for the unmap function */
|
||||
areq_ctx->buff_index = (areq_ctx->buff_index^1);
|
||||
SSI_LOG_DEBUG("areq_ctx->data_dma_buf_type = %s\n",
|
||||
GET_DMA_BUFFER_TYPE(areq_ctx->data_dma_buf_type));
|
||||
return 0;
|
||||
|
||||
fail_unmap_din:
|
||||
dma_unmap_sg(dev, src, areq_ctx->in_nents, DMA_TO_DEVICE);
|
||||
|
||||
unmap_curr_buff:
|
||||
if (*curr_buff_cnt != 0 ) {
|
||||
dma_unmap_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE);
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int ssi_buffer_mgr_map_hash_request_update(
|
||||
struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, unsigned int block_size)
|
||||
{
|
||||
struct ahash_req_ctx *areq_ctx = (struct ahash_req_ctx *)ctx;
|
||||
struct device *dev = &drvdata->plat_dev->dev;
|
||||
uint8_t* curr_buff = areq_ctx->buff_index ? areq_ctx->buff1 :
|
||||
areq_ctx->buff0;
|
||||
uint32_t *curr_buff_cnt = areq_ctx->buff_index ? &areq_ctx->buff1_cnt :
|
||||
&areq_ctx->buff0_cnt;
|
||||
uint8_t* next_buff = areq_ctx->buff_index ? areq_ctx->buff0 :
|
||||
areq_ctx->buff1;
|
||||
uint32_t *next_buff_cnt = areq_ctx->buff_index ? &areq_ctx->buff0_cnt :
|
||||
&areq_ctx->buff1_cnt;
|
||||
struct mlli_params *mlli_params = &areq_ctx->mlli_params;
|
||||
unsigned int update_data_len;
|
||||
uint32_t total_in_len = nbytes + *curr_buff_cnt;
|
||||
struct buffer_array sg_data;
|
||||
struct buff_mgr_handle *buff_mgr = drvdata->buff_mgr_handle;
|
||||
unsigned int swap_index = 0;
|
||||
uint32_t dummy = 0;
|
||||
uint32_t mapped_nents = 0;
|
||||
|
||||
SSI_LOG_DEBUG(" update params : curr_buff=%pK "
|
||||
"curr_buff_cnt=0x%X nbytes=0x%X "
|
||||
"src=%pK curr_index=%u \n",
|
||||
curr_buff, *curr_buff_cnt, nbytes,
|
||||
src, areq_ctx->buff_index);
|
||||
/* Init the type of the dma buffer */
|
||||
areq_ctx->data_dma_buf_type = SSI_DMA_BUF_NULL;
|
||||
mlli_params->curr_pool = NULL;
|
||||
areq_ctx->curr_sg = NULL;
|
||||
sg_data.num_of_buffers = 0;
|
||||
areq_ctx->in_nents = 0;
|
||||
|
||||
if (unlikely(total_in_len < block_size)) {
|
||||
SSI_LOG_DEBUG(" less than one block: curr_buff=%pK "
|
||||
"*curr_buff_cnt=0x%X copy_to=%pK\n",
|
||||
curr_buff, *curr_buff_cnt,
|
||||
&curr_buff[*curr_buff_cnt]);
|
||||
areq_ctx->in_nents =
|
||||
ssi_buffer_mgr_get_sgl_nents(src,
|
||||
nbytes,
|
||||
&dummy, NULL);
|
||||
sg_copy_to_buffer(src, areq_ctx->in_nents,
|
||||
&curr_buff[*curr_buff_cnt], nbytes);
|
||||
*curr_buff_cnt += nbytes;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Calculate the residue size*/
|
||||
*next_buff_cnt = total_in_len & (block_size - 1);
|
||||
/* update data len */
|
||||
update_data_len = total_in_len - *next_buff_cnt;
|
||||
|
||||
SSI_LOG_DEBUG(" temp length : *next_buff_cnt=0x%X "
|
||||
"update_data_len=0x%X\n",
|
||||
*next_buff_cnt, update_data_len);
|
||||
|
||||
/* Copy the new residue to next buffer */
|
||||
if (*next_buff_cnt != 0) {
|
||||
SSI_LOG_DEBUG(" handle residue: next buff %pK skip data %u"
|
||||
" residue %u \n", next_buff,
|
||||
(update_data_len - *curr_buff_cnt),
|
||||
*next_buff_cnt);
|
||||
ssi_buffer_mgr_copy_scatterlist_portion(next_buff, src,
|
||||
(update_data_len -*curr_buff_cnt),
|
||||
nbytes,SSI_SG_TO_BUF);
|
||||
/* change the buffer index for next operation */
|
||||
swap_index = 1;
|
||||
}
|
||||
|
||||
if (*curr_buff_cnt != 0) {
|
||||
if (ssi_ahash_handle_curr_buf(dev, areq_ctx, curr_buff,
|
||||
*curr_buff_cnt, &sg_data) != 0) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* change the buffer index for next operation */
|
||||
swap_index = 1;
|
||||
}
|
||||
|
||||
if ( update_data_len > *curr_buff_cnt ) {
|
||||
if ( unlikely( ssi_buffer_mgr_map_scatterlist( dev,src,
|
||||
(update_data_len -*curr_buff_cnt),
|
||||
DMA_TO_DEVICE,
|
||||
&areq_ctx->in_nents,
|
||||
LLI_MAX_NUM_OF_DATA_ENTRIES,
|
||||
&dummy, &mapped_nents))){
|
||||
goto unmap_curr_buff;
|
||||
}
|
||||
if ( (mapped_nents == 1)
|
||||
&& (areq_ctx->data_dma_buf_type == SSI_DMA_BUF_NULL) ) {
|
||||
/* only one entry in the SG and no previous data */
|
||||
memcpy(areq_ctx->buff_sg,src,
|
||||
sizeof(struct scatterlist));
|
||||
areq_ctx->buff_sg->length = update_data_len;
|
||||
areq_ctx->data_dma_buf_type = SSI_DMA_BUF_DLLI;
|
||||
areq_ctx->curr_sg = areq_ctx->buff_sg;
|
||||
} else {
|
||||
areq_ctx->data_dma_buf_type = SSI_DMA_BUF_MLLI;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(areq_ctx->data_dma_buf_type == SSI_DMA_BUF_MLLI)) {
|
||||
mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
|
||||
/* add the src data to the sg_data */
|
||||
ssi_buffer_mgr_add_scatterlist_entry(&sg_data,
|
||||
areq_ctx->in_nents,
|
||||
src,
|
||||
(update_data_len - *curr_buff_cnt), 0,
|
||||
true, &areq_ctx->mlli_nents);
|
||||
if (unlikely(ssi_buffer_mgr_generate_mlli(dev, &sg_data,
|
||||
mlli_params) != 0)) {
|
||||
goto fail_unmap_din;
|
||||
}
|
||||
|
||||
}
|
||||
areq_ctx->buff_index = (areq_ctx->buff_index^swap_index);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_unmap_din:
|
||||
dma_unmap_sg(dev, src, areq_ctx->in_nents, DMA_TO_DEVICE);
|
||||
|
||||
unmap_curr_buff:
|
||||
if (*curr_buff_cnt != 0 ) {
|
||||
dma_unmap_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE);
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void ssi_buffer_mgr_unmap_hash_request(
|
||||
struct device *dev, void *ctx, struct scatterlist *src, bool do_revert)
|
||||
{
|
||||
struct ahash_req_ctx *areq_ctx = (struct ahash_req_ctx *)ctx;
|
||||
uint32_t *prev_len = areq_ctx->buff_index ? &areq_ctx->buff0_cnt :
|
||||
&areq_ctx->buff1_cnt;
|
||||
|
||||
/*In case a pool was set, a table was
|
||||
allocated and should be released */
|
||||
if (areq_ctx->mlli_params.curr_pool != NULL) {
|
||||
SSI_LOG_DEBUG("free MLLI buffer: dma=0x%llX virt=%pK\n",
|
||||
(unsigned long long)areq_ctx->mlli_params.mlli_dma_addr,
|
||||
areq_ctx->mlli_params.mlli_virt_addr);
|
||||
SSI_RESTORE_DMA_ADDR_TO_48BIT(areq_ctx->mlli_params.mlli_dma_addr);
|
||||
dma_pool_free(areq_ctx->mlli_params.curr_pool,
|
||||
areq_ctx->mlli_params.mlli_virt_addr,
|
||||
areq_ctx->mlli_params.mlli_dma_addr);
|
||||
}
|
||||
|
||||
if ((src) && likely(areq_ctx->in_nents != 0)) {
|
||||
SSI_LOG_DEBUG("Unmapped sg src: virt=%pK dma=0x%llX len=0x%X\n",
|
||||
sg_virt(src),
|
||||
(unsigned long long)sg_dma_address(src),
|
||||
sg_dma_len(src));
|
||||
SSI_RESTORE_DMA_ADDR_TO_48BIT(sg_dma_address(src));
|
||||
dma_unmap_sg(dev, src,
|
||||
areq_ctx->in_nents, DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
if (*prev_len != 0) {
|
||||
SSI_LOG_DEBUG("Unmapped buffer: areq_ctx->buff_sg=%pK"
|
||||
"dma=0x%llX len 0x%X\n",
|
||||
sg_virt(areq_ctx->buff_sg),
|
||||
(unsigned long long)sg_dma_address(areq_ctx->buff_sg),
|
||||
sg_dma_len(areq_ctx->buff_sg));
|
||||
dma_unmap_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE);
|
||||
if (!do_revert) {
|
||||
/* clean the previous data length for update operation */
|
||||
*prev_len = 0;
|
||||
} else {
|
||||
areq_ctx->buff_index ^= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata)
|
||||
{
|
||||
struct buff_mgr_handle *buff_mgr_handle;
|
||||
|
@ -55,6 +55,12 @@ int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata);
|
||||
|
||||
int ssi_buffer_mgr_fini(struct ssi_drvdata *drvdata);
|
||||
|
||||
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);
|
||||
|
||||
void ssi_buffer_mgr_unmap_hash_request(struct device *dev, void *ctx, struct scatterlist *src, bool do_revert);
|
||||
|
||||
void ssi_buffer_mgr_copy_scatterlist_portion(u8 *dest, struct scatterlist *sg, uint32_t to_skip, uint32_t end, enum ssi_sg_cpy_direct direct);
|
||||
|
||||
void ssi_buffer_mgr_zero_sgl(struct scatterlist *sgl, uint32_t data_len);
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "ssi_request_mgr.h"
|
||||
#include "ssi_buffer_mgr.h"
|
||||
#include "ssi_sysfs.h"
|
||||
#include "ssi_hash.h"
|
||||
#include "ssi_sram_mgr.h"
|
||||
#include "ssi_pm.h"
|
||||
|
||||
@ -218,8 +219,6 @@ static int init_cc_resources(struct platform_device *plat_dev)
|
||||
goto init_cc_res_err;
|
||||
}
|
||||
|
||||
new_drvdata->inflight_counter = 0;
|
||||
|
||||
dev_set_drvdata(&plat_dev->dev, new_drvdata);
|
||||
/* Get device resources */
|
||||
/* First CC registers space */
|
||||
@ -344,12 +343,19 @@ static int init_cc_resources(struct platform_device *plat_dev)
|
||||
goto init_cc_res_err;
|
||||
}
|
||||
|
||||
rc = ssi_hash_alloc(new_drvdata);
|
||||
if (unlikely(rc != 0)) {
|
||||
SSI_LOG_ERR("ssi_hash_alloc failed\n");
|
||||
goto init_cc_res_err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
init_cc_res_err:
|
||||
SSI_LOG_ERR("Freeing CC HW resources!\n");
|
||||
|
||||
if (new_drvdata != NULL) {
|
||||
ssi_hash_free(new_drvdata);
|
||||
ssi_power_mgr_fini(new_drvdata);
|
||||
ssi_buffer_mgr_fini(new_drvdata);
|
||||
request_mgr_fini(new_drvdata);
|
||||
@ -389,6 +395,7 @@ static void cleanup_cc_resources(struct platform_device *plat_dev)
|
||||
struct ssi_drvdata *drvdata =
|
||||
(struct ssi_drvdata *)dev_get_drvdata(&plat_dev->dev);
|
||||
|
||||
ssi_hash_free(drvdata);
|
||||
ssi_power_mgr_fini(drvdata);
|
||||
ssi_buffer_mgr_fini(drvdata);
|
||||
request_mgr_fini(drvdata);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/authenc.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#ifndef INT32_MAX /* Missing in Linux kernel */
|
||||
@ -50,6 +51,7 @@
|
||||
#define CC_SUPPORT_SHA DX_DEV_SHA_MAX
|
||||
#include "cc_crypto_ctx.h"
|
||||
#include "ssi_sysfs.h"
|
||||
#include "hash_defs.h"
|
||||
|
||||
#define DRV_MODULE_VERSION "3.0"
|
||||
|
||||
@ -138,13 +140,13 @@ struct ssi_drvdata {
|
||||
ssi_sram_addr_t mlli_sram_addr;
|
||||
struct completion icache_setup_completion;
|
||||
void *buff_mgr_handle;
|
||||
void *hash_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;
|
||||
|
||||
};
|
||||
|
||||
|
2732
drivers/staging/ccree/ssi_hash.c
Normal file
2732
drivers/staging/ccree/ssi_hash.c
Normal file
File diff suppressed because it is too large
Load Diff
101
drivers/staging/ccree/ssi_hash.h
Normal file
101
drivers/staging/ccree/ssi_hash.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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_hash.h
|
||||
ARM CryptoCell Hash Crypto API
|
||||
*/
|
||||
|
||||
#ifndef __SSI_HASH_H__
|
||||
#define __SSI_HASH_H__
|
||||
|
||||
#include "ssi_buffer_mgr.h"
|
||||
|
||||
#define HMAC_IPAD_CONST 0x36363636
|
||||
#define HMAC_OPAD_CONST 0x5C5C5C5C
|
||||
#if (DX_DEV_SHA_MAX > 256)
|
||||
#define HASH_LEN_SIZE 16
|
||||
#define SSI_MAX_HASH_DIGEST_SIZE SHA512_DIGEST_SIZE
|
||||
#define SSI_MAX_HASH_BLCK_SIZE SHA512_BLOCK_SIZE
|
||||
#else
|
||||
#define HASH_LEN_SIZE 8
|
||||
#define SSI_MAX_HASH_DIGEST_SIZE SHA256_DIGEST_SIZE
|
||||
#define SSI_MAX_HASH_BLCK_SIZE SHA256_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
#define XCBC_MAC_K1_OFFSET 0
|
||||
#define XCBC_MAC_K2_OFFSET 16
|
||||
#define XCBC_MAC_K3_OFFSET 32
|
||||
|
||||
// this struct was taken from drivers/crypto/nx/nx-aes-xcbc.c and it is used for xcbc/cmac statesize
|
||||
struct aeshash_state {
|
||||
u8 state[AES_BLOCK_SIZE];
|
||||
unsigned int count;
|
||||
u8 buffer[AES_BLOCK_SIZE];
|
||||
};
|
||||
|
||||
/* ahash state */
|
||||
struct ahash_req_ctx {
|
||||
uint8_t* buff0;
|
||||
uint8_t* buff1;
|
||||
uint8_t* digest_result_buff;
|
||||
struct async_gen_req_ctx gen_ctx;
|
||||
enum ssi_req_dma_buf_type data_dma_buf_type;
|
||||
uint8_t *digest_buff;
|
||||
uint8_t *opad_digest_buff;
|
||||
uint8_t *digest_bytes_len;
|
||||
dma_addr_t opad_digest_dma_addr;
|
||||
dma_addr_t digest_buff_dma_addr;
|
||||
dma_addr_t digest_bytes_len_dma_addr;
|
||||
dma_addr_t digest_result_dma_addr;
|
||||
uint32_t buff0_cnt;
|
||||
uint32_t buff1_cnt;
|
||||
uint32_t buff_index;
|
||||
uint32_t xcbc_count; /* count xcbc update operatations */
|
||||
struct scatterlist buff_sg[2];
|
||||
struct scatterlist *curr_sg;
|
||||
uint32_t in_nents;
|
||||
uint32_t mlli_nents;
|
||||
struct mlli_params mlli_params;
|
||||
};
|
||||
|
||||
int ssi_hash_alloc(struct ssi_drvdata *drvdata);
|
||||
int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata);
|
||||
int ssi_hash_free(struct ssi_drvdata *drvdata);
|
||||
|
||||
/*!
|
||||
* Gets the initial digest length
|
||||
*
|
||||
* \param drvdata
|
||||
* \param mode The Hash mode. Supported modes: MD5/SHA1/SHA224/SHA256/SHA384/SHA512
|
||||
*
|
||||
* \return uint32_t returns the address of the initial digest length in SRAM
|
||||
*/
|
||||
ssi_sram_addr_t
|
||||
ssi_ahash_get_initial_digest_len_sram_addr(void *drvdata, uint32_t mode);
|
||||
|
||||
/*!
|
||||
* Gets the address of the initial digest in SRAM
|
||||
* according to the given hash mode
|
||||
*
|
||||
* \param drvdata
|
||||
* \param mode The Hash mode. Supported modes: MD5/SHA1/SHA224/SHA256/SHA384/SHA512
|
||||
*
|
||||
* \return uint32_t The address of the inital digest in SRAM
|
||||
*/
|
||||
ssi_sram_addr_t ssi_ahash_get_larval_digest_sram_addr(void *drvdata, uint32_t mode);
|
||||
|
||||
#endif /*__SSI_HASH_H__*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ssi_request_mgr.h"
|
||||
#include "ssi_sram_mgr.h"
|
||||
#include "ssi_sysfs.h"
|
||||
#include "ssi_hash.h"
|
||||
#include "ssi_pm.h"
|
||||
#include "ssi_pm_ext.h"
|
||||
|
||||
@ -79,6 +80,9 @@ int ssi_power_mgr_runtime_resume(struct device *dev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* must be after the queue resuming as it uses the HW queue*/
|
||||
ssi_hash_init_sram_digest_consts(drvdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user