summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2011-03-29 16:23:23 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-04-01 19:24:30 -0700
commit87f5fb73c936229d2fd8c99a50fca296ed372554 (patch)
treec8698d8af951d57f5f0bc29790f60d7ebc157eb4
parentcc733bbc1ec1a353750694effa3efb6b58bbee97 (diff)
crypto: tegra-aes: reclaim key slot in cra_exit
clients call the algorithm's close api, which results in the algo's cra_exit getting called, when they are done using the hardware. we need to free the key slot which was being used by the client when its cra_exit is called. Change-Id: Ib42d445f5068c4ea1ef6b3edbbc547fe9eeef583 Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/24673 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--drivers/crypto/tegra-aes.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c
index c330a94b9e89..c56d87c18118 100644
--- a/drivers/crypto/tegra-aes.c
+++ b/drivers/crypto/tegra-aes.c
@@ -183,6 +183,7 @@ struct tegra_aes_ctx {
struct tegra_aes_dev *dd;
unsigned long flags;
struct tegra_aes_slot *slot;
+ u8 key[AES_MAX_KEY_SIZE];
int keylen;
};
@@ -326,11 +327,11 @@ static int aes_start_crypt(struct tegra_aes_dev *dd, u32 in_addr, u32 out_addr,
return 0;
}
-static void aes_release_key_slot(struct tegra_aes_dev *dd)
+static void aes_release_key_slot(struct tegra_aes_ctx *ctx)
{
spin_lock(&list_lock);
- dd->ctx->slot->available = true;
- dd->ctx->slot = NULL;
+ ctx->slot->available = true;
+ ctx->slot = NULL;
spin_unlock(&list_lock);
}
@@ -486,12 +487,14 @@ static int tegra_aes_handle_req(struct tegra_aes_dev *dd)
/* assign new context to device */
ctx->dd = dd;
- if (dd->ctx != ctx)
- dd->ctx = ctx;
+ dd->ctx = ctx;
- if (dd->flags & FLAGS_NEW_KEY) {
+ if (ctx->flags & FLAGS_NEW_KEY) {
+ /* copy the key */
+ memset(dd->ivkey_base, 0, AES_HW_KEY_TABLE_LENGTH_BYTES);
+ memcpy(dd->ivkey_base, ctx->key, ctx->keylen);
aes_set_key(dd);
- dd->flags &= ~FLAGS_NEW_KEY;
+ ctx->flags &= ~FLAGS_NEW_KEY;
}
if ((dd->flags & FLAGS_CBC) && dd->iv) {
@@ -583,27 +586,23 @@ static int tegra_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
dev_dbg(dd->dev, "keylen: %d\n", keylen);
ctx->dd = dd;
- dd->ctx = ctx;
-
- if (ctx->slot)
- aes_release_key_slot(dd);
if (key) {
- key_slot = aes_find_key_slot(dd);
- if (!key_slot) {
- dev_err(dd->dev, "no empty slot\n");
- return -ENOMEM;
+ if (!ctx->slot) {
+ key_slot = aes_find_key_slot(dd);
+ if (!key_slot) {
+ dev_err(dd->dev, "no empty slot\n");
+ return -ENOMEM;
+ }
+
+ ctx->slot = key_slot;
}
- ctx->slot = key_slot;
+ memcpy(ctx->key, key, keylen);
ctx->keylen = keylen;
-
- /* copy the key */
- memset(dd->ivkey_base, 0, AES_HW_KEY_TABLE_LENGTH_BYTES);
- memcpy(dd->ivkey_base, key, keylen);
}
- dd->flags |= FLAGS_NEW_KEY;
+ ctx->flags |= FLAGS_NEW_KEY;
dev_dbg(dd->dev, "done\n");
return 0;
}
@@ -848,6 +847,14 @@ static int tegra_aes_cra_init(struct crypto_tfm *tfm)
return 0;
}
+void tegra_aes_cra_exit(struct crypto_tfm *tfm)
+{
+ struct tegra_aes_ctx *ctx = crypto_ablkcipher_ctx((struct crypto_ablkcipher *)tfm);
+
+ if (ctx && ctx->slot)
+ aes_release_key_slot(ctx);
+}
+
static struct crypto_alg algs[] = {
{
.cra_name = "disabled_ecb(aes)",
@@ -860,6 +867,7 @@ static struct crypto_alg algs[] = {
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = tegra_aes_cra_init,
+ .cra_exit = tegra_aes_cra_exit,
.cra_u.ablkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
@@ -878,6 +886,7 @@ static struct crypto_alg algs[] = {
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = tegra_aes_cra_init,
+ .cra_exit = tegra_aes_cra_exit,
.cra_u.ablkcipher = {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
@@ -895,6 +904,7 @@ static struct crypto_alg algs[] = {
.cra_type = &crypto_rng_type,
.cra_module = THIS_MODULE,
.cra_init = tegra_aes_cra_init,
+ .cra_exit = tegra_aes_cra_exit,
.cra_u.rng = {
.rng_make_random = tegra_aes_get_random,
.rng_reset = tegra_aes_rng_reset,