aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSandeep Nair2013-07-10 18:20:21 -0500
committerMurali Karicheri2014-12-03 10:51:23 -0600
commit703ecb1f3919fca2af64204767d11c371cb66c31 (patch)
tree286c4df067ec1dd04f8ecca5df90d749dfb5abda
parentc95655622816ccea66879d5111d38c83c1691adc (diff)
downloadlinux-703ecb1f3919fca2af64204767d11c371cb66c31.tar.gz
linux-703ecb1f3919fca2af64204767d11c371cb66c31.tar.xz
linux-703ecb1f3919fca2af64204767d11c371cb66c31.zip
crypto: keystone: Fix security context teardown procedure
After initiating a security context teardown, host should wait until the ownership flag is cleared by CP_ACE. Non-compliance to this procedure could create race condition when the same SCID is reused for a new context. Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
-rw-r--r--drivers/crypto/keystone-sa.c34
-rw-r--r--drivers/crypto/keystone-sa.h6
2 files changed, 37 insertions, 3 deletions
diff --git a/drivers/crypto/keystone-sa.c b/drivers/crypto/keystone-sa.c
index b59cb1f3a49..bba1025ff81 100644
--- a/drivers/crypto/keystone-sa.c
+++ b/drivers/crypto/keystone-sa.c
@@ -2015,7 +2015,7 @@ static int sa_init_sc(struct sa_ctx_info *ctx, const u8 *enc_key,
2015 php_f = php_e = SA_CTX_DMA_SIZE_64; 2015 php_f = php_e = SA_CTX_DMA_SIZE_64;
2016 2016
2017 /* SCCTL Owner info: 0=host, 1=CP_ACE */ 2017 /* SCCTL Owner info: 0=host, 1=CP_ACE */
2018 sc_buf[0] = 0; 2018 sc_buf[SA_CTX_SCCTL_OWNER_OFFSET] = 0;
2019 /* SCCTL F/E control */ 2019 /* SCCTL F/E control */
2020 sc_buf[1] = SA_CTX_SCCTL_MK_DMA_INFO(php_f, eng0_f, eng1_f, php_e); 2020 sc_buf[1] = SA_CTX_SCCTL_MK_DMA_INFO(php_f, eng0_f, eng1_f, php_e);
2021 memcpy(&sc_buf[2], &sc_id, 2); /*(optional) 2021 memcpy(&sc_buf[2], &sc_id, 2); /*(optional)
@@ -2045,7 +2045,7 @@ static int sa_init_sc(struct sa_ctx_info *ctx, const u8 *enc_key,
2045 } 2045 }
2046 2046
2047 /* Set the ownership of context to CP_ACE */ 2047 /* Set the ownership of context to CP_ACE */
2048 sc_buf[0] = 0x80; 2048 sc_buf[SA_CTX_SCCTL_OWNER_OFFSET] = 0x80;
2049 2049
2050 /* swizzle the security context */ 2050 /* swizzle the security context */
2051 sa_swiz_128(sc_buf, sc_buf, SA_CTX_MAX_SZ); 2051 sa_swiz_128(sc_buf, sc_buf, SA_CTX_MAX_SZ);
@@ -2077,17 +2077,20 @@ static int sa_init_sc(struct sa_ctx_info *ctx, const u8 *enc_key,
2077} 2077}
2078 2078
2079/* Tear down the Security Context */ 2079/* Tear down the Security Context */
2080#define SA_SC_TEAR_RETRIES 5
2081#define SA_SC_TEAR_DELAY 20 /* msecs */
2080static int sa_tear_sc(struct sa_ctx_info *ctx, 2082static int sa_tear_sc(struct sa_ctx_info *ctx,
2081 struct keystone_crypto_data *pdata) 2083 struct keystone_crypto_data *pdata)
2082{ 2084{
2085 int own_off, cnt = SA_SC_TEAR_RETRIES;
2083 struct dma_async_tx_descriptor *desc; 2086 struct dma_async_tx_descriptor *desc;
2084 struct sa_dma_req_ctx *dma_ctx; 2087 struct sa_dma_req_ctx *dma_ctx;
2085 struct sa_swinfo swinfo; 2088 struct sa_swinfo swinfo;
2086 dma_cookie_t cookie; 2089 dma_cookie_t cookie;
2087 unsigned long flags; 2090 unsigned long flags;
2088 u16 queue_id; 2091 u16 queue_id;
2089 u8 flow_id;
2090 int ret = 0; 2092 int ret = 0;
2093 u8 flow_id;
2091 2094
2092 dma_ctx = kmalloc(sizeof(struct sa_dma_req_ctx), 0); 2095 dma_ctx = kmalloc(sizeof(struct sa_dma_req_ctx), 0);
2093 if (!dma_ctx) 2096 if (!dma_ctx)
@@ -2152,6 +2155,22 @@ static int sa_tear_sc(struct sa_ctx_info *ctx,
2152 ret = -ENXIO; 2155 ret = -ENXIO;
2153 goto err; 2156 goto err;
2154 } 2157 }
2158
2159 /*
2160 * Check that CP_ACE has released the context
2161 * by making sure that the owner bit is 0
2162 */
2163 /*
2164 * Security context had been swizzled by 128 bits
2165 * before handing to CP_ACE
2166 */
2167 own_off = ((SA_CTX_SCCTL_OWNER_OFFSET/16) * 16)
2168 + (15 - (SA_CTX_SCCTL_OWNER_OFFSET % 16));
2169 while (__raw_readb(&ctx->sc[own_off])) {
2170 if (!--cnt)
2171 return -EAGAIN;
2172 msleep_interruptible(SA_SC_TEAR_DELAY);
2173 }
2155 return 0; 2174 return 0;
2156 2175
2157err: 2176err:
@@ -2184,6 +2203,7 @@ static void sa_free_ctx_info
2184 if (sa_tear_sc(ctx, data)) { 2203 if (sa_tear_sc(ctx, data)) {
2185 dev_err(keystone_dev, 2204 dev_err(keystone_dev,
2186 "Failed to tear down context id(%x)\n", ctx->sc_id); 2205 "Failed to tear down context id(%x)\n", ctx->sc_id);
2206 return;
2187 } 2207 }
2188 2208
2189 bn = ctx->sc_id - data->sc_id_start; 2209 bn = ctx->sc_id - data->sc_id_start;
@@ -2284,6 +2304,9 @@ static int sa_init_tfm(struct crypto_tfm *tfm)
2284 } 2304 }
2285 } 2305 }
2286 2306
2307 dev_dbg(keystone_dev, "%s(0x%p) sc-ids(0x%x(0x%x), 0x%x(0x%x))\n",
2308 __func__, tfm, ctx->enc.sc_id, ctx->enc.sc_phys,
2309 ctx->dec.sc_id, ctx->dec.sc_phys);
2287 return 0; 2310 return 0;
2288} 2311}
2289 2312
@@ -2312,6 +2335,10 @@ static void sa_exit_tfm(struct crypto_tfm *tfm)
2312 struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm); 2335 struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
2313 struct keystone_crypto_data *data = dev_get_drvdata(keystone_dev); 2336 struct keystone_crypto_data *data = dev_get_drvdata(keystone_dev);
2314 2337
2338 dev_dbg(keystone_dev, "%s(0x%p) sc-ids(0x%x(0x%x), 0x%x(0x%x))\n",
2339 __func__, tfm, ctx->enc.sc_id, ctx->enc.sc_phys,
2340 ctx->dec.sc_id, ctx->dec.sc_phys);
2341
2315 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) 2342 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK)
2316 == CRYPTO_ALG_TYPE_AEAD) { 2343 == CRYPTO_ALG_TYPE_AEAD) {
2317 sa_free_ctx_info(&ctx->enc, data); 2344 sa_free_ctx_info(&ctx->enc, data);
@@ -3084,6 +3111,7 @@ static int keystone_crypto_remove(struct platform_device *pdev)
3084 3111
3085 /* un-register crypto algorithms */ 3112 /* un-register crypto algorithms */
3086 sa_unregister_algos(&pdev->dev); 3113 sa_unregister_algos(&pdev->dev);
3114 dma_pool_destroy(crypto->sc_pool);
3087 clk_disable_unprepare(crypto->clk); 3115 clk_disable_unprepare(crypto->clk);
3088 clk_put(crypto->clk); 3116 clk_put(crypto->clk);
3089 kfree(crypto); 3117 kfree(crypto);
diff --git a/drivers/crypto/keystone-sa.h b/drivers/crypto/keystone-sa.h
index 5e6420f7a18..a390892485c 100644
--- a/drivers/crypto/keystone-sa.h
+++ b/drivers/crypto/keystone-sa.h
@@ -214,6 +214,12 @@ typedef u8 SA_CTX_PE_PKT_TYPE_T;
214 ((php_e) << 6)) 214 ((php_e) << 6))
215 215
216/* 216/*
217 * Byte offset of the owner word in SCCTL
218 * in the security context
219 */
220#define SA_CTX_SCCTL_OWNER_OFFSET 0
221
222/*
217 * Assumption: CTX size is mutiple of 32 223 * Assumption: CTX size is mutiple of 32
218 */ 224 */
219#define SA_CTX_SIZE_TO_DMA_SIZE(ctx_sz) \ 225#define SA_CTX_SIZE_TO_DMA_SIZE(ctx_sz) \