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