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