diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 13:25:58 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 13:25:58 -0500 |
| commit | 27d189c02ba25851973c8582e419c0bded9f7e5b (patch) | |
| tree | be142d664bc4e3cec7ab2878a243343f46e897ee /crypto | |
| parent | a1703154200c390ab03c10224c586e815d3e31e8 (diff) | |
| parent | 55db8387a5e8d07407f0b7c6b2526417a2bc6243 (diff) | |
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: (46 commits)
hwrng: via_rng - Fix memory scribbling on some CPUs
crypto: padlock - Move padlock.h into include/crypto
hwrng: via_rng - Fix asm constraints
crypto: n2 - use __devexit not __exit in n2_unregister_algs
crypto: mark crypto workqueues CPU_INTENSIVE
crypto: mv_cesa - dont return PTR_ERR() of wrong pointer
crypto: ripemd - Set module author and update email address
crypto: omap-sham - backlog handling fix
crypto: gf128mul - Remove experimental tag
crypto: af_alg - fix af_alg memory_allocated data type
crypto: aesni-intel - Fixed build with binutils 2.16
crypto: af_alg - Make sure sk_security is initialized on accept()ed sockets
net: Add missing lockdep class names for af_alg
include: Install linux/if_alg.h for user-space crypto API
crypto: omap-aes - checkpatch --file warning fixes
crypto: omap-aes - initialize aes module once per request
crypto: omap-aes - unnecessary code removed
crypto: omap-aes - error handling implementation improved
crypto: omap-aes - redundant locking is removed
crypto: omap-aes - DMA initialization fixes for OMAP off mode
...
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/Kconfig | 34 | ||||
| -rw-r--r-- | crypto/Makefile | 17 | ||||
| -rw-r--r-- | crypto/af_alg.c | 483 | ||||
| -rw-r--r-- | crypto/algif_hash.c | 319 | ||||
| -rw-r--r-- | crypto/algif_skcipher.c | 632 | ||||
| -rw-r--r-- | crypto/authenc.c | 22 | ||||
| -rw-r--r-- | crypto/cast5.c | 74 | ||||
| -rw-r--r-- | crypto/crypto_wq.c | 3 | ||||
| -rw-r--r-- | crypto/deflate.c | 3 | ||||
| -rw-r--r-- | crypto/eseqiv.c | 18 | ||||
| -rw-r--r-- | crypto/gcm.c | 19 | ||||
| -rw-r--r-- | crypto/pcrypt.c | 3 | ||||
| -rw-r--r-- | crypto/rmd128.c | 3 | ||||
| -rw-r--r-- | crypto/rmd160.c | 3 | ||||
| -rw-r--r-- | crypto/rmd256.c | 3 | ||||
| -rw-r--r-- | crypto/rmd320.c | 3 | ||||
| -rw-r--r-- | crypto/shash.c | 8 | ||||
| -rw-r--r-- | crypto/tcrypt.c | 11 | ||||
| -rw-r--r-- | crypto/testmgr.c | 24 | ||||
| -rw-r--r-- | crypto/testmgr.h | 361 | ||||
| -rw-r--r-- | crypto/zlib.c | 3 |
21 files changed, 1921 insertions, 125 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index e4bac29a32e7..4b7cb0e691cd 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
| @@ -110,7 +110,6 @@ config CRYPTO_MANAGER_DISABLE_TESTS | |||
| 110 | 110 | ||
| 111 | config CRYPTO_GF128MUL | 111 | config CRYPTO_GF128MUL |
| 112 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" | 112 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" |
| 113 | depends on EXPERIMENTAL | ||
| 114 | help | 113 | help |
| 115 | Efficient table driven implementation of multiplications in the | 114 | Efficient table driven implementation of multiplications in the |
| 116 | field GF(2^128). This is needed by some cypher modes. This | 115 | field GF(2^128). This is needed by some cypher modes. This |
| @@ -539,8 +538,9 @@ config CRYPTO_AES_X86_64 | |||
| 539 | 538 | ||
| 540 | config CRYPTO_AES_NI_INTEL | 539 | config CRYPTO_AES_NI_INTEL |
| 541 | tristate "AES cipher algorithms (AES-NI)" | 540 | tristate "AES cipher algorithms (AES-NI)" |
| 542 | depends on (X86 || UML_X86) && 64BIT | 541 | depends on (X86 || UML_X86) |
| 543 | select CRYPTO_AES_X86_64 | 542 | select CRYPTO_AES_X86_64 if 64BIT |
| 543 | select CRYPTO_AES_586 if !64BIT | ||
| 544 | select CRYPTO_CRYPTD | 544 | select CRYPTO_CRYPTD |
| 545 | select CRYPTO_ALGAPI | 545 | select CRYPTO_ALGAPI |
| 546 | select CRYPTO_FPU | 546 | select CRYPTO_FPU |
| @@ -563,9 +563,10 @@ config CRYPTO_AES_NI_INTEL | |||
| 563 | 563 | ||
| 564 | See <http://csrc.nist.gov/encryption/aes/> for more information. | 564 | See <http://csrc.nist.gov/encryption/aes/> for more information. |
| 565 | 565 | ||
| 566 | In addition to AES cipher algorithm support, the | 566 | In addition to AES cipher algorithm support, the acceleration |
| 567 | acceleration for some popular block cipher mode is supported | 567 | for some popular block cipher mode is supported too, including |
| 568 | too, including ECB, CBC, CTR, LRW, PCBC, XTS. | 568 | ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional |
| 569 | acceleration for CTR. | ||
| 569 | 570 | ||
| 570 | config CRYPTO_ANUBIS | 571 | config CRYPTO_ANUBIS |
| 571 | tristate "Anubis cipher algorithm" | 572 | tristate "Anubis cipher algorithm" |
| @@ -841,6 +842,27 @@ config CRYPTO_ANSI_CPRNG | |||
| 841 | ANSI X9.31 A.2.4. Note that this option must be enabled if | 842 | ANSI X9.31 A.2.4. Note that this option must be enabled if |
| 842 | CRYPTO_FIPS is selected | 843 | CRYPTO_FIPS is selected |
| 843 | 844 | ||
| 845 | config CRYPTO_USER_API | ||
| 846 | tristate | ||
| 847 | |||
| 848 | config CRYPTO_USER_API_HASH | ||
| 849 | tristate "User-space interface for hash algorithms" | ||
| 850 | depends on NET | ||
| 851 | select CRYPTO_HASH | ||
| 852 | select CRYPTO_USER_API | ||
| 853 | help | ||
| 854 | This option enables the user-spaces interface for hash | ||
| 855 | algorithms. | ||
| 856 | |||
| 857 | config CRYPTO_USER_API_SKCIPHER | ||
| 858 | tristate "User-space interface for symmetric key cipher algorithms" | ||
| 859 | depends on NET | ||
| 860 | select CRYPTO_BLKCIPHER | ||
| 861 | select CRYPTO_USER_API | ||
| 862 | help | ||
| 863 | This option enables the user-spaces interface for symmetric | ||
| 864 | key cipher algorithms. | ||
| 865 | |||
| 844 | source "drivers/crypto/Kconfig" | 866 | source "drivers/crypto/Kconfig" |
| 845 | 867 | ||
| 846 | endif # if CRYPTO | 868 | endif # if CRYPTO |
diff --git a/crypto/Makefile b/crypto/Makefile index 423b7de61f93..e9a399ca69db 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
| @@ -3,32 +3,32 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_CRYPTO) += crypto.o | 5 | obj-$(CONFIG_CRYPTO) += crypto.o |
| 6 | crypto-objs := api.o cipher.o compress.o | 6 | crypto-y := api.o cipher.o compress.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o | 8 | obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o |
| 9 | 9 | ||
| 10 | obj-$(CONFIG_CRYPTO_FIPS) += fips.o | 10 | obj-$(CONFIG_CRYPTO_FIPS) += fips.o |
| 11 | 11 | ||
| 12 | crypto_algapi-$(CONFIG_PROC_FS) += proc.o | 12 | crypto_algapi-$(CONFIG_PROC_FS) += proc.o |
| 13 | crypto_algapi-objs := algapi.o scatterwalk.o $(crypto_algapi-y) | 13 | crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y) |
| 14 | obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o | 14 | obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o |
| 15 | 15 | ||
| 16 | obj-$(CONFIG_CRYPTO_AEAD2) += aead.o | 16 | obj-$(CONFIG_CRYPTO_AEAD2) += aead.o |
| 17 | 17 | ||
| 18 | crypto_blkcipher-objs := ablkcipher.o | 18 | crypto_blkcipher-y := ablkcipher.o |
| 19 | crypto_blkcipher-objs += blkcipher.o | 19 | crypto_blkcipher-y += blkcipher.o |
| 20 | obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o | 20 | obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o |
| 21 | obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o | 21 | obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o |
| 22 | obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o | 22 | obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o |
| 23 | obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o | 23 | obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o |
| 24 | 24 | ||
| 25 | crypto_hash-objs += ahash.o | 25 | crypto_hash-y += ahash.o |
| 26 | crypto_hash-objs += shash.o | 26 | crypto_hash-y += shash.o |
| 27 | obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o | 27 | obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o |
| 28 | 28 | ||
| 29 | obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o | 29 | obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o |
| 30 | 30 | ||
| 31 | cryptomgr-objs := algboss.o testmgr.o | 31 | cryptomgr-y := algboss.o testmgr.o |
| 32 | 32 | ||
| 33 | obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o | 33 | obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o |
| 34 | obj-$(CONFIG_CRYPTO_HMAC) += hmac.o | 34 | obj-$(CONFIG_CRYPTO_HMAC) += hmac.o |
| @@ -85,6 +85,9 @@ obj-$(CONFIG_CRYPTO_RNG2) += krng.o | |||
| 85 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o | 85 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o |
| 86 | obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o | 86 | obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o |
| 87 | obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o | 87 | obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o |
| 88 | obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o | ||
| 89 | obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o | ||
| 90 | obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o | ||
| 88 | 91 | ||
| 89 | # | 92 | # |
| 90 | # generic algorithms and the async_tx api | 93 | # generic algorithms and the async_tx api |
diff --git a/crypto/af_alg.c b/crypto/af_alg.c new file mode 100644 index 000000000000..940d70cb5c25 --- /dev/null +++ b/crypto/af_alg.c | |||
| @@ -0,0 +1,483 @@ | |||
| 1 | /* | ||
| 2 | * af_alg: User-space algorithm interface | ||
| 3 | * | ||
| 4 | * This file provides the user-space API for algorithms. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the Free | ||
| 10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <asm/atomic.h> | ||
| 16 | #include <crypto/if_alg.h> | ||
| 17 | #include <linux/crypto.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/list.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/net.h> | ||
| 23 | #include <linux/rwsem.h> | ||
| 24 | |||
| 25 | struct alg_type_list { | ||
| 26 | const struct af_alg_type *type; | ||
| 27 | struct list_head list; | ||
| 28 | }; | ||
| 29 | |||
| 30 | static atomic_long_t alg_memory_allocated; | ||
| 31 | |||
| 32 | static struct proto alg_proto = { | ||
| 33 | .name = "ALG", | ||
| 34 | .owner = THIS_MODULE, | ||
| 35 | .memory_allocated = &alg_memory_allocated, | ||
| 36 | .obj_size = sizeof(struct alg_sock), | ||
| 37 | }; | ||
| 38 | |||
| 39 | static LIST_HEAD(alg_types); | ||
| 40 | static DECLARE_RWSEM(alg_types_sem); | ||
| 41 | |||
| 42 | static const struct af_alg_type *alg_get_type(const char *name) | ||
| 43 | { | ||
| 44 | const struct af_alg_type *type = ERR_PTR(-ENOENT); | ||
| 45 | struct alg_type_list *node; | ||
| 46 | |||
| 47 | down_read(&alg_types_sem); | ||
| 48 | list_for_each_entry(node, &alg_types, list) { | ||
| 49 | if (strcmp(node->type->name, name)) | ||
| 50 | continue; | ||
| 51 | |||
| 52 | if (try_module_get(node->type->owner)) | ||
| 53 | type = node->type; | ||
| 54 | break; | ||
| 55 | } | ||
| 56 | up_read(&alg_types_sem); | ||
| 57 | |||
| 58 | return type; | ||
| 59 | } | ||
| 60 | |||
| 61 | int af_alg_register_type(const struct af_alg_type *type) | ||
| 62 | { | ||
| 63 | struct alg_type_list *node; | ||
| 64 | int err = -EEXIST; | ||
| 65 | |||
| 66 | down_write(&alg_types_sem); | ||
| 67 | list_for_each_entry(node, &alg_types, list) { | ||
| 68 | if (!strcmp(node->type->name, type->name)) | ||
| 69 | goto unlock; | ||
| 70 | } | ||
| 71 | |||
| 72 | node = kmalloc(sizeof(*node), GFP_KERNEL); | ||
| 73 | err = -ENOMEM; | ||
| 74 | if (!node) | ||
| 75 | goto unlock; | ||
| 76 | |||
| 77 | type->ops->owner = THIS_MODULE; | ||
| 78 | node->type = type; | ||
| 79 | list_add(&node->list, &alg_types); | ||
| 80 | err = 0; | ||
| 81 | |||
| 82 | unlock: | ||
| 83 | up_write(&alg_types_sem); | ||
| 84 | |||
| 85 | return err; | ||
| 86 | } | ||
| 87 | EXPORT_SYMBOL_GPL(af_alg_register_type); | ||
| 88 | |||
| 89 | int af_alg_unregister_type(const struct af_alg_type *type) | ||
| 90 | { | ||
| 91 | struct alg_type_list *node; | ||
| 92 | int err = -ENOENT; | ||
| 93 | |||
| 94 | down_write(&alg_types_sem); | ||
| 95 | list_for_each_entry(node, &alg_types, list) { | ||
| 96 | if (strcmp(node->type->name, type->name)) | ||
| 97 | continue; | ||
| 98 | |||
| 99 | list_del(&node->list); | ||
| 100 | kfree(node); | ||
| 101 | err = 0; | ||
| 102 | break; | ||
| 103 | } | ||
| 104 | up_write(&alg_types_sem); | ||
| 105 | |||
| 106 | return err; | ||
| 107 | } | ||
| 108 | EXPORT_SYMBOL_GPL(af_alg_unregister_type); | ||
| 109 | |||
| 110 | static void alg_do_release(const struct af_alg_type *type, void *private) | ||
| 111 | { | ||
| 112 | if (!type) | ||
| 113 | return; | ||
| 114 | |||
| 115 | type->release(private); | ||
| 116 | module_put(type->owner); | ||
| 117 | } | ||
| 118 | |||
| 119 | int af_alg_release(struct socket *sock) | ||
| 120 | { | ||
| 121 | if (sock->sk) | ||
| 122 | sock_put(sock->sk); | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | EXPORT_SYMBOL_GPL(af_alg_release); | ||
| 126 | |||
| 127 | static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | ||
| 128 | { | ||
| 129 | struct sock *sk = sock->sk; | ||
| 130 | struct alg_sock *ask = alg_sk(sk); | ||
| 131 | struct sockaddr_alg *sa = (void *)uaddr; | ||
| 132 | const struct af_alg_type *type; | ||
| 133 | void *private; | ||
| 134 | |||
| 135 | if (sock->state == SS_CONNECTED) | ||
| 136 | return -EINVAL; | ||
| 137 | |||
| 138 | if (addr_len != sizeof(*sa)) | ||
| 139 | return -EINVAL; | ||
| 140 | |||
| 141 | sa->salg_type[sizeof(sa->salg_type) - 1] = 0; | ||
| 142 | sa->salg_name[sizeof(sa->salg_name) - 1] = 0; | ||
| 143 | |||
| 144 | type = alg_get_type(sa->salg_type); | ||
| 145 | if (IS_ERR(type) && PTR_ERR(type) == -ENOENT) { | ||
| 146 | request_module("algif-%s", sa->salg_type); | ||
| 147 | type = alg_get_type(sa->salg_type); | ||
| 148 | } | ||
| 149 | |||
| 150 | if (IS_ERR(type)) | ||
| 151 | return PTR_ERR(type); | ||
| 152 | |||
| 153 | private = type->bind(sa->salg_name, sa->salg_feat, sa->salg_mask); | ||
| 154 | if (IS_ERR(private)) { | ||
| 155 | module_put(type->owner); | ||
| 156 | return PTR_ERR(private); | ||
| 157 | } | ||
| 158 | |||
| 159 | lock_sock(sk); | ||
| 160 | |||
| 161 | swap(ask->type, type); | ||
| 162 | swap(ask->private, private); | ||
| 163 | |||
| 164 | release_sock(sk); | ||
| 165 | |||
| 166 | alg_do_release(type, private); | ||
| 167 | |||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int alg_setkey(struct sock *sk, char __user *ukey, | ||
| 172 | unsigned int keylen) | ||
| 173 | { | ||
| 174 | struct alg_sock *ask = alg_sk(sk); | ||
| 175 | const struct af_alg_type *type = ask->type; | ||
| 176 | u8 *key; | ||
| 177 | int err; | ||
| 178 | |||
| 179 | key = sock_kmalloc(sk, keylen, GFP_KERNEL); | ||
| 180 | if (!key) | ||
| 181 | return -ENOMEM; | ||
| 182 | |||
| 183 | err = -EFAULT; | ||
| 184 | if (copy_from_user(key, ukey, keylen)) | ||
| 185 | goto out; | ||
| 186 | |||
| 187 | err = type->setkey(ask->private, key, keylen); | ||
| 188 | |||
| 189 | out: | ||
| 190 | sock_kfree_s(sk, key, keylen); | ||
| 191 | |||
| 192 | return err; | ||
| 193 | } | ||
| 194 | |||
| 195 | static int alg_setsockopt(struct socket *sock, int level, int optname, | ||
| 196 | char __user *optval, unsigned int optlen) | ||
| 197 | { | ||
| 198 | struct sock *sk = sock->sk; | ||
| 199 | struct alg_sock *ask = alg_sk(sk); | ||
| 200 | const struct af_alg_type *type; | ||
| 201 | int err = -ENOPROTOOPT; | ||
| 202 | |||
| 203 | lock_sock(sk); | ||
| 204 | type = ask->type; | ||
| 205 | |||
| 206 | if (level != SOL_ALG || !type) | ||
| 207 | goto unlock; | ||
| 208 | |||
| 209 | switch (optname) { | ||
| 210 | case ALG_SET_KEY: | ||
| 211 | if (sock->state == SS_CONNECTED) | ||
| 212 | goto unlock; | ||
| 213 | if (!type->setkey) | ||
| 214 | goto unlock; | ||
| 215 | |||
| 216 | err = alg_setkey(sk, optval, optlen); | ||
| 217 | } | ||
| 218 | |||
| 219 | unlock: | ||
| 220 | release_sock(sk); | ||
| 221 | |||
| 222 | return err; | ||
| 223 | } | ||
| 224 | |||
| 225 | int af_alg_accept(struct sock *sk, struct socket *newsock) | ||
| 226 | { | ||
| 227 | struct alg_sock *ask = alg_sk(sk); | ||
| 228 | const struct af_alg_type *type; | ||
| 229 | struct sock *sk2; | ||
| 230 | int err; | ||
| 231 | |||
| 232 | lock_sock(sk); | ||
| 233 | type = ask->type; | ||
| 234 | |||
| 235 | err = -EINVAL; | ||
| 236 | if (!type) | ||
| 237 | goto unlock; | ||
| 238 | |||
| 239 | sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto); | ||
| 240 | err = -ENOMEM; | ||
| 241 | if (!sk2) | ||
| 242 | goto unlock; | ||
| 243 | |||
| 244 | sock_init_data(newsock, sk2); | ||
| 245 | sock_graft(sk2, newsock); | ||
| 246 | |||
| 247 | err = type->accept(ask->private, sk2); | ||
| 248 | if (err) { | ||
| 249 | sk_free(sk2); | ||
| 250 | goto unlock; | ||
| 251 | } | ||
| 252 | |||
| 253 | sk2->sk_family = PF_ALG; | ||
| 254 | |||
| 255 | sock_hold(sk); | ||
| 256 | alg_sk(sk2)->parent = sk; | ||
| 257 | alg_sk(sk2)->type = type; | ||
| 258 | |||
| 259 | newsock->ops = type->ops; | ||
| 260 | newsock->state = SS_CONNECTED; | ||
| 261 | |||
| 262 | err = 0; | ||
| 263 | |||
| 264 | unlock: | ||
| 265 | release_sock(sk); | ||
| 266 | |||
| 267 | return err; | ||
| 268 | } | ||
| 269 | EXPORT_SYMBOL_GPL(af_alg_accept); | ||
| 270 | |||
| 271 | static int alg_accept(struct socket *sock, struct socket *newsock, int flags) | ||
| 272 | { | ||
| 273 | return af_alg_accept(sock->sk, newsock); | ||
| 274 | } | ||
| 275 | |||
| 276 | static const struct proto_ops alg_proto_ops = { | ||
| 277 | .family = PF_ALG, | ||
| 278 | .owner = THIS_MODULE, | ||
| 279 | |||
| 280 | .connect = sock_no_connect, | ||
| 281 | .socketpair = sock_no_socketpair, | ||
| 282 | .getname = sock_no_getname, | ||
| 283 | .ioctl = sock_no_ioctl, | ||
| 284 | .listen = sock_no_listen, | ||
| 285 | .shutdown = sock_no_shutdown, | ||
| 286 | .getsockopt = sock_no_getsockopt, | ||
| 287 | .mmap = sock_no_mmap, | ||
| 288 | .sendpage = sock_no_sendpage, | ||
| 289 | .sendmsg = sock_no_sendmsg, | ||
| 290 | .recvmsg = sock_no_recvmsg, | ||
| 291 | .poll = sock_no_poll, | ||
| 292 | |||
| 293 | .bind = alg_bind, | ||
| 294 | .release = af_alg_release, | ||
| 295 | .setsockopt = alg_setsockopt, | ||
| 296 | .accept = alg_accept, | ||
| 297 | }; | ||
| 298 | |||
| 299 | static void alg_sock_destruct(struct sock *sk) | ||
| 300 | { | ||
| 301 | struct alg_sock *ask = alg_sk(sk); | ||
| 302 | |||
| 303 | alg_do_release(ask->type, ask->private); | ||
| 304 | } | ||
| 305 | |||
| 306 | static int alg_create(struct net *net, struct socket *sock, int protocol, | ||
| 307 | int kern) | ||
| 308 | { | ||
| 309 | struct sock *sk; | ||
| 310 | int err; | ||
| 311 | |||
| 312 | if (sock->type != SOCK_SEQPACKET) | ||
| 313 | return -ESOCKTNOSUPPORT; | ||
| 314 | if (protocol != 0) | ||
| 315 | return -EPROTONOSUPPORT; | ||
| 316 | |||
| 317 | err = -ENOMEM; | ||
| 318 | sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto); | ||
| 319 | if (!sk) | ||
| 320 | goto out; | ||
| 321 | |||
| 322 | sock->ops = &alg_proto_ops; | ||
| 323 | sock_init_data(sock, sk); | ||
| 324 | |||
| 325 | sk->sk_family = PF_ALG; | ||
| 326 | sk->sk_destruct = alg_sock_destruct; | ||
| 327 | |||
| 328 | return 0; | ||
| 329 | out: | ||
| 330 | return err; | ||
| 331 | } | ||
| 332 | |||
| 333 | static const struct net_proto_family alg_family = { | ||
| 334 | .family = PF_ALG, | ||
| 335 | .create = alg_create, | ||
| 336 | .owner = THIS_MODULE, | ||
| 337 | }; | ||
| 338 | |||
| 339 | int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, | ||
| 340 | int write) | ||
| 341 | { | ||
| 342 | unsigned long from = (unsigned long)addr; | ||
| 343 | unsigned long npages; | ||
| 344 | unsigned off; | ||
| 345 | int err; | ||
| 346 | int i; | ||
| 347 | |||
| 348 | err = -EFAULT; | ||
| 349 | if (!access_ok(write ? VERIFY_READ : VERIFY_WRITE, addr, len)) | ||
| 350 | goto out; | ||
| 351 | |||
| 352 | off = from & ~PAGE_MASK; | ||
| 353 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 354 | if (npages > ALG_MAX_PAGES) | ||
| 355 | npages = ALG_MAX_PAGES; | ||
| 356 | |||
| 357 | err = get_user_pages_fast(from, npages, write, sgl->pages); | ||
| 358 | if (err < 0) | ||
| 359 | goto out; | ||
| 360 | |||
| 361 | npages = err; | ||
| 362 | err = -EINVAL; | ||
| 363 | if (WARN_ON(npages == 0)) | ||
| 364 | goto out; | ||
| 365 | |||
| 366 | err = 0; | ||
| 367 | |||
| 368 | sg_init_table(sgl->sg, npages); | ||
| 369 | |||
| 370 | for (i = 0; i < npages; i++) { | ||
| 371 | int plen = min_t(int, len, PAGE_SIZE - off); | ||
| 372 | |||
| 373 | sg_set_page(sgl->sg + i, sgl->pages[i], plen, off); | ||
| 374 | |||
| 375 | off = 0; | ||
| 376 | len -= plen; | ||
| 377 | err += plen; | ||
| 378 | } | ||
| 379 | |||
| 380 | out: | ||
| 381 | return err; | ||
| 382 | } | ||
| 383 | EXPORT_SYMBOL_GPL(af_alg_make_sg); | ||
| 384 | |||
| 385 | void af_alg_free_sg(struct af_alg_sgl *sgl) | ||
| 386 | { | ||
| 387 | int i; | ||
| 388 | |||
| 389 | i = 0; | ||
| 390 | do { | ||
| 391 | put_page(sgl->pages[i]); | ||
| 392 | } while (!sg_is_last(sgl->sg + (i++))); | ||
| 393 | } | ||
| 394 | EXPORT_SYMBOL_GPL(af_alg_free_sg); | ||
| 395 | |||
| 396 | int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con) | ||
| 397 | { | ||
| 398 | struct cmsghdr *cmsg; | ||
| 399 | |||
| 400 | for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { | ||
| 401 | if (!CMSG_OK(msg, cmsg)) | ||
| 402 | return -EINVAL; | ||
| 403 | if (cmsg->cmsg_level != SOL_ALG) | ||
| 404 | continue; | ||
| 405 | |||
| 406 | switch(cmsg->cmsg_type) { | ||
| 407 | case ALG_SET_IV: | ||
| 408 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(*con->iv))) | ||
| 409 | return -EINVAL; | ||
| 410 | con->iv = (void *)CMSG_DATA(cmsg); | ||
| 411 | if (cmsg->cmsg_len < CMSG_LEN(con->iv->ivlen + | ||
| 412 | sizeof(*con->iv))) | ||
| 413 | return -EINVAL; | ||
| 414 | break; | ||
| 415 | |||
| 416 | case ALG_SET_OP: | ||
| 417 | if (cmsg->cmsg_len < CMSG_LEN(sizeof(u32))) | ||
| 418 | return -EINVAL; | ||
| 419 | con->op = *(u32 *)CMSG_DATA(cmsg); | ||
| 420 | break; | ||
| 421 | |||
| 422 | default: | ||
| 423 | return -EINVAL; | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 427 | return 0; | ||
| 428 | } | ||
| 429 | EXPORT_SYMBOL_GPL(af_alg_cmsg_send); | ||
| 430 | |||
| 431 | int af_alg_wait_for_completion(int err, struct af_alg_completion *completion) | ||
| 432 | { | ||
| 433 | switch (err) { | ||
| 434 | case -EINPROGRESS: | ||
| 435 | case -EBUSY: | ||
| 436 | wait_for_completion(&completion->completion); | ||
| 437 | INIT_COMPLETION(completion->completion); | ||
| 438 | err = completion->err; | ||
| 439 | break; | ||
| 440 | }; | ||
| 441 | |||
| 442 | return err; | ||
| 443 | } | ||
| 444 | EXPORT_SYMBOL_GPL(af_alg_wait_for_completion); | ||
| 445 | |||
| 446 | void af_alg_complete(struct crypto_async_request *req, int err) | ||
| 447 | { | ||
| 448 | struct af_alg_completion *completion = req->data; | ||
| 449 | |||
| 450 | completion->err = err; | ||
| 451 | complete(&completion->completion); | ||
| 452 | } | ||
| 453 | EXPORT_SYMBOL_GPL(af_alg_complete); | ||
| 454 | |||
| 455 | static int __init af_alg_init(void) | ||
| 456 | { | ||
| 457 | int err = proto_register(&alg_proto, 0); | ||
| 458 | |||
| 459 | if (err) | ||
| 460 | goto out; | ||
| 461 | |||
| 462 | err = sock_register(&alg_family); | ||
| 463 | if (err != 0) | ||
| 464 | goto out_unregister_proto; | ||
| 465 | |||
| 466 | out: | ||
| 467 | return err; | ||
| 468 | |||
| 469 | out_unregister_proto: | ||
| 470 | proto_unregister(&alg_proto); | ||
| 471 | goto out; | ||
| 472 | } | ||
| 473 | |||
| 474 | static void __exit af_alg_exit(void) | ||
| 475 | { | ||
| 476 | sock_unregister(PF_ALG); | ||
| 477 | proto_unregister(&alg_proto); | ||
| 478 | } | ||
| 479 | |||
| 480 | module_init(af_alg_init); | ||
| 481 | module_exit(af_alg_exit); | ||
| 482 | MODULE_LICENSE("GPL"); | ||
| 483 | MODULE_ALIAS_NETPROTO(AF_ALG); | ||
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c new file mode 100644 index 000000000000..62122a1a2f7a --- /dev/null +++ b/crypto/algif_hash.c | |||
| @@ -0,0 +1,319 @@ | |||
| 1 | /* | ||
| 2 | * algif_hash: User-space interface for hash algorithms | ||
| 3 | * | ||
| 4 | * This file provides the user-space API for hash algorithms. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the Free | ||
| 10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <crypto/hash.h> | ||
| 16 | #include <crypto/if_alg.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/mm.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/net.h> | ||
| 22 | #include <net/sock.h> | ||
| 23 | |||
| 24 | struct hash_ctx { | ||
| 25 | struct af_alg_sgl sgl; | ||
| 26 | |||
| 27 | u8 *result; | ||
| 28 | |||
| 29 | struct af_alg_completion completion; | ||
| 30 | |||
| 31 | unsigned int len; | ||
| 32 | bool more; | ||
| 33 | |||
| 34 | struct ahash_request req; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static int hash_sendmsg(struct kiocb *unused, struct socket *sock, | ||
| 38 | struct msghdr *msg, size_t ignored) | ||
| 39 | { | ||
| 40 | int limit = ALG_MAX_PAGES * PAGE_SIZE; | ||
| 41 | struct sock *sk = sock->sk; | ||
| 42 | struct alg_sock *ask = alg_sk(sk); | ||
| 43 | struct hash_ctx *ctx = ask->private; | ||
| 44 | unsigned long iovlen; | ||
| 45 | struct iovec *iov; | ||
| 46 | long copied = 0; | ||
| 47 | int err; | ||
| 48 | |||
| 49 | if (limit > sk->sk_sndbuf) | ||
| 50 | limit = sk->sk_sndbuf; | ||
| 51 | |||
| 52 | lock_sock(sk); | ||
| 53 | if (!ctx->more) { | ||
| 54 | err = crypto_ahash_init(&ctx->req); | ||
| 55 | if (err) | ||
| 56 | goto unlock; | ||
| 57 | } | ||
| 58 | |||
| 59 | ctx->more = 0; | ||
| 60 | |||
| 61 | for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; | ||
| 62 | iovlen--, iov++) { | ||
| 63 | unsigned long seglen = iov->iov_len; | ||
| 64 | char __user *from = iov->iov_base; | ||
| 65 | |||
| 66 | while (seglen) { | ||
| 67 | int len = min_t(unsigned long, seglen, limit); | ||
| 68 | int newlen; | ||
| 69 | |||
| 70 | newlen = af_alg_make_sg(&ctx->sgl, from, len, 0); | ||
| 71 | if (newlen < 0) | ||
| 72 | goto unlock; | ||
| 73 | |||
| 74 | ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL, | ||
| 75 | newlen); | ||
| 76 | |||
| 77 | err = af_alg_wait_for_completion( | ||
| 78 | crypto_ahash_update(&ctx->req), | ||
| 79 | &ctx->completion); | ||
| 80 | |||
| 81 | af_alg_free_sg(&ctx->sgl); | ||
| 82 | |||
| 83 | if (err) | ||
| 84 | goto unlock; | ||
| 85 | |||
| 86 | seglen -= newlen; | ||
| 87 | from += newlen; | ||
| 88 | copied += newlen; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | err = 0; | ||
| 93 | |||
| 94 | ctx->more = msg->msg_flags & MSG_MORE; | ||
| 95 | if (!ctx->more) { | ||
| 96 | ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0); | ||
| 97 | err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req), | ||
| 98 | &ctx->completion); | ||
| 99 | } | ||
| 100 | |||
| 101 | unlock: | ||
| 102 | release_sock(sk); | ||
| 103 | |||
| 104 | return err ?: copied; | ||
| 105 | } | ||
| 106 | |||
| 107 | static ssize_t hash_sendpage(struct socket *sock, struct page *page, | ||
| 108 | int offset, size_t size, int flags) | ||
| 109 | { | ||
| 110 | struct sock *sk = sock->sk; | ||
| 111 | struct alg_sock *ask = alg_sk(sk); | ||
| 112 | struct hash_ctx *ctx = ask->private; | ||
| 113 | int err; | ||
| 114 | |||
| 115 | lock_sock(sk); | ||
| 116 | sg_init_table(ctx->sgl.sg, 1); | ||
| 117 | sg_set_page(ctx->sgl.sg, page, size, offset); | ||
| 118 | |||
| 119 | ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, ctx->result, size); | ||
| 120 | |||
| 121 | if (!(flags & MSG_MORE)) { | ||
| 122 | if (ctx->more) | ||
| 123 | err = crypto_ahash_finup(&ctx->req); | ||
| 124 | else | ||
| 125 | err = crypto_ahash_digest(&ctx->req); | ||
| 126 | } else { | ||
| 127 | if (!ctx->more) { | ||
| 128 | err = crypto_ahash_init(&ctx->req); | ||
| 129 | if (err) | ||
| 130 | goto unlock; | ||
| 131 | } | ||
| 132 | |||
| 133 | err = crypto_ahash_update(&ctx->req); | ||
| 134 | } | ||
| 135 | |||
| 136 | err = af_alg_wait_for_completion(err, &ctx->completion); | ||
| 137 | if (err) | ||
| 138 | goto unlock; | ||
| 139 | |||
| 140 | ctx->more = flags & MSG_MORE; | ||
| 141 | |||
| 142 | unlock: | ||
| 143 | release_sock(sk); | ||
| 144 | |||
| 145 | return err ?: size; | ||
| 146 | } | ||
| 147 | |||
| 148 | static int hash_recvmsg(struct kiocb *unused, struct socket *sock, | ||
| 149 | struct msghdr *msg, size_t len, int flags) | ||
| 150 | { | ||
| 151 | struct sock *sk = sock->sk; | ||
| 152 | struct alg_sock *ask = alg_sk(sk); | ||
| 153 | struct hash_ctx *ctx = ask->private; | ||
| 154 | unsigned ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req)); | ||
| 155 | int err; | ||
| 156 | |||
| 157 | if (len > ds) | ||
| 158 | len = ds; | ||
| 159 | else if (len < ds) | ||
| 160 | msg->msg_flags |= MSG_TRUNC; | ||
| 161 | |||
| 162 | lock_sock(sk); | ||
| 163 | if (ctx->more) { | ||
| 164 | ctx->more = 0; | ||
| 165 | ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0); | ||
| 166 | err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req), | ||
| 167 | &ctx->completion); | ||
| 168 | if (err) | ||
| 169 | goto unlock; | ||
| 170 | } | ||
| 171 | |||
| 172 | err = memcpy_toiovec(msg->msg_iov, ctx->result, len); | ||
| 173 | |||
| 174 | unlock: | ||
| 175 | release_sock(sk); | ||
| 176 | |||
| 177 | return err ?: len; | ||
| 178 | } | ||
| 179 | |||
| 180 | static int hash_accept(struct socket *sock, struct socket *newsock, int flags) | ||
| 181 | { | ||
| 182 | struct sock *sk = sock->sk; | ||
| 183 | struct alg_sock *ask = alg_sk(sk); | ||
| 184 | struct hash_ctx *ctx = ask->private; | ||
| 185 | struct ahash_request *req = &ctx->req; | ||
| 186 | char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req))]; | ||
| 187 | struct sock *sk2; | ||
| 188 | struct alg_sock *ask2; | ||
| 189 | struct hash_ctx *ctx2; | ||
| 190 | int err; | ||
| 191 | |||
| 192 | err = crypto_ahash_export(req, state); | ||
| 193 | if (err) | ||
| 194 | return err; | ||
| 195 | |||
| 196 | err = af_alg_accept(ask->parent, newsock); | ||
| 197 | if (err) | ||
| 198 | return err; | ||
| 199 | |||
| 200 | sk2 = newsock->sk; | ||
| 201 | ask2 = alg_sk(sk2); | ||
| 202 | ctx2 = ask2->private; | ||
| 203 | ctx2->more = 1; | ||
| 204 | |||
| 205 | err = crypto_ahash_import(&ctx2->req, state); | ||
| 206 | if (err) { | ||
| 207 | sock_orphan(sk2); | ||
| 208 | sock_put(sk2); | ||
| 209 | } | ||
| 210 | |||
| 211 | return err; | ||
| 212 | } | ||
| 213 | |||
| 214 | static struct proto_ops algif_hash_ops = { | ||
| 215 | .family = PF_ALG, | ||
| 216 | |||
| 217 | .connect = sock_no_connect, | ||
| 218 | .socketpair = sock_no_socketpair, | ||
| 219 | .getname = sock_no_getname, | ||
| 220 | .ioctl = sock_no_ioctl, | ||
| 221 | .listen = sock_no_listen, | ||
| 222 | .shutdown = sock_no_shutdown, | ||
| 223 | .getsockopt = sock_no_getsockopt, | ||
| 224 | .mmap = sock_no_mmap, | ||
| 225 | .bind = sock_no_bind, | ||
| 226 | .setsockopt = sock_no_setsockopt, | ||
| 227 | .poll = sock_no_poll, | ||
| 228 | |||
| 229 | .release = af_alg_release, | ||
| 230 | .sendmsg = hash_sendmsg, | ||
| 231 | .sendpage = hash_sendpage, | ||
| 232 | .recvmsg = hash_recvmsg, | ||
| 233 | .accept = hash_accept, | ||
| 234 | }; | ||
| 235 | |||
| 236 | static void *hash_bind(const char *name, u32 type, u32 mask) | ||
| 237 | { | ||
| 238 | return crypto_alloc_ahash(name, type, mask); | ||
| 239 | } | ||
| 240 | |||
| 241 | static void hash_release(void *private) | ||
| 242 | { | ||
| 243 | crypto_free_ahash(private); | ||
| 244 | } | ||
| 245 | |||
| 246 | static int hash_setkey(void *private, const u8 *key, unsigned int keylen) | ||
| 247 | { | ||
| 248 | return crypto_ahash_setkey(private, key, keylen); | ||
| 249 | } | ||
| 250 | |||
| 251 | static void hash_sock_destruct(struct sock *sk) | ||
| 252 | { | ||
| 253 | struct alg_sock *ask = alg_sk(sk); | ||
| 254 | struct hash_ctx *ctx = ask->private; | ||
| 255 | |||
| 256 | sock_kfree_s(sk, ctx->result, | ||
| 257 | crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req))); | ||
| 258 | sock_kfree_s(sk, ctx, ctx->len); | ||
| 259 | af_alg_release_parent(sk); | ||
| 260 | } | ||
| 261 | |||
| 262 | static int hash_accept_parent(void *private, struct sock *sk) | ||
| 263 | { | ||
| 264 | struct hash_ctx *ctx; | ||
| 265 | struct alg_sock *ask = alg_sk(sk); | ||
| 266 | unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private); | ||
| 267 | unsigned ds = crypto_ahash_digestsize(private); | ||
| 268 | |||
| 269 | ctx = sock_kmalloc(sk, len, GFP_KERNEL); | ||
| 270 | if (!ctx) | ||
| 271 | return -ENOMEM; | ||
| 272 | |||
| 273 | ctx->result = sock_kmalloc(sk, ds, GFP_KERNEL); | ||
| 274 | if (!ctx->result) { | ||
| 275 | sock_kfree_s(sk, ctx, len); | ||
| 276 | return -ENOMEM; | ||
| 277 | } | ||
| 278 | |||
| 279 | memset(ctx->result, 0, ds); | ||
| 280 | |||
| 281 | ctx->len = len; | ||
| 282 | ctx->more = 0; | ||
| 283 | af_alg_init_completion(&ctx->completion); | ||
| 284 | |||
| 285 | ask->private = ctx; | ||
| 286 | |||
| 287 | ahash_request_set_tfm(&ctx->req, private); | ||
| 288 | ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
| 289 | af_alg_complete, &ctx->completion); | ||
| 290 | |||
| 291 | sk->sk_destruct = hash_sock_destruct; | ||
| 292 | |||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 296 | static const struct af_alg_type algif_type_hash = { | ||
| 297 | .bind = hash_bind, | ||
| 298 | .release = hash_release, | ||
| 299 | .setkey = hash_setkey, | ||
| 300 | .accept = hash_accept_parent, | ||
| 301 | .ops = &algif_hash_ops, | ||
| 302 | .name = "hash", | ||
| 303 | .owner = THIS_MODULE | ||
| 304 | }; | ||
| 305 | |||
| 306 | static int __init algif_hash_init(void) | ||
| 307 | { | ||
| 308 | return af_alg_register_type(&algif_type_hash); | ||
| 309 | } | ||
| 310 | |||
| 311 | static void __exit algif_hash_exit(void) | ||
| 312 | { | ||
| 313 | int err = af_alg_unregister_type(&algif_type_hash); | ||
| 314 | BUG_ON(err); | ||
| 315 | } | ||
| 316 | |||
| 317 | module_init(algif_hash_init); | ||
| 318 | module_exit(algif_hash_exit); | ||
| 319 | MODULE_LICENSE("GPL"); | ||
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c new file mode 100644 index 000000000000..6a6dfc062d2a --- /dev/null +++ b/crypto/algif_skcipher.c | |||
| @@ -0,0 +1,632 @@ | |||
| 1 | /* | ||
| 2 | * algif_skcipher: User-space interface for skcipher algorithms | ||
| 3 | * | ||
| 4 | * This file provides the user-space API for symmetric key ciphers. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the Free | ||
| 10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <crypto/scatterwalk.h> | ||
| 16 | #include <crypto/skcipher.h> | ||
| 17 | #include <crypto/if_alg.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/list.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/mm.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/net.h> | ||
| 24 | #include <net/sock.h> | ||
| 25 | |||
| 26 | struct skcipher_sg_list { | ||
| 27 | struct list_head list; | ||
| 28 | |||
| 29 | int cur; | ||
| 30 | |||
| 31 | struct scatterlist sg[0]; | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct skcipher_ctx { | ||
| 35 | struct list_head tsgl; | ||
| 36 | struct af_alg_sgl rsgl; | ||
| 37 | |||
| 38 | void *iv; | ||
| 39 | |||
| 40 | struct af_alg_completion completion; | ||
| 41 | |||
| 42 | unsigned used; | ||
| 43 | |||
| 44 | unsigned int len; | ||
| 45 | bool more; | ||
| 46 | bool merge; | ||
| 47 | bool enc; | ||
| 48 | |||
| 49 | struct ablkcipher_request req; | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \ | ||
| 53 | sizeof(struct scatterlist) - 1) | ||
| 54 | |||
| 55 | static inline int skcipher_sndbuf(struct sock *sk) | ||
| 56 | { | ||
| 57 | struct alg_sock *ask = alg_sk(sk); | ||
| 58 | struct skcipher_ctx *ctx = ask->private; | ||
| 59 | |||
| 60 | return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) - | ||
| 61 | ctx->used, 0); | ||
| 62 | } | ||
| 63 | |||
| 64 | static inline bool skcipher_writable(struct sock *sk) | ||
| 65 | { | ||
| 66 | return PAGE_SIZE <= skcipher_sndbuf(sk); | ||
| 67 | } | ||
| 68 | |||
| 69 | static int skcipher_alloc_sgl(struct sock *sk) | ||
| 70 | { | ||
| 71 | struct alg_sock *ask = alg_sk(sk); | ||
| 72 | struct skcipher_ctx *ctx = ask->private; | ||
| 73 | struct skcipher_sg_list *sgl; | ||
| 74 | struct scatterlist *sg = NULL; | ||
| 75 | |||
| 76 | sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); | ||
| 77 | if (!list_empty(&ctx->tsgl)) | ||
| 78 | sg = sgl->sg; | ||
| 79 | |||
| 80 | if (!sg || sgl->cur >= MAX_SGL_ENTS) { | ||
| 81 | sgl = sock_kmalloc(sk, sizeof(*sgl) + | ||
| 82 | sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1), | ||
| 83 | GFP_KERNEL); | ||
| 84 | if (!sgl) | ||
| 85 | return -ENOMEM; | ||
| 86 | |||
| 87 | sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); | ||
| 88 | sgl->cur = 0; | ||
| 89 | |||
| 90 | if (sg) | ||
| 91 | scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); | ||
| 92 | |||
| 93 | list_add_tail(&sgl->list, &ctx->tsgl); | ||
| 94 | } | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static void skcipher_pull_sgl(struct sock *sk, int used) | ||
| 100 | { | ||
| 101 | struct alg_sock *ask = alg_sk(sk); | ||
| 102 | struct skcipher_ctx *ctx = ask->private; | ||
| 103 | struct skcipher_sg_list *sgl; | ||
| 104 | struct scatterlist *sg; | ||
| 105 | int i; | ||
| 106 | |||
| 107 | while (!list_empty(&ctx->tsgl)) { | ||
| 108 | sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, | ||
| 109 | list); | ||
| 110 | sg = sgl->sg; | ||
| 111 | |||
| 112 | for (i = 0; i < sgl->cur; i++) { | ||
| 113 | int plen = min_t(int, used, sg[i].length); | ||
| 114 | |||
| 115 | if (!sg_page(sg + i)) | ||
| 116 | continue; | ||
| 117 | |||
| 118 | sg[i].length -= plen; | ||
| 119 | sg[i].offset += plen; | ||
| 120 | |||
| 121 | used -= plen; | ||
| 122 | ctx->used -= plen; | ||
| 123 | |||
| 124 | if (sg[i].length) | ||
| 125 | return; | ||
| 126 | |||
| 127 | put_page(sg_page(sg + i)); | ||
| 128 | sg_assign_page(sg + i, NULL); | ||
| 129 | } | ||
| 130 | |||
| 131 | list_del(&sgl->list); | ||
| 132 | sock_kfree_s(sk, sgl, | ||
| 133 | sizeof(*sgl) + sizeof(sgl->sg[0]) * | ||
| 134 | (MAX_SGL_ENTS + 1)); | ||
| 135 | } | ||
| 136 | |||
| 137 | if (!ctx->used) | ||
| 138 | ctx->merge = 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | static void skcipher_free_sgl(struct sock *sk) | ||
| 142 | { | ||
| 143 | struct alg_sock *ask = alg_sk(sk); | ||
| 144 | struct skcipher_ctx *ctx = ask->private; | ||
| 145 | |||
| 146 | skcipher_pull_sgl(sk, ctx->used); | ||
| 147 | } | ||
| 148 | |||
| 149 | static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags) | ||
| 150 | { | ||
| 151 | long timeout; | ||
| 152 | DEFINE_WAIT(wait); | ||
| 153 | int err = -ERESTARTSYS; | ||
| 154 | |||
| 155 | if (flags & MSG_DONTWAIT) | ||
| 156 | return -EAGAIN; | ||
| 157 | |||
| 158 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | ||
| 159 | |||
| 160 | for (;;) { | ||
| 161 | if (signal_pending(current)) | ||
| 162 | break; | ||
| 163 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 164 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
| 165 | if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) { | ||
| 166 | err = 0; | ||
| 167 | break; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | finish_wait(sk_sleep(sk), &wait); | ||
| 171 | |||
| 172 | return err; | ||
| 173 | } | ||
| 174 | |||
| 175 | static void skcipher_wmem_wakeup(struct sock *sk) | ||
| 176 | { | ||
| 177 | struct socket_wq *wq; | ||
| 178 | |||
| 179 | if (!skcipher_writable(sk)) | ||
| 180 | return; | ||
| 181 | |||
| 182 | rcu_read_lock(); | ||
| 183 | wq = rcu_dereference(sk->sk_wq); | ||
| 184 | if (wq_has_sleeper(wq)) | ||
| 185 | wake_up_interruptible_sync_poll(&wq->wait, POLLIN | | ||
| 186 | POLLRDNORM | | ||
| 187 | POLLRDBAND); | ||
| 188 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); | ||
| 189 | rcu_read_unlock(); | ||
| 190 | } | ||
| 191 | |||
| 192 | static int skcipher_wait_for_data(struct sock *sk, unsigned flags) | ||
| 193 | { | ||
| 194 | struct alg_sock *ask = alg_sk(sk); | ||
| 195 | struct skcipher_ctx *ctx = ask->private; | ||
| 196 | long timeout; | ||
| 197 | DEFINE_WAIT(wait); | ||
| 198 | int err = -ERESTARTSYS; | ||
| 199 | |||
| 200 | if (flags & MSG_DONTWAIT) { | ||
| 201 | return -EAGAIN; | ||
| 202 | } | ||
| 203 | |||
| 204 | set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | ||
| 205 | |||
| 206 | for (;;) { | ||
| 207 | if (signal_pending(current)) | ||
| 208 | break; | ||
| 209 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 210 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
| 211 | if (sk_wait_event(sk, &timeout, ctx->used)) { | ||
| 212 | err = 0; | ||
| 213 | break; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | finish_wait(sk_sleep(sk), &wait); | ||
| 217 | |||
| 218 | clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); | ||
| 219 | |||
| 220 | return err; | ||
| 221 | } | ||
| 222 | |||
| 223 | static void skcipher_data_wakeup(struct sock *sk) | ||
| 224 | { | ||
| 225 | struct alg_sock *ask = alg_sk(sk); | ||
| 226 | struct skcipher_ctx *ctx = ask->private; | ||
| 227 | struct socket_wq *wq; | ||
| 228 | |||
| 229 | if (!ctx->used) | ||
| 230 | return; | ||
| 231 | |||
| 232 | rcu_read_lock(); | ||
| 233 | wq = rcu_dereference(sk->sk_wq); | ||
| 234 | if (wq_has_sleeper(wq)) | ||
| 235 | wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | | ||
| 236 | POLLRDNORM | | ||
| 237 | POLLRDBAND); | ||
| 238 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | ||
| 239 | rcu_read_unlock(); | ||
| 240 | } | ||
| 241 | |||
| 242 | static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, | ||
| 243 | struct msghdr *msg, size_t size) | ||
| 244 | { | ||
| 245 | struct sock *sk = sock->sk; | ||
| 246 | struct alg_sock *ask = alg_sk(sk); | ||
| 247 | struct skcipher_ctx *ctx = ask->private; | ||
| 248 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); | ||
| 249 | unsigned ivsize = crypto_ablkcipher_ivsize(tfm); | ||
| 250 | struct skcipher_sg_list *sgl; | ||
| 251 | struct af_alg_control con = {}; | ||
| 252 | long copied = 0; | ||
| 253 | bool enc = 0; | ||
| 254 | int err; | ||
| 255 | int i; | ||
| 256 | |||
| 257 | if (msg->msg_controllen) { | ||
| 258 | err = af_alg_cmsg_send(msg, &con); | ||
| 259 | if (err) | ||
| 260 | return err; | ||
| 261 | |||
| 262 | switch (con.op) { | ||
| 263 | case ALG_OP_ENCRYPT: | ||
| 264 | enc = 1; | ||
| 265 | break; | ||
| 266 | case ALG_OP_DECRYPT: | ||
| 267 | enc = 0; | ||
| 268 | break; | ||
| 269 | default: | ||
| 270 | return -EINVAL; | ||
| 271 | } | ||
| 272 | |||
| 273 | if (con.iv && con.iv->ivlen != ivsize) | ||
| 274 | return -EINVAL; | ||
| 275 | } | ||
| 276 | |||
| 277 | err = -EINVAL; | ||
| 278 | |||
| 279 | lock_sock(sk); | ||
| 280 | if (!ctx->more && ctx->used) | ||
| 281 | goto unlock; | ||
| 282 | |||
| 283 | if (!ctx->used) { | ||
| 284 | ctx->enc = enc; | ||
| 285 | if (con.iv) | ||
| 286 | memcpy(ctx->iv, con.iv->iv, ivsize); | ||
| 287 | } | ||
| 288 | |||
| 289 | while (size) { | ||
| 290 | struct scatterlist *sg; | ||
| 291 | unsigned long len = size; | ||
| 292 | int plen; | ||
| 293 | |||
| 294 | if (ctx->merge) { | ||
| 295 | sgl = list_entry(ctx->tsgl.prev, | ||
| 296 | struct skcipher_sg_list, list); | ||
| 297 | sg = sgl->sg + sgl->cur - 1; | ||
| 298 | len = min_t(unsigned long, len, | ||
| 299 | PAGE_SIZE - sg->offset - sg->length); | ||
| 300 | |||
| 301 | err = memcpy_fromiovec(page_address(sg_page(sg)) + | ||
| 302 | sg->offset + sg->length, | ||
| 303 | msg->msg_iov, len); | ||
| 304 | if (err) | ||
| 305 | goto unlock; | ||
| 306 | |||
| 307 | sg->length += len; | ||
| 308 | ctx->merge = (sg->offset + sg->length) & | ||
| 309 | (PAGE_SIZE - 1); | ||
| 310 | |||
| 311 | ctx->used += len; | ||
| 312 | copied += len; | ||
| 313 | size -= len; | ||
| 314 | continue; | ||
| 315 | } | ||
| 316 | |||
| 317 | if (!skcipher_writable(sk)) { | ||
| 318 | err = skcipher_wait_for_wmem(sk, msg->msg_flags); | ||
| 319 | if (err) | ||
| 320 | goto unlock; | ||
| 321 | } | ||
| 322 | |||
| 323 | len = min_t(unsigned long, len, skcipher_sndbuf(sk)); | ||
| 324 | |||
| 325 | err = skcipher_alloc_sgl(sk); | ||
| 326 | if (err) | ||
| 327 | goto unlock; | ||
| 328 | |||
| 329 | sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); | ||
| 330 | sg = sgl->sg; | ||
| 331 | do { | ||
| 332 | i = sgl->cur; | ||
| 333 | plen = min_t(int, len, PAGE_SIZE); | ||
| 334 | |||
| 335 | sg_assign_page(sg + i, alloc_page(GFP_KERNEL)); | ||
| 336 | err = -ENOMEM; | ||
| 337 | if (!sg_page(sg + i)) | ||
| 338 | goto unlock; | ||
| 339 | |||
| 340 | err = memcpy_fromiovec(page_address(sg_page(sg + i)), | ||
| 341 | msg->msg_iov, plen); | ||
| 342 | if (err) { | ||
| 343 | __free_page(sg_page(sg + i)); | ||
| 344 | sg_assign_page(sg + i, NULL); | ||
| 345 | goto unlock; | ||
| 346 | } | ||
| 347 | |||
| 348 | sg[i].length = plen; | ||
| 349 | len -= plen; | ||
| 350 | ctx->used += plen; | ||
| 351 | copied += plen; | ||
| 352 | size -= plen; | ||
| 353 | sgl->cur++; | ||
| 354 | } while (len && sgl->cur < MAX_SGL_ENTS); | ||
| 355 | |||
| 356 | ctx->merge = plen & (PAGE_SIZE - 1); | ||
| 357 | } | ||
| 358 | |||
| 359 | err = 0; | ||
| 360 | |||
| 361 | ctx->more = msg->msg_flags & MSG_MORE; | ||
| 362 | if (!ctx->more && !list_empty(&ctx->tsgl)) | ||
| 363 | sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); | ||
| 364 | |||
| 365 | unlock: | ||
| 366 | skcipher_data_wakeup(sk); | ||
| 367 | release_sock(sk); | ||
| 368 | |||
| 369 | return copied ?: err; | ||
| 370 | } | ||
| 371 | |||
| 372 | static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, | ||
| 373 | int offset, size_t size, int flags) | ||
| 374 | { | ||
| 375 | struct sock *sk = sock->sk; | ||
| 376 | struct alg_sock *ask = alg_sk(sk); | ||
| 377 | struct skcipher_ctx *ctx = ask->private; | ||
| 378 | struct skcipher_sg_list *sgl; | ||
| 379 | int err = -EINVAL; | ||
| 380 | |||
| 381 | lock_sock(sk); | ||
| 382 | if (!ctx->more && ctx->used) | ||
| 383 | goto unlock; | ||
| 384 | |||
| 385 | if (!size) | ||
| 386 | goto done; | ||
| 387 | |||
| 388 | if (!skcipher_writable(sk)) { | ||
| 389 | err = skcipher_wait_for_wmem(sk, flags); | ||
| 390 | if (err) | ||
| 391 | goto unlock; | ||
| 392 | } | ||
| 393 | |||
| 394 | err = skcipher_alloc_sgl(sk); | ||
| 395 | if (err) | ||
| 396 | goto unlock; | ||
| 397 | |||
| 398 | ctx->merge = 0; | ||
| 399 | sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); | ||
| 400 | |||
| 401 | get_page(page); | ||
| 402 | sg_set_page(sgl->sg + sgl->cur, page, size, offset); | ||
| 403 | sgl->cur++; | ||
| 404 | ctx->used += size; | ||
| 405 | |||
| 406 | done: | ||
| 407 | ctx->more = flags & MSG_MORE; | ||
| 408 | if (!ctx->more && !list_empty(&ctx->tsgl)) | ||
| 409 | sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); | ||
| 410 | |||
| 411 | unlock: | ||
| 412 | skcipher_data_wakeup(sk); | ||
| 413 | release_sock(sk); | ||
| 414 | |||
| 415 | return err ?: size; | ||
| 416 | } | ||
| 417 | |||
| 418 | static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, | ||
| 419 | struct msghdr *msg, size_t ignored, int flags) | ||
| 420 | { | ||
| 421 | struct sock *sk = sock->sk; | ||
| 422 | struct alg_sock *ask = alg_sk(sk); | ||
| 423 | struct skcipher_ctx *ctx = ask->private; | ||
| 424 | unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm( | ||
| 425 | &ctx->req)); | ||
| 426 | struct skcipher_sg_list *sgl; | ||
| 427 | struct scatterlist *sg; | ||
| 428 | unsigned long iovlen; | ||
| 429 | struct iovec *iov; | ||
| 430 | int err = -EAGAIN; | ||
| 431 | int used; | ||
| 432 | long copied = 0; | ||
| 433 | |||
| 434 | lock_sock(sk); | ||
| 435 | for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; | ||
| 436 | iovlen--, iov++) { | ||
| 437 | unsigned long seglen = iov->iov_len; | ||
| 438 | char __user *from = iov->iov_base; | ||
| 439 | |||
| 440 | while (seglen) { | ||
| 441 | sgl = list_first_entry(&ctx->tsgl, | ||
| 442 | struct skcipher_sg_list, list); | ||
| 443 | sg = sgl->sg; | ||
| 444 | |||
| 445 | while (!sg->length) | ||
| 446 | sg++; | ||
| 447 | |||
| 448 | used = ctx->used; | ||
| 449 | if (!used) { | ||
| 450 | err = skcipher_wait_for_data(sk, flags); | ||
| 451 | if (err) | ||
| 452 | goto unlock; | ||
| 453 | } | ||
| 454 | |||
| 455 | used = min_t(unsigned long, used, seglen); | ||
| 456 | |||
| 457 | used = af_alg_make_sg(&ctx->rsgl, from, used, 1); | ||
| 458 | err = used; | ||
| 459 | if (err < 0) | ||
| 460 | goto unlock; | ||
| 461 | |||
| 462 | if (ctx->more || used < ctx->used) | ||
| 463 | used -= used % bs; | ||
| 464 | |||
| 465 | err = -EINVAL; | ||
| 466 | if (!used) | ||
| 467 | goto free; | ||
| 468 | |||
| 469 | ablkcipher_request_set_crypt(&ctx->req, sg, | ||
| 470 | ctx->rsgl.sg, used, | ||
| 471 | ctx->iv); | ||
| 472 | |||
| 473 | err = af_alg_wait_for_completion( | ||
| 474 | ctx->enc ? | ||
| 475 | crypto_ablkcipher_encrypt(&ctx->req) : | ||
| 476 | crypto_ablkcipher_decrypt(&ctx->req), | ||
| 477 | &ctx->completion); | ||
| 478 | |||
| 479 | free: | ||
| 480 | af_alg_free_sg(&ctx->rsgl); | ||
| 481 | |||
| 482 | if (err) | ||
| 483 | goto unlock; | ||
| 484 | |||
| 485 | copied += used; | ||
| 486 | from += used; | ||
| 487 | seglen -= used; | ||
| 488 | skcipher_pull_sgl(sk, used); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | err = 0; | ||
| 493 | |||
| 494 | unlock: | ||
| 495 | skcipher_wmem_wakeup(sk); | ||
| 496 | release_sock(sk); | ||
| 497 | |||
| 498 | return copied ?: err; | ||
| 499 | } | ||
| 500 | |||
| 501 | |||
| 502 | static unsigned int skcipher_poll(struct file *file, struct socket *sock, | ||
| 503 | poll_table *wait) | ||
| 504 | { | ||
| 505 | struct sock *sk = sock->sk; | ||
| 506 | struct alg_sock *ask = alg_sk(sk); | ||
| 507 | struct skcipher_ctx *ctx = ask->private; | ||
| 508 | unsigned int mask; | ||
| 509 | |||
| 510 | sock_poll_wait(file, sk_sleep(sk), wait); | ||
| 511 | mask = 0; | ||
| 512 | |||
| 513 | if (ctx->used) | ||
| 514 | mask |= POLLIN | POLLRDNORM; | ||
| 515 | |||
| 516 | if (skcipher_writable(sk)) | ||
| 517 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | ||
| 518 | |||
| 519 | return mask; | ||
| 520 | } | ||
| 521 | |||
| 522 | static struct proto_ops algif_skcipher_ops = { | ||
| 523 | .family = PF_ALG, | ||
| 524 | |||
| 525 | .connect = sock_no_connect, | ||
| 526 | .socketpair = sock_no_socketpair, | ||
| 527 | .getname = sock_no_getname, | ||
| 528 | .ioctl = sock_no_ioctl, | ||
| 529 | .listen = sock_no_listen, | ||
| 530 | .shutdown = sock_no_shutdown, | ||
| 531 | .getsockopt = sock_no_getsockopt, | ||
| 532 | .mmap = sock_no_mmap, | ||
| 533 | .bind = sock_no_bind, | ||
| 534 | .accept = sock_no_accept, | ||
| 535 | .setsockopt = sock_no_setsockopt, | ||
| 536 | |||
| 537 | .release = af_alg_release, | ||
| 538 | .sendmsg = skcipher_sendmsg, | ||
| 539 | .sendpage = skcipher_sendpage, | ||
| 540 | .recvmsg = skcipher_recvmsg, | ||
| 541 | .poll = skcipher_poll, | ||
| 542 | }; | ||
| 543 | |||
| 544 | static void *skcipher_bind(const char *name, u32 type, u32 mask) | ||
| 545 | { | ||
| 546 | return crypto_alloc_ablkcipher(name, type, mask); | ||
| 547 | } | ||
| 548 | |||
| 549 | static void skcipher_release(void *private) | ||
| 550 | { | ||
| 551 | crypto_free_ablkcipher(private); | ||
| 552 | } | ||
| 553 | |||
| 554 | static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) | ||
| 555 | { | ||
| 556 | return crypto_ablkcipher_setkey(private, key, keylen); | ||
| 557 | } | ||
| 558 | |||
| 559 | static void skcipher_sock_destruct(struct sock *sk) | ||
| 560 | { | ||
| 561 | struct alg_sock *ask = alg_sk(sk); | ||
| 562 | struct skcipher_ctx *ctx = ask->private; | ||
| 563 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); | ||
| 564 | |||
| 565 | skcipher_free_sgl(sk); | ||
| 566 | sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm)); | ||
| 567 | sock_kfree_s(sk, ctx, ctx->len); | ||
| 568 | af_alg_release_parent(sk); | ||
| 569 | } | ||
| 570 | |||
| 571 | static int skcipher_accept_parent(void *private, struct sock *sk) | ||
| 572 | { | ||
| 573 | struct skcipher_ctx *ctx; | ||
| 574 | struct alg_sock *ask = alg_sk(sk); | ||
| 575 | unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private); | ||
| 576 | |||
| 577 | ctx = sock_kmalloc(sk, len, GFP_KERNEL); | ||
| 578 | if (!ctx) | ||
| 579 | return -ENOMEM; | ||
| 580 | |||
| 581 | ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private), | ||
| 582 | GFP_KERNEL); | ||
| 583 | if (!ctx->iv) { | ||
| 584 | sock_kfree_s(sk, ctx, len); | ||
| 585 | return -ENOMEM; | ||
| 586 | } | ||
| 587 | |||
| 588 | memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private)); | ||
| 589 | |||
| 590 | INIT_LIST_HEAD(&ctx->tsgl); | ||
| 591 | ctx->len = len; | ||
| 592 | ctx->used = 0; | ||
| 593 | ctx->more = 0; | ||
| 594 | ctx->merge = 0; | ||
| 595 | ctx->enc = 0; | ||
| 596 | af_alg_init_completion(&ctx->completion); | ||
| 597 | |||
| 598 | ask->private = ctx; | ||
| 599 | |||
| 600 | ablkcipher_request_set_tfm(&ctx->req, private); | ||
| 601 | ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
| 602 | af_alg_complete, &ctx->completion); | ||
| 603 | |||
| 604 | sk->sk_destruct = skcipher_sock_destruct; | ||
| 605 | |||
| 606 | return 0; | ||
| 607 | } | ||
| 608 | |||
| 609 | static const struct af_alg_type algif_type_skcipher = { | ||
| 610 | .bind = skcipher_bind, | ||
| 611 | .release = skcipher_release, | ||
| 612 | .setkey = skcipher_setkey, | ||
| 613 | .accept = skcipher_accept_parent, | ||
| 614 | .ops = &algif_skcipher_ops, | ||
| 615 | .name = "skcipher", | ||
| 616 | .owner = THIS_MODULE | ||
| 617 | }; | ||
| 618 | |||
| 619 | static int __init algif_skcipher_init(void) | ||
| 620 | { | ||
| 621 | return af_alg_register_type(&algif_type_skcipher); | ||
| 622 | } | ||
| 623 | |||
| 624 | static void __exit algif_skcipher_exit(void) | ||
| 625 | { | ||
| 626 | int err = af_alg_unregister_type(&algif_type_skcipher); | ||
| 627 | BUG_ON(err); | ||
| 628 | } | ||
| 629 | |||
| 630 | module_init(algif_skcipher_init); | ||
| 631 | module_exit(algif_skcipher_exit); | ||
| 632 | MODULE_LICENSE("GPL"); | ||
diff --git a/crypto/authenc.c b/crypto/authenc.c index a5a22cfcd07b..5ef7ba6b6a76 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c | |||
| @@ -107,20 +107,6 @@ badkey: | |||
| 107 | goto out; | 107 | goto out; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static void authenc_chain(struct scatterlist *head, struct scatterlist *sg, | ||
| 111 | int chain) | ||
| 112 | { | ||
| 113 | if (chain) { | ||
| 114 | head->length += sg->length; | ||
| 115 | sg = scatterwalk_sg_next(sg); | ||
| 116 | } | ||
| 117 | |||
| 118 | if (sg) | ||
| 119 | scatterwalk_sg_chain(head, 2, sg); | ||
| 120 | else | ||
| 121 | sg_mark_end(head); | ||
| 122 | } | ||
| 123 | |||
| 124 | static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq, | 110 | static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq, |
| 125 | int err) | 111 | int err) |
| 126 | { | 112 | { |
| @@ -345,7 +331,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, | |||
| 345 | if (ivsize) { | 331 | if (ivsize) { |
| 346 | sg_init_table(cipher, 2); | 332 | sg_init_table(cipher, 2); |
| 347 | sg_set_buf(cipher, iv, ivsize); | 333 | sg_set_buf(cipher, iv, ivsize); |
| 348 | authenc_chain(cipher, dst, vdst == iv + ivsize); | 334 | scatterwalk_crypto_chain(cipher, dst, vdst == iv + ivsize, 2); |
| 349 | dst = cipher; | 335 | dst = cipher; |
| 350 | cryptlen += ivsize; | 336 | cryptlen += ivsize; |
| 351 | } | 337 | } |
| @@ -354,7 +340,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, | |||
| 354 | authenc_ahash_fn = crypto_authenc_ahash; | 340 | authenc_ahash_fn = crypto_authenc_ahash; |
| 355 | sg_init_table(asg, 2); | 341 | sg_init_table(asg, 2); |
| 356 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); | 342 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); |
| 357 | authenc_chain(asg, dst, 0); | 343 | scatterwalk_crypto_chain(asg, dst, 0, 2); |
| 358 | dst = asg; | 344 | dst = asg; |
| 359 | cryptlen += req->assoclen; | 345 | cryptlen += req->assoclen; |
| 360 | } | 346 | } |
| @@ -499,7 +485,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, | |||
| 499 | if (ivsize) { | 485 | if (ivsize) { |
| 500 | sg_init_table(cipher, 2); | 486 | sg_init_table(cipher, 2); |
| 501 | sg_set_buf(cipher, iv, ivsize); | 487 | sg_set_buf(cipher, iv, ivsize); |
| 502 | authenc_chain(cipher, src, vsrc == iv + ivsize); | 488 | scatterwalk_crypto_chain(cipher, src, vsrc == iv + ivsize, 2); |
| 503 | src = cipher; | 489 | src = cipher; |
| 504 | cryptlen += ivsize; | 490 | cryptlen += ivsize; |
| 505 | } | 491 | } |
| @@ -508,7 +494,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, | |||
| 508 | authenc_ahash_fn = crypto_authenc_ahash; | 494 | authenc_ahash_fn = crypto_authenc_ahash; |
| 509 | sg_init_table(asg, 2); | 495 | sg_init_table(asg, 2); |
| 510 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); | 496 | sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); |
| 511 | authenc_chain(asg, src, 0); | 497 | scatterwalk_crypto_chain(asg, src, 0, 2); |
| 512 | src = asg; | 498 | src = asg; |
| 513 | cryptlen += req->assoclen; | 499 | cryptlen += req->assoclen; |
| 514 | } | 500 | } |
diff --git a/crypto/cast5.c b/crypto/cast5.c index a1d2294b50ad..4a230ddec877 100644 --- a/crypto/cast5.c +++ b/crypto/cast5.c | |||
| @@ -604,36 +604,23 @@ static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) | |||
| 604 | * Rounds 3, 6, 9, 12, and 15 use f function Type 3. | 604 | * Rounds 3, 6, 9, 12, and 15 use f function Type 3. |
| 605 | */ | 605 | */ |
| 606 | 606 | ||
| 607 | t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); | ||
| 608 | t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); | ||
| 609 | t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); | ||
| 610 | t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); | ||
| 611 | t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); | ||
| 612 | t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); | ||
| 613 | t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); | ||
| 614 | t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); | ||
| 615 | t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); | ||
| 616 | t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); | ||
| 617 | t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); | ||
| 618 | t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); | ||
| 607 | if (!(c->rr)) { | 619 | if (!(c->rr)) { |
| 608 | t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); | ||
| 609 | t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); | ||
| 610 | t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); | ||
| 611 | t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); | ||
| 612 | t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); | ||
| 613 | t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); | ||
| 614 | t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); | ||
| 615 | t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); | ||
| 616 | t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); | ||
| 617 | t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); | ||
| 618 | t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); | ||
| 619 | t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); | ||
| 620 | t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); | 620 | t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); |
| 621 | t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); | 621 | t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); |
| 622 | t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); | 622 | t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); |
| 623 | t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); | 623 | t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); |
| 624 | } else { | ||
| 625 | t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); | ||
| 626 | t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); | ||
| 627 | t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); | ||
| 628 | t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); | ||
| 629 | t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); | ||
| 630 | t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); | ||
| 631 | t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); | ||
| 632 | t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); | ||
| 633 | t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); | ||
| 634 | t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); | ||
| 635 | t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); | ||
| 636 | t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); | ||
| 637 | } | 624 | } |
| 638 | 625 | ||
| 639 | /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and | 626 | /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and |
| @@ -663,32 +650,19 @@ static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) | |||
| 663 | t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); | 650 | t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); |
| 664 | t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); | 651 | t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); |
| 665 | t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); | 652 | t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); |
| 666 | t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); | ||
| 667 | t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); | ||
| 668 | t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); | ||
| 669 | t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); | ||
| 670 | t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); | ||
| 671 | t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); | ||
| 672 | t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); | ||
| 673 | t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); | ||
| 674 | t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); | ||
| 675 | t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); | ||
| 676 | t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); | ||
| 677 | t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); | ||
| 678 | } else { | ||
| 679 | t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); | ||
| 680 | t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); | ||
| 681 | t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); | ||
| 682 | t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); | ||
| 683 | t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); | ||
| 684 | t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); | ||
| 685 | t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); | ||
| 686 | t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); | ||
| 687 | t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); | ||
| 688 | t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); | ||
| 689 | t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); | ||
| 690 | t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); | ||
| 691 | } | 653 | } |
| 654 | t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); | ||
| 655 | t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); | ||
| 656 | t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); | ||
| 657 | t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); | ||
| 658 | t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); | ||
| 659 | t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); | ||
| 660 | t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); | ||
| 661 | t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); | ||
| 662 | t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); | ||
| 663 | t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); | ||
| 664 | t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); | ||
| 665 | t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); | ||
| 692 | 666 | ||
| 693 | dst[0] = cpu_to_be32(r); | 667 | dst[0] = cpu_to_be32(r); |
| 694 | dst[1] = cpu_to_be32(l); | 668 | dst[1] = cpu_to_be32(l); |
diff --git a/crypto/crypto_wq.c b/crypto/crypto_wq.c index fdcf6248f152..b980ee1af459 100644 --- a/crypto/crypto_wq.c +++ b/crypto/crypto_wq.c | |||
| @@ -20,7 +20,8 @@ EXPORT_SYMBOL_GPL(kcrypto_wq); | |||
| 20 | 20 | ||
| 21 | static int __init crypto_wq_init(void) | 21 | static int __init crypto_wq_init(void) |
| 22 | { | 22 | { |
| 23 | kcrypto_wq = create_workqueue("crypto"); | 23 | kcrypto_wq = alloc_workqueue("crypto", |
| 24 | WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1); | ||
| 24 | if (unlikely(!kcrypto_wq)) | 25 | if (unlikely(!kcrypto_wq)) |
| 25 | return -ENOMEM; | 26 | return -ENOMEM; |
| 26 | return 0; | 27 | return 0; |
diff --git a/crypto/deflate.c b/crypto/deflate.c index 463dc859aa05..cbc7a33a9600 100644 --- a/crypto/deflate.c +++ b/crypto/deflate.c | |||
| @@ -48,12 +48,11 @@ static int deflate_comp_init(struct deflate_ctx *ctx) | |||
| 48 | int ret = 0; | 48 | int ret = 0; |
| 49 | struct z_stream_s *stream = &ctx->comp_stream; | 49 | struct z_stream_s *stream = &ctx->comp_stream; |
| 50 | 50 | ||
| 51 | stream->workspace = vmalloc(zlib_deflate_workspacesize()); | 51 | stream->workspace = vzalloc(zlib_deflate_workspacesize()); |
| 52 | if (!stream->workspace) { | 52 | if (!stream->workspace) { |
| 53 | ret = -ENOMEM; | 53 | ret = -ENOMEM; |
| 54 | goto out; | 54 | goto out; |
| 55 | } | 55 | } |
| 56 | memset(stream->workspace, 0, zlib_deflate_workspacesize()); | ||
| 57 | ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, | 56 | ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, |
| 58 | -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, | 57 | -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, |
| 59 | Z_DEFAULT_STRATEGY); | 58 | Z_DEFAULT_STRATEGY); |
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c index 3ca3b669d5d5..42ce9f570aec 100644 --- a/crypto/eseqiv.c +++ b/crypto/eseqiv.c | |||
| @@ -62,20 +62,6 @@ out: | |||
| 62 | skcipher_givcrypt_complete(req, err); | 62 | skcipher_givcrypt_complete(req, err); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static void eseqiv_chain(struct scatterlist *head, struct scatterlist *sg, | ||
| 66 | int chain) | ||
| 67 | { | ||
| 68 | if (chain) { | ||
| 69 | head->length += sg->length; | ||
| 70 | sg = scatterwalk_sg_next(sg); | ||
| 71 | } | ||
| 72 | |||
| 73 | if (sg) | ||
| 74 | scatterwalk_sg_chain(head, 2, sg); | ||
| 75 | else | ||
| 76 | sg_mark_end(head); | ||
| 77 | } | ||
| 78 | |||
| 79 | static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) | 65 | static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) |
| 80 | { | 66 | { |
| 81 | struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); | 67 | struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); |
| @@ -124,13 +110,13 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) | |||
| 124 | 110 | ||
| 125 | sg_init_table(reqctx->src, 2); | 111 | sg_init_table(reqctx->src, 2); |
| 126 | sg_set_buf(reqctx->src, giv, ivsize); | 112 | sg_set_buf(reqctx->src, giv, ivsize); |
| 127 | eseqiv_chain(reqctx->src, osrc, vsrc == giv + ivsize); | 113 | scatterwalk_crypto_chain(reqctx->src, osrc, vsrc == giv + ivsize, 2); |
| 128 | 114 | ||
| 129 | dst = reqctx->src; | 115 | dst = reqctx->src; |
| 130 | if (osrc != odst) { | 116 | if (osrc != odst) { |
| 131 | sg_init_table(reqctx->dst, 2); | 117 | sg_init_table(reqctx->dst, 2); |
| 132 | sg_set_buf(reqctx->dst, giv, ivsize); | 118 | sg_set_buf(reqctx->dst, giv, ivsize); |
| 133 | eseqiv_chain(reqctx->dst, odst, vdst == giv + ivsize); | 119 | scatterwalk_crypto_chain(reqctx->dst, odst, vdst == giv + ivsize, 2); |
| 134 | 120 | ||
| 135 | dst = reqctx->dst; | 121 | dst = reqctx->dst; |
| 136 | } | 122 | } |
diff --git a/crypto/gcm.c b/crypto/gcm.c index 2f5fbba6576c..1a252639ef91 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c | |||
| @@ -1102,21 +1102,6 @@ static int crypto_rfc4543_setauthsize(struct crypto_aead *parent, | |||
| 1102 | return crypto_aead_setauthsize(ctx->child, authsize); | 1102 | return crypto_aead_setauthsize(ctx->child, authsize); |
| 1103 | } | 1103 | } |
| 1104 | 1104 | ||
| 1105 | /* this is the same as crypto_authenc_chain */ | ||
| 1106 | static void crypto_rfc4543_chain(struct scatterlist *head, | ||
| 1107 | struct scatterlist *sg, int chain) | ||
| 1108 | { | ||
| 1109 | if (chain) { | ||
| 1110 | head->length += sg->length; | ||
| 1111 | sg = scatterwalk_sg_next(sg); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | if (sg) | ||
| 1115 | scatterwalk_sg_chain(head, 2, sg); | ||
| 1116 | else | ||
| 1117 | sg_mark_end(head); | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, | 1105 | static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, |
| 1121 | int enc) | 1106 | int enc) |
| 1122 | { | 1107 | { |
| @@ -1154,13 +1139,13 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, | |||
| 1154 | 1139 | ||
| 1155 | sg_init_table(payload, 2); | 1140 | sg_init_table(payload, 2); |
| 1156 | sg_set_buf(payload, req->iv, 8); | 1141 | sg_set_buf(payload, req->iv, 8); |
| 1157 | crypto_rfc4543_chain(payload, dst, vdst == req->iv + 8); | 1142 | scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2); |
| 1158 | assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); | 1143 | assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); |
| 1159 | 1144 | ||
| 1160 | sg_init_table(assoc, 2); | 1145 | sg_init_table(assoc, 2); |
| 1161 | sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, | 1146 | sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, |
| 1162 | req->assoc->offset); | 1147 | req->assoc->offset); |
| 1163 | crypto_rfc4543_chain(assoc, payload, 0); | 1148 | scatterwalk_crypto_chain(assoc, payload, 0, 2); |
| 1164 | 1149 | ||
| 1165 | aead_request_set_tfm(subreq, ctx->child); | 1150 | aead_request_set_tfm(subreq, ctx->child); |
| 1166 | aead_request_set_callback(subreq, req->base.flags, req->base.complete, | 1151 | aead_request_set_callback(subreq, req->base.flags, req->base.complete, |
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c index 75586f1f86e7..29a89dad68b6 100644 --- a/crypto/pcrypt.c +++ b/crypto/pcrypt.c | |||
| @@ -455,7 +455,8 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt, | |||
| 455 | 455 | ||
| 456 | get_online_cpus(); | 456 | get_online_cpus(); |
| 457 | 457 | ||
| 458 | pcrypt->wq = create_workqueue(name); | 458 | pcrypt->wq = alloc_workqueue(name, |
| 459 | WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1); | ||
| 459 | if (!pcrypt->wq) | 460 | if (!pcrypt->wq) |
| 460 | goto err; | 461 | goto err; |
| 461 | 462 | ||
diff --git a/crypto/rmd128.c b/crypto/rmd128.c index 1ceb6735aa53..8a0f68b7f257 100644 --- a/crypto/rmd128.c +++ b/crypto/rmd128.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC | 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> | 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> |
| 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 |
| 11 | * under the terms of the GNU General Public License as published by the Free | 11 | * under the terms of the GNU General Public License as published by the Free |
| @@ -325,4 +325,5 @@ module_init(rmd128_mod_init); | |||
| 325 | module_exit(rmd128_mod_fini); | 325 | module_exit(rmd128_mod_fini); |
| 326 | 326 | ||
| 327 | MODULE_LICENSE("GPL"); | 327 | MODULE_LICENSE("GPL"); |
| 328 | MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); | ||
| 328 | MODULE_DESCRIPTION("RIPEMD-128 Message Digest"); | 329 | MODULE_DESCRIPTION("RIPEMD-128 Message Digest"); |
diff --git a/crypto/rmd160.c b/crypto/rmd160.c index 472261fc913f..525d7bb752cf 100644 --- a/crypto/rmd160.c +++ b/crypto/rmd160.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC | 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> | 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> |
| 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 |
| 11 | * under the terms of the GNU General Public License as published by the Free | 11 | * under the terms of the GNU General Public License as published by the Free |
| @@ -369,4 +369,5 @@ module_init(rmd160_mod_init); | |||
| 369 | module_exit(rmd160_mod_fini); | 369 | module_exit(rmd160_mod_fini); |
| 370 | 370 | ||
| 371 | MODULE_LICENSE("GPL"); | 371 | MODULE_LICENSE("GPL"); |
| 372 | MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); | ||
| 372 | MODULE_DESCRIPTION("RIPEMD-160 Message Digest"); | 373 | MODULE_DESCRIPTION("RIPEMD-160 Message Digest"); |
diff --git a/crypto/rmd256.c b/crypto/rmd256.c index 72eafa8d2e7b..69293d9b56e0 100644 --- a/crypto/rmd256.c +++ b/crypto/rmd256.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC | 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> | 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> |
| 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 |
| 11 | * under the terms of the GNU General Public License as published by the Free | 11 | * under the terms of the GNU General Public License as published by the Free |
| @@ -344,4 +344,5 @@ module_init(rmd256_mod_init); | |||
| 344 | module_exit(rmd256_mod_fini); | 344 | module_exit(rmd256_mod_fini); |
| 345 | 345 | ||
| 346 | MODULE_LICENSE("GPL"); | 346 | MODULE_LICENSE("GPL"); |
| 347 | MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); | ||
| 347 | MODULE_DESCRIPTION("RIPEMD-256 Message Digest"); | 348 | MODULE_DESCRIPTION("RIPEMD-256 Message Digest"); |
diff --git a/crypto/rmd320.c b/crypto/rmd320.c index 86becaba2f05..09f97dfdfbba 100644 --- a/crypto/rmd320.c +++ b/crypto/rmd320.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC | 6 | * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> | 8 | * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> |
| 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 |
| 11 | * under the terms of the GNU General Public License as published by the Free | 11 | * under the terms of the GNU General Public License as published by the Free |
| @@ -393,4 +393,5 @@ module_init(rmd320_mod_init); | |||
| 393 | module_exit(rmd320_mod_fini); | 393 | module_exit(rmd320_mod_fini); |
| 394 | 394 | ||
| 395 | MODULE_LICENSE("GPL"); | 395 | MODULE_LICENSE("GPL"); |
| 396 | MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); | ||
| 396 | MODULE_DESCRIPTION("RIPEMD-320 Message Digest"); | 397 | MODULE_DESCRIPTION("RIPEMD-320 Message Digest"); |
diff --git a/crypto/shash.c b/crypto/shash.c index 22fd9433141f..76f74b963151 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
| @@ -310,7 +310,13 @@ static int shash_async_export(struct ahash_request *req, void *out) | |||
| 310 | 310 | ||
| 311 | static int shash_async_import(struct ahash_request *req, const void *in) | 311 | static int shash_async_import(struct ahash_request *req, const void *in) |
| 312 | { | 312 | { |
| 313 | return crypto_shash_import(ahash_request_ctx(req), in); | 313 | struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); |
| 314 | struct shash_desc *desc = ahash_request_ctx(req); | ||
| 315 | |||
| 316 | desc->tfm = *ctx; | ||
| 317 | desc->flags = req->base.flags; | ||
| 318 | |||
| 319 | return crypto_shash_import(desc, in); | ||
| 314 | } | 320 | } |
| 315 | 321 | ||
| 316 | static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) | 322 | static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) |
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 3ca68f9fc14d..9aac5e58be94 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c | |||
| @@ -8,6 +8,13 @@ | |||
| 8 | * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> | 8 | * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> |
| 9 | * Copyright (c) 2007 Nokia Siemens Networks | 9 | * Copyright (c) 2007 Nokia Siemens Networks |
| 10 | * | 10 | * |
| 11 | * Updated RFC4106 AES-GCM testing. | ||
| 12 | * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) | ||
| 13 | * Adrian Hoban <adrian.hoban@intel.com> | ||
| 14 | * Gabriele Paoloni <gabriele.paoloni@intel.com> | ||
| 15 | * Tadeusz Struk (tadeusz.struk@intel.com) | ||
| 16 | * Copyright (c) 2010, Intel Corporation. | ||
| 17 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify it | 18 | * 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 | 19 | * 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) | 20 | * Software Foundation; either version 2 of the License, or (at your option) |
| @@ -980,6 +987,10 @@ static int do_test(int m) | |||
| 980 | ret += tcrypt_test("ansi_cprng"); | 987 | ret += tcrypt_test("ansi_cprng"); |
| 981 | break; | 988 | break; |
| 982 | 989 | ||
| 990 | case 151: | ||
| 991 | ret += tcrypt_test("rfc4106(gcm(aes))"); | ||
| 992 | break; | ||
| 993 | |||
| 983 | case 200: | 994 | case 200: |
| 984 | test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, | 995 | test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, |
| 985 | speed_template_16_24_32); | 996 | speed_template_16_24_32); |
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index fa8c8f78c8d4..27ea9fe9476f 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
| @@ -6,6 +6,13 @@ | |||
| 6 | * Copyright (c) 2007 Nokia Siemens Networks | 6 | * Copyright (c) 2007 Nokia Siemens Networks |
| 7 | * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> | 7 | * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> |
| 8 | * | 8 | * |
| 9 | * Updated RFC4106 AES-GCM testing. | ||
| 10 | * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) | ||
| 11 | * Adrian Hoban <adrian.hoban@intel.com> | ||
| 12 | * Gabriele Paoloni <gabriele.paoloni@intel.com> | ||
| 13 | * Tadeusz Struk (tadeusz.struk@intel.com) | ||
| 14 | * Copyright (c) 2010, Intel Corporation. | ||
| 15 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | 16 | * This program is free software; you can redistribute it and/or modify it |
| 10 | * under the terms of the GNU General Public License as published by the Free | 17 | * under the terms of the GNU General Public License as published by the Free |
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | 18 | * Software Foundation; either version 2 of the License, or (at your option) |
| @@ -2242,6 +2249,23 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
| 2242 | } | 2249 | } |
| 2243 | } | 2250 | } |
| 2244 | }, { | 2251 | }, { |
| 2252 | .alg = "rfc4106(gcm(aes))", | ||
| 2253 | .test = alg_test_aead, | ||
| 2254 | .suite = { | ||
| 2255 | .aead = { | ||
| 2256 | .enc = { | ||
| 2257 | .vecs = aes_gcm_rfc4106_enc_tv_template, | ||
| 2258 | .count = AES_GCM_4106_ENC_TEST_VECTORS | ||
| 2259 | }, | ||
| 2260 | .dec = { | ||
| 2261 | .vecs = aes_gcm_rfc4106_dec_tv_template, | ||
| 2262 | .count = AES_GCM_4106_DEC_TEST_VECTORS | ||
| 2263 | } | ||
| 2264 | } | ||
| 2265 | } | ||
| 2266 | }, { | ||
| 2267 | |||
| 2268 | |||
| 2245 | .alg = "rfc4309(ccm(aes))", | 2269 | .alg = "rfc4309(ccm(aes))", |
| 2246 | .test = alg_test_aead, | 2270 | .test = alg_test_aead, |
| 2247 | .fips_allowed = 1, | 2271 | .fips_allowed = 1, |
diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 74e35377fd30..834af7f2adee 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h | |||
| @@ -6,6 +6,15 @@ | |||
| 6 | * Copyright (c) 2007 Nokia Siemens Networks | 6 | * Copyright (c) 2007 Nokia Siemens Networks |
| 7 | * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> | 7 | * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> |
| 8 | * | 8 | * |
| 9 | * Updated RFC4106 AES-GCM testing. Some test vectors were taken from | ||
| 10 | * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ | ||
| 11 | * gcm/gcm-test-vectors.tar.gz | ||
| 12 | * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) | ||
| 13 | * Adrian Hoban <adrian.hoban@intel.com> | ||
| 14 | * Gabriele Paoloni <gabriele.paoloni@intel.com> | ||
| 15 | * Tadeusz Struk (tadeusz.struk@intel.com) | ||
| 16 | * Copyright (c) 2010, Intel Corporation. | ||
| 17 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | 18 | * This program is free software; you can redistribute it and/or modify it |
| 10 | * under the terms of the GNU General Public License as published by the Free | 19 | * under the terms of the GNU General Public License as published by the Free |
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | 20 | * Software Foundation; either version 2 of the License, or (at your option) |
| @@ -2947,6 +2956,8 @@ static struct cipher_testvec cast6_dec_tv_template[] = { | |||
| 2947 | #define AES_CTR_3686_DEC_TEST_VECTORS 6 | 2956 | #define AES_CTR_3686_DEC_TEST_VECTORS 6 |
| 2948 | #define AES_GCM_ENC_TEST_VECTORS 9 | 2957 | #define AES_GCM_ENC_TEST_VECTORS 9 |
| 2949 | #define AES_GCM_DEC_TEST_VECTORS 8 | 2958 | #define AES_GCM_DEC_TEST_VECTORS 8 |
| 2959 | #define AES_GCM_4106_ENC_TEST_VECTORS 7 | ||
| 2960 | #define AES_GCM_4106_DEC_TEST_VECTORS 7 | ||
| 2950 | #define AES_CCM_ENC_TEST_VECTORS 7 | 2961 | #define AES_CCM_ENC_TEST_VECTORS 7 |
| 2951 | #define AES_CCM_DEC_TEST_VECTORS 7 | 2962 | #define AES_CCM_DEC_TEST_VECTORS 7 |
| 2952 | #define AES_CCM_4309_ENC_TEST_VECTORS 7 | 2963 | #define AES_CCM_4309_ENC_TEST_VECTORS 7 |
| @@ -5829,6 +5840,356 @@ static struct aead_testvec aes_gcm_dec_tv_template[] = { | |||
| 5829 | } | 5840 | } |
| 5830 | }; | 5841 | }; |
| 5831 | 5842 | ||
| 5843 | static struct aead_testvec aes_gcm_rfc4106_enc_tv_template[] = { | ||
| 5844 | { /* Generated using Crypto++ */ | ||
| 5845 | .key = zeroed_string, | ||
| 5846 | .klen = 20, | ||
| 5847 | .iv = zeroed_string, | ||
| 5848 | .input = zeroed_string, | ||
| 5849 | .ilen = 16, | ||
| 5850 | .assoc = zeroed_string, | ||
| 5851 | .alen = 8, | ||
| 5852 | .result = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92" | ||
| 5853 | "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78" | ||
| 5854 | "\x97\xFE\x4C\x23\x37\x42\x01\xE0" | ||
| 5855 | "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B", | ||
| 5856 | .rlen = 32, | ||
| 5857 | },{ | ||
| 5858 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 5859 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 5860 | "\x00\x00\x00\x00", | ||
| 5861 | .klen = 20, | ||
| 5862 | .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" | ||
| 5863 | "\x00\x00\x00\x00", | ||
| 5864 | .input = zeroed_string, | ||
| 5865 | .ilen = 16, | ||
| 5866 | .assoc = zeroed_string, | ||
| 5867 | .alen = 8, | ||
| 5868 | .result = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18" | ||
| 5869 | "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28" | ||
| 5870 | "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D" | ||
| 5871 | "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF", | ||
| 5872 | .rlen = 32, | ||
| 5873 | |||
| 5874 | }, { | ||
| 5875 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 5876 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 5877 | "\x00\x00\x00\x00", | ||
| 5878 | .klen = 20, | ||
| 5879 | .iv = zeroed_string, | ||
| 5880 | .input = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5881 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 5882 | .ilen = 16, | ||
| 5883 | .assoc = zeroed_string, | ||
| 5884 | .alen = 8, | ||
| 5885 | .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" | ||
| 5886 | "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" | ||
| 5887 | "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C" | ||
| 5888 | "\xB1\x68\xFD\x14\x52\x64\x61\xB2", | ||
| 5889 | .rlen = 32, | ||
| 5890 | }, { | ||
| 5891 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 5892 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 5893 | "\x00\x00\x00\x00", | ||
| 5894 | .klen = 20, | ||
| 5895 | .iv = zeroed_string, | ||
| 5896 | .input = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5897 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 5898 | .ilen = 16, | ||
| 5899 | .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 5900 | .alen = 8, | ||
| 5901 | .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" | ||
| 5902 | "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" | ||
| 5903 | "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63" | ||
| 5904 | "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5", | ||
| 5905 | .rlen = 32, | ||
| 5906 | }, { | ||
| 5907 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 5908 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 5909 | "\x00\x00\x00\x00", | ||
| 5910 | .klen = 20, | ||
| 5911 | .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" | ||
| 5912 | "\x00\x00\x00\x00", | ||
| 5913 | .input = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5914 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 5915 | .ilen = 16, | ||
| 5916 | .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 5917 | .alen = 8, | ||
| 5918 | .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" | ||
| 5919 | "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" | ||
| 5920 | "\x64\x50\xF9\x32\x13\xFB\x74\x61" | ||
| 5921 | "\xF4\xED\x52\xD3\xC5\x10\x55\x3C", | ||
| 5922 | .rlen = 32, | ||
| 5923 | }, { | ||
| 5924 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 5925 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 5926 | "\x00\x00\x00\x00", | ||
| 5927 | .klen = 20, | ||
| 5928 | .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" | ||
| 5929 | "\x00\x00\x00\x00", | ||
| 5930 | .input = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5931 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5932 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5933 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5934 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5935 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5936 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 5937 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 5938 | .ilen = 64, | ||
| 5939 | .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 5940 | .alen = 8, | ||
| 5941 | .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" | ||
| 5942 | "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" | ||
| 5943 | "\x98\x14\xA1\x42\x37\x80\xFD\x90" | ||
| 5944 | "\x68\x12\x01\xA8\x91\x89\xB9\x83" | ||
| 5945 | "\x5B\x11\x77\x12\x9B\xFF\x24\x89" | ||
| 5946 | "\x94\x5F\x18\x12\xBA\x27\x09\x39" | ||
| 5947 | "\x99\x96\x76\x42\x15\x1C\xCD\xCB" | ||
| 5948 | "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD" | ||
| 5949 | "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85" | ||
| 5950 | "\xBD\xCF\x62\x98\x58\x14\xE5\xBD", | ||
| 5951 | .rlen = 80, | ||
| 5952 | }, { | ||
| 5953 | .key = "\x00\x01\x02\x03\x04\x05\x06\x07" | ||
| 5954 | "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" | ||
| 5955 | "\x00\x00\x00\x00", | ||
| 5956 | .klen = 20, | ||
| 5957 | .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef" | ||
| 5958 | "\x00\x00\x00\x00", | ||
| 5959 | .input = "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5960 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5961 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5962 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5963 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5964 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5965 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5966 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5967 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5968 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5969 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5970 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5971 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5972 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5973 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5974 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5975 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5976 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5977 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5978 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5979 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5980 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5981 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 5982 | "\xff\xff\xff\xff\xff\xff\xff\xff", | ||
| 5983 | .ilen = 192, | ||
| 5984 | .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | ||
| 5985 | "\xaa\xaa\xaa\xaa", | ||
| 5986 | .alen = 12, | ||
| 5987 | .result = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE" | ||
| 5988 | "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A" | ||
| 5989 | "\x44\x6D\xC3\x88\x46\x2E\xC2\x01" | ||
| 5990 | "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82" | ||
| 5991 | "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44" | ||
| 5992 | "\x41\xA9\x82\x6F\x22\xA1\x23\x1A" | ||
| 5993 | "\xA8\xE3\x16\xFD\x31\x5C\x27\x31" | ||
| 5994 | "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1" | ||
| 5995 | "\xCF\x07\x57\x41\x67\xD0\xC4\x42" | ||
| 5996 | "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F" | ||
| 5997 | "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B" | ||
| 5998 | "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE" | ||
| 5999 | "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C" | ||
| 6000 | "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF" | ||
| 6001 | "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59" | ||
| 6002 | "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA" | ||
| 6003 | "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25" | ||
| 6004 | "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B" | ||
| 6005 | "\x7E\x13\x06\x82\x08\x17\xA4\x35" | ||
| 6006 | "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F" | ||
| 6007 | "\xA3\x05\x38\x95\x20\x1A\x47\x04" | ||
| 6008 | "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35" | ||
| 6009 | "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E" | ||
| 6010 | "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B" | ||
| 6011 | "\x37\x08\x1C\xCF\xBA\x5D\x71\x46" | ||
| 6012 | "\x80\x72\xB0\x4C\x82\x0D\x60\x3C", | ||
| 6013 | .rlen = 208, | ||
| 6014 | } | ||
| 6015 | }; | ||
| 6016 | |||
| 6017 | static struct aead_testvec aes_gcm_rfc4106_dec_tv_template[] = { | ||
| 6018 | { /* Generated using Crypto++ */ | ||
| 6019 | .key = zeroed_string, | ||
| 6020 | .klen = 20, | ||
| 6021 | .iv = zeroed_string, | ||
| 6022 | .input = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92" | ||
| 6023 | "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78" | ||
| 6024 | "\x97\xFE\x4C\x23\x37\x42\x01\xE0" | ||
| 6025 | "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B", | ||
| 6026 | .ilen = 32, | ||
| 6027 | .assoc = zeroed_string, | ||
| 6028 | .alen = 8, | ||
| 6029 | .result = zeroed_string, | ||
| 6030 | .rlen = 16, | ||
| 6031 | |||
| 6032 | },{ | ||
| 6033 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 6034 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 6035 | "\x00\x00\x00\x00", | ||
| 6036 | .klen = 20, | ||
| 6037 | .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" | ||
| 6038 | "\x00\x00\x00\x00", | ||
| 6039 | .input = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18" | ||
| 6040 | "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28" | ||
| 6041 | "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D" | ||
| 6042 | "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF", | ||
| 6043 | .ilen = 32, | ||
| 6044 | .assoc = zeroed_string, | ||
| 6045 | .alen = 8, | ||
| 6046 | .result = zeroed_string, | ||
| 6047 | .rlen = 16, | ||
| 6048 | }, { | ||
| 6049 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 6050 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 6051 | "\x00\x00\x00\x00", | ||
| 6052 | .klen = 20, | ||
| 6053 | .iv = zeroed_string, | ||
| 6054 | .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" | ||
| 6055 | "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" | ||
| 6056 | "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C" | ||
| 6057 | "\xB1\x68\xFD\x14\x52\x64\x61\xB2", | ||
| 6058 | .ilen = 32, | ||
| 6059 | .assoc = zeroed_string, | ||
| 6060 | .alen = 8, | ||
| 6061 | .result = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6062 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 6063 | .rlen = 16, | ||
| 6064 | }, { | ||
| 6065 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 6066 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 6067 | "\x00\x00\x00\x00", | ||
| 6068 | .klen = 20, | ||
| 6069 | .iv = zeroed_string, | ||
| 6070 | .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" | ||
| 6071 | "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" | ||
| 6072 | "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63" | ||
| 6073 | "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5", | ||
| 6074 | .ilen = 32, | ||
| 6075 | .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 6076 | .alen = 8, | ||
| 6077 | .result = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6078 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 6079 | .rlen = 16, | ||
| 6080 | |||
| 6081 | }, { | ||
| 6082 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 6083 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 6084 | "\x00\x00\x00\x00", | ||
| 6085 | .klen = 20, | ||
| 6086 | .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" | ||
| 6087 | "\x00\x00\x00\x00", | ||
| 6088 | .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" | ||
| 6089 | "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" | ||
| 6090 | "\x64\x50\xF9\x32\x13\xFB\x74\x61" | ||
| 6091 | "\xF4\xED\x52\xD3\xC5\x10\x55\x3C", | ||
| 6092 | .ilen = 32, | ||
| 6093 | .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 6094 | .alen = 8, | ||
| 6095 | .result = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6096 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 6097 | .rlen = 16, | ||
| 6098 | }, { | ||
| 6099 | .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" | ||
| 6100 | "\x6d\x6a\x8f\x94\x67\x30\x83\x08" | ||
| 6101 | "\x00\x00\x00\x00", | ||
| 6102 | .klen = 20, | ||
| 6103 | .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" | ||
| 6104 | "\x00\x00\x00\x00", | ||
| 6105 | .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" | ||
| 6106 | "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" | ||
| 6107 | "\x98\x14\xA1\x42\x37\x80\xFD\x90" | ||
| 6108 | "\x68\x12\x01\xA8\x91\x89\xB9\x83" | ||
| 6109 | "\x5B\x11\x77\x12\x9B\xFF\x24\x89" | ||
| 6110 | "\x94\x5F\x18\x12\xBA\x27\x09\x39" | ||
| 6111 | "\x99\x96\x76\x42\x15\x1C\xCD\xCB" | ||
| 6112 | "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD" | ||
| 6113 | "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85" | ||
| 6114 | "\xBD\xCF\x62\x98\x58\x14\xE5\xBD", | ||
| 6115 | .ilen = 80, | ||
| 6116 | .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 6117 | .alen = 8, | ||
| 6118 | .result = "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6119 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6120 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6121 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6122 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6123 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6124 | "\x01\x01\x01\x01\x01\x01\x01\x01" | ||
| 6125 | "\x01\x01\x01\x01\x01\x01\x01\x01", | ||
| 6126 | .rlen = 64, | ||
| 6127 | }, { | ||
| 6128 | .key = "\x00\x01\x02\x03\x04\x05\x06\x07" | ||
| 6129 | "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" | ||
| 6130 | "\x00\x00\x00\x00", | ||
| 6131 | .klen = 20, | ||
| 6132 | .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef" | ||
| 6133 | "\x00\x00\x00\x00", | ||
| 6134 | .input = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE" | ||
| 6135 | "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A" | ||
| 6136 | "\x44\x6D\xC3\x88\x46\x2E\xC2\x01" | ||
| 6137 | "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82" | ||
| 6138 | "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44" | ||
| 6139 | "\x41\xA9\x82\x6F\x22\xA1\x23\x1A" | ||
| 6140 | "\xA8\xE3\x16\xFD\x31\x5C\x27\x31" | ||
| 6141 | "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1" | ||
| 6142 | "\xCF\x07\x57\x41\x67\xD0\xC4\x42" | ||
| 6143 | "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F" | ||
| 6144 | "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B" | ||
| 6145 | "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE" | ||
| 6146 | "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C" | ||
| 6147 | "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF" | ||
| 6148 | "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59" | ||
| 6149 | "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA" | ||
| 6150 | "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25" | ||
| 6151 | "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B" | ||
| 6152 | "\x7E\x13\x06\x82\x08\x17\xA4\x35" | ||
| 6153 | "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F" | ||
| 6154 | "\xA3\x05\x38\x95\x20\x1A\x47\x04" | ||
| 6155 | "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35" | ||
| 6156 | "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E" | ||
| 6157 | "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B" | ||
| 6158 | "\x37\x08\x1C\xCF\xBA\x5D\x71\x46" | ||
| 6159 | "\x80\x72\xB0\x4C\x82\x0D\x60\x3C", | ||
| 6160 | .ilen = 208, | ||
| 6161 | .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | ||
| 6162 | "\xaa\xaa\xaa\xaa", | ||
| 6163 | .alen = 12, | ||
| 6164 | .result = "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6165 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6166 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6167 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6168 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6169 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6170 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6171 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6172 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6173 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6174 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6175 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6176 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6177 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6178 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6179 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6180 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6181 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6182 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6183 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6184 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6185 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6186 | "\xff\xff\xff\xff\xff\xff\xff\xff" | ||
| 6187 | "\xff\xff\xff\xff\xff\xff\xff\xff", | ||
| 6188 | .rlen = 192, | ||
| 6189 | |||
| 6190 | } | ||
| 6191 | }; | ||
| 6192 | |||
| 5832 | static struct aead_testvec aes_ccm_enc_tv_template[] = { | 6193 | static struct aead_testvec aes_ccm_enc_tv_template[] = { |
| 5833 | { /* From RFC 3610 */ | 6194 | { /* From RFC 3610 */ |
| 5834 | .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" | 6195 | .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" |
diff --git a/crypto/zlib.c b/crypto/zlib.c index c3015733c990..739b8fca4cea 100644 --- a/crypto/zlib.c +++ b/crypto/zlib.c | |||
| @@ -95,11 +95,10 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params, | |||
| 95 | zlib_comp_exit(ctx); | 95 | zlib_comp_exit(ctx); |
| 96 | 96 | ||
| 97 | workspacesize = zlib_deflate_workspacesize(); | 97 | workspacesize = zlib_deflate_workspacesize(); |
| 98 | stream->workspace = vmalloc(workspacesize); | 98 | stream->workspace = vzalloc(workspacesize); |
| 99 | if (!stream->workspace) | 99 | if (!stream->workspace) |
| 100 | return -ENOMEM; | 100 | return -ENOMEM; |
| 101 | 101 | ||
| 102 | memset(stream->workspace, 0, workspacesize); | ||
| 103 | ret = zlib_deflateInit2(stream, | 102 | ret = zlib_deflateInit2(stream, |
| 104 | tb[ZLIB_COMP_LEVEL] | 103 | tb[ZLIB_COMP_LEVEL] |
| 105 | ? nla_get_u32(tb[ZLIB_COMP_LEVEL]) | 104 | ? nla_get_u32(tb[ZLIB_COMP_LEVEL]) |
