Linux Audio

Check our new training course

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