Root/net/xfrm/xfrm_algo.c

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

Archive Download this file



interactive