#include <linux/vmalloc.h>
#include <linux/sw842.h>
#include <linux/ratelimit.h>
+#include <linux/spinlock.h>
#include "nx-842.h"
}
struct nx842_crypto_ctx {
+ spinlock_t lock;
+
u8 *wmem;
u8 *sbounce, *dbounce;
{
struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
+ spin_lock_init(&ctx->lock);
ctx->wmem = kmalloc(nx842_workmem_size(), GFP_KERNEL);
ctx->sbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
DIV_ROUND_UP(p.iremain, c.maximum));
hdrsize = NX842_CRYPTO_HEADER_SIZE(groups);
+ spin_lock_bh(&ctx->lock);
+
/* skip adding header if the buffers meet all constraints */
add_header = (p.iremain % c.multiple ||
p.iremain < c.minimum ||
while (p.iremain > 0) {
n = hdr->groups++;
+ ret = -ENOSPC;
if (hdr->groups > NX842_CRYPTO_GROUP_MAX)
- return -ENOSPC;
+ goto unlock;
/* header goes before first group */
h = !n && add_header ? hdrsize : 0;
ret = compress(ctx, &p, &hdr->group[n], &c, &ignore, h);
if (ret)
- return ret;
+ goto unlock;
}
if (!add_header && hdr->groups > 1) {
pr_err("Internal error: No header but multiple groups\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
/* ignore indicates the input stream needed to be padded */
if (add_header)
ret = nx842_crypto_add_header(hdr, dst);
if (ret)
- return ret;
+ goto unlock;
*dlen = p.ototal;
pr_debug("compress total slen %x dlen %x\n", slen, *dlen);
- return 0;
+unlock:
+ spin_unlock_bh(&ctx->lock);
+ return ret;
}
static int decompress(struct nx842_crypto_ctx *ctx,
hdr = (struct nx842_crypto_header *)src;
+ spin_lock_bh(&ctx->lock);
+
/* If it doesn't start with our header magic number, assume it's a raw
* 842 compressed buffer and pass it directly to the hardware driver
*/
ret = decompress(ctx, &p, &g, &c, 0, usehw);
if (ret)
- return ret;
+ goto unlock;
*dlen = p.ototal;
- return 0;
+ ret = 0;
+ goto unlock;
}
if (!hdr->groups) {
pr_err("header has no groups\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
if (hdr->groups > NX842_CRYPTO_GROUP_MAX) {
pr_err("header has too many groups %x, max %x\n",
hdr->groups, NX842_CRYPTO_GROUP_MAX);
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
hdr_len = NX842_CRYPTO_HEADER_SIZE(hdr->groups);
- if (hdr_len > slen)
- return -EOVERFLOW;
+ if (hdr_len > slen) {
+ ret = -EOVERFLOW;
+ goto unlock;
+ }
memcpy(&ctx->header, src, hdr_len);
hdr = &ctx->header;
ret = decompress(ctx, &p, &hdr->group[n], &c, ignore, usehw);
if (ret)
- return ret;
+ goto unlock;
}
*dlen = p.ototal;
pr_debug("decompress total slen %x dlen %x\n", slen, *dlen);
- return 0;
+ ret = 0;
+
+unlock:
+ spin_unlock_bh(&ctx->lock);
+
+ return ret;
}
static struct crypto_alg alg = {