1 /* 2 * xfrm algorithm interface 3 * 4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/pfkeyv2.h> 15 #include <linux/crypto.h> 16 #include <linux/scatterlist.h> 17 #include <net/xfrm.h> 18 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) 19 #include <net/esp.h> 20 #endif 21 22 /* 23 * Algorithms supported by IPsec. These entries contain properties which 24 * are used in key negotiation and xfrm processing, and are used to verify 25 * that instantiated crypto transforms have correct parameters for IPsec 26 * purposes. 27 */ 28 static struct xfrm_algo_desc aead_list[] = { 29 { 30 .name = "rfc4106(gcm(aes))", 31 32 .uinfo = { 33 .aead = { 34 .geniv = "seqniv", 35 .icv_truncbits = 64, 36 } 37 }, 38 39 .pfkey_supported = 1, 40 41 .desc = { 42 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8, 43 .sadb_alg_ivlen = 8, 44 .sadb_alg_minbits = 128, 45 .sadb_alg_maxbits = 256 46 } 47 }, 48 { 49 .name = "rfc4106(gcm(aes))", 50 51 .uinfo = { 52 .aead = { 53 .geniv = "seqniv", 54 .icv_truncbits = 96, 55 } 56 }, 57 58 .pfkey_supported = 1, 59 60 .desc = { 61 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12, 62 .sadb_alg_ivlen = 8, 63 .sadb_alg_minbits = 128, 64 .sadb_alg_maxbits = 256 65 } 66 }, 67 { 68 .name = "rfc4106(gcm(aes))", 69 70 .uinfo = { 71 .aead = { 72 .geniv = "seqniv", 73 .icv_truncbits = 128, 74 } 75 }, 76 77 .pfkey_supported = 1, 78 79 .desc = { 80 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16, 81 .sadb_alg_ivlen = 8, 82 .sadb_alg_minbits = 128, 83 .sadb_alg_maxbits = 256 84 } 85 }, 86 { 87 .name = "rfc4309(ccm(aes))", 88 89 .uinfo = { 90 .aead = { 91 .geniv = "seqniv", 92 .icv_truncbits = 64, 93 } 94 }, 95 96 .pfkey_supported = 1, 97 98 .desc = { 99 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8, 100 .sadb_alg_ivlen = 8, 101 .sadb_alg_minbits = 128, 102 .sadb_alg_maxbits = 256 103 } 104 }, 105 { 106 .name = "rfc4309(ccm(aes))", 107 108 .uinfo = { 109 .aead = { 110 .geniv = "seqniv", 111 .icv_truncbits = 96, 112 } 113 }, 114 115 .pfkey_supported = 1, 116 117 .desc = { 118 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12, 119 .sadb_alg_ivlen = 8, 120 .sadb_alg_minbits = 128, 121 .sadb_alg_maxbits = 256 122 } 123 }, 124 { 125 .name = "rfc4309(ccm(aes))", 126 127 .uinfo = { 128 .aead = { 129 .geniv = "seqniv", 130 .icv_truncbits = 128, 131 } 132 }, 133 134 .pfkey_supported = 1, 135 136 .desc = { 137 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16, 138 .sadb_alg_ivlen = 8, 139 .sadb_alg_minbits = 128, 140 .sadb_alg_maxbits = 256 141 } 142 }, 143 { 144 .name = "rfc4543(gcm(aes))", 145 146 .uinfo = { 147 .aead = { 148 .geniv = "seqiv", 149 .icv_truncbits = 128, 150 } 151 }, 152 153 .pfkey_supported = 1, 154 155 .desc = { 156 .sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC, 157 .sadb_alg_ivlen = 8, 158 .sadb_alg_minbits = 128, 159 .sadb_alg_maxbits = 256 160 } 161 }, 162 { 163 .name = "rfc7539esp(chacha20,poly1305)", 164 165 .uinfo = { 166 .aead = { 167 .geniv = "seqniv", 168 .icv_truncbits = 128, 169 } 170 }, 171 172 .pfkey_supported = 0, 173 }, 174 }; 175 176 static struct xfrm_algo_desc aalg_list[] = { 177 { 178 .name = "digest_null", 179 180 .uinfo = { 181 .auth = { 182 .icv_truncbits = 0, 183 .icv_fullbits = 0, 184 } 185 }, 186 187 .pfkey_supported = 1, 188 189 .desc = { 190 .sadb_alg_id = SADB_X_AALG_NULL, 191 .sadb_alg_ivlen = 0, 192 .sadb_alg_minbits = 0, 193 .sadb_alg_maxbits = 0 194 } 195 }, 196 { 197 .name = "hmac(md5)", 198 .compat = "md5", 199 200 .uinfo = { 201 .auth = { 202 .icv_truncbits = 96, 203 .icv_fullbits = 128, 204 } 205 }, 206 207 .pfkey_supported = 1, 208 209 .desc = { 210 .sadb_alg_id = SADB_AALG_MD5HMAC, 211 .sadb_alg_ivlen = 0, 212 .sadb_alg_minbits = 128, 213 .sadb_alg_maxbits = 128 214 } 215 }, 216 { 217 .name = "hmac(sha1)", 218 .compat = "sha1", 219 220 .uinfo = { 221 .auth = { 222 .icv_truncbits = 96, 223 .icv_fullbits = 160, 224 } 225 }, 226 227 .pfkey_supported = 1, 228 229 .desc = { 230 .sadb_alg_id = SADB_AALG_SHA1HMAC, 231 .sadb_alg_ivlen = 0, 232 .sadb_alg_minbits = 160, 233 .sadb_alg_maxbits = 160 234 } 235 }, 236 { 237 .name = "hmac(sha256)", 238 .compat = "sha256", 239 240 .uinfo = { 241 .auth = { 242 .icv_truncbits = 96, 243 .icv_fullbits = 256, 244 } 245 }, 246 247 .pfkey_supported = 1, 248 249 .desc = { 250 .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC, 251 .sadb_alg_ivlen = 0, 252 .sadb_alg_minbits = 256, 253 .sadb_alg_maxbits = 256 254 } 255 }, 256 { 257 .name = "hmac(sha384)", 258 259 .uinfo = { 260 .auth = { 261 .icv_truncbits = 192, 262 .icv_fullbits = 384, 263 } 264 }, 265 266 .pfkey_supported = 1, 267 268 .desc = { 269 .sadb_alg_id = SADB_X_AALG_SHA2_384HMAC, 270 .sadb_alg_ivlen = 0, 271 .sadb_alg_minbits = 384, 272 .sadb_alg_maxbits = 384 273 } 274 }, 275 { 276 .name = "hmac(sha512)", 277 278 .uinfo = { 279 .auth = { 280 .icv_truncbits = 256, 281 .icv_fullbits = 512, 282 } 283 }, 284 285 .pfkey_supported = 1, 286 287 .desc = { 288 .sadb_alg_id = SADB_X_AALG_SHA2_512HMAC, 289 .sadb_alg_ivlen = 0, 290 .sadb_alg_minbits = 512, 291 .sadb_alg_maxbits = 512 292 } 293 }, 294 { 295 .name = "hmac(rmd160)", 296 .compat = "rmd160", 297 298 .uinfo = { 299 .auth = { 300 .icv_truncbits = 96, 301 .icv_fullbits = 160, 302 } 303 }, 304 305 .pfkey_supported = 1, 306 307 .desc = { 308 .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC, 309 .sadb_alg_ivlen = 0, 310 .sadb_alg_minbits = 160, 311 .sadb_alg_maxbits = 160 312 } 313 }, 314 { 315 .name = "xcbc(aes)", 316 317 .uinfo = { 318 .auth = { 319 .icv_truncbits = 96, 320 .icv_fullbits = 128, 321 } 322 }, 323 324 .pfkey_supported = 1, 325 326 .desc = { 327 .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC, 328 .sadb_alg_ivlen = 0, 329 .sadb_alg_minbits = 128, 330 .sadb_alg_maxbits = 128 331 } 332 }, 333 { 334 /* rfc4494 */ 335 .name = "cmac(aes)", 336 337 .uinfo = { 338 .auth = { 339 .icv_truncbits = 96, 340 .icv_fullbits = 128, 341 } 342 }, 343 344 .pfkey_supported = 0, 345 }, 346 }; 347 348 static struct xfrm_algo_desc ealg_list[] = { 349 { 350 .name = "ecb(cipher_null)", 351 .compat = "cipher_null", 352 353 .uinfo = { 354 .encr = { 355 .blockbits = 8, 356 .defkeybits = 0, 357 } 358 }, 359 360 .pfkey_supported = 1, 361 362 .desc = { 363 .sadb_alg_id = SADB_EALG_NULL, 364 .sadb_alg_ivlen = 0, 365 .sadb_alg_minbits = 0, 366 .sadb_alg_maxbits = 0 367 } 368 }, 369 { 370 .name = "cbc(des)", 371 .compat = "des", 372 373 .uinfo = { 374 .encr = { 375 .geniv = "echainiv", 376 .blockbits = 64, 377 .defkeybits = 64, 378 } 379 }, 380 381 .pfkey_supported = 1, 382 383 .desc = { 384 .sadb_alg_id = SADB_EALG_DESCBC, 385 .sadb_alg_ivlen = 8, 386 .sadb_alg_minbits = 64, 387 .sadb_alg_maxbits = 64 388 } 389 }, 390 { 391 .name = "cbc(des3_ede)", 392 .compat = "des3_ede", 393 394 .uinfo = { 395 .encr = { 396 .geniv = "echainiv", 397 .blockbits = 64, 398 .defkeybits = 192, 399 } 400 }, 401 402 .pfkey_supported = 1, 403 404 .desc = { 405 .sadb_alg_id = SADB_EALG_3DESCBC, 406 .sadb_alg_ivlen = 8, 407 .sadb_alg_minbits = 192, 408 .sadb_alg_maxbits = 192 409 } 410 }, 411 { 412 .name = "cbc(cast5)", 413 .compat = "cast5", 414 415 .uinfo = { 416 .encr = { 417 .geniv = "echainiv", 418 .blockbits = 64, 419 .defkeybits = 128, 420 } 421 }, 422 423 .pfkey_supported = 1, 424 425 .desc = { 426 .sadb_alg_id = SADB_X_EALG_CASTCBC, 427 .sadb_alg_ivlen = 8, 428 .sadb_alg_minbits = 40, 429 .sadb_alg_maxbits = 128 430 } 431 }, 432 { 433 .name = "cbc(blowfish)", 434 .compat = "blowfish", 435 436 .uinfo = { 437 .encr = { 438 .geniv = "echainiv", 439 .blockbits = 64, 440 .defkeybits = 128, 441 } 442 }, 443 444 .pfkey_supported = 1, 445 446 .desc = { 447 .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC, 448 .sadb_alg_ivlen = 8, 449 .sadb_alg_minbits = 40, 450 .sadb_alg_maxbits = 448 451 } 452 }, 453 { 454 .name = "cbc(aes)", 455 .compat = "aes", 456 457 .uinfo = { 458 .encr = { 459 .geniv = "echainiv", 460 .blockbits = 128, 461 .defkeybits = 128, 462 } 463 }, 464 465 .pfkey_supported = 1, 466 467 .desc = { 468 .sadb_alg_id = SADB_X_EALG_AESCBC, 469 .sadb_alg_ivlen = 8, 470 .sadb_alg_minbits = 128, 471 .sadb_alg_maxbits = 256 472 } 473 }, 474 { 475 .name = "cbc(serpent)", 476 .compat = "serpent", 477 478 .uinfo = { 479 .encr = { 480 .geniv = "echainiv", 481 .blockbits = 128, 482 .defkeybits = 128, 483 } 484 }, 485 486 .pfkey_supported = 1, 487 488 .desc = { 489 .sadb_alg_id = SADB_X_EALG_SERPENTCBC, 490 .sadb_alg_ivlen = 8, 491 .sadb_alg_minbits = 128, 492 .sadb_alg_maxbits = 256, 493 } 494 }, 495 { 496 .name = "cbc(camellia)", 497 .compat = "camellia", 498 499 .uinfo = { 500 .encr = { 501 .geniv = "echainiv", 502 .blockbits = 128, 503 .defkeybits = 128, 504 } 505 }, 506 507 .pfkey_supported = 1, 508 509 .desc = { 510 .sadb_alg_id = SADB_X_EALG_CAMELLIACBC, 511 .sadb_alg_ivlen = 8, 512 .sadb_alg_minbits = 128, 513 .sadb_alg_maxbits = 256 514 } 515 }, 516 { 517 .name = "cbc(twofish)", 518 .compat = "twofish", 519 520 .uinfo = { 521 .encr = { 522 .geniv = "echainiv", 523 .blockbits = 128, 524 .defkeybits = 128, 525 } 526 }, 527 528 .pfkey_supported = 1, 529 530 .desc = { 531 .sadb_alg_id = SADB_X_EALG_TWOFISHCBC, 532 .sadb_alg_ivlen = 8, 533 .sadb_alg_minbits = 128, 534 .sadb_alg_maxbits = 256 535 } 536 }, 537 { 538 .name = "rfc3686(ctr(aes))", 539 540 .uinfo = { 541 .encr = { 542 .geniv = "seqiv", 543 .blockbits = 128, 544 .defkeybits = 160, /* 128-bit key + 32-bit nonce */ 545 } 546 }, 547 548 .pfkey_supported = 1, 549 550 .desc = { 551 .sadb_alg_id = SADB_X_EALG_AESCTR, 552 .sadb_alg_ivlen = 8, 553 .sadb_alg_minbits = 160, 554 .sadb_alg_maxbits = 288 555 } 556 }, 557 }; 558 559 static struct xfrm_algo_desc calg_list[] = { 560 { 561 .name = "deflate", 562 .uinfo = { 563 .comp = { 564 .threshold = 90, 565 } 566 }, 567 .pfkey_supported = 1, 568 .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE } 569 }, 570 { 571 .name = "lzs", 572 .uinfo = { 573 .comp = { 574 .threshold = 90, 575 } 576 }, 577 .pfkey_supported = 1, 578 .desc = { .sadb_alg_id = SADB_X_CALG_LZS } 579 }, 580 { 581 .name = "lzjh", 582 .uinfo = { 583 .comp = { 584 .threshold = 50, 585 } 586 }, 587 .pfkey_supported = 1, 588 .desc = { .sadb_alg_id = SADB_X_CALG_LZJH } 589 }, 590 }; 591 592 static inline int aalg_entries(void) 593 { 594 return ARRAY_SIZE(aalg_list); 595 } 596 597 static inline int ealg_entries(void) 598 { 599 return ARRAY_SIZE(ealg_list); 600 } 601 602 static inline int calg_entries(void) 603 { 604 return ARRAY_SIZE(calg_list); 605 } 606 607 struct xfrm_algo_list { 608 struct xfrm_algo_desc *algs; 609 int entries; 610 u32 type; 611 u32 mask; 612 }; 613 614 static const struct xfrm_algo_list xfrm_aead_list = { 615 .algs = aead_list, 616 .entries = ARRAY_SIZE(aead_list), 617 .type = CRYPTO_ALG_TYPE_AEAD, 618 .mask = CRYPTO_ALG_TYPE_MASK, 619 }; 620 621 static const struct xfrm_algo_list xfrm_aalg_list = { 622 .algs = aalg_list, 623 .entries = ARRAY_SIZE(aalg_list), 624 .type = CRYPTO_ALG_TYPE_HASH, 625 .mask = CRYPTO_ALG_TYPE_HASH_MASK, 626 }; 627 628 static const struct xfrm_algo_list xfrm_ealg_list = { 629 .algs = ealg_list, 630 .entries = ARRAY_SIZE(ealg_list), 631 .type = CRYPTO_ALG_TYPE_BLKCIPHER, 632 .mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK, 633 }; 634 635 static const struct xfrm_algo_list xfrm_calg_list = { 636 .algs = calg_list, 637 .entries = ARRAY_SIZE(calg_list), 638 .type = CRYPTO_ALG_TYPE_COMPRESS, 639 .mask = CRYPTO_ALG_TYPE_MASK, 640 }; 641 642 static struct xfrm_algo_desc *xfrm_find_algo( 643 const struct xfrm_algo_list *algo_list, 644 int match(const struct xfrm_algo_desc *entry, const void *data), 645 const void *data, int probe) 646 { 647 struct xfrm_algo_desc *list = algo_list->algs; 648 int i, status; 649 650 for (i = 0; i < algo_list->entries; i++) { 651 if (!match(list + i, data)) 652 continue; 653 654 if (list[i].available) 655 return &list[i]; 656 657 if (!probe) 658 break; 659 660 status = crypto_has_alg(list[i].name, algo_list->type, 661 algo_list->mask); 662 if (!status) 663 break; 664 665 list[i].available = status; 666 return &list[i]; 667 } 668 return NULL; 669 } 670 671 static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry, 672 const void *data) 673 { 674 return entry->desc.sadb_alg_id == (unsigned long)data; 675 } 676 677 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) 678 { 679 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match, 680 (void *)(unsigned long)alg_id, 1); 681 } 682 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); 683 684 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) 685 { 686 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match, 687 (void *)(unsigned long)alg_id, 1); 688 } 689 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); 690 691 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) 692 { 693 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match, 694 (void *)(unsigned long)alg_id, 1); 695 } 696 EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); 697 698 static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry, 699 const void *data) 700 { 701 const char *name = data; 702 703 return name && (!strcmp(name, entry->name) || 704 (entry->compat && !strcmp(name, entry->compat))); 705 } 706 707 struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe) 708 { 709 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name, 710 probe); 711 } 712 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); 713 714 struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe) 715 { 716 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name, 717 probe); 718 } 719 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); 720 721 struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe) 722 { 723 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name, 724 probe); 725 } 726 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); 727 728 struct xfrm_aead_name { 729 const char *name; 730 int icvbits; 731 }; 732 733 static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry, 734 const void *data) 735 { 736 const struct xfrm_aead_name *aead = data; 737 const char *name = aead->name; 738 739 return aead->icvbits == entry->uinfo.aead.icv_truncbits && name && 740 !strcmp(name, entry->name); 741 } 742 743 struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe) 744 { 745 struct xfrm_aead_name data = { 746 .name = name, 747 .icvbits = icv_len, 748 }; 749 750 return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data, 751 probe); 752 } 753 EXPORT_SYMBOL_GPL(xfrm_aead_get_byname); 754 755 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx) 756 { 757 if (idx >= aalg_entries()) 758 return NULL; 759 760 return &aalg_list[idx]; 761 } 762 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx); 763 764 struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx) 765 { 766 if (idx >= ealg_entries()) 767 return NULL; 768 769 return &ealg_list[idx]; 770 } 771 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx); 772 773 /* 774 * Probe for the availability of crypto algorithms, and set the available 775 * flag for any algorithms found on the system. This is typically called by 776 * pfkey during userspace SA add, update or register. 777 */ 778 void xfrm_probe_algs(void) 779 { 780 int i, status; 781 782 BUG_ON(in_softirq()); 783 784 for (i = 0; i < aalg_entries(); i++) { 785 status = crypto_has_hash(aalg_list[i].name, 0, 786 CRYPTO_ALG_ASYNC); 787 if (aalg_list[i].available != status) 788 aalg_list[i].available = status; 789 } 790 791 for (i = 0; i < ealg_entries(); i++) { 792 status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0); 793 if (ealg_list[i].available != status) 794 ealg_list[i].available = status; 795 } 796 797 for (i = 0; i < calg_entries(); i++) { 798 status = crypto_has_comp(calg_list[i].name, 0, 799 CRYPTO_ALG_ASYNC); 800 if (calg_list[i].available != status) 801 calg_list[i].available = status; 802 } 803 } 804 EXPORT_SYMBOL_GPL(xfrm_probe_algs); 805 806 int xfrm_count_pfkey_auth_supported(void) 807 { 808 int i, n; 809 810 for (i = 0, n = 0; i < aalg_entries(); i++) 811 if (aalg_list[i].available && aalg_list[i].pfkey_supported) 812 n++; 813 return n; 814 } 815 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported); 816 817 int xfrm_count_pfkey_enc_supported(void) 818 { 819 int i, n; 820 821 for (i = 0, n = 0; i < ealg_entries(); i++) 822 if (ealg_list[i].available && ealg_list[i].pfkey_supported) 823 n++; 824 return n; 825 } 826 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported); 827 828 MODULE_LICENSE("GPL"); 829