diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-22 14:58:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-22 14:58:43 -0500 |
commit | 48162a203e1d0762569d9e7d2de153d9135b35f8 (patch) | |
tree | 2f3b6f03d62d5e4a7e3224fb4536edc8def992c1 /crypto | |
parent | e7cc3edd1758f9aab39f5afcd988ffed55cb26ca (diff) | |
parent | 202736d99b7f29279db9da61587f11a08a04a9c6 (diff) |
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu:
"This fixes the following issues:
API:
- A large number of bug fixes for the af_alg interface, credit goes
to Dmitry Vyukov for discovering and reporting these issues.
Algorithms:
- sw842 needs to select crc32.
- The soft dependency on crc32c is now in the correct spot.
Drivers:
- The atmel AES driver needs HAS_DMA.
- The atmel AES driver was a missing break statement, fortunately
it's only a debug function.
- A number of bug fixes for the Intel qat driver"
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (24 commits)
crypto: algif_skcipher - sendmsg SG marking is off by one
crypto: crc32c - Fix crc32c soft dependency
crypto: algif_skcipher - Load TX SG list after waiting
crypto: atmel-aes - Add missing break to atmel_aes_reg_name
crypto: algif_skcipher - Fix race condition in skcipher_check_key
crypto: algif_hash - Fix race condition in hash_check_key
crypto: CRYPTO_DEV_ATMEL_AES should depend on HAS_DMA
lib: sw842: select crc32
crypto: af_alg - Forbid bind(2) when nokey child sockets are present
crypto: algif_skcipher - Remove custom release parent function
crypto: algif_hash - Remove custom release parent function
crypto: af_alg - Allow af_af_alg_release_parent to be called on nokey path
crypto: qat - update init_esram for C3xxx dev type
crypto: qat - fix timeout issues
crypto: qat - remove to call get_sram_bar_id for qat_c3xxx
crypto: algif_skcipher - Add key check exception for cipher_null
crypto: skcipher - Add crypto_skcipher_has_setkey
crypto: algif_hash - Require setkey before accept(2)
crypto: hash - Add crypto_ahash_has_setkey
crypto: algif_skcipher - Add nokey compatibility path
...
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/af_alg.c | 55 | ||||
-rw-r--r-- | crypto/ahash.c | 5 | ||||
-rw-r--r-- | crypto/algif_hash.c | 165 | ||||
-rw-r--r-- | crypto/algif_skcipher.c | 172 | ||||
-rw-r--r-- | crypto/crc32c_generic.c | 1 | ||||
-rw-r--r-- | crypto/shash.c | 4 | ||||
-rw-r--r-- | crypto/skcipher.c | 2 |
7 files changed, 372 insertions, 32 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index a8e7aa3e257b..f5e18c2a4852 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c | |||
@@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type) | |||
76 | goto unlock; | 76 | goto unlock; |
77 | 77 | ||
78 | type->ops->owner = THIS_MODULE; | 78 | type->ops->owner = THIS_MODULE; |
79 | if (type->ops_nokey) | ||
80 | type->ops_nokey->owner = THIS_MODULE; | ||
79 | node->type = type; | 81 | node->type = type; |
80 | list_add(&node->list, &alg_types); | 82 | list_add(&node->list, &alg_types); |
81 | err = 0; | 83 | err = 0; |
@@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock) | |||
125 | } | 127 | } |
126 | EXPORT_SYMBOL_GPL(af_alg_release); | 128 | EXPORT_SYMBOL_GPL(af_alg_release); |
127 | 129 | ||
130 | void af_alg_release_parent(struct sock *sk) | ||
131 | { | ||
132 | struct alg_sock *ask = alg_sk(sk); | ||
133 | unsigned int nokey = ask->nokey_refcnt; | ||
134 | bool last = nokey && !ask->refcnt; | ||
135 | |||
136 | sk = ask->parent; | ||
137 | ask = alg_sk(sk); | ||
138 | |||
139 | lock_sock(sk); | ||
140 | ask->nokey_refcnt -= nokey; | ||
141 | if (!last) | ||
142 | last = !--ask->refcnt; | ||
143 | release_sock(sk); | ||
144 | |||
145 | if (last) | ||
146 | sock_put(sk); | ||
147 | } | ||
148 | EXPORT_SYMBOL_GPL(af_alg_release_parent); | ||
149 | |||
128 | static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | 150 | static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) |
129 | { | 151 | { |
130 | const u32 forbidden = CRYPTO_ALG_INTERNAL; | 152 | const u32 forbidden = CRYPTO_ALG_INTERNAL; |
@@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
133 | struct sockaddr_alg *sa = (void *)uaddr; | 155 | struct sockaddr_alg *sa = (void *)uaddr; |
134 | const struct af_alg_type *type; | 156 | const struct af_alg_type *type; |
135 | void *private; | 157 | void *private; |
158 | int err; | ||
136 | 159 | ||
137 | if (sock->state == SS_CONNECTED) | 160 | if (sock->state == SS_CONNECTED) |
138 | return -EINVAL; | 161 | return -EINVAL; |
@@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
160 | return PTR_ERR(private); | 183 | return PTR_ERR(private); |
161 | } | 184 | } |
162 | 185 | ||
186 | err = -EBUSY; | ||
163 | lock_sock(sk); | 187 | lock_sock(sk); |
188 | if (ask->refcnt | ask->nokey_refcnt) | ||
189 | goto unlock; | ||
164 | 190 | ||
165 | swap(ask->type, type); | 191 | swap(ask->type, type); |
166 | swap(ask->private, private); | 192 | swap(ask->private, private); |
167 | 193 | ||
194 | err = 0; | ||
195 | |||
196 | unlock: | ||
168 | release_sock(sk); | 197 | release_sock(sk); |
169 | 198 | ||
170 | alg_do_release(type, private); | 199 | alg_do_release(type, private); |
171 | 200 | ||
172 | return 0; | 201 | return err; |
173 | } | 202 | } |
174 | 203 | ||
175 | static int alg_setkey(struct sock *sk, char __user *ukey, | 204 | static int alg_setkey(struct sock *sk, char __user *ukey, |
@@ -202,11 +231,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, | |||
202 | struct sock *sk = sock->sk; | 231 | struct sock *sk = sock->sk; |
203 | struct alg_sock *ask = alg_sk(sk); | 232 | struct alg_sock *ask = alg_sk(sk); |
204 | const struct af_alg_type *type; | 233 | const struct af_alg_type *type; |
205 | int err = -ENOPROTOOPT; | 234 | int err = -EBUSY; |
206 | 235 | ||
207 | lock_sock(sk); | 236 | lock_sock(sk); |
237 | if (ask->refcnt) | ||
238 | goto unlock; | ||
239 | |||
208 | type = ask->type; | 240 | type = ask->type; |
209 | 241 | ||
242 | err = -ENOPROTOOPT; | ||
210 | if (level != SOL_ALG || !type) | 243 | if (level != SOL_ALG || !type) |
211 | goto unlock; | 244 | goto unlock; |
212 | 245 | ||
@@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) | |||
238 | struct alg_sock *ask = alg_sk(sk); | 271 | struct alg_sock *ask = alg_sk(sk); |
239 | const struct af_alg_type *type; | 272 | const struct af_alg_type *type; |
240 | struct sock *sk2; | 273 | struct sock *sk2; |
274 | unsigned int nokey; | ||
241 | int err; | 275 | int err; |
242 | 276 | ||
243 | lock_sock(sk); | 277 | lock_sock(sk); |
@@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) | |||
257 | security_sk_clone(sk, sk2); | 291 | security_sk_clone(sk, sk2); |
258 | 292 | ||
259 | err = type->accept(ask->private, sk2); | 293 | err = type->accept(ask->private, sk2); |
260 | if (err) { | 294 | |
261 | sk_free(sk2); | 295 | nokey = err == -ENOKEY; |
296 | if (nokey && type->accept_nokey) | ||
297 | err = type->accept_nokey(ask->private, sk2); | ||
298 | |||
299 | if (err) | ||
262 | goto unlock; | 300 | goto unlock; |
263 | } | ||
264 | 301 | ||
265 | sk2->sk_family = PF_ALG; | 302 | sk2->sk_family = PF_ALG; |
266 | 303 | ||
267 | sock_hold(sk); | 304 | if (nokey || !ask->refcnt++) |
305 | sock_hold(sk); | ||
306 | ask->nokey_refcnt += nokey; | ||
268 | alg_sk(sk2)->parent = sk; | 307 | alg_sk(sk2)->parent = sk; |
269 | alg_sk(sk2)->type = type; | 308 | alg_sk(sk2)->type = type; |
309 | alg_sk(sk2)->nokey_refcnt = nokey; | ||
270 | 310 | ||
271 | newsock->ops = type->ops; | 311 | newsock->ops = type->ops; |
272 | newsock->state = SS_CONNECTED; | 312 | newsock->state = SS_CONNECTED; |
273 | 313 | ||
314 | if (nokey) | ||
315 | newsock->ops = type->ops_nokey; | ||
316 | |||
274 | err = 0; | 317 | err = 0; |
275 | 318 | ||
276 | unlock: | 319 | unlock: |
diff --git a/crypto/ahash.c b/crypto/ahash.c index 9c1dc8d6106a..d19b52324cf5 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
@@ -451,6 +451,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm) | |||
451 | struct ahash_alg *alg = crypto_ahash_alg(hash); | 451 | struct ahash_alg *alg = crypto_ahash_alg(hash); |
452 | 452 | ||
453 | hash->setkey = ahash_nosetkey; | 453 | hash->setkey = ahash_nosetkey; |
454 | hash->has_setkey = false; | ||
454 | hash->export = ahash_no_export; | 455 | hash->export = ahash_no_export; |
455 | hash->import = ahash_no_import; | 456 | hash->import = ahash_no_import; |
456 | 457 | ||
@@ -463,8 +464,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm) | |||
463 | hash->finup = alg->finup ?: ahash_def_finup; | 464 | hash->finup = alg->finup ?: ahash_def_finup; |
464 | hash->digest = alg->digest; | 465 | hash->digest = alg->digest; |
465 | 466 | ||
466 | if (alg->setkey) | 467 | if (alg->setkey) { |
467 | hash->setkey = alg->setkey; | 468 | hash->setkey = alg->setkey; |
469 | hash->has_setkey = true; | ||
470 | } | ||
468 | if (alg->export) | 471 | if (alg->export) |
469 | hash->export = alg->export; | 472 | hash->export = alg->export; |
470 | if (alg->import) | 473 | if (alg->import) |
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index b4c24fe3dcfb..608a7562839d 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c | |||
@@ -34,6 +34,11 @@ struct hash_ctx { | |||
34 | struct ahash_request req; | 34 | struct ahash_request req; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | struct algif_hash_tfm { | ||
38 | struct crypto_ahash *hash; | ||
39 | bool has_key; | ||
40 | }; | ||
41 | |||
37 | static int hash_sendmsg(struct socket *sock, struct msghdr *msg, | 42 | static int hash_sendmsg(struct socket *sock, struct msghdr *msg, |
38 | size_t ignored) | 43 | size_t ignored) |
39 | { | 44 | { |
@@ -235,19 +240,151 @@ static struct proto_ops algif_hash_ops = { | |||
235 | .accept = hash_accept, | 240 | .accept = hash_accept, |
236 | }; | 241 | }; |
237 | 242 | ||
243 | static int hash_check_key(struct socket *sock) | ||
244 | { | ||
245 | int err = 0; | ||
246 | struct sock *psk; | ||
247 | struct alg_sock *pask; | ||
248 | struct algif_hash_tfm *tfm; | ||
249 | struct sock *sk = sock->sk; | ||
250 | struct alg_sock *ask = alg_sk(sk); | ||
251 | |||
252 | lock_sock(sk); | ||
253 | if (ask->refcnt) | ||
254 | goto unlock_child; | ||
255 | |||
256 | psk = ask->parent; | ||
257 | pask = alg_sk(ask->parent); | ||
258 | tfm = pask->private; | ||
259 | |||
260 | err = -ENOKEY; | ||
261 | lock_sock_nested(psk, SINGLE_DEPTH_NESTING); | ||
262 | if (!tfm->has_key) | ||
263 | goto unlock; | ||
264 | |||
265 | if (!pask->refcnt++) | ||
266 | sock_hold(psk); | ||
267 | |||
268 | ask->refcnt = 1; | ||
269 | sock_put(psk); | ||
270 | |||
271 | err = 0; | ||
272 | |||
273 | unlock: | ||
274 | release_sock(psk); | ||
275 | unlock_child: | ||
276 | release_sock(sk); | ||
277 | |||
278 | return err; | ||
279 | } | ||
280 | |||
281 | static int hash_sendmsg_nokey(struct socket *sock, struct msghdr *msg, | ||
282 | size_t size) | ||
283 | { | ||
284 | int err; | ||
285 | |||
286 | err = hash_check_key(sock); | ||
287 | if (err) | ||
288 | return err; | ||
289 | |||
290 | return hash_sendmsg(sock, msg, size); | ||
291 | } | ||
292 | |||
293 | static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page, | ||
294 | int offset, size_t size, int flags) | ||
295 | { | ||
296 | int err; | ||
297 | |||
298 | err = hash_check_key(sock); | ||
299 | if (err) | ||
300 | return err; | ||
301 | |||
302 | return hash_sendpage(sock, page, offset, size, flags); | ||
303 | } | ||
304 | |||
305 | static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg, | ||
306 | size_t ignored, int flags) | ||
307 | { | ||
308 | int err; | ||
309 | |||
310 | err = hash_check_key(sock); | ||
311 | if (err) | ||
312 | return err; | ||
313 | |||
314 | return hash_recvmsg(sock, msg, ignored, flags); | ||
315 | } | ||
316 | |||
317 | static int hash_accept_nokey(struct socket *sock, struct socket *newsock, | ||
318 | int flags) | ||
319 | { | ||
320 | int err; | ||
321 | |||
322 | err = hash_check_key(sock); | ||
323 | if (err) | ||
324 | return err; | ||
325 | |||
326 | return hash_accept(sock, newsock, flags); | ||
327 | } | ||
328 | |||
329 | static struct proto_ops algif_hash_ops_nokey = { | ||
330 | .family = PF_ALG, | ||
331 | |||
332 | .connect = sock_no_connect, | ||
333 | .socketpair = sock_no_socketpair, | ||
334 | .getname = sock_no_getname, | ||
335 | .ioctl = sock_no_ioctl, | ||
336 | .listen = sock_no_listen, | ||
337 | .shutdown = sock_no_shutdown, | ||
338 | .getsockopt = sock_no_getsockopt, | ||
339 | .mmap = sock_no_mmap, | ||
340 | .bind = sock_no_bind, | ||
341 | .setsockopt = sock_no_setsockopt, | ||
342 | .poll = sock_no_poll, | ||
343 | |||
344 | .release = af_alg_release, | ||
345 | .sendmsg = hash_sendmsg_nokey, | ||
346 | .sendpage = hash_sendpage_nokey, | ||
347 | .recvmsg = hash_recvmsg_nokey, | ||
348 | .accept = hash_accept_nokey, | ||
349 | }; | ||
350 | |||
238 | static void *hash_bind(const char *name, u32 type, u32 mask) | 351 | static void *hash_bind(const char *name, u32 type, u32 mask) |
239 | { | 352 | { |
240 | return crypto_alloc_ahash(name, type, mask); | 353 | struct algif_hash_tfm *tfm; |
354 | struct crypto_ahash *hash; | ||
355 | |||
356 | tfm = kzalloc(sizeof(*tfm), GFP_KERNEL); | ||
357 | if (!tfm) | ||
358 | return ERR_PTR(-ENOMEM); | ||
359 | |||
360 | hash = crypto_alloc_ahash(name, type, mask); | ||
361 | if (IS_ERR(hash)) { | ||
362 | kfree(tfm); | ||
363 | return ERR_CAST(hash); | ||
364 | } | ||
365 | |||
366 | tfm->hash = hash; | ||
367 | |||
368 | return tfm; | ||
241 | } | 369 | } |
242 | 370 | ||
243 | static void hash_release(void *private) | 371 | static void hash_release(void *private) |
244 | { | 372 | { |
245 | crypto_free_ahash(private); | 373 | struct algif_hash_tfm *tfm = private; |
374 | |||
375 | crypto_free_ahash(tfm->hash); | ||
376 | kfree(tfm); | ||
246 | } | 377 | } |
247 | 378 | ||
248 | static int hash_setkey(void *private, const u8 *key, unsigned int keylen) | 379 | static int hash_setkey(void *private, const u8 *key, unsigned int keylen) |
249 | { | 380 | { |
250 | return crypto_ahash_setkey(private, key, keylen); | 381 | struct algif_hash_tfm *tfm = private; |
382 | int err; | ||
383 | |||
384 | err = crypto_ahash_setkey(tfm->hash, key, keylen); | ||
385 | tfm->has_key = !err; | ||
386 | |||
387 | return err; | ||
251 | } | 388 | } |
252 | 389 | ||
253 | static void hash_sock_destruct(struct sock *sk) | 390 | static void hash_sock_destruct(struct sock *sk) |
@@ -261,12 +398,14 @@ static void hash_sock_destruct(struct sock *sk) | |||
261 | af_alg_release_parent(sk); | 398 | af_alg_release_parent(sk); |
262 | } | 399 | } |
263 | 400 | ||
264 | static int hash_accept_parent(void *private, struct sock *sk) | 401 | static int hash_accept_parent_nokey(void *private, struct sock *sk) |
265 | { | 402 | { |
266 | struct hash_ctx *ctx; | 403 | struct hash_ctx *ctx; |
267 | struct alg_sock *ask = alg_sk(sk); | 404 | struct alg_sock *ask = alg_sk(sk); |
268 | unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private); | 405 | struct algif_hash_tfm *tfm = private; |
269 | unsigned ds = crypto_ahash_digestsize(private); | 406 | struct crypto_ahash *hash = tfm->hash; |
407 | unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash); | ||
408 | unsigned ds = crypto_ahash_digestsize(hash); | ||
270 | 409 | ||
271 | ctx = sock_kmalloc(sk, len, GFP_KERNEL); | 410 | ctx = sock_kmalloc(sk, len, GFP_KERNEL); |
272 | if (!ctx) | 411 | if (!ctx) |
@@ -286,7 +425,7 @@ static int hash_accept_parent(void *private, struct sock *sk) | |||
286 | 425 | ||
287 | ask->private = ctx; | 426 | ask->private = ctx; |
288 | 427 | ||
289 | ahash_request_set_tfm(&ctx->req, private); | 428 | ahash_request_set_tfm(&ctx->req, hash); |
290 | ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, | 429 | ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
291 | af_alg_complete, &ctx->completion); | 430 | af_alg_complete, &ctx->completion); |
292 | 431 | ||
@@ -295,12 +434,24 @@ static int hash_accept_parent(void *private, struct sock *sk) | |||
295 | return 0; | 434 | return 0; |
296 | } | 435 | } |
297 | 436 | ||
437 | static int hash_accept_parent(void *private, struct sock *sk) | ||
438 | { | ||
439 | struct algif_hash_tfm *tfm = private; | ||
440 | |||
441 | if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash)) | ||
442 | return -ENOKEY; | ||
443 | |||
444 | return hash_accept_parent_nokey(private, sk); | ||
445 | } | ||
446 | |||
298 | static const struct af_alg_type algif_type_hash = { | 447 | static const struct af_alg_type algif_type_hash = { |
299 | .bind = hash_bind, | 448 | .bind = hash_bind, |
300 | .release = hash_release, | 449 | .release = hash_release, |
301 | .setkey = hash_setkey, | 450 | .setkey = hash_setkey, |
302 | .accept = hash_accept_parent, | 451 | .accept = hash_accept_parent, |
452 | .accept_nokey = hash_accept_parent_nokey, | ||
303 | .ops = &algif_hash_ops, | 453 | .ops = &algif_hash_ops, |
454 | .ops_nokey = &algif_hash_ops_nokey, | ||
304 | .name = "hash", | 455 | .name = "hash", |
305 | .owner = THIS_MODULE | 456 | .owner = THIS_MODULE |
306 | }; | 457 | }; |
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index eaa9f9be5b87..38c1aa89d3a0 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c | |||
@@ -31,6 +31,11 @@ struct skcipher_sg_list { | |||
31 | struct scatterlist sg[0]; | 31 | struct scatterlist sg[0]; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | struct skcipher_tfm { | ||
35 | struct crypto_skcipher *skcipher; | ||
36 | bool has_key; | ||
37 | }; | ||
38 | |||
34 | struct skcipher_ctx { | 39 | struct skcipher_ctx { |
35 | struct list_head tsgl; | 40 | struct list_head tsgl; |
36 | struct af_alg_sgl rsgl; | 41 | struct af_alg_sgl rsgl; |
@@ -387,7 +392,8 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, | |||
387 | 392 | ||
388 | sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); | 393 | sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); |
389 | sg = sgl->sg; | 394 | sg = sgl->sg; |
390 | sg_unmark_end(sg + sgl->cur); | 395 | if (sgl->cur) |
396 | sg_unmark_end(sg + sgl->cur - 1); | ||
391 | do { | 397 | do { |
392 | i = sgl->cur; | 398 | i = sgl->cur; |
393 | plen = min_t(size_t, len, PAGE_SIZE); | 399 | plen = min_t(size_t, len, PAGE_SIZE); |
@@ -642,13 +648,6 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg, | |||
642 | 648 | ||
643 | lock_sock(sk); | 649 | lock_sock(sk); |
644 | while (msg_data_left(msg)) { | 650 | while (msg_data_left(msg)) { |
645 | sgl = list_first_entry(&ctx->tsgl, | ||
646 | struct skcipher_sg_list, list); | ||
647 | sg = sgl->sg; | ||
648 | |||
649 | while (!sg->length) | ||
650 | sg++; | ||
651 | |||
652 | if (!ctx->used) { | 651 | if (!ctx->used) { |
653 | err = skcipher_wait_for_data(sk, flags); | 652 | err = skcipher_wait_for_data(sk, flags); |
654 | if (err) | 653 | if (err) |
@@ -669,6 +668,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg, | |||
669 | if (!used) | 668 | if (!used) |
670 | goto free; | 669 | goto free; |
671 | 670 | ||
671 | sgl = list_first_entry(&ctx->tsgl, | ||
672 | struct skcipher_sg_list, list); | ||
673 | sg = sgl->sg; | ||
674 | |||
675 | while (!sg->length) | ||
676 | sg++; | ||
677 | |||
672 | skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used, | 678 | skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used, |
673 | ctx->iv); | 679 | ctx->iv); |
674 | 680 | ||
@@ -748,19 +754,139 @@ static struct proto_ops algif_skcipher_ops = { | |||
748 | .poll = skcipher_poll, | 754 | .poll = skcipher_poll, |
749 | }; | 755 | }; |
750 | 756 | ||
757 | static int skcipher_check_key(struct socket *sock) | ||
758 | { | ||
759 | int err = 0; | ||
760 | struct sock *psk; | ||
761 | struct alg_sock *pask; | ||
762 | struct skcipher_tfm *tfm; | ||
763 | struct sock *sk = sock->sk; | ||
764 | struct alg_sock *ask = alg_sk(sk); | ||
765 | |||
766 | lock_sock(sk); | ||
767 | if (ask->refcnt) | ||
768 | goto unlock_child; | ||
769 | |||
770 | psk = ask->parent; | ||
771 | pask = alg_sk(ask->parent); | ||
772 | tfm = pask->private; | ||
773 | |||
774 | err = -ENOKEY; | ||
775 | lock_sock_nested(psk, SINGLE_DEPTH_NESTING); | ||
776 | if (!tfm->has_key) | ||
777 | goto unlock; | ||
778 | |||
779 | if (!pask->refcnt++) | ||
780 | sock_hold(psk); | ||
781 | |||
782 | ask->refcnt = 1; | ||
783 | sock_put(psk); | ||
784 | |||
785 | err = 0; | ||
786 | |||
787 | unlock: | ||
788 | release_sock(psk); | ||
789 | unlock_child: | ||
790 | release_sock(sk); | ||
791 | |||
792 | return err; | ||
793 | } | ||
794 | |||
795 | static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg, | ||
796 | size_t size) | ||
797 | { | ||
798 | int err; | ||
799 | |||
800 | err = skcipher_check_key(sock); | ||
801 | if (err) | ||
802 | return err; | ||
803 | |||
804 | return skcipher_sendmsg(sock, msg, size); | ||
805 | } | ||
806 | |||
807 | static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page, | ||
808 | int offset, size_t size, int flags) | ||
809 | { | ||
810 | int err; | ||
811 | |||
812 | err = skcipher_check_key(sock); | ||
813 | if (err) | ||
814 | return err; | ||
815 | |||
816 | return skcipher_sendpage(sock, page, offset, size, flags); | ||
817 | } | ||
818 | |||
819 | static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg, | ||
820 | size_t ignored, int flags) | ||
821 | { | ||
822 | int err; | ||
823 | |||
824 | err = skcipher_check_key(sock); | ||
825 | if (err) | ||
826 | return err; | ||
827 | |||
828 | return skcipher_recvmsg(sock, msg, ignored, flags); | ||
829 | } | ||
830 | |||
831 | static struct proto_ops algif_skcipher_ops_nokey = { | ||
832 | .family = PF_ALG, | ||
833 | |||
834 | .connect = sock_no_connect, | ||
835 | .socketpair = sock_no_socketpair, | ||
836 | .getname = sock_no_getname, | ||
837 | .ioctl = sock_no_ioctl, | ||
838 | .listen = sock_no_listen, | ||
839 | .shutdown = sock_no_shutdown, | ||
840 | .getsockopt = sock_no_getsockopt, | ||
841 | .mmap = sock_no_mmap, | ||
842 | .bind = sock_no_bind, | ||
843 | .accept = sock_no_accept, | ||
844 | .setsockopt = sock_no_setsockopt, | ||
845 | |||
846 | .release = af_alg_release, | ||
847 | .sendmsg = skcipher_sendmsg_nokey, | ||
848 | .sendpage = skcipher_sendpage_nokey, | ||
849 | .recvmsg = skcipher_recvmsg_nokey, | ||
850 | .poll = skcipher_poll, | ||
851 | }; | ||
852 | |||
751 | static void *skcipher_bind(const char *name, u32 type, u32 mask) | 853 | static void *skcipher_bind(const char *name, u32 type, u32 mask) |
752 | { | 854 | { |
753 | return crypto_alloc_skcipher(name, type, mask); | 855 | struct skcipher_tfm *tfm; |
856 | struct crypto_skcipher *skcipher; | ||
857 | |||
858 | tfm = kzalloc(sizeof(*tfm), GFP_KERNEL); | ||
859 | if (!tfm) | ||
860 | return ERR_PTR(-ENOMEM); | ||
861 | |||
862 | skcipher = crypto_alloc_skcipher(name, type, mask); | ||
863 | if (IS_ERR(skcipher)) { | ||
864 | kfree(tfm); | ||
865 | return ERR_CAST(skcipher); | ||
866 | } | ||
867 | |||
868 | tfm->skcipher = skcipher; | ||
869 | |||
870 | return tfm; | ||
754 | } | 871 | } |
755 | 872 | ||
756 | static void skcipher_release(void *private) | 873 | static void skcipher_release(void *private) |
757 | { | 874 | { |
758 | crypto_free_skcipher(private); | 875 | struct skcipher_tfm *tfm = private; |
876 | |||
877 | crypto_free_skcipher(tfm->skcipher); | ||
878 | kfree(tfm); | ||
759 | } | 879 | } |
760 | 880 | ||
761 | static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) | 881 | static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) |
762 | { | 882 | { |
763 | return crypto_skcipher_setkey(private, key, keylen); | 883 | struct skcipher_tfm *tfm = private; |
884 | int err; | ||
885 | |||
886 | err = crypto_skcipher_setkey(tfm->skcipher, key, keylen); | ||
887 | tfm->has_key = !err; | ||
888 | |||
889 | return err; | ||
764 | } | 890 | } |
765 | 891 | ||
766 | static void skcipher_wait(struct sock *sk) | 892 | static void skcipher_wait(struct sock *sk) |
@@ -788,24 +914,26 @@ static void skcipher_sock_destruct(struct sock *sk) | |||
788 | af_alg_release_parent(sk); | 914 | af_alg_release_parent(sk); |
789 | } | 915 | } |
790 | 916 | ||
791 | static int skcipher_accept_parent(void *private, struct sock *sk) | 917 | static int skcipher_accept_parent_nokey(void *private, struct sock *sk) |
792 | { | 918 | { |
793 | struct skcipher_ctx *ctx; | 919 | struct skcipher_ctx *ctx; |
794 | struct alg_sock *ask = alg_sk(sk); | 920 | struct alg_sock *ask = alg_sk(sk); |
795 | unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(private); | 921 | struct skcipher_tfm *tfm = private; |
922 | struct crypto_skcipher *skcipher = tfm->skcipher; | ||
923 | unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(skcipher); | ||
796 | 924 | ||
797 | ctx = sock_kmalloc(sk, len, GFP_KERNEL); | 925 | ctx = sock_kmalloc(sk, len, GFP_KERNEL); |
798 | if (!ctx) | 926 | if (!ctx) |
799 | return -ENOMEM; | 927 | return -ENOMEM; |
800 | 928 | ||
801 | ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private), | 929 | ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher), |
802 | GFP_KERNEL); | 930 | GFP_KERNEL); |
803 | if (!ctx->iv) { | 931 | if (!ctx->iv) { |
804 | sock_kfree_s(sk, ctx, len); | 932 | sock_kfree_s(sk, ctx, len); |
805 | return -ENOMEM; | 933 | return -ENOMEM; |
806 | } | 934 | } |
807 | 935 | ||
808 | memset(ctx->iv, 0, crypto_skcipher_ivsize(private)); | 936 | memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher)); |
809 | 937 | ||
810 | INIT_LIST_HEAD(&ctx->tsgl); | 938 | INIT_LIST_HEAD(&ctx->tsgl); |
811 | ctx->len = len; | 939 | ctx->len = len; |
@@ -818,7 +946,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk) | |||
818 | 946 | ||
819 | ask->private = ctx; | 947 | ask->private = ctx; |
820 | 948 | ||
821 | skcipher_request_set_tfm(&ctx->req, private); | 949 | skcipher_request_set_tfm(&ctx->req, skcipher); |
822 | skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, | 950 | skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
823 | af_alg_complete, &ctx->completion); | 951 | af_alg_complete, &ctx->completion); |
824 | 952 | ||
@@ -827,12 +955,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk) | |||
827 | return 0; | 955 | return 0; |
828 | } | 956 | } |
829 | 957 | ||
958 | static int skcipher_accept_parent(void *private, struct sock *sk) | ||
959 | { | ||
960 | struct skcipher_tfm *tfm = private; | ||
961 | |||
962 | if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher)) | ||
963 | return -ENOKEY; | ||
964 | |||
965 | return skcipher_accept_parent_nokey(private, sk); | ||
966 | } | ||
967 | |||
830 | static const struct af_alg_type algif_type_skcipher = { | 968 | static const struct af_alg_type algif_type_skcipher = { |
831 | .bind = skcipher_bind, | 969 | .bind = skcipher_bind, |
832 | .release = skcipher_release, | 970 | .release = skcipher_release, |
833 | .setkey = skcipher_setkey, | 971 | .setkey = skcipher_setkey, |
834 | .accept = skcipher_accept_parent, | 972 | .accept = skcipher_accept_parent, |
973 | .accept_nokey = skcipher_accept_parent_nokey, | ||
835 | .ops = &algif_skcipher_ops, | 974 | .ops = &algif_skcipher_ops, |
975 | .ops_nokey = &algif_skcipher_ops_nokey, | ||
836 | .name = "skcipher", | 976 | .name = "skcipher", |
837 | .owner = THIS_MODULE | 977 | .owner = THIS_MODULE |
838 | }; | 978 | }; |
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c index 06f1b60f02b2..4c0a0e271876 100644 --- a/crypto/crc32c_generic.c +++ b/crypto/crc32c_generic.c | |||
@@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c"); | |||
172 | MODULE_LICENSE("GPL"); | 172 | MODULE_LICENSE("GPL"); |
173 | MODULE_ALIAS_CRYPTO("crc32c"); | 173 | MODULE_ALIAS_CRYPTO("crc32c"); |
174 | MODULE_ALIAS_CRYPTO("crc32c-generic"); | 174 | MODULE_ALIAS_CRYPTO("crc32c-generic"); |
175 | MODULE_SOFTDEP("pre: crc32c"); | ||
diff --git a/crypto/shash.c b/crypto/shash.c index ecb1e3d39bf0..88a27de79848 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
@@ -355,8 +355,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm) | |||
355 | crt->finup = shash_async_finup; | 355 | crt->finup = shash_async_finup; |
356 | crt->digest = shash_async_digest; | 356 | crt->digest = shash_async_digest; |
357 | 357 | ||
358 | if (alg->setkey) | 358 | if (alg->setkey) { |
359 | crt->setkey = shash_async_setkey; | 359 | crt->setkey = shash_async_setkey; |
360 | crt->has_setkey = true; | ||
361 | } | ||
360 | if (alg->export) | 362 | if (alg->export) |
361 | crt->export = shash_async_export; | 363 | crt->export = shash_async_export; |
362 | if (alg->import) | 364 | if (alg->import) |
diff --git a/crypto/skcipher.c b/crypto/skcipher.c index 7591928be7ca..d199c0b1751c 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c | |||
@@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm) | |||
118 | skcipher->decrypt = skcipher_decrypt_blkcipher; | 118 | skcipher->decrypt = skcipher_decrypt_blkcipher; |
119 | 119 | ||
120 | skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher); | 120 | skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher); |
121 | skcipher->has_setkey = calg->cra_blkcipher.max_keysize; | ||
121 | 122 | ||
122 | return 0; | 123 | return 0; |
123 | } | 124 | } |
@@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm) | |||
210 | skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher); | 211 | skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher); |
211 | skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) + | 212 | skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) + |
212 | sizeof(struct ablkcipher_request); | 213 | sizeof(struct ablkcipher_request); |
214 | skcipher->has_setkey = calg->cra_ablkcipher.max_keysize; | ||
213 | 215 | ||
214 | return 0; | 216 | return 0; |
215 | } | 217 | } |