xref: /openbmc/linux/net/xfrm/xfrm_algo.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * xfrm algorithm interface
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
817bc1970SHerbert Xu #include <crypto/hash.h>
917bc1970SHerbert Xu #include <crypto/skcipher.h>
101da177e4SLinus Torvalds #include <linux/module.h>
111da177e4SLinus Torvalds #include <linux/kernel.h>
121da177e4SLinus Torvalds #include <linux/pfkeyv2.h>
131da177e4SLinus Torvalds #include <linux/crypto.h>
14b3b724f4SHeiko Carstens #include <linux/scatterlist.h>
151da177e4SLinus Torvalds #include <net/xfrm.h>
1665b323e2SJavier Martinez Canillas #if IS_ENABLED(CONFIG_INET_ESP) || IS_ENABLED(CONFIG_INET6_ESP)
171da177e4SLinus Torvalds #include <net/esp.h>
181da177e4SLinus Torvalds #endif
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds /*
211da177e4SLinus Torvalds  * Algorithms supported by IPsec.  These entries contain properties which
221da177e4SLinus Torvalds  * are used in key negotiation and xfrm processing, and are used to verify
231da177e4SLinus Torvalds  * that instantiated crypto transforms have correct parameters for IPsec
241da177e4SLinus Torvalds  * purposes.
251da177e4SLinus Torvalds  */
261a6509d9SHerbert Xu static struct xfrm_algo_desc aead_list[] = {
271a6509d9SHerbert Xu {
281a6509d9SHerbert Xu 	.name = "rfc4106(gcm(aes))",
291a6509d9SHerbert Xu 
301a6509d9SHerbert Xu 	.uinfo = {
311a6509d9SHerbert Xu 		.aead = {
32de0ded77SHerbert Xu 			.geniv = "seqiv",
331a6509d9SHerbert Xu 			.icv_truncbits = 64,
341a6509d9SHerbert Xu 		}
351a6509d9SHerbert Xu 	},
361a6509d9SHerbert Xu 
377e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
387e50f84cSJussi Kivilinna 
391a6509d9SHerbert Xu 	.desc = {
401a6509d9SHerbert Xu 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
411a6509d9SHerbert Xu 		.sadb_alg_ivlen = 8,
421a6509d9SHerbert Xu 		.sadb_alg_minbits = 128,
431a6509d9SHerbert Xu 		.sadb_alg_maxbits = 256
441a6509d9SHerbert Xu 	}
451a6509d9SHerbert Xu },
461a6509d9SHerbert Xu {
471a6509d9SHerbert Xu 	.name = "rfc4106(gcm(aes))",
481a6509d9SHerbert Xu 
491a6509d9SHerbert Xu 	.uinfo = {
501a6509d9SHerbert Xu 		.aead = {
51de0ded77SHerbert Xu 			.geniv = "seqiv",
521a6509d9SHerbert Xu 			.icv_truncbits = 96,
531a6509d9SHerbert Xu 		}
541a6509d9SHerbert Xu 	},
551a6509d9SHerbert Xu 
567e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
577e50f84cSJussi Kivilinna 
581a6509d9SHerbert Xu 	.desc = {
591a6509d9SHerbert Xu 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
601a6509d9SHerbert Xu 		.sadb_alg_ivlen = 8,
611a6509d9SHerbert Xu 		.sadb_alg_minbits = 128,
621a6509d9SHerbert Xu 		.sadb_alg_maxbits = 256
631a6509d9SHerbert Xu 	}
641a6509d9SHerbert Xu },
651a6509d9SHerbert Xu {
661a6509d9SHerbert Xu 	.name = "rfc4106(gcm(aes))",
671a6509d9SHerbert Xu 
681a6509d9SHerbert Xu 	.uinfo = {
691a6509d9SHerbert Xu 		.aead = {
70de0ded77SHerbert Xu 			.geniv = "seqiv",
711a6509d9SHerbert Xu 			.icv_truncbits = 128,
721a6509d9SHerbert Xu 		}
731a6509d9SHerbert Xu 	},
741a6509d9SHerbert Xu 
757e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
767e50f84cSJussi Kivilinna 
771a6509d9SHerbert Xu 	.desc = {
781a6509d9SHerbert Xu 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
791a6509d9SHerbert Xu 		.sadb_alg_ivlen = 8,
801a6509d9SHerbert Xu 		.sadb_alg_minbits = 128,
811a6509d9SHerbert Xu 		.sadb_alg_maxbits = 256
821a6509d9SHerbert Xu 	}
831a6509d9SHerbert Xu },
841a6509d9SHerbert Xu {
851a6509d9SHerbert Xu 	.name = "rfc4309(ccm(aes))",
861a6509d9SHerbert Xu 
871a6509d9SHerbert Xu 	.uinfo = {
881a6509d9SHerbert Xu 		.aead = {
89de0ded77SHerbert Xu 			.geniv = "seqiv",
901a6509d9SHerbert Xu 			.icv_truncbits = 64,
911a6509d9SHerbert Xu 		}
921a6509d9SHerbert Xu 	},
931a6509d9SHerbert Xu 
947e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
957e50f84cSJussi Kivilinna 
961a6509d9SHerbert Xu 	.desc = {
971a6509d9SHerbert Xu 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
981a6509d9SHerbert Xu 		.sadb_alg_ivlen = 8,
991a6509d9SHerbert Xu 		.sadb_alg_minbits = 128,
1001a6509d9SHerbert Xu 		.sadb_alg_maxbits = 256
1011a6509d9SHerbert Xu 	}
1021a6509d9SHerbert Xu },
1031a6509d9SHerbert Xu {
1041a6509d9SHerbert Xu 	.name = "rfc4309(ccm(aes))",
1051a6509d9SHerbert Xu 
1061a6509d9SHerbert Xu 	.uinfo = {
1071a6509d9SHerbert Xu 		.aead = {
108de0ded77SHerbert Xu 			.geniv = "seqiv",
1091a6509d9SHerbert Xu 			.icv_truncbits = 96,
1101a6509d9SHerbert Xu 		}
1111a6509d9SHerbert Xu 	},
1121a6509d9SHerbert Xu 
1137e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
1147e50f84cSJussi Kivilinna 
1151a6509d9SHerbert Xu 	.desc = {
1161a6509d9SHerbert Xu 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
1171a6509d9SHerbert Xu 		.sadb_alg_ivlen = 8,
1181a6509d9SHerbert Xu 		.sadb_alg_minbits = 128,
1191a6509d9SHerbert Xu 		.sadb_alg_maxbits = 256
1201a6509d9SHerbert Xu 	}
1211a6509d9SHerbert Xu },
1221a6509d9SHerbert Xu {
1231a6509d9SHerbert Xu 	.name = "rfc4309(ccm(aes))",
1241a6509d9SHerbert Xu 
1251a6509d9SHerbert Xu 	.uinfo = {
1261a6509d9SHerbert Xu 		.aead = {
127de0ded77SHerbert Xu 			.geniv = "seqiv",
1281a6509d9SHerbert Xu 			.icv_truncbits = 128,
1291a6509d9SHerbert Xu 		}
1301a6509d9SHerbert Xu 	},
1311a6509d9SHerbert Xu 
1327e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
1337e50f84cSJussi Kivilinna 
1341a6509d9SHerbert Xu 	.desc = {
1351a6509d9SHerbert Xu 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
1361a6509d9SHerbert Xu 		.sadb_alg_ivlen = 8,
1371a6509d9SHerbert Xu 		.sadb_alg_minbits = 128,
1381a6509d9SHerbert Xu 		.sadb_alg_maxbits = 256
1391a6509d9SHerbert Xu 	}
1401a6509d9SHerbert Xu },
14173c89c15STobias Brunner {
14273c89c15STobias Brunner 	.name = "rfc4543(gcm(aes))",
14373c89c15STobias Brunner 
14473c89c15STobias Brunner 	.uinfo = {
14573c89c15STobias Brunner 		.aead = {
146165ecc63SHerbert Xu 			.geniv = "seqiv",
14773c89c15STobias Brunner 			.icv_truncbits = 128,
14873c89c15STobias Brunner 		}
14973c89c15STobias Brunner 	},
15073c89c15STobias Brunner 
1517e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
1527e50f84cSJussi Kivilinna 
15373c89c15STobias Brunner 	.desc = {
15473c89c15STobias Brunner 		.sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
15573c89c15STobias Brunner 		.sadb_alg_ivlen = 8,
15673c89c15STobias Brunner 		.sadb_alg_minbits = 128,
15773c89c15STobias Brunner 		.sadb_alg_maxbits = 256
15873c89c15STobias Brunner 	}
15973c89c15STobias Brunner },
160b08b6b77SMartin Willi {
161b08b6b77SMartin Willi 	.name = "rfc7539esp(chacha20,poly1305)",
162b08b6b77SMartin Willi 
163b08b6b77SMartin Willi 	.uinfo = {
164b08b6b77SMartin Willi 		.aead = {
165de0ded77SHerbert Xu 			.geniv = "seqiv",
166b08b6b77SMartin Willi 			.icv_truncbits = 128,
167b08b6b77SMartin Willi 		}
168b08b6b77SMartin Willi 	},
169b08b6b77SMartin Willi 
170b08b6b77SMartin Willi 	.pfkey_supported = 0,
171b08b6b77SMartin Willi },
1721a6509d9SHerbert Xu };
1731a6509d9SHerbert Xu 
1741da177e4SLinus Torvalds static struct xfrm_algo_desc aalg_list[] = {
1751da177e4SLinus Torvalds {
17601a2202cSHerbert Xu 	.name = "digest_null",
1771da177e4SLinus Torvalds 
1781da177e4SLinus Torvalds 	.uinfo = {
1791da177e4SLinus Torvalds 		.auth = {
1801da177e4SLinus Torvalds 			.icv_truncbits = 0,
1811da177e4SLinus Torvalds 			.icv_fullbits = 0,
1821da177e4SLinus Torvalds 		}
1831da177e4SLinus Torvalds 	},
1841da177e4SLinus Torvalds 
1857e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
1867e50f84cSJussi Kivilinna 
1871da177e4SLinus Torvalds 	.desc = {
1881da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_AALG_NULL,
1891da177e4SLinus Torvalds 		.sadb_alg_ivlen = 0,
1901da177e4SLinus Torvalds 		.sadb_alg_minbits = 0,
1911da177e4SLinus Torvalds 		.sadb_alg_maxbits = 0
1921da177e4SLinus Torvalds 	}
1931da177e4SLinus Torvalds },
1941da177e4SLinus Torvalds {
19507d4ee58SHerbert Xu 	.name = "hmac(md5)",
19607d4ee58SHerbert Xu 	.compat = "md5",
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds 	.uinfo = {
1991da177e4SLinus Torvalds 		.auth = {
2001da177e4SLinus Torvalds 			.icv_truncbits = 96,
2011da177e4SLinus Torvalds 			.icv_fullbits = 128,
2021da177e4SLinus Torvalds 		}
2031da177e4SLinus Torvalds 	},
2041da177e4SLinus Torvalds 
2057e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
2067e50f84cSJussi Kivilinna 
2071da177e4SLinus Torvalds 	.desc = {
2081da177e4SLinus Torvalds 		.sadb_alg_id = SADB_AALG_MD5HMAC,
2091da177e4SLinus Torvalds 		.sadb_alg_ivlen = 0,
2101da177e4SLinus Torvalds 		.sadb_alg_minbits = 128,
2111da177e4SLinus Torvalds 		.sadb_alg_maxbits = 128
2121da177e4SLinus Torvalds 	}
2131da177e4SLinus Torvalds },
2141da177e4SLinus Torvalds {
21507d4ee58SHerbert Xu 	.name = "hmac(sha1)",
21607d4ee58SHerbert Xu 	.compat = "sha1",
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds 	.uinfo = {
2191da177e4SLinus Torvalds 		.auth = {
2201da177e4SLinus Torvalds 			.icv_truncbits = 96,
2211da177e4SLinus Torvalds 			.icv_fullbits = 160,
2221da177e4SLinus Torvalds 		}
2231da177e4SLinus Torvalds 	},
2241da177e4SLinus Torvalds 
2257e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
2267e50f84cSJussi Kivilinna 
2271da177e4SLinus Torvalds 	.desc = {
2281da177e4SLinus Torvalds 		.sadb_alg_id = SADB_AALG_SHA1HMAC,
2291da177e4SLinus Torvalds 		.sadb_alg_ivlen = 0,
2301da177e4SLinus Torvalds 		.sadb_alg_minbits = 160,
2311da177e4SLinus Torvalds 		.sadb_alg_maxbits = 160
2321da177e4SLinus Torvalds 	}
2331da177e4SLinus Torvalds },
2341da177e4SLinus Torvalds {
23507d4ee58SHerbert Xu 	.name = "hmac(sha256)",
23607d4ee58SHerbert Xu 	.compat = "sha256",
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds 	.uinfo = {
2391da177e4SLinus Torvalds 		.auth = {
2401da177e4SLinus Torvalds 			.icv_truncbits = 96,
2411da177e4SLinus Torvalds 			.icv_fullbits = 256,
2421da177e4SLinus Torvalds 		}
2431da177e4SLinus Torvalds 	},
2441da177e4SLinus Torvalds 
2457e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
2467e50f84cSJussi Kivilinna 
2471da177e4SLinus Torvalds 	.desc = {
2481da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
2491da177e4SLinus Torvalds 		.sadb_alg_ivlen = 0,
2501da177e4SLinus Torvalds 		.sadb_alg_minbits = 256,
2511da177e4SLinus Torvalds 		.sadb_alg_maxbits = 256
2521da177e4SLinus Torvalds 	}
2531da177e4SLinus Torvalds },
2541da177e4SLinus Torvalds {
255bc74b0c8SMartin Willi 	.name = "hmac(sha384)",
256bc74b0c8SMartin Willi 
257bc74b0c8SMartin Willi 	.uinfo = {
258bc74b0c8SMartin Willi 		.auth = {
259bc74b0c8SMartin Willi 			.icv_truncbits = 192,
260bc74b0c8SMartin Willi 			.icv_fullbits = 384,
261bc74b0c8SMartin Willi 		}
262bc74b0c8SMartin Willi 	},
263bc74b0c8SMartin Willi 
2647e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
2657e50f84cSJussi Kivilinna 
266bc74b0c8SMartin Willi 	.desc = {
267bc74b0c8SMartin Willi 		.sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
268bc74b0c8SMartin Willi 		.sadb_alg_ivlen = 0,
269bc74b0c8SMartin Willi 		.sadb_alg_minbits = 384,
270bc74b0c8SMartin Willi 		.sadb_alg_maxbits = 384
271bc74b0c8SMartin Willi 	}
272bc74b0c8SMartin Willi },
273bc74b0c8SMartin Willi {
274bc74b0c8SMartin Willi 	.name = "hmac(sha512)",
275bc74b0c8SMartin Willi 
276bc74b0c8SMartin Willi 	.uinfo = {
277bc74b0c8SMartin Willi 		.auth = {
278bc74b0c8SMartin Willi 			.icv_truncbits = 256,
279bc74b0c8SMartin Willi 			.icv_fullbits = 512,
280bc74b0c8SMartin Willi 		}
281bc74b0c8SMartin Willi 	},
282bc74b0c8SMartin Willi 
2837e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
2847e50f84cSJussi Kivilinna 
285bc74b0c8SMartin Willi 	.desc = {
286bc74b0c8SMartin Willi 		.sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
287bc74b0c8SMartin Willi 		.sadb_alg_ivlen = 0,
288bc74b0c8SMartin Willi 		.sadb_alg_minbits = 512,
289bc74b0c8SMartin Willi 		.sadb_alg_maxbits = 512
290bc74b0c8SMartin Willi 	}
291bc74b0c8SMartin Willi },
292bc74b0c8SMartin Willi {
293a13366c6SAdrian-Ken Rueegsegger 	.name = "hmac(rmd160)",
294a13366c6SAdrian-Ken Rueegsegger 	.compat = "rmd160",
2951da177e4SLinus Torvalds 
2961da177e4SLinus Torvalds 	.uinfo = {
2971da177e4SLinus Torvalds 		.auth = {
2981da177e4SLinus Torvalds 			.icv_truncbits = 96,
2991da177e4SLinus Torvalds 			.icv_fullbits = 160,
3001da177e4SLinus Torvalds 		}
3011da177e4SLinus Torvalds 	},
3021da177e4SLinus Torvalds 
3037e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
3047e50f84cSJussi Kivilinna 
3051da177e4SLinus Torvalds 	.desc = {
3061da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
3071da177e4SLinus Torvalds 		.sadb_alg_ivlen = 0,
3081da177e4SLinus Torvalds 		.sadb_alg_minbits = 160,
3091da177e4SLinus Torvalds 		.sadb_alg_maxbits = 160
3101da177e4SLinus Torvalds 	}
3111da177e4SLinus Torvalds },
3127cf4c1a5SKazunori MIYAZAWA {
3137cf4c1a5SKazunori MIYAZAWA 	.name = "xcbc(aes)",
3147cf4c1a5SKazunori MIYAZAWA 
3157cf4c1a5SKazunori MIYAZAWA 	.uinfo = {
3167cf4c1a5SKazunori MIYAZAWA 		.auth = {
3177cf4c1a5SKazunori MIYAZAWA 			.icv_truncbits = 96,
3187cf4c1a5SKazunori MIYAZAWA 			.icv_fullbits = 128,
3197cf4c1a5SKazunori MIYAZAWA 		}
3207cf4c1a5SKazunori MIYAZAWA 	},
3217cf4c1a5SKazunori MIYAZAWA 
3227e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
3237e50f84cSJussi Kivilinna 
3247cf4c1a5SKazunori MIYAZAWA 	.desc = {
3257cf4c1a5SKazunori MIYAZAWA 		.sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
3267cf4c1a5SKazunori MIYAZAWA 		.sadb_alg_ivlen = 0,
3277cf4c1a5SKazunori MIYAZAWA 		.sadb_alg_minbits = 128,
3287cf4c1a5SKazunori MIYAZAWA 		.sadb_alg_maxbits = 128
3297cf4c1a5SKazunori MIYAZAWA 	}
3307cf4c1a5SKazunori MIYAZAWA },
331d2049d85SJussi Kivilinna {
332d2049d85SJussi Kivilinna 	/* rfc4494 */
333d2049d85SJussi Kivilinna 	.name = "cmac(aes)",
334d2049d85SJussi Kivilinna 
335d2049d85SJussi Kivilinna 	.uinfo = {
336d2049d85SJussi Kivilinna 		.auth = {
337d2049d85SJussi Kivilinna 			.icv_truncbits = 96,
338d2049d85SJussi Kivilinna 			.icv_fullbits = 128,
339d2049d85SJussi Kivilinna 		}
340d2049d85SJussi Kivilinna 	},
341d2049d85SJussi Kivilinna 
342d2049d85SJussi Kivilinna 	.pfkey_supported = 0,
343d2049d85SJussi Kivilinna },
344e6911affSXu Jia {
345e6911affSXu Jia 	.name = "hmac(sm3)",
346e6911affSXu Jia 	.compat = "sm3",
347e6911affSXu Jia 
348e6911affSXu Jia 	.uinfo = {
349e6911affSXu Jia 		.auth = {
350e6911affSXu Jia 			.icv_truncbits = 256,
351e6911affSXu Jia 			.icv_fullbits = 256,
352e6911affSXu Jia 		}
353e6911affSXu Jia 	},
354e6911affSXu Jia 
355e6911affSXu Jia 	.pfkey_supported = 1,
356e6911affSXu Jia 
357e6911affSXu Jia 	.desc = {
358e6911affSXu Jia 		.sadb_alg_id = SADB_X_AALG_SM3_256HMAC,
359e6911affSXu Jia 		.sadb_alg_ivlen = 0,
360e6911affSXu Jia 		.sadb_alg_minbits = 256,
361e6911affSXu Jia 		.sadb_alg_maxbits = 256
362e6911affSXu Jia 	}
363e6911affSXu Jia },
3641da177e4SLinus Torvalds };
3651da177e4SLinus Torvalds 
3661da177e4SLinus Torvalds static struct xfrm_algo_desc ealg_list[] = {
3671da177e4SLinus Torvalds {
3686b7326c8SHerbert Xu 	.name = "ecb(cipher_null)",
3696b7326c8SHerbert Xu 	.compat = "cipher_null",
3701da177e4SLinus Torvalds 
3711da177e4SLinus Torvalds 	.uinfo = {
3721da177e4SLinus Torvalds 		.encr = {
3731da177e4SLinus Torvalds 			.blockbits = 8,
3741da177e4SLinus Torvalds 			.defkeybits = 0,
3751da177e4SLinus Torvalds 		}
3761da177e4SLinus Torvalds 	},
3771da177e4SLinus Torvalds 
3787e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
3797e50f84cSJussi Kivilinna 
3801da177e4SLinus Torvalds 	.desc = {
3811da177e4SLinus Torvalds 		.sadb_alg_id =	SADB_EALG_NULL,
3821da177e4SLinus Torvalds 		.sadb_alg_ivlen = 0,
3831da177e4SLinus Torvalds 		.sadb_alg_minbits = 0,
3841da177e4SLinus Torvalds 		.sadb_alg_maxbits = 0
3851da177e4SLinus Torvalds 	}
3861da177e4SLinus Torvalds },
3871da177e4SLinus Torvalds {
3886b7326c8SHerbert Xu 	.name = "cbc(des)",
3896b7326c8SHerbert Xu 	.compat = "des",
3901da177e4SLinus Torvalds 
3911da177e4SLinus Torvalds 	.uinfo = {
3921da177e4SLinus Torvalds 		.encr = {
393165ecc63SHerbert Xu 			.geniv = "echainiv",
3941da177e4SLinus Torvalds 			.blockbits = 64,
3951da177e4SLinus Torvalds 			.defkeybits = 64,
3961da177e4SLinus Torvalds 		}
3971da177e4SLinus Torvalds 	},
3981da177e4SLinus Torvalds 
3997e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
4007e50f84cSJussi Kivilinna 
4011da177e4SLinus Torvalds 	.desc = {
4021da177e4SLinus Torvalds 		.sadb_alg_id = SADB_EALG_DESCBC,
4031da177e4SLinus Torvalds 		.sadb_alg_ivlen = 8,
4041da177e4SLinus Torvalds 		.sadb_alg_minbits = 64,
4051da177e4SLinus Torvalds 		.sadb_alg_maxbits = 64
4061da177e4SLinus Torvalds 	}
4071da177e4SLinus Torvalds },
4081da177e4SLinus Torvalds {
4096b7326c8SHerbert Xu 	.name = "cbc(des3_ede)",
4106b7326c8SHerbert Xu 	.compat = "des3_ede",
4111da177e4SLinus Torvalds 
4121da177e4SLinus Torvalds 	.uinfo = {
4131da177e4SLinus Torvalds 		.encr = {
414165ecc63SHerbert Xu 			.geniv = "echainiv",
4151da177e4SLinus Torvalds 			.blockbits = 64,
4161da177e4SLinus Torvalds 			.defkeybits = 192,
4171da177e4SLinus Torvalds 		}
4181da177e4SLinus Torvalds 	},
4191da177e4SLinus Torvalds 
4207e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
4217e50f84cSJussi Kivilinna 
4221da177e4SLinus Torvalds 	.desc = {
4231da177e4SLinus Torvalds 		.sadb_alg_id = SADB_EALG_3DESCBC,
4241da177e4SLinus Torvalds 		.sadb_alg_ivlen = 8,
4251da177e4SLinus Torvalds 		.sadb_alg_minbits = 192,
4261da177e4SLinus Torvalds 		.sadb_alg_maxbits = 192
4271da177e4SLinus Torvalds 	}
4281da177e4SLinus Torvalds },
4291da177e4SLinus Torvalds {
430245acb87SHerbert Xu 	.name = "cbc(cast5)",
431245acb87SHerbert Xu 	.compat = "cast5",
4321da177e4SLinus Torvalds 
4331da177e4SLinus Torvalds 	.uinfo = {
4341da177e4SLinus Torvalds 		.encr = {
435165ecc63SHerbert Xu 			.geniv = "echainiv",
4361da177e4SLinus Torvalds 			.blockbits = 64,
4371da177e4SLinus Torvalds 			.defkeybits = 128,
4381da177e4SLinus Torvalds 		}
4391da177e4SLinus Torvalds 	},
4401da177e4SLinus Torvalds 
4417e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
4427e50f84cSJussi Kivilinna 
4431da177e4SLinus Torvalds 	.desc = {
4441da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_EALG_CASTCBC,
4451da177e4SLinus Torvalds 		.sadb_alg_ivlen = 8,
4461da177e4SLinus Torvalds 		.sadb_alg_minbits = 40,
4471da177e4SLinus Torvalds 		.sadb_alg_maxbits = 128
4481da177e4SLinus Torvalds 	}
4491da177e4SLinus Torvalds },
4501da177e4SLinus Torvalds {
4516b7326c8SHerbert Xu 	.name = "cbc(blowfish)",
4526b7326c8SHerbert Xu 	.compat = "blowfish",
4531da177e4SLinus Torvalds 
4541da177e4SLinus Torvalds 	.uinfo = {
4551da177e4SLinus Torvalds 		.encr = {
456165ecc63SHerbert Xu 			.geniv = "echainiv",
4571da177e4SLinus Torvalds 			.blockbits = 64,
4581da177e4SLinus Torvalds 			.defkeybits = 128,
4591da177e4SLinus Torvalds 		}
4601da177e4SLinus Torvalds 	},
4611da177e4SLinus Torvalds 
4627e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
4637e50f84cSJussi Kivilinna 
4641da177e4SLinus Torvalds 	.desc = {
4651da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
4661da177e4SLinus Torvalds 		.sadb_alg_ivlen = 8,
4671da177e4SLinus Torvalds 		.sadb_alg_minbits = 40,
4681da177e4SLinus Torvalds 		.sadb_alg_maxbits = 448
4691da177e4SLinus Torvalds 	}
4701da177e4SLinus Torvalds },
4711da177e4SLinus Torvalds {
4726b7326c8SHerbert Xu 	.name = "cbc(aes)",
4736b7326c8SHerbert Xu 	.compat = "aes",
4741da177e4SLinus Torvalds 
4751da177e4SLinus Torvalds 	.uinfo = {
4761da177e4SLinus Torvalds 		.encr = {
477165ecc63SHerbert Xu 			.geniv = "echainiv",
4781da177e4SLinus Torvalds 			.blockbits = 128,
4791da177e4SLinus Torvalds 			.defkeybits = 128,
4801da177e4SLinus Torvalds 		}
4811da177e4SLinus Torvalds 	},
4821da177e4SLinus Torvalds 
4837e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
4847e50f84cSJussi Kivilinna 
4851da177e4SLinus Torvalds 	.desc = {
4861da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_EALG_AESCBC,
4871da177e4SLinus Torvalds 		.sadb_alg_ivlen = 8,
4881da177e4SLinus Torvalds 		.sadb_alg_minbits = 128,
4891da177e4SLinus Torvalds 		.sadb_alg_maxbits = 256
4901da177e4SLinus Torvalds 	}
4911da177e4SLinus Torvalds },
4921da177e4SLinus Torvalds {
4936b7326c8SHerbert Xu 	.name = "cbc(serpent)",
4946b7326c8SHerbert Xu 	.compat = "serpent",
4951da177e4SLinus Torvalds 
4961da177e4SLinus Torvalds 	.uinfo = {
4971da177e4SLinus Torvalds 		.encr = {
498165ecc63SHerbert Xu 			.geniv = "echainiv",
4991da177e4SLinus Torvalds 			.blockbits = 128,
5001da177e4SLinus Torvalds 			.defkeybits = 128,
5011da177e4SLinus Torvalds 		}
5021da177e4SLinus Torvalds 	},
5031da177e4SLinus Torvalds 
5047e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
5057e50f84cSJussi Kivilinna 
5061da177e4SLinus Torvalds 	.desc = {
5071da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_EALG_SERPENTCBC,
5081da177e4SLinus Torvalds 		.sadb_alg_ivlen = 8,
5091da177e4SLinus Torvalds 		.sadb_alg_minbits = 128,
5101da177e4SLinus Torvalds 		.sadb_alg_maxbits = 256,
5111da177e4SLinus Torvalds 	}
5121da177e4SLinus Torvalds },
5131da177e4SLinus Torvalds {
5146a0dc8d7SNoriaki TAKAMIYA 	.name = "cbc(camellia)",
515138f3c85SLi Yewang 	.compat = "camellia",
5166a0dc8d7SNoriaki TAKAMIYA 
5176a0dc8d7SNoriaki TAKAMIYA 	.uinfo = {
5186a0dc8d7SNoriaki TAKAMIYA 		.encr = {
519165ecc63SHerbert Xu 			.geniv = "echainiv",
5206a0dc8d7SNoriaki TAKAMIYA 			.blockbits = 128,
5216a0dc8d7SNoriaki TAKAMIYA 			.defkeybits = 128,
5226a0dc8d7SNoriaki TAKAMIYA 		}
5236a0dc8d7SNoriaki TAKAMIYA 	},
5246a0dc8d7SNoriaki TAKAMIYA 
5257e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
5267e50f84cSJussi Kivilinna 
5276a0dc8d7SNoriaki TAKAMIYA 	.desc = {
5286a0dc8d7SNoriaki TAKAMIYA 		.sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
5296a0dc8d7SNoriaki TAKAMIYA 		.sadb_alg_ivlen = 8,
5306a0dc8d7SNoriaki TAKAMIYA 		.sadb_alg_minbits = 128,
5316a0dc8d7SNoriaki TAKAMIYA 		.sadb_alg_maxbits = 256
5326a0dc8d7SNoriaki TAKAMIYA 	}
5336a0dc8d7SNoriaki TAKAMIYA },
5346a0dc8d7SNoriaki TAKAMIYA {
5356b7326c8SHerbert Xu 	.name = "cbc(twofish)",
5366b7326c8SHerbert Xu 	.compat = "twofish",
5371da177e4SLinus Torvalds 
5381da177e4SLinus Torvalds 	.uinfo = {
5391da177e4SLinus Torvalds 		.encr = {
540165ecc63SHerbert Xu 			.geniv = "echainiv",
5411da177e4SLinus Torvalds 			.blockbits = 128,
5421da177e4SLinus Torvalds 			.defkeybits = 128,
5431da177e4SLinus Torvalds 		}
5441da177e4SLinus Torvalds 	},
5451da177e4SLinus Torvalds 
5467e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
5477e50f84cSJussi Kivilinna 
5481da177e4SLinus Torvalds 	.desc = {
5491da177e4SLinus Torvalds 		.sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
5501da177e4SLinus Torvalds 		.sadb_alg_ivlen = 8,
5511da177e4SLinus Torvalds 		.sadb_alg_minbits = 128,
5521da177e4SLinus Torvalds 		.sadb_alg_maxbits = 256
5531da177e4SLinus Torvalds 	}
5541da177e4SLinus Torvalds },
555405137d1SJoy Latten {
556405137d1SJoy Latten 	.name = "rfc3686(ctr(aes))",
557405137d1SJoy Latten 
558405137d1SJoy Latten 	.uinfo = {
559405137d1SJoy Latten 		.encr = {
560165ecc63SHerbert Xu 			.geniv = "seqiv",
561405137d1SJoy Latten 			.blockbits = 128,
562405137d1SJoy Latten 			.defkeybits = 160, /* 128-bit key + 32-bit nonce */
563405137d1SJoy Latten 		}
564405137d1SJoy Latten 	},
565405137d1SJoy Latten 
5667e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
5677e50f84cSJussi Kivilinna 
568405137d1SJoy Latten 	.desc = {
569405137d1SJoy Latten 		.sadb_alg_id = SADB_X_EALG_AESCTR,
570405137d1SJoy Latten 		.sadb_alg_ivlen	= 8,
5714203223aSTushar Gohad 		.sadb_alg_minbits = 160,
5724203223aSTushar Gohad 		.sadb_alg_maxbits = 288
573405137d1SJoy Latten 	}
574405137d1SJoy Latten },
575*23b6a6dfSXu Jia {
576*23b6a6dfSXu Jia 	.name = "cbc(sm4)",
577*23b6a6dfSXu Jia 	.compat = "sm4",
578*23b6a6dfSXu Jia 
579*23b6a6dfSXu Jia 	.uinfo = {
580*23b6a6dfSXu Jia 		.encr = {
581*23b6a6dfSXu Jia 			.geniv = "echainiv",
582*23b6a6dfSXu Jia 			.blockbits = 128,
583*23b6a6dfSXu Jia 			.defkeybits = 128,
584*23b6a6dfSXu Jia 		}
585*23b6a6dfSXu Jia 	},
586*23b6a6dfSXu Jia 
587*23b6a6dfSXu Jia 	.pfkey_supported = 1,
588*23b6a6dfSXu Jia 
589*23b6a6dfSXu Jia 	.desc = {
590*23b6a6dfSXu Jia 		.sadb_alg_id = SADB_X_EALG_SM4CBC,
591*23b6a6dfSXu Jia 		.sadb_alg_ivlen	= 16,
592*23b6a6dfSXu Jia 		.sadb_alg_minbits = 128,
593*23b6a6dfSXu Jia 		.sadb_alg_maxbits = 256
594*23b6a6dfSXu Jia 	}
595*23b6a6dfSXu Jia },
5961da177e4SLinus Torvalds };
5971da177e4SLinus Torvalds 
5981da177e4SLinus Torvalds static struct xfrm_algo_desc calg_list[] = {
5991da177e4SLinus Torvalds {
6001da177e4SLinus Torvalds 	.name = "deflate",
6011da177e4SLinus Torvalds 	.uinfo = {
6021da177e4SLinus Torvalds 		.comp = {
6031da177e4SLinus Torvalds 			.threshold = 90,
6041da177e4SLinus Torvalds 		}
6051da177e4SLinus Torvalds 	},
6067e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
6071da177e4SLinus Torvalds 	.desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
6081da177e4SLinus Torvalds },
6091da177e4SLinus Torvalds {
6101da177e4SLinus Torvalds 	.name = "lzs",
6111da177e4SLinus Torvalds 	.uinfo = {
6121da177e4SLinus Torvalds 		.comp = {
6131da177e4SLinus Torvalds 			.threshold = 90,
6141da177e4SLinus Torvalds 		}
6151da177e4SLinus Torvalds 	},
6167e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
6171da177e4SLinus Torvalds 	.desc = { .sadb_alg_id = SADB_X_CALG_LZS }
6181da177e4SLinus Torvalds },
6191da177e4SLinus Torvalds {
6201da177e4SLinus Torvalds 	.name = "lzjh",
6211da177e4SLinus Torvalds 	.uinfo = {
6221da177e4SLinus Torvalds 		.comp = {
6231da177e4SLinus Torvalds 			.threshold = 50,
6241da177e4SLinus Torvalds 		}
6251da177e4SLinus Torvalds 	},
6267e50f84cSJussi Kivilinna 	.pfkey_supported = 1,
6271da177e4SLinus Torvalds 	.desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
6281da177e4SLinus Torvalds },
6291da177e4SLinus Torvalds };
6301da177e4SLinus Torvalds 
aalg_entries(void)6311da177e4SLinus Torvalds static inline int aalg_entries(void)
6321da177e4SLinus Torvalds {
6331da177e4SLinus Torvalds 	return ARRAY_SIZE(aalg_list);
6341da177e4SLinus Torvalds }
6351da177e4SLinus Torvalds 
ealg_entries(void)6361da177e4SLinus Torvalds static inline int ealg_entries(void)
6371da177e4SLinus Torvalds {
6381da177e4SLinus Torvalds 	return ARRAY_SIZE(ealg_list);
6391da177e4SLinus Torvalds }
6401da177e4SLinus Torvalds 
calg_entries(void)6411da177e4SLinus Torvalds static inline int calg_entries(void)
6421da177e4SLinus Torvalds {
6431da177e4SLinus Torvalds 	return ARRAY_SIZE(calg_list);
6441da177e4SLinus Torvalds }
6451da177e4SLinus Torvalds 
646c92b3a2fSHerbert Xu struct xfrm_algo_list {
647c92b3a2fSHerbert Xu 	struct xfrm_algo_desc *algs;
648c92b3a2fSHerbert Xu 	int entries;
649c92b3a2fSHerbert Xu 	u32 type;
650c92b3a2fSHerbert Xu 	u32 mask;
651c92b3a2fSHerbert Xu };
652c92b3a2fSHerbert Xu 
6531a6509d9SHerbert Xu static const struct xfrm_algo_list xfrm_aead_list = {
6541a6509d9SHerbert Xu 	.algs = aead_list,
6551a6509d9SHerbert Xu 	.entries = ARRAY_SIZE(aead_list),
6561a6509d9SHerbert Xu 	.type = CRYPTO_ALG_TYPE_AEAD,
6571a6509d9SHerbert Xu 	.mask = CRYPTO_ALG_TYPE_MASK,
6581a6509d9SHerbert Xu };
6591a6509d9SHerbert Xu 
660c92b3a2fSHerbert Xu static const struct xfrm_algo_list xfrm_aalg_list = {
661c92b3a2fSHerbert Xu 	.algs = aalg_list,
662c92b3a2fSHerbert Xu 	.entries = ARRAY_SIZE(aalg_list),
663c92b3a2fSHerbert Xu 	.type = CRYPTO_ALG_TYPE_HASH,
6646fbf2cb7SHerbert Xu 	.mask = CRYPTO_ALG_TYPE_HASH_MASK,
665c92b3a2fSHerbert Xu };
666c92b3a2fSHerbert Xu 
667c92b3a2fSHerbert Xu static const struct xfrm_algo_list xfrm_ealg_list = {
668c92b3a2fSHerbert Xu 	.algs = ealg_list,
669c92b3a2fSHerbert Xu 	.entries = ARRAY_SIZE(ealg_list),
670c65058b7SEric Biggers 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
671c65058b7SEric Biggers 	.mask = CRYPTO_ALG_TYPE_MASK,
672c92b3a2fSHerbert Xu };
673c92b3a2fSHerbert Xu 
674c92b3a2fSHerbert Xu static const struct xfrm_algo_list xfrm_calg_list = {
675c92b3a2fSHerbert Xu 	.algs = calg_list,
676c92b3a2fSHerbert Xu 	.entries = ARRAY_SIZE(calg_list),
677c92b3a2fSHerbert Xu 	.type = CRYPTO_ALG_TYPE_COMPRESS,
6786fbf2cb7SHerbert Xu 	.mask = CRYPTO_ALG_TYPE_MASK,
679c92b3a2fSHerbert Xu };
680c92b3a2fSHerbert Xu 
xfrm_find_algo(const struct xfrm_algo_list * algo_list,int match (const struct xfrm_algo_desc * entry,const void * data),const void * data,int probe)681c92b3a2fSHerbert Xu static struct xfrm_algo_desc *xfrm_find_algo(
682c92b3a2fSHerbert Xu 	const struct xfrm_algo_list *algo_list,
683c92b3a2fSHerbert Xu 	int match(const struct xfrm_algo_desc *entry, const void *data),
684c92b3a2fSHerbert Xu 	const void *data, int probe)
6851da177e4SLinus Torvalds {
686c92b3a2fSHerbert Xu 	struct xfrm_algo_desc *list = algo_list->algs;
6871da177e4SLinus Torvalds 	int i, status;
6881da177e4SLinus Torvalds 
689c92b3a2fSHerbert Xu 	for (i = 0; i < algo_list->entries; i++) {
690c92b3a2fSHerbert Xu 		if (!match(list + i, data))
6911da177e4SLinus Torvalds 			continue;
6921da177e4SLinus Torvalds 
6931da177e4SLinus Torvalds 		if (list[i].available)
6941da177e4SLinus Torvalds 			return &list[i];
6951da177e4SLinus Torvalds 
6961da177e4SLinus Torvalds 		if (!probe)
6971da177e4SLinus Torvalds 			break;
6981da177e4SLinus Torvalds 
699c92b3a2fSHerbert Xu 		status = crypto_has_alg(list[i].name, algo_list->type,
700c92b3a2fSHerbert Xu 					algo_list->mask);
7011da177e4SLinus Torvalds 		if (!status)
7021da177e4SLinus Torvalds 			break;
7031da177e4SLinus Torvalds 
7041da177e4SLinus Torvalds 		list[i].available = status;
7051da177e4SLinus Torvalds 		return &list[i];
7061da177e4SLinus Torvalds 	}
7071da177e4SLinus Torvalds 	return NULL;
7081da177e4SLinus Torvalds }
7091da177e4SLinus Torvalds 
xfrm_alg_id_match(const struct xfrm_algo_desc * entry,const void * data)710c92b3a2fSHerbert Xu static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
711c92b3a2fSHerbert Xu 			     const void *data)
712c92b3a2fSHerbert Xu {
71326b8e51eSHerbert Xu 	return entry->desc.sadb_alg_id == (unsigned long)data;
714c92b3a2fSHerbert Xu }
715c92b3a2fSHerbert Xu 
xfrm_aalg_get_byid(int alg_id)716c92b3a2fSHerbert Xu struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
717c92b3a2fSHerbert Xu {
718c92b3a2fSHerbert Xu 	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
71926b8e51eSHerbert Xu 			      (void *)(unsigned long)alg_id, 1);
720c92b3a2fSHerbert Xu }
721c92b3a2fSHerbert Xu EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
722c92b3a2fSHerbert Xu 
xfrm_ealg_get_byid(int alg_id)723c92b3a2fSHerbert Xu struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
724c92b3a2fSHerbert Xu {
725c92b3a2fSHerbert Xu 	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
72626b8e51eSHerbert Xu 			      (void *)(unsigned long)alg_id, 1);
727c92b3a2fSHerbert Xu }
728c92b3a2fSHerbert Xu EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
729c92b3a2fSHerbert Xu 
xfrm_calg_get_byid(int alg_id)730c92b3a2fSHerbert Xu struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
731c92b3a2fSHerbert Xu {
732c92b3a2fSHerbert Xu 	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
73326b8e51eSHerbert Xu 			      (void *)(unsigned long)alg_id, 1);
734c92b3a2fSHerbert Xu }
735c92b3a2fSHerbert Xu EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
736c92b3a2fSHerbert Xu 
xfrm_alg_name_match(const struct xfrm_algo_desc * entry,const void * data)737c92b3a2fSHerbert Xu static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
738c92b3a2fSHerbert Xu 			       const void *data)
739c92b3a2fSHerbert Xu {
740c92b3a2fSHerbert Xu 	const char *name = data;
741c92b3a2fSHerbert Xu 
742c92b3a2fSHerbert Xu 	return name && (!strcmp(name, entry->name) ||
743c92b3a2fSHerbert Xu 			(entry->compat && !strcmp(name, entry->compat)));
744c92b3a2fSHerbert Xu }
745c92b3a2fSHerbert Xu 
xfrm_aalg_get_byname(const char * name,int probe)7466f2f19edSDavid S. Miller struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
7471da177e4SLinus Torvalds {
748c92b3a2fSHerbert Xu 	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
749c92b3a2fSHerbert Xu 			      probe);
7501da177e4SLinus Torvalds }
7511da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
7521da177e4SLinus Torvalds 
xfrm_ealg_get_byname(const char * name,int probe)7536f2f19edSDavid S. Miller struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
7541da177e4SLinus Torvalds {
755c92b3a2fSHerbert Xu 	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
756c92b3a2fSHerbert Xu 			      probe);
7571da177e4SLinus Torvalds }
7581da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
7591da177e4SLinus Torvalds 
xfrm_calg_get_byname(const char * name,int probe)7606f2f19edSDavid S. Miller struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
7611da177e4SLinus Torvalds {
762c92b3a2fSHerbert Xu 	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
763c92b3a2fSHerbert Xu 			      probe);
7641da177e4SLinus Torvalds }
7651da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
7661da177e4SLinus Torvalds 
7671a6509d9SHerbert Xu struct xfrm_aead_name {
7681a6509d9SHerbert Xu 	const char *name;
7691a6509d9SHerbert Xu 	int icvbits;
7701a6509d9SHerbert Xu };
7711a6509d9SHerbert Xu 
xfrm_aead_name_match(const struct xfrm_algo_desc * entry,const void * data)7721a6509d9SHerbert Xu static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
7731a6509d9SHerbert Xu 				const void *data)
7741a6509d9SHerbert Xu {
7751a6509d9SHerbert Xu 	const struct xfrm_aead_name *aead = data;
7761a6509d9SHerbert Xu 	const char *name = aead->name;
7771a6509d9SHerbert Xu 
7781a6509d9SHerbert Xu 	return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
7791a6509d9SHerbert Xu 	       !strcmp(name, entry->name);
7801a6509d9SHerbert Xu }
7811a6509d9SHerbert Xu 
xfrm_aead_get_byname(const char * name,int icv_len,int probe)7826f2f19edSDavid S. Miller struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
7831a6509d9SHerbert Xu {
7841a6509d9SHerbert Xu 	struct xfrm_aead_name data = {
7851a6509d9SHerbert Xu 		.name = name,
7861a6509d9SHerbert Xu 		.icvbits = icv_len,
7871a6509d9SHerbert Xu 	};
7881a6509d9SHerbert Xu 
7891a6509d9SHerbert Xu 	return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
7901a6509d9SHerbert Xu 			      probe);
7911a6509d9SHerbert Xu }
7921a6509d9SHerbert Xu EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
7931a6509d9SHerbert Xu 
xfrm_aalg_get_byidx(unsigned int idx)7941da177e4SLinus Torvalds struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
7951da177e4SLinus Torvalds {
7961da177e4SLinus Torvalds 	if (idx >= aalg_entries())
7971da177e4SLinus Torvalds 		return NULL;
7981da177e4SLinus Torvalds 
7991da177e4SLinus Torvalds 	return &aalg_list[idx];
8001da177e4SLinus Torvalds }
8011da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
8021da177e4SLinus Torvalds 
xfrm_ealg_get_byidx(unsigned int idx)8031da177e4SLinus Torvalds struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
8041da177e4SLinus Torvalds {
8051da177e4SLinus Torvalds 	if (idx >= ealg_entries())
8061da177e4SLinus Torvalds 		return NULL;
8071da177e4SLinus Torvalds 
8081da177e4SLinus Torvalds 	return &ealg_list[idx];
8091da177e4SLinus Torvalds }
8101da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
8111da177e4SLinus Torvalds 
8121da177e4SLinus Torvalds /*
8131da177e4SLinus Torvalds  * Probe for the availability of crypto algorithms, and set the available
8141da177e4SLinus Torvalds  * flag for any algorithms found on the system.  This is typically called by
8151da177e4SLinus Torvalds  * pfkey during userspace SA add, update or register.
8161da177e4SLinus Torvalds  */
xfrm_probe_algs(void)8171da177e4SLinus Torvalds void xfrm_probe_algs(void)
8181da177e4SLinus Torvalds {
8191da177e4SLinus Torvalds 	int i, status;
8201da177e4SLinus Torvalds 
8211da177e4SLinus Torvalds 	BUG_ON(in_softirq());
8221da177e4SLinus Torvalds 
8231da177e4SLinus Torvalds 	for (i = 0; i < aalg_entries(); i++) {
82417bc1970SHerbert Xu 		status = crypto_has_ahash(aalg_list[i].name, 0, 0);
8251da177e4SLinus Torvalds 		if (aalg_list[i].available != status)
8261da177e4SLinus Torvalds 			aalg_list[i].available = status;
8271da177e4SLinus Torvalds 	}
8281da177e4SLinus Torvalds 
8291da177e4SLinus Torvalds 	for (i = 0; i < ealg_entries(); i++) {
83017bc1970SHerbert Xu 		status = crypto_has_skcipher(ealg_list[i].name, 0, 0);
8311da177e4SLinus Torvalds 		if (ealg_list[i].available != status)
8321da177e4SLinus Torvalds 			ealg_list[i].available = status;
8331da177e4SLinus Torvalds 	}
8341da177e4SLinus Torvalds 
8351da177e4SLinus Torvalds 	for (i = 0; i < calg_entries(); i++) {
836e4d5b79cSHerbert Xu 		status = crypto_has_comp(calg_list[i].name, 0,
837e4d5b79cSHerbert Xu 					 CRYPTO_ALG_ASYNC);
8381da177e4SLinus Torvalds 		if (calg_list[i].available != status)
8391da177e4SLinus Torvalds 			calg_list[i].available = status;
8401da177e4SLinus Torvalds 	}
8411da177e4SLinus Torvalds }
8421da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(xfrm_probe_algs);
8431da177e4SLinus Torvalds 
xfrm_count_pfkey_auth_supported(void)8447e50f84cSJussi Kivilinna int xfrm_count_pfkey_auth_supported(void)
8451da177e4SLinus Torvalds {
8461da177e4SLinus Torvalds 	int i, n;
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 	for (i = 0, n = 0; i < aalg_entries(); i++)
8497e50f84cSJussi Kivilinna 		if (aalg_list[i].available && aalg_list[i].pfkey_supported)
8501da177e4SLinus Torvalds 			n++;
8511da177e4SLinus Torvalds 	return n;
8521da177e4SLinus Torvalds }
8537e50f84cSJussi Kivilinna EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
8541da177e4SLinus Torvalds 
xfrm_count_pfkey_enc_supported(void)8557e50f84cSJussi Kivilinna int xfrm_count_pfkey_enc_supported(void)
8561da177e4SLinus Torvalds {
8571da177e4SLinus Torvalds 	int i, n;
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds 	for (i = 0, n = 0; i < ealg_entries(); i++)
8607e50f84cSJussi Kivilinna 		if (ealg_list[i].available && ealg_list[i].pfkey_supported)
8611da177e4SLinus Torvalds 			n++;
8621da177e4SLinus Torvalds 	return n;
8631da177e4SLinus Torvalds }
8647e50f84cSJussi Kivilinna EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
8651da177e4SLinus Torvalds 
8667e152524SJan Beulich MODULE_LICENSE("GPL");
867