summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-01-03 14:16:29 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2018-01-12 07:03:39 -0500
commitf8d33fac84806eebd2ba31a3136066eeca19255f (patch)
treeca1ff03d50c7f17a3a1ae173f1324af826068619 /crypto
parent4e1d14bcd10a33537918a9a747ab90fc5c2e6d7f (diff)
crypto: skcipher - prevent using skciphers without setting key
Similar to what was done for the hash API, update the skcipher API to track whether each transform has been keyed, and reject encryption/decryption if a key is needed but one hasn't been set. This isn't as important as the equivalent fix for the hash API because symmetric ciphers almost always require a key (the "null cipher" is the only exception), so are unlikely to be used without one. Still, tracking the key will prevent accidental unkeyed use. algif_skcipher also had to track the key anyway, so the new flag replaces that and simplifies the algif_skcipher implementation. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/algif_skcipher.c59
-rw-r--r--crypto/skcipher.c30
2 files changed, 39 insertions, 50 deletions
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index c5c47b680152..c88e5e4cd6a6 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -38,11 +38,6 @@
38#include <linux/net.h> 38#include <linux/net.h>
39#include <net/sock.h> 39#include <net/sock.h>
40 40
41struct skcipher_tfm {
42 struct crypto_skcipher *skcipher;
43 bool has_key;
44};
45
46static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, 41static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
47 size_t size) 42 size_t size)
48{ 43{
@@ -50,8 +45,7 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
50 struct alg_sock *ask = alg_sk(sk); 45 struct alg_sock *ask = alg_sk(sk);
51 struct sock *psk = ask->parent; 46 struct sock *psk = ask->parent;
52 struct alg_sock *pask = alg_sk(psk); 47 struct alg_sock *pask = alg_sk(psk);
53 struct skcipher_tfm *skc = pask->private; 48 struct crypto_skcipher *tfm = pask->private;
54 struct crypto_skcipher *tfm = skc->skcipher;
55 unsigned ivsize = crypto_skcipher_ivsize(tfm); 49 unsigned ivsize = crypto_skcipher_ivsize(tfm);
56 50
57 return af_alg_sendmsg(sock, msg, size, ivsize); 51 return af_alg_sendmsg(sock, msg, size, ivsize);
@@ -65,8 +59,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
65 struct sock *psk = ask->parent; 59 struct sock *psk = ask->parent;
66 struct alg_sock *pask = alg_sk(psk); 60 struct alg_sock *pask = alg_sk(psk);
67 struct af_alg_ctx *ctx = ask->private; 61 struct af_alg_ctx *ctx = ask->private;
68 struct skcipher_tfm *skc = pask->private; 62 struct crypto_skcipher *tfm = pask->private;
69 struct crypto_skcipher *tfm = skc->skcipher;
70 unsigned int bs = crypto_skcipher_blocksize(tfm); 63 unsigned int bs = crypto_skcipher_blocksize(tfm);
71 struct af_alg_async_req *areq; 64 struct af_alg_async_req *areq;
72 int err = 0; 65 int err = 0;
@@ -221,7 +214,7 @@ static int skcipher_check_key(struct socket *sock)
221 int err = 0; 214 int err = 0;
222 struct sock *psk; 215 struct sock *psk;
223 struct alg_sock *pask; 216 struct alg_sock *pask;
224 struct skcipher_tfm *tfm; 217 struct crypto_skcipher *tfm;
225 struct sock *sk = sock->sk; 218 struct sock *sk = sock->sk;
226 struct alg_sock *ask = alg_sk(sk); 219 struct alg_sock *ask = alg_sk(sk);
227 220
@@ -235,7 +228,7 @@ static int skcipher_check_key(struct socket *sock)
235 228
236 err = -ENOKEY; 229 err = -ENOKEY;
237 lock_sock_nested(psk, SINGLE_DEPTH_NESTING); 230 lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
238 if (!tfm->has_key) 231 if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
239 goto unlock; 232 goto unlock;
240 233
241 if (!pask->refcnt++) 234 if (!pask->refcnt++)
@@ -314,41 +307,17 @@ static struct proto_ops algif_skcipher_ops_nokey = {
314 307
315static void *skcipher_bind(const char *name, u32 type, u32 mask) 308static void *skcipher_bind(const char *name, u32 type, u32 mask)
316{ 309{
317 struct skcipher_tfm *tfm; 310 return crypto_alloc_skcipher(name, type, mask);
318 struct crypto_skcipher *skcipher;
319
320 tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
321 if (!tfm)
322 return ERR_PTR(-ENOMEM);
323
324 skcipher = crypto_alloc_skcipher(name, type, mask);
325 if (IS_ERR(skcipher)) {
326 kfree(tfm);
327 return ERR_CAST(skcipher);
328 }
329
330 tfm->skcipher = skcipher;
331
332 return tfm;
333} 311}
334 312
335static void skcipher_release(void *private) 313static void skcipher_release(void *private)
336{ 314{
337 struct skcipher_tfm *tfm = private; 315 crypto_free_skcipher(private);
338
339 crypto_free_skcipher(tfm->skcipher);
340 kfree(tfm);
341} 316}
342 317
343static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) 318static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
344{ 319{
345 struct skcipher_tfm *tfm = private; 320 return crypto_skcipher_setkey(private, key, keylen);
346 int err;
347
348 err = crypto_skcipher_setkey(tfm->skcipher, key, keylen);
349 tfm->has_key = !err;
350
351 return err;
352} 321}
353 322
354static void skcipher_sock_destruct(struct sock *sk) 323static void skcipher_sock_destruct(struct sock *sk)
@@ -357,8 +326,7 @@ static void skcipher_sock_destruct(struct sock *sk)
357 struct af_alg_ctx *ctx = ask->private; 326 struct af_alg_ctx *ctx = ask->private;
358 struct sock *psk = ask->parent; 327 struct sock *psk = ask->parent;
359 struct alg_sock *pask = alg_sk(psk); 328 struct alg_sock *pask = alg_sk(psk);
360 struct skcipher_tfm *skc = pask->private; 329 struct crypto_skcipher *tfm = pask->private;
361 struct crypto_skcipher *tfm = skc->skcipher;
362 330
363 af_alg_pull_tsgl(sk, ctx->used, NULL, 0); 331 af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
364 sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm)); 332 sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
@@ -370,22 +338,21 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
370{ 338{
371 struct af_alg_ctx *ctx; 339 struct af_alg_ctx *ctx;
372 struct alg_sock *ask = alg_sk(sk); 340 struct alg_sock *ask = alg_sk(sk);
373 struct skcipher_tfm *tfm = private; 341 struct crypto_skcipher *tfm = private;
374 struct crypto_skcipher *skcipher = tfm->skcipher;
375 unsigned int len = sizeof(*ctx); 342 unsigned int len = sizeof(*ctx);
376 343
377 ctx = sock_kmalloc(sk, len, GFP_KERNEL); 344 ctx = sock_kmalloc(sk, len, GFP_KERNEL);
378 if (!ctx) 345 if (!ctx)
379 return -ENOMEM; 346 return -ENOMEM;
380 347
381 ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher), 348 ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm),
382 GFP_KERNEL); 349 GFP_KERNEL);
383 if (!ctx->iv) { 350 if (!ctx->iv) {
384 sock_kfree_s(sk, ctx, len); 351 sock_kfree_s(sk, ctx, len);
385 return -ENOMEM; 352 return -ENOMEM;
386 } 353 }
387 354
388 memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher)); 355 memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm));
389 356
390 INIT_LIST_HEAD(&ctx->tsgl_list); 357 INIT_LIST_HEAD(&ctx->tsgl_list);
391 ctx->len = len; 358 ctx->len = len;
@@ -405,9 +372,9 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
405 372
406static int skcipher_accept_parent(void *private, struct sock *sk) 373static int skcipher_accept_parent(void *private, struct sock *sk)
407{ 374{
408 struct skcipher_tfm *tfm = private; 375 struct crypto_skcipher *tfm = private;
409 376
410 if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher)) 377 if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
411 return -ENOKEY; 378 return -ENOKEY;
412 379
413 return skcipher_accept_parent_nokey(private, sk); 380 return skcipher_accept_parent_nokey(private, sk);
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 11af5fd6a443..0fe2a2923ad0 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -598,8 +598,11 @@ static int skcipher_setkey_blkcipher(struct crypto_skcipher *tfm,
598 err = crypto_blkcipher_setkey(blkcipher, key, keylen); 598 err = crypto_blkcipher_setkey(blkcipher, key, keylen);
599 crypto_skcipher_set_flags(tfm, crypto_blkcipher_get_flags(blkcipher) & 599 crypto_skcipher_set_flags(tfm, crypto_blkcipher_get_flags(blkcipher) &
600 CRYPTO_TFM_RES_MASK); 600 CRYPTO_TFM_RES_MASK);
601 if (err)
602 return err;
601 603
602 return err; 604 crypto_skcipher_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
605 return 0;
603} 606}
604 607
605static int skcipher_crypt_blkcipher(struct skcipher_request *req, 608static int skcipher_crypt_blkcipher(struct skcipher_request *req,
@@ -674,6 +677,9 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
674 skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher); 677 skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
675 skcipher->keysize = calg->cra_blkcipher.max_keysize; 678 skcipher->keysize = calg->cra_blkcipher.max_keysize;
676 679
680 if (skcipher->keysize)
681 crypto_skcipher_set_flags(skcipher, CRYPTO_TFM_NEED_KEY);
682
677 return 0; 683 return 0;
678} 684}
679 685
@@ -692,8 +698,11 @@ static int skcipher_setkey_ablkcipher(struct crypto_skcipher *tfm,
692 crypto_skcipher_set_flags(tfm, 698 crypto_skcipher_set_flags(tfm,
693 crypto_ablkcipher_get_flags(ablkcipher) & 699 crypto_ablkcipher_get_flags(ablkcipher) &
694 CRYPTO_TFM_RES_MASK); 700 CRYPTO_TFM_RES_MASK);
701 if (err)
702 return err;
695 703
696 return err; 704 crypto_skcipher_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
705 return 0;
697} 706}
698 707
699static int skcipher_crypt_ablkcipher(struct skcipher_request *req, 708static int skcipher_crypt_ablkcipher(struct skcipher_request *req,
@@ -767,6 +776,9 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
767 sizeof(struct ablkcipher_request); 776 sizeof(struct ablkcipher_request);
768 skcipher->keysize = calg->cra_ablkcipher.max_keysize; 777 skcipher->keysize = calg->cra_ablkcipher.max_keysize;
769 778
779 if (skcipher->keysize)
780 crypto_skcipher_set_flags(skcipher, CRYPTO_TFM_NEED_KEY);
781
770 return 0; 782 return 0;
771} 783}
772 784
@@ -796,6 +808,7 @@ static int skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
796{ 808{
797 struct skcipher_alg *cipher = crypto_skcipher_alg(tfm); 809 struct skcipher_alg *cipher = crypto_skcipher_alg(tfm);
798 unsigned long alignmask = crypto_skcipher_alignmask(tfm); 810 unsigned long alignmask = crypto_skcipher_alignmask(tfm);
811 int err;
799 812
800 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { 813 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
801 crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 814 crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
@@ -803,9 +816,15 @@ static int skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
803 } 816 }
804 817
805 if ((unsigned long)key & alignmask) 818 if ((unsigned long)key & alignmask)
806 return skcipher_setkey_unaligned(tfm, key, keylen); 819 err = skcipher_setkey_unaligned(tfm, key, keylen);
820 else
821 err = cipher->setkey(tfm, key, keylen);
822
823 if (err)
824 return err;
807 825
808 return cipher->setkey(tfm, key, keylen); 826 crypto_skcipher_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
827 return 0;
809} 828}
810 829
811static void crypto_skcipher_exit_tfm(struct crypto_tfm *tfm) 830static void crypto_skcipher_exit_tfm(struct crypto_tfm *tfm)
@@ -834,6 +853,9 @@ static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
834 skcipher->ivsize = alg->ivsize; 853 skcipher->ivsize = alg->ivsize;
835 skcipher->keysize = alg->max_keysize; 854 skcipher->keysize = alg->max_keysize;
836 855
856 if (skcipher->keysize)
857 crypto_skcipher_set_flags(skcipher, CRYPTO_TFM_NEED_KEY);
858
837 if (alg->exit) 859 if (alg->exit)
838 skcipher->base.exit = crypto_skcipher_exit_tfm; 860 skcipher->base.exit = crypto_skcipher_exit_tfm;
839 861