Commit a23a334b authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (34 commits)
  crypto: caam - ablkcipher support
  crypto: caam - faster aead implementation
  crypto: caam - structure renaming
  crypto: caam - shorter names
  crypto: talitos - don't bad_key in ablkcipher setkey
  crypto: talitos - remove unused giv from ablkcipher methods
  crypto: talitos - don't set done notification in hot path
  crypto: talitos - ensure request ordering within a single tfm
  crypto: gf128mul - fix call to memset()
  crypto: s390 - support hardware accelerated SHA-224
  crypto: algif_hash - Handle initial af_alg_make_sg error correctly
  crypto: sha1_generic - use SHA1_BLOCK_SIZE
  hwrng: ppc4xx - add support for ppc4xx TRNG
  crypto: crypto4xx - Perform read/modify/write on device control register
  crypto: caam - fix build warning when DEBUG_FS not configured
  crypto: arc4 - Fixed coding style issues
  crypto: crc32c - Fixed coding style issue
  crypto: omap-sham - do not schedule tasklet if there is no active requests
  crypto: omap-sham - clear device flags when finishing request
  crypto: omap-sham - irq handler must not clear error code
  ...
parents a6422850 acdca31d
/* /*
* Cryptographic API. * Cryptographic API.
* *
* s390 implementation of the SHA256 Secure Hash Algorithm. * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm.
* *
* s390 Version: * s390 Version:
* Copyright IBM Corp. 2005,2007 * Copyright IBM Corp. 2005,2011
* Author(s): Jan Glauber (jang@de.ibm.com) * Author(s): Jan Glauber (jang@de.ibm.com)
* *
* Derived from "crypto/sha256_generic.c"
* and "arch/s390/crypto/sha1_s390.c"
*
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free * under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) * Software Foundation; either version 2 of the License, or (at your option)
...@@ -65,7 +62,7 @@ static int sha256_import(struct shash_desc *desc, const void *in) ...@@ -65,7 +62,7 @@ static int sha256_import(struct shash_desc *desc, const void *in)
return 0; return 0;
} }
static struct shash_alg alg = { static struct shash_alg sha256_alg = {
.digestsize = SHA256_DIGEST_SIZE, .digestsize = SHA256_DIGEST_SIZE,
.init = sha256_init, .init = sha256_init,
.update = s390_sha_update, .update = s390_sha_update,
...@@ -84,22 +81,69 @@ static struct shash_alg alg = { ...@@ -84,22 +81,69 @@ static struct shash_alg alg = {
} }
}; };
static int sha256_s390_init(void) static int sha224_init(struct shash_desc *desc)
{ {
struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
sctx->state[0] = SHA224_H0;
sctx->state[1] = SHA224_H1;
sctx->state[2] = SHA224_H2;
sctx->state[3] = SHA224_H3;
sctx->state[4] = SHA224_H4;
sctx->state[5] = SHA224_H5;
sctx->state[6] = SHA224_H6;
sctx->state[7] = SHA224_H7;
sctx->count = 0;
sctx->func = KIMD_SHA_256;
return 0;
}
static struct shash_alg sha224_alg = {
.digestsize = SHA224_DIGEST_SIZE,
.init = sha224_init,
.update = s390_sha_update,
.final = s390_sha_final,
.export = sha256_export,
.import = sha256_import,
.descsize = sizeof(struct s390_sha_ctx),
.statesize = sizeof(struct sha256_state),
.base = {
.cra_name = "sha224",
.cra_driver_name= "sha224-s390",
.cra_priority = CRYPT_S390_PRIORITY,
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
.cra_blocksize = SHA224_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
};
static int __init sha256_s390_init(void)
{
int ret;
if (!crypt_s390_func_available(KIMD_SHA_256, CRYPT_S390_MSA)) if (!crypt_s390_func_available(KIMD_SHA_256, CRYPT_S390_MSA))
return -EOPNOTSUPP; return -EOPNOTSUPP;
ret = crypto_register_shash(&sha256_alg);
return crypto_register_shash(&alg); if (ret < 0)
goto out;
ret = crypto_register_shash(&sha224_alg);
if (ret < 0)
crypto_unregister_shash(&sha256_alg);
out:
return ret;
} }
static void __exit sha256_s390_fini(void) static void __exit sha256_s390_fini(void)
{ {
crypto_unregister_shash(&alg); crypto_unregister_shash(&sha224_alg);
crypto_unregister_shash(&sha256_alg);
} }
module_init(sha256_s390_init); module_init(sha256_s390_init);
module_exit(sha256_s390_fini); module_exit(sha256_s390_fini);
MODULE_ALIAS("sha256"); MODULE_ALIAS("sha256");
MODULE_ALIAS("sha224");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm"); MODULE_DESCRIPTION("SHA256 and SHA224 Secure Hash Algorithm");
...@@ -245,7 +245,7 @@ static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key, ...@@ -245,7 +245,7 @@ static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
crypto_ahash_set_flags(tfm, crypto_ahash_get_flags(child) crypto_ahash_set_flags(tfm, crypto_ahash_get_flags(child)
& CRYPTO_TFM_RES_MASK); & CRYPTO_TFM_RES_MASK);
return 0; return err;
} }
static int ghash_async_init_tfm(struct crypto_tfm *tfm) static int ghash_async_init_tfm(struct crypto_tfm *tfm)
......
...@@ -458,7 +458,7 @@ config CRYPTO_WP512 ...@@ -458,7 +458,7 @@ config CRYPTO_WP512
config CRYPTO_GHASH_CLMUL_NI_INTEL config CRYPTO_GHASH_CLMUL_NI_INTEL
tristate "GHASH digest algorithm (CLMUL-NI accelerated)" tristate "GHASH digest algorithm (CLMUL-NI accelerated)"
depends on (X86 || UML_X86) && 64BIT depends on X86 && 64BIT
select CRYPTO_SHASH select CRYPTO_SHASH
select CRYPTO_CRYPTD select CRYPTO_CRYPTD
help help
...@@ -533,7 +533,7 @@ config CRYPTO_AES_X86_64 ...@@ -533,7 +533,7 @@ config CRYPTO_AES_X86_64
config CRYPTO_AES_NI_INTEL config CRYPTO_AES_NI_INTEL
tristate "AES cipher algorithms (AES-NI)" tristate "AES cipher algorithms (AES-NI)"
depends on (X86 || UML_X86) depends on X86
select CRYPTO_AES_X86_64 if 64BIT select CRYPTO_AES_X86_64 if 64BIT
select CRYPTO_AES_586 if !64BIT select CRYPTO_AES_586 if !64BIT
select CRYPTO_CRYPTD select CRYPTO_CRYPTD
......
...@@ -68,8 +68,10 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock, ...@@ -68,8 +68,10 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
int newlen; int newlen;
newlen = af_alg_make_sg(&ctx->sgl, from, len, 0); newlen = af_alg_make_sg(&ctx->sgl, from, len, 0);
if (newlen < 0) if (newlen < 0) {
err = copied ? 0 : newlen;
goto unlock; goto unlock;
}
ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL, ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL,
newlen); newlen);
......
/* /*
* Cryptographic API * Cryptographic API
* *
* ARC4 Cipher Algorithm * ARC4 Cipher Algorithm
...@@ -33,16 +33,15 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, ...@@ -33,16 +33,15 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key,
ctx->x = 1; ctx->x = 1;
ctx->y = 0; ctx->y = 0;
for(i = 0; i < 256; i++) for (i = 0; i < 256; i++)
ctx->S[i] = i; ctx->S[i] = i;
for(i = 0; i < 256; i++) for (i = 0; i < 256; i++) {
{
u8 a = ctx->S[i]; u8 a = ctx->S[i];
j = (j + in_key[k] + a) & 0xff; j = (j + in_key[k] + a) & 0xff;
ctx->S[i] = ctx->S[j]; ctx->S[i] = ctx->S[j];
ctx->S[j] = a; ctx->S[j] = a;
if(++k >= key_len) if (++k >= key_len)
k = 0; k = 0;
} }
...@@ -80,9 +79,9 @@ static struct crypto_alg arc4_alg = { ...@@ -80,9 +79,9 @@ static struct crypto_alg arc4_alg = {
.cra_u = { .cipher = { .cra_u = { .cipher = {
.cia_min_keysize = ARC4_MIN_KEY_SIZE, .cia_min_keysize = ARC4_MIN_KEY_SIZE,
.cia_max_keysize = ARC4_MAX_KEY_SIZE, .cia_max_keysize = ARC4_MAX_KEY_SIZE,
.cia_setkey = arc4_set_key, .cia_setkey = arc4_set_key,
.cia_encrypt = arc4_crypt, .cia_encrypt = arc4_crypt,
.cia_decrypt = arc4_crypt } } .cia_decrypt = arc4_crypt } }
}; };
static int __init arc4_init(void) static int __init arc4_init(void)
......
...@@ -224,11 +224,11 @@ static int crc32c_cra_init(struct crypto_tfm *tfm) ...@@ -224,11 +224,11 @@ static int crc32c_cra_init(struct crypto_tfm *tfm)
static struct shash_alg alg = { static struct shash_alg alg = {
.digestsize = CHKSUM_DIGEST_SIZE, .digestsize = CHKSUM_DIGEST_SIZE,
.setkey = chksum_setkey, .setkey = chksum_setkey,
.init = chksum_init, .init = chksum_init,
.update = chksum_update, .update = chksum_update,
.final = chksum_final, .final = chksum_final,
.finup = chksum_finup, .finup = chksum_finup,
.digest = chksum_digest, .digest = chksum_digest,
.descsize = sizeof(struct chksum_desc_ctx), .descsize = sizeof(struct chksum_desc_ctx),
.base = { .base = {
.cra_name = "crc32c", .cra_name = "crc32c",
......
...@@ -182,7 +182,7 @@ void gf128mul_lle(be128 *r, const be128 *b) ...@@ -182,7 +182,7 @@ void gf128mul_lle(be128 *r, const be128 *b)
for (i = 0; i < 7; ++i) for (i = 0; i < 7; ++i)
gf128mul_x_lle(&p[i + 1], &p[i]); gf128mul_x_lle(&p[i + 1], &p[i]);
memset(r, 0, sizeof(r)); memset(r, 0, sizeof(*r));
for (i = 0;;) { for (i = 0;;) {
u8 ch = ((u8 *)b)[15 - i]; u8 ch = ((u8 *)b)[15 - i];
...@@ -220,7 +220,7 @@ void gf128mul_bbe(be128 *r, const be128 *b) ...@@ -220,7 +220,7 @@ void gf128mul_bbe(be128 *r, const be128 *b)
for (i = 0; i < 7; ++i) for (i = 0; i < 7; ++i)
gf128mul_x_bbe(&p[i + 1], &p[i]); gf128mul_x_bbe(&p[i + 1], &p[i]);
memset(r, 0, sizeof(r)); memset(r, 0, sizeof(*r));
for (i = 0;;) { for (i = 0;;) {
u8 ch = ((u8 *)b)[i]; u8 ch = ((u8 *)b)[i];
......
...@@ -43,25 +43,26 @@ static int sha1_update(struct shash_desc *desc, const u8 *data, ...@@ -43,25 +43,26 @@ static int sha1_update(struct shash_desc *desc, const u8 *data,
unsigned int partial, done; unsigned int partial, done;
const u8 *src; const u8 *src;
partial = sctx->count & 0x3f; partial = sctx->count % SHA1_BLOCK_SIZE;
sctx->count += len; sctx->count += len;
done = 0; done = 0;
src = data; src = data;
if ((partial + len) > 63) { if ((partial + len) >= SHA1_BLOCK_SIZE) {
u32 temp[SHA_WORKSPACE_WORDS]; u32 temp[SHA_WORKSPACE_WORDS];
if (partial) { if (partial) {
done = -partial; done = -partial;
memcpy(sctx->buffer + partial, data, done + 64); memcpy(sctx->buffer + partial, data,
done + SHA1_BLOCK_SIZE);
src = sctx->buffer; src = sctx->buffer;
} }
do { do {
sha_transform(sctx->state, src, temp); sha_transform(sctx->state, src, temp);
done += 64; done += SHA1_BLOCK_SIZE;
src = data + done; src = data + done;
} while (done + 63 < len); } while (done + SHA1_BLOCK_SIZE <= len);
memset(temp, 0, sizeof(temp)); memset(temp, 0, sizeof(temp));
partial = 0; partial = 0;
......
This diff is collapsed.
...@@ -210,3 +210,15 @@ config HW_RANDOM_PICOXCELL ...@@ -210,3 +210,15 @@ config HW_RANDOM_PICOXCELL
module will be called picoxcell-rng. module will be called picoxcell-rng.
If unsure, say Y. If unsure, say Y.
config HW_RANDOM_PPC4XX
tristate "PowerPC 4xx generic true random number generator support"
depends on HW_RANDOM && PPC && 4xx
---help---
This driver provides the kernel-side support for the TRNG hardware
found in the security function of some PowerPC 4xx SoCs.
To compile this driver as a module, choose M here: the
module will be called ppc4xx-rng.
If unsure, say N.
...@@ -20,3 +20,4 @@ obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o ...@@ -20,3 +20,4 @@ obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
...@@ -55,7 +55,7 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id) ...@@ -55,7 +55,7 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
ret = amba_request_regions(dev, dev->dev.init_name); ret = amba_request_regions(dev, dev->dev.init_name);
if (ret) if (ret)
return ret; goto out_clk;
ret = -ENOMEM; ret = -ENOMEM;
base = ioremap(dev->res.start, resource_size(&dev->res)); base = ioremap(dev->res.start, resource_size(&dev->res));
if (!base) if (!base)
...@@ -70,6 +70,7 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id) ...@@ -70,6 +70,7 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
iounmap(base); iounmap(base);
out_release: out_release:
amba_release_regions(dev); amba_release_regions(dev);
out_clk:
clk_disable(rng_clk); clk_disable(rng_clk);
clk_put(rng_clk); clk_put(rng_clk);
return ret; return ret;
......
...@@ -113,8 +113,10 @@ static int __devinit omap_rng_probe(struct platform_device *pdev) ...@@ -113,8 +113,10 @@ static int __devinit omap_rng_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) if (!res) {
return -ENOENT; ret = -ENOENT;
goto err_region;
}
if (!request_mem_region(res->start, resource_size(res), pdev->name)) { if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
ret = -EBUSY; ret = -EBUSY;
......
/*
* Generic PowerPC 44x RNG driver
*
* Copyright 2011 IBM Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2 of the License.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
#include <linux/of_platform.h>
#include <asm/io.h>
#define PPC4XX_TRNG_DEV_CTRL 0x60080
#define PPC4XX_TRNGE 0x00020000
#define PPC4XX_TRNG_CTRL 0x0008
#define PPC4XX_TRNG_CTRL_DALM 0x20
#define PPC4XX_TRNG_STAT 0x0004
#define PPC4XX_TRNG_STAT_B 0x1
#define PPC4XX_TRNG_DATA 0x0000
#define MODULE_NAME "ppc4xx_rng"
static int ppc4xx_rng_data_present(struct hwrng *rng, int wait)
{
void __iomem *rng_regs = (void __iomem *) rng->priv;
int busy, i, present = 0;
for (i = 0; i < 20; i++) {
busy = (in_le32(rng_regs + PPC4XX_TRNG_STAT) & PPC4XX_TRNG_STAT_B);
if (!busy || !wait) {
present = 1;
break;
}
udelay(10);
}
return present;
}
static int ppc4xx_rng_data_read(struct hwrng *rng, u32 *data)
{
void __iomem *rng_regs = (void __iomem *) rng->priv;
*data = in_le32(rng_regs + PPC4XX_TRNG_DATA);
return 4;
}
static int ppc4xx_rng_enable(int enable)
{
struct device_node *ctrl;
void __iomem *ctrl_reg;
int err = 0;
u32 val;
/* Find the main crypto device node and map it to turn the TRNG on */
ctrl = of_find_compatible_node(NULL, NULL, "amcc,ppc4xx-crypto");
if (!ctrl)
return -ENODEV;
ctrl_reg = of_iomap(ctrl, 0);
if (!ctrl_reg) {
err = -ENODEV;
goto out;
}
val = in_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL);
if (enable)
val |= PPC4XX_TRNGE;
else
val = val & ~PPC4XX_TRNGE;
out_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL, val);
iounmap(ctrl_reg);
out:
of_node_put(ctrl);
return err;
}
static struct hwrng ppc4xx_rng = {
.name = MODULE_NAME,
.data_present = ppc4xx_rng_data_present,
.data_read = ppc4xx_rng_data_read,
};
static int __devinit ppc4xx_rng_probe(struct platform_device *dev)
{
void __iomem *rng_regs;
int err = 0;
rng_regs = of_iomap(dev->dev.of_node, 0);
if (!rng_regs)
return -ENODEV;
err = ppc4xx_rng_enable(1);
if (err)
return err;
out_le32(rng_regs + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
ppc4xx_rng.priv = (unsigned long) rng_regs;
err = hwrng_register(&ppc4xx_rng);
return err;
}
static int __devexit ppc4xx_rng_remove(struct platform_device *dev)
{
void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv;
hwrng_unregister(&ppc4xx_rng);
ppc4xx_rng_enable(0);
iounmap(rng_regs);
return 0;
}
static struct of_device_id ppc4xx_rng_match[] = {
{ .compatible = "ppc4xx-rng", },
{ .compatible = "amcc,ppc460ex-rng", },
{ .compatible = "amcc,ppc440epx-rng", },
{},
};
static struct platform_driver ppc4xx_rng_driver = {
.driver = {
.name = MODULE_NAME,
.owner = THIS_MODULE,
.of_match_table = ppc4xx_rng_match,
},
.probe = ppc4xx_rng_probe,
.remove = ppc4xx_rng_remove,
};
static int __init ppc4xx_rng_init(void)
{
return platform_driver_register(&ppc4xx_rng_driver);
}
module_init(ppc4xx_rng_init);
static void __exit ppc4xx_rng_exit(void)
{
platform_driver_unregister(&ppc4xx_rng_driver);
}
module_exit(ppc4xx_rng_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>");
MODULE_DESCRIPTION("HW RNG driver for PPC 4xx processors");
...@@ -100,8 +100,7 @@ static int __devinit timeriomem_rng_probe(struct platform_device *pdev) ...@@ -100,8 +100,7 @@ static int __devinit timeriomem_rng_probe(struct platform_device *pdev)
timeriomem_rng_data = pdev->dev.platform_data; timeriomem_rng_data = pdev->dev.platform_data;
timeriomem_rng_data->address = ioremap(res->start, timeriomem_rng_data->address = ioremap(res->start, resource_size(res));
res->end - res->start + 1);
if (!timeriomem_rng_data->address) if (!timeriomem_rng_data->address)
return -EIO; return -EIO;
......
...@@ -51,6 +51,7 @@ static void crypto4xx_hw_init(struct crypto4xx_device *dev) ...@@ -51,6 +51,7 @@ static void crypto4xx_hw_init(struct crypto4xx_device *dev)
union ce_io_threshold io_threshold; union ce_io_threshold io_threshold;
u32 rand_num; u32 rand_num;
union ce_pe_dma_cfg pe_dma_cfg; union ce_pe_dma_cfg pe_dma_cfg;
u32 device_ctrl;
writel(PPC4XX_BYTE_ORDER, dev->ce_base + CRYPTO4XX_BYTE_ORDER_CFG); writel(PPC4XX_BYTE_ORDER, dev->ce_base + CRYPTO4XX_BYTE_ORDER_CFG);
/* setup pe dma, include reset sg, pdr and pe, then release reset */ /* setup pe dma, include reset sg, pdr and pe, then release reset */
...@@ -84,7 +85,9 @@ static void crypto4xx_hw_init(struct crypto4xx_device *dev) ...@@ -84,7 +85,9 @@ static void crypto4xx_hw_init(struct crypto4xx_device *dev)
writel(ring_size.w, dev->ce_base + CRYPTO4XX_RING_SIZE); writel(ring_size.w, dev->ce_base + CRYPTO4XX_RING_SIZE);
ring_ctrl.w = 0; ring_ctrl.w = 0;
writel(ring_ctrl.w, dev->ce_base + CRYPTO4XX_RING_CTRL); writel(ring_ctrl.w, dev->ce_base + CRYPTO4XX_RING_CTRL);
writel(PPC4XX_DC_3DES_EN, dev->ce_base + CRYPTO4XX_DEVICE_CTRL); device_ctrl = readl(dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
device_ctrl |= PPC4XX_DC_3DES_EN;
writel(device_ctrl, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
writel(dev->gdr_pa, dev->ce_base + CRYPTO4XX_GATH_RING_BASE); writel(dev->gdr_pa, dev->ce_base + CRYPTO4XX_GATH_RING_BASE);
writel(dev->sdr_pa, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE); writel(dev->sdr_pa, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE);
part_ring_size.w = 0; part_ring_size.w = 0;
......
This diff is collapsed.
...@@ -31,5 +31,6 @@ ...@@ -31,5 +31,6 @@
#include <crypto/aead.h> #include <crypto/aead.h>
#include <crypto/authenc.h> #include <crypto/authenc.h>
#include <crypto/scatterwalk.h> #include <crypto/scatterwalk.h>
#include <crypto/internal/skcipher.h>
#endif /* !defined(CAAM_COMPAT_H) */ #endif /* !defined(CAAM_COMPAT_H) */
...@@ -52,9 +52,11 @@ static int caam_probe(struct platform_device *pdev) ...@@ -52,9 +52,11 @@ static int caam_probe(struct platform_device *pdev)
struct caam_ctrl __iomem *ctrl; struct caam_ctrl __iomem *ctrl;
struct caam_full __iomem *topregs; struct caam_full __iomem *topregs;
struct caam_drv_private *ctrlpriv; struct caam_drv_private *ctrlpriv;
struct caam_perfmon *perfmon;
struct caam_deco **deco; struct caam_deco **deco;
u32 deconum; u32 deconum;
#ifdef CONFIG_DEBUG_FS
struct caam_perfmon *perfmon;
#endif
ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL); ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
if (!ctrlpriv) if (!ctrlpriv)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define IMMEDIATE (1 << 23) #define IMMEDIATE (1 << 23)
#define CAAM_CMD_SZ sizeof(u32) #define CAAM_CMD_SZ sizeof(u32)
#define CAAM_PTR_SZ sizeof(dma_addr_t) #define CAAM_PTR_SZ sizeof(dma_addr_t)
#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * 64) #define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
#ifdef DEBUG #ifdef DEBUG
#define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\ #define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#define PRINT_POS #define PRINT_POS
#endif #endif
#define SET_OK_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
LDST_SRCDST_WORD_DECOCTRL | \
(LDOFF_CHG_SHARE_OK_PROP << LDST_OFFSET_SHIFT))
#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \ #define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
LDST_SRCDST_WORD_DECOCTRL | \ LDST_SRCDST_WORD_DECOCTRL | \
(LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT)) (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
...@@ -203,3 +206,56 @@ static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \ ...@@ -203,3 +206,56 @@ static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \
append_cmd(desc, immediate); \ append_cmd(desc, immediate); \
} }
APPEND_CMD_RAW_IMM(load, LOAD, u32); APPEND_CMD_RAW_IMM(load, LOAD, u32);
/*
* Append math command. Only the last part of destination and source need to
* be specified
*/
#define APPEND_MATH(op, desc, dest, src_0, src_1, len) \
append_cmd(desc, CMD_MATH | MATH_FUN_##op | MATH_DEST_##dest | \
MATH_SRC0_##src_0 | MATH_SRC1_##src_1 | (u32) (len & MATH_LEN_MASK));
#define append_math_add(desc, dest, src0, src1, len) \
APPEND_MATH(ADD, desc, dest, src0, src1, len)
#define append_math_sub(desc, dest, src0, src1, len) \
APPEND_MATH(SUB, desc, dest, src0, src1, len)
#define append_math_add_c(desc, dest, src0, src1, len) \
APPEND_MATH(ADDC, desc, dest, src0, src1, len)
#define append_math_sub_b(desc, dest, src0, src1, len) \
APPEND_MATH(SUBB, desc, dest, src0, src1, len)
#define append_math_and(desc, dest, src0, src1, len) \
APPEND_MATH(AND, desc, dest, src0, src1, len)
#define append_math_or(desc, dest, src0, src1, len) \
APPEND_MATH(OR, desc, dest, src0, src1, len)
#define append_math_xor(desc, dest, src0, src1, len) \
APPEND_MATH(XOR, desc, dest, src0, src1, len)
#define append_math_lshift(desc, dest, src0, src1, len) \
APPEND_MATH(LSHIFT, desc, dest, src0, src1, len)
#define append_math_rshift(desc, dest, src0, src1, len) \
APPEND_MATH(RSHIFT, desc, dest, src0, src1, len)
/* Exactly one source is IMM. Data is passed in as u32 value */
#define APPEND_MATH_IMM_u32(op, desc, dest, src_0, src_1, data) \
do { \
APPEND_MATH(op, desc, dest, src_0, src_1, CAAM_CMD_SZ); \
append_cmd(desc, data); \
} while (0);
#define append_math_add_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(ADD, desc, dest, src0, src1, data)
#define append_math_sub_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(SUB, desc, dest, src0, src1, data)
#define append_math_add_c_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(ADDC, desc, dest, src0, src1, data)
#define append_math_sub_b_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(SUBB, desc, dest, src0, src1, data)
#define append_math_and_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(AND, desc, dest, src0, src1, data)
#define append_math_or_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(OR, desc, dest, src0, src1, data)
#define append_math_xor_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(XOR, desc, dest, src0, src1, data)
#define append_math_lshift_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(LSHIFT, desc, dest, src0, src1, data)
#define append_math_rshift_imm_u32(desc, dest, src0, src1, data) \
APPEND_MATH_IMM_u32(RSHIFT, desc, dest, src0, src1, data)
This diff is collapsed.
/* /*
* talitos - Freescale Integrated Security Engine (SEC) device driver * talitos - Freescale Integrated Security Engine (SEC) device driver
* *
* Copyright (c) 2008-2010 Freescale Semiconductor, Inc. * Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
* *
* Scatterlist Crypto API glue code copied from files with the following: * Scatterlist Crypto API glue code copied from files with the following:
* Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au> * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
...@@ -282,6 +282,7 @@ static int init_device(struct device *dev) ...@@ -282,6 +282,7 @@ static int init_device(struct device *dev)
/** /**
* talitos_submit - submits a descriptor to the device for processing * talitos_submit - submits a descriptor to the device for processing
* @dev: the SEC device to be used * @dev: the SEC device to be used
* @ch: the SEC device channel to be used
* @desc: the descriptor to be processed by the device * @desc: the descriptor to be processed by the device
* @callback: whom to call when processing is complete * @callback: whom to call when processing is complete
* @context: a handle for use by caller (optional) * @context: a handle for use by caller (optional)
...@@ -290,7 +291,7 @@ static int init_device(struct device *dev) ...@@ -290,7 +291,7 @@ static int init_device(struct device *dev)
* callback must check err and feedback in descriptor header * callback must check err and feedback in descriptor header
* for device processing status. * for device processing status.
*/ */
static int talitos_submit(struct device *dev, struct talitos_desc *desc, static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
void (*callback)(struct device *dev, void (*callback)(struct device *dev,
struct talitos_desc *desc, struct talitos_desc *desc,
void *context, int error), void *context, int error),
...@@ -298,15 +299,9 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc, ...@@ -298,15 +299,9 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc,
{ {
struct talitos_private *priv = dev_get_drvdata(dev); struct talitos_private *priv = dev_get_drvdata(dev);
struct talitos_request *request; struct talitos_request *request;
unsigned long flags, ch; unsigned long flags;
int head; int head;
/* select done notification */
desc->hdr |= DESC_HDR_DONE_NOTIFY;
/* emulate SEC's round-robin channel fifo polling scheme */
ch = atomic_inc_return(&priv->last_chan) & (priv->num_channels - 1);
spin_lock_irqsave(&priv->chan[ch].head_lock, flags); spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) { if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
...@@ -706,6 +701,7 @@ static void talitos_unregister_rng(struct device *dev) ...@@ -706,6 +701,7 @@ static void talitos_unregister_rng(struct device *dev)
struct talitos_ctx { struct talitos_ctx {
struct device *dev; struct device *dev;
int ch;
__be32 desc_hdr_template; __be32 desc_hdr_template;
u8 key[TALITOS_MAX_KEY_SIZE]; u8 key[TALITOS_MAX_KEY_SIZE];
u8 iv[TALITOS_MAX_IV_LENGTH]; u8 iv[TALITOS_MAX_IV_LENGTH];
...@@ -1117,7 +1113,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, ...@@ -1117,7 +1113,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 0, map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 0,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
ret = talitos_submit(dev, desc, callback, areq); ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
if (ret != -EINPROGRESS) { if (ret != -EINPROGRESS) {
ipsec_esp_unmap(dev, edesc, areq); ipsec_esp_unmap(dev, edesc, areq);
kfree(edesc); kfree(edesc);
...@@ -1382,22 +1378,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *cipher, ...@@ -1382,22 +1378,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
const u8 *key, unsigned int keylen) const u8 *key, unsigned int keylen)
{ {
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
struct ablkcipher_alg *alg = crypto_ablkcipher_alg(cipher);
if (keylen > TALITOS_MAX_KEY_SIZE)
goto badkey;
if (keylen < alg->min_keysize || keylen > alg->max_keysize)
goto badkey;
memcpy(&ctx->key, key, keylen); memcpy(&ctx->key, key, keylen);
ctx->keylen = keylen; ctx->keylen = keylen;
return 0; return 0;
badkey:
crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
} }
static void common_nonsnoop_unmap(struct device *dev, static void common_nonsnoop_unmap(struct device *dev,
...@@ -1433,7 +1418,6 @@ static void ablkcipher_done(struct device *dev, ...@@ -1433,7 +1418,6 @@ static void ablkcipher_done(struct device *dev,
static int common_nonsnoop(struct talitos_edesc *edesc, static int common_nonsnoop(struct talitos_edesc *edesc,
struct ablkcipher_request *areq, struct ablkcipher_request *areq,
u8 *giv,
void (*callback) (struct device *dev, void (*callback) (struct device *dev,
struct talitos_desc *desc, struct talitos_desc *desc,
void *context, int error)) void *context, int error))
...@@ -1453,7 +1437,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc, ...@@ -1453,7 +1437,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
/* cipher iv */ /* cipher iv */
ivsize = crypto_ablkcipher_ivsize(cipher); ivsize = crypto_ablkcipher_ivsize(cipher);
map_single_talitos_ptr(dev, &desc->ptr[1], ivsize, giv ?: areq->info, 0, map_single_talitos_ptr(dev, &desc->ptr[1], ivsize, areq->info, 0,
DMA_TO_DEVICE); DMA_TO_DEVICE);
/* cipher key */ /* cipher key */
...@@ -1524,7 +1508,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc, ...@@ -1524,7 +1508,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
to_talitos_ptr(&desc->ptr[6], 0); to_talitos_ptr(&desc->ptr[6], 0);
desc->ptr[6].j_extent = 0; desc->ptr[6].j_extent = 0;
ret = talitos_submit(dev, desc, callback, areq); ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
if (ret != -EINPROGRESS) { if (ret != -EINPROGRESS) {
common_nonsnoop_unmap(dev, edesc, areq); common_nonsnoop_unmap(dev, edesc, areq);
kfree(edesc); kfree(edesc);
...@@ -1556,7 +1540,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq) ...@@ -1556,7 +1540,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq)
/* set encrypt */ /* set encrypt */
edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
return common_nonsnoop(edesc, areq, NULL, ablkcipher_done); return common_nonsnoop(edesc, areq, ablkcipher_done);
} }
static int ablkcipher_decrypt(struct ablkcipher_request *areq) static int ablkcipher_decrypt(struct ablkcipher_request *areq)
...@@ -1572,7 +1556,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq) ...@@ -1572,7 +1556,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)
edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND; edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_DIR_INBOUND;
return common_nonsnoop(edesc, areq, NULL, ablkcipher_done); return common_nonsnoop(edesc, areq, ablkcipher_done);
} }
static void common_nonsnoop_hash_unmap(struct device *dev, static void common_nonsnoop_hash_unmap(struct device *dev,
...@@ -1703,7 +1687,7 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc, ...@@ -1703,7 +1687,7 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
/* last DWORD empty */ /* last DWORD empty */
desc->ptr[6] = zero_entry; desc->ptr[6] = zero_entry;
ret = talitos_submit(dev, desc, callback, areq); ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
if (ret != -EINPROGRESS) { if (ret != -EINPROGRESS) {
common_nonsnoop_hash_unmap(dev, edesc, areq); common_nonsnoop_hash_unmap(dev, edesc, areq);
kfree(edesc); kfree(edesc);
...@@ -2244,6 +2228,7 @@ static int talitos_cra_init(struct crypto_tfm *tfm) ...@@ -2244,6 +2228,7 @@ static int talitos_cra_init(struct crypto_tfm *tfm)
struct crypto_alg *alg = tfm->__crt_alg; struct crypto_alg *alg = tfm->__crt_alg;
struct talitos_crypto_alg *talitos_alg; struct talitos_crypto_alg *talitos_alg;
struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
struct talitos_private *priv;
if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH) if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
talitos_alg = container_of(__crypto_ahash_alg(alg), talitos_alg = container_of(__crypto_ahash_alg(alg),
...@@ -2256,9 +2241,17 @@ static int talitos_cra_init(struct crypto_tfm *tfm) ...@@ -2256,9 +2241,17 @@ static int talitos_cra_init(struct crypto_tfm *tfm)
/* update context with ptr to dev */ /* update context with ptr to dev */
ctx->dev = talitos_alg->dev; ctx->dev = talitos_alg->dev;
/* assign SEC channel to tfm in round-robin fashion */
priv = dev_get_drvdata(ctx->dev);
ctx->ch = atomic_inc_return(&priv->last_chan) &
(priv->num_channels - 1);
/* copy descriptor header template value */ /* copy descriptor header template value */
ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template; ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
/* select done notification */
ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment