diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2011-07-14 14:56:02 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:47:47 -0800 |
commit | 9912c17107e458d514eae715605031b6881ecb51 (patch) | |
tree | ff263c2d9db922ada0721a3a4d1055bbe268b76c /drivers/crypto | |
parent | 5ad1649c366c5ec16386d5cb8bfc8e101cb65726 (diff) |
crypto: tegra-se: add support to use ssk
support to use ssk for some special encrypt
decrypt operations. algo names changed to match
the ones accessed by /dev/tegra-crypto
Bug 850434
Original-Change-Id: I8f13ae1fd15ffeae4aceee5799552d173560479a
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/41012
Reviewed-by: Mallikarjun Kasoju <mkasoju@nvidia.com>
Reviewed-by: Hanumanth Venkateswa Moganty <vmoganty@nvidia.com>
Rebase-Id: R86620bd834ae7740377f43c285ba86aee74bb4cc
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/tegra-se.c | 105 |
1 files changed, 53 insertions, 52 deletions
diff --git a/drivers/crypto/tegra-se.c b/drivers/crypto/tegra-se.c index 54be8f93dc9c..3d1c8c479b7c 100644 --- a/drivers/crypto/tegra-se.c +++ b/drivers/crypto/tegra-se.c @@ -101,7 +101,7 @@ struct tegra_se_aes_context { u32 op_mode; /* AES operation mode */ }; -/* Security Engine randon number generator context */ +/* Security Engine random number generator context */ struct tegra_se_rng_context { struct tegra_se_dev *se_dev; /* Security Engine device */ struct tegra_se_slot *slot; /* Security Engine key slot */ @@ -138,6 +138,11 @@ struct tegra_se_slot { bool available; /* Tells whether key slot is free to use */ }; +static struct tegra_se_slot ssk_slot = { + .slot_num = 15, + .available = false, +}; + /* Security Engine Linked List */ struct tegra_se_ll { dma_addr_t addr; /* DMA buffer address */ @@ -188,9 +193,11 @@ static inline unsigned int se_readl(struct tegra_se_dev *se_dev, static void tegra_se_free_key_slot(struct tegra_se_slot *slot) { - spin_lock(&key_slot_lock); - slot->available = true; - spin_unlock(&key_slot_lock); + if (slot) { + spin_lock(&key_slot_lock); + slot->available = true; + spin_unlock(&key_slot_lock); + } } void tegra_se_clk_enable(struct clk *c) @@ -401,6 +408,9 @@ static void tegra_se_write_key_table(u8 *pdata, u32 data_len, u8 pkt = 0, quad = 0; u32 val = 0, i; + if ((type == SE_KEY_TABLE_TYPE_KEY) && (slot_num == ssk_slot.slot_num)) + return; + if (type == SE_KEY_TABLE_TYPE_ORGIV) quad = QUAD_ORG_IV; else if (type == SE_KEY_TABLE_TYPE_UPDTDIV) @@ -616,7 +626,6 @@ static int tegra_se_alloc_ll_buf(struct tegra_se_dev *se_dev, return 0; } - static void tegra_se_free_ll_buf(struct tegra_se_dev *se_dev) { if (se_dev->src_ll_buf) { @@ -632,7 +641,6 @@ static void tegra_se_free_ll_buf(struct tegra_se_dev *se_dev) } } - static int tegra_se_setup_ablk_req(struct tegra_se_dev *se_dev, struct ablkcipher_request *req) { @@ -690,7 +698,6 @@ static int tegra_se_setup_ablk_req(struct tegra_se_dev *se_dev, return ret; } - static void tegra_se_dequeue_complete_req(struct tegra_se_dev *se_dev, struct ablkcipher_request *req) { @@ -746,7 +753,6 @@ static void tegra_se_process_new_req(struct crypto_async_request *async_req) req->base.complete(&req->base, ret); } - static irqreturn_t tegra_se_irq(int irq, void *dev) { struct tegra_se_dev *se_dev = dev; @@ -902,6 +908,7 @@ static int tegra_se_aes_setkey(struct crypto_ablkcipher *tfm, { struct tegra_se_aes_context *ctx = crypto_ablkcipher_ctx(tfm); struct tegra_se_dev *se_dev = ctx->se_dev; + struct tegra_se_slot *pslot; u8 *pdata = (u8 *)key; if (!ctx) { @@ -909,13 +916,23 @@ static int tegra_se_aes_setkey(struct crypto_ablkcipher *tfm, return -EINVAL; } - if (!key) { - dev_err(se_dev->dev, "invalid argument key"); - return -EINVAL; + if (key) { + if (!ctx->slot || (ctx->slot && + ctx->slot->slot_num == ssk_slot.slot_num)) { + pslot = tegra_se_alloc_key_slot(); + if (!pslot) { + dev_err(se_dev->dev, "no free key slot\n"); + return -ENOMEM; + } + ctx->slot = pslot; + } + ctx->keylen = keylen; + } else { + tegra_se_free_key_slot(ctx->slot); + ctx->slot = &ssk_slot; + ctx->keylen = AES_KEYSIZE_128; } - ctx->keylen = keylen; - /* take access to the hw */ mutex_lock(&se_hw_lock); tegra_se_clk_enable(se_dev->pclk); @@ -932,18 +949,7 @@ static int tegra_se_aes_setkey(struct crypto_ablkcipher *tfm, static int tegra_se_aes_cra_init(struct crypto_tfm *tfm) { - struct tegra_se_dev *se_dev = sg_tegra_se_dev; struct tegra_se_aes_context *ctx = crypto_tfm_ctx(tfm); - struct tegra_se_slot *pslot; - - if (!ctx->slot) { - pslot = tegra_se_alloc_key_slot(); - if (!pslot) { - dev_err(se_dev->dev, "no free key slot\n"); - return -ENOMEM; - } - ctx->slot = pslot; - } ctx->se_dev = sg_tegra_se_dev; tfm->crt_ablkcipher.reqsize = sizeof(struct tegra_se_req_context); @@ -1207,18 +1213,16 @@ static int tegra_se_sha_digest(struct ahash_request *req) int tegra_se_sha_cra_init(struct crypto_tfm *tfm) { - int err = 0; - crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct tegra_se_sha_context)); - return err; + return 0; } void tegra_se_sha_cra_exit(struct crypto_tfm *tfm) { + /* do nothing */ } - int tegra_se_aes_cmac_init(struct ahash_request *req) { @@ -1406,6 +1410,7 @@ int tegra_se_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, struct tegra_se_aes_cmac_context *ctx = crypto_ahash_ctx(tfm); struct tegra_se_dev *se_dev = sg_tegra_se_dev; struct tegra_se_ll *src_ll, *dst_ll; + struct tegra_se_slot *pslot; u8 piv[TEGRA_SE_AES_IV_SIZE]; u32 *pbuf; dma_addr_t pbuf_adr; @@ -1418,13 +1423,23 @@ int tegra_se_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, return -EINVAL; } - if (!key) { - dev_err(se_dev->dev, "invalid argument key"); - return -EINVAL; + if (key) { + if (!ctx->slot || (ctx->slot && + ctx->slot->slot_num == ssk_slot.slot_num)) { + pslot = tegra_se_alloc_key_slot(); + if (!pslot) { + dev_err(se_dev->dev, "no free key slot\n"); + return -ENOMEM; + } + ctx->slot = pslot; + } + ctx->keylen = keylen; + } else { + tegra_se_free_key_slot(ctx->slot); + ctx->slot = &ssk_slot; + ctx->keylen = AES_KEYSIZE_128; } - ctx->keylen = keylen; - pbuf = dma_alloc_coherent(se_dev->dev, TEGRA_SE_AES_BLOCK_SIZE, &pbuf_adr, GFP_KERNEL); if (!pbuf) { @@ -1492,7 +1507,6 @@ out: pbuf, pbuf_adr); } - return 0; } @@ -1508,19 +1522,6 @@ int tegra_se_aes_cmac_finup(struct ahash_request *req) int tegra_se_aes_cmac_cra_init(struct crypto_tfm *tfm) { - struct tegra_se_dev *se_dev = sg_tegra_se_dev; - struct tegra_se_aes_cmac_context *ctx = crypto_tfm_ctx(tfm); - struct tegra_se_slot *pslot; - - if (!ctx->slot) { - pslot = tegra_se_alloc_key_slot(); - if (!pslot) { - dev_err(se_dev->dev, "no free key slot\n"); - return -ENOMEM; - } - ctx->slot = pslot; - } - crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct tegra_se_aes_cmac_context)); @@ -1537,7 +1538,7 @@ void tegra_se_aes_cmac_cra_exit(struct crypto_tfm *tfm) static struct crypto_alg aes_algs[] = { { .cra_name = "cbc(aes)", - .cra_driver_name = "tegra-se-aes-cbc", + .cra_driver_name = "cbc-aes-tegra", .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TEGRA_SE_AES_BLOCK_SIZE, @@ -1557,7 +1558,7 @@ static struct crypto_alg aes_algs[] = { } }, { .cra_name = "ecb(aes)", - .cra_driver_name = "tegra-se-aes-ecb", + .cra_driver_name = "ecb-aes-tegra", .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TEGRA_SE_AES_BLOCK_SIZE, @@ -1577,7 +1578,7 @@ static struct crypto_alg aes_algs[] = { } }, { .cra_name = "ctr(aes)", - .cra_driver_name = "tegra-se-aes-ctr", + .cra_driver_name = "ctr-aes-tegra", .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TEGRA_SE_AES_BLOCK_SIZE, @@ -1598,7 +1599,7 @@ static struct crypto_alg aes_algs[] = { } }, { .cra_name = "ofb(aes)", - .cra_driver_name = "tegra-se-aes-ofb", + .cra_driver_name = "ofb-aes-tegra", .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = TEGRA_SE_AES_BLOCK_SIZE, @@ -1619,7 +1620,7 @@ static struct crypto_alg aes_algs[] = { } }, { .cra_name = "ansi_cprng", - .cra_driver_name = "tegra_ansi_cprng", + .cra_driver_name = "rng-aes-tegra", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_RNG, .cra_ctxsize = sizeof(struct tegra_se_rng_context), |