mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
crypto: tegra: Align with upstream
Fix the known bugs in the SE driver and align the driver with the
upstream version
Bug 4488964
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Change-Id: I6efa471b6efcd161d36167a0784185f3e0266d7c
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3124250
(cherry picked from commit abb0a027b2)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3196063
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
0d1196a9f2
commit
80c7d7a67b
@@ -5,9 +5,7 @@ ifdef CONFIG_TEGRA_HOST1X
|
|||||||
obj-m += tegra-hv-vse-safety.o
|
obj-m += tegra-hv-vse-safety.o
|
||||||
obj-m += tegra-nvvse-cryptodev.o
|
obj-m += tegra-nvvse-cryptodev.o
|
||||||
ifdef CONFIG_CRYPTO_ENGINE
|
ifdef CONFIG_CRYPTO_ENGINE
|
||||||
ifndef CONFIG_SKIP_CRYPTO
|
|
||||||
obj-m += tegra/
|
obj-m += tegra/
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
obj-m += tegra-se-nvrng.o
|
obj-m += tegra-se-nvrng.o
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
ccflags-y += -I$(srctree.nvidia)/drivers/gpu/host1x/include
|
ccflags-y += -I$(srctree.nvidia)/drivers/gpu/host1x/include
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,10 +4,8 @@
|
|||||||
* Crypto driver to handle HASH algorithms using NVIDIA Security Engine.
|
* Crypto driver to handle HASH algorithms using NVIDIA Security Engine.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nvidia/conftest.h>
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/host1x-next.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
@@ -24,18 +22,15 @@
|
|||||||
#include "tegra-se.h"
|
#include "tegra-se.h"
|
||||||
|
|
||||||
struct tegra_sha_ctx {
|
struct tegra_sha_ctx {
|
||||||
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
struct crypto_engine_ctx enginectx;
|
struct crypto_engine_ctx enginectx;
|
||||||
#endif
|
|
||||||
struct crypto_ahash *fallback_tfm;
|
|
||||||
struct tegra_se *se;
|
struct tegra_se *se;
|
||||||
unsigned int alg;
|
unsigned int alg;
|
||||||
bool fallback;
|
bool fallback;
|
||||||
u32 key_id;
|
u32 key_id;
|
||||||
|
struct crypto_ahash *fallback_tfm;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tegra_sha_reqctx {
|
struct tegra_sha_reqctx {
|
||||||
struct ahash_request fallback_req;
|
|
||||||
struct scatterlist *src_sg;
|
struct scatterlist *src_sg;
|
||||||
struct tegra_se_datbuf datbuf;
|
struct tegra_se_datbuf datbuf;
|
||||||
struct tegra_se_datbuf residue;
|
struct tegra_se_datbuf residue;
|
||||||
@@ -46,6 +41,8 @@ struct tegra_sha_reqctx {
|
|||||||
unsigned int blk_size;
|
unsigned int blk_size;
|
||||||
unsigned int task;
|
unsigned int task;
|
||||||
u32 key_id;
|
u32 key_id;
|
||||||
|
u32 result[HASH_RESULT_REG_COUNT];
|
||||||
|
struct ahash_request fallback_req;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int tegra_sha_get_config(u32 alg)
|
static int tegra_sha_get_config(u32 alg)
|
||||||
@@ -216,13 +213,13 @@ static int tegra_sha_fallback_export(struct ahash_request *req, void *out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
||||||
struct tegra_sha_reqctx *rctx)
|
struct tegra_sha_reqctx *rctx)
|
||||||
{
|
{
|
||||||
u64 msg_len, msg_left;
|
u64 msg_len, msg_left;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
msg_len = (u64)rctx->total_len * 8;
|
msg_len = rctx->total_len * 8;
|
||||||
msg_left = (u64)rctx->datbuf.size * 8;
|
msg_left = rctx->datbuf.size * 8;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If IN_ADDR_HI_0.SZ > SHA_MSG_LEFT_[0-3] to the HASH engine,
|
* If IN_ADDR_HI_0.SZ > SHA_MSG_LEFT_[0-3] to the HASH engine,
|
||||||
@@ -236,7 +233,7 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(8);
|
cpuvaddr[i++] = host1x_opcode_setpayload(8);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(SE_SHA_MSG_LENGTH);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_MSG_LENGTH);
|
||||||
cpuvaddr[i++] = lower_32_bits(msg_len);
|
cpuvaddr[i++] = lower_32_bits(msg_len);
|
||||||
cpuvaddr[i++] = upper_32_bits(msg_len);
|
cpuvaddr[i++] = upper_32_bits(msg_len);
|
||||||
cpuvaddr[i++] = 0;
|
cpuvaddr[i++] = 0;
|
||||||
@@ -246,14 +243,15 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
|||||||
cpuvaddr[i++] = 0;
|
cpuvaddr[i++] = 0;
|
||||||
cpuvaddr[i++] = 0;
|
cpuvaddr[i++] = 0;
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(6);
|
cpuvaddr[i++] = host1x_opcode_setpayload(6);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(SE_SHA_CFG);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_CFG);
|
||||||
cpuvaddr[i++] = rctx->config;
|
cpuvaddr[i++] = rctx->config;
|
||||||
|
|
||||||
if (rctx->task & SHA_FIRST) {
|
if (rctx->task & SHA_FIRST) {
|
||||||
cpuvaddr[i++] = SE_SHA_TASK_HASH_INIT;
|
cpuvaddr[i++] = SE_SHA_TASK_HASH_INIT;
|
||||||
rctx->task &= ~SHA_FIRST;
|
rctx->task &= ~SHA_FIRST;
|
||||||
} else
|
} else {
|
||||||
cpuvaddr[i++] = 0;
|
cpuvaddr[i++] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
cpuvaddr[i++] = rctx->datbuf.addr;
|
cpuvaddr[i++] = rctx->datbuf.addr;
|
||||||
cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->datbuf.addr)) |
|
cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->datbuf.addr)) |
|
||||||
@@ -263,30 +261,47 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
|||||||
SE_ADDR_HI_SZ(rctx->digest.size));
|
SE_ADDR_HI_SZ(rctx->digest.size));
|
||||||
if (rctx->key_id) {
|
if (rctx->key_id) {
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_nonincr_w(SE_SHA_CRYPTO_CFG);
|
cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_CRYPTO_CFG);
|
||||||
cpuvaddr[i++] = SE_AES_KEY_INDEX(rctx->key_id);
|
cpuvaddr[i++] = SE_AES_KEY_INDEX(rctx->key_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_nonincr_w(SE_SHA_OPERATION);
|
cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_OPERATION);
|
||||||
cpuvaddr[i++] = SE_SHA_OP_WRSTALL |
|
cpuvaddr[i++] = SE_SHA_OP_WRSTALL |
|
||||||
SE_SHA_OP_START |
|
SE_SHA_OP_START |
|
||||||
SE_SHA_OP_LASTBUF;
|
SE_SHA_OP_LASTBUF;
|
||||||
cpuvaddr[i++] = host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
|
cpuvaddr[i++] = se_host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
|
||||||
cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
|
cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
|
||||||
host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
|
host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
|
||||||
|
|
||||||
dev_dbg(se->dev, "msg len %llu msg left %llu cfg %#x",
|
dev_dbg(se->dev, "msg len %llu msg left %llu cfg %#x",
|
||||||
msg_len, msg_left, rctx->config);
|
msg_len, msg_left, rctx->config);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tegra_sha_copy_hash_result(struct tegra_se *se, struct tegra_sha_reqctx *rctx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < HASH_RESULT_REG_COUNT; i++)
|
||||||
|
rctx->result[i] = readl(se->base + se->hw->regs->result + (i * 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tegra_sha_paste_hash_result(struct tegra_se *se, struct tegra_sha_reqctx *rctx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < HASH_RESULT_REG_COUNT; i++)
|
||||||
|
writel(rctx->result[i],
|
||||||
|
se->base + se->hw->regs->result + (i * 4));
|
||||||
|
}
|
||||||
|
|
||||||
static int tegra_sha_do_update(struct ahash_request *req)
|
static int tegra_sha_do_update(struct ahash_request *req)
|
||||||
{
|
{
|
||||||
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
|
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
|
||||||
struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
|
struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
|
||||||
unsigned int nblks, nresidue, size;
|
unsigned int nblks, nresidue, size, ret;
|
||||||
u32 *cpuvaddr = ctx->se->cmdbuf->addr;
|
u32 *cpuvaddr = ctx->se->cmdbuf->addr;
|
||||||
|
|
||||||
nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
|
nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
|
||||||
@@ -311,7 +326,7 @@ static int tegra_sha_do_update(struct ahash_request *req)
|
|||||||
*/
|
*/
|
||||||
if (nblks < 1) {
|
if (nblks < 1) {
|
||||||
scatterwalk_map_and_copy(rctx->residue.buf + rctx->residue.size,
|
scatterwalk_map_and_copy(rctx->residue.buf + rctx->residue.size,
|
||||||
rctx->src_sg, 0, req->nbytes, 0);
|
rctx->src_sg, 0, req->nbytes, 0);
|
||||||
|
|
||||||
rctx->residue.size += req->nbytes;
|
rctx->residue.size += req->nbytes;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -322,10 +337,10 @@ static int tegra_sha_do_update(struct ahash_request *req)
|
|||||||
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
|
||||||
|
|
||||||
scatterwalk_map_and_copy(rctx->datbuf.buf + rctx->residue.size,
|
scatterwalk_map_and_copy(rctx->datbuf.buf + rctx->residue.size,
|
||||||
rctx->src_sg, 0, req->nbytes - nresidue, 0);
|
rctx->src_sg, 0, req->nbytes - nresidue, 0);
|
||||||
|
|
||||||
scatterwalk_map_and_copy(rctx->residue.buf, rctx->src_sg,
|
scatterwalk_map_and_copy(rctx->residue.buf, rctx->src_sg,
|
||||||
req->nbytes - nresidue, nresidue, 0);
|
req->nbytes - nresidue, nresidue, 0);
|
||||||
|
|
||||||
/* Update residue value with the residue after current block */
|
/* Update residue value with the residue after current block */
|
||||||
rctx->residue.size = nresidue;
|
rctx->residue.size = nresidue;
|
||||||
@@ -333,9 +348,27 @@ static int tegra_sha_do_update(struct ahash_request *req)
|
|||||||
rctx->config = tegra_sha_get_config(rctx->alg) |
|
rctx->config = tegra_sha_get_config(rctx->alg) |
|
||||||
SE_SHA_DST_HASH_REG;
|
SE_SHA_DST_HASH_REG;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is not the first 'update' call, paste the previous copied
|
||||||
|
* intermediate results to the registers so that it gets picked up.
|
||||||
|
* This is to support the import/export functionality.
|
||||||
|
*/
|
||||||
|
if (!(rctx->task & SHA_FIRST))
|
||||||
|
tegra_sha_paste_hash_result(ctx->se, rctx);
|
||||||
|
|
||||||
size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx);
|
size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx);
|
||||||
|
|
||||||
return tegra_se_host1x_submit(ctx->se, size);
|
ret = tegra_se_host1x_submit(ctx->se, size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is not the final update, copy the intermediate results
|
||||||
|
* from the registers so that it can be used in the next 'update'
|
||||||
|
* call. This is to support the import/export functionality.
|
||||||
|
*/
|
||||||
|
if (!(rctx->task & SHA_FINAL))
|
||||||
|
tegra_sha_copy_hash_result(ctx->se, rctx);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_sha_do_final(struct ahash_request *req)
|
static int tegra_sha_do_final(struct ahash_request *req)
|
||||||
@@ -365,11 +398,11 @@ static int tegra_sha_do_final(struct ahash_request *req)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
dma_free_coherent(se->dev, SE_SHA_BUFLEN,
|
dma_free_coherent(se->dev, SE_SHA_BUFLEN,
|
||||||
rctx->datbuf.buf, rctx->datbuf.addr);
|
rctx->datbuf.buf, rctx->datbuf.addr);
|
||||||
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm),
|
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm),
|
||||||
rctx->residue.buf, rctx->residue.addr);
|
rctx->residue.buf, rctx->residue.addr);
|
||||||
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
|
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
|
||||||
rctx->digest.addr);
|
rctx->digest.addr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +413,7 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq)
|
|||||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||||
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
|
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
|
||||||
struct tegra_se *se = ctx->se;
|
struct tegra_se *se = ctx->se;
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
|
|
||||||
if (rctx->task & SHA_UPDATE) {
|
if (rctx->task & SHA_UPDATE) {
|
||||||
ret = tegra_sha_do_update(req);
|
ret = tegra_sha_do_update(req);
|
||||||
@@ -394,50 +427,67 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq)
|
|||||||
|
|
||||||
crypto_finalize_hash_request(se->engine, req, ret);
|
crypto_finalize_hash_request(se->engine, req, ret);
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tegra_sha_init_fallback(struct tegra_sha_ctx *ctx, const char *algname)
|
static void tegra_sha_init_fallback(struct crypto_ahash *tfm, struct tegra_sha_ctx *ctx,
|
||||||
|
const char *algname)
|
||||||
{
|
{
|
||||||
|
unsigned int statesize;
|
||||||
|
|
||||||
ctx->fallback_tfm = crypto_alloc_ahash(algname, 0, CRYPTO_ALG_ASYNC |
|
ctx->fallback_tfm = crypto_alloc_ahash(algname, 0, CRYPTO_ALG_ASYNC |
|
||||||
CRYPTO_ALG_NEED_FALLBACK);
|
CRYPTO_ALG_NEED_FALLBACK);
|
||||||
|
|
||||||
if (IS_ERR(ctx->fallback_tfm)) {
|
if (IS_ERR(ctx->fallback_tfm)) {
|
||||||
dev_warn(ctx->se->dev, "failed to allocate fallback for %s %ld\n",
|
dev_warn(ctx->se->dev,
|
||||||
algname, PTR_ERR(ctx->fallback_tfm));
|
"failed to allocate fallback for %s\n", algname);
|
||||||
ctx->fallback_tfm = NULL;
|
ctx->fallback_tfm = NULL;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statesize = crypto_ahash_statesize(ctx->fallback_tfm);
|
||||||
|
|
||||||
|
if (statesize > sizeof(struct tegra_sha_reqctx))
|
||||||
|
crypto_hash_alg_common(tfm)->statesize = statesize;
|
||||||
|
|
||||||
|
/* Update reqsize if fallback is added */
|
||||||
|
crypto_ahash_set_reqsize(tfm,
|
||||||
|
sizeof(struct tegra_sha_reqctx) +
|
||||||
|
crypto_ahash_reqsize(ctx->fallback_tfm));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_sha_cra_init(struct crypto_tfm *tfm)
|
static int tegra_sha_cra_init(struct crypto_tfm *tfm)
|
||||||
{
|
{
|
||||||
struct tegra_sha_ctx *ctx = crypto_tfm_ctx(tfm);
|
struct tegra_sha_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||||
|
struct crypto_ahash *ahash_tfm = __crypto_ahash_cast(tfm);
|
||||||
struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
|
struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
|
||||||
struct tegra_se_alg *se_alg;
|
struct tegra_se_alg *se_alg;
|
||||||
const char *algname;
|
const char *algname;
|
||||||
|
int ret;
|
||||||
|
|
||||||
algname = crypto_tfm_alg_name(tfm);
|
algname = crypto_tfm_alg_name(tfm);
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
se_alg = container_of(alg, struct tegra_se_alg, alg.ahash.base);
|
|
||||||
#else
|
|
||||||
se_alg = container_of(alg, struct tegra_se_alg, alg.ahash);
|
se_alg = container_of(alg, struct tegra_se_alg, alg.ahash);
|
||||||
#endif
|
|
||||||
|
|
||||||
crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
|
crypto_ahash_set_reqsize(ahash_tfm, sizeof(struct tegra_sha_reqctx));
|
||||||
sizeof(struct tegra_sha_reqctx));
|
|
||||||
|
|
||||||
ctx->se = se_alg->se_dev;
|
ctx->se = se_alg->se_dev;
|
||||||
ctx->fallback = false;
|
ctx->fallback = false;
|
||||||
ctx->key_id = 0;
|
ctx->key_id = 0;
|
||||||
ctx->alg = se_algname_to_algid(algname);
|
|
||||||
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
ret = se_algname_to_algid(algname);
|
||||||
ctx->enginectx.op.prepare_request = NULL;
|
if (ret < 0) {
|
||||||
ctx->enginectx.op.do_one_request = tegra_sha_do_one_req;
|
dev_err(ctx->se->dev, "invalid algorithm\n");
|
||||||
ctx->enginectx.op.unprepare_request = NULL;
|
return ret;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (se_alg->alg_base)
|
if (se_alg->alg_base)
|
||||||
tegra_sha_init_fallback(ctx, algname);
|
tegra_sha_init_fallback(ahash_tfm, ctx, algname);
|
||||||
|
|
||||||
|
ctx->alg = ret;
|
||||||
|
|
||||||
|
ctx->enginectx.op.prepare_request = NULL;
|
||||||
|
ctx->enginectx.op.unprepare_request = NULL;
|
||||||
|
ctx->enginectx.op.do_one_request = tegra_sha_do_one_req;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -449,7 +499,7 @@ static void tegra_sha_cra_exit(struct crypto_tfm *tfm)
|
|||||||
if (ctx->fallback_tfm)
|
if (ctx->fallback_tfm)
|
||||||
crypto_free_ahash(ctx->fallback_tfm);
|
crypto_free_ahash(ctx->fallback_tfm);
|
||||||
|
|
||||||
tegra_key_invalidate(ctx->se, ctx->key_id);
|
tegra_key_invalidate(ctx->se, ctx->key_id, ctx->alg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_sha_init(struct ahash_request *req)
|
static int tegra_sha_init(struct ahash_request *req)
|
||||||
@@ -458,34 +508,31 @@ static int tegra_sha_init(struct ahash_request *req)
|
|||||||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||||
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
|
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
|
||||||
struct tegra_se *se = ctx->se;
|
struct tegra_se *se = ctx->se;
|
||||||
const char *algname;
|
|
||||||
|
|
||||||
if (ctx->fallback)
|
if (ctx->fallback)
|
||||||
return tegra_sha_fallback_init(req);
|
return tegra_sha_fallback_init(req);
|
||||||
|
|
||||||
algname = crypto_tfm_alg_name(&tfm->base);
|
|
||||||
|
|
||||||
rctx->total_len = 0;
|
rctx->total_len = 0;
|
||||||
rctx->datbuf.size = 0;
|
rctx->datbuf.size = 0;
|
||||||
rctx->residue.size = 0;
|
rctx->residue.size = 0;
|
||||||
rctx->key_id = ctx->key_id;
|
rctx->key_id = ctx->key_id;
|
||||||
rctx->task = SHA_FIRST;
|
rctx->task = SHA_FIRST;
|
||||||
rctx->alg = se_algname_to_algid(algname);
|
rctx->alg = ctx->alg;
|
||||||
rctx->blk_size = crypto_ahash_blocksize(tfm);
|
rctx->blk_size = crypto_ahash_blocksize(tfm);
|
||||||
rctx->digest.size = crypto_ahash_digestsize(tfm);
|
rctx->digest.size = crypto_ahash_digestsize(tfm);
|
||||||
|
|
||||||
rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
|
rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
|
||||||
&rctx->digest.addr, GFP_KERNEL);
|
&rctx->digest.addr, GFP_KERNEL);
|
||||||
if (!rctx->digest.buf)
|
if (!rctx->digest.buf)
|
||||||
goto digbuf_fail;
|
goto digbuf_fail;
|
||||||
|
|
||||||
rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size,
|
rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size,
|
||||||
&rctx->residue.addr, GFP_KERNEL);
|
&rctx->residue.addr, GFP_KERNEL);
|
||||||
if (!rctx->residue.buf)
|
if (!rctx->residue.buf)
|
||||||
goto resbuf_fail;
|
goto resbuf_fail;
|
||||||
|
|
||||||
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
|
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
|
||||||
&rctx->datbuf.addr, GFP_KERNEL);
|
&rctx->datbuf.addr, GFP_KERNEL);
|
||||||
if (!rctx->datbuf.buf)
|
if (!rctx->datbuf.buf)
|
||||||
goto datbuf_fail;
|
goto datbuf_fail;
|
||||||
|
|
||||||
@@ -493,10 +540,10 @@ static int tegra_sha_init(struct ahash_request *req)
|
|||||||
|
|
||||||
datbuf_fail:
|
datbuf_fail:
|
||||||
dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
|
dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
|
||||||
rctx->residue.addr);
|
rctx->residue.addr);
|
||||||
resbuf_fail:
|
resbuf_fail:
|
||||||
dma_free_coherent(se->dev, SE_SHA_BUFLEN, rctx->datbuf.buf,
|
dma_free_coherent(se->dev, SE_SHA_BUFLEN, rctx->datbuf.buf,
|
||||||
rctx->datbuf.addr);
|
rctx->datbuf.addr);
|
||||||
digbuf_fail:
|
digbuf_fail:
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -505,7 +552,7 @@ static int tegra_hmac_fallback_setkey(struct tegra_sha_ctx *ctx, const u8 *key,
|
|||||||
unsigned int keylen)
|
unsigned int keylen)
|
||||||
{
|
{
|
||||||
if (!ctx->fallback_tfm) {
|
if (!ctx->fallback_tfm) {
|
||||||
dev_err(ctx->se->dev, "invalid key length\n");
|
dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,9 +640,6 @@ static int tegra_sha_export(struct ahash_request *req, void *out)
|
|||||||
return tegra_sha_fallback_export(req, out);
|
return tegra_sha_fallback_export(req, out);
|
||||||
|
|
||||||
memcpy(out, rctx, sizeof(*rctx));
|
memcpy(out, rctx, sizeof(*rctx));
|
||||||
/*
|
|
||||||
* TODO: Copy HASH_RESULT registers as well.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -617,9 +661,6 @@ static int tegra_sha_import(struct ahash_request *req, const void *in)
|
|||||||
static struct tegra_se_alg tegra_hash_algs[] = {
|
static struct tegra_se_alg tegra_hash_algs[] = {
|
||||||
{
|
{
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -629,7 +670,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA1_DIGEST_SIZE,
|
.halg.digestsize = SHA1_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha1",
|
.cra_name = "sha1",
|
||||||
.cra_driver_name = "tegra-se-sha1",
|
.cra_driver_name = "tegra-se-sha1",
|
||||||
@@ -642,16 +682,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -661,7 +694,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA224_DIGEST_SIZE,
|
.halg.digestsize = SHA224_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha224",
|
.cra_name = "sha224",
|
||||||
.cra_driver_name = "tegra-se-sha224",
|
.cra_driver_name = "tegra-se-sha224",
|
||||||
@@ -674,16 +706,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -693,7 +718,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA256_DIGEST_SIZE,
|
.halg.digestsize = SHA256_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha256",
|
.cra_name = "sha256",
|
||||||
.cra_driver_name = "tegra-se-sha256",
|
.cra_driver_name = "tegra-se-sha256",
|
||||||
@@ -706,16 +730,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -725,7 +742,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA384_DIGEST_SIZE,
|
.halg.digestsize = SHA384_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha384",
|
.cra_name = "sha384",
|
||||||
.cra_driver_name = "tegra-se-sha384",
|
.cra_driver_name = "tegra-se-sha384",
|
||||||
@@ -738,16 +754,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -757,7 +766,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA512_DIGEST_SIZE,
|
.halg.digestsize = SHA512_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha512",
|
.cra_name = "sha512",
|
||||||
.cra_driver_name = "tegra-se-sha512",
|
.cra_driver_name = "tegra-se-sha512",
|
||||||
@@ -770,16 +778,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -789,7 +790,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA3_224_DIGEST_SIZE,
|
.halg.digestsize = SHA3_224_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha3-224",
|
.cra_name = "sha3-224",
|
||||||
.cra_driver_name = "tegra-se-sha3-224",
|
.cra_driver_name = "tegra-se-sha3-224",
|
||||||
@@ -802,16 +802,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -821,7 +814,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA3_256_DIGEST_SIZE,
|
.halg.digestsize = SHA3_256_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha3-256",
|
.cra_name = "sha3-256",
|
||||||
.cra_driver_name = "tegra-se-sha3-256",
|
.cra_driver_name = "tegra-se-sha3-256",
|
||||||
@@ -834,16 +826,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -853,7 +838,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA3_384_DIGEST_SIZE,
|
.halg.digestsize = SHA3_384_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha3-384",
|
.cra_name = "sha3-384",
|
||||||
.cra_driver_name = "tegra-se-sha3-384",
|
.cra_driver_name = "tegra-se-sha3-384",
|
||||||
@@ -866,16 +850,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -885,7 +862,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.import = tegra_sha_import,
|
.import = tegra_sha_import,
|
||||||
.halg.digestsize = SHA3_512_DIGEST_SIZE,
|
.halg.digestsize = SHA3_512_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "sha3-512",
|
.cra_name = "sha3-512",
|
||||||
.cra_driver_name = "tegra-se-sha3-512",
|
.cra_driver_name = "tegra-se-sha3-512",
|
||||||
@@ -898,17 +874,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg_base = "sha224",
|
.alg_base = "sha224",
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -919,7 +888,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.setkey = tegra_hmac_setkey,
|
.setkey = tegra_hmac_setkey,
|
||||||
.halg.digestsize = SHA224_DIGEST_SIZE,
|
.halg.digestsize = SHA224_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "hmac(sha224)",
|
.cra_name = "hmac(sha224)",
|
||||||
.cra_driver_name = "tegra-se-hmac-sha224",
|
.cra_driver_name = "tegra-se-hmac-sha224",
|
||||||
@@ -932,17 +900,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg_base = "sha256",
|
.alg_base = "sha256",
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -953,7 +914,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.setkey = tegra_hmac_setkey,
|
.setkey = tegra_hmac_setkey,
|
||||||
.halg.digestsize = SHA256_DIGEST_SIZE,
|
.halg.digestsize = SHA256_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "hmac(sha256)",
|
.cra_name = "hmac(sha256)",
|
||||||
.cra_driver_name = "tegra-se-hmac-sha256",
|
.cra_driver_name = "tegra-se-hmac-sha256",
|
||||||
@@ -966,17 +926,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg_base = "sha384",
|
.alg_base = "sha384",
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -987,7 +940,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.setkey = tegra_hmac_setkey,
|
.setkey = tegra_hmac_setkey,
|
||||||
.halg.digestsize = SHA384_DIGEST_SIZE,
|
.halg.digestsize = SHA384_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "hmac(sha384)",
|
.cra_name = "hmac(sha384)",
|
||||||
.cra_driver_name = "tegra-se-hmac-sha384",
|
.cra_driver_name = "tegra-se-hmac-sha384",
|
||||||
@@ -1000,17 +952,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
.alg_base = "sha512",
|
.alg_base = "sha512",
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
.base = {
|
|
||||||
#endif
|
|
||||||
.init = tegra_sha_init,
|
.init = tegra_sha_init,
|
||||||
.update = tegra_sha_update,
|
.update = tegra_sha_update,
|
||||||
.final = tegra_sha_final,
|
.final = tegra_sha_final,
|
||||||
@@ -1021,7 +966,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.setkey = tegra_hmac_setkey,
|
.setkey = tegra_hmac_setkey,
|
||||||
.halg.digestsize = SHA512_DIGEST_SIZE,
|
.halg.digestsize = SHA512_DIGEST_SIZE,
|
||||||
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
.halg.statesize = sizeof(struct tegra_sha_reqctx),
|
||||||
|
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
.cra_name = "hmac(sha512)",
|
.cra_name = "hmac(sha512)",
|
||||||
.cra_driver_name = "tegra-se-hmac-sha512",
|
.cra_driver_name = "tegra-se-hmac-sha512",
|
||||||
@@ -1034,10 +978,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
|||||||
.cra_init = tegra_sha_cra_init,
|
.cra_init = tegra_sha_cra_init,
|
||||||
.cra_exit = tegra_sha_cra_exit,
|
.cra_exit = tegra_sha_cra_exit,
|
||||||
}
|
}
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
},
|
|
||||||
.op.do_one_request = tegra_sha_do_one_req,
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1077,42 +1017,36 @@ static int tegra_hash_kac_manifest(u32 user, u32 alg, u32 keylen)
|
|||||||
|
|
||||||
int tegra_init_hash(struct tegra_se *se)
|
int tegra_init_hash(struct tegra_se *se)
|
||||||
{
|
{
|
||||||
|
struct ahash_alg *alg;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
se->manifest = tegra_hash_kac_manifest;
|
se->manifest = tegra_hash_kac_manifest;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++) {
|
for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++) {
|
||||||
|
|
||||||
tegra_hash_algs[i].se_dev = se;
|
tegra_hash_algs[i].se_dev = se;
|
||||||
ret = CRYPTO_REGISTER(ahash, &tegra_hash_algs[i].alg.ahash);
|
alg = &tegra_hash_algs[i].alg.ahash;
|
||||||
|
|
||||||
|
ret = crypto_register_ahash(alg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
dev_err(se->dev, "failed to register %s\n",
|
dev_err(se->dev, "failed to register %s\n",
|
||||||
tegra_hash_algs[i].alg.ahash.base.halg.base.cra_name);
|
alg->halg.base.cra_name);
|
||||||
#else
|
|
||||||
dev_err(se->dev, "failed to register %s\n",
|
|
||||||
tegra_hash_algs[i].alg.ahash.halg.base.cra_name);
|
|
||||||
#endif
|
|
||||||
goto sha_err;
|
goto sha_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_info(se->dev, "registered HASH algorithms\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sha_err:
|
sha_err:
|
||||||
for (--i; i >= 0; i--)
|
while (i--)
|
||||||
CRYPTO_UNREGISTER(ahash, &tegra_hash_algs[i].alg.ahash);
|
crypto_unregister_ahash(&tegra_hash_algs[i].alg.ahash);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tegra_deinit_hash(struct tegra_se *se)
|
||||||
void tegra_deinit_hash(void)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++)
|
for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++)
|
||||||
CRYPTO_UNREGISTER(ahash, &tegra_hash_algs[i].alg.ahash);
|
crypto_unregister_ahash(&tegra_hash_algs[i].alg.ahash);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
/*
|
/*
|
||||||
* Crypto driver file to manage keys of NVIDIA Security Engine.
|
* Crypto driver file to manage keys of NVIDIA Security Engine.
|
||||||
*/
|
*/
|
||||||
@@ -16,66 +16,77 @@
|
|||||||
#define SE_KEY_RSVD_MASK (BIT(0) | BIT(14) | BIT(15))
|
#define SE_KEY_RSVD_MASK (BIT(0) | BIT(14) | BIT(15))
|
||||||
#define SE_KEY_VALID_MASK (SE_KEY_FULL_MASK & ~SE_KEY_RSVD_MASK)
|
#define SE_KEY_VALID_MASK (SE_KEY_FULL_MASK & ~SE_KEY_RSVD_MASK)
|
||||||
|
|
||||||
|
/* Mutex lock to guard keyslots */
|
||||||
|
static DEFINE_MUTEX(kslt_lock);
|
||||||
|
|
||||||
|
/* Keyslot bitmask (0 = available, 1 = in use/not available) */
|
||||||
static u16 tegra_se_keyslots = SE_KEY_RSVD_MASK;
|
static u16 tegra_se_keyslots = SE_KEY_RSVD_MASK;
|
||||||
|
|
||||||
static u16 tegra_keyslot_alloc(void)
|
static u16 tegra_keyslot_alloc(void)
|
||||||
{
|
{
|
||||||
u16 keyid;
|
u16 keyid;
|
||||||
|
|
||||||
|
mutex_lock(&kslt_lock);
|
||||||
/* Check if all key slots are full */
|
/* Check if all key slots are full */
|
||||||
if (tegra_se_keyslots == GENMASK(SE_MAX_KEYSLOT, 0))
|
if (tegra_se_keyslots == GENMASK(SE_MAX_KEYSLOT, 0)) {
|
||||||
|
mutex_unlock(&kslt_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
keyid = ffz(tegra_se_keyslots);
|
keyid = ffz(tegra_se_keyslots);
|
||||||
tegra_se_keyslots |= BIT(keyid);
|
tegra_se_keyslots |= BIT(keyid);
|
||||||
|
|
||||||
|
mutex_unlock(&kslt_lock);
|
||||||
|
|
||||||
return keyid;
|
return keyid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tegra_keyslot_free(u16 slot)
|
static void tegra_keyslot_free(u16 slot)
|
||||||
{
|
{
|
||||||
|
mutex_lock(&kslt_lock);
|
||||||
tegra_se_keyslots &= ~(BIT(slot));
|
tegra_se_keyslots &= ~(BIT(slot));
|
||||||
|
mutex_unlock(&kslt_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int tegra_key_prep_ins_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
static unsigned int tegra_key_prep_ins_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
||||||
const u32 *key, u32 keylen, u16 slot, u32 alg)
|
const u32 *key, u32 keylen, u16 slot, u32 alg)
|
||||||
{
|
{
|
||||||
int i = 0, j;
|
int i = 0, j;
|
||||||
|
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->op);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->op);
|
||||||
cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_DUMMY;
|
cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_DUMMY;
|
||||||
|
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->manifest);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->manifest);
|
||||||
cpuvaddr[i++] = se->manifest(se->owner, alg, keylen);
|
cpuvaddr[i++] = se->manifest(se->owner, alg, keylen);
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->key_dst);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_dst);
|
||||||
|
|
||||||
cpuvaddr[i++] = SE_AES_KEY_DST_INDEX(slot);
|
cpuvaddr[i++] = SE_AES_KEY_DST_INDEX(slot);
|
||||||
|
|
||||||
for (j = 0; j < keylen / 4; j++) {
|
for (j = 0; j < keylen / 4; j++) {
|
||||||
/* Set key address */
|
/* Set key address */
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->key_addr);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_addr);
|
||||||
cpuvaddr[i++] = j;
|
cpuvaddr[i++] = j;
|
||||||
|
|
||||||
/* Set key data */
|
/* Set key data */
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->key_data);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_data);
|
||||||
cpuvaddr[i++] = key[j];
|
cpuvaddr[i++] = key[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->config);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->config);
|
||||||
cpuvaddr[i++] = SE_CFG_INS;
|
cpuvaddr[i++] = SE_CFG_INS;
|
||||||
|
|
||||||
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
cpuvaddr[i++] = host1x_opcode_setpayload(1);
|
||||||
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->op);
|
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->op);
|
||||||
cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_START |
|
cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_START |
|
||||||
SE_AES_OP_LASTBUF;
|
SE_AES_OP_LASTBUF;
|
||||||
|
|
||||||
cpuvaddr[i++] = host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
|
cpuvaddr[i++] = se_host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
|
||||||
cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
|
cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
|
||||||
host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
|
host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
|
||||||
|
|
||||||
@@ -87,15 +98,21 @@ static unsigned int tegra_key_prep_ins_cmd(struct tegra_se *se, u32 *cpuvaddr,
|
|||||||
|
|
||||||
static bool tegra_key_in_kslt(u32 keyid)
|
static bool tegra_key_in_kslt(u32 keyid)
|
||||||
{
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
if (keyid > SE_MAX_KEYSLOT)
|
if (keyid > SE_MAX_KEYSLOT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return ((BIT(keyid) & SE_KEY_VALID_MASK) &&
|
mutex_lock(&kslt_lock);
|
||||||
|
ret = ((BIT(keyid) & SE_KEY_VALID_MASK) &&
|
||||||
(BIT(keyid) & tegra_se_keyslots));
|
(BIT(keyid) & tegra_se_keyslots));
|
||||||
|
mutex_unlock(&kslt_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_key_insert(struct tegra_se *se, const u8 *key,
|
static int tegra_key_insert(struct tegra_se *se, const u8 *key,
|
||||||
u32 keylen, u16 slot, u32 alg)
|
u32 keylen, u16 slot, u32 alg)
|
||||||
{
|
{
|
||||||
const u32 *keyval = (u32 *)key;
|
const u32 *keyval = (u32 *)key;
|
||||||
u32 *addr = se->cmdbuf->addr, size;
|
u32 *addr = se->cmdbuf->addr, size;
|
||||||
@@ -105,11 +122,16 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key,
|
|||||||
return tegra_se_host1x_submit(se, size);
|
return tegra_se_host1x_submit(se, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tegra_key_invalidate(struct tegra_se *se, u32 keyid)
|
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)
|
||||||
{
|
{
|
||||||
|
u8 zkey[AES_MAX_KEY_SIZE] = {0};
|
||||||
|
|
||||||
if (!keyid)
|
if (!keyid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Overwrite the key with 0s */
|
||||||
|
tegra_key_insert(se, zkey, AES_MAX_KEY_SIZE, keyid, alg);
|
||||||
|
|
||||||
tegra_keyslot_free(keyid);
|
tegra_keyslot_free(keyid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +142,10 @@ int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u3
|
|||||||
/* Use the existing slot if it is already allocated */
|
/* Use the existing slot if it is already allocated */
|
||||||
if (!tegra_key_in_kslt(*keyid)) {
|
if (!tegra_key_in_kslt(*keyid)) {
|
||||||
*keyid = tegra_keyslot_alloc();
|
*keyid = tegra_keyslot_alloc();
|
||||||
if (!(*keyid))
|
if (!(*keyid)) {
|
||||||
|
dev_err(se->dev, "failed to allocate key slot\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tegra_key_insert(se, key, keylen, *keyid, alg);
|
ret = tegra_key_insert(se, key, keylen, *keyid, alg);
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
/*
|
/*
|
||||||
* Crypto driver for NVIDIA Security Engine in Tegra Chips
|
* Crypto driver for NVIDIA Security Engine in Tegra Chips
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/host1x-next.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
@@ -124,7 +123,7 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi
|
|||||||
struct tegra_se_cmdbuf *cmdbuf;
|
struct tegra_se_cmdbuf *cmdbuf;
|
||||||
struct device *dev = se->dev->parent;
|
struct device *dev = se->dev->parent;
|
||||||
|
|
||||||
cmdbuf = kzalloc(sizeof(struct tegra_se_cmdbuf), GFP_KERNEL);
|
cmdbuf = kzalloc(sizeof(*cmdbuf), GFP_KERNEL);
|
||||||
if (!cmdbuf)
|
if (!cmdbuf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -153,7 +152,7 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
job->syncpt = host1x_syncpt_get(se->syncpt);
|
job->syncpt = host1x_syncpt_get(se->syncpt);
|
||||||
job->syncpt_incrs = 1;
|
job->syncpt_incrs = 1;
|
||||||
job->client = &se->client;
|
job->client = &se->client;
|
||||||
job->class = se->client.class;
|
job->class = se->client.class;
|
||||||
@@ -168,17 +167,17 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
|
|||||||
ret = host1x_job_pin(job, se->dev);
|
ret = host1x_job_pin(job, se->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(se->dev, "failed to pin host1x job\n");
|
dev_err(se->dev, "failed to pin host1x job\n");
|
||||||
goto err_job_pin;
|
goto job_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = host1x_job_submit(job);
|
ret = host1x_job_submit(job);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(se->dev, "failed to submit host1x job\n");
|
dev_err(se->dev, "failed to submit host1x job\n");
|
||||||
goto err_job_submit;
|
goto job_unpin;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = host1x_syncpt_wait(job->syncpt, job->syncpt_end,
|
ret = host1x_syncpt_wait(job->syncpt, job->syncpt_end,
|
||||||
MAX_SCHEDULE_TIMEOUT, NULL);
|
MAX_SCHEDULE_TIMEOUT, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(se->dev, "host1x job timed out\n");
|
dev_err(se->dev, "host1x job timed out\n");
|
||||||
return ret;
|
return ret;
|
||||||
@@ -187,9 +186,9 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
|
|||||||
host1x_job_put(job);
|
host1x_job_put(job);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_job_submit:
|
job_unpin:
|
||||||
host1x_job_unpin(job);
|
host1x_job_unpin(job);
|
||||||
err_job_pin:
|
job_put:
|
||||||
host1x_job_put(job);
|
host1x_job_put(job);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -210,7 +209,7 @@ static int tegra_se_client_init(struct host1x_client *client)
|
|||||||
if (!se->syncpt) {
|
if (!se->syncpt) {
|
||||||
dev_err(se->dev, "host1x syncpt allocation failed\n");
|
dev_err(se->dev, "host1x syncpt allocation failed\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err_syncpt;
|
goto channel_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
se->syncpt_id = host1x_syncpt_id(se->syncpt);
|
se->syncpt_id = host1x_syncpt_id(se->syncpt);
|
||||||
@@ -218,22 +217,22 @@ static int tegra_se_client_init(struct host1x_client *client)
|
|||||||
se->cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
|
se->cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
|
||||||
if (!se->cmdbuf) {
|
if (!se->cmdbuf) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_bo;
|
goto syncpt_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = se->hw->init_alg(se);
|
ret = se->hw->init_alg(se);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(se->dev, "failed to register algorithms\n");
|
dev_err(se->dev, "failed to register algorithms\n");
|
||||||
goto err_alg_reg;
|
goto cmdbuf_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_alg_reg:
|
cmdbuf_put:
|
||||||
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
|
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
|
||||||
err_bo:
|
syncpt_put:
|
||||||
host1x_syncpt_put(se->syncpt);
|
host1x_syncpt_put(se->syncpt);
|
||||||
err_syncpt:
|
channel_put:
|
||||||
host1x_channel_put(se->channel);
|
host1x_channel_put(se->channel);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -243,7 +242,7 @@ static int tegra_se_client_deinit(struct host1x_client *client)
|
|||||||
{
|
{
|
||||||
struct tegra_se *se = container_of(client, struct tegra_se, client);
|
struct tegra_se *se = container_of(client, struct tegra_se, client);
|
||||||
|
|
||||||
se->hw->deinit_alg();
|
se->hw->deinit_alg(se);
|
||||||
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
|
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
|
||||||
host1x_syncpt_put(se->syncpt);
|
host1x_syncpt_put(se->syncpt);
|
||||||
host1x_channel_put(se->channel);
|
host1x_channel_put(se->channel);
|
||||||
@@ -256,7 +255,7 @@ static const struct host1x_client_ops tegra_se_client_ops = {
|
|||||||
.exit = tegra_se_client_deinit,
|
.exit = tegra_se_client_deinit,
|
||||||
};
|
};
|
||||||
|
|
||||||
int tegra_se_host1x_register(struct tegra_se *se)
|
static int tegra_se_host1x_register(struct tegra_se *se)
|
||||||
{
|
{
|
||||||
INIT_LIST_HEAD(&se->client.list);
|
INIT_LIST_HEAD(&se->client.list);
|
||||||
se->client.dev = se->dev;
|
se->client.dev = se->dev;
|
||||||
@@ -269,38 +268,6 @@ int tegra_se_host1x_register(struct tegra_se *se)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_se_clk_init(struct tegra_se *se)
|
|
||||||
{
|
|
||||||
int i, ret;
|
|
||||||
|
|
||||||
se->num_clks = devm_clk_bulk_get_all(se->dev, &se->clks);
|
|
||||||
if (se->num_clks < 0) {
|
|
||||||
dev_err(se->dev, "failed to get clocks\n");
|
|
||||||
return se->num_clks;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < se->num_clks; i++) {
|
|
||||||
ret = clk_set_rate(se->clks[i].clk, ULONG_MAX);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(se->dev, "failed to set %d clock rate", i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_bulk_prepare_enable(se->num_clks, se->clks);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(se->dev, "failed to enable clocks\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tegra_se_clk_deinit(struct tegra_se *se)
|
|
||||||
{
|
|
||||||
clk_bulk_disable_unprepare(se->num_clks, se->clks);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tegra_se_probe(struct platform_device *pdev)
|
static int tegra_se_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
@@ -312,61 +279,45 @@ static int tegra_se_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
se->dev = dev;
|
se->dev = dev;
|
||||||
|
se->owner = TEGRA_GPSE_ID;
|
||||||
se->hw = device_get_match_data(&pdev->dev);
|
se->hw = device_get_match_data(&pdev->dev);
|
||||||
|
|
||||||
se->base = devm_platform_ioremap_resource(pdev, 0);
|
se->base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
if (IS_ERR(se->base))
|
if (IS_ERR(se->base))
|
||||||
return PTR_ERR(se->base);
|
return PTR_ERR(se->base);
|
||||||
|
|
||||||
se->owner = TEGRA_GPSE_ID;
|
|
||||||
|
|
||||||
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(39));
|
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(39));
|
||||||
platform_set_drvdata(pdev, se);
|
platform_set_drvdata(pdev, se);
|
||||||
|
|
||||||
ret = tegra_se_clk_init(se);
|
se->clk = devm_clk_get_enabled(se->dev, NULL);
|
||||||
if (ret) {
|
if (IS_ERR(se->clk))
|
||||||
dev_err(dev, "failed to init clocks\n");
|
return dev_err_probe(dev, PTR_ERR(se->clk),
|
||||||
return ret;
|
"failed to enable clocks\n");
|
||||||
}
|
|
||||||
|
|
||||||
if (!tegra_dev_iommu_get_stream_id(dev, &se->stream_id)) {
|
if (!tegra_dev_iommu_get_stream_id(dev, &se->stream_id))
|
||||||
dev_err(dev, "failed to get IOMMU stream ID\n");
|
return dev_err_probe(dev, -ENODEV,
|
||||||
goto err_iommu_spec;
|
"failed to get IOMMU stream ID\n");
|
||||||
}
|
|
||||||
|
|
||||||
se_writel(se, se->stream_id, SE_STREAM_ID);
|
writel(se->stream_id, se->base + SE_STREAM_ID);
|
||||||
|
|
||||||
se->engine = crypto_engine_alloc_init(dev, 0);
|
se->engine = crypto_engine_alloc_init(dev, 0);
|
||||||
if (!se->engine) {
|
if (!se->engine)
|
||||||
dev_err(dev, "failed to init crypto engine\n");
|
return dev_err_probe(dev, -ENOMEM, "failed to init crypto engine\n");
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_engine_alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = crypto_engine_start(se->engine);
|
ret = crypto_engine_start(se->engine);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "failed to start crypto engine\n");
|
crypto_engine_exit(se->engine);
|
||||||
goto err_engine_start;
|
return dev_err_probe(dev, ret, "failed to start crypto engine\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tegra_se_host1x_register(se);
|
ret = tegra_se_host1x_register(se);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "failed to init host1x params\n");
|
crypto_engine_stop(se->engine);
|
||||||
goto err_host1x_init;
|
crypto_engine_exit(se->engine);
|
||||||
|
return dev_err_probe(dev, ret, "failed to init host1x params\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_host1x_init:
|
|
||||||
crypto_engine_stop(se->engine);
|
|
||||||
err_engine_start:
|
|
||||||
crypto_engine_exit(se->engine);
|
|
||||||
err_engine_alloc:
|
|
||||||
iommu_fwspec_free(se->dev);
|
|
||||||
err_iommu_spec:
|
|
||||||
tegra_se_clk_deinit(se);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_se_remove(struct platform_device *pdev)
|
static int tegra_se_remove(struct platform_device *pdev)
|
||||||
@@ -377,7 +328,6 @@ static int tegra_se_remove(struct platform_device *pdev)
|
|||||||
crypto_engine_exit(se->engine);
|
crypto_engine_exit(se->engine);
|
||||||
iommu_fwspec_free(se->dev);
|
iommu_fwspec_free(se->dev);
|
||||||
host1x_client_unregister(&se->client);
|
host1x_client_unregister(&se->client);
|
||||||
tegra_se_clk_deinit(se);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -424,10 +374,10 @@ static const struct tegra_se_hw tegra234_hash_hw = {
|
|||||||
|
|
||||||
static const struct of_device_id tegra_se_of_match[] = {
|
static const struct of_device_id tegra_se_of_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "nvidia,tegra234-se2-aes",
|
.compatible = "nvidia,tegra234-se-aes",
|
||||||
.data = &tegra234_aes_hw
|
.data = &tegra234_aes_hw
|
||||||
}, {
|
}, {
|
||||||
.compatible = "nvidia,tegra234-se4-hash",
|
.compatible = "nvidia,tegra234-se-hash",
|
||||||
.data = &tegra234_hash_hw,
|
.data = &tegra234_hash_hw,
|
||||||
},
|
},
|
||||||
{ },
|
{ },
|
||||||
@@ -486,4 +436,4 @@ module_exit(tegra_se_module_exit);
|
|||||||
|
|
||||||
MODULE_DESCRIPTION("NVIDIA Tegra Security Engine Driver");
|
MODULE_DESCRIPTION("NVIDIA Tegra Security Engine Driver");
|
||||||
MODULE_AUTHOR("Akhil R <akhilrajeev@nvidia.com>");
|
MODULE_AUTHOR("Akhil R <akhilrajeev@nvidia.com>");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL");
|
||||||
|
|||||||
@@ -7,22 +7,18 @@
|
|||||||
#ifndef _TEGRA_SE_H
|
#ifndef _TEGRA_SE_H
|
||||||
#define _TEGRA_SE_H
|
#define _TEGRA_SE_H
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <nvidia/conftest.h>
|
||||||
|
|
||||||
|
#include <linux/bitfield.h>
|
||||||
#include <linux/iommu.h>
|
#include <linux/iommu.h>
|
||||||
#include <linux/host1x-next.h>
|
#include <linux/host1x-next.h>
|
||||||
#include <linux/version.h>
|
|
||||||
#include <crypto/aead.h>
|
#include <crypto/aead.h>
|
||||||
|
#include <crypto/engine.h>
|
||||||
#include <crypto/hash.h>
|
#include <crypto/hash.h>
|
||||||
#include <crypto/sha1.h>
|
#include <crypto/sha1.h>
|
||||||
#include <crypto/sha3.h>
|
#include <crypto/sha3.h>
|
||||||
#include <crypto/sm3.h>
|
|
||||||
#include <crypto/skcipher.h>
|
#include <crypto/skcipher.h>
|
||||||
#include <nvidia/conftest.h>
|
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
#include <crypto/engine.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SE_MAX_INSTANCES 3
|
|
||||||
#define SE_OWNERSHIP 0x14
|
#define SE_OWNERSHIP 0x14
|
||||||
#define SE_OWNERSHIP_UID(x) FIELD_GET(GENMASK(7, 0), x)
|
#define SE_OWNERSHIP_UID(x) FIELD_GET(GENMASK(7, 0), x)
|
||||||
#define TEGRA_GPSE_ID 3
|
#define TEGRA_GPSE_ID 3
|
||||||
@@ -67,11 +63,8 @@
|
|||||||
#define SE_SHA_ENC_ALG_HMAC SE_SHA_CFG_ENC_ALG(7)
|
#define SE_SHA_ENC_ALG_HMAC SE_SHA_CFG_ENC_ALG(7)
|
||||||
#define SE_SHA_ENC_ALG_KDF SE_SHA_CFG_ENC_ALG(8)
|
#define SE_SHA_ENC_ALG_KDF SE_SHA_CFG_ENC_ALG(8)
|
||||||
#define SE_SHA_ENC_ALG_KEY_INVLD SE_SHA_CFG_ENC_ALG(10)
|
#define SE_SHA_ENC_ALG_KEY_INVLD SE_SHA_CFG_ENC_ALG(10)
|
||||||
#define SE_SHA_ENC_ALG_KEY_MOV SE_SHA_CFG_ENC_ALG(11)
|
|
||||||
#define SE_SHA_ENC_ALG_KEY_INQUIRE SE_SHA_CFG_ENC_ALG(12)
|
#define SE_SHA_ENC_ALG_KEY_INQUIRE SE_SHA_CFG_ENC_ALG(12)
|
||||||
#define SE_SHA_ENC_ALG_INS SE_SHA_CFG_ENC_ALG(13)
|
#define SE_SHA_ENC_ALG_INS SE_SHA_CFG_ENC_ALG(13)
|
||||||
#define SE_SHA_ENC_ALG_CLONE SE_SHA_CFG_ENC_ALG(14)
|
|
||||||
#define SE_SHA_ENC_ALG_LOCK SE_SHA_CFG_ENC_ALG(15)
|
|
||||||
|
|
||||||
#define SE_SHA_OP_LASTBUF FIELD_PREP(BIT(16), 1)
|
#define SE_SHA_OP_LASTBUF FIELD_PREP(BIT(16), 1)
|
||||||
#define SE_SHA_OP_WRSTALL FIELD_PREP(BIT(15), 1)
|
#define SE_SHA_OP_WRSTALL FIELD_PREP(BIT(15), 1)
|
||||||
@@ -311,12 +304,6 @@
|
|||||||
SE_AES_CORE_SEL_DECRYPT | \
|
SE_AES_CORE_SEL_DECRYPT | \
|
||||||
SE_AES_IV_SEL_REG)
|
SE_AES_IV_SEL_REG)
|
||||||
|
|
||||||
#define SE_CRYPTO_CFG_OFB (SE_AES_INPUT_SEL_AESOUT | \
|
|
||||||
SE_AES_VCTRAM_SEL_MEMORY | \
|
|
||||||
SE_AES_XOR_POS_BOTTOM | \
|
|
||||||
SE_AES_CORE_SEL_ENCRYPT | \
|
|
||||||
SE_AES_IV_SEL_REG)
|
|
||||||
|
|
||||||
#define SE_CRYPTO_CFG_CTR (SE_AES_INPUT_SEL_LINEAR_CTR | \
|
#define SE_CRYPTO_CFG_CTR (SE_AES_INPUT_SEL_LINEAR_CTR | \
|
||||||
SE_AES_VCTRAM_SEL_MEMORY | \
|
SE_AES_VCTRAM_SEL_MEMORY | \
|
||||||
SE_AES_XOR_POS_BOTTOM | \
|
SE_AES_XOR_POS_BOTTOM | \
|
||||||
@@ -356,34 +343,17 @@
|
|||||||
#define SE_MAX_KEYSLOT 15
|
#define SE_MAX_KEYSLOT 15
|
||||||
#define SE_MAX_MEM_ALLOC SZ_4M
|
#define SE_MAX_MEM_ALLOC SZ_4M
|
||||||
#define SE_AES_BUFLEN 0x8000
|
#define SE_AES_BUFLEN 0x8000
|
||||||
#define SE_SHA_BUFLEN SZ_4M
|
#define SE_SHA_BUFLEN 0x2000
|
||||||
|
|
||||||
#define SHA_FIRST BIT(0)
|
#define SHA_FIRST BIT(0)
|
||||||
#define SHA_UPDATE BIT(1)
|
#define SHA_UPDATE BIT(1)
|
||||||
#define SHA_FINAL BIT(2)
|
#define SHA_FINAL BIT(2)
|
||||||
|
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
#define CRYPTO_REGISTER(alg, x) \
|
|
||||||
crypto_engine_register_##alg(x)
|
|
||||||
#else
|
|
||||||
#define CRYPTO_REGISTER(alg, x) \
|
|
||||||
crypto_register_##alg(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
|
||||||
#define CRYPTO_UNREGISTER(alg, x) \
|
|
||||||
crypto_engine_unregister_##alg(x)
|
|
||||||
#else
|
|
||||||
#define CRYPTO_UNREGISTER(alg, x) \
|
|
||||||
crypto_unregister_##alg(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Security Engine operation modes */
|
/* Security Engine operation modes */
|
||||||
enum se_aes_alg {
|
enum se_aes_alg {
|
||||||
SE_ALG_CBC, /* Cipher Block Chaining (CBC) mode */
|
SE_ALG_CBC, /* Cipher Block Chaining (CBC) mode */
|
||||||
SE_ALG_ECB, /* Electronic Codebook (ECB) mode */
|
SE_ALG_ECB, /* Electronic Codebook (ECB) mode */
|
||||||
SE_ALG_CTR, /* Counter (CTR) mode */
|
SE_ALG_CTR, /* Counter (CTR) mode */
|
||||||
SE_ALG_OFB, /* Output feedback (CFB) mode */
|
|
||||||
SE_ALG_XTS, /* XTS mode */
|
SE_ALG_XTS, /* XTS mode */
|
||||||
SE_ALG_GMAC, /* GMAC mode */
|
SE_ALG_GMAC, /* GMAC mode */
|
||||||
SE_ALG_GCM, /* GCM mode */
|
SE_ALG_GCM, /* GCM mode */
|
||||||
@@ -416,15 +386,9 @@ struct tegra_se_alg {
|
|||||||
const char *alg_base;
|
const char *alg_base;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
struct skcipher_alg skcipher;
|
||||||
struct skcipher_alg skcipher;
|
struct aead_alg aead;
|
||||||
struct aead_alg aead;
|
struct ahash_alg ahash;
|
||||||
struct ahash_alg ahash;
|
|
||||||
#else
|
|
||||||
struct skcipher_engine_alg skcipher;
|
|
||||||
struct aead_engine_alg aead;
|
|
||||||
struct ahash_engine_alg ahash;
|
|
||||||
#endif
|
|
||||||
} alg;
|
} alg;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -446,7 +410,7 @@ struct tegra_se_regs {
|
|||||||
struct tegra_se_hw {
|
struct tegra_se_hw {
|
||||||
const struct tegra_se_regs *regs;
|
const struct tegra_se_regs *regs;
|
||||||
int (*init_alg)(struct tegra_se *se);
|
int (*init_alg)(struct tegra_se *se);
|
||||||
void (*deinit_alg)(void);
|
void (*deinit_alg)(struct tegra_se *se);
|
||||||
bool support_sm_alg;
|
bool support_sm_alg;
|
||||||
u32 host1x_class;
|
u32 host1x_class;
|
||||||
u32 kac_ver;
|
u32 kac_ver;
|
||||||
@@ -455,18 +419,17 @@ struct tegra_se_hw {
|
|||||||
struct tegra_se {
|
struct tegra_se {
|
||||||
int (*manifest)(u32 user, u32 alg, u32 keylen);
|
int (*manifest)(u32 user, u32 alg, u32 keylen);
|
||||||
const struct tegra_se_hw *hw;
|
const struct tegra_se_hw *hw;
|
||||||
struct crypto_engine *engine;
|
|
||||||
struct host1x_channel *channel;
|
|
||||||
struct host1x_client client;
|
struct host1x_client client;
|
||||||
struct host1x_syncpt *syncpt;
|
struct host1x_channel *channel;
|
||||||
struct clk_bulk_data *clks;
|
|
||||||
struct tegra_se_cmdbuf *cmdbuf;
|
struct tegra_se_cmdbuf *cmdbuf;
|
||||||
|
struct crypto_engine *engine;
|
||||||
|
struct host1x_syncpt *syncpt;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct clk *clk;
|
||||||
unsigned int opcode_addr;
|
unsigned int opcode_addr;
|
||||||
unsigned int stream_id;
|
unsigned int stream_id;
|
||||||
unsigned int syncpt_id;
|
unsigned int syncpt_id;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
int num_clks;
|
|
||||||
u32 owner;
|
u32 owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -476,8 +439,8 @@ struct tegra_se_cmdbuf {
|
|||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct kref ref;
|
struct kref ref;
|
||||||
struct host1x_bo bo;
|
struct host1x_bo bo;
|
||||||
u32 words;
|
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
|
u32 words;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tegra_se_datbuf {
|
struct tegra_se_datbuf {
|
||||||
@@ -492,8 +455,6 @@ static inline int se_algname_to_algid(const char *name)
|
|||||||
return SE_ALG_CBC;
|
return SE_ALG_CBC;
|
||||||
else if (!strcmp(name, "ecb(aes)"))
|
else if (!strcmp(name, "ecb(aes)"))
|
||||||
return SE_ALG_ECB;
|
return SE_ALG_ECB;
|
||||||
else if (!strcmp(name, "ofb(aes)"))
|
|
||||||
return SE_ALG_OFB;
|
|
||||||
else if (!strcmp(name, "ctr(aes)"))
|
else if (!strcmp(name, "ctr(aes)"))
|
||||||
return SE_ALG_CTR;
|
return SE_ALG_CTR;
|
||||||
else if (!strcmp(name, "xts(aes)"))
|
else if (!strcmp(name, "xts(aes)"))
|
||||||
@@ -536,87 +497,61 @@ static inline int se_algname_to_algid(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
int tegra_init_aead(struct tegra_se *se);
|
|
||||||
int tegra_init_aes(struct tegra_se *se);
|
int tegra_init_aes(struct tegra_se *se);
|
||||||
int tegra_init_hash(struct tegra_se *se);
|
int tegra_init_hash(struct tegra_se *se);
|
||||||
void tegra_deinit_aead(void);
|
void tegra_deinit_aes(struct tegra_se *se);
|
||||||
void tegra_deinit_aes(void);
|
void tegra_deinit_hash(struct tegra_se *se);
|
||||||
void tegra_deinit_hash(void);
|
int tegra_key_submit(struct tegra_se *se, const u8 *key,
|
||||||
|
u32 keylen, u32 alg, u32 *keyid);
|
||||||
int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u32 *keyid);
|
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg);
|
||||||
unsigned int tegra_key_get_idx(struct tegra_se *se, u32 keyid);
|
|
||||||
void tegra_key_invalidate(struct tegra_se *se, u32 keyid);
|
|
||||||
|
|
||||||
int tegra_se_host1x_register(struct tegra_se *se);
|
|
||||||
int tegra_se_host1x_submit(struct tegra_se *se, u32 size);
|
int tegra_se_host1x_submit(struct tegra_se *se, u32 size);
|
||||||
|
|
||||||
static inline void se_writel(struct tegra_se *se, unsigned int val,
|
/* HOST1x OPCODES */
|
||||||
unsigned int offset)
|
|
||||||
{
|
|
||||||
writel_relaxed(val, se->base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 se_readl(struct tegra_se *se, unsigned int offset)
|
|
||||||
{
|
|
||||||
return readl_relaxed(se->base + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****
|
|
||||||
*
|
|
||||||
* HOST1x OPCODES
|
|
||||||
*
|
|
||||||
****/
|
|
||||||
|
|
||||||
static inline u32 host1x_opcode_setpayload(unsigned int payload)
|
static inline u32 host1x_opcode_setpayload(unsigned int payload)
|
||||||
{
|
{
|
||||||
return (9 << 28) | payload;
|
return (9 << 28) | payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define host1x_opcode_incr_w(x) __host1x_opcode_incr_w((x) / 4)
|
static inline u32 host1x_opcode_incr_w(unsigned int offset)
|
||||||
static inline u32 __host1x_opcode_incr_w(unsigned int offset)
|
|
||||||
{
|
{
|
||||||
/* 22-bit offset supported */
|
/* 22-bit offset supported */
|
||||||
return (10 << 28) | offset;
|
return (10 << 28) | offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define host1x_opcode_nonincr_w(x) __host1x_opcode_nonincr_w((x) / 4)
|
static inline u32 host1x_opcode_nonincr_w(unsigned int offset)
|
||||||
static inline u32 __host1x_opcode_nonincr_w(unsigned int offset)
|
|
||||||
{
|
{
|
||||||
/* 22-bit offset supported */
|
/* 22-bit offset supported */
|
||||||
return (11 << 28) | offset;
|
return (11 << 28) | offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define host1x_opcode_incr(x, y) __host1x_opcode_incr((x) / 4, y)
|
static inline u32 host1x_opcode_incr(unsigned int offset, unsigned int count)
|
||||||
static inline u32 __host1x_opcode_incr(unsigned int offset, unsigned int count)
|
|
||||||
{
|
{
|
||||||
return (1 << 28) | (offset << 16) | count;
|
return (1 << 28) | (offset << 16) | count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define host1x_opcode_nonincr(x, y) __host1x_opcode_nonincr((x) / 4, y)
|
static inline u32 host1x_opcode_nonincr(unsigned int offset, unsigned int count)
|
||||||
static inline u32 __host1x_opcode_nonincr(unsigned int offset, unsigned int count)
|
|
||||||
{
|
{
|
||||||
return (2 << 28) | (offset << 16) | count;
|
return (2 << 28) | (offset << 16) | count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
|
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
|
||||||
{
|
{
|
||||||
return (v & 0xff) << 10;
|
return (v & 0xff) << 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
|
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
|
||||||
{
|
{
|
||||||
return (v & 0x3ff) << 0;
|
return (v & 0x3ff) << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 host1x_uclass_wait_syncpt_r(void)
|
static inline u32 host1x_uclass_wait_syncpt_r(void)
|
||||||
{
|
{
|
||||||
return 0x8;
|
return 0x8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 host1x_uclass_incr_syncpt_r(void)
|
static inline u32 host1x_uclass_incr_syncpt_r(void)
|
||||||
{
|
{
|
||||||
return 0x0;
|
return 0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(NV_TEGRA_DEV_IOMMU_GET_STREAM_ID_PRESENT)
|
#if !defined(NV_TEGRA_DEV_IOMMU_GET_STREAM_ID_PRESENT)
|
||||||
@@ -635,4 +570,9 @@ static inline bool tegra_dev_iommu_get_stream_id(struct device *dev, u32 *stream
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define se_host1x_opcode_incr_w(x) host1x_opcode_incr_w((x) / 4)
|
||||||
|
#define se_host1x_opcode_nonincr_w(x) host1x_opcode_nonincr_w((x) / 4)
|
||||||
|
#define se_host1x_opcode_incr(x, y) host1x_opcode_incr((x) / 4, y)
|
||||||
|
#define se_host1x_opcode_nonincr(x, y) host1x_opcode_nonincr((x) / 4, y)
|
||||||
|
|
||||||
#endif /*_TEGRA_SE_H*/
|
#endif /*_TEGRA_SE_H*/
|
||||||
|
|||||||
Reference in New Issue
Block a user