diff options
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/Kconfig | 44 | ||||
| -rw-r--r-- | crypto/Makefile | 5 | ||||
| -rw-r--r-- | crypto/ablkcipher.c | 19 | ||||
| -rw-r--r-- | crypto/aead.c | 16 | ||||
| -rw-r--r-- | crypto/algboss.c | 20 | ||||
| -rw-r--r-- | crypto/ansi_cprng.c | 17 | ||||
| -rw-r--r-- | crypto/api.c | 17 | ||||
| -rw-r--r-- | crypto/blkcipher.c | 2 | ||||
| -rw-r--r-- | crypto/chainiv.c | 3 | ||||
| -rw-r--r-- | crypto/cryptd.c | 237 | ||||
| -rw-r--r-- | crypto/crypto_wq.c | 38 | ||||
| -rw-r--r-- | crypto/gf128mul.c | 2 | ||||
| -rw-r--r-- | crypto/internal.h | 6 | ||||
| -rw-r--r-- | crypto/pcompress.c | 97 | ||||
| -rw-r--r-- | crypto/sha256_generic.c | 2 | ||||
| -rw-r--r-- | crypto/shash.c | 20 | ||||
| -rw-r--r-- | crypto/tcrypt.c | 6 | ||||
| -rw-r--r-- | crypto/testmgr.c | 198 | ||||
| -rw-r--r-- | crypto/testmgr.h | 147 | ||||
| -rw-r--r-- | crypto/zlib.c | 378 |
20 files changed, 1130 insertions, 144 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 8dde4fcf99c9..74d0e622a515 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
| @@ -56,6 +56,7 @@ config CRYPTO_BLKCIPHER2 | |||
| 56 | tristate | 56 | tristate |
| 57 | select CRYPTO_ALGAPI2 | 57 | select CRYPTO_ALGAPI2 |
| 58 | select CRYPTO_RNG2 | 58 | select CRYPTO_RNG2 |
| 59 | select CRYPTO_WORKQUEUE | ||
| 59 | 60 | ||
| 60 | config CRYPTO_HASH | 61 | config CRYPTO_HASH |
| 61 | tristate | 62 | tristate |
| @@ -75,6 +76,10 @@ config CRYPTO_RNG2 | |||
| 75 | tristate | 76 | tristate |
| 76 | select CRYPTO_ALGAPI2 | 77 | select CRYPTO_ALGAPI2 |
| 77 | 78 | ||
| 79 | config CRYPTO_PCOMP | ||
| 80 | tristate | ||
| 81 | select CRYPTO_ALGAPI2 | ||
| 82 | |||
| 78 | config CRYPTO_MANAGER | 83 | config CRYPTO_MANAGER |
| 79 | tristate "Cryptographic algorithm manager" | 84 | tristate "Cryptographic algorithm manager" |
| 80 | select CRYPTO_MANAGER2 | 85 | select CRYPTO_MANAGER2 |
| @@ -87,6 +92,7 @@ config CRYPTO_MANAGER2 | |||
| 87 | select CRYPTO_AEAD2 | 92 | select CRYPTO_AEAD2 |
| 88 | select CRYPTO_HASH2 | 93 | select CRYPTO_HASH2 |
| 89 | select CRYPTO_BLKCIPHER2 | 94 | select CRYPTO_BLKCIPHER2 |
| 95 | select CRYPTO_PCOMP | ||
| 90 | 96 | ||
| 91 | config CRYPTO_GF128MUL | 97 | config CRYPTO_GF128MUL |
| 92 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" | 98 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" |
| @@ -106,11 +112,15 @@ config CRYPTO_NULL | |||
| 106 | help | 112 | help |
| 107 | These are 'Null' algorithms, used by IPsec, which do nothing. | 113 | These are 'Null' algorithms, used by IPsec, which do nothing. |
| 108 | 114 | ||
| 115 | config CRYPTO_WORKQUEUE | ||
| 116 | tristate | ||
| 117 | |||
| 109 | config CRYPTO_CRYPTD | 118 | config CRYPTO_CRYPTD |
| 110 | tristate "Software async crypto daemon" | 119 | tristate "Software async crypto daemon" |
| 111 | select CRYPTO_BLKCIPHER | 120 | select CRYPTO_BLKCIPHER |
| 112 | select CRYPTO_HASH | 121 | select CRYPTO_HASH |
| 113 | select CRYPTO_MANAGER | 122 | select CRYPTO_MANAGER |
| 123 | select CRYPTO_WORKQUEUE | ||
| 114 | help | 124 | help |
| 115 | This is a generic software asynchronous crypto daemon that | 125 | This is a generic software asynchronous crypto daemon that |
| 116 | converts an arbitrary synchronous software crypto algorithm | 126 | converts an arbitrary synchronous software crypto algorithm |
| @@ -470,6 +480,31 @@ config CRYPTO_AES_X86_64 | |||
| 470 | 480 | ||
| 471 | See <http://csrc.nist.gov/encryption/aes/> for more information. | 481 | See <http://csrc.nist.gov/encryption/aes/> for more information. |
| 472 | 482 | ||
| 483 | config CRYPTO_AES_NI_INTEL | ||
| 484 | tristate "AES cipher algorithms (AES-NI)" | ||
| 485 | depends on (X86 || UML_X86) && 64BIT | ||
| 486 | select CRYPTO_AES_X86_64 | ||
| 487 | select CRYPTO_CRYPTD | ||
| 488 | select CRYPTO_ALGAPI | ||
| 489 | help | ||
| 490 | Use Intel AES-NI instructions for AES algorithm. | ||
| 491 | |||
| 492 | AES cipher algorithms (FIPS-197). AES uses the Rijndael | ||
| 493 | algorithm. | ||
| 494 | |||
| 495 | Rijndael appears to be consistently a very good performer in | ||
| 496 | both hardware and software across a wide range of computing | ||
| 497 | environments regardless of its use in feedback or non-feedback | ||
| 498 | modes. Its key setup time is excellent, and its key agility is | ||
| 499 | good. Rijndael's very low memory requirements make it very well | ||
| 500 | suited for restricted-space environments, in which it also | ||
| 501 | demonstrates excellent performance. Rijndael's operations are | ||
| 502 | among the easiest to defend against power and timing attacks. | ||
| 503 | |||
| 504 | The AES specifies three key sizes: 128, 192 and 256 bits | ||
| 505 | |||
| 506 | See <http://csrc.nist.gov/encryption/aes/> for more information. | ||
| 507 | |||
| 473 | config CRYPTO_ANUBIS | 508 | config CRYPTO_ANUBIS |
| 474 | tristate "Anubis cipher algorithm" | 509 | tristate "Anubis cipher algorithm" |
| 475 | select CRYPTO_ALGAPI | 510 | select CRYPTO_ALGAPI |
| @@ -714,6 +749,15 @@ config CRYPTO_DEFLATE | |||
| 714 | 749 | ||
| 715 | You will most probably want this if using IPSec. | 750 | You will most probably want this if using IPSec. |
| 716 | 751 | ||
| 752 | config CRYPTO_ZLIB | ||
| 753 | tristate "Zlib compression algorithm" | ||
| 754 | select CRYPTO_PCOMP | ||
| 755 | select ZLIB_INFLATE | ||
| 756 | select ZLIB_DEFLATE | ||
| 757 | select NLATTR | ||
| 758 | help | ||
| 759 | This is the zlib algorithm. | ||
| 760 | |||
| 717 | config CRYPTO_LZO | 761 | config CRYPTO_LZO |
| 718 | tristate "LZO compression algorithm" | 762 | tristate "LZO compression algorithm" |
| 719 | select CRYPTO_ALGAPI | 763 | select CRYPTO_ALGAPI |
diff --git a/crypto/Makefile b/crypto/Makefile index 46b08bf2035f..673d9f7c1bda 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | obj-$(CONFIG_CRYPTO) += crypto.o | 5 | obj-$(CONFIG_CRYPTO) += crypto.o |
| 6 | crypto-objs := api.o cipher.o digest.o compress.o | 6 | crypto-objs := api.o cipher.o digest.o compress.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o | ||
| 9 | |||
| 8 | obj-$(CONFIG_CRYPTO_FIPS) += fips.o | 10 | obj-$(CONFIG_CRYPTO_FIPS) += fips.o |
| 9 | 11 | ||
| 10 | crypto_algapi-$(CONFIG_PROC_FS) += proc.o | 12 | crypto_algapi-$(CONFIG_PROC_FS) += proc.o |
| @@ -25,6 +27,8 @@ crypto_hash-objs += ahash.o | |||
| 25 | crypto_hash-objs += shash.o | 27 | crypto_hash-objs += shash.o |
| 26 | obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o | 28 | obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o |
| 27 | 29 | ||
| 30 | obj-$(CONFIG_CRYPTO_PCOMP) += pcompress.o | ||
| 31 | |||
| 28 | cryptomgr-objs := algboss.o testmgr.o | 32 | cryptomgr-objs := algboss.o testmgr.o |
| 29 | 33 | ||
| 30 | obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o | 34 | obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o |
| @@ -70,6 +74,7 @@ obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o | |||
| 70 | obj-$(CONFIG_CRYPTO_SEED) += seed.o | 74 | obj-$(CONFIG_CRYPTO_SEED) += seed.o |
| 71 | obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o | 75 | obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o |
| 72 | obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o | 76 | obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o |
| 77 | obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o | ||
| 73 | obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o | 78 | obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o |
| 74 | obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o | 79 | obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o |
| 75 | obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o | 80 | obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o |
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 94140b3756fc..e11ce37c7104 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c | |||
| @@ -282,6 +282,25 @@ static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, | |||
| 282 | alg->cra_ablkcipher.ivsize)) | 282 | alg->cra_ablkcipher.ivsize)) |
| 283 | return alg; | 283 | return alg; |
| 284 | 284 | ||
| 285 | crypto_mod_put(alg); | ||
| 286 | alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED, | ||
| 287 | mask & ~CRYPTO_ALG_TESTED); | ||
| 288 | if (IS_ERR(alg)) | ||
| 289 | return alg; | ||
| 290 | |||
| 291 | if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
| 292 | CRYPTO_ALG_TYPE_GIVCIPHER) { | ||
| 293 | if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) { | ||
| 294 | crypto_mod_put(alg); | ||
| 295 | alg = ERR_PTR(-ENOENT); | ||
| 296 | } | ||
| 297 | return alg; | ||
| 298 | } | ||
| 299 | |||
| 300 | BUG_ON(!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
| 301 | CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : | ||
| 302 | alg->cra_ablkcipher.ivsize)); | ||
| 303 | |||
| 285 | return ERR_PTR(crypto_givcipher_default(alg, type, mask)); | 304 | return ERR_PTR(crypto_givcipher_default(alg, type, mask)); |
| 286 | } | 305 | } |
| 287 | 306 | ||
diff --git a/crypto/aead.c b/crypto/aead.c index 3a6f3f52c7c7..d9aa733db164 100644 --- a/crypto/aead.c +++ b/crypto/aead.c | |||
| @@ -422,6 +422,22 @@ static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, | |||
| 422 | if (!alg->cra_aead.ivsize) | 422 | if (!alg->cra_aead.ivsize) |
| 423 | return alg; | 423 | return alg; |
| 424 | 424 | ||
| 425 | crypto_mod_put(alg); | ||
| 426 | alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED, | ||
| 427 | mask & ~CRYPTO_ALG_TESTED); | ||
| 428 | if (IS_ERR(alg)) | ||
| 429 | return alg; | ||
| 430 | |||
| 431 | if (alg->cra_type == &crypto_aead_type) { | ||
| 432 | if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) { | ||
| 433 | crypto_mod_put(alg); | ||
| 434 | alg = ERR_PTR(-ENOENT); | ||
| 435 | } | ||
| 436 | return alg; | ||
| 437 | } | ||
| 438 | |||
| 439 | BUG_ON(!alg->cra_aead.ivsize); | ||
| 440 | |||
| 425 | return ERR_PTR(crypto_nivaead_default(alg, type, mask)); | 441 | return ERR_PTR(crypto_nivaead_default(alg, type, mask)); |
| 426 | } | 442 | } |
| 427 | 443 | ||
diff --git a/crypto/algboss.c b/crypto/algboss.c index 4601e4267c88..6906f92aeac0 100644 --- a/crypto/algboss.c +++ b/crypto/algboss.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | * | 10 | * |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/crypto.h> | 13 | #include <crypto/internal/aead.h> |
| 14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
| 15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| @@ -206,8 +206,7 @@ static int cryptomgr_test(void *data) | |||
| 206 | u32 type = param->type; | 206 | u32 type = param->type; |
| 207 | int err = 0; | 207 | int err = 0; |
| 208 | 208 | ||
| 209 | if (!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & | 209 | if (type & CRYPTO_ALG_TESTED) |
| 210 | CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV)) | ||
| 211 | goto skiptest; | 210 | goto skiptest; |
| 212 | 211 | ||
| 213 | err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED); | 212 | err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED); |
| @@ -223,6 +222,7 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg) | |||
| 223 | { | 222 | { |
| 224 | struct task_struct *thread; | 223 | struct task_struct *thread; |
| 225 | struct crypto_test_param *param; | 224 | struct crypto_test_param *param; |
| 225 | u32 type; | ||
| 226 | 226 | ||
| 227 | if (!try_module_get(THIS_MODULE)) | 227 | if (!try_module_get(THIS_MODULE)) |
| 228 | goto err; | 228 | goto err; |
| @@ -233,7 +233,19 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg) | |||
| 233 | 233 | ||
| 234 | memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver)); | 234 | memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver)); |
| 235 | memcpy(param->alg, alg->cra_name, sizeof(param->alg)); | 235 | memcpy(param->alg, alg->cra_name, sizeof(param->alg)); |
| 236 | param->type = alg->cra_flags; | 236 | type = alg->cra_flags; |
| 237 | |||
| 238 | /* This piece of crap needs to disappear into per-type test hooks. */ | ||
| 239 | if ((!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & | ||
| 240 | CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV) && | ||
| 241 | ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | ||
| 242 | CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : | ||
| 243 | alg->cra_ablkcipher.ivsize)) || | ||
| 244 | (!((type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK) && | ||
| 245 | alg->cra_type == &crypto_nivaead_type && alg->cra_aead.ivsize)) | ||
| 246 | type |= CRYPTO_ALG_TESTED; | ||
| 247 | |||
| 248 | param->type = type; | ||
| 237 | 249 | ||
| 238 | thread = kthread_run(cryptomgr_test, param, "cryptomgr_test"); | 250 | thread = kthread_run(cryptomgr_test, param, "cryptomgr_test"); |
| 239 | if (IS_ERR(thread)) | 251 | if (IS_ERR(thread)) |
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c index 0fac8ffc2fb7..d80ed4c1e009 100644 --- a/crypto/ansi_cprng.c +++ b/crypto/ansi_cprng.c | |||
| @@ -132,9 +132,15 @@ static int _get_more_prng_bytes(struct prng_context *ctx) | |||
| 132 | */ | 132 | */ |
| 133 | if (!memcmp(ctx->rand_data, ctx->last_rand_data, | 133 | if (!memcmp(ctx->rand_data, ctx->last_rand_data, |
| 134 | DEFAULT_BLK_SZ)) { | 134 | DEFAULT_BLK_SZ)) { |
| 135 | if (fips_enabled) { | ||
| 136 | panic("cprng %p Failed repetition check!\n", | ||
| 137 | ctx); | ||
| 138 | } | ||
| 139 | |||
| 135 | printk(KERN_ERR | 140 | printk(KERN_ERR |
| 136 | "ctx %p Failed repetition check!\n", | 141 | "ctx %p Failed repetition check!\n", |
| 137 | ctx); | 142 | ctx); |
| 143 | |||
| 138 | ctx->flags |= PRNG_NEED_RESET; | 144 | ctx->flags |= PRNG_NEED_RESET; |
| 139 | return -EINVAL; | 145 | return -EINVAL; |
| 140 | } | 146 | } |
| @@ -338,7 +344,16 @@ static int cprng_init(struct crypto_tfm *tfm) | |||
| 338 | 344 | ||
| 339 | spin_lock_init(&ctx->prng_lock); | 345 | spin_lock_init(&ctx->prng_lock); |
| 340 | 346 | ||
| 341 | return reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL); | 347 | if (reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL) < 0) |
| 348 | return -EINVAL; | ||
| 349 | |||
| 350 | /* | ||
| 351 | * after allocation, we should always force the user to reset | ||
| 352 | * so they don't inadvertently use the insecure default values | ||
| 353 | * without specifying them intentially | ||
| 354 | */ | ||
| 355 | ctx->flags |= PRNG_NEED_RESET; | ||
| 356 | return 0; | ||
| 342 | } | 357 | } |
| 343 | 358 | ||
| 344 | static void cprng_exit(struct crypto_tfm *tfm) | 359 | static void cprng_exit(struct crypto_tfm *tfm) |
diff --git a/crypto/api.c b/crypto/api.c index 38a2bc02a98c..314dab96840e 100644 --- a/crypto/api.c +++ b/crypto/api.c | |||
| @@ -255,7 +255,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) | |||
| 255 | struct crypto_alg *larval; | 255 | struct crypto_alg *larval; |
| 256 | int ok; | 256 | int ok; |
| 257 | 257 | ||
| 258 | if (!(mask & CRYPTO_ALG_TESTED)) { | 258 | if (!((type | mask) & CRYPTO_ALG_TESTED)) { |
| 259 | type |= CRYPTO_ALG_TESTED; | 259 | type |= CRYPTO_ALG_TESTED; |
| 260 | mask |= CRYPTO_ALG_TESTED; | 260 | mask |= CRYPTO_ALG_TESTED; |
| 261 | } | 261 | } |
| @@ -464,8 +464,8 @@ err: | |||
| 464 | } | 464 | } |
| 465 | EXPORT_SYMBOL_GPL(crypto_alloc_base); | 465 | EXPORT_SYMBOL_GPL(crypto_alloc_base); |
| 466 | 466 | ||
| 467 | struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg, | 467 | void *crypto_create_tfm(struct crypto_alg *alg, |
| 468 | const struct crypto_type *frontend) | 468 | const struct crypto_type *frontend) |
| 469 | { | 469 | { |
| 470 | char *mem; | 470 | char *mem; |
| 471 | struct crypto_tfm *tfm = NULL; | 471 | struct crypto_tfm *tfm = NULL; |
| @@ -499,9 +499,9 @@ out_free_tfm: | |||
| 499 | crypto_shoot_alg(alg); | 499 | crypto_shoot_alg(alg); |
| 500 | kfree(mem); | 500 | kfree(mem); |
| 501 | out_err: | 501 | out_err: |
| 502 | tfm = ERR_PTR(err); | 502 | mem = ERR_PTR(err); |
| 503 | out: | 503 | out: |
| 504 | return tfm; | 504 | return mem; |
| 505 | } | 505 | } |
| 506 | EXPORT_SYMBOL_GPL(crypto_create_tfm); | 506 | EXPORT_SYMBOL_GPL(crypto_create_tfm); |
| 507 | 507 | ||
| @@ -525,12 +525,11 @@ EXPORT_SYMBOL_GPL(crypto_create_tfm); | |||
| 525 | * | 525 | * |
| 526 | * In case of error the return value is an error pointer. | 526 | * In case of error the return value is an error pointer. |
| 527 | */ | 527 | */ |
| 528 | struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, | 528 | void *crypto_alloc_tfm(const char *alg_name, |
| 529 | const struct crypto_type *frontend, | 529 | const struct crypto_type *frontend, u32 type, u32 mask) |
| 530 | u32 type, u32 mask) | ||
| 531 | { | 530 | { |
| 532 | struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask); | 531 | struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask); |
| 533 | struct crypto_tfm *tfm; | 532 | void *tfm; |
| 534 | int err; | 533 | int err; |
| 535 | 534 | ||
| 536 | type &= frontend->maskclear; | 535 | type &= frontend->maskclear; |
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index d70a41c002df..90d26c91f4e9 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
| @@ -521,7 +521,7 @@ static int crypto_grab_nivcipher(struct crypto_skcipher_spawn *spawn, | |||
| 521 | int err; | 521 | int err; |
| 522 | 522 | ||
| 523 | type = crypto_skcipher_type(type); | 523 | type = crypto_skcipher_type(type); |
| 524 | mask = crypto_skcipher_mask(mask) | CRYPTO_ALG_GENIV; | 524 | mask = crypto_skcipher_mask(mask)| CRYPTO_ALG_GENIV; |
| 525 | 525 | ||
| 526 | alg = crypto_alg_mod_lookup(name, type, mask); | 526 | alg = crypto_alg_mod_lookup(name, type, mask); |
| 527 | if (IS_ERR(alg)) | 527 | if (IS_ERR(alg)) |
diff --git a/crypto/chainiv.c b/crypto/chainiv.c index 7c37a497b860..ba200b07449d 100644 --- a/crypto/chainiv.c +++ b/crypto/chainiv.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <crypto/internal/skcipher.h> | 16 | #include <crypto/internal/skcipher.h> |
| 17 | #include <crypto/rng.h> | 17 | #include <crypto/rng.h> |
| 18 | #include <crypto/crypto_wq.h> | ||
| 18 | #include <linux/err.h> | 19 | #include <linux/err.h> |
| 19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| @@ -133,7 +134,7 @@ static int async_chainiv_schedule_work(struct async_chainiv_ctx *ctx) | |||
| 133 | goto out; | 134 | goto out; |
| 134 | } | 135 | } |
| 135 | 136 | ||
| 136 | queued = schedule_work(&ctx->postponed); | 137 | queued = queue_work(kcrypto_wq, &ctx->postponed); |
| 137 | BUG_ON(!queued); | 138 | BUG_ON(!queued); |
| 138 | 139 | ||
| 139 | out: | 140 | out: |
diff --git a/crypto/cryptd.c b/crypto/cryptd.c index d29e06b350ff..d14b22658d7a 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c | |||
| @@ -12,30 +12,31 @@ | |||
| 12 | 12 | ||
| 13 | #include <crypto/algapi.h> | 13 | #include <crypto/algapi.h> |
| 14 | #include <crypto/internal/hash.h> | 14 | #include <crypto/internal/hash.h> |
| 15 | #include <crypto/cryptd.h> | ||
| 16 | #include <crypto/crypto_wq.h> | ||
| 15 | #include <linux/err.h> | 17 | #include <linux/err.h> |
| 16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 17 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 18 | #include <linux/kthread.h> | ||
| 19 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 21 | #include <linux/mutex.h> | ||
| 22 | #include <linux/scatterlist.h> | 22 | #include <linux/scatterlist.h> |
| 23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <linux/spinlock.h> | ||
| 26 | 25 | ||
| 27 | #define CRYPTD_MAX_QLEN 100 | 26 | #define CRYPTD_MAX_CPU_QLEN 100 |
| 28 | 27 | ||
| 29 | struct cryptd_state { | 28 | struct cryptd_cpu_queue { |
| 30 | spinlock_t lock; | ||
| 31 | struct mutex mutex; | ||
| 32 | struct crypto_queue queue; | 29 | struct crypto_queue queue; |
| 33 | struct task_struct *task; | 30 | struct work_struct work; |
| 31 | }; | ||
| 32 | |||
| 33 | struct cryptd_queue { | ||
| 34 | struct cryptd_cpu_queue *cpu_queue; | ||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | struct cryptd_instance_ctx { | 37 | struct cryptd_instance_ctx { |
| 37 | struct crypto_spawn spawn; | 38 | struct crypto_spawn spawn; |
| 38 | struct cryptd_state *state; | 39 | struct cryptd_queue *queue; |
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | struct cryptd_blkcipher_ctx { | 42 | struct cryptd_blkcipher_ctx { |
| @@ -54,11 +55,85 @@ struct cryptd_hash_request_ctx { | |||
| 54 | crypto_completion_t complete; | 55 | crypto_completion_t complete; |
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| 57 | static inline struct cryptd_state *cryptd_get_state(struct crypto_tfm *tfm) | 58 | static void cryptd_queue_worker(struct work_struct *work); |
| 59 | |||
| 60 | static int cryptd_init_queue(struct cryptd_queue *queue, | ||
| 61 | unsigned int max_cpu_qlen) | ||
| 62 | { | ||
| 63 | int cpu; | ||
| 64 | struct cryptd_cpu_queue *cpu_queue; | ||
| 65 | |||
| 66 | queue->cpu_queue = alloc_percpu(struct cryptd_cpu_queue); | ||
| 67 | if (!queue->cpu_queue) | ||
| 68 | return -ENOMEM; | ||
| 69 | for_each_possible_cpu(cpu) { | ||
| 70 | cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu); | ||
| 71 | crypto_init_queue(&cpu_queue->queue, max_cpu_qlen); | ||
| 72 | INIT_WORK(&cpu_queue->work, cryptd_queue_worker); | ||
| 73 | } | ||
| 74 | return 0; | ||
| 75 | } | ||
| 76 | |||
| 77 | static void cryptd_fini_queue(struct cryptd_queue *queue) | ||
| 78 | { | ||
| 79 | int cpu; | ||
| 80 | struct cryptd_cpu_queue *cpu_queue; | ||
| 81 | |||
| 82 | for_each_possible_cpu(cpu) { | ||
| 83 | cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu); | ||
| 84 | BUG_ON(cpu_queue->queue.qlen); | ||
| 85 | } | ||
| 86 | free_percpu(queue->cpu_queue); | ||
| 87 | } | ||
| 88 | |||
| 89 | static int cryptd_enqueue_request(struct cryptd_queue *queue, | ||
| 90 | struct crypto_async_request *request) | ||
| 91 | { | ||
| 92 | int cpu, err; | ||
| 93 | struct cryptd_cpu_queue *cpu_queue; | ||
| 94 | |||
| 95 | cpu = get_cpu(); | ||
| 96 | cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu); | ||
| 97 | err = crypto_enqueue_request(&cpu_queue->queue, request); | ||
| 98 | queue_work_on(cpu, kcrypto_wq, &cpu_queue->work); | ||
| 99 | put_cpu(); | ||
| 100 | |||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* Called in workqueue context, do one real cryption work (via | ||
| 105 | * req->complete) and reschedule itself if there are more work to | ||
| 106 | * do. */ | ||
| 107 | static void cryptd_queue_worker(struct work_struct *work) | ||
| 108 | { | ||
| 109 | struct cryptd_cpu_queue *cpu_queue; | ||
| 110 | struct crypto_async_request *req, *backlog; | ||
| 111 | |||
| 112 | cpu_queue = container_of(work, struct cryptd_cpu_queue, work); | ||
| 113 | /* Only handle one request at a time to avoid hogging crypto | ||
| 114 | * workqueue. preempt_disable/enable is used to prevent | ||
| 115 | * being preempted by cryptd_enqueue_request() */ | ||
| 116 | preempt_disable(); | ||
| 117 | backlog = crypto_get_backlog(&cpu_queue->queue); | ||
| 118 | req = crypto_dequeue_request(&cpu_queue->queue); | ||
| 119 | preempt_enable(); | ||
| 120 | |||
| 121 | if (!req) | ||
| 122 | return; | ||
| 123 | |||
| 124 | if (backlog) | ||
| 125 | backlog->complete(backlog, -EINPROGRESS); | ||
| 126 | req->complete(req, 0); | ||
| 127 | |||
| 128 | if (cpu_queue->queue.qlen) | ||
| 129 | queue_work(kcrypto_wq, &cpu_queue->work); | ||
| 130 | } | ||
| 131 | |||
| 132 | static inline struct cryptd_queue *cryptd_get_queue(struct crypto_tfm *tfm) | ||
| 58 | { | 133 | { |
| 59 | struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); | 134 | struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); |
| 60 | struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst); | 135 | struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst); |
| 61 | return ictx->state; | 136 | return ictx->queue; |
| 62 | } | 137 | } |
| 63 | 138 | ||
| 64 | static int cryptd_blkcipher_setkey(struct crypto_ablkcipher *parent, | 139 | static int cryptd_blkcipher_setkey(struct crypto_ablkcipher *parent, |
| @@ -130,19 +205,13 @@ static int cryptd_blkcipher_enqueue(struct ablkcipher_request *req, | |||
| 130 | { | 205 | { |
| 131 | struct cryptd_blkcipher_request_ctx *rctx = ablkcipher_request_ctx(req); | 206 | struct cryptd_blkcipher_request_ctx *rctx = ablkcipher_request_ctx(req); |
| 132 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | 207 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); |
| 133 | struct cryptd_state *state = | 208 | struct cryptd_queue *queue; |
| 134 | cryptd_get_state(crypto_ablkcipher_tfm(tfm)); | ||
| 135 | int err; | ||
| 136 | 209 | ||
| 210 | queue = cryptd_get_queue(crypto_ablkcipher_tfm(tfm)); | ||
| 137 | rctx->complete = req->base.complete; | 211 | rctx->complete = req->base.complete; |
| 138 | req->base.complete = complete; | 212 | req->base.complete = complete; |
| 139 | 213 | ||
| 140 | spin_lock_bh(&state->lock); | 214 | return cryptd_enqueue_request(queue, &req->base); |
| 141 | err = ablkcipher_enqueue_request(&state->queue, req); | ||
| 142 | spin_unlock_bh(&state->lock); | ||
| 143 | |||
| 144 | wake_up_process(state->task); | ||
| 145 | return err; | ||
| 146 | } | 215 | } |
| 147 | 216 | ||
| 148 | static int cryptd_blkcipher_encrypt_enqueue(struct ablkcipher_request *req) | 217 | static int cryptd_blkcipher_encrypt_enqueue(struct ablkcipher_request *req) |
| @@ -176,21 +245,12 @@ static int cryptd_blkcipher_init_tfm(struct crypto_tfm *tfm) | |||
| 176 | static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm) | 245 | static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm) |
| 177 | { | 246 | { |
| 178 | struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(tfm); | 247 | struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(tfm); |
| 179 | struct cryptd_state *state = cryptd_get_state(tfm); | ||
| 180 | int active; | ||
| 181 | |||
| 182 | mutex_lock(&state->mutex); | ||
| 183 | active = ablkcipher_tfm_in_queue(&state->queue, | ||
| 184 | __crypto_ablkcipher_cast(tfm)); | ||
| 185 | mutex_unlock(&state->mutex); | ||
| 186 | |||
| 187 | BUG_ON(active); | ||
| 188 | 248 | ||
| 189 | crypto_free_blkcipher(ctx->child); | 249 | crypto_free_blkcipher(ctx->child); |
| 190 | } | 250 | } |
| 191 | 251 | ||
| 192 | static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, | 252 | static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, |
| 193 | struct cryptd_state *state) | 253 | struct cryptd_queue *queue) |
| 194 | { | 254 | { |
| 195 | struct crypto_instance *inst; | 255 | struct crypto_instance *inst; |
| 196 | struct cryptd_instance_ctx *ctx; | 256 | struct cryptd_instance_ctx *ctx; |
| @@ -213,7 +273,7 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, | |||
| 213 | if (err) | 273 | if (err) |
| 214 | goto out_free_inst; | 274 | goto out_free_inst; |
| 215 | 275 | ||
| 216 | ctx->state = state; | 276 | ctx->queue = queue; |
| 217 | 277 | ||
| 218 | memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); | 278 | memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); |
| 219 | 279 | ||
| @@ -231,7 +291,7 @@ out_free_inst: | |||
| 231 | } | 291 | } |
| 232 | 292 | ||
| 233 | static struct crypto_instance *cryptd_alloc_blkcipher( | 293 | static struct crypto_instance *cryptd_alloc_blkcipher( |
| 234 | struct rtattr **tb, struct cryptd_state *state) | 294 | struct rtattr **tb, struct cryptd_queue *queue) |
| 235 | { | 295 | { |
| 236 | struct crypto_instance *inst; | 296 | struct crypto_instance *inst; |
| 237 | struct crypto_alg *alg; | 297 | struct crypto_alg *alg; |
| @@ -241,7 +301,7 @@ static struct crypto_instance *cryptd_alloc_blkcipher( | |||
| 241 | if (IS_ERR(alg)) | 301 | if (IS_ERR(alg)) |
| 242 | return ERR_CAST(alg); | 302 | return ERR_CAST(alg); |
| 243 | 303 | ||
| 244 | inst = cryptd_alloc_instance(alg, state); | 304 | inst = cryptd_alloc_instance(alg, queue); |
| 245 | if (IS_ERR(inst)) | 305 | if (IS_ERR(inst)) |
| 246 | goto out_put_alg; | 306 | goto out_put_alg; |
| 247 | 307 | ||
| @@ -289,15 +349,6 @@ static int cryptd_hash_init_tfm(struct crypto_tfm *tfm) | |||
| 289 | static void cryptd_hash_exit_tfm(struct crypto_tfm *tfm) | 349 | static void cryptd_hash_exit_tfm(struct crypto_tfm *tfm) |
| 290 | { | 350 | { |
| 291 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); | 351 | struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm); |
| 292 | struct cryptd_state *state = cryptd_get_state(tfm); | ||
| 293 | int active; | ||
| 294 | |||
| 295 | mutex_lock(&state->mutex); | ||
| 296 | active = ahash_tfm_in_queue(&state->queue, | ||
| 297 | __crypto_ahash_cast(tfm)); | ||
| 298 | mutex_unlock(&state->mutex); | ||
| 299 | |||
| 300 | BUG_ON(active); | ||
| 301 | 352 | ||
| 302 | crypto_free_hash(ctx->child); | 353 | crypto_free_hash(ctx->child); |
| 303 | } | 354 | } |
| @@ -323,19 +374,13 @@ static int cryptd_hash_enqueue(struct ahash_request *req, | |||
| 323 | { | 374 | { |
| 324 | struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); | 375 | struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req); |
| 325 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 376 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
| 326 | struct cryptd_state *state = | 377 | struct cryptd_queue *queue = |
| 327 | cryptd_get_state(crypto_ahash_tfm(tfm)); | 378 | cryptd_get_queue(crypto_ahash_tfm(tfm)); |
| 328 | int err; | ||
| 329 | 379 | ||
| 330 | rctx->complete = req->base.complete; | 380 | rctx->complete = req->base.complete; |
| 331 | req->base.complete = complete; | 381 | req->base.complete = complete; |
| 332 | 382 | ||
| 333 | spin_lock_bh(&state->lock); | 383 | return cryptd_enqueue_request(queue, &req->base); |
| 334 | err = ahash_enqueue_request(&state->queue, req); | ||
| 335 | spin_unlock_bh(&state->lock); | ||
| 336 | |||
| 337 | wake_up_process(state->task); | ||
| 338 | return err; | ||
| 339 | } | 384 | } |
| 340 | 385 | ||
| 341 | static void cryptd_hash_init(struct crypto_async_request *req_async, int err) | 386 | static void cryptd_hash_init(struct crypto_async_request *req_async, int err) |
| @@ -468,7 +513,7 @@ static int cryptd_hash_digest_enqueue(struct ahash_request *req) | |||
| 468 | } | 513 | } |
| 469 | 514 | ||
| 470 | static struct crypto_instance *cryptd_alloc_hash( | 515 | static struct crypto_instance *cryptd_alloc_hash( |
| 471 | struct rtattr **tb, struct cryptd_state *state) | 516 | struct rtattr **tb, struct cryptd_queue *queue) |
| 472 | { | 517 | { |
| 473 | struct crypto_instance *inst; | 518 | struct crypto_instance *inst; |
| 474 | struct crypto_alg *alg; | 519 | struct crypto_alg *alg; |
| @@ -478,7 +523,7 @@ static struct crypto_instance *cryptd_alloc_hash( | |||
| 478 | if (IS_ERR(alg)) | 523 | if (IS_ERR(alg)) |
| 479 | return ERR_PTR(PTR_ERR(alg)); | 524 | return ERR_PTR(PTR_ERR(alg)); |
| 480 | 525 | ||
| 481 | inst = cryptd_alloc_instance(alg, state); | 526 | inst = cryptd_alloc_instance(alg, queue); |
| 482 | if (IS_ERR(inst)) | 527 | if (IS_ERR(inst)) |
| 483 | goto out_put_alg; | 528 | goto out_put_alg; |
| 484 | 529 | ||
| @@ -502,7 +547,7 @@ out_put_alg: | |||
| 502 | return inst; | 547 | return inst; |
| 503 | } | 548 | } |
| 504 | 549 | ||
| 505 | static struct cryptd_state state; | 550 | static struct cryptd_queue queue; |
| 506 | 551 | ||
| 507 | static struct crypto_instance *cryptd_alloc(struct rtattr **tb) | 552 | static struct crypto_instance *cryptd_alloc(struct rtattr **tb) |
| 508 | { | 553 | { |
| @@ -514,9 +559,9 @@ static struct crypto_instance *cryptd_alloc(struct rtattr **tb) | |||
| 514 | 559 | ||
| 515 | switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) { | 560 | switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) { |
| 516 | case CRYPTO_ALG_TYPE_BLKCIPHER: | 561 | case CRYPTO_ALG_TYPE_BLKCIPHER: |
| 517 | return cryptd_alloc_blkcipher(tb, &state); | 562 | return cryptd_alloc_blkcipher(tb, &queue); |
| 518 | case CRYPTO_ALG_TYPE_DIGEST: | 563 | case CRYPTO_ALG_TYPE_DIGEST: |
| 519 | return cryptd_alloc_hash(tb, &state); | 564 | return cryptd_alloc_hash(tb, &queue); |
| 520 | } | 565 | } |
| 521 | 566 | ||
| 522 | return ERR_PTR(-EINVAL); | 567 | return ERR_PTR(-EINVAL); |
| @@ -537,82 +582,58 @@ static struct crypto_template cryptd_tmpl = { | |||
| 537 | .module = THIS_MODULE, | 582 | .module = THIS_MODULE, |
| 538 | }; | 583 | }; |
| 539 | 584 | ||
| 540 | static inline int cryptd_create_thread(struct cryptd_state *state, | 585 | struct cryptd_ablkcipher *cryptd_alloc_ablkcipher(const char *alg_name, |
| 541 | int (*fn)(void *data), const char *name) | 586 | u32 type, u32 mask) |
| 542 | { | 587 | { |
| 543 | spin_lock_init(&state->lock); | 588 | char cryptd_alg_name[CRYPTO_MAX_ALG_NAME]; |
| 544 | mutex_init(&state->mutex); | 589 | struct crypto_ablkcipher *tfm; |
| 545 | crypto_init_queue(&state->queue, CRYPTD_MAX_QLEN); | 590 | |
| 546 | 591 | if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME, | |
| 547 | state->task = kthread_run(fn, state, name); | 592 | "cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME) |
| 548 | if (IS_ERR(state->task)) | 593 | return ERR_PTR(-EINVAL); |
| 549 | return PTR_ERR(state->task); | 594 | tfm = crypto_alloc_ablkcipher(cryptd_alg_name, type, mask); |
| 595 | if (IS_ERR(tfm)) | ||
| 596 | return ERR_CAST(tfm); | ||
| 597 | if (crypto_ablkcipher_tfm(tfm)->__crt_alg->cra_module != THIS_MODULE) { | ||
| 598 | crypto_free_ablkcipher(tfm); | ||
| 599 | return ERR_PTR(-EINVAL); | ||
| 600 | } | ||
| 550 | 601 | ||
| 551 | return 0; | 602 | return __cryptd_ablkcipher_cast(tfm); |
| 552 | } | 603 | } |
| 604 | EXPORT_SYMBOL_GPL(cryptd_alloc_ablkcipher); | ||
| 553 | 605 | ||
| 554 | static inline void cryptd_stop_thread(struct cryptd_state *state) | 606 | struct crypto_blkcipher *cryptd_ablkcipher_child(struct cryptd_ablkcipher *tfm) |
| 555 | { | 607 | { |
| 556 | BUG_ON(state->queue.qlen); | 608 | struct cryptd_blkcipher_ctx *ctx = crypto_ablkcipher_ctx(&tfm->base); |
| 557 | kthread_stop(state->task); | 609 | return ctx->child; |
| 558 | } | 610 | } |
| 611 | EXPORT_SYMBOL_GPL(cryptd_ablkcipher_child); | ||
| 559 | 612 | ||
| 560 | static int cryptd_thread(void *data) | 613 | void cryptd_free_ablkcipher(struct cryptd_ablkcipher *tfm) |
| 561 | { | 614 | { |
| 562 | struct cryptd_state *state = data; | 615 | crypto_free_ablkcipher(&tfm->base); |
| 563 | int stop; | ||
| 564 | |||
| 565 | current->flags |= PF_NOFREEZE; | ||
| 566 | |||
| 567 | do { | ||
| 568 | struct crypto_async_request *req, *backlog; | ||
| 569 | |||
| 570 | mutex_lock(&state->mutex); | ||
| 571 | __set_current_state(TASK_INTERRUPTIBLE); | ||
| 572 | |||
| 573 | spin_lock_bh(&state->lock); | ||
| 574 | backlog = crypto_get_backlog(&state->queue); | ||
| 575 | req = crypto_dequeue_request(&state->queue); | ||
| 576 | spin_unlock_bh(&state->lock); | ||
| 577 | |||
| 578 | stop = kthread_should_stop(); | ||
| 579 | |||
| 580 | if (stop || req) { | ||
| 581 | __set_current_state(TASK_RUNNING); | ||
| 582 | if (req) { | ||
| 583 | if (backlog) | ||
| 584 | backlog->complete(backlog, | ||
| 585 | -EINPROGRESS); | ||
| 586 | req->complete(req, 0); | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 590 | mutex_unlock(&state->mutex); | ||
| 591 | |||
| 592 | schedule(); | ||
| 593 | } while (!stop); | ||
| 594 | |||
| 595 | return 0; | ||
| 596 | } | 616 | } |
| 617 | EXPORT_SYMBOL_GPL(cryptd_free_ablkcipher); | ||
| 597 | 618 | ||
| 598 | static int __init cryptd_init(void) | 619 | static int __init cryptd_init(void) |
| 599 | { | 620 | { |
| 600 | int err; | 621 | int err; |
| 601 | 622 | ||
| 602 | err = cryptd_create_thread(&state, cryptd_thread, "cryptd"); | 623 | err = cryptd_init_queue(&queue, CRYPTD_MAX_CPU_QLEN); |
| 603 | if (err) | 624 | if (err) |
| 604 | return err; | 625 | return err; |
| 605 | 626 | ||
| 606 | err = crypto_register_template(&cryptd_tmpl); | 627 | err = crypto_register_template(&cryptd_tmpl); |
| 607 | if (err) | 628 | if (err) |
| 608 | kthread_stop(state.task); | 629 | cryptd_fini_queue(&queue); |
| 609 | 630 | ||
| 610 | return err; | 631 | return err; |
| 611 | } | 632 | } |
| 612 | 633 | ||
| 613 | static void __exit cryptd_exit(void) | 634 | static void __exit cryptd_exit(void) |
| 614 | { | 635 | { |
| 615 | cryptd_stop_thread(&state); | 636 | cryptd_fini_queue(&queue); |
| 616 | crypto_unregister_template(&cryptd_tmpl); | 637 | crypto_unregister_template(&cryptd_tmpl); |
| 617 | } | 638 | } |
| 618 | 639 | ||
diff --git a/crypto/crypto_wq.c b/crypto/crypto_wq.c new file mode 100644 index 000000000000..fdcf6248f152 --- /dev/null +++ b/crypto/crypto_wq.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | * Workqueue for crypto subsystem | ||
| 3 | * | ||
| 4 | * Copyright (c) 2009 Intel Corp. | ||
| 5 | * Author: Huang Ying <ying.huang@intel.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the Free | ||
| 9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 10 | * any later version. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/workqueue.h> | ||
| 15 | #include <crypto/algapi.h> | ||
| 16 | #include <crypto/crypto_wq.h> | ||
| 17 | |||
| 18 | struct workqueue_struct *kcrypto_wq; | ||
| 19 | EXPORT_SYMBOL_GPL(kcrypto_wq); | ||
| 20 | |||
| 21 | static int __init crypto_wq_init(void) | ||
| 22 | { | ||
| 23 | kcrypto_wq = create_workqueue("crypto"); | ||
| 24 | if (unlikely(!kcrypto_wq)) | ||
| 25 | return -ENOMEM; | ||
| 26 | return 0; | ||
| 27 | } | ||
| 28 | |||
| 29 | static void __exit crypto_wq_exit(void) | ||
| 30 | { | ||
| 31 | destroy_workqueue(kcrypto_wq); | ||
| 32 | } | ||
| 33 | |||
| 34 | module_init(crypto_wq_init); | ||
| 35 | module_exit(crypto_wq_exit); | ||
| 36 | |||
| 37 | MODULE_LICENSE("GPL"); | ||
| 38 | MODULE_DESCRIPTION("Workqueue for crypto subsystem"); | ||
diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c index ecbeaa1f17e1..a90d260528d4 100644 --- a/crypto/gf128mul.c +++ b/crypto/gf128mul.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Copyright (c) 2006, Rik Snel <rsnel@cube.dyndns.org> | 4 | * Copyright (c) 2006, Rik Snel <rsnel@cube.dyndns.org> |
| 5 | * | 5 | * |
| 6 | * Based on Dr Brian Gladman's (GPL'd) work published at | 6 | * Based on Dr Brian Gladman's (GPL'd) work published at |
| 7 | * http://fp.gladman.plus.com/cryptography_technology/index.htm | 7 | * http://gladman.plushost.co.uk/oldsite/cryptography_technology/index.php |
| 8 | * See the original copyright notice below. | 8 | * See the original copyright notice below. |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
diff --git a/crypto/internal.h b/crypto/internal.h index 3c19a27a7563..fc76e1f37fc3 100644 --- a/crypto/internal.h +++ b/crypto/internal.h | |||
| @@ -109,8 +109,10 @@ void crypto_alg_tested(const char *name, int err); | |||
| 109 | void crypto_shoot_alg(struct crypto_alg *alg); | 109 | void crypto_shoot_alg(struct crypto_alg *alg); |
| 110 | struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, | 110 | struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, |
| 111 | u32 mask); | 111 | u32 mask); |
| 112 | struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg, | 112 | void *crypto_create_tfm(struct crypto_alg *alg, |
| 113 | const struct crypto_type *frontend); | 113 | const struct crypto_type *frontend); |
| 114 | void *crypto_alloc_tfm(const char *alg_name, | ||
| 115 | const struct crypto_type *frontend, u32 type, u32 mask); | ||
| 114 | 116 | ||
| 115 | int crypto_register_instance(struct crypto_template *tmpl, | 117 | int crypto_register_instance(struct crypto_template *tmpl, |
| 116 | struct crypto_instance *inst); | 118 | struct crypto_instance *inst); |
diff --git a/crypto/pcompress.c b/crypto/pcompress.c new file mode 100644 index 000000000000..ca9a4af91efe --- /dev/null +++ b/crypto/pcompress.c | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* | ||
| 2 | * Cryptographic API. | ||
| 3 | * | ||
| 4 | * Partial (de)compression operations. | ||
| 5 | * | ||
| 6 | * Copyright 2008 Sony Corporation | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; version 2 of the License. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program. | ||
| 19 | * If not, see <http://www.gnu.org/licenses/>. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/crypto.h> | ||
| 23 | #include <linux/errno.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/seq_file.h> | ||
| 26 | #include <linux/string.h> | ||
| 27 | |||
| 28 | #include <crypto/compress.h> | ||
| 29 | |||
| 30 | #include "internal.h" | ||
| 31 | |||
| 32 | |||
| 33 | static int crypto_pcomp_init(struct crypto_tfm *tfm, u32 type, u32 mask) | ||
| 34 | { | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | |||
| 38 | static unsigned int crypto_pcomp_extsize(struct crypto_alg *alg, | ||
| 39 | const struct crypto_type *frontend) | ||
| 40 | { | ||
| 41 | return alg->cra_ctxsize; | ||
| 42 | } | ||
| 43 | |||
| 44 | static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm, | ||
| 45 | const struct crypto_type *frontend) | ||
| 46 | { | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) | ||
| 51 | __attribute__ ((unused)); | ||
| 52 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) | ||
| 53 | { | ||
| 54 | seq_printf(m, "type : pcomp\n"); | ||
| 55 | } | ||
| 56 | |||
| 57 | static const struct crypto_type crypto_pcomp_type = { | ||
| 58 | .extsize = crypto_pcomp_extsize, | ||
| 59 | .init = crypto_pcomp_init, | ||
| 60 | .init_tfm = crypto_pcomp_init_tfm, | ||
| 61 | #ifdef CONFIG_PROC_FS | ||
| 62 | .show = crypto_pcomp_show, | ||
| 63 | #endif | ||
| 64 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, | ||
| 65 | .maskset = CRYPTO_ALG_TYPE_MASK, | ||
| 66 | .type = CRYPTO_ALG_TYPE_PCOMPRESS, | ||
| 67 | .tfmsize = offsetof(struct crypto_pcomp, base), | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct crypto_pcomp *crypto_alloc_pcomp(const char *alg_name, u32 type, | ||
| 71 | u32 mask) | ||
| 72 | { | ||
| 73 | return crypto_alloc_tfm(alg_name, &crypto_pcomp_type, type, mask); | ||
| 74 | } | ||
| 75 | EXPORT_SYMBOL_GPL(crypto_alloc_pcomp); | ||
| 76 | |||
| 77 | int crypto_register_pcomp(struct pcomp_alg *alg) | ||
| 78 | { | ||
| 79 | struct crypto_alg *base = &alg->base; | ||
| 80 | |||
| 81 | base->cra_type = &crypto_pcomp_type; | ||
| 82 | base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; | ||
| 83 | base->cra_flags |= CRYPTO_ALG_TYPE_PCOMPRESS; | ||
| 84 | |||
| 85 | return crypto_register_alg(base); | ||
| 86 | } | ||
| 87 | EXPORT_SYMBOL_GPL(crypto_register_pcomp); | ||
| 88 | |||
| 89 | int crypto_unregister_pcomp(struct pcomp_alg *alg) | ||
| 90 | { | ||
| 91 | return crypto_unregister_alg(&alg->base); | ||
| 92 | } | ||
| 93 | EXPORT_SYMBOL_GPL(crypto_unregister_pcomp); | ||
| 94 | |||
| 95 | MODULE_LICENSE("GPL"); | ||
| 96 | MODULE_DESCRIPTION("Partial (de)compression type"); | ||
| 97 | MODULE_AUTHOR("Sony Corporation"); | ||
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c index caa3542e6ce8..6349d8339d37 100644 --- a/crypto/sha256_generic.c +++ b/crypto/sha256_generic.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Cryptographic API. | 2 | * Cryptographic API. |
| 3 | * | 3 | * |
| 4 | * SHA-256, as specified in | 4 | * SHA-256, as specified in |
| 5 | * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf | 5 | * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf |
| 6 | * | 6 | * |
| 7 | * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>. | 7 | * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>. |
| 8 | * | 8 | * |
diff --git a/crypto/shash.c b/crypto/shash.c index d5a2b619c55f..7a659733f94a 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
| @@ -18,15 +18,10 @@ | |||
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
| 20 | 20 | ||
| 21 | static const struct crypto_type crypto_shash_type; | ||
| 22 | |||
| 23 | static inline struct crypto_shash *__crypto_shash_cast(struct crypto_tfm *tfm) | ||
| 24 | { | ||
| 25 | return container_of(tfm, struct crypto_shash, base); | ||
| 26 | } | ||
| 27 | |||
| 28 | #include "internal.h" | 21 | #include "internal.h" |
| 29 | 22 | ||
| 23 | static const struct crypto_type crypto_shash_type; | ||
| 24 | |||
| 30 | static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, | 25 | static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, |
| 31 | unsigned int keylen) | 26 | unsigned int keylen) |
| 32 | { | 27 | { |
| @@ -282,8 +277,7 @@ static int crypto_init_shash_ops_async(struct crypto_tfm *tfm) | |||
| 282 | if (!crypto_mod_get(calg)) | 277 | if (!crypto_mod_get(calg)) |
| 283 | return -EAGAIN; | 278 | return -EAGAIN; |
| 284 | 279 | ||
| 285 | shash = __crypto_shash_cast(crypto_create_tfm( | 280 | shash = crypto_create_tfm(calg, &crypto_shash_type); |
| 286 | calg, &crypto_shash_type)); | ||
| 287 | if (IS_ERR(shash)) { | 281 | if (IS_ERR(shash)) { |
| 288 | crypto_mod_put(calg); | 282 | crypto_mod_put(calg); |
| 289 | return PTR_ERR(shash); | 283 | return PTR_ERR(shash); |
| @@ -391,8 +385,7 @@ static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm) | |||
| 391 | if (!crypto_mod_get(calg)) | 385 | if (!crypto_mod_get(calg)) |
| 392 | return -EAGAIN; | 386 | return -EAGAIN; |
| 393 | 387 | ||
| 394 | shash = __crypto_shash_cast(crypto_create_tfm( | 388 | shash = crypto_create_tfm(calg, &crypto_shash_type); |
| 395 | calg, &crypto_shash_type)); | ||
| 396 | if (IS_ERR(shash)) { | 389 | if (IS_ERR(shash)) { |
| 397 | crypto_mod_put(calg); | 390 | crypto_mod_put(calg); |
| 398 | return PTR_ERR(shash); | 391 | return PTR_ERR(shash); |
| @@ -442,8 +435,6 @@ static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type, | |||
| 442 | static int crypto_shash_init_tfm(struct crypto_tfm *tfm, | 435 | static int crypto_shash_init_tfm(struct crypto_tfm *tfm, |
| 443 | const struct crypto_type *frontend) | 436 | const struct crypto_type *frontend) |
| 444 | { | 437 | { |
| 445 | if (frontend->type != CRYPTO_ALG_TYPE_SHASH) | ||
| 446 | return -EINVAL; | ||
| 447 | return 0; | 438 | return 0; |
| 448 | } | 439 | } |
| 449 | 440 | ||
| @@ -482,8 +473,7 @@ static const struct crypto_type crypto_shash_type = { | |||
| 482 | struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, | 473 | struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, |
| 483 | u32 mask) | 474 | u32 mask) |
| 484 | { | 475 | { |
| 485 | return __crypto_shash_cast( | 476 | return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask); |
| 486 | crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask)); | ||
| 487 | } | 477 | } |
| 488 | EXPORT_SYMBOL_GPL(crypto_alloc_shash); | 478 | EXPORT_SYMBOL_GPL(crypto_alloc_shash); |
| 489 | 479 | ||
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 28a45a1e6f42..c3c9124209a1 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c | |||
| @@ -53,7 +53,7 @@ static char *check[] = { | |||
| 53 | "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", | 53 | "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", |
| 54 | "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", | 54 | "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", |
| 55 | "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320", | 55 | "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320", |
| 56 | "lzo", "cts", NULL | 56 | "lzo", "cts", "zlib", NULL |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, | 59 | static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, |
| @@ -661,6 +661,10 @@ static void do_test(int m) | |||
| 661 | tcrypt_test("ecb(seed)"); | 661 | tcrypt_test("ecb(seed)"); |
| 662 | break; | 662 | break; |
| 663 | 663 | ||
| 664 | case 44: | ||
| 665 | tcrypt_test("zlib"); | ||
| 666 | break; | ||
| 667 | |||
| 664 | case 100: | 668 | case 100: |
| 665 | tcrypt_test("hmac(md5)"); | 669 | tcrypt_test("hmac(md5)"); |
| 666 | break; | 670 | break; |
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index a75f11ffb957..b50c3c6b17a2 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
| @@ -72,6 +72,13 @@ struct comp_test_suite { | |||
| 72 | } comp, decomp; | 72 | } comp, decomp; |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | struct pcomp_test_suite { | ||
| 76 | struct { | ||
| 77 | struct pcomp_testvec *vecs; | ||
| 78 | unsigned int count; | ||
| 79 | } comp, decomp; | ||
| 80 | }; | ||
| 81 | |||
| 75 | struct hash_test_suite { | 82 | struct hash_test_suite { |
| 76 | struct hash_testvec *vecs; | 83 | struct hash_testvec *vecs; |
| 77 | unsigned int count; | 84 | unsigned int count; |
| @@ -86,6 +93,7 @@ struct alg_test_desc { | |||
| 86 | struct aead_test_suite aead; | 93 | struct aead_test_suite aead; |
| 87 | struct cipher_test_suite cipher; | 94 | struct cipher_test_suite cipher; |
| 88 | struct comp_test_suite comp; | 95 | struct comp_test_suite comp; |
| 96 | struct pcomp_test_suite pcomp; | ||
| 89 | struct hash_test_suite hash; | 97 | struct hash_test_suite hash; |
| 90 | } suite; | 98 | } suite; |
| 91 | }; | 99 | }; |
| @@ -898,6 +906,159 @@ out: | |||
| 898 | return ret; | 906 | return ret; |
| 899 | } | 907 | } |
| 900 | 908 | ||
| 909 | static int test_pcomp(struct crypto_pcomp *tfm, | ||
| 910 | struct pcomp_testvec *ctemplate, | ||
| 911 | struct pcomp_testvec *dtemplate, int ctcount, | ||
| 912 | int dtcount) | ||
| 913 | { | ||
| 914 | const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm)); | ||
| 915 | unsigned int i; | ||
| 916 | char result[COMP_BUF_SIZE]; | ||
| 917 | int error; | ||
| 918 | |||
| 919 | for (i = 0; i < ctcount; i++) { | ||
| 920 | struct comp_request req; | ||
| 921 | |||
| 922 | error = crypto_compress_setup(tfm, ctemplate[i].params, | ||
| 923 | ctemplate[i].paramsize); | ||
| 924 | if (error) { | ||
| 925 | pr_err("alg: pcomp: compression setup failed on test " | ||
| 926 | "%d for %s: error=%d\n", i + 1, algo, error); | ||
| 927 | return error; | ||
| 928 | } | ||
| 929 | |||
| 930 | error = crypto_compress_init(tfm); | ||
| 931 | if (error) { | ||
| 932 | pr_err("alg: pcomp: compression init failed on test " | ||
| 933 | "%d for %s: error=%d\n", i + 1, algo, error); | ||
| 934 | return error; | ||
| 935 | } | ||
| 936 | |||
| 937 | memset(result, 0, sizeof(result)); | ||
| 938 | |||
| 939 | req.next_in = ctemplate[i].input; | ||
| 940 | req.avail_in = ctemplate[i].inlen / 2; | ||
| 941 | req.next_out = result; | ||
| 942 | req.avail_out = ctemplate[i].outlen / 2; | ||
| 943 | |||
| 944 | error = crypto_compress_update(tfm, &req); | ||
| 945 | if (error && (error != -EAGAIN || req.avail_in)) { | ||
| 946 | pr_err("alg: pcomp: compression update failed on test " | ||
| 947 | "%d for %s: error=%d\n", i + 1, algo, error); | ||
| 948 | return error; | ||
| 949 | } | ||
| 950 | |||
| 951 | /* Add remaining input data */ | ||
| 952 | req.avail_in += (ctemplate[i].inlen + 1) / 2; | ||
| 953 | |||
| 954 | error = crypto_compress_update(tfm, &req); | ||
| 955 | if (error && (error != -EAGAIN || req.avail_in)) { | ||
| 956 | pr_err("alg: pcomp: compression update failed on test " | ||
| 957 | "%d for %s: error=%d\n", i + 1, algo, error); | ||
| 958 | return error; | ||
| 959 | } | ||
| 960 | |||
| 961 | /* Provide remaining output space */ | ||
| 962 | req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2; | ||
| 963 | |||
| 964 | error = crypto_compress_final(tfm, &req); | ||
| 965 | if (error) { | ||
| 966 | pr_err("alg: pcomp: compression final failed on test " | ||
| 967 | "%d for %s: error=%d\n", i + 1, algo, error); | ||
| 968 | return error; | ||
| 969 | } | ||
| 970 | |||
| 971 | if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) { | ||
| 972 | pr_err("alg: comp: Compression test %d failed for %s: " | ||
| 973 | "output len = %d (expected %d)\n", i + 1, algo, | ||
| 974 | COMP_BUF_SIZE - req.avail_out, | ||
| 975 | ctemplate[i].outlen); | ||
| 976 | return -EINVAL; | ||
| 977 | } | ||
| 978 | |||
| 979 | if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) { | ||
| 980 | pr_err("alg: pcomp: Compression test %d failed for " | ||
| 981 | "%s\n", i + 1, algo); | ||
| 982 | hexdump(result, ctemplate[i].outlen); | ||
| 983 | return -EINVAL; | ||
| 984 | } | ||
| 985 | } | ||
| 986 | |||
| 987 | for (i = 0; i < dtcount; i++) { | ||
| 988 | struct comp_request req; | ||
| 989 | |||
| 990 | error = crypto_decompress_setup(tfm, dtemplate[i].params, | ||
| 991 | dtemplate[i].paramsize); | ||
| 992 | if (error) { | ||
| 993 | pr_err("alg: pcomp: decompression setup failed on " | ||
| 994 | "test %d for %s: error=%d\n", i + 1, algo, | ||
| 995 | error); | ||
| 996 | return error; | ||
| 997 | } | ||
| 998 | |||
| 999 | error = crypto_decompress_init(tfm); | ||
| 1000 | if (error) { | ||
| 1001 | pr_err("alg: pcomp: decompression init failed on test " | ||
| 1002 | "%d for %s: error=%d\n", i + 1, algo, error); | ||
| 1003 | return error; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | memset(result, 0, sizeof(result)); | ||
| 1007 | |||
| 1008 | req.next_in = dtemplate[i].input; | ||
| 1009 | req.avail_in = dtemplate[i].inlen / 2; | ||
| 1010 | req.next_out = result; | ||
| 1011 | req.avail_out = dtemplate[i].outlen / 2; | ||
| 1012 | |||
| 1013 | error = crypto_decompress_update(tfm, &req); | ||
| 1014 | if (error && (error != -EAGAIN || req.avail_in)) { | ||
| 1015 | pr_err("alg: pcomp: decompression update failed on " | ||
| 1016 | "test %d for %s: error=%d\n", i + 1, algo, | ||
| 1017 | error); | ||
| 1018 | return error; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | /* Add remaining input data */ | ||
| 1022 | req.avail_in += (dtemplate[i].inlen + 1) / 2; | ||
| 1023 | |||
| 1024 | error = crypto_decompress_update(tfm, &req); | ||
| 1025 | if (error && (error != -EAGAIN || req.avail_in)) { | ||
| 1026 | pr_err("alg: pcomp: decompression update failed on " | ||
| 1027 | "test %d for %s: error=%d\n", i + 1, algo, | ||
| 1028 | error); | ||
| 1029 | return error; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | /* Provide remaining output space */ | ||
| 1033 | req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2; | ||
| 1034 | |||
| 1035 | error = crypto_decompress_final(tfm, &req); | ||
| 1036 | if (error && (error != -EAGAIN || req.avail_in)) { | ||
| 1037 | pr_err("alg: pcomp: decompression final failed on " | ||
| 1038 | "test %d for %s: error=%d\n", i + 1, algo, | ||
| 1039 | error); | ||
| 1040 | return error; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) { | ||
| 1044 | pr_err("alg: comp: Decompression test %d failed for " | ||
| 1045 | "%s: output len = %d (expected %d)\n", i + 1, | ||
| 1046 | algo, COMP_BUF_SIZE - req.avail_out, | ||
| 1047 | dtemplate[i].outlen); | ||
| 1048 | return -EINVAL; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) { | ||
| 1052 | pr_err("alg: pcomp: Decompression test %d failed for " | ||
| 1053 | "%s\n", i + 1, algo); | ||
| 1054 | hexdump(result, dtemplate[i].outlen); | ||
| 1055 | return -EINVAL; | ||
| 1056 | } | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | return 0; | ||
| 1060 | } | ||
| 1061 | |||
| 901 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, | 1062 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, |
| 902 | u32 type, u32 mask) | 1063 | u32 type, u32 mask) |
| 903 | { | 1064 | { |
| @@ -1007,6 +1168,28 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, | |||
| 1007 | return err; | 1168 | return err; |
| 1008 | } | 1169 | } |
| 1009 | 1170 | ||
| 1171 | static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver, | ||
| 1172 | u32 type, u32 mask) | ||
| 1173 | { | ||
| 1174 | struct crypto_pcomp *tfm; | ||
| 1175 | int err; | ||
| 1176 | |||
| 1177 | tfm = crypto_alloc_pcomp(driver, type, mask); | ||
| 1178 | if (IS_ERR(tfm)) { | ||
| 1179 | pr_err("alg: pcomp: Failed to load transform for %s: %ld\n", | ||
| 1180 | driver, PTR_ERR(tfm)); | ||
| 1181 | return PTR_ERR(tfm); | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs, | ||
| 1185 | desc->suite.pcomp.decomp.vecs, | ||
| 1186 | desc->suite.pcomp.comp.count, | ||
| 1187 | desc->suite.pcomp.decomp.count); | ||
| 1188 | |||
| 1189 | crypto_free_pcomp(tfm); | ||
| 1190 | return err; | ||
| 1191 | } | ||
| 1192 | |||
| 1010 | static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, | 1193 | static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, |
| 1011 | u32 type, u32 mask) | 1194 | u32 type, u32 mask) |
| 1012 | { | 1195 | { |
| @@ -1835,6 +2018,21 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
| 1835 | } | 2018 | } |
| 1836 | } | 2019 | } |
| 1837 | } | 2020 | } |
| 2021 | }, { | ||
| 2022 | .alg = "zlib", | ||
| 2023 | .test = alg_test_pcomp, | ||
| 2024 | .suite = { | ||
| 2025 | .pcomp = { | ||
| 2026 | .comp = { | ||
| 2027 | .vecs = zlib_comp_tv_template, | ||
| 2028 | .count = ZLIB_COMP_TEST_VECTORS | ||
| 2029 | }, | ||
| 2030 | .decomp = { | ||
| 2031 | .vecs = zlib_decomp_tv_template, | ||
| 2032 | .count = ZLIB_DECOMP_TEST_VECTORS | ||
| 2033 | } | ||
| 2034 | } | ||
| 2035 | } | ||
| 1838 | } | 2036 | } |
| 1839 | }; | 2037 | }; |
| 1840 | 2038 | ||
diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 132953e144d3..526f00a9c72f 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h | |||
| @@ -15,6 +15,11 @@ | |||
| 15 | #ifndef _CRYPTO_TESTMGR_H | 15 | #ifndef _CRYPTO_TESTMGR_H |
| 16 | #define _CRYPTO_TESTMGR_H | 16 | #define _CRYPTO_TESTMGR_H |
| 17 | 17 | ||
| 18 | #include <linux/netlink.h> | ||
| 19 | #include <linux/zlib.h> | ||
| 20 | |||
| 21 | #include <crypto/compress.h> | ||
| 22 | |||
| 18 | #define MAX_DIGEST_SIZE 64 | 23 | #define MAX_DIGEST_SIZE 64 |
| 19 | #define MAX_TAP 8 | 24 | #define MAX_TAP 8 |
| 20 | 25 | ||
| @@ -8347,10 +8352,19 @@ struct comp_testvec { | |||
| 8347 | char output[COMP_BUF_SIZE]; | 8352 | char output[COMP_BUF_SIZE]; |
| 8348 | }; | 8353 | }; |
| 8349 | 8354 | ||
| 8355 | struct pcomp_testvec { | ||
| 8356 | void *params; | ||
| 8357 | unsigned int paramsize; | ||
| 8358 | int inlen, outlen; | ||
| 8359 | char input[COMP_BUF_SIZE]; | ||
| 8360 | char output[COMP_BUF_SIZE]; | ||
| 8361 | }; | ||
| 8362 | |||
| 8350 | /* | 8363 | /* |
| 8351 | * Deflate test vectors (null-terminated strings). | 8364 | * Deflate test vectors (null-terminated strings). |
| 8352 | * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL. | 8365 | * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL. |
| 8353 | */ | 8366 | */ |
| 8367 | |||
| 8354 | #define DEFLATE_COMP_TEST_VECTORS 2 | 8368 | #define DEFLATE_COMP_TEST_VECTORS 2 |
| 8355 | #define DEFLATE_DECOMP_TEST_VECTORS 2 | 8369 | #define DEFLATE_DECOMP_TEST_VECTORS 2 |
| 8356 | 8370 | ||
| @@ -8426,6 +8440,139 @@ static struct comp_testvec deflate_decomp_tv_template[] = { | |||
| 8426 | }, | 8440 | }, |
| 8427 | }; | 8441 | }; |
| 8428 | 8442 | ||
| 8443 | #define ZLIB_COMP_TEST_VECTORS 2 | ||
| 8444 | #define ZLIB_DECOMP_TEST_VECTORS 2 | ||
| 8445 | |||
| 8446 | static const struct { | ||
| 8447 | struct nlattr nla; | ||
| 8448 | int val; | ||
| 8449 | } deflate_comp_params[] = { | ||
| 8450 | { | ||
| 8451 | .nla = { | ||
| 8452 | .nla_len = NLA_HDRLEN + sizeof(int), | ||
| 8453 | .nla_type = ZLIB_COMP_LEVEL, | ||
| 8454 | }, | ||
| 8455 | .val = Z_DEFAULT_COMPRESSION, | ||
| 8456 | }, { | ||
| 8457 | .nla = { | ||
| 8458 | .nla_len = NLA_HDRLEN + sizeof(int), | ||
| 8459 | .nla_type = ZLIB_COMP_METHOD, | ||
| 8460 | }, | ||
| 8461 | .val = Z_DEFLATED, | ||
| 8462 | }, { | ||
| 8463 | .nla = { | ||
| 8464 | .nla_len = NLA_HDRLEN + sizeof(int), | ||
| 8465 | .nla_type = ZLIB_COMP_WINDOWBITS, | ||
| 8466 | }, | ||
| 8467 | .val = -11, | ||
| 8468 | }, { | ||
| 8469 | .nla = { | ||
| 8470 | .nla_len = NLA_HDRLEN + sizeof(int), | ||
| 8471 | .nla_type = ZLIB_COMP_MEMLEVEL, | ||
| 8472 | }, | ||
| 8473 | .val = MAX_MEM_LEVEL, | ||
| 8474 | }, { | ||
| 8475 | .nla = { | ||
| 8476 | .nla_len = NLA_HDRLEN + sizeof(int), | ||
| 8477 | .nla_type = ZLIB_COMP_STRATEGY, | ||
| 8478 | }, | ||
| 8479 | .val = Z_DEFAULT_STRATEGY, | ||
| 8480 | } | ||
| 8481 | }; | ||
| 8482 | |||
| 8483 | static const struct { | ||
| 8484 | struct nlattr nla; | ||
| 8485 | int val; | ||
| 8486 | } deflate_decomp_params[] = { | ||
| 8487 | { | ||
| 8488 | .nla = { | ||
| 8489 | .nla_len = NLA_HDRLEN + sizeof(int), | ||
| 8490 | .nla_type = ZLIB_DECOMP_WINDOWBITS, | ||
| 8491 | }, | ||
| 8492 | .val = -11, | ||
| 8493 | } | ||
| 8494 | }; | ||
| 8495 | |||
| 8496 | static struct pcomp_testvec zlib_comp_tv_template[] = { | ||
| 8497 | { | ||
| 8498 | .params = &deflate_comp_params, | ||
| 8499 | .paramsize = sizeof(deflate_comp_params), | ||
| 8500 | .inlen = 70, | ||
| 8501 | .outlen = 38, | ||
| 8502 | .input = "Join us now and share the software " | ||
| 8503 | "Join us now and share the software ", | ||
| 8504 | .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56" | ||
| 8505 | "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51" | ||
| 8506 | "\x28\xce\x48\x2c\x4a\x55\x28\xc9" | ||
| 8507 | "\x48\x55\x28\xce\x4f\x2b\x29\x07" | ||
| 8508 | "\x71\xbc\x08\x2b\x01\x00", | ||
| 8509 | }, { | ||
| 8510 | .params = &deflate_comp_params, | ||
| 8511 | .paramsize = sizeof(deflate_comp_params), | ||
| 8512 | .inlen = 191, | ||
| 8513 | .outlen = 122, | ||
| 8514 | .input = "This document describes a compression method based on the DEFLATE" | ||
| 8515 | "compression algorithm. This document defines the application of " | ||
| 8516 | "the DEFLATE algorithm to the IP Payload Compression Protocol.", | ||
| 8517 | .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04" | ||
| 8518 | "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09" | ||
| 8519 | "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8" | ||
| 8520 | "\x24\xdb\x67\xd9\x47\xc1\xef\x49" | ||
| 8521 | "\x68\x12\x51\xae\x76\x67\xd6\x27" | ||
| 8522 | "\x19\x88\x1a\xde\x85\xab\x21\xf2" | ||
| 8523 | "\x08\x5d\x16\x1e\x20\x04\x2d\xad" | ||
| 8524 | "\xf3\x18\xa2\x15\x85\x2d\x69\xc4" | ||
| 8525 | "\x42\x83\x23\xb6\x6c\x89\x71\x9b" | ||
| 8526 | "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f" | ||
| 8527 | "\xed\x62\xa9\x4c\x80\xff\x13\xaf" | ||
| 8528 | "\x52\x37\xed\x0e\x52\x6b\x59\x02" | ||
| 8529 | "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98" | ||
| 8530 | "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a" | ||
| 8531 | "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79" | ||
| 8532 | "\xfa\x02", | ||
| 8533 | }, | ||
| 8534 | }; | ||
| 8535 | |||
| 8536 | static struct pcomp_testvec zlib_decomp_tv_template[] = { | ||
| 8537 | { | ||
| 8538 | .params = &deflate_decomp_params, | ||
| 8539 | .paramsize = sizeof(deflate_decomp_params), | ||
| 8540 | .inlen = 122, | ||
| 8541 | .outlen = 191, | ||
| 8542 | .input = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04" | ||
| 8543 | "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09" | ||
| 8544 | "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8" | ||
| 8545 | "\x24\xdb\x67\xd9\x47\xc1\xef\x49" | ||
| 8546 | "\x68\x12\x51\xae\x76\x67\xd6\x27" | ||
| 8547 | "\x19\x88\x1a\xde\x85\xab\x21\xf2" | ||
| 8548 | "\x08\x5d\x16\x1e\x20\x04\x2d\xad" | ||
| 8549 | "\xf3\x18\xa2\x15\x85\x2d\x69\xc4" | ||
| 8550 | "\x42\x83\x23\xb6\x6c\x89\x71\x9b" | ||
| 8551 | "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f" | ||
| 8552 | "\xed\x62\xa9\x4c\x80\xff\x13\xaf" | ||
| 8553 | "\x52\x37\xed\x0e\x52\x6b\x59\x02" | ||
| 8554 | "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98" | ||
| 8555 | "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a" | ||
| 8556 | "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79" | ||
| 8557 | "\xfa\x02", | ||
| 8558 | .output = "This document describes a compression method based on the DEFLATE" | ||
| 8559 | "compression algorithm. This document defines the application of " | ||
| 8560 | "the DEFLATE algorithm to the IP Payload Compression Protocol.", | ||
| 8561 | }, { | ||
| 8562 | .params = &deflate_decomp_params, | ||
| 8563 | .paramsize = sizeof(deflate_decomp_params), | ||
| 8564 | .inlen = 38, | ||
| 8565 | .outlen = 70, | ||
| 8566 | .input = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56" | ||
| 8567 | "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51" | ||
| 8568 | "\x28\xce\x48\x2c\x4a\x55\x28\xc9" | ||
| 8569 | "\x48\x55\x28\xce\x4f\x2b\x29\x07" | ||
| 8570 | "\x71\xbc\x08\x2b\x01\x00", | ||
| 8571 | .output = "Join us now and share the software " | ||
| 8572 | "Join us now and share the software ", | ||
| 8573 | }, | ||
| 8574 | }; | ||
| 8575 | |||
| 8429 | /* | 8576 | /* |
| 8430 | * LZO test vectors (null-terminated strings). | 8577 | * LZO test vectors (null-terminated strings). |
| 8431 | */ | 8578 | */ |
diff --git a/crypto/zlib.c b/crypto/zlib.c new file mode 100644 index 000000000000..33609bab614e --- /dev/null +++ b/crypto/zlib.c | |||
| @@ -0,0 +1,378 @@ | |||
| 1 | /* | ||
| 2 | * Cryptographic API. | ||
| 3 | * | ||
| 4 | * Zlib algorithm | ||
| 5 | * | ||
| 6 | * Copyright 2008 Sony Corporation | ||
| 7 | * | ||
| 8 | * Based on deflate.c, which is | ||
| 9 | * Copyright (c) 2003 James Morris <jmorris@intercode.com.au> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify it | ||
| 12 | * under the terms of the GNU General Public License as published by the Free | ||
| 13 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 14 | * any later version. | ||
| 15 | * | ||
| 16 | * FIXME: deflate transforms will require up to a total of about 436k of kernel | ||
| 17 | * memory on i386 (390k for compression, the rest for decompression), as the | ||
| 18 | * current zlib kernel code uses a worst case pre-allocation system by default. | ||
| 19 | * This needs to be fixed so that the amount of memory required is properly | ||
| 20 | * related to the winbits and memlevel parameters. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
| 24 | |||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/zlib.h> | ||
| 28 | #include <linux/vmalloc.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/mm.h> | ||
| 31 | #include <linux/net.h> | ||
| 32 | #include <linux/slab.h> | ||
| 33 | |||
| 34 | #include <crypto/internal/compress.h> | ||
| 35 | |||
| 36 | #include <net/netlink.h> | ||
| 37 | |||
| 38 | |||
| 39 | struct zlib_ctx { | ||
| 40 | struct z_stream_s comp_stream; | ||
| 41 | struct z_stream_s decomp_stream; | ||
| 42 | int decomp_windowBits; | ||
| 43 | }; | ||
| 44 | |||
| 45 | |||
| 46 | static void zlib_comp_exit(struct zlib_ctx *ctx) | ||
| 47 | { | ||
| 48 | struct z_stream_s *stream = &ctx->comp_stream; | ||
| 49 | |||
| 50 | if (stream->workspace) { | ||
| 51 | zlib_deflateEnd(stream); | ||
| 52 | vfree(stream->workspace); | ||
| 53 | stream->workspace = NULL; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | static void zlib_decomp_exit(struct zlib_ctx *ctx) | ||
| 58 | { | ||
| 59 | struct z_stream_s *stream = &ctx->decomp_stream; | ||
| 60 | |||
| 61 | if (stream->workspace) { | ||
| 62 | zlib_inflateEnd(stream); | ||
| 63 | kfree(stream->workspace); | ||
| 64 | stream->workspace = NULL; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | static int zlib_init(struct crypto_tfm *tfm) | ||
| 69 | { | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | static void zlib_exit(struct crypto_tfm *tfm) | ||
| 74 | { | ||
| 75 | struct zlib_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 76 | |||
| 77 | zlib_comp_exit(ctx); | ||
| 78 | zlib_decomp_exit(ctx); | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params, | ||
| 83 | unsigned int len) | ||
| 84 | { | ||
| 85 | struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 86 | struct z_stream_s *stream = &ctx->comp_stream; | ||
| 87 | struct nlattr *tb[ZLIB_COMP_MAX + 1]; | ||
| 88 | size_t workspacesize; | ||
| 89 | int ret; | ||
| 90 | |||
| 91 | ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL); | ||
| 92 | if (ret) | ||
| 93 | return ret; | ||
| 94 | |||
| 95 | zlib_comp_exit(ctx); | ||
| 96 | |||
| 97 | workspacesize = zlib_deflate_workspacesize(); | ||
| 98 | stream->workspace = vmalloc(workspacesize); | ||
| 99 | if (!stream->workspace) | ||
| 100 | return -ENOMEM; | ||
| 101 | |||
| 102 | memset(stream->workspace, 0, workspacesize); | ||
| 103 | ret = zlib_deflateInit2(stream, | ||
| 104 | tb[ZLIB_COMP_LEVEL] | ||
| 105 | ? nla_get_u32(tb[ZLIB_COMP_LEVEL]) | ||
| 106 | : Z_DEFAULT_COMPRESSION, | ||
| 107 | tb[ZLIB_COMP_METHOD] | ||
| 108 | ? nla_get_u32(tb[ZLIB_COMP_METHOD]) | ||
| 109 | : Z_DEFLATED, | ||
| 110 | tb[ZLIB_COMP_WINDOWBITS] | ||
| 111 | ? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS]) | ||
| 112 | : MAX_WBITS, | ||
| 113 | tb[ZLIB_COMP_MEMLEVEL] | ||
| 114 | ? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL]) | ||
| 115 | : DEF_MEM_LEVEL, | ||
| 116 | tb[ZLIB_COMP_STRATEGY] | ||
| 117 | ? nla_get_u32(tb[ZLIB_COMP_STRATEGY]) | ||
| 118 | : Z_DEFAULT_STRATEGY); | ||
| 119 | if (ret != Z_OK) { | ||
| 120 | vfree(stream->workspace); | ||
| 121 | stream->workspace = NULL; | ||
| 122 | return -EINVAL; | ||
| 123 | } | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static int zlib_compress_init(struct crypto_pcomp *tfm) | ||
| 129 | { | ||
| 130 | int ret; | ||
| 131 | struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 132 | struct z_stream_s *stream = &dctx->comp_stream; | ||
| 133 | |||
| 134 | ret = zlib_deflateReset(stream); | ||
| 135 | if (ret != Z_OK) | ||
| 136 | return -EINVAL; | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | static int zlib_compress_update(struct crypto_pcomp *tfm, | ||
| 142 | struct comp_request *req) | ||
| 143 | { | ||
| 144 | int ret; | ||
| 145 | struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 146 | struct z_stream_s *stream = &dctx->comp_stream; | ||
| 147 | |||
| 148 | pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); | ||
| 149 | stream->next_in = req->next_in; | ||
| 150 | stream->avail_in = req->avail_in; | ||
| 151 | stream->next_out = req->next_out; | ||
| 152 | stream->avail_out = req->avail_out; | ||
| 153 | |||
| 154 | ret = zlib_deflate(stream, Z_NO_FLUSH); | ||
| 155 | switch (ret) { | ||
| 156 | case Z_OK: | ||
| 157 | break; | ||
| 158 | |||
| 159 | case Z_BUF_ERROR: | ||
| 160 | pr_debug("zlib_deflate could not make progress\n"); | ||
| 161 | return -EAGAIN; | ||
| 162 | |||
| 163 | default: | ||
| 164 | pr_debug("zlib_deflate failed %d\n", ret); | ||
| 165 | return -EINVAL; | ||
| 166 | } | ||
| 167 | |||
| 168 | pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n", | ||
| 169 | stream->avail_in, stream->avail_out, | ||
| 170 | req->avail_in - stream->avail_in, | ||
| 171 | req->avail_out - stream->avail_out); | ||
| 172 | req->next_in = stream->next_in; | ||
| 173 | req->avail_in = stream->avail_in; | ||
| 174 | req->next_out = stream->next_out; | ||
| 175 | req->avail_out = stream->avail_out; | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | |||
| 179 | static int zlib_compress_final(struct crypto_pcomp *tfm, | ||
| 180 | struct comp_request *req) | ||
| 181 | { | ||
| 182 | int ret; | ||
| 183 | struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 184 | struct z_stream_s *stream = &dctx->comp_stream; | ||
| 185 | |||
| 186 | pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); | ||
| 187 | stream->next_in = req->next_in; | ||
| 188 | stream->avail_in = req->avail_in; | ||
| 189 | stream->next_out = req->next_out; | ||
| 190 | stream->avail_out = req->avail_out; | ||
| 191 | |||
| 192 | ret = zlib_deflate(stream, Z_FINISH); | ||
| 193 | if (ret != Z_STREAM_END) { | ||
| 194 | pr_debug("zlib_deflate failed %d\n", ret); | ||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | |||
| 198 | pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n", | ||
| 199 | stream->avail_in, stream->avail_out, | ||
| 200 | req->avail_in - stream->avail_in, | ||
| 201 | req->avail_out - stream->avail_out); | ||
| 202 | req->next_in = stream->next_in; | ||
| 203 | req->avail_in = stream->avail_in; | ||
| 204 | req->next_out = stream->next_out; | ||
| 205 | req->avail_out = stream->avail_out; | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | |||
| 210 | static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params, | ||
| 211 | unsigned int len) | ||
| 212 | { | ||
| 213 | struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 214 | struct z_stream_s *stream = &ctx->decomp_stream; | ||
| 215 | struct nlattr *tb[ZLIB_DECOMP_MAX + 1]; | ||
| 216 | int ret = 0; | ||
| 217 | |||
| 218 | ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL); | ||
| 219 | if (ret) | ||
| 220 | return ret; | ||
| 221 | |||
| 222 | zlib_decomp_exit(ctx); | ||
| 223 | |||
| 224 | ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS] | ||
| 225 | ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS]) | ||
| 226 | : DEF_WBITS; | ||
| 227 | |||
| 228 | stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL); | ||
| 229 | if (!stream->workspace) | ||
| 230 | return -ENOMEM; | ||
| 231 | |||
| 232 | ret = zlib_inflateInit2(stream, ctx->decomp_windowBits); | ||
| 233 | if (ret != Z_OK) { | ||
| 234 | kfree(stream->workspace); | ||
| 235 | stream->workspace = NULL; | ||
| 236 | return -EINVAL; | ||
| 237 | } | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | static int zlib_decompress_init(struct crypto_pcomp *tfm) | ||
| 243 | { | ||
| 244 | int ret; | ||
| 245 | struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 246 | struct z_stream_s *stream = &dctx->decomp_stream; | ||
| 247 | |||
| 248 | ret = zlib_inflateReset(stream); | ||
| 249 | if (ret != Z_OK) | ||
| 250 | return -EINVAL; | ||
| 251 | |||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | static int zlib_decompress_update(struct crypto_pcomp *tfm, | ||
| 256 | struct comp_request *req) | ||
| 257 | { | ||
| 258 | int ret; | ||
| 259 | struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 260 | struct z_stream_s *stream = &dctx->decomp_stream; | ||
| 261 | |||
| 262 | pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); | ||
| 263 | stream->next_in = req->next_in; | ||
| 264 | stream->avail_in = req->avail_in; | ||
| 265 | stream->next_out = req->next_out; | ||
| 266 | stream->avail_out = req->avail_out; | ||
| 267 | |||
| 268 | ret = zlib_inflate(stream, Z_SYNC_FLUSH); | ||
| 269 | switch (ret) { | ||
| 270 | case Z_OK: | ||
| 271 | case Z_STREAM_END: | ||
| 272 | break; | ||
| 273 | |||
| 274 | case Z_BUF_ERROR: | ||
| 275 | pr_debug("zlib_inflate could not make progress\n"); | ||
| 276 | return -EAGAIN; | ||
| 277 | |||
| 278 | default: | ||
| 279 | pr_debug("zlib_inflate failed %d\n", ret); | ||
| 280 | return -EINVAL; | ||
| 281 | } | ||
| 282 | |||
| 283 | pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n", | ||
| 284 | stream->avail_in, stream->avail_out, | ||
| 285 | req->avail_in - stream->avail_in, | ||
| 286 | req->avail_out - stream->avail_out); | ||
| 287 | req->next_in = stream->next_in; | ||
| 288 | req->avail_in = stream->avail_in; | ||
| 289 | req->next_out = stream->next_out; | ||
| 290 | req->avail_out = stream->avail_out; | ||
| 291 | return 0; | ||
| 292 | } | ||
| 293 | |||
| 294 | static int zlib_decompress_final(struct crypto_pcomp *tfm, | ||
| 295 | struct comp_request *req) | ||
| 296 | { | ||
| 297 | int ret; | ||
| 298 | struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | ||
| 299 | struct z_stream_s *stream = &dctx->decomp_stream; | ||
| 300 | |||
| 301 | pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); | ||
| 302 | stream->next_in = req->next_in; | ||
| 303 | stream->avail_in = req->avail_in; | ||
| 304 | stream->next_out = req->next_out; | ||
| 305 | stream->avail_out = req->avail_out; | ||
| 306 | |||
| 307 | if (dctx->decomp_windowBits < 0) { | ||
| 308 | ret = zlib_inflate(stream, Z_SYNC_FLUSH); | ||
| 309 | /* | ||
| 310 | * Work around a bug in zlib, which sometimes wants to taste an | ||
| 311 | * extra byte when being used in the (undocumented) raw deflate | ||
| 312 | * mode. (From USAGI). | ||
| 313 | */ | ||
| 314 | if (ret == Z_OK && !stream->avail_in && stream->avail_out) { | ||
| 315 | const void *saved_next_in = stream->next_in; | ||
| 316 | u8 zerostuff = 0; | ||
| 317 | |||
| 318 | stream->next_in = &zerostuff; | ||
| 319 | stream->avail_in = 1; | ||
| 320 | ret = zlib_inflate(stream, Z_FINISH); | ||
| 321 | stream->next_in = saved_next_in; | ||
| 322 | stream->avail_in = 0; | ||
| 323 | } | ||
| 324 | } else | ||
| 325 | ret = zlib_inflate(stream, Z_FINISH); | ||
| 326 | if (ret != Z_STREAM_END) { | ||
| 327 | pr_debug("zlib_inflate failed %d\n", ret); | ||
| 328 | return -EINVAL; | ||
| 329 | } | ||
| 330 | |||
| 331 | pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n", | ||
| 332 | stream->avail_in, stream->avail_out, | ||
| 333 | req->avail_in - stream->avail_in, | ||
| 334 | req->avail_out - stream->avail_out); | ||
| 335 | req->next_in = stream->next_in; | ||
| 336 | req->avail_in = stream->avail_in; | ||
| 337 | req->next_out = stream->next_out; | ||
| 338 | req->avail_out = stream->avail_out; | ||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | |||
| 343 | static struct pcomp_alg zlib_alg = { | ||
| 344 | .compress_setup = zlib_compress_setup, | ||
| 345 | .compress_init = zlib_compress_init, | ||
| 346 | .compress_update = zlib_compress_update, | ||
| 347 | .compress_final = zlib_compress_final, | ||
| 348 | .decompress_setup = zlib_decompress_setup, | ||
| 349 | .decompress_init = zlib_decompress_init, | ||
| 350 | .decompress_update = zlib_decompress_update, | ||
| 351 | .decompress_final = zlib_decompress_final, | ||
| 352 | |||
| 353 | .base = { | ||
| 354 | .cra_name = "zlib", | ||
| 355 | .cra_flags = CRYPTO_ALG_TYPE_PCOMPRESS, | ||
| 356 | .cra_ctxsize = sizeof(struct zlib_ctx), | ||
| 357 | .cra_module = THIS_MODULE, | ||
| 358 | .cra_init = zlib_init, | ||
| 359 | .cra_exit = zlib_exit, | ||
| 360 | } | ||
| 361 | }; | ||
| 362 | |||
| 363 | static int __init zlib_mod_init(void) | ||
| 364 | { | ||
| 365 | return crypto_register_pcomp(&zlib_alg); | ||
| 366 | } | ||
| 367 | |||
| 368 | static void __exit zlib_mod_fini(void) | ||
| 369 | { | ||
| 370 | crypto_unregister_pcomp(&zlib_alg); | ||
| 371 | } | ||
| 372 | |||
| 373 | module_init(zlib_mod_init); | ||
| 374 | module_exit(zlib_mod_fini); | ||
| 375 | |||
| 376 | MODULE_LICENSE("GPL"); | ||
| 377 | MODULE_DESCRIPTION("Zlib Compression Algorithm"); | ||
| 378 | MODULE_AUTHOR("Sony Corporation"); | ||
