in ccree/cc_buffer_mgr.c [937:1129]
int cc_map_aead_request(struct cc_drvdata *drvdata, struct aead_request *req)
{
struct aead_req_ctx *areq_ctx = aead_request_ctx(req);
struct mlli_params *mlli_params = &areq_ctx->mlli_params;
struct device *dev = drvdata_to_dev(drvdata);
struct buffer_array sg_data;
unsigned int authsize = areq_ctx->req_authsize;
int rc = 0;
dma_addr_t dma_addr;
u32 mapped_nents = 0;
u32 dummy = 0; /*used for the assoc data fragments */
u32 size_to_map;
gfp_t flags = cc_gfp_flags(&req->base);
mlli_params->curr_pool = NULL;
sg_data.num_of_buffers = 0;
/* copy mac to a temporary location to deal with possible
* data memory overriding that caused by cache coherence problem.
*/
if (drvdata->coherent &&
areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT &&
req->src == req->dst)
cc_copy_mac(dev, req, CC_SG_TO_BUF);
/* cacluate the size for cipher remove ICV in decrypt*/
areq_ctx->cryptlen = (areq_ctx->gen_ctx.op_type ==
DRV_CRYPTO_DIRECTION_ENCRYPT) ?
req->cryptlen :
(req->cryptlen - authsize);
dma_addr = dma_map_single(dev, areq_ctx->mac_buf, MAX_MAC_SIZE,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "Mapping mac_buf %u B at va=%pK for DMA failed\n",
MAX_MAC_SIZE, areq_ctx->mac_buf);
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->mac_buf_dma_addr = dma_addr;
if (areq_ctx->ccm_hdr_size != ccm_header_size_null) {
void *addr = areq_ctx->ccm_config + CCM_CTR_COUNT_0_OFFSET;
dma_addr = dma_map_single(dev, addr, AES_BLOCK_SIZE,
DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "Mapping mac_buf %u B at va=%pK for DMA failed\n",
AES_BLOCK_SIZE, addr);
areq_ctx->ccm_iv0_dma_addr = 0;
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->ccm_iv0_dma_addr = dma_addr;
rc = cc_set_aead_conf_buf(dev, areq_ctx, areq_ctx->ccm_config,
&sg_data, areq_ctx->assoclen);
if (rc)
goto aead_map_failure;
}
if (areq_ctx->cipher_mode == DRV_CIPHER_GCTR) {
dma_addr = dma_map_single(dev, areq_ctx->hkey, AES_BLOCK_SIZE,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "Mapping hkey %u B at va=%pK for DMA failed\n",
AES_BLOCK_SIZE, areq_ctx->hkey);
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->hkey_dma_addr = dma_addr;
dma_addr = dma_map_single(dev, &areq_ctx->gcm_len_block,
AES_BLOCK_SIZE, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "Mapping gcm_len_block %u B at va=%pK for DMA failed\n",
AES_BLOCK_SIZE, &areq_ctx->gcm_len_block);
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->gcm_block_len_dma_addr = dma_addr;
dma_addr = dma_map_single(dev, areq_ctx->gcm_iv_inc1,
AES_BLOCK_SIZE, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "Mapping gcm_iv_inc1 %u B at va=%pK for DMA failed\n",
AES_BLOCK_SIZE, (areq_ctx->gcm_iv_inc1));
areq_ctx->gcm_iv_inc1_dma_addr = 0;
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->gcm_iv_inc1_dma_addr = dma_addr;
dma_addr = dma_map_single(dev, areq_ctx->gcm_iv_inc2,
AES_BLOCK_SIZE, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "Mapping gcm_iv_inc2 %u B at va=%pK for DMA failed\n",
AES_BLOCK_SIZE, (areq_ctx->gcm_iv_inc2));
areq_ctx->gcm_iv_inc2_dma_addr = 0;
rc = -ENOMEM;
goto aead_map_failure;
}
areq_ctx->gcm_iv_inc2_dma_addr = dma_addr;
}
size_to_map = req->cryptlen + req->assoclen;
/* If we do in-place encryption, we also need the auth tag */
if ((areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_ENCRYPT) &&
(req->src == req->dst)) {
size_to_map += authsize;
}
rc = cc_map_sg(dev, req->src, size_to_map, DMA_BIDIRECTIONAL,
&areq_ctx->src.mapped_nents,
(LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES +
LLI_MAX_NUM_OF_DATA_ENTRIES),
&dummy, &mapped_nents);
if (rc)
goto aead_map_failure;
if (areq_ctx->is_single_pass) {
/*
* Create MLLI table for:
* (1) Assoc. data
* (2) Src/Dst SGLs
* Note: IV is contg. buffer (not an SGL)
*/
rc = cc_aead_chain_assoc(drvdata, req, &sg_data, true, false);
if (rc)
goto aead_map_failure;
rc = cc_aead_chain_iv(drvdata, req, &sg_data, true, false);
if (rc)
goto aead_map_failure;
rc = cc_aead_chain_data(drvdata, req, &sg_data, true, false);
if (rc)
goto aead_map_failure;
} else { /* DOUBLE-PASS flow */
/*
* Prepare MLLI table(s) in this order:
*
* If ENCRYPT/DECRYPT (inplace):
* (1) MLLI table for assoc
* (2) IV entry (chained right after end of assoc)
* (3) MLLI for src/dst (inplace operation)
*
* If ENCRYPT (non-inplace)
* (1) MLLI table for assoc
* (2) IV entry (chained right after end of assoc)
* (3) MLLI for dst
* (4) MLLI for src
*
* If DECRYPT (non-inplace)
* (1) MLLI table for assoc
* (2) IV entry (chained right after end of assoc)
* (3) MLLI for src
* (4) MLLI for dst
*/
rc = cc_aead_chain_assoc(drvdata, req, &sg_data, false, true);
if (rc)
goto aead_map_failure;
rc = cc_aead_chain_iv(drvdata, req, &sg_data, false, true);
if (rc)
goto aead_map_failure;
rc = cc_aead_chain_data(drvdata, req, &sg_data, true, true);
if (rc)
goto aead_map_failure;
}
/* Mlli support -start building the MLLI according to the above
* results
*/
if (areq_ctx->assoc_buff_type == CC_DMA_BUF_MLLI ||
areq_ctx->data_buff_type == CC_DMA_BUF_MLLI) {
mlli_params->curr_pool = drvdata->mlli_buffs_pool;
rc = cc_generate_mlli(dev, &sg_data, mlli_params, flags);
if (rc)
goto aead_map_failure;
cc_update_aead_mlli_nents(drvdata, req);
dev_dbg(dev, "assoc params mn %d\n",
areq_ctx->assoc.mlli_nents);
dev_dbg(dev, "src params mn %d\n", areq_ctx->src.mlli_nents);
dev_dbg(dev, "dst params mn %d\n", areq_ctx->dst.mlli_nents);
}
return 0;
aead_map_failure:
cc_unmap_aead_request(dev, req);
return rc;
}