forked from luck/tmp_suning_uos_patched
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 ...
This commit is contained in:
commit
a23a334bd5
|
@ -1,15 +1,12 @@
|
|||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* s390 implementation of the SHA256 Secure Hash Algorithm.
|
||||
* s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm.
|
||||
*
|
||||
* s390 Version:
|
||||
* Copyright IBM Corp. 2005,2007
|
||||
* Copyright IBM Corp. 2005,2011
|
||||
* 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
|
||||
* 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)
|
||||
|
@ -65,7 +62,7 @@ static int sha256_import(struct shash_desc *desc, const void *in)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg alg = {
|
||||
static struct shash_alg sha256_alg = {
|
||||
.digestsize = SHA256_DIGEST_SIZE,
|
||||
.init = sha256_init,
|
||||
.update = s390_sha_update,
|
||||
|
@ -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))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return crypto_register_shash(&alg);
|
||||
ret = crypto_register_shash(&sha256_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)
|
||||
{
|
||||
crypto_unregister_shash(&alg);
|
||||
crypto_unregister_shash(&sha224_alg);
|
||||
crypto_unregister_shash(&sha256_alg);
|
||||
}
|
||||
|
||||
module_init(sha256_s390_init);
|
||||
module_exit(sha256_s390_fini);
|
||||
|
||||
MODULE_ALIAS("sha256");
|
||||
MODULE_ALIAS("sha224");
|
||||
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,
|
|||
crypto_ahash_set_flags(tfm, crypto_ahash_get_flags(child)
|
||||
& CRYPTO_TFM_RES_MASK);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ghash_async_init_tfm(struct crypto_tfm *tfm)
|
||||
|
|
|
@ -458,7 +458,7 @@ config CRYPTO_WP512
|
|||
|
||||
config CRYPTO_GHASH_CLMUL_NI_INTEL
|
||||
tristate "GHASH digest algorithm (CLMUL-NI accelerated)"
|
||||
depends on (X86 || UML_X86) && 64BIT
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_SHASH
|
||||
select CRYPTO_CRYPTD
|
||||
help
|
||||
|
@ -533,7 +533,7 @@ config CRYPTO_AES_X86_64
|
|||
|
||||
config CRYPTO_AES_NI_INTEL
|
||||
tristate "AES cipher algorithms (AES-NI)"
|
||||
depends on (X86 || UML_X86)
|
||||
depends on X86
|
||||
select CRYPTO_AES_X86_64 if 64BIT
|
||||
select CRYPTO_AES_586 if !64BIT
|
||||
select CRYPTO_CRYPTD
|
||||
|
|
|
@ -68,8 +68,10 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
|
|||
int newlen;
|
||||
|
||||
newlen = af_alg_make_sg(&ctx->sgl, from, len, 0);
|
||||
if (newlen < 0)
|
||||
if (newlen < 0) {
|
||||
err = copied ? 0 : newlen;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL,
|
||||
newlen);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Cryptographic API
|
||||
*
|
||||
* ARC4 Cipher Algorithm
|
||||
|
@ -33,16 +33,15 @@ static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
|||
ctx->x = 1;
|
||||
ctx->y = 0;
|
||||
|
||||
for(i = 0; i < 256; i++)
|
||||
for (i = 0; i < 256; i++)
|
||||
ctx->S[i] = i;
|
||||
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
for (i = 0; i < 256; i++) {
|
||||
u8 a = ctx->S[i];
|
||||
j = (j + in_key[k] + a) & 0xff;
|
||||
ctx->S[i] = ctx->S[j];
|
||||
ctx->S[j] = a;
|
||||
if(++k >= key_len)
|
||||
if (++k >= key_len)
|
||||
k = 0;
|
||||
}
|
||||
|
||||
|
@ -80,9 +79,9 @@ static struct crypto_alg arc4_alg = {
|
|||
.cra_u = { .cipher = {
|
||||
.cia_min_keysize = ARC4_MIN_KEY_SIZE,
|
||||
.cia_max_keysize = ARC4_MAX_KEY_SIZE,
|
||||
.cia_setkey = arc4_set_key,
|
||||
.cia_encrypt = arc4_crypt,
|
||||
.cia_decrypt = arc4_crypt } }
|
||||
.cia_setkey = arc4_set_key,
|
||||
.cia_encrypt = arc4_crypt,
|
||||
.cia_decrypt = arc4_crypt } }
|
||||
};
|
||||
|
||||
static int __init arc4_init(void)
|
||||
|
|
|
@ -224,11 +224,11 @@ static int crc32c_cra_init(struct crypto_tfm *tfm)
|
|||
static struct shash_alg alg = {
|
||||
.digestsize = CHKSUM_DIGEST_SIZE,
|
||||
.setkey = chksum_setkey,
|
||||
.init = chksum_init,
|
||||
.update = chksum_update,
|
||||
.final = chksum_final,
|
||||
.finup = chksum_finup,
|
||||
.digest = chksum_digest,
|
||||
.init = chksum_init,
|
||||
.update = chksum_update,
|
||||
.final = chksum_final,
|
||||
.finup = chksum_finup,
|
||||
.digest = chksum_digest,
|
||||
.descsize = sizeof(struct chksum_desc_ctx),
|
||||
.base = {
|
||||
.cra_name = "crc32c",
|
||||
|
|
|
@ -182,7 +182,7 @@ void gf128mul_lle(be128 *r, const be128 *b)
|
|||
for (i = 0; i < 7; ++i)
|
||||
gf128mul_x_lle(&p[i + 1], &p[i]);
|
||||
|
||||
memset(r, 0, sizeof(r));
|
||||
memset(r, 0, sizeof(*r));
|
||||
for (i = 0;;) {
|
||||
u8 ch = ((u8 *)b)[15 - i];
|
||||
|
||||
|
@ -220,7 +220,7 @@ void gf128mul_bbe(be128 *r, const be128 *b)
|
|||
for (i = 0; i < 7; ++i)
|
||||
gf128mul_x_bbe(&p[i + 1], &p[i]);
|
||||
|
||||
memset(r, 0, sizeof(r));
|
||||
memset(r, 0, sizeof(*r));
|
||||
for (i = 0;;) {
|
||||
u8 ch = ((u8 *)b)[i];
|
||||
|
||||
|
|
|
@ -43,25 +43,26 @@ static int sha1_update(struct shash_desc *desc, const u8 *data,
|
|||
unsigned int partial, done;
|
||||
const u8 *src;
|
||||
|
||||
partial = sctx->count & 0x3f;
|
||||
partial = sctx->count % SHA1_BLOCK_SIZE;
|
||||
sctx->count += len;
|
||||
done = 0;
|
||||
src = data;
|
||||
|
||||
if ((partial + len) > 63) {
|
||||
if ((partial + len) >= SHA1_BLOCK_SIZE) {
|
||||
u32 temp[SHA_WORKSPACE_WORDS];
|
||||
|
||||
if (partial) {
|
||||
done = -partial;
|
||||
memcpy(sctx->buffer + partial, data, done + 64);
|
||||
memcpy(sctx->buffer + partial, data,
|
||||
done + SHA1_BLOCK_SIZE);
|
||||
src = sctx->buffer;
|
||||
}
|
||||
|
||||
do {
|
||||
sha_transform(sctx->state, src, temp);
|
||||
done += 64;
|
||||
done += SHA1_BLOCK_SIZE;
|
||||
src = data + done;
|
||||
} while (done + 63 < len);
|
||||
} while (done + SHA1_BLOCK_SIZE <= len);
|
||||
|
||||
memset(temp, 0, sizeof(temp));
|
||||
partial = 0;
|
||||
|
|
293
crypto/testmgr.h
293
crypto/testmgr.h
|
@ -2976,8 +2976,8 @@ static struct cipher_testvec cast6_dec_tv_template[] = {
|
|||
#define AES_CBC_DEC_TEST_VECTORS 4
|
||||
#define AES_LRW_ENC_TEST_VECTORS 8
|
||||
#define AES_LRW_DEC_TEST_VECTORS 8
|
||||
#define AES_XTS_ENC_TEST_VECTORS 4
|
||||
#define AES_XTS_DEC_TEST_VECTORS 4
|
||||
#define AES_XTS_ENC_TEST_VECTORS 5
|
||||
#define AES_XTS_DEC_TEST_VECTORS 5
|
||||
#define AES_CTR_ENC_TEST_VECTORS 3
|
||||
#define AES_CTR_DEC_TEST_VECTORS 3
|
||||
#define AES_OFB_ENC_TEST_VECTORS 1
|
||||
|
@ -3926,6 +3926,150 @@ static struct cipher_testvec aes_xts_enc_tv_template[] = {
|
|||
"\x0a\x28\x2d\xf9\x20\x14\x7b\xea"
|
||||
"\xbe\x42\x1e\xe5\x31\x9d\x05\x68",
|
||||
.rlen = 512,
|
||||
}, { /* XTS-AES 10, XTS-AES-256, data unit 512 bytes */
|
||||
.key = "\x27\x18\x28\x18\x28\x45\x90\x45"
|
||||
"\x23\x53\x60\x28\x74\x71\x35\x26"
|
||||
"\x62\x49\x77\x57\x24\x70\x93\x69"
|
||||
"\x99\x59\x57\x49\x66\x96\x76\x27"
|
||||
"\x31\x41\x59\x26\x53\x58\x97\x93"
|
||||
"\x23\x84\x62\x64\x33\x83\x27\x95"
|
||||
"\x02\x88\x41\x97\x16\x93\x99\x37"
|
||||
"\x51\x05\x82\x09\x74\x94\x45\x92",
|
||||
.klen = 64,
|
||||
.iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.input = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
||||
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17"
|
||||
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
||||
"\x20\x21\x22\x23\x24\x25\x26\x27"
|
||||
"\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
||||
"\x30\x31\x32\x33\x34\x35\x36\x37"
|
||||
"\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
||||
"\x40\x41\x42\x43\x44\x45\x46\x47"
|
||||
"\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
||||
"\x50\x51\x52\x53\x54\x55\x56\x57"
|
||||
"\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
||||
"\x60\x61\x62\x63\x64\x65\x66\x67"
|
||||
"\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
||||
"\x70\x71\x72\x73\x74\x75\x76\x77"
|
||||
"\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
||||
"\x80\x81\x82\x83\x84\x85\x86\x87"
|
||||
"\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
||||
"\x90\x91\x92\x93\x94\x95\x96\x97"
|
||||
"\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
||||
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
||||
"\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
||||
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
||||
"\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
||||
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
||||
"\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
||||
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
||||
"\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
||||
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
||||
"\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
||||
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
||||
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07"
|
||||
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17"
|
||||
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
||||
"\x20\x21\x22\x23\x24\x25\x26\x27"
|
||||
"\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
||||
"\x30\x31\x32\x33\x34\x35\x36\x37"
|
||||
"\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
||||
"\x40\x41\x42\x43\x44\x45\x46\x47"
|
||||
"\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
||||
"\x50\x51\x52\x53\x54\x55\x56\x57"
|
||||
"\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
||||
"\x60\x61\x62\x63\x64\x65\x66\x67"
|
||||
"\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
||||
"\x70\x71\x72\x73\x74\x75\x76\x77"
|
||||
"\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
||||
"\x80\x81\x82\x83\x84\x85\x86\x87"
|
||||
"\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
||||
"\x90\x91\x92\x93\x94\x95\x96\x97"
|
||||
"\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
||||
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
||||
"\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
||||
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
||||
"\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
||||
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
||||
"\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
||||
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
||||
"\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
||||
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
||||
"\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
||||
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
||||
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
|
||||
.ilen = 512,
|
||||
.result = "\x1c\x3b\x3a\x10\x2f\x77\x03\x86"
|
||||
"\xe4\x83\x6c\x99\xe3\x70\xcf\x9b"
|
||||
"\xea\x00\x80\x3f\x5e\x48\x23\x57"
|
||||
"\xa4\xae\x12\xd4\x14\xa3\xe6\x3b"
|
||||
"\x5d\x31\xe2\x76\xf8\xfe\x4a\x8d"
|
||||
"\x66\xb3\x17\xf9\xac\x68\x3f\x44"
|
||||
"\x68\x0a\x86\xac\x35\xad\xfc\x33"
|
||||
"\x45\xbe\xfe\xcb\x4b\xb1\x88\xfd"
|
||||
"\x57\x76\x92\x6c\x49\xa3\x09\x5e"
|
||||
"\xb1\x08\xfd\x10\x98\xba\xec\x70"
|
||||
"\xaa\xa6\x69\x99\xa7\x2a\x82\xf2"
|
||||
"\x7d\x84\x8b\x21\xd4\xa7\x41\xb0"
|
||||
"\xc5\xcd\x4d\x5f\xff\x9d\xac\x89"
|
||||
"\xae\xba\x12\x29\x61\xd0\x3a\x75"
|
||||
"\x71\x23\xe9\x87\x0f\x8a\xcf\x10"
|
||||
"\x00\x02\x08\x87\x89\x14\x29\xca"
|
||||
"\x2a\x3e\x7a\x7d\x7d\xf7\xb1\x03"
|
||||
"\x55\x16\x5c\x8b\x9a\x6d\x0a\x7d"
|
||||
"\xe8\xb0\x62\xc4\x50\x0d\xc4\xcd"
|
||||
"\x12\x0c\x0f\x74\x18\xda\xe3\xd0"
|
||||
"\xb5\x78\x1c\x34\x80\x3f\xa7\x54"
|
||||
"\x21\xc7\x90\xdf\xe1\xde\x18\x34"
|
||||
"\xf2\x80\xd7\x66\x7b\x32\x7f\x6c"
|
||||
"\x8c\xd7\x55\x7e\x12\xac\x3a\x0f"
|
||||
"\x93\xec\x05\xc5\x2e\x04\x93\xef"
|
||||
"\x31\xa1\x2d\x3d\x92\x60\xf7\x9a"
|
||||
"\x28\x9d\x6a\x37\x9b\xc7\x0c\x50"
|
||||
"\x84\x14\x73\xd1\xa8\xcc\x81\xec"
|
||||
"\x58\x3e\x96\x45\xe0\x7b\x8d\x96"
|
||||
"\x70\x65\x5b\xa5\xbb\xcf\xec\xc6"
|
||||
"\xdc\x39\x66\x38\x0a\xd8\xfe\xcb"
|
||||
"\x17\xb6\xba\x02\x46\x9a\x02\x0a"
|
||||
"\x84\xe1\x8e\x8f\x84\x25\x20\x70"
|
||||
"\xc1\x3e\x9f\x1f\x28\x9b\xe5\x4f"
|
||||
"\xbc\x48\x14\x57\x77\x8f\x61\x60"
|
||||
"\x15\xe1\x32\x7a\x02\xb1\x40\xf1"
|
||||
"\x50\x5e\xb3\x09\x32\x6d\x68\x37"
|
||||
"\x8f\x83\x74\x59\x5c\x84\x9d\x84"
|
||||
"\xf4\xc3\x33\xec\x44\x23\x88\x51"
|
||||
"\x43\xcb\x47\xbd\x71\xc5\xed\xae"
|
||||
"\x9b\xe6\x9a\x2f\xfe\xce\xb1\xbe"
|
||||
"\xc9\xde\x24\x4f\xbe\x15\x99\x2b"
|
||||
"\x11\xb7\x7c\x04\x0f\x12\xbd\x8f"
|
||||
"\x6a\x97\x5a\x44\xa0\xf9\x0c\x29"
|
||||
"\xa9\xab\xc3\xd4\xd8\x93\x92\x72"
|
||||
"\x84\xc5\x87\x54\xcc\xe2\x94\x52"
|
||||
"\x9f\x86\x14\xdc\xd2\xab\xa9\x91"
|
||||
"\x92\x5f\xed\xc4\xae\x74\xff\xac"
|
||||
"\x6e\x33\x3b\x93\xeb\x4a\xff\x04"
|
||||
"\x79\xda\x9a\x41\x0e\x44\x50\xe0"
|
||||
"\xdd\x7a\xe4\xc6\xe2\x91\x09\x00"
|
||||
"\x57\x5d\xa4\x01\xfc\x07\x05\x9f"
|
||||
"\x64\x5e\x8b\x7e\x9b\xfd\xef\x33"
|
||||
"\x94\x30\x54\xff\x84\x01\x14\x93"
|
||||
"\xc2\x7b\x34\x29\xea\xed\xb4\xed"
|
||||
"\x53\x76\x44\x1a\x77\xed\x43\x85"
|
||||
"\x1a\xd7\x7f\x16\xf5\x41\xdf\xd2"
|
||||
"\x69\xd5\x0d\x6a\x5f\x14\xfb\x0a"
|
||||
"\xab\x1c\xbb\x4c\x15\x50\xbe\x97"
|
||||
"\xf7\xab\x40\x66\x19\x3c\x4c\xaa"
|
||||
"\x77\x3d\xad\x38\x01\x4b\xd2\x09"
|
||||
"\x2f\xa7\x55\xc8\x24\xbb\x5e\x54"
|
||||
"\xc4\xf3\x6f\xfd\xa9\xfc\xea\x70"
|
||||
"\xb9\xc6\xe6\x93\xe1\x48\xc1\x51",
|
||||
.rlen = 512,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4123,6 +4267,151 @@ static struct cipher_testvec aes_xts_dec_tv_template[] = {
|
|||
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
||||
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
|
||||
.rlen = 512,
|
||||
}, { /* XTS-AES 10, XTS-AES-256, data unit 512 bytes */
|
||||
.key = "\x27\x18\x28\x18\x28\x45\x90\x45"
|
||||
"\x23\x53\x60\x28\x74\x71\x35\x26"
|
||||
"\x62\x49\x77\x57\x24\x70\x93\x69"
|
||||
"\x99\x59\x57\x49\x66\x96\x76\x27"
|
||||
"\x31\x41\x59\x26\x53\x58\x97\x93"
|
||||
"\x23\x84\x62\x64\x33\x83\x27\x95"
|
||||
"\x02\x88\x41\x97\x16\x93\x99\x37"
|
||||
"\x51\x05\x82\x09\x74\x94\x45\x92",
|
||||
.klen = 64,
|
||||
.iv = "\xff\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
.input = "\x1c\x3b\x3a\x10\x2f\x77\x03\x86"
|
||||
"\xe4\x83\x6c\x99\xe3\x70\xcf\x9b"
|
||||
"\xea\x00\x80\x3f\x5e\x48\x23\x57"
|
||||
"\xa4\xae\x12\xd4\x14\xa3\xe6\x3b"
|
||||
"\x5d\x31\xe2\x76\xf8\xfe\x4a\x8d"
|
||||
"\x66\xb3\x17\xf9\xac\x68\x3f\x44"
|
||||
"\x68\x0a\x86\xac\x35\xad\xfc\x33"
|
||||
"\x45\xbe\xfe\xcb\x4b\xb1\x88\xfd"
|
||||
"\x57\x76\x92\x6c\x49\xa3\x09\x5e"
|
||||
"\xb1\x08\xfd\x10\x98\xba\xec\x70"
|
||||
"\xaa\xa6\x69\x99\xa7\x2a\x82\xf2"
|
||||
"\x7d\x84\x8b\x21\xd4\xa7\x41\xb0"
|
||||
"\xc5\xcd\x4d\x5f\xff\x9d\xac\x89"
|
||||
"\xae\xba\x12\x29\x61\xd0\x3a\x75"
|
||||
"\x71\x23\xe9\x87\x0f\x8a\xcf\x10"
|
||||
"\x00\x02\x08\x87\x89\x14\x29\xca"
|
||||
"\x2a\x3e\x7a\x7d\x7d\xf7\xb1\x03"
|
||||
"\x55\x16\x5c\x8b\x9a\x6d\x0a\x7d"
|
||||
"\xe8\xb0\x62\xc4\x50\x0d\xc4\xcd"
|
||||
"\x12\x0c\x0f\x74\x18\xda\xe3\xd0"
|
||||
"\xb5\x78\x1c\x34\x80\x3f\xa7\x54"
|
||||
"\x21\xc7\x90\xdf\xe1\xde\x18\x34"
|
||||
"\xf2\x80\xd7\x66\x7b\x32\x7f\x6c"
|
||||
"\x8c\xd7\x55\x7e\x12\xac\x3a\x0f"
|
||||
"\x93\xec\x05\xc5\x2e\x04\x93\xef"
|
||||
"\x31\xa1\x2d\x3d\x92\x60\xf7\x9a"
|
||||
"\x28\x9d\x6a\x37\x9b\xc7\x0c\x50"
|
||||
"\x84\x14\x73\xd1\xa8\xcc\x81\xec"
|
||||
"\x58\x3e\x96\x45\xe0\x7b\x8d\x96"
|
||||
"\x70\x65\x5b\xa5\xbb\xcf\xec\xc6"
|
||||
"\xdc\x39\x66\x38\x0a\xd8\xfe\xcb"
|
||||
"\x17\xb6\xba\x02\x46\x9a\x02\x0a"
|
||||
"\x84\xe1\x8e\x8f\x84\x25\x20\x70"
|
||||
"\xc1\x3e\x9f\x1f\x28\x9b\xe5\x4f"
|
||||
"\xbc\x48\x14\x57\x77\x8f\x61\x60"
|
||||
"\x15\xe1\x32\x7a\x02\xb1\x40\xf1"
|
||||
"\x50\x5e\xb3\x09\x32\x6d\x68\x37"
|
||||
"\x8f\x83\x74\x59\x5c\x84\x9d\x84"
|
||||
"\xf4\xc3\x33\xec\x44\x23\x88\x51"
|
||||
"\x43\xcb\x47\xbd\x71\xc5\xed\xae"
|
||||
"\x9b\xe6\x9a\x2f\xfe\xce\xb1\xbe"
|
||||
"\xc9\xde\x24\x4f\xbe\x15\x99\x2b"
|
||||
"\x11\xb7\x7c\x04\x0f\x12\xbd\x8f"
|
||||
"\x6a\x97\x5a\x44\xa0\xf9\x0c\x29"
|
||||
"\xa9\xab\xc3\xd4\xd8\x93\x92\x72"
|
||||
"\x84\xc5\x87\x54\xcc\xe2\x94\x52"
|
||||
"\x9f\x86\x14\xdc\xd2\xab\xa9\x91"
|
||||
"\x92\x5f\xed\xc4\xae\x74\xff\xac"
|
||||
"\x6e\x33\x3b\x93\xeb\x4a\xff\x04"
|
||||
"\x79\xda\x9a\x41\x0e\x44\x50\xe0"
|
||||
"\xdd\x7a\xe4\xc6\xe2\x91\x09\x00"
|
||||
"\x57\x5d\xa4\x01\xfc\x07\x05\x9f"
|
||||
"\x64\x5e\x8b\x7e\x9b\xfd\xef\x33"
|
||||
"\x94\x30\x54\xff\x84\x01\x14\x93"
|
||||
"\xc2\x7b\x34\x29\xea\xed\xb4\xed"
|
||||
"\x53\x76\x44\x1a\x77\xed\x43\x85"
|
||||
"\x1a\xd7\x7f\x16\xf5\x41\xdf\xd2"
|
||||
"\x69\xd5\x0d\x6a\x5f\x14\xfb\x0a"
|
||||
"\xab\x1c\xbb\x4c\x15\x50\xbe\x97"
|
||||
"\xf7\xab\x40\x66\x19\x3c\x4c\xaa"
|
||||
"\x77\x3d\xad\x38\x01\x4b\xd2\x09"
|
||||
"\x2f\xa7\x55\xc8\x24\xbb\x5e\x54"
|
||||
"\xc4\xf3\x6f\xfd\xa9\xfc\xea\x70"
|
||||
"\xb9\xc6\xe6\x93\xe1\x48\xc1\x51",
|
||||
.ilen = 512,
|
||||
.result = "\x00\x01\x02\x03\x04\x05\x06\x07"
|
||||
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17"
|
||||
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
||||
"\x20\x21\x22\x23\x24\x25\x26\x27"
|
||||
"\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
||||
"\x30\x31\x32\x33\x34\x35\x36\x37"
|
||||
"\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
||||
"\x40\x41\x42\x43\x44\x45\x46\x47"
|
||||
"\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
||||
"\x50\x51\x52\x53\x54\x55\x56\x57"
|
||||
"\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
||||
"\x60\x61\x62\x63\x64\x65\x66\x67"
|
||||
"\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
||||
"\x70\x71\x72\x73\x74\x75\x76\x77"
|
||||
"\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
||||
"\x80\x81\x82\x83\x84\x85\x86\x87"
|
||||
"\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
||||
"\x90\x91\x92\x93\x94\x95\x96\x97"
|
||||
"\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
||||
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
||||
"\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
||||
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
||||
"\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
||||
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
||||
"\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
||||
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
||||
"\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
||||
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
||||
"\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
||||
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
||||
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07"
|
||||
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
|
||||
"\x10\x11\x12\x13\x14\x15\x16\x17"
|
||||
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
||||
"\x20\x21\x22\x23\x24\x25\x26\x27"
|
||||
"\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
|
||||
"\x30\x31\x32\x33\x34\x35\x36\x37"
|
||||
"\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
|
||||
"\x40\x41\x42\x43\x44\x45\x46\x47"
|
||||
"\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
|
||||
"\x50\x51\x52\x53\x54\x55\x56\x57"
|
||||
"\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
|
||||
"\x60\x61\x62\x63\x64\x65\x66\x67"
|
||||
"\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
|
||||
"\x70\x71\x72\x73\x74\x75\x76\x77"
|
||||
"\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
|
||||
"\x80\x81\x82\x83\x84\x85\x86\x87"
|
||||
"\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
|
||||
"\x90\x91\x92\x93\x94\x95\x96\x97"
|
||||
"\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
|
||||
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
|
||||
"\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
|
||||
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
|
||||
"\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
|
||||
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
|
||||
"\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
|
||||
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
|
||||
"\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
|
||||
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
|
||||
"\xe8\xe9\xea\xeb\xec\xed\xee\xef"
|
||||
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
|
||||
"\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
|
||||
.rlen = 512,
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -210,3 +210,15 @@ config HW_RANDOM_PICOXCELL
|
|||
module will be called picoxcell-rng.
|
||||
|
||||
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
|
|||
obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-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)
|
|||
|
||||
ret = amba_request_regions(dev, dev->dev.init_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_clk;
|
||||
ret = -ENOMEM;
|
||||
base = ioremap(dev->res.start, resource_size(&dev->res));
|
||||
if (!base)
|
||||
|
@ -70,6 +70,7 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
|
|||
iounmap(base);
|
||||
out_release:
|
||||
amba_release_regions(dev);
|
||||
out_clk:
|
||||
clk_disable(rng_clk);
|
||||
clk_put(rng_clk);
|
||||
return ret;
|
||||
|
|
|
@ -113,8 +113,10 @@ static int __devinit omap_rng_probe(struct platform_device *pdev)
|
|||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
if (!res)
|
||||
return -ENOENT;
|
||||
if (!res) {
|
||||
ret = -ENOENT;
|
||||
goto err_region;
|
||||
}
|
||||
|
||||
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
|
||||
ret = -EBUSY;
|
||||
|
|
156
drivers/char/hw_random/ppc4xx-rng.c
Normal file
156
drivers/char/hw_random/ppc4xx-rng.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* 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)
|
|||
|
||||
timeriomem_rng_data = pdev->dev.platform_data;
|
||||
|
||||
timeriomem_rng_data->address = ioremap(res->start,
|
||||
res->end - res->start + 1);
|
||||
timeriomem_rng_data->address = ioremap(res->start, resource_size(res));
|
||||
if (!timeriomem_rng_data->address)
|
||||
return -EIO;
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ static void crypto4xx_hw_init(struct crypto4xx_device *dev)
|
|||
union ce_io_threshold io_threshold;
|
||||
u32 rand_num;
|
||||
union ce_pe_dma_cfg pe_dma_cfg;
|
||||
u32 device_ctrl;
|
||||
|
||||
writel(PPC4XX_BYTE_ORDER, dev->ce_base + CRYPTO4XX_BYTE_ORDER_CFG);
|
||||
/* 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)
|
|||
writel(ring_size.w, dev->ce_base + CRYPTO4XX_RING_SIZE);
|
||||
ring_ctrl.w = 0;
|
||||
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->sdr_pa, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE);
|
||||
part_ring_size.w = 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,5 +31,6 @@
|
|||
#include <crypto/aead.h>
|
||||
#include <crypto/authenc.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
|
||||
#endif /* !defined(CAAM_COMPAT_H) */
|
||||
|
|
|
@ -52,9 +52,11 @@ static int caam_probe(struct platform_device *pdev)
|
|||
struct caam_ctrl __iomem *ctrl;
|
||||
struct caam_full __iomem *topregs;
|
||||
struct caam_drv_private *ctrlpriv;
|
||||
struct caam_perfmon *perfmon;
|
||||
struct caam_deco **deco;
|
||||
u32 deconum;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct caam_perfmon *perfmon;
|
||||
#endif
|
||||
|
||||
ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
|
||||
if (!ctrlpriv)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#define IMMEDIATE (1 << 23)
|
||||
#define CAAM_CMD_SZ sizeof(u32)
|
||||
#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
|
||||
#define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\
|
||||
|
@ -18,6 +18,9 @@
|
|||
#define PRINT_POS
|
||||
#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 | \
|
||||
LDST_SRCDST_WORD_DECOCTRL | \
|
||||
(LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
|
||||
|
@ -203,3 +206,56 @@ static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \
|
|||
append_cmd(desc, immediate); \
|
||||
}
|
||||
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)
|
||||
|
|
|
@ -72,17 +72,20 @@
|
|||
|
||||
#define DEFAULT_TIMEOUT_INTERVAL HZ
|
||||
|
||||
#define FLAGS_FINUP 0x0002
|
||||
#define FLAGS_FINAL 0x0004
|
||||
#define FLAGS_SG 0x0008
|
||||
#define FLAGS_SHA1 0x0010
|
||||
#define FLAGS_DMA_ACTIVE 0x0020
|
||||
#define FLAGS_OUTPUT_READY 0x0040
|
||||
#define FLAGS_INIT 0x0100
|
||||
#define FLAGS_CPU 0x0200
|
||||
#define FLAGS_HMAC 0x0400
|
||||
#define FLAGS_ERROR 0x0800
|
||||
#define FLAGS_BUSY 0x1000
|
||||
/* mostly device flags */
|
||||
#define FLAGS_BUSY 0
|
||||
#define FLAGS_FINAL 1
|
||||
#define FLAGS_DMA_ACTIVE 2
|
||||
#define FLAGS_OUTPUT_READY 3
|
||||
#define FLAGS_INIT 4
|
||||
#define FLAGS_CPU 5
|
||||
#define FLAGS_DMA_READY 6
|
||||
/* context flags */
|
||||
#define FLAGS_FINUP 16
|
||||
#define FLAGS_SG 17
|
||||
#define FLAGS_SHA1 18
|
||||
#define FLAGS_HMAC 19
|
||||
#define FLAGS_ERROR 20
|
||||
|
||||
#define OP_UPDATE 1
|
||||
#define OP_FINAL 2
|
||||
|
@ -144,7 +147,6 @@ struct omap_sham_dev {
|
|||
int dma;
|
||||
int dma_lch;
|
||||
struct tasklet_struct done_task;
|
||||
struct tasklet_struct queue_task;
|
||||
|
||||
unsigned long flags;
|
||||
struct crypto_queue queue;
|
||||
|
@ -223,7 +225,7 @@ static void omap_sham_copy_ready_hash(struct ahash_request *req)
|
|||
if (!hash)
|
||||
return;
|
||||
|
||||
if (likely(ctx->flags & FLAGS_SHA1)) {
|
||||
if (likely(ctx->flags & BIT(FLAGS_SHA1))) {
|
||||
/* SHA1 results are in big endian */
|
||||
for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++)
|
||||
hash[i] = be32_to_cpu(in[i]);
|
||||
|
@ -238,7 +240,7 @@ static int omap_sham_hw_init(struct omap_sham_dev *dd)
|
|||
{
|
||||
clk_enable(dd->iclk);
|
||||
|
||||
if (!(dd->flags & FLAGS_INIT)) {
|
||||
if (!test_bit(FLAGS_INIT, &dd->flags)) {
|
||||
omap_sham_write_mask(dd, SHA_REG_MASK,
|
||||
SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
|
||||
|
||||
|
@ -246,7 +248,7 @@ static int omap_sham_hw_init(struct omap_sham_dev *dd)
|
|||
SHA_REG_SYSSTATUS_RESETDONE))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
dd->flags |= FLAGS_INIT;
|
||||
set_bit(FLAGS_INIT, &dd->flags);
|
||||
dd->err = 0;
|
||||
}
|
||||
|
||||
|
@ -269,7 +271,7 @@ static void omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length,
|
|||
* Setting ALGO_CONST only for the first iteration
|
||||
* and CLOSE_HASH only for the last one.
|
||||
*/
|
||||
if (ctx->flags & FLAGS_SHA1)
|
||||
if (ctx->flags & BIT(FLAGS_SHA1))
|
||||
val |= SHA_REG_CTRL_ALGO;
|
||||
if (!ctx->digcnt)
|
||||
val |= SHA_REG_CTRL_ALGO_CONST;
|
||||
|
@ -301,7 +303,9 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf,
|
|||
return -ETIMEDOUT;
|
||||
|
||||
if (final)
|
||||
ctx->flags |= FLAGS_FINAL; /* catch last interrupt */
|
||||
set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */
|
||||
|
||||
set_bit(FLAGS_CPU, &dd->flags);
|
||||
|
||||
len32 = DIV_ROUND_UP(length, sizeof(u32));
|
||||
|
||||
|
@ -334,9 +338,9 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr,
|
|||
ctx->digcnt += length;
|
||||
|
||||
if (final)
|
||||
ctx->flags |= FLAGS_FINAL; /* catch last interrupt */
|
||||
set_bit(FLAGS_FINAL, &dd->flags); /* catch last interrupt */
|
||||
|
||||
dd->flags |= FLAGS_DMA_ACTIVE;
|
||||
set_bit(FLAGS_DMA_ACTIVE, &dd->flags);
|
||||
|
||||
omap_start_dma(dd->dma_lch);
|
||||
|
||||
|
@ -392,7 +396,7 @@ static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->flags &= ~FLAGS_SG;
|
||||
ctx->flags &= ~BIT(FLAGS_SG);
|
||||
|
||||
/* next call does not fail... so no unmap in the case of error */
|
||||
return omap_sham_xmit_dma(dd, ctx->dma_addr, length, final);
|
||||
|
@ -406,7 +410,7 @@ static int omap_sham_update_dma_slow(struct omap_sham_dev *dd)
|
|||
|
||||
omap_sham_append_sg(ctx);
|
||||
|
||||
final = (ctx->flags & FLAGS_FINUP) && !ctx->total;
|
||||
final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
|
||||
|
||||
dev_dbg(dd->dev, "slow: bufcnt: %u, digcnt: %d, final: %d\n",
|
||||
ctx->bufcnt, ctx->digcnt, final);
|
||||
|
@ -452,7 +456,7 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
|
|||
length = min(ctx->total, sg->length);
|
||||
|
||||
if (sg_is_last(sg)) {
|
||||
if (!(ctx->flags & FLAGS_FINUP)) {
|
||||
if (!(ctx->flags & BIT(FLAGS_FINUP))) {
|
||||
/* not last sg must be SHA1_MD5_BLOCK_SIZE aligned */
|
||||
tail = length & (SHA1_MD5_BLOCK_SIZE - 1);
|
||||
/* without finup() we need one block to close hash */
|
||||
|
@ -467,12 +471,12 @@ static int omap_sham_update_dma_start(struct omap_sham_dev *dd)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->flags |= FLAGS_SG;
|
||||
ctx->flags |= BIT(FLAGS_SG);
|
||||
|
||||
ctx->total -= length;
|
||||
ctx->offset = length; /* offset where to start slow */
|
||||
|
||||
final = (ctx->flags & FLAGS_FINUP) && !ctx->total;
|
||||
final = (ctx->flags & BIT(FLAGS_FINUP)) && !ctx->total;
|
||||
|
||||
/* next call does not fail... so no unmap in the case of error */
|
||||
return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final);
|
||||
|
@ -495,7 +499,7 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd)
|
|||
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
|
||||
|
||||
omap_stop_dma(dd->dma_lch);
|
||||
if (ctx->flags & FLAGS_SG) {
|
||||
if (ctx->flags & BIT(FLAGS_SG)) {
|
||||
dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
|
||||
if (ctx->sg->length == ctx->offset) {
|
||||
ctx->sg = sg_next(ctx->sg);
|
||||
|
@ -537,18 +541,18 @@ static int omap_sham_init(struct ahash_request *req)
|
|||
crypto_ahash_digestsize(tfm));
|
||||
|
||||
if (crypto_ahash_digestsize(tfm) == SHA1_DIGEST_SIZE)
|
||||
ctx->flags |= FLAGS_SHA1;
|
||||
ctx->flags |= BIT(FLAGS_SHA1);
|
||||
|
||||
ctx->bufcnt = 0;
|
||||
ctx->digcnt = 0;
|
||||
ctx->buflen = BUFLEN;
|
||||
|
||||
if (tctx->flags & FLAGS_HMAC) {
|
||||
if (tctx->flags & BIT(FLAGS_HMAC)) {
|
||||
struct omap_sham_hmac_ctx *bctx = tctx->base;
|
||||
|
||||
memcpy(ctx->buffer, bctx->ipad, SHA1_MD5_BLOCK_SIZE);
|
||||
ctx->bufcnt = SHA1_MD5_BLOCK_SIZE;
|
||||
ctx->flags |= FLAGS_HMAC;
|
||||
ctx->flags |= BIT(FLAGS_HMAC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -562,9 +566,9 @@ static int omap_sham_update_req(struct omap_sham_dev *dd)
|
|||
int err;
|
||||
|
||||
dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n",
|
||||
ctx->total, ctx->digcnt, (ctx->flags & FLAGS_FINUP) != 0);
|
||||
ctx->total, ctx->digcnt, (ctx->flags & BIT(FLAGS_FINUP)) != 0);
|
||||
|
||||
if (ctx->flags & FLAGS_CPU)
|
||||
if (ctx->flags & BIT(FLAGS_CPU))
|
||||
err = omap_sham_update_cpu(dd);
|
||||
else
|
||||
err = omap_sham_update_dma_start(dd);
|
||||
|
@ -624,7 +628,7 @@ static int omap_sham_finish(struct ahash_request *req)
|
|||
|
||||
if (ctx->digcnt) {
|
||||
omap_sham_copy_ready_hash(req);
|
||||
if (ctx->flags & FLAGS_HMAC)
|
||||
if (ctx->flags & BIT(FLAGS_HMAC))
|
||||
err = omap_sham_finish_hmac(req);
|
||||
}
|
||||
|
||||
|
@ -639,18 +643,23 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
|
|||
struct omap_sham_dev *dd = ctx->dd;
|
||||
|
||||
if (!err) {
|
||||
omap_sham_copy_hash(ctx->dd->req, 1);
|
||||
if (ctx->flags & FLAGS_FINAL)
|
||||
omap_sham_copy_hash(req, 1);
|
||||
if (test_bit(FLAGS_FINAL, &dd->flags))
|
||||
err = omap_sham_finish(req);
|
||||
} else {
|
||||
ctx->flags |= FLAGS_ERROR;
|
||||
ctx->flags |= BIT(FLAGS_ERROR);
|
||||
}
|
||||
|
||||
/* atomic operation is not needed here */
|
||||
dd->flags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) |
|
||||
BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY));
|
||||
clk_disable(dd->iclk);
|
||||
dd->flags &= ~FLAGS_BUSY;
|
||||
|
||||
if (req->base.complete)
|
||||
req->base.complete(&req->base, err);
|
||||
|
||||
/* handle new request */
|
||||
tasklet_schedule(&dd->done_task);
|
||||
}
|
||||
|
||||
static int omap_sham_handle_queue(struct omap_sham_dev *dd,
|
||||
|
@ -658,21 +667,20 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
|
|||
{
|
||||
struct crypto_async_request *async_req, *backlog;
|
||||
struct omap_sham_reqctx *ctx;
|
||||
struct ahash_request *prev_req;
|
||||
unsigned long flags;
|
||||
int err = 0, ret = 0;
|
||||
|
||||
spin_lock_irqsave(&dd->lock, flags);
|
||||
if (req)
|
||||
ret = ahash_enqueue_request(&dd->queue, req);
|
||||
if (dd->flags & FLAGS_BUSY) {
|
||||
if (test_bit(FLAGS_BUSY, &dd->flags)) {
|
||||
spin_unlock_irqrestore(&dd->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
backlog = crypto_get_backlog(&dd->queue);
|
||||
async_req = crypto_dequeue_request(&dd->queue);
|
||||
if (async_req)
|
||||
dd->flags |= FLAGS_BUSY;
|
||||
set_bit(FLAGS_BUSY, &dd->flags);
|
||||
spin_unlock_irqrestore(&dd->lock, flags);
|
||||
|
||||
if (!async_req)
|
||||
|
@ -682,16 +690,12 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
|
|||
backlog->complete(backlog, -EINPROGRESS);
|
||||
|
||||
req = ahash_request_cast(async_req);
|
||||
|
||||
prev_req = dd->req;
|
||||
dd->req = req;
|
||||
|
||||
ctx = ahash_request_ctx(req);
|
||||
|
||||
dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n",
|
||||
ctx->op, req->nbytes);
|
||||
|
||||
|
||||
err = omap_sham_hw_init(dd);
|
||||
if (err)
|
||||
goto err1;
|
||||
|
@ -712,18 +716,16 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
|
|||
|
||||
if (ctx->op == OP_UPDATE) {
|
||||
err = omap_sham_update_req(dd);
|
||||
if (err != -EINPROGRESS && (ctx->flags & FLAGS_FINUP))
|
||||
if (err != -EINPROGRESS && (ctx->flags & BIT(FLAGS_FINUP)))
|
||||
/* no final() after finup() */
|
||||
err = omap_sham_final_req(dd);
|
||||
} else if (ctx->op == OP_FINAL) {
|
||||
err = omap_sham_final_req(dd);
|
||||
}
|
||||
err1:
|
||||
if (err != -EINPROGRESS) {
|
||||
if (err != -EINPROGRESS)
|
||||
/* done_task will not finish it, so do it here */
|
||||
omap_sham_finish_req(req, err);
|
||||
tasklet_schedule(&dd->queue_task);
|
||||
}
|
||||
|
||||
dev_dbg(dd->dev, "exit, err: %d\n", err);
|
||||
|
||||
|
@ -752,7 +754,7 @@ static int omap_sham_update(struct ahash_request *req)
|
|||
ctx->sg = req->src;
|
||||
ctx->offset = 0;
|
||||
|
||||
if (ctx->flags & FLAGS_FINUP) {
|
||||
if (ctx->flags & BIT(FLAGS_FINUP)) {
|
||||
if ((ctx->digcnt + ctx->bufcnt + ctx->total) < 9) {
|
||||
/*
|
||||
* OMAP HW accel works only with buffers >= 9
|
||||
|
@ -765,7 +767,7 @@ static int omap_sham_update(struct ahash_request *req)
|
|||
/*
|
||||
* faster to use CPU for short transfers
|
||||
*/
|
||||
ctx->flags |= FLAGS_CPU;
|
||||
ctx->flags |= BIT(FLAGS_CPU);
|
||||
}
|
||||
} else if (ctx->bufcnt + ctx->total < ctx->buflen) {
|
||||
omap_sham_append_sg(ctx);
|
||||
|
@ -802,9 +804,9 @@ static int omap_sham_final(struct ahash_request *req)
|
|||
{
|
||||
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
|
||||
|
||||
ctx->flags |= FLAGS_FINUP;
|
||||
ctx->flags |= BIT(FLAGS_FINUP);
|
||||
|
||||
if (ctx->flags & FLAGS_ERROR)
|
||||
if (ctx->flags & BIT(FLAGS_ERROR))
|
||||
return 0; /* uncompleted hash is not needed */
|
||||
|
||||
/* OMAP HW accel works only with buffers >= 9 */
|
||||
|
@ -823,7 +825,7 @@ static int omap_sham_finup(struct ahash_request *req)
|
|||
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
|
||||
int err1, err2;
|
||||
|
||||
ctx->flags |= FLAGS_FINUP;
|
||||
ctx->flags |= BIT(FLAGS_FINUP);
|
||||
|
||||
err1 = omap_sham_update(req);
|
||||
if (err1 == -EINPROGRESS || err1 == -EBUSY)
|
||||
|
@ -895,7 +897,7 @@ static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
|
|||
|
||||
if (alg_base) {
|
||||
struct omap_sham_hmac_ctx *bctx = tctx->base;
|
||||
tctx->flags |= FLAGS_HMAC;
|
||||
tctx->flags |= BIT(FLAGS_HMAC);
|
||||
bctx->shash = crypto_alloc_shash(alg_base, 0,
|
||||
CRYPTO_ALG_NEED_FALLBACK);
|
||||
if (IS_ERR(bctx->shash)) {
|
||||
|
@ -932,7 +934,7 @@ static void omap_sham_cra_exit(struct crypto_tfm *tfm)
|
|||
crypto_free_shash(tctx->fallback);
|
||||
tctx->fallback = NULL;
|
||||
|
||||
if (tctx->flags & FLAGS_HMAC) {
|
||||
if (tctx->flags & BIT(FLAGS_HMAC)) {
|
||||
struct omap_sham_hmac_ctx *bctx = tctx->base;
|
||||
crypto_free_shash(bctx->shash);
|
||||
}
|
||||
|
@ -1036,51 +1038,46 @@ static struct ahash_alg algs[] = {
|
|||
static void omap_sham_done_task(unsigned long data)
|
||||
{
|
||||
struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
|
||||
struct ahash_request *req = dd->req;
|
||||
struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
|
||||
int ready = 0, err = 0;
|
||||
int err = 0;
|
||||
|
||||
if (ctx->flags & FLAGS_OUTPUT_READY) {
|
||||
ctx->flags &= ~FLAGS_OUTPUT_READY;
|
||||
ready = 1;
|
||||
}
|
||||
|
||||
if (dd->flags & FLAGS_DMA_ACTIVE) {
|
||||
dd->flags &= ~FLAGS_DMA_ACTIVE;
|
||||
omap_sham_update_dma_stop(dd);
|
||||
if (!dd->err)
|
||||
err = omap_sham_update_dma_start(dd);
|
||||
}
|
||||
|
||||
err = dd->err ? : err;
|
||||
|
||||
if (err != -EINPROGRESS && (ready || err)) {
|
||||
dev_dbg(dd->dev, "update done: err: %d\n", err);
|
||||
/* finish curent request */
|
||||
omap_sham_finish_req(req, err);
|
||||
/* start new request */
|
||||
if (!test_bit(FLAGS_BUSY, &dd->flags)) {
|
||||
omap_sham_handle_queue(dd, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void omap_sham_queue_task(unsigned long data)
|
||||
{
|
||||
struct omap_sham_dev *dd = (struct omap_sham_dev *)data;
|
||||
if (test_bit(FLAGS_CPU, &dd->flags)) {
|
||||
if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags))
|
||||
goto finish;
|
||||
} else if (test_bit(FLAGS_DMA_READY, &dd->flags)) {
|
||||
if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) {
|
||||
omap_sham_update_dma_stop(dd);
|
||||
if (dd->err) {
|
||||
err = dd->err;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) {
|
||||
/* hash or semi-hash ready */
|
||||
clear_bit(FLAGS_DMA_READY, &dd->flags);
|
||||
err = omap_sham_update_dma_start(dd);
|
||||
if (err != -EINPROGRESS)
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
omap_sham_handle_queue(dd, NULL);
|
||||
return;
|
||||
|
||||
finish:
|
||||
dev_dbg(dd->dev, "update done: err: %d\n", err);
|
||||
/* finish curent request */
|
||||
omap_sham_finish_req(dd->req, err);
|
||||
}
|
||||
|
||||
static irqreturn_t omap_sham_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct omap_sham_dev *dd = dev_id;
|
||||
struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req);
|
||||
|
||||
if (!ctx) {
|
||||
dev_err(dd->dev, "unknown interrupt.\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (unlikely(ctx->flags & FLAGS_FINAL))
|
||||
if (unlikely(test_bit(FLAGS_FINAL, &dd->flags)))
|
||||
/* final -> allow device to go to power-saving mode */
|
||||
omap_sham_write_mask(dd, SHA_REG_CTRL, 0, SHA_REG_CTRL_LENGTH);
|
||||
|
||||
|
@ -1088,8 +1085,12 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id)
|
|||
SHA_REG_CTRL_OUTPUT_READY);
|
||||
omap_sham_read(dd, SHA_REG_CTRL);
|
||||
|
||||
ctx->flags |= FLAGS_OUTPUT_READY;
|
||||
dd->err = 0;
|
||||
if (!test_bit(FLAGS_BUSY, &dd->flags)) {
|
||||
dev_warn(dd->dev, "Interrupt when no active requests.\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
set_bit(FLAGS_OUTPUT_READY, &dd->flags);
|
||||
tasklet_schedule(&dd->done_task);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
@ -1102,9 +1103,10 @@ static void omap_sham_dma_callback(int lch, u16 ch_status, void *data)
|
|||
if (ch_status != OMAP_DMA_BLOCK_IRQ) {
|
||||
pr_err("omap-sham DMA error status: 0x%hx\n", ch_status);
|
||||
dd->err = -EIO;
|
||||
dd->flags &= ~FLAGS_INIT; /* request to re-initialize */
|
||||
clear_bit(FLAGS_INIT, &dd->flags);/* request to re-initialize */
|
||||
}
|
||||
|
||||
set_bit(FLAGS_DMA_READY, &dd->flags);
|
||||
tasklet_schedule(&dd->done_task);
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1153,6 @@ static int __devinit omap_sham_probe(struct platform_device *pdev)
|
|||
INIT_LIST_HEAD(&dd->list);
|
||||
spin_lock_init(&dd->lock);
|
||||
tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd);
|
||||
tasklet_init(&dd->queue_task, omap_sham_queue_task, (unsigned long)dd);
|
||||
crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH);
|
||||
|
||||
dd->irq = -1;
|
||||
|
@ -1260,7 +1261,6 @@ static int __devexit omap_sham_remove(struct platform_device *pdev)
|
|||
for (i = 0; i < ARRAY_SIZE(algs); i++)
|
||||
crypto_unregister_ahash(&algs[i]);
|
||||
tasklet_kill(&dd->done_task);
|
||||
tasklet_kill(&dd->queue_task);
|
||||
iounmap(dd->io_base);
|
||||
clk_put(dd->iclk);
|
||||
omap_sham_dma_cleanup(dd);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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:
|
||||
* Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
@ -282,6 +282,7 @@ static int init_device(struct device *dev)
|
|||
/**
|
||||
* talitos_submit - submits a descriptor to the device for processing
|
||||
* @dev: the SEC device to be used
|
||||
* @ch: the SEC device channel to be used
|
||||
* @desc: the descriptor to be processed by the device
|
||||
* @callback: whom to call when processing is complete
|
||||
* @context: a handle for use by caller (optional)
|
||||
|
@ -290,7 +291,7 @@ static int init_device(struct device *dev)
|
|||
* callback must check err and feedback in descriptor header
|
||||
* 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,
|
||||
struct talitos_desc *desc,
|
||||
void *context, int error),
|
||||
|
@ -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_request *request;
|
||||
unsigned long flags, ch;
|
||||
unsigned long flags;
|
||||
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);
|
||||
|
||||
if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
|
||||
|
@ -706,6 +701,7 @@ static void talitos_unregister_rng(struct device *dev)
|
|||
|
||||
struct talitos_ctx {
|
||||
struct device *dev;
|
||||
int ch;
|
||||
__be32 desc_hdr_template;
|
||||
u8 key[TALITOS_MAX_KEY_SIZE];
|
||||
u8 iv[TALITOS_MAX_IV_LENGTH];
|
||||
|
@ -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,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
ret = talitos_submit(dev, desc, callback, areq);
|
||||
ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
|
||||
if (ret != -EINPROGRESS) {
|
||||
ipsec_esp_unmap(dev, edesc, areq);
|
||||
kfree(edesc);
|
||||
|
@ -1382,22 +1378,11 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
|
|||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
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);
|
||||
ctx->keylen = keylen;
|
||||
|
||||
return 0;
|
||||
|
||||
badkey:
|
||||
crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void common_nonsnoop_unmap(struct device *dev,
|
||||
|
@ -1433,7 +1418,6 @@ static void ablkcipher_done(struct device *dev,
|
|||
|
||||
static int common_nonsnoop(struct talitos_edesc *edesc,
|
||||
struct ablkcipher_request *areq,
|
||||
u8 *giv,
|
||||
void (*callback) (struct device *dev,
|
||||
struct talitos_desc *desc,
|
||||
void *context, int error))
|
||||
|
@ -1453,7 +1437,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
|
|||
|
||||
/* cipher iv */
|
||||
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);
|
||||
|
||||
/* cipher key */
|
||||
|
@ -1524,7 +1508,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
|
|||
to_talitos_ptr(&desc->ptr[6], 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) {
|
||||
common_nonsnoop_unmap(dev, edesc, areq);
|
||||
kfree(edesc);
|
||||
|
@ -1556,7 +1540,7 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq)
|
|||
/* set 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)
|
||||
|
@ -1572,7 +1556,7 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)
|
|||
|
||||
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,
|
||||
|
@ -1703,7 +1687,7 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
|
|||
/* last DWORD empty */
|
||||
desc->ptr[6] = zero_entry;
|
||||
|
||||
ret = talitos_submit(dev, desc, callback, areq);
|
||||
ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
|
||||
if (ret != -EINPROGRESS) {
|
||||
common_nonsnoop_hash_unmap(dev, edesc, areq);
|
||||
kfree(edesc);
|
||||
|
@ -2244,6 +2228,7 @@ static int talitos_cra_init(struct crypto_tfm *tfm)
|
|||
struct crypto_alg *alg = tfm->__crt_alg;
|
||||
struct talitos_crypto_alg *talitos_alg;
|
||||
struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
struct talitos_private *priv;
|
||||
|
||||
if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
|
||||
talitos_alg = container_of(__crypto_ahash_alg(alg),
|
||||
|
@ -2256,9 +2241,17 @@ static int talitos_cra_init(struct crypto_tfm *tfm)
|
|||
/* update context with ptr to 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 */
|
||||
ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template;
|
||||
|
||||
/* select done notification */
|
||||
ctx->desc_hdr_template |= DESC_HDR_DONE_NOTIFY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user