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