aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/crypto_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/crypto_user.c')
-rw-r--r--crypto/crypto_user.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f76e42bcc6e7..f1ea0a064135 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -21,9 +21,13 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/crypto.h> 22#include <linux/crypto.h>
23#include <linux/cryptouser.h> 23#include <linux/cryptouser.h>
24#include <linux/sched.h>
24#include <net/netlink.h> 25#include <net/netlink.h>
25#include <linux/security.h> 26#include <linux/security.h>
26#include <net/net_namespace.h> 27#include <net/net_namespace.h>
28#include <crypto/internal/aead.h>
29#include <crypto/internal/skcipher.h>
30
27#include "internal.h" 31#include "internal.h"
28 32
29DEFINE_MUTEX(crypto_cfg_mutex); 33DEFINE_MUTEX(crypto_cfg_mutex);
@@ -301,6 +305,60 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
301 return crypto_unregister_instance(alg); 305 return crypto_unregister_instance(alg);
302} 306}
303 307
308static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type,
309 u32 mask)
310{
311 int err;
312 struct crypto_alg *alg;
313
314 type = crypto_skcipher_type(type);
315 mask = crypto_skcipher_mask(mask);
316
317 for (;;) {
318 alg = crypto_lookup_skcipher(name, type, mask);
319 if (!IS_ERR(alg))
320 return alg;
321
322 err = PTR_ERR(alg);
323 if (err != -EAGAIN)
324 break;
325 if (signal_pending(current)) {
326 err = -EINTR;
327 break;
328 }
329 }
330
331 return ERR_PTR(err);
332}
333
334static struct crypto_alg *crypto_user_aead_alg(const char *name, u32 type,
335 u32 mask)
336{
337 int err;
338 struct crypto_alg *alg;
339
340 type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
341 type |= CRYPTO_ALG_TYPE_AEAD;
342 mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV);
343 mask |= CRYPTO_ALG_TYPE_MASK;
344
345 for (;;) {
346 alg = crypto_lookup_aead(name, type, mask);
347 if (!IS_ERR(alg))
348 return alg;
349
350 err = PTR_ERR(alg);
351 if (err != -EAGAIN)
352 break;
353 if (signal_pending(current)) {
354 err = -EINTR;
355 break;
356 }
357 }
358
359 return ERR_PTR(err);
360}
361
304static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, 362static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
305 struct nlattr **attrs) 363 struct nlattr **attrs)
306{ 364{
@@ -325,7 +383,19 @@ static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
325 else 383 else
326 name = p->cru_name; 384 name = p->cru_name;
327 385
328 alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); 386 switch (p->cru_type & p->cru_mask & CRYPTO_ALG_TYPE_MASK) {
387 case CRYPTO_ALG_TYPE_AEAD:
388 alg = crypto_user_aead_alg(name, p->cru_type, p->cru_mask);
389 break;
390 case CRYPTO_ALG_TYPE_GIVCIPHER:
391 case CRYPTO_ALG_TYPE_BLKCIPHER:
392 case CRYPTO_ALG_TYPE_ABLKCIPHER:
393 alg = crypto_user_skcipher_alg(name, p->cru_type, p->cru_mask);
394 break;
395 default:
396 alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask);
397 }
398
329 if (IS_ERR(alg)) 399 if (IS_ERR(alg))
330 return PTR_ERR(alg); 400 return PTR_ERR(alg);
331 401
@@ -387,12 +457,20 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
387 457
388 if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && 458 if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
389 (nlh->nlmsg_flags & NLM_F_DUMP))) { 459 (nlh->nlmsg_flags & NLM_F_DUMP))) {
460 struct crypto_alg *alg;
461 u16 dump_alloc = 0;
462
390 if (link->dump == NULL) 463 if (link->dump == NULL)
391 return -EINVAL; 464 return -EINVAL;
465
466 list_for_each_entry(alg, &crypto_alg_list, cra_list)
467 dump_alloc += CRYPTO_REPORT_MAXSIZE;
468
392 { 469 {
393 struct netlink_dump_control c = { 470 struct netlink_dump_control c = {
394 .dump = link->dump, 471 .dump = link->dump,
395 .done = link->done, 472 .done = link->done,
473 .min_dump_alloc = dump_alloc,
396 }; 474 };
397 return netlink_dump_start(crypto_nlsk, skb, nlh, &c); 475 return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
398 } 476 }