1 /* 2 * Crypto user configuration API. 3 * 4 * Copyright (C) 2011 secunet Security Networks AG 5 * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms and conditions of the GNU General Public License, 9 * version 2, as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #include <linux/module.h> 22 #include <linux/crypto.h> 23 #include <linux/cryptouser.h> 24 #include <linux/sched.h> 25 #include <net/netlink.h> 26 #include <linux/security.h> 27 #include <net/net_namespace.h> 28 #include <crypto/internal/aead.h> 29 #include <crypto/internal/skcipher.h> 30 #include <crypto/internal/rng.h> 31 #include <crypto/akcipher.h> 32 33 #include "internal.h" 34 35 #define null_terminated(x) (strnlen(x, sizeof(x)) < sizeof(x)) 36 37 static DEFINE_MUTEX(crypto_cfg_mutex); 38 39 /* The crypto netlink socket */ 40 static struct sock *crypto_nlsk; 41 42 struct crypto_dump_info { 43 struct sk_buff *in_skb; 44 struct sk_buff *out_skb; 45 u32 nlmsg_seq; 46 u16 nlmsg_flags; 47 }; 48 49 static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact) 50 { 51 struct crypto_alg *q, *alg = NULL; 52 53 down_read(&crypto_alg_sem); 54 55 list_for_each_entry(q, &crypto_alg_list, cra_list) { 56 int match = 0; 57 58 if ((q->cra_flags ^ p->cru_type) & p->cru_mask) 59 continue; 60 61 if (strlen(p->cru_driver_name)) 62 match = !strcmp(q->cra_driver_name, 63 p->cru_driver_name); 64 else if (!exact) 65 match = !strcmp(q->cra_name, p->cru_name); 66 67 if (!match) 68 continue; 69 70 if (unlikely(!crypto_mod_get(q))) 71 continue; 72 73 alg = q; 74 break; 75 } 76 77 up_read(&crypto_alg_sem); 78 79 return alg; 80 } 81 82 static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) 83 { 84 struct crypto_report_cipher rcipher; 85 86 strncpy(rcipher.type, "cipher", sizeof(rcipher.type)); 87 88 rcipher.blocksize = alg->cra_blocksize; 89 rcipher.min_keysize = alg->cra_cipher.cia_min_keysize; 90 rcipher.max_keysize = alg->cra_cipher.cia_max_keysize; 91 92 if (nla_put(skb, CRYPTOCFGA_REPORT_CIPHER, 93 sizeof(struct crypto_report_cipher), &rcipher)) 94 goto nla_put_failure; 95 return 0; 96 97 nla_put_failure: 98 return -EMSGSIZE; 99 } 100 101 static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg) 102 { 103 struct crypto_report_comp rcomp; 104 105 strncpy(rcomp.type, "compression", sizeof(rcomp.type)); 106 if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS, 107 sizeof(struct crypto_report_comp), &rcomp)) 108 goto nla_put_failure; 109 return 0; 110 111 nla_put_failure: 112 return -EMSGSIZE; 113 } 114 115 static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg) 116 { 117 struct crypto_report_akcipher rakcipher; 118 119 strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type)); 120 121 if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER, 122 sizeof(struct crypto_report_akcipher), &rakcipher)) 123 goto nla_put_failure; 124 return 0; 125 126 nla_put_failure: 127 return -EMSGSIZE; 128 } 129 130 static int crypto_report_one(struct crypto_alg *alg, 131 struct crypto_user_alg *ualg, struct sk_buff *skb) 132 { 133 strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name)); 134 strncpy(ualg->cru_driver_name, alg->cra_driver_name, 135 sizeof(ualg->cru_driver_name)); 136 strncpy(ualg->cru_module_name, module_name(alg->cra_module), 137 sizeof(ualg->cru_module_name)); 138 139 ualg->cru_type = 0; 140 ualg->cru_mask = 0; 141 ualg->cru_flags = alg->cra_flags; 142 ualg->cru_refcnt = atomic_read(&alg->cra_refcnt); 143 144 if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority)) 145 goto nla_put_failure; 146 if (alg->cra_flags & CRYPTO_ALG_LARVAL) { 147 struct crypto_report_larval rl; 148 149 strncpy(rl.type, "larval", sizeof(rl.type)); 150 if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL, 151 sizeof(struct crypto_report_larval), &rl)) 152 goto nla_put_failure; 153 goto out; 154 } 155 156 if (alg->cra_type && alg->cra_type->report) { 157 if (alg->cra_type->report(skb, alg)) 158 goto nla_put_failure; 159 160 goto out; 161 } 162 163 switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) { 164 case CRYPTO_ALG_TYPE_CIPHER: 165 if (crypto_report_cipher(skb, alg)) 166 goto nla_put_failure; 167 168 break; 169 case CRYPTO_ALG_TYPE_COMPRESS: 170 if (crypto_report_comp(skb, alg)) 171 goto nla_put_failure; 172 173 break; 174 175 case CRYPTO_ALG_TYPE_AKCIPHER: 176 if (crypto_report_akcipher(skb, alg)) 177 goto nla_put_failure; 178 179 break; 180 } 181 182 out: 183 return 0; 184 185 nla_put_failure: 186 return -EMSGSIZE; 187 } 188 189 static int crypto_report_alg(struct crypto_alg *alg, 190 struct crypto_dump_info *info) 191 { 192 struct sk_buff *in_skb = info->in_skb; 193 struct sk_buff *skb = info->out_skb; 194 struct nlmsghdr *nlh; 195 struct crypto_user_alg *ualg; 196 int err = 0; 197 198 nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, info->nlmsg_seq, 199 CRYPTO_MSG_GETALG, sizeof(*ualg), info->nlmsg_flags); 200 if (!nlh) { 201 err = -EMSGSIZE; 202 goto out; 203 } 204 205 ualg = nlmsg_data(nlh); 206 207 err = crypto_report_one(alg, ualg, skb); 208 if (err) { 209 nlmsg_cancel(skb, nlh); 210 goto out; 211 } 212 213 nlmsg_end(skb, nlh); 214 215 out: 216 return err; 217 } 218 219 static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, 220 struct nlattr **attrs) 221 { 222 struct crypto_user_alg *p = nlmsg_data(in_nlh); 223 struct crypto_alg *alg; 224 struct sk_buff *skb; 225 struct crypto_dump_info info; 226 int err; 227 228 if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 229 return -EINVAL; 230 231 alg = crypto_alg_match(p, 0); 232 if (!alg) 233 return -ENOENT; 234 235 err = -ENOMEM; 236 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 237 if (!skb) 238 goto drop_alg; 239 240 info.in_skb = in_skb; 241 info.out_skb = skb; 242 info.nlmsg_seq = in_nlh->nlmsg_seq; 243 info.nlmsg_flags = 0; 244 245 err = crypto_report_alg(alg, &info); 246 247 drop_alg: 248 crypto_mod_put(alg); 249 250 if (err) 251 return err; 252 253 return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid); 254 } 255 256 static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb) 257 { 258 struct crypto_alg *alg; 259 struct crypto_dump_info info; 260 int err; 261 262 if (cb->args[0]) 263 goto out; 264 265 cb->args[0] = 1; 266 267 info.in_skb = cb->skb; 268 info.out_skb = skb; 269 info.nlmsg_seq = cb->nlh->nlmsg_seq; 270 info.nlmsg_flags = NLM_F_MULTI; 271 272 list_for_each_entry(alg, &crypto_alg_list, cra_list) { 273 err = crypto_report_alg(alg, &info); 274 if (err) 275 goto out_err; 276 } 277 278 out: 279 return skb->len; 280 out_err: 281 return err; 282 } 283 284 static int crypto_dump_report_done(struct netlink_callback *cb) 285 { 286 return 0; 287 } 288 289 static int crypto_update_alg(struct sk_buff *skb, struct nlmsghdr *nlh, 290 struct nlattr **attrs) 291 { 292 struct crypto_alg *alg; 293 struct crypto_user_alg *p = nlmsg_data(nlh); 294 struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL]; 295 LIST_HEAD(list); 296 297 if (!netlink_capable(skb, CAP_NET_ADMIN)) 298 return -EPERM; 299 300 if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 301 return -EINVAL; 302 303 if (priority && !strlen(p->cru_driver_name)) 304 return -EINVAL; 305 306 alg = crypto_alg_match(p, 1); 307 if (!alg) 308 return -ENOENT; 309 310 down_write(&crypto_alg_sem); 311 312 crypto_remove_spawns(alg, &list, NULL); 313 314 if (priority) 315 alg->cra_priority = nla_get_u32(priority); 316 317 up_write(&crypto_alg_sem); 318 319 crypto_mod_put(alg); 320 crypto_remove_final(&list); 321 322 return 0; 323 } 324 325 static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, 326 struct nlattr **attrs) 327 { 328 struct crypto_alg *alg; 329 struct crypto_user_alg *p = nlmsg_data(nlh); 330 int err; 331 332 if (!netlink_capable(skb, CAP_NET_ADMIN)) 333 return -EPERM; 334 335 if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 336 return -EINVAL; 337 338 alg = crypto_alg_match(p, 1); 339 if (!alg) 340 return -ENOENT; 341 342 /* We can not unregister core algorithms such as aes-generic. 343 * We would loose the reference in the crypto_alg_list to this algorithm 344 * if we try to unregister. Unregistering such an algorithm without 345 * removing the module is not possible, so we restrict to crypto 346 * instances that are build from templates. */ 347 err = -EINVAL; 348 if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE)) 349 goto drop_alg; 350 351 err = -EBUSY; 352 if (atomic_read(&alg->cra_refcnt) > 2) 353 goto drop_alg; 354 355 err = crypto_unregister_instance((struct crypto_instance *)alg); 356 357 drop_alg: 358 crypto_mod_put(alg); 359 return err; 360 } 361 362 static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type, 363 u32 mask) 364 { 365 int err; 366 struct crypto_alg *alg; 367 368 type = crypto_skcipher_type(type); 369 mask = crypto_skcipher_mask(mask); 370 371 for (;;) { 372 alg = crypto_lookup_skcipher(name, type, mask); 373 if (!IS_ERR(alg)) 374 return alg; 375 376 err = PTR_ERR(alg); 377 if (err != -EAGAIN) 378 break; 379 if (signal_pending(current)) { 380 err = -EINTR; 381 break; 382 } 383 } 384 385 return ERR_PTR(err); 386 } 387 388 static struct crypto_alg *crypto_user_aead_alg(const char *name, u32 type, 389 u32 mask) 390 { 391 int err; 392 struct crypto_alg *alg; 393 394 type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 395 type |= CRYPTO_ALG_TYPE_AEAD; 396 mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 397 mask |= CRYPTO_ALG_TYPE_MASK; 398 399 for (;;) { 400 alg = crypto_lookup_aead(name, type, mask); 401 if (!IS_ERR(alg)) 402 return alg; 403 404 err = PTR_ERR(alg); 405 if (err != -EAGAIN) 406 break; 407 if (signal_pending(current)) { 408 err = -EINTR; 409 break; 410 } 411 } 412 413 return ERR_PTR(err); 414 } 415 416 static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, 417 struct nlattr **attrs) 418 { 419 int exact = 0; 420 const char *name; 421 struct crypto_alg *alg; 422 struct crypto_user_alg *p = nlmsg_data(nlh); 423 struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL]; 424 425 if (!netlink_capable(skb, CAP_NET_ADMIN)) 426 return -EPERM; 427 428 if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 429 return -EINVAL; 430 431 if (strlen(p->cru_driver_name)) 432 exact = 1; 433 434 if (priority && !exact) 435 return -EINVAL; 436 437 alg = crypto_alg_match(p, exact); 438 if (alg) { 439 crypto_mod_put(alg); 440 return -EEXIST; 441 } 442 443 if (strlen(p->cru_driver_name)) 444 name = p->cru_driver_name; 445 else 446 name = p->cru_name; 447 448 switch (p->cru_type & p->cru_mask & CRYPTO_ALG_TYPE_MASK) { 449 case CRYPTO_ALG_TYPE_AEAD: 450 alg = crypto_user_aead_alg(name, p->cru_type, p->cru_mask); 451 break; 452 case CRYPTO_ALG_TYPE_GIVCIPHER: 453 case CRYPTO_ALG_TYPE_BLKCIPHER: 454 case CRYPTO_ALG_TYPE_ABLKCIPHER: 455 alg = crypto_user_skcipher_alg(name, p->cru_type, p->cru_mask); 456 break; 457 default: 458 alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); 459 } 460 461 if (IS_ERR(alg)) 462 return PTR_ERR(alg); 463 464 down_write(&crypto_alg_sem); 465 466 if (priority) 467 alg->cra_priority = nla_get_u32(priority); 468 469 up_write(&crypto_alg_sem); 470 471 crypto_mod_put(alg); 472 473 return 0; 474 } 475 476 static int crypto_del_rng(struct sk_buff *skb, struct nlmsghdr *nlh, 477 struct nlattr **attrs) 478 { 479 if (!netlink_capable(skb, CAP_NET_ADMIN)) 480 return -EPERM; 481 return crypto_del_default_rng(); 482 } 483 484 #define MSGSIZE(type) sizeof(struct type) 485 486 static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = { 487 [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 488 [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 489 [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), 490 [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = 0, 491 }; 492 493 static const struct nla_policy crypto_policy[CRYPTOCFGA_MAX+1] = { 494 [CRYPTOCFGA_PRIORITY_VAL] = { .type = NLA_U32}, 495 }; 496 497 #undef MSGSIZE 498 499 static const struct crypto_link { 500 int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); 501 int (*dump)(struct sk_buff *, struct netlink_callback *); 502 int (*done)(struct netlink_callback *); 503 } crypto_dispatch[CRYPTO_NR_MSGTYPES] = { 504 [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = { .doit = crypto_add_alg}, 505 [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = { .doit = crypto_del_alg}, 506 [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = { .doit = crypto_update_alg}, 507 [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = { .doit = crypto_report, 508 .dump = crypto_dump_report, 509 .done = crypto_dump_report_done}, 510 [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng }, 511 }; 512 513 static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 514 { 515 struct nlattr *attrs[CRYPTOCFGA_MAX+1]; 516 const struct crypto_link *link; 517 int type, err; 518 519 type = nlh->nlmsg_type; 520 if (type > CRYPTO_MSG_MAX) 521 return -EINVAL; 522 523 type -= CRYPTO_MSG_BASE; 524 link = &crypto_dispatch[type]; 525 526 if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && 527 (nlh->nlmsg_flags & NLM_F_DUMP))) { 528 struct crypto_alg *alg; 529 u16 dump_alloc = 0; 530 531 if (link->dump == NULL) 532 return -EINVAL; 533 534 list_for_each_entry(alg, &crypto_alg_list, cra_list) 535 dump_alloc += CRYPTO_REPORT_MAXSIZE; 536 537 { 538 struct netlink_dump_control c = { 539 .dump = link->dump, 540 .done = link->done, 541 .min_dump_alloc = dump_alloc, 542 }; 543 return netlink_dump_start(crypto_nlsk, skb, nlh, &c); 544 } 545 } 546 547 err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX, 548 crypto_policy); 549 if (err < 0) 550 return err; 551 552 if (link->doit == NULL) 553 return -EINVAL; 554 555 return link->doit(skb, nlh, attrs); 556 } 557 558 static void crypto_netlink_rcv(struct sk_buff *skb) 559 { 560 mutex_lock(&crypto_cfg_mutex); 561 netlink_rcv_skb(skb, &crypto_user_rcv_msg); 562 mutex_unlock(&crypto_cfg_mutex); 563 } 564 565 static int __init crypto_user_init(void) 566 { 567 struct netlink_kernel_cfg cfg = { 568 .input = crypto_netlink_rcv, 569 }; 570 571 crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg); 572 if (!crypto_nlsk) 573 return -ENOMEM; 574 575 return 0; 576 } 577 578 static void __exit crypto_user_exit(void) 579 { 580 netlink_kernel_release(crypto_nlsk); 581 } 582 583 module_init(crypto_user_init); 584 module_exit(crypto_user_exit); 585 MODULE_LICENSE("GPL"); 586 MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>"); 587 MODULE_DESCRIPTION("Crypto userspace configuration API"); 588 MODULE_ALIAS("net-pf-16-proto-21"); 589