aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/ccree/ssi_cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/ccree/ssi_cipher.c')
-rw-r--r--drivers/staging/ccree/ssi_cipher.c189
1 files changed, 95 insertions, 94 deletions
diff --git a/drivers/staging/ccree/ssi_cipher.c b/drivers/staging/ccree/ssi_cipher.c
index 8d31a93fd8b7..ee85cbf7c9ae 100644
--- a/drivers/staging/ccree/ssi_cipher.c
+++ b/drivers/staging/ccree/ssi_cipher.c
@@ -181,45 +181,42 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm)
struct crypto_alg *alg = tfm->__crt_alg;
struct ssi_crypto_alg *ssi_alg =
container_of(alg, struct ssi_crypto_alg, crypto_alg);
- struct device *dev;
+ struct device *dev = drvdata_to_dev(ssi_alg->drvdata);
int rc = 0;
unsigned int max_key_buf_size = get_max_keysize(tfm);
- SSI_LOG_DEBUG("Initializing context @%p for %s\n",
- ctx_p, crypto_tfm_alg_name(tfm));
+ dev_dbg(dev, "Initializing context @%p for %s\n", ctx_p,
+ crypto_tfm_alg_name(tfm));
ctx_p->cipher_mode = ssi_alg->cipher_mode;
ctx_p->flow_mode = ssi_alg->flow_mode;
ctx_p->drvdata = ssi_alg->drvdata;
- dev = &ctx_p->drvdata->plat_dev->dev;
/* Allocate key buffer, cache line aligned */
ctx_p->user.key = kmalloc(max_key_buf_size, GFP_KERNEL | GFP_DMA);
- if (!ctx_p->user.key) {
- SSI_LOG_ERR("Allocating key buffer in context failed\n");
- rc = -ENOMEM;
- }
- SSI_LOG_DEBUG("Allocated key buffer in context. key=@%p\n",
- ctx_p->user.key);
+ if (!ctx_p->user.key)
+ return -ENOMEM;
+
+ dev_dbg(dev, "Allocated key buffer in context. key=@%p\n",
+ ctx_p->user.key);
/* Map key buffer */
ctx_p->user.key_dma_addr = dma_map_single(dev, (void *)ctx_p->user.key,
max_key_buf_size,
DMA_TO_DEVICE);
if (dma_mapping_error(dev, ctx_p->user.key_dma_addr)) {
- SSI_LOG_ERR("Mapping Key %u B at va=%pK for DMA failed\n",
- max_key_buf_size, ctx_p->user.key);
+ dev_err(dev, "Mapping Key %u B at va=%pK for DMA failed\n",
+ max_key_buf_size, ctx_p->user.key);
return -ENOMEM;
}
- SSI_LOG_DEBUG("Mapped key %u B at va=%pK to dma=%pad\n",
- max_key_buf_size, ctx_p->user.key,
- ctx_p->user.key_dma_addr);
+ dev_dbg(dev, "Mapped key %u B at va=%pK to dma=%pad\n",
+ max_key_buf_size, ctx_p->user.key, &ctx_p->user.key_dma_addr);
if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) {
/* Alloc hash tfm for essiv */
ctx_p->shash_tfm = crypto_alloc_shash("sha256-generic", 0, 0);
if (IS_ERR(ctx_p->shash_tfm)) {
- SSI_LOG_ERR("Error allocating hash tfm for ESSIV.\n");
+ dev_err(dev, "Error allocating hash tfm for ESSIV.\n");
return PTR_ERR(ctx_p->shash_tfm);
}
}
@@ -230,11 +227,11 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm)
static void ssi_blkcipher_exit(struct crypto_tfm *tfm)
{
struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
- struct device *dev = &ctx_p->drvdata->plat_dev->dev;
+ struct device *dev = drvdata_to_dev(ctx_p->drvdata);
unsigned int max_key_buf_size = get_max_keysize(tfm);
- SSI_LOG_DEBUG("Clearing context @%p for %s\n",
- crypto_tfm_ctx(tfm), crypto_tfm_alg_name(tfm));
+ dev_dbg(dev, "Clearing context @%p for %s\n",
+ crypto_tfm_ctx(tfm), crypto_tfm_alg_name(tfm));
if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) {
/* Free hash tfm for essiv */
@@ -245,12 +242,12 @@ static void ssi_blkcipher_exit(struct crypto_tfm *tfm)
/* Unmap key buffer */
dma_unmap_single(dev, ctx_p->user.key_dma_addr, max_key_buf_size,
DMA_TO_DEVICE);
- SSI_LOG_DEBUG("Unmapped key buffer key_dma_addr=%pad\n",
- ctx_p->user.key_dma_addr);
+ dev_dbg(dev, "Unmapped key buffer key_dma_addr=%pad\n",
+ &ctx_p->user.key_dma_addr);
/* Free key buffer in context */
kfree(ctx_p->user.key);
- SSI_LOG_DEBUG("Free key buffer in context. key=@%p\n", ctx_p->user.key);
+ dev_dbg(dev, "Free key buffer in context. key=@%p\n", ctx_p->user.key);
}
struct tdes_keys {
@@ -298,16 +295,14 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
unsigned int keylen)
{
struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
- struct device *dev = &ctx_p->drvdata->plat_dev->dev;
+ struct device *dev = drvdata_to_dev(ctx_p->drvdata);
u32 tmp[DES_EXPKEY_WORDS];
unsigned int max_key_buf_size = get_max_keysize(tfm);
- SSI_LOG_DEBUG("Setting key in context @%p for %s. keylen=%u\n",
- ctx_p, crypto_tfm_alg_name(tfm), keylen);
+ dev_dbg(dev, "Setting key in context @%p for %s. keylen=%u\n",
+ ctx_p, crypto_tfm_alg_name(tfm), keylen);
dump_byte_array("key", (u8 *)key, keylen);
- SSI_LOG_DEBUG("after FIPS check");
-
/* STAT_PHASE_0: Init and sanity checks */
#if SSI_CC_HAS_MULTI2
@@ -317,7 +312,7 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
#endif /*SSI_CC_HAS_MULTI2*/
if (unlikely(validate_keys_sizes(ctx_p, keylen) != 0)) {
- SSI_LOG_ERR("Unsupported key size %d.\n", keylen);
+ dev_err(dev, "Unsupported key size %d.\n", keylen);
crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
@@ -327,13 +322,14 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
struct arm_hw_key_info *hki = (struct arm_hw_key_info *)key;
if (unlikely(ctx_p->flow_mode != S_DIN_to_AES)) {
- SSI_LOG_ERR("HW key not supported for non-AES flows\n");
+ dev_err(dev, "HW key not supported for non-AES flows\n");
return -EINVAL;
}
ctx_p->hw.key1_slot = hw_key_to_cc_hw_key(hki->hw_key1);
if (unlikely(ctx_p->hw.key1_slot == END_OF_KEYS)) {
- SSI_LOG_ERR("Unsupported hw key1 number (%d)\n", hki->hw_key1);
+ dev_err(dev, "Unsupported hw key1 number (%d)\n",
+ hki->hw_key1);
return -EINVAL;
}
@@ -341,18 +337,20 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
(ctx_p->cipher_mode == DRV_CIPHER_ESSIV) ||
(ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER)) {
if (unlikely(hki->hw_key1 == hki->hw_key2)) {
- SSI_LOG_ERR("Illegal hw key numbers (%d,%d)\n", hki->hw_key1, hki->hw_key2);
+ dev_err(dev, "Illegal hw key numbers (%d,%d)\n",
+ hki->hw_key1, hki->hw_key2);
return -EINVAL;
}
ctx_p->hw.key2_slot = hw_key_to_cc_hw_key(hki->hw_key2);
if (unlikely(ctx_p->hw.key2_slot == END_OF_KEYS)) {
- SSI_LOG_ERR("Unsupported hw key2 number (%d)\n", hki->hw_key2);
+ dev_err(dev, "Unsupported hw key2 number (%d)\n",
+ hki->hw_key2);
return -EINVAL;
}
}
ctx_p->keylen = keylen;
- SSI_LOG_DEBUG("ssi_is_hw_key ret 0");
+ dev_dbg(dev, "ssi_is_hw_key ret 0");
return 0;
}
@@ -362,19 +360,19 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
if (unlikely(!des_ekey(tmp, key)) &&
(crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_WEAK_KEY)) {
tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
- SSI_LOG_DEBUG("weak DES key");
+ dev_dbg(dev, "weak DES key");
return -EINVAL;
}
}
if ((ctx_p->cipher_mode == DRV_CIPHER_XTS) &&
xts_check_key(tfm, key, keylen) != 0) {
- SSI_LOG_DEBUG("weak XTS key");
+ dev_dbg(dev, "weak XTS key");
return -EINVAL;
}
if ((ctx_p->flow_mode == S_DIN_to_DES) &&
(keylen == DES3_EDE_KEY_SIZE) &&
ssi_verify_3des_keys(key, keylen) != 0) {
- SSI_LOG_DEBUG("weak 3DES key");
+ dev_dbg(dev, "weak 3DES key");
return -EINVAL;
}
@@ -389,7 +387,7 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
if (ctx_p->key_round_number < CC_MULTI2_MIN_NUM_ROUNDS ||
ctx_p->key_round_number > CC_MULTI2_MAX_NUM_ROUNDS) {
crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
- SSI_LOG_DEBUG("SSI_CC_HAS_MULTI2 einval");
+ dev_dbg(dev, "SSI_CC_HAS_MULTI2 einval");
return -EINVAL;
#endif /*SSI_CC_HAS_MULTI2*/
} else {
@@ -407,7 +405,7 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
err = crypto_shash_digest(desc, ctx_p->user.key, key_len, ctx_p->user.key + key_len);
if (err) {
- SSI_LOG_ERR("Failed to hash ESSIV key.\n");
+ dev_err(dev, "Failed to hash ESSIV key.\n");
return err;
}
}
@@ -416,7 +414,7 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm,
max_key_buf_size, DMA_TO_DEVICE);
ctx_p->keylen = keylen;
- SSI_LOG_DEBUG("return safely");
+ dev_dbg(dev, "return safely");
return 0;
}
@@ -430,6 +428,7 @@ ssi_blkcipher_create_setup_desc(
unsigned int *seq_size)
{
struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
+ struct device *dev = drvdata_to_dev(ctx_p->drvdata);
int cipher_mode = ctx_p->cipher_mode;
int flow_mode = ctx_p->flow_mode;
int direction = req_ctx->gen_ctx.op_type;
@@ -540,8 +539,7 @@ ssi_blkcipher_create_setup_desc(
(*seq_size)++;
break;
default:
- SSI_LOG_ERR("Unsupported cipher mode (%d)\n", cipher_mode);
- BUG();
+ dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode);
}
}
@@ -601,6 +599,7 @@ ssi_blkcipher_create_data_desc(
unsigned int *seq_size)
{
struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
+ struct device *dev = drvdata_to_dev(ctx_p->drvdata);
unsigned int flow_mode = ctx_p->flow_mode;
switch (ctx_p->flow_mode) {
@@ -616,15 +615,15 @@ ssi_blkcipher_create_data_desc(
break;
#endif /*SSI_CC_HAS_MULTI2*/
default:
- SSI_LOG_ERR("invalid flow mode, flow_mode = %d\n", flow_mode);
+ dev_err(dev, "invalid flow mode, flow_mode = %d\n", flow_mode);
return;
}
/* Process */
if (likely(req_ctx->dma_buf_type == SSI_DMA_BUF_DLLI)) {
- SSI_LOG_DEBUG(" data params addr %pad length 0x%X\n",
- sg_dma_address(src), nbytes);
- SSI_LOG_DEBUG(" data params addr %pad length 0x%X\n",
- sg_dma_address(dst), nbytes);
+ dev_dbg(dev, " data params addr %pad length 0x%X\n",
+ &sg_dma_address(src), nbytes);
+ dev_dbg(dev, " data params addr %pad length 0x%X\n",
+ &sg_dma_address(dst), nbytes);
hw_desc_init(&desc[*seq_size]);
set_din_type(&desc[*seq_size], DMA_DLLI, sg_dma_address(src),
nbytes, NS_BIT);
@@ -637,9 +636,8 @@ ssi_blkcipher_create_data_desc(
(*seq_size)++;
} else {
/* bypass */
- SSI_LOG_DEBUG(" bypass params addr %pad "
- "length 0x%X addr 0x%08X\n",
- req_ctx->mlli_params.mlli_dma_addr,
+ dev_dbg(dev, " bypass params addr %pad length 0x%X addr 0x%08X\n",
+ &req_ctx->mlli_params.mlli_dma_addr,
req_ctx->mlli_params.mlli_len,
(unsigned int)ctx_p->drvdata->mlli_sram_addr);
hw_desc_init(&desc[*seq_size]);
@@ -657,21 +655,18 @@ ssi_blkcipher_create_data_desc(
ctx_p->drvdata->mlli_sram_addr,
req_ctx->in_mlli_nents, NS_BIT);
if (req_ctx->out_nents == 0) {
- SSI_LOG_DEBUG(" din/dout params addr 0x%08X "
- "addr 0x%08X\n",
- (unsigned int)ctx_p->drvdata->mlli_sram_addr,
- (unsigned int)ctx_p->drvdata->mlli_sram_addr);
+ dev_dbg(dev, " din/dout params addr 0x%08X addr 0x%08X\n",
+ (unsigned int)ctx_p->drvdata->mlli_sram_addr,
+ (unsigned int)ctx_p->drvdata->mlli_sram_addr);
set_dout_mlli(&desc[*seq_size],
ctx_p->drvdata->mlli_sram_addr,
req_ctx->in_mlli_nents, NS_BIT,
(!areq ? 0 : 1));
} else {
- SSI_LOG_DEBUG(" din/dout params "
- "addr 0x%08X addr 0x%08X\n",
+ dev_dbg(dev, " din/dout params addr 0x%08X addr 0x%08X\n",
(unsigned int)ctx_p->drvdata->mlli_sram_addr,
(unsigned int)ctx_p->drvdata->mlli_sram_addr +
- (u32)LLI_ENTRY_BYTE_SIZE *
- req_ctx->in_nents);
+ (u32)LLI_ENTRY_BYTE_SIZE * req_ctx->in_nents);
set_dout_mlli(&desc[*seq_size],
(ctx_p->drvdata->mlli_sram_addr +
(LLI_ENTRY_BYTE_SIZE *
@@ -697,16 +692,10 @@ static int ssi_blkcipher_complete(struct device *dev,
void __iomem *cc_base)
{
int completion_error = 0;
- u32 inflight_counter;
struct ablkcipher_request *req = (struct ablkcipher_request *)areq;
ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst);
-
- /*Set the inflight couter value to local variable*/
- inflight_counter = ctx_p->drvdata->inflight_counter;
- /*Decrease the inflight counter*/
- if (ctx_p->flow_mode == BYPASS && ctx_p->drvdata->inflight_counter > 0)
- ctx_p->drvdata->inflight_counter--;
+ kfree(req_ctx->iv);
if (areq) {
/*
@@ -742,20 +731,20 @@ static int ssi_blkcipher_process(
enum drv_crypto_direction direction)
{
struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
- struct device *dev = &ctx_p->drvdata->plat_dev->dev;
+ struct device *dev = drvdata_to_dev(ctx_p->drvdata);
struct cc_hw_desc desc[MAX_ABLKCIPHER_SEQ_LEN];
struct ssi_crypto_req ssi_req = {};
int rc, seq_len = 0, cts_restore_flag = 0;
- SSI_LOG_DEBUG("%s areq=%p info=%p nbytes=%d\n",
- ((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Encrypt" : "Decrypt"),
- areq, info, nbytes);
+ dev_dbg(dev, "%s areq=%p info=%p nbytes=%d\n",
+ ((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ?
+ "Encrypt" : "Decrypt"), areq, info, nbytes);
/* STAT_PHASE_0: Init and sanity checks */
/* TODO: check data length according to mode */
if (unlikely(validate_data_size(ctx_p, nbytes))) {
- SSI_LOG_ERR("Unsupported data size %d.\n", nbytes);
+ dev_err(dev, "Unsupported data size %d.\n", nbytes);
crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_BLOCK_LEN);
rc = -EINVAL;
goto exit_process;
@@ -765,6 +754,17 @@ static int ssi_blkcipher_process(
rc = 0;
goto exit_process;
}
+
+ /* The IV we are handed may be allocted from the stack so
+ * we must copy it to a DMAable buffer before use.
+ */
+ req_ctx->iv = kmalloc(ivsize, GFP_KERNEL);
+ if (!req_ctx->iv) {
+ rc = -ENOMEM;
+ goto exit_process;
+ }
+ memcpy(req_ctx->iv, info, ivsize);
+
/*For CTS in case of data size aligned to 16 use CBC mode*/
if (((nbytes % AES_BLOCK_SIZE) == 0) && (ctx_p->cipher_mode == DRV_CIPHER_CBC_CTS)) {
ctx_p->cipher_mode = DRV_CIPHER_CBC;
@@ -786,9 +786,11 @@ static int ssi_blkcipher_process(
/* STAT_PHASE_1: Map buffers */
- rc = ssi_buffer_mgr_map_blkcipher_request(ctx_p->drvdata, req_ctx, ivsize, nbytes, info, src, dst);
+ rc = ssi_buffer_mgr_map_blkcipher_request(ctx_p->drvdata, req_ctx,
+ ivsize, nbytes, req_ctx->iv,
+ src, dst);
if (unlikely(rc != 0)) {
- SSI_LOG_ERR("map_request() failed\n");
+ dev_err(dev, "map_request() failed\n");
goto exit_process;
}
@@ -838,8 +840,10 @@ exit_process:
if (cts_restore_flag != 0)
ctx_p->cipher_mode = DRV_CIPHER_CBC_CTS;
- if (rc != -EINPROGRESS)
+ if (rc != -EINPROGRESS) {
kfree(req_ctx->backup_info);
+ kfree(req_ctx->iv);
+ }
return rc;
}
@@ -1245,16 +1249,15 @@ static struct ssi_alg_template blkcipher_algs[] = {
};
static
-struct ssi_crypto_alg *ssi_ablkcipher_create_alg(struct ssi_alg_template *template)
+struct ssi_crypto_alg *ssi_ablkcipher_create_alg(struct ssi_alg_template
+ *template, struct device *dev)
{
struct ssi_crypto_alg *t_alg;
struct crypto_alg *alg;
t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
- if (!t_alg) {
- SSI_LOG_ERR("failed to allocate t_alg\n");
+ if (!t_alg)
return ERR_PTR(-ENOMEM);
- }
alg = &t_alg->crypto_alg;
@@ -1285,10 +1288,6 @@ int ssi_ablkcipher_free(struct ssi_drvdata *drvdata)
struct ssi_crypto_alg *t_alg, *n;
struct ssi_blkcipher_handle *blkcipher_handle =
drvdata->blkcipher_handle;
- struct device *dev;
-
- dev = &drvdata->plat_dev->dev;
-
if (blkcipher_handle) {
/* Remove registered algs */
list_for_each_entry_safe(t_alg, n,
@@ -1308,6 +1307,7 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata)
{
struct ssi_blkcipher_handle *ablkcipher_handle;
struct ssi_crypto_alg *t_alg;
+ struct device *dev = drvdata_to_dev(drvdata);
int rc = -ENOMEM;
int alg;
@@ -1315,37 +1315,38 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata)
if (!ablkcipher_handle)
return -ENOMEM;
- drvdata->blkcipher_handle = ablkcipher_handle;
-
INIT_LIST_HEAD(&ablkcipher_handle->blkcipher_alg_list);
+ drvdata->blkcipher_handle = ablkcipher_handle;
/* Linux crypto */
- SSI_LOG_DEBUG("Number of algorithms = %zu\n", ARRAY_SIZE(blkcipher_algs));
+ dev_dbg(dev, "Number of algorithms = %zu\n",
+ ARRAY_SIZE(blkcipher_algs));
for (alg = 0; alg < ARRAY_SIZE(blkcipher_algs); alg++) {
- SSI_LOG_DEBUG("creating %s\n", blkcipher_algs[alg].driver_name);
- t_alg = ssi_ablkcipher_create_alg(&blkcipher_algs[alg]);
+ dev_dbg(dev, "creating %s\n", blkcipher_algs[alg].driver_name);
+ t_alg = ssi_ablkcipher_create_alg(&blkcipher_algs[alg], dev);
if (IS_ERR(t_alg)) {
rc = PTR_ERR(t_alg);
- SSI_LOG_ERR("%s alg allocation failed\n",
- blkcipher_algs[alg].driver_name);
+ dev_err(dev, "%s alg allocation failed\n",
+ blkcipher_algs[alg].driver_name);
goto fail0;
}
t_alg->drvdata = drvdata;
- SSI_LOG_DEBUG("registering %s\n", blkcipher_algs[alg].driver_name);
+ dev_dbg(dev, "registering %s\n",
+ blkcipher_algs[alg].driver_name);
rc = crypto_register_alg(&t_alg->crypto_alg);
- SSI_LOG_DEBUG("%s alg registration rc = %x\n",
- t_alg->crypto_alg.cra_driver_name, rc);
+ dev_dbg(dev, "%s alg registration rc = %x\n",
+ t_alg->crypto_alg.cra_driver_name, rc);
if (unlikely(rc != 0)) {
- SSI_LOG_ERR("%s alg registration failed\n",
- t_alg->crypto_alg.cra_driver_name);
+ dev_err(dev, "%s alg registration failed\n",
+ t_alg->crypto_alg.cra_driver_name);
kfree(t_alg);
goto fail0;
} else {
list_add_tail(&t_alg->entry,
&ablkcipher_handle->blkcipher_alg_list);
- SSI_LOG_DEBUG("Registered %s\n",
- t_alg->crypto_alg.cra_driver_name);
+ dev_dbg(dev, "Registered %s\n",
+ t_alg->crypto_alg.cra_driver_name);
}
}
return 0;