18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * xfrm algorithm interface
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <crypto/hash.h>
98c2ecf20Sopenharmony_ci#include <crypto/skcipher.h>
108c2ecf20Sopenharmony_ci#include <linux/module.h>
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/pfkeyv2.h>
138c2ecf20Sopenharmony_ci#include <linux/crypto.h>
148c2ecf20Sopenharmony_ci#include <linux/scatterlist.h>
158c2ecf20Sopenharmony_ci#include <net/xfrm.h>
168c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INET_ESP) || IS_ENABLED(CONFIG_INET6_ESP)
178c2ecf20Sopenharmony_ci#include <net/esp.h>
188c2ecf20Sopenharmony_ci#endif
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/*
218c2ecf20Sopenharmony_ci * Algorithms supported by IPsec.  These entries contain properties which
228c2ecf20Sopenharmony_ci * are used in key negotiation and xfrm processing, and are used to verify
238c2ecf20Sopenharmony_ci * that instantiated crypto transforms have correct parameters for IPsec
248c2ecf20Sopenharmony_ci * purposes.
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_cistatic struct xfrm_algo_desc aead_list[] = {
278c2ecf20Sopenharmony_ci{
288c2ecf20Sopenharmony_ci	.name = "rfc4106(gcm(aes))",
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	.uinfo = {
318c2ecf20Sopenharmony_ci		.aead = {
328c2ecf20Sopenharmony_ci			.geniv = "seqiv",
338c2ecf20Sopenharmony_ci			.icv_truncbits = 64,
348c2ecf20Sopenharmony_ci		}
358c2ecf20Sopenharmony_ci	},
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	.desc = {
408c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
418c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
428c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
438c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
448c2ecf20Sopenharmony_ci	}
458c2ecf20Sopenharmony_ci},
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	.name = "rfc4106(gcm(aes))",
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	.uinfo = {
508c2ecf20Sopenharmony_ci		.aead = {
518c2ecf20Sopenharmony_ci			.geniv = "seqiv",
528c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
538c2ecf20Sopenharmony_ci		}
548c2ecf20Sopenharmony_ci	},
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	.desc = {
598c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
608c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
618c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
628c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
638c2ecf20Sopenharmony_ci	}
648c2ecf20Sopenharmony_ci},
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	.name = "rfc4106(gcm(aes))",
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	.uinfo = {
698c2ecf20Sopenharmony_ci		.aead = {
708c2ecf20Sopenharmony_ci			.geniv = "seqiv",
718c2ecf20Sopenharmony_ci			.icv_truncbits = 128,
728c2ecf20Sopenharmony_ci		}
738c2ecf20Sopenharmony_ci	},
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	.desc = {
788c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
798c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
808c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
818c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
828c2ecf20Sopenharmony_ci	}
838c2ecf20Sopenharmony_ci},
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	.name = "rfc4309(ccm(aes))",
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	.uinfo = {
888c2ecf20Sopenharmony_ci		.aead = {
898c2ecf20Sopenharmony_ci			.geniv = "seqiv",
908c2ecf20Sopenharmony_ci			.icv_truncbits = 64,
918c2ecf20Sopenharmony_ci		}
928c2ecf20Sopenharmony_ci	},
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	.desc = {
978c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
988c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
998c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
1008c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
1018c2ecf20Sopenharmony_ci	}
1028c2ecf20Sopenharmony_ci},
1038c2ecf20Sopenharmony_ci{
1048c2ecf20Sopenharmony_ci	.name = "rfc4309(ccm(aes))",
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	.uinfo = {
1078c2ecf20Sopenharmony_ci		.aead = {
1088c2ecf20Sopenharmony_ci			.geniv = "seqiv",
1098c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
1108c2ecf20Sopenharmony_ci		}
1118c2ecf20Sopenharmony_ci	},
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	.desc = {
1168c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
1178c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
1188c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
1198c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
1208c2ecf20Sopenharmony_ci	}
1218c2ecf20Sopenharmony_ci},
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	.name = "rfc4309(ccm(aes))",
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	.uinfo = {
1268c2ecf20Sopenharmony_ci		.aead = {
1278c2ecf20Sopenharmony_ci			.geniv = "seqiv",
1288c2ecf20Sopenharmony_ci			.icv_truncbits = 128,
1298c2ecf20Sopenharmony_ci		}
1308c2ecf20Sopenharmony_ci	},
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	.desc = {
1358c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
1368c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
1378c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
1388c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
1398c2ecf20Sopenharmony_ci	}
1408c2ecf20Sopenharmony_ci},
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci	.name = "rfc4543(gcm(aes))",
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	.uinfo = {
1458c2ecf20Sopenharmony_ci		.aead = {
1468c2ecf20Sopenharmony_ci			.geniv = "seqiv",
1478c2ecf20Sopenharmony_ci			.icv_truncbits = 128,
1488c2ecf20Sopenharmony_ci		}
1498c2ecf20Sopenharmony_ci	},
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	.desc = {
1548c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
1558c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
1568c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
1578c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
1588c2ecf20Sopenharmony_ci	}
1598c2ecf20Sopenharmony_ci},
1608c2ecf20Sopenharmony_ci{
1618c2ecf20Sopenharmony_ci	.name = "rfc7539esp(chacha20,poly1305)",
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	.uinfo = {
1648c2ecf20Sopenharmony_ci		.aead = {
1658c2ecf20Sopenharmony_ci			.geniv = "seqiv",
1668c2ecf20Sopenharmony_ci			.icv_truncbits = 128,
1678c2ecf20Sopenharmony_ci		}
1688c2ecf20Sopenharmony_ci	},
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	.pfkey_supported = 0,
1718c2ecf20Sopenharmony_ci},
1728c2ecf20Sopenharmony_ci};
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cistatic struct xfrm_algo_desc aalg_list[] = {
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	.name = "digest_null",
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	.uinfo = {
1798c2ecf20Sopenharmony_ci		.auth = {
1808c2ecf20Sopenharmony_ci			.icv_truncbits = 0,
1818c2ecf20Sopenharmony_ci			.icv_fullbits = 0,
1828c2ecf20Sopenharmony_ci		}
1838c2ecf20Sopenharmony_ci	},
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	.desc = {
1888c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_AALG_NULL,
1898c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
1908c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 0,
1918c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 0
1928c2ecf20Sopenharmony_ci	}
1938c2ecf20Sopenharmony_ci},
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	.name = "hmac(md5)",
1968c2ecf20Sopenharmony_ci	.compat = "md5",
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	.uinfo = {
1998c2ecf20Sopenharmony_ci		.auth = {
2008c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
2018c2ecf20Sopenharmony_ci			.icv_fullbits = 128,
2028c2ecf20Sopenharmony_ci		}
2038c2ecf20Sopenharmony_ci	},
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	.desc = {
2088c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_AALG_MD5HMAC,
2098c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
2108c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
2118c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 128
2128c2ecf20Sopenharmony_ci	}
2138c2ecf20Sopenharmony_ci},
2148c2ecf20Sopenharmony_ci{
2158c2ecf20Sopenharmony_ci	.name = "hmac(sha1)",
2168c2ecf20Sopenharmony_ci	.compat = "sha1",
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	.uinfo = {
2198c2ecf20Sopenharmony_ci		.auth = {
2208c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
2218c2ecf20Sopenharmony_ci			.icv_fullbits = 160,
2228c2ecf20Sopenharmony_ci		}
2238c2ecf20Sopenharmony_ci	},
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	.desc = {
2288c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_AALG_SHA1HMAC,
2298c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
2308c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 160,
2318c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 160
2328c2ecf20Sopenharmony_ci	}
2338c2ecf20Sopenharmony_ci},
2348c2ecf20Sopenharmony_ci{
2358c2ecf20Sopenharmony_ci	.name = "hmac(sha256)",
2368c2ecf20Sopenharmony_ci	.compat = "sha256",
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	.uinfo = {
2398c2ecf20Sopenharmony_ci		.auth = {
2408c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
2418c2ecf20Sopenharmony_ci			.icv_fullbits = 256,
2428c2ecf20Sopenharmony_ci		}
2438c2ecf20Sopenharmony_ci	},
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	.desc = {
2488c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
2498c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
2508c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 256,
2518c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
2528c2ecf20Sopenharmony_ci	}
2538c2ecf20Sopenharmony_ci},
2548c2ecf20Sopenharmony_ci{
2558c2ecf20Sopenharmony_ci	.name = "hmac(sha384)",
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci	.uinfo = {
2588c2ecf20Sopenharmony_ci		.auth = {
2598c2ecf20Sopenharmony_ci			.icv_truncbits = 192,
2608c2ecf20Sopenharmony_ci			.icv_fullbits = 384,
2618c2ecf20Sopenharmony_ci		}
2628c2ecf20Sopenharmony_ci	},
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	.desc = {
2678c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
2688c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
2698c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 384,
2708c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 384
2718c2ecf20Sopenharmony_ci	}
2728c2ecf20Sopenharmony_ci},
2738c2ecf20Sopenharmony_ci{
2748c2ecf20Sopenharmony_ci	.name = "hmac(sha512)",
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	.uinfo = {
2778c2ecf20Sopenharmony_ci		.auth = {
2788c2ecf20Sopenharmony_ci			.icv_truncbits = 256,
2798c2ecf20Sopenharmony_ci			.icv_fullbits = 512,
2808c2ecf20Sopenharmony_ci		}
2818c2ecf20Sopenharmony_ci	},
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci	.desc = {
2868c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
2878c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
2888c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 512,
2898c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 512
2908c2ecf20Sopenharmony_ci	}
2918c2ecf20Sopenharmony_ci},
2928c2ecf20Sopenharmony_ci{
2938c2ecf20Sopenharmony_ci	.name = "hmac(rmd160)",
2948c2ecf20Sopenharmony_ci	.compat = "rmd160",
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	.uinfo = {
2978c2ecf20Sopenharmony_ci		.auth = {
2988c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
2998c2ecf20Sopenharmony_ci			.icv_fullbits = 160,
3008c2ecf20Sopenharmony_ci		}
3018c2ecf20Sopenharmony_ci	},
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	.desc = {
3068c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
3078c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
3088c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 160,
3098c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 160
3108c2ecf20Sopenharmony_ci	}
3118c2ecf20Sopenharmony_ci},
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci	.name = "xcbc(aes)",
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	.uinfo = {
3168c2ecf20Sopenharmony_ci		.auth = {
3178c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
3188c2ecf20Sopenharmony_ci			.icv_fullbits = 128,
3198c2ecf20Sopenharmony_ci		}
3208c2ecf20Sopenharmony_ci	},
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	.desc = {
3258c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
3268c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
3278c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
3288c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 128
3298c2ecf20Sopenharmony_ci	}
3308c2ecf20Sopenharmony_ci},
3318c2ecf20Sopenharmony_ci{
3328c2ecf20Sopenharmony_ci	/* rfc4494 */
3338c2ecf20Sopenharmony_ci	.name = "cmac(aes)",
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	.uinfo = {
3368c2ecf20Sopenharmony_ci		.auth = {
3378c2ecf20Sopenharmony_ci			.icv_truncbits = 96,
3388c2ecf20Sopenharmony_ci			.icv_fullbits = 128,
3398c2ecf20Sopenharmony_ci		}
3408c2ecf20Sopenharmony_ci	},
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	.pfkey_supported = 0,
3438c2ecf20Sopenharmony_ci},
3448c2ecf20Sopenharmony_ci};
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_cistatic struct xfrm_algo_desc ealg_list[] = {
3478c2ecf20Sopenharmony_ci{
3488c2ecf20Sopenharmony_ci	.name = "ecb(cipher_null)",
3498c2ecf20Sopenharmony_ci	.compat = "cipher_null",
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci	.uinfo = {
3528c2ecf20Sopenharmony_ci		.encr = {
3538c2ecf20Sopenharmony_ci			.blockbits = 8,
3548c2ecf20Sopenharmony_ci			.defkeybits = 0,
3558c2ecf20Sopenharmony_ci		}
3568c2ecf20Sopenharmony_ci	},
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	.desc = {
3618c2ecf20Sopenharmony_ci		.sadb_alg_id =	SADB_EALG_NULL,
3628c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 0,
3638c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 0,
3648c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 0
3658c2ecf20Sopenharmony_ci	}
3668c2ecf20Sopenharmony_ci},
3678c2ecf20Sopenharmony_ci{
3688c2ecf20Sopenharmony_ci	.name = "cbc(des)",
3698c2ecf20Sopenharmony_ci	.compat = "des",
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci	.uinfo = {
3728c2ecf20Sopenharmony_ci		.encr = {
3738c2ecf20Sopenharmony_ci			.geniv = "echainiv",
3748c2ecf20Sopenharmony_ci			.blockbits = 64,
3758c2ecf20Sopenharmony_ci			.defkeybits = 64,
3768c2ecf20Sopenharmony_ci		}
3778c2ecf20Sopenharmony_ci	},
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci	.desc = {
3828c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_EALG_DESCBC,
3838c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
3848c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 64,
3858c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 64
3868c2ecf20Sopenharmony_ci	}
3878c2ecf20Sopenharmony_ci},
3888c2ecf20Sopenharmony_ci{
3898c2ecf20Sopenharmony_ci	.name = "cbc(des3_ede)",
3908c2ecf20Sopenharmony_ci	.compat = "des3_ede",
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	.uinfo = {
3938c2ecf20Sopenharmony_ci		.encr = {
3948c2ecf20Sopenharmony_ci			.geniv = "echainiv",
3958c2ecf20Sopenharmony_ci			.blockbits = 64,
3968c2ecf20Sopenharmony_ci			.defkeybits = 192,
3978c2ecf20Sopenharmony_ci		}
3988c2ecf20Sopenharmony_ci	},
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	.desc = {
4038c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_EALG_3DESCBC,
4048c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
4058c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 192,
4068c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 192
4078c2ecf20Sopenharmony_ci	}
4088c2ecf20Sopenharmony_ci},
4098c2ecf20Sopenharmony_ci{
4108c2ecf20Sopenharmony_ci	.name = "cbc(cast5)",
4118c2ecf20Sopenharmony_ci	.compat = "cast5",
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci	.uinfo = {
4148c2ecf20Sopenharmony_ci		.encr = {
4158c2ecf20Sopenharmony_ci			.geniv = "echainiv",
4168c2ecf20Sopenharmony_ci			.blockbits = 64,
4178c2ecf20Sopenharmony_ci			.defkeybits = 128,
4188c2ecf20Sopenharmony_ci		}
4198c2ecf20Sopenharmony_ci	},
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci	.desc = {
4248c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_CASTCBC,
4258c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
4268c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 40,
4278c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 128
4288c2ecf20Sopenharmony_ci	}
4298c2ecf20Sopenharmony_ci},
4308c2ecf20Sopenharmony_ci{
4318c2ecf20Sopenharmony_ci	.name = "cbc(blowfish)",
4328c2ecf20Sopenharmony_ci	.compat = "blowfish",
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	.uinfo = {
4358c2ecf20Sopenharmony_ci		.encr = {
4368c2ecf20Sopenharmony_ci			.geniv = "echainiv",
4378c2ecf20Sopenharmony_ci			.blockbits = 64,
4388c2ecf20Sopenharmony_ci			.defkeybits = 128,
4398c2ecf20Sopenharmony_ci		}
4408c2ecf20Sopenharmony_ci	},
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	.desc = {
4458c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
4468c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
4478c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 40,
4488c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 448
4498c2ecf20Sopenharmony_ci	}
4508c2ecf20Sopenharmony_ci},
4518c2ecf20Sopenharmony_ci{
4528c2ecf20Sopenharmony_ci	.name = "cbc(aes)",
4538c2ecf20Sopenharmony_ci	.compat = "aes",
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci	.uinfo = {
4568c2ecf20Sopenharmony_ci		.encr = {
4578c2ecf20Sopenharmony_ci			.geniv = "echainiv",
4588c2ecf20Sopenharmony_ci			.blockbits = 128,
4598c2ecf20Sopenharmony_ci			.defkeybits = 128,
4608c2ecf20Sopenharmony_ci		}
4618c2ecf20Sopenharmony_ci	},
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	.desc = {
4668c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AESCBC,
4678c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
4688c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
4698c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
4708c2ecf20Sopenharmony_ci	}
4718c2ecf20Sopenharmony_ci},
4728c2ecf20Sopenharmony_ci{
4738c2ecf20Sopenharmony_ci	.name = "cbc(serpent)",
4748c2ecf20Sopenharmony_ci	.compat = "serpent",
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	.uinfo = {
4778c2ecf20Sopenharmony_ci		.encr = {
4788c2ecf20Sopenharmony_ci			.geniv = "echainiv",
4798c2ecf20Sopenharmony_ci			.blockbits = 128,
4808c2ecf20Sopenharmony_ci			.defkeybits = 128,
4818c2ecf20Sopenharmony_ci		}
4828c2ecf20Sopenharmony_ci	},
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	.desc = {
4878c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_SERPENTCBC,
4888c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
4898c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
4908c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256,
4918c2ecf20Sopenharmony_ci	}
4928c2ecf20Sopenharmony_ci},
4938c2ecf20Sopenharmony_ci{
4948c2ecf20Sopenharmony_ci	.name = "cbc(camellia)",
4958c2ecf20Sopenharmony_ci	.compat = "camellia",
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_ci	.uinfo = {
4988c2ecf20Sopenharmony_ci		.encr = {
4998c2ecf20Sopenharmony_ci			.geniv = "echainiv",
5008c2ecf20Sopenharmony_ci			.blockbits = 128,
5018c2ecf20Sopenharmony_ci			.defkeybits = 128,
5028c2ecf20Sopenharmony_ci		}
5038c2ecf20Sopenharmony_ci	},
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
5068c2ecf20Sopenharmony_ci
5078c2ecf20Sopenharmony_ci	.desc = {
5088c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
5098c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
5108c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
5118c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
5128c2ecf20Sopenharmony_ci	}
5138c2ecf20Sopenharmony_ci},
5148c2ecf20Sopenharmony_ci{
5158c2ecf20Sopenharmony_ci	.name = "cbc(twofish)",
5168c2ecf20Sopenharmony_ci	.compat = "twofish",
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_ci	.uinfo = {
5198c2ecf20Sopenharmony_ci		.encr = {
5208c2ecf20Sopenharmony_ci			.geniv = "echainiv",
5218c2ecf20Sopenharmony_ci			.blockbits = 128,
5228c2ecf20Sopenharmony_ci			.defkeybits = 128,
5238c2ecf20Sopenharmony_ci		}
5248c2ecf20Sopenharmony_ci	},
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci	.desc = {
5298c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
5308c2ecf20Sopenharmony_ci		.sadb_alg_ivlen = 8,
5318c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 128,
5328c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 256
5338c2ecf20Sopenharmony_ci	}
5348c2ecf20Sopenharmony_ci},
5358c2ecf20Sopenharmony_ci{
5368c2ecf20Sopenharmony_ci	.name = "rfc3686(ctr(aes))",
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	.uinfo = {
5398c2ecf20Sopenharmony_ci		.encr = {
5408c2ecf20Sopenharmony_ci			.geniv = "seqiv",
5418c2ecf20Sopenharmony_ci			.blockbits = 128,
5428c2ecf20Sopenharmony_ci			.defkeybits = 160, /* 128-bit key + 32-bit nonce */
5438c2ecf20Sopenharmony_ci		}
5448c2ecf20Sopenharmony_ci	},
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci	.desc = {
5498c2ecf20Sopenharmony_ci		.sadb_alg_id = SADB_X_EALG_AESCTR,
5508c2ecf20Sopenharmony_ci		.sadb_alg_ivlen	= 8,
5518c2ecf20Sopenharmony_ci		.sadb_alg_minbits = 160,
5528c2ecf20Sopenharmony_ci		.sadb_alg_maxbits = 288
5538c2ecf20Sopenharmony_ci	}
5548c2ecf20Sopenharmony_ci},
5558c2ecf20Sopenharmony_ci};
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_cistatic struct xfrm_algo_desc calg_list[] = {
5588c2ecf20Sopenharmony_ci{
5598c2ecf20Sopenharmony_ci	.name = "deflate",
5608c2ecf20Sopenharmony_ci	.uinfo = {
5618c2ecf20Sopenharmony_ci		.comp = {
5628c2ecf20Sopenharmony_ci			.threshold = 90,
5638c2ecf20Sopenharmony_ci		}
5648c2ecf20Sopenharmony_ci	},
5658c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
5668c2ecf20Sopenharmony_ci	.desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
5678c2ecf20Sopenharmony_ci},
5688c2ecf20Sopenharmony_ci{
5698c2ecf20Sopenharmony_ci	.name = "lzs",
5708c2ecf20Sopenharmony_ci	.uinfo = {
5718c2ecf20Sopenharmony_ci		.comp = {
5728c2ecf20Sopenharmony_ci			.threshold = 90,
5738c2ecf20Sopenharmony_ci		}
5748c2ecf20Sopenharmony_ci	},
5758c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
5768c2ecf20Sopenharmony_ci	.desc = { .sadb_alg_id = SADB_X_CALG_LZS }
5778c2ecf20Sopenharmony_ci},
5788c2ecf20Sopenharmony_ci{
5798c2ecf20Sopenharmony_ci	.name = "lzjh",
5808c2ecf20Sopenharmony_ci	.uinfo = {
5818c2ecf20Sopenharmony_ci		.comp = {
5828c2ecf20Sopenharmony_ci			.threshold = 50,
5838c2ecf20Sopenharmony_ci		}
5848c2ecf20Sopenharmony_ci	},
5858c2ecf20Sopenharmony_ci	.pfkey_supported = 1,
5868c2ecf20Sopenharmony_ci	.desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
5878c2ecf20Sopenharmony_ci},
5888c2ecf20Sopenharmony_ci};
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_cistatic inline int aalg_entries(void)
5918c2ecf20Sopenharmony_ci{
5928c2ecf20Sopenharmony_ci	return ARRAY_SIZE(aalg_list);
5938c2ecf20Sopenharmony_ci}
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_cistatic inline int ealg_entries(void)
5968c2ecf20Sopenharmony_ci{
5978c2ecf20Sopenharmony_ci	return ARRAY_SIZE(ealg_list);
5988c2ecf20Sopenharmony_ci}
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_cistatic inline int calg_entries(void)
6018c2ecf20Sopenharmony_ci{
6028c2ecf20Sopenharmony_ci	return ARRAY_SIZE(calg_list);
6038c2ecf20Sopenharmony_ci}
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_cistruct xfrm_algo_list {
6068c2ecf20Sopenharmony_ci	struct xfrm_algo_desc *algs;
6078c2ecf20Sopenharmony_ci	int entries;
6088c2ecf20Sopenharmony_ci	u32 type;
6098c2ecf20Sopenharmony_ci	u32 mask;
6108c2ecf20Sopenharmony_ci};
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_cistatic const struct xfrm_algo_list xfrm_aead_list = {
6138c2ecf20Sopenharmony_ci	.algs = aead_list,
6148c2ecf20Sopenharmony_ci	.entries = ARRAY_SIZE(aead_list),
6158c2ecf20Sopenharmony_ci	.type = CRYPTO_ALG_TYPE_AEAD,
6168c2ecf20Sopenharmony_ci	.mask = CRYPTO_ALG_TYPE_MASK,
6178c2ecf20Sopenharmony_ci};
6188c2ecf20Sopenharmony_ci
6198c2ecf20Sopenharmony_cistatic const struct xfrm_algo_list xfrm_aalg_list = {
6208c2ecf20Sopenharmony_ci	.algs = aalg_list,
6218c2ecf20Sopenharmony_ci	.entries = ARRAY_SIZE(aalg_list),
6228c2ecf20Sopenharmony_ci	.type = CRYPTO_ALG_TYPE_HASH,
6238c2ecf20Sopenharmony_ci	.mask = CRYPTO_ALG_TYPE_HASH_MASK,
6248c2ecf20Sopenharmony_ci};
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_cistatic const struct xfrm_algo_list xfrm_ealg_list = {
6278c2ecf20Sopenharmony_ci	.algs = ealg_list,
6288c2ecf20Sopenharmony_ci	.entries = ARRAY_SIZE(ealg_list),
6298c2ecf20Sopenharmony_ci	.type = CRYPTO_ALG_TYPE_SKCIPHER,
6308c2ecf20Sopenharmony_ci	.mask = CRYPTO_ALG_TYPE_MASK,
6318c2ecf20Sopenharmony_ci};
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_cistatic const struct xfrm_algo_list xfrm_calg_list = {
6348c2ecf20Sopenharmony_ci	.algs = calg_list,
6358c2ecf20Sopenharmony_ci	.entries = ARRAY_SIZE(calg_list),
6368c2ecf20Sopenharmony_ci	.type = CRYPTO_ALG_TYPE_COMPRESS,
6378c2ecf20Sopenharmony_ci	.mask = CRYPTO_ALG_TYPE_MASK,
6388c2ecf20Sopenharmony_ci};
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_cistatic struct xfrm_algo_desc *xfrm_find_algo(
6418c2ecf20Sopenharmony_ci	const struct xfrm_algo_list *algo_list,
6428c2ecf20Sopenharmony_ci	int match(const struct xfrm_algo_desc *entry, const void *data),
6438c2ecf20Sopenharmony_ci	const void *data, int probe)
6448c2ecf20Sopenharmony_ci{
6458c2ecf20Sopenharmony_ci	struct xfrm_algo_desc *list = algo_list->algs;
6468c2ecf20Sopenharmony_ci	int i, status;
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	for (i = 0; i < algo_list->entries; i++) {
6498c2ecf20Sopenharmony_ci		if (!match(list + i, data))
6508c2ecf20Sopenharmony_ci			continue;
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci		if (list[i].available)
6538c2ecf20Sopenharmony_ci			return &list[i];
6548c2ecf20Sopenharmony_ci
6558c2ecf20Sopenharmony_ci		if (!probe)
6568c2ecf20Sopenharmony_ci			break;
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_ci		status = crypto_has_alg(list[i].name, algo_list->type,
6598c2ecf20Sopenharmony_ci					algo_list->mask);
6608c2ecf20Sopenharmony_ci		if (!status)
6618c2ecf20Sopenharmony_ci			break;
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci		list[i].available = status;
6648c2ecf20Sopenharmony_ci		return &list[i];
6658c2ecf20Sopenharmony_ci	}
6668c2ecf20Sopenharmony_ci	return NULL;
6678c2ecf20Sopenharmony_ci}
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_cistatic int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
6708c2ecf20Sopenharmony_ci			     const void *data)
6718c2ecf20Sopenharmony_ci{
6728c2ecf20Sopenharmony_ci	return entry->desc.sadb_alg_id == (unsigned long)data;
6738c2ecf20Sopenharmony_ci}
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
6768c2ecf20Sopenharmony_ci{
6778c2ecf20Sopenharmony_ci	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
6788c2ecf20Sopenharmony_ci			      (void *)(unsigned long)alg_id, 1);
6798c2ecf20Sopenharmony_ci}
6808c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
6838c2ecf20Sopenharmony_ci{
6848c2ecf20Sopenharmony_ci	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
6858c2ecf20Sopenharmony_ci			      (void *)(unsigned long)alg_id, 1);
6868c2ecf20Sopenharmony_ci}
6878c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
6908c2ecf20Sopenharmony_ci{
6918c2ecf20Sopenharmony_ci	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
6928c2ecf20Sopenharmony_ci			      (void *)(unsigned long)alg_id, 1);
6938c2ecf20Sopenharmony_ci}
6948c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_cistatic int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
6978c2ecf20Sopenharmony_ci			       const void *data)
6988c2ecf20Sopenharmony_ci{
6998c2ecf20Sopenharmony_ci	const char *name = data;
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_ci	return name && (!strcmp(name, entry->name) ||
7028c2ecf20Sopenharmony_ci			(entry->compat && !strcmp(name, entry->compat)));
7038c2ecf20Sopenharmony_ci}
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
7068c2ecf20Sopenharmony_ci{
7078c2ecf20Sopenharmony_ci	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
7088c2ecf20Sopenharmony_ci			      probe);
7098c2ecf20Sopenharmony_ci}
7108c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
7138c2ecf20Sopenharmony_ci{
7148c2ecf20Sopenharmony_ci	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
7158c2ecf20Sopenharmony_ci			      probe);
7168c2ecf20Sopenharmony_ci}
7178c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
7208c2ecf20Sopenharmony_ci{
7218c2ecf20Sopenharmony_ci	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
7228c2ecf20Sopenharmony_ci			      probe);
7238c2ecf20Sopenharmony_ci}
7248c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_cistruct xfrm_aead_name {
7278c2ecf20Sopenharmony_ci	const char *name;
7288c2ecf20Sopenharmony_ci	int icvbits;
7298c2ecf20Sopenharmony_ci};
7308c2ecf20Sopenharmony_ci
7318c2ecf20Sopenharmony_cistatic int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
7328c2ecf20Sopenharmony_ci				const void *data)
7338c2ecf20Sopenharmony_ci{
7348c2ecf20Sopenharmony_ci	const struct xfrm_aead_name *aead = data;
7358c2ecf20Sopenharmony_ci	const char *name = aead->name;
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci	return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
7388c2ecf20Sopenharmony_ci	       !strcmp(name, entry->name);
7398c2ecf20Sopenharmony_ci}
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
7428c2ecf20Sopenharmony_ci{
7438c2ecf20Sopenharmony_ci	struct xfrm_aead_name data = {
7448c2ecf20Sopenharmony_ci		.name = name,
7458c2ecf20Sopenharmony_ci		.icvbits = icv_len,
7468c2ecf20Sopenharmony_ci	};
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_ci	return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
7498c2ecf20Sopenharmony_ci			      probe);
7508c2ecf20Sopenharmony_ci}
7518c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
7548c2ecf20Sopenharmony_ci{
7558c2ecf20Sopenharmony_ci	if (idx >= aalg_entries())
7568c2ecf20Sopenharmony_ci		return NULL;
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci	return &aalg_list[idx];
7598c2ecf20Sopenharmony_ci}
7608c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_cistruct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
7638c2ecf20Sopenharmony_ci{
7648c2ecf20Sopenharmony_ci	if (idx >= ealg_entries())
7658c2ecf20Sopenharmony_ci		return NULL;
7668c2ecf20Sopenharmony_ci
7678c2ecf20Sopenharmony_ci	return &ealg_list[idx];
7688c2ecf20Sopenharmony_ci}
7698c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
7708c2ecf20Sopenharmony_ci
7718c2ecf20Sopenharmony_ci/*
7728c2ecf20Sopenharmony_ci * Probe for the availability of crypto algorithms, and set the available
7738c2ecf20Sopenharmony_ci * flag for any algorithms found on the system.  This is typically called by
7748c2ecf20Sopenharmony_ci * pfkey during userspace SA add, update or register.
7758c2ecf20Sopenharmony_ci */
7768c2ecf20Sopenharmony_civoid xfrm_probe_algs(void)
7778c2ecf20Sopenharmony_ci{
7788c2ecf20Sopenharmony_ci	int i, status;
7798c2ecf20Sopenharmony_ci
7808c2ecf20Sopenharmony_ci	BUG_ON(in_softirq());
7818c2ecf20Sopenharmony_ci
7828c2ecf20Sopenharmony_ci	for (i = 0; i < aalg_entries(); i++) {
7838c2ecf20Sopenharmony_ci		status = crypto_has_ahash(aalg_list[i].name, 0, 0);
7848c2ecf20Sopenharmony_ci		if (aalg_list[i].available != status)
7858c2ecf20Sopenharmony_ci			aalg_list[i].available = status;
7868c2ecf20Sopenharmony_ci	}
7878c2ecf20Sopenharmony_ci
7888c2ecf20Sopenharmony_ci	for (i = 0; i < ealg_entries(); i++) {
7898c2ecf20Sopenharmony_ci		status = crypto_has_skcipher(ealg_list[i].name, 0, 0);
7908c2ecf20Sopenharmony_ci		if (ealg_list[i].available != status)
7918c2ecf20Sopenharmony_ci			ealg_list[i].available = status;
7928c2ecf20Sopenharmony_ci	}
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_ci	for (i = 0; i < calg_entries(); i++) {
7958c2ecf20Sopenharmony_ci		status = crypto_has_comp(calg_list[i].name, 0,
7968c2ecf20Sopenharmony_ci					 CRYPTO_ALG_ASYNC);
7978c2ecf20Sopenharmony_ci		if (calg_list[i].available != status)
7988c2ecf20Sopenharmony_ci			calg_list[i].available = status;
7998c2ecf20Sopenharmony_ci	}
8008c2ecf20Sopenharmony_ci}
8018c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_probe_algs);
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_ciint xfrm_count_pfkey_auth_supported(void)
8048c2ecf20Sopenharmony_ci{
8058c2ecf20Sopenharmony_ci	int i, n;
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_ci	for (i = 0, n = 0; i < aalg_entries(); i++)
8088c2ecf20Sopenharmony_ci		if (aalg_list[i].available && aalg_list[i].pfkey_supported)
8098c2ecf20Sopenharmony_ci			n++;
8108c2ecf20Sopenharmony_ci	return n;
8118c2ecf20Sopenharmony_ci}
8128c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
8138c2ecf20Sopenharmony_ci
8148c2ecf20Sopenharmony_ciint xfrm_count_pfkey_enc_supported(void)
8158c2ecf20Sopenharmony_ci{
8168c2ecf20Sopenharmony_ci	int i, n;
8178c2ecf20Sopenharmony_ci
8188c2ecf20Sopenharmony_ci	for (i = 0, n = 0; i < ealg_entries(); i++)
8198c2ecf20Sopenharmony_ci		if (ealg_list[i].available && ealg_list[i].pfkey_supported)
8208c2ecf20Sopenharmony_ci			n++;
8218c2ecf20Sopenharmony_ci	return n;
8228c2ecf20Sopenharmony_ci}
8238c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
826