blob: 67266b7501f13a02184306f5e6dd01924b99bbaf [file] [log] [blame]
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * xfrm algorithm interface
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +09008 * Software Foundation; either version 2 of the License, or (at your option)
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * any later version.
10 */
11
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/pfkeyv2.h>
15#include <linux/crypto.h>
Heiko Carstensb3b724f2007-10-23 09:28:34 +020016#include <linux/scatterlist.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <net/xfrm.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
19#include <net/esp.h>
20#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22/*
23 * Algorithms supported by IPsec. These entries contain properties which
24 * are used in key negotiation and xfrm processing, and are used to verify
25 * that instantiated crypto transforms have correct parameters for IPsec
26 * purposes.
27 */
Herbert Xu1a6509d2008-01-28 19:37:29 -080028static struct xfrm_algo_desc aead_list[] = {
29{
30 .name = "rfc4106(gcm(aes))",
31
32 .uinfo = {
33 .aead = {
Herbert Xu165ecc62015-05-27 16:03:44 +080034 .geniv = "seqniv",
Herbert Xu1a6509d2008-01-28 19:37:29 -080035 .icv_truncbits = 64,
36 }
37 },
38
Jussi Kivilinna7e50f842013-01-31 12:40:38 +020039 .pfkey_supported = 1,
40
Herbert Xu1a6509d2008-01-28 19:37:29 -080041 .desc = {
42 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
43 .sadb_alg_ivlen = 8,
44 .sadb_alg_minbits = 128,
45 .sadb_alg_maxbits = 256
46 }
47},
48{
49 .name = "rfc4106(gcm(aes))",
50
51 .uinfo = {
52 .aead = {
Herbert Xu165ecc62015-05-27 16:03:44 +080053 .geniv = "seqniv",
Herbert Xu1a6509d2008-01-28 19:37:29 -080054 .icv_truncbits = 96,
55 }
56 },
57
Jussi Kivilinna7e50f842013-01-31 12:40:38 +020058 .pfkey_supported = 1,
59
Herbert Xu1a6509d2008-01-28 19:37:29 -080060 .desc = {
61 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
62 .sadb_alg_ivlen = 8,
63 .sadb_alg_minbits = 128,
64 .sadb_alg_maxbits = 256
65 }
66},
67{
68 .name = "rfc4106(gcm(aes))",
69
70 .uinfo = {
71 .aead = {
Herbert Xu165ecc62015-05-27 16:03:44 +080072 .geniv = "seqniv",
Herbert Xu1a6509d2008-01-28 19:37:29 -080073 .icv_truncbits = 128,
74 }
75 },
76
Jussi Kivilinna7e50f842013-01-31 12:40:38 +020077 .pfkey_supported = 1,
78
Herbert Xu1a6509d2008-01-28 19:37:29 -080079 .desc = {
80 .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
81 .sadb_alg_ivlen = 8,
82 .sadb_alg_minbits = 128,
83 .sadb_alg_maxbits = 256
84 }
85},
86{
87 .name = "rfc4309(ccm(aes))",
88
89 .uinfo = {
90 .aead = {
Herbert Xu165ecc62015-05-27 16:03:44 +080091 .geniv = "seqniv",
Herbert Xu1a6509d2008-01-28 19:37:29 -080092 .icv_truncbits = 64,
93 }
94 },
95
Jussi Kivilinna7e50f842013-01-31 12:40:38 +020096 .pfkey_supported = 1,
97
Herbert Xu1a6509d2008-01-28 19:37:29 -080098 .desc = {
99 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
100 .sadb_alg_ivlen = 8,
101 .sadb_alg_minbits = 128,
102 .sadb_alg_maxbits = 256
103 }
104},
105{
106 .name = "rfc4309(ccm(aes))",
107
108 .uinfo = {
109 .aead = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800110 .geniv = "seqniv",
Herbert Xu1a6509d2008-01-28 19:37:29 -0800111 .icv_truncbits = 96,
112 }
113 },
114
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200115 .pfkey_supported = 1,
116
Herbert Xu1a6509d2008-01-28 19:37:29 -0800117 .desc = {
118 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
119 .sadb_alg_ivlen = 8,
120 .sadb_alg_minbits = 128,
121 .sadb_alg_maxbits = 256
122 }
123},
124{
125 .name = "rfc4309(ccm(aes))",
126
127 .uinfo = {
128 .aead = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800129 .geniv = "seqniv",
Herbert Xu1a6509d2008-01-28 19:37:29 -0800130 .icv_truncbits = 128,
131 }
132 },
133
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200134 .pfkey_supported = 1,
135
Herbert Xu1a6509d2008-01-28 19:37:29 -0800136 .desc = {
137 .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
138 .sadb_alg_ivlen = 8,
139 .sadb_alg_minbits = 128,
140 .sadb_alg_maxbits = 256
141 }
142},
Tobias Brunner73c89c12010-01-17 21:52:11 +1100143{
144 .name = "rfc4543(gcm(aes))",
145
146 .uinfo = {
147 .aead = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800148 .geniv = "seqiv",
Tobias Brunner73c89c12010-01-17 21:52:11 +1100149 .icv_truncbits = 128,
150 }
151 },
152
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200153 .pfkey_supported = 1,
154
Tobias Brunner73c89c12010-01-17 21:52:11 +1100155 .desc = {
156 .sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
157 .sadb_alg_ivlen = 8,
158 .sadb_alg_minbits = 128,
159 .sadb_alg_maxbits = 256
160 }
161},
Herbert Xu1a6509d2008-01-28 19:37:29 -0800162};
163
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164static struct xfrm_algo_desc aalg_list[] = {
165{
Herbert Xu01a22022008-04-27 00:59:59 -0700166 .name = "digest_null",
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900167
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 .uinfo = {
169 .auth = {
170 .icv_truncbits = 0,
171 .icv_fullbits = 0,
172 }
173 },
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900174
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200175 .pfkey_supported = 1,
176
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 .desc = {
178 .sadb_alg_id = SADB_X_AALG_NULL,
179 .sadb_alg_ivlen = 0,
180 .sadb_alg_minbits = 0,
181 .sadb_alg_maxbits = 0
182 }
183},
184{
Herbert Xu07d4ee52006-08-20 14:24:50 +1000185 .name = "hmac(md5)",
186 .compat = "md5",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187
188 .uinfo = {
189 .auth = {
190 .icv_truncbits = 96,
191 .icv_fullbits = 128,
192 }
193 },
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900194
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200195 .pfkey_supported = 1,
196
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 .desc = {
198 .sadb_alg_id = SADB_AALG_MD5HMAC,
199 .sadb_alg_ivlen = 0,
200 .sadb_alg_minbits = 128,
201 .sadb_alg_maxbits = 128
202 }
203},
204{
Herbert Xu07d4ee52006-08-20 14:24:50 +1000205 .name = "hmac(sha1)",
206 .compat = "sha1",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207
208 .uinfo = {
209 .auth = {
210 .icv_truncbits = 96,
211 .icv_fullbits = 160,
212 }
213 },
214
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200215 .pfkey_supported = 1,
216
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 .desc = {
218 .sadb_alg_id = SADB_AALG_SHA1HMAC,
219 .sadb_alg_ivlen = 0,
220 .sadb_alg_minbits = 160,
221 .sadb_alg_maxbits = 160
222 }
223},
224{
Herbert Xu07d4ee52006-08-20 14:24:50 +1000225 .name = "hmac(sha256)",
226 .compat = "sha256",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228 .uinfo = {
229 .auth = {
230 .icv_truncbits = 96,
231 .icv_fullbits = 256,
232 }
233 },
234
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200235 .pfkey_supported = 1,
236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 .desc = {
238 .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
239 .sadb_alg_ivlen = 0,
240 .sadb_alg_minbits = 256,
241 .sadb_alg_maxbits = 256
242 }
243},
244{
Martin Willibc74b0c2009-11-25 00:58:39 +0000245 .name = "hmac(sha384)",
246
247 .uinfo = {
248 .auth = {
249 .icv_truncbits = 192,
250 .icv_fullbits = 384,
251 }
252 },
253
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200254 .pfkey_supported = 1,
255
Martin Willibc74b0c2009-11-25 00:58:39 +0000256 .desc = {
257 .sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
258 .sadb_alg_ivlen = 0,
259 .sadb_alg_minbits = 384,
260 .sadb_alg_maxbits = 384
261 }
262},
263{
264 .name = "hmac(sha512)",
265
266 .uinfo = {
267 .auth = {
268 .icv_truncbits = 256,
269 .icv_fullbits = 512,
270 }
271 },
272
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200273 .pfkey_supported = 1,
274
Martin Willibc74b0c2009-11-25 00:58:39 +0000275 .desc = {
276 .sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
277 .sadb_alg_ivlen = 0,
278 .sadb_alg_minbits = 512,
279 .sadb_alg_maxbits = 512
280 }
281},
282{
Adrian-Ken Rueegseggera13366c2008-06-04 12:04:55 -0700283 .name = "hmac(rmd160)",
284 .compat = "rmd160",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
286 .uinfo = {
287 .auth = {
288 .icv_truncbits = 96,
289 .icv_fullbits = 160,
290 }
291 },
292
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200293 .pfkey_supported = 1,
294
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 .desc = {
296 .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
297 .sadb_alg_ivlen = 0,
298 .sadb_alg_minbits = 160,
299 .sadb_alg_maxbits = 160
300 }
301},
Kazunori MIYAZAWA7cf4c1a2006-10-28 13:21:22 +1000302{
303 .name = "xcbc(aes)",
304
305 .uinfo = {
306 .auth = {
307 .icv_truncbits = 96,
308 .icv_fullbits = 128,
309 }
310 },
311
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200312 .pfkey_supported = 1,
313
Kazunori MIYAZAWA7cf4c1a2006-10-28 13:21:22 +1000314 .desc = {
315 .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
316 .sadb_alg_ivlen = 0,
317 .sadb_alg_minbits = 128,
318 .sadb_alg_maxbits = 128
319 }
320},
Jussi Kivilinnad2049d82013-04-08 10:48:49 +0300321{
322 /* rfc4494 */
323 .name = "cmac(aes)",
324
325 .uinfo = {
326 .auth = {
327 .icv_truncbits = 96,
328 .icv_fullbits = 128,
329 }
330 },
331
332 .pfkey_supported = 0,
333},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334};
335
336static struct xfrm_algo_desc ealg_list[] = {
337{
Herbert Xu6b7326c2006-07-30 15:41:01 +1000338 .name = "ecb(cipher_null)",
339 .compat = "cipher_null",
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900340
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 .uinfo = {
342 .encr = {
343 .blockbits = 8,
344 .defkeybits = 0,
345 }
346 },
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900347
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200348 .pfkey_supported = 1,
349
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 .desc = {
351 .sadb_alg_id = SADB_EALG_NULL,
352 .sadb_alg_ivlen = 0,
353 .sadb_alg_minbits = 0,
354 .sadb_alg_maxbits = 0
355 }
356},
357{
Herbert Xu6b7326c2006-07-30 15:41:01 +1000358 .name = "cbc(des)",
359 .compat = "des",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
361 .uinfo = {
362 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800363 .geniv = "echainiv",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 .blockbits = 64,
365 .defkeybits = 64,
366 }
367 },
368
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200369 .pfkey_supported = 1,
370
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 .desc = {
372 .sadb_alg_id = SADB_EALG_DESCBC,
373 .sadb_alg_ivlen = 8,
374 .sadb_alg_minbits = 64,
375 .sadb_alg_maxbits = 64
376 }
377},
378{
Herbert Xu6b7326c2006-07-30 15:41:01 +1000379 .name = "cbc(des3_ede)",
380 .compat = "des3_ede",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
382 .uinfo = {
383 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800384 .geniv = "echainiv",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 .blockbits = 64,
386 .defkeybits = 192,
387 }
388 },
389
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200390 .pfkey_supported = 1,
391
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 .desc = {
393 .sadb_alg_id = SADB_EALG_3DESCBC,
394 .sadb_alg_ivlen = 8,
395 .sadb_alg_minbits = 192,
396 .sadb_alg_maxbits = 192
397 }
398},
399{
Herbert Xu245acb82009-06-24 03:55:41 -0700400 .name = "cbc(cast5)",
401 .compat = "cast5",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
403 .uinfo = {
404 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800405 .geniv = "echainiv",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 .blockbits = 64,
407 .defkeybits = 128,
408 }
409 },
410
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200411 .pfkey_supported = 1,
412
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 .desc = {
414 .sadb_alg_id = SADB_X_EALG_CASTCBC,
415 .sadb_alg_ivlen = 8,
416 .sadb_alg_minbits = 40,
417 .sadb_alg_maxbits = 128
418 }
419},
420{
Herbert Xu6b7326c2006-07-30 15:41:01 +1000421 .name = "cbc(blowfish)",
422 .compat = "blowfish",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
424 .uinfo = {
425 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800426 .geniv = "echainiv",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 .blockbits = 64,
428 .defkeybits = 128,
429 }
430 },
431
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200432 .pfkey_supported = 1,
433
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 .desc = {
435 .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
436 .sadb_alg_ivlen = 8,
437 .sadb_alg_minbits = 40,
438 .sadb_alg_maxbits = 448
439 }
440},
441{
Herbert Xu6b7326c2006-07-30 15:41:01 +1000442 .name = "cbc(aes)",
443 .compat = "aes",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444
445 .uinfo = {
446 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800447 .geniv = "echainiv",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 .blockbits = 128,
449 .defkeybits = 128,
450 }
451 },
452
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200453 .pfkey_supported = 1,
454
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 .desc = {
456 .sadb_alg_id = SADB_X_EALG_AESCBC,
457 .sadb_alg_ivlen = 8,
458 .sadb_alg_minbits = 128,
459 .sadb_alg_maxbits = 256
460 }
461},
462{
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900463 .name = "cbc(serpent)",
464 .compat = "serpent",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900466 .uinfo = {
467 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800468 .geniv = "echainiv",
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900469 .blockbits = 128,
470 .defkeybits = 128,
471 }
472 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200474 .pfkey_supported = 1,
475
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900476 .desc = {
477 .sadb_alg_id = SADB_X_EALG_SERPENTCBC,
478 .sadb_alg_ivlen = 8,
479 .sadb_alg_minbits = 128,
480 .sadb_alg_maxbits = 256,
481 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482},
483{
Noriaki TAKAMIYA6a0dc8d2006-10-22 15:05:57 +1000484 .name = "cbc(camellia)",
Li Yewang138f3c82009-12-01 15:35:05 -0800485 .compat = "camellia",
Noriaki TAKAMIYA6a0dc8d2006-10-22 15:05:57 +1000486
487 .uinfo = {
488 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800489 .geniv = "echainiv",
Noriaki TAKAMIYA6a0dc8d2006-10-22 15:05:57 +1000490 .blockbits = 128,
491 .defkeybits = 128,
492 }
493 },
494
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200495 .pfkey_supported = 1,
496
Noriaki TAKAMIYA6a0dc8d2006-10-22 15:05:57 +1000497 .desc = {
498 .sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
499 .sadb_alg_ivlen = 8,
500 .sadb_alg_minbits = 128,
501 .sadb_alg_maxbits = 256
502 }
503},
504{
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900505 .name = "cbc(twofish)",
506 .compat = "twofish",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900508 .uinfo = {
509 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800510 .geniv = "echainiv",
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900511 .blockbits = 128,
512 .defkeybits = 128,
513 }
514 },
515
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200516 .pfkey_supported = 1,
517
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900518 .desc = {
519 .sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
520 .sadb_alg_ivlen = 8,
521 .sadb_alg_minbits = 128,
522 .sadb_alg_maxbits = 256
523 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524},
Joy Latten405137d2008-02-07 23:11:56 -0800525{
526 .name = "rfc3686(ctr(aes))",
527
528 .uinfo = {
529 .encr = {
Herbert Xu165ecc62015-05-27 16:03:44 +0800530 .geniv = "seqiv",
Joy Latten405137d2008-02-07 23:11:56 -0800531 .blockbits = 128,
532 .defkeybits = 160, /* 128-bit key + 32-bit nonce */
533 }
534 },
535
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200536 .pfkey_supported = 1,
537
Joy Latten405137d2008-02-07 23:11:56 -0800538 .desc = {
539 .sadb_alg_id = SADB_X_EALG_AESCTR,
540 .sadb_alg_ivlen = 8,
Tushar Gohad42032232011-07-28 10:36:20 +0000541 .sadb_alg_minbits = 160,
542 .sadb_alg_maxbits = 288
Joy Latten405137d2008-02-07 23:11:56 -0800543 }
544},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545};
546
547static struct xfrm_algo_desc calg_list[] = {
548{
549 .name = "deflate",
550 .uinfo = {
551 .comp = {
552 .threshold = 90,
553 }
554 },
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200555 .pfkey_supported = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
557},
558{
559 .name = "lzs",
560 .uinfo = {
561 .comp = {
562 .threshold = 90,
563 }
564 },
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200565 .pfkey_supported = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 .desc = { .sadb_alg_id = SADB_X_CALG_LZS }
567},
568{
569 .name = "lzjh",
570 .uinfo = {
571 .comp = {
572 .threshold = 50,
573 }
574 },
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200575 .pfkey_supported = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 .desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
577},
578};
579
580static inline int aalg_entries(void)
581{
582 return ARRAY_SIZE(aalg_list);
583}
584
585static inline int ealg_entries(void)
586{
587 return ARRAY_SIZE(ealg_list);
588}
589
590static inline int calg_entries(void)
591{
592 return ARRAY_SIZE(calg_list);
593}
594
Herbert Xuc92b3a22007-05-19 14:21:18 -0700595struct xfrm_algo_list {
596 struct xfrm_algo_desc *algs;
597 int entries;
598 u32 type;
599 u32 mask;
600};
601
Herbert Xu1a6509d2008-01-28 19:37:29 -0800602static const struct xfrm_algo_list xfrm_aead_list = {
603 .algs = aead_list,
604 .entries = ARRAY_SIZE(aead_list),
605 .type = CRYPTO_ALG_TYPE_AEAD,
606 .mask = CRYPTO_ALG_TYPE_MASK,
607};
608
Herbert Xuc92b3a22007-05-19 14:21:18 -0700609static const struct xfrm_algo_list xfrm_aalg_list = {
610 .algs = aalg_list,
611 .entries = ARRAY_SIZE(aalg_list),
612 .type = CRYPTO_ALG_TYPE_HASH,
Herbert Xu6fbf2cb2008-01-28 19:35:49 -0800613 .mask = CRYPTO_ALG_TYPE_HASH_MASK,
Herbert Xuc92b3a22007-05-19 14:21:18 -0700614};
615
616static const struct xfrm_algo_list xfrm_ealg_list = {
617 .algs = ealg_list,
618 .entries = ARRAY_SIZE(ealg_list),
619 .type = CRYPTO_ALG_TYPE_BLKCIPHER,
Herbert Xu6fbf2cb2008-01-28 19:35:49 -0800620 .mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
Herbert Xuc92b3a22007-05-19 14:21:18 -0700621};
622
623static const struct xfrm_algo_list xfrm_calg_list = {
624 .algs = calg_list,
625 .entries = ARRAY_SIZE(calg_list),
626 .type = CRYPTO_ALG_TYPE_COMPRESS,
Herbert Xu6fbf2cb2008-01-28 19:35:49 -0800627 .mask = CRYPTO_ALG_TYPE_MASK,
Herbert Xuc92b3a22007-05-19 14:21:18 -0700628};
629
630static struct xfrm_algo_desc *xfrm_find_algo(
631 const struct xfrm_algo_list *algo_list,
632 int match(const struct xfrm_algo_desc *entry, const void *data),
633 const void *data, int probe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
Herbert Xuc92b3a22007-05-19 14:21:18 -0700635 struct xfrm_algo_desc *list = algo_list->algs;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 int i, status;
637
Herbert Xuc92b3a22007-05-19 14:21:18 -0700638 for (i = 0; i < algo_list->entries; i++) {
639 if (!match(list + i, data))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 continue;
641
642 if (list[i].available)
643 return &list[i];
644
645 if (!probe)
646 break;
647
Herbert Xuc92b3a22007-05-19 14:21:18 -0700648 status = crypto_has_alg(list[i].name, algo_list->type,
649 algo_list->mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 if (!status)
651 break;
652
653 list[i].available = status;
654 return &list[i];
655 }
656 return NULL;
657}
658
Herbert Xuc92b3a22007-05-19 14:21:18 -0700659static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
660 const void *data)
661{
Herbert Xu26b8e512007-05-22 16:12:26 -0700662 return entry->desc.sadb_alg_id == (unsigned long)data;
Herbert Xuc92b3a22007-05-19 14:21:18 -0700663}
664
665struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
666{
667 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
Herbert Xu26b8e512007-05-22 16:12:26 -0700668 (void *)(unsigned long)alg_id, 1);
Herbert Xuc92b3a22007-05-19 14:21:18 -0700669}
670EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
671
672struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
673{
674 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
Herbert Xu26b8e512007-05-22 16:12:26 -0700675 (void *)(unsigned long)alg_id, 1);
Herbert Xuc92b3a22007-05-19 14:21:18 -0700676}
677EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
678
679struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
680{
681 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
Herbert Xu26b8e512007-05-22 16:12:26 -0700682 (void *)(unsigned long)alg_id, 1);
Herbert Xuc92b3a22007-05-19 14:21:18 -0700683}
684EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
685
686static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
687 const void *data)
688{
689 const char *name = data;
690
691 return name && (!strcmp(name, entry->name) ||
692 (entry->compat && !strcmp(name, entry->compat)));
693}
694
David S. Miller6f2f19e2011-02-27 23:04:45 -0800695struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696{
Herbert Xuc92b3a22007-05-19 14:21:18 -0700697 return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
698 probe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699}
700EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
701
David S. Miller6f2f19e2011-02-27 23:04:45 -0800702struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703{
Herbert Xuc92b3a22007-05-19 14:21:18 -0700704 return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
705 probe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706}
707EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
708
David S. Miller6f2f19e2011-02-27 23:04:45 -0800709struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710{
Herbert Xuc92b3a22007-05-19 14:21:18 -0700711 return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
712 probe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713}
714EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
715
Herbert Xu1a6509d2008-01-28 19:37:29 -0800716struct xfrm_aead_name {
717 const char *name;
718 int icvbits;
719};
720
721static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
722 const void *data)
723{
724 const struct xfrm_aead_name *aead = data;
725 const char *name = aead->name;
726
727 return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
728 !strcmp(name, entry->name);
729}
730
David S. Miller6f2f19e2011-02-27 23:04:45 -0800731struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
Herbert Xu1a6509d2008-01-28 19:37:29 -0800732{
733 struct xfrm_aead_name data = {
734 .name = name,
735 .icvbits = icv_len,
736 };
737
738 return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
739 probe);
740}
741EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
742
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
744{
745 if (idx >= aalg_entries())
746 return NULL;
747
748 return &aalg_list[idx];
749}
750EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
751
752struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
753{
754 if (idx >= ealg_entries())
755 return NULL;
756
757 return &ealg_list[idx];
758}
759EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
760
761/*
762 * Probe for the availability of crypto algorithms, and set the available
763 * flag for any algorithms found on the system. This is typically called by
764 * pfkey during userspace SA add, update or register.
765 */
766void xfrm_probe_algs(void)
767{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 int i, status;
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900769
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 BUG_ON(in_softirq());
771
772 for (i = 0; i < aalg_entries(); i++) {
Herbert Xue4d5b792006-08-26 18:12:40 +1000773 status = crypto_has_hash(aalg_list[i].name, 0,
774 CRYPTO_ALG_ASYNC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 if (aalg_list[i].available != status)
776 aalg_list[i].available = status;
777 }
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900778
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 for (i = 0; i < ealg_entries(); i++) {
Jussi Kivilinna71331da2012-12-28 12:04:53 +0200780 status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 if (ealg_list[i].available != status)
782 ealg_list[i].available = status;
783 }
YOSHIFUJI Hideakia716c112007-02-09 23:25:29 +0900784
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 for (i = 0; i < calg_entries(); i++) {
Herbert Xue4d5b792006-08-26 18:12:40 +1000786 status = crypto_has_comp(calg_list[i].name, 0,
787 CRYPTO_ALG_ASYNC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 if (calg_list[i].available != status)
789 calg_list[i].available = status;
790 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791}
792EXPORT_SYMBOL_GPL(xfrm_probe_algs);
793
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200794int xfrm_count_pfkey_auth_supported(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795{
796 int i, n;
797
798 for (i = 0, n = 0; i < aalg_entries(); i++)
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200799 if (aalg_list[i].available && aalg_list[i].pfkey_supported)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 n++;
801 return n;
802}
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200803EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200805int xfrm_count_pfkey_enc_supported(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806{
807 int i, n;
808
809 for (i = 0, n = 0; i < ealg_entries(); i++)
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200810 if (ealg_list[i].available && ealg_list[i].pfkey_supported)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 n++;
812 return n;
813}
Jussi Kivilinna7e50f842013-01-31 12:40:38 +0200814EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
Jan Beulich7e152522012-05-15 01:57:44 +0000816MODULE_LICENSE("GPL");