OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [xfrm/] [xfrm_algo.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
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
 */
31
static struct xfrm_algo_desc aalg_list[] = {
32
{
33
        .name = "hmac(digest_null)",
34
        .compat = "digest_null",
35
 
36
        .uinfo = {
37
                .auth = {
38
                        .icv_truncbits = 0,
39
                        .icv_fullbits = 0,
40
                }
41
        },
42
 
43
        .desc = {
44
                .sadb_alg_id = SADB_X_AALG_NULL,
45
                .sadb_alg_ivlen = 0,
46
                .sadb_alg_minbits = 0,
47
                .sadb_alg_maxbits = 0
48
        }
49
},
50
{
51
        .name = "hmac(md5)",
52
        .compat = "md5",
53
 
54
        .uinfo = {
55
                .auth = {
56
                        .icv_truncbits = 96,
57
                        .icv_fullbits = 128,
58
                }
59
        },
60
 
61
        .desc = {
62
                .sadb_alg_id = SADB_AALG_MD5HMAC,
63
                .sadb_alg_ivlen = 0,
64
                .sadb_alg_minbits = 128,
65
                .sadb_alg_maxbits = 128
66
        }
67
},
68
{
69
        .name = "hmac(sha1)",
70
        .compat = "sha1",
71
 
72
        .uinfo = {
73
                .auth = {
74
                        .icv_truncbits = 96,
75
                        .icv_fullbits = 160,
76
                }
77
        },
78
 
79
        .desc = {
80
                .sadb_alg_id = SADB_AALG_SHA1HMAC,
81
                .sadb_alg_ivlen = 0,
82
                .sadb_alg_minbits = 160,
83
                .sadb_alg_maxbits = 160
84
        }
85
},
86
{
87
        .name = "hmac(sha256)",
88
        .compat = "sha256",
89
 
90
        .uinfo = {
91
                .auth = {
92
                        .icv_truncbits = 96,
93
                        .icv_fullbits = 256,
94
                }
95
        },
96
 
97
        .desc = {
98
                .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
99
                .sadb_alg_ivlen = 0,
100
                .sadb_alg_minbits = 256,
101
                .sadb_alg_maxbits = 256
102
        }
103
},
104
{
105
        .name = "hmac(ripemd160)",
106
        .compat = "ripemd160",
107
 
108
        .uinfo = {
109
                .auth = {
110
                        .icv_truncbits = 96,
111
                        .icv_fullbits = 160,
112
                }
113
        },
114
 
115
        .desc = {
116
                .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
117
                .sadb_alg_ivlen = 0,
118
                .sadb_alg_minbits = 160,
119
                .sadb_alg_maxbits = 160
120
        }
121
},
122
{
123
        .name = "xcbc(aes)",
124
 
125
        .uinfo = {
126
                .auth = {
127
                        .icv_truncbits = 96,
128
                        .icv_fullbits = 128,
129
                }
130
        },
131
 
132
        .desc = {
133
                .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
134
                .sadb_alg_ivlen = 0,
135
                .sadb_alg_minbits = 128,
136
                .sadb_alg_maxbits = 128
137
        }
138
},
139
};
140
 
141
static struct xfrm_algo_desc ealg_list[] = {
142
{
143
        .name = "ecb(cipher_null)",
144
        .compat = "cipher_null",
145
 
146
        .uinfo = {
147
                .encr = {
148
                        .blockbits = 8,
149
                        .defkeybits = 0,
150
                }
151
        },
152
 
153
        .desc = {
154
                .sadb_alg_id =  SADB_EALG_NULL,
155
                .sadb_alg_ivlen = 0,
156
                .sadb_alg_minbits = 0,
157
                .sadb_alg_maxbits = 0
158
        }
159
},
160
{
161
        .name = "cbc(des)",
162
        .compat = "des",
163
 
164
        .uinfo = {
165
                .encr = {
166
                        .blockbits = 64,
167
                        .defkeybits = 64,
168
                }
169
        },
170
 
171
        .desc = {
172
                .sadb_alg_id = SADB_EALG_DESCBC,
173
                .sadb_alg_ivlen = 8,
174
                .sadb_alg_minbits = 64,
175
                .sadb_alg_maxbits = 64
176
        }
177
},
178
{
179
        .name = "cbc(des3_ede)",
180
        .compat = "des3_ede",
181
 
182
        .uinfo = {
183
                .encr = {
184
                        .blockbits = 64,
185
                        .defkeybits = 192,
186
                }
187
        },
188
 
189
        .desc = {
190
                .sadb_alg_id = SADB_EALG_3DESCBC,
191
                .sadb_alg_ivlen = 8,
192
                .sadb_alg_minbits = 192,
193
                .sadb_alg_maxbits = 192
194
        }
195
},
196
{
197
        .name = "cbc(cast128)",
198
        .compat = "cast128",
199
 
200
        .uinfo = {
201
                .encr = {
202
                        .blockbits = 64,
203
                        .defkeybits = 128,
204
                }
205
        },
206
 
207
        .desc = {
208
                .sadb_alg_id = SADB_X_EALG_CASTCBC,
209
                .sadb_alg_ivlen = 8,
210
                .sadb_alg_minbits = 40,
211
                .sadb_alg_maxbits = 128
212
        }
213
},
214
{
215
        .name = "cbc(blowfish)",
216
        .compat = "blowfish",
217
 
218
        .uinfo = {
219
                .encr = {
220
                        .blockbits = 64,
221
                        .defkeybits = 128,
222
                }
223
        },
224
 
225
        .desc = {
226
                .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
227
                .sadb_alg_ivlen = 8,
228
                .sadb_alg_minbits = 40,
229
                .sadb_alg_maxbits = 448
230
        }
231
},
232
{
233
        .name = "cbc(aes)",
234
        .compat = "aes",
235
 
236
        .uinfo = {
237
                .encr = {
238
                        .blockbits = 128,
239
                        .defkeybits = 128,
240
                }
241
        },
242
 
243
        .desc = {
244
                .sadb_alg_id = SADB_X_EALG_AESCBC,
245
                .sadb_alg_ivlen = 8,
246
                .sadb_alg_minbits = 128,
247
                .sadb_alg_maxbits = 256
248
        }
249
},
250
{
251
        .name = "cbc(serpent)",
252
        .compat = "serpent",
253
 
254
        .uinfo = {
255
                .encr = {
256
                        .blockbits = 128,
257
                        .defkeybits = 128,
258
                }
259
        },
260
 
261
        .desc = {
262
                .sadb_alg_id = SADB_X_EALG_SERPENTCBC,
263
                .sadb_alg_ivlen = 8,
264
                .sadb_alg_minbits = 128,
265
                .sadb_alg_maxbits = 256,
266
        }
267
},
268
{
269
        .name = "cbc(camellia)",
270
 
271
        .uinfo = {
272
                .encr = {
273
                        .blockbits = 128,
274
                        .defkeybits = 128,
275
                }
276
        },
277
 
278
        .desc = {
279
                .sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
280
                .sadb_alg_ivlen = 8,
281
                .sadb_alg_minbits = 128,
282
                .sadb_alg_maxbits = 256
283
        }
284
},
285
{
286
        .name = "cbc(twofish)",
287
        .compat = "twofish",
288
 
289
        .uinfo = {
290
                .encr = {
291
                        .blockbits = 128,
292
                        .defkeybits = 128,
293
                }
294
        },
295
 
296
        .desc = {
297
                .sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
298
                .sadb_alg_ivlen = 8,
299
                .sadb_alg_minbits = 128,
300
                .sadb_alg_maxbits = 256
301
        }
302
},
303
};
304
 
305
static struct xfrm_algo_desc calg_list[] = {
306
{
307
        .name = "deflate",
308
        .uinfo = {
309
                .comp = {
310
                        .threshold = 90,
311
                }
312
        },
313
        .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
314
},
315
{
316
        .name = "lzs",
317
        .uinfo = {
318
                .comp = {
319
                        .threshold = 90,
320
                }
321
        },
322
        .desc = { .sadb_alg_id = SADB_X_CALG_LZS }
323
},
324
{
325
        .name = "lzjh",
326
        .uinfo = {
327
                .comp = {
328
                        .threshold = 50,
329
                }
330
        },
331
        .desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
332
},
333
};
334
 
335
static inline int aalg_entries(void)
336
{
337
        return ARRAY_SIZE(aalg_list);
338
}
339
 
340
static inline int ealg_entries(void)
341
{
342
        return ARRAY_SIZE(ealg_list);
343
}
344
 
345
static inline int calg_entries(void)
346
{
347
        return ARRAY_SIZE(calg_list);
348
}
349
 
350
struct xfrm_algo_list {
351
        struct xfrm_algo_desc *algs;
352
        int entries;
353
        u32 type;
354
        u32 mask;
355
};
356
 
357
static const struct xfrm_algo_list xfrm_aalg_list = {
358
        .algs = aalg_list,
359
        .entries = ARRAY_SIZE(aalg_list),
360
        .type = CRYPTO_ALG_TYPE_HASH,
361
        .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
362
};
363
 
364
static const struct xfrm_algo_list xfrm_ealg_list = {
365
        .algs = ealg_list,
366
        .entries = ARRAY_SIZE(ealg_list),
367
        .type = CRYPTO_ALG_TYPE_BLKCIPHER,
368
        .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
369
};
370
 
371
static const struct xfrm_algo_list xfrm_calg_list = {
372
        .algs = calg_list,
373
        .entries = ARRAY_SIZE(calg_list),
374
        .type = CRYPTO_ALG_TYPE_COMPRESS,
375
        .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
376
};
377
 
378
static struct xfrm_algo_desc *xfrm_find_algo(
379
        const struct xfrm_algo_list *algo_list,
380
        int match(const struct xfrm_algo_desc *entry, const void *data),
381
        const void *data, int probe)
382
{
383
        struct xfrm_algo_desc *list = algo_list->algs;
384
        int i, status;
385
 
386
        for (i = 0; i < algo_list->entries; i++) {
387
                if (!match(list + i, data))
388
                        continue;
389
 
390
                if (list[i].available)
391
                        return &list[i];
392
 
393
                if (!probe)
394
                        break;
395
 
396
                status = crypto_has_alg(list[i].name, algo_list->type,
397
                                        algo_list->mask);
398
                if (!status)
399
                        break;
400
 
401
                list[i].available = status;
402
                return &list[i];
403
        }
404
        return NULL;
405
}
406
 
407
static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
408
                             const void *data)
409
{
410
        return entry->desc.sadb_alg_id == (unsigned long)data;
411
}
412
 
413
struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
414
{
415
        return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
416
                              (void *)(unsigned long)alg_id, 1);
417
}
418
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
419
 
420
struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
421
{
422
        return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
423
                              (void *)(unsigned long)alg_id, 1);
424
}
425
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
426
 
427
struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
428
{
429
        return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
430
                              (void *)(unsigned long)alg_id, 1);
431
}
432
EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
433
 
434
static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
435
                               const void *data)
436
{
437
        const char *name = data;
438
 
439
        return name && (!strcmp(name, entry->name) ||
440
                        (entry->compat && !strcmp(name, entry->compat)));
441
}
442
 
443
struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
444
{
445
        return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
446
                              probe);
447
}
448
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
449
 
450
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
451
{
452
        return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
453
                              probe);
454
}
455
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
456
 
457
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
458
{
459
        return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
460
                              probe);
461
}
462
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
463
 
464
struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
465
{
466
        if (idx >= aalg_entries())
467
                return NULL;
468
 
469
        return &aalg_list[idx];
470
}
471
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
472
 
473
struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
474
{
475
        if (idx >= ealg_entries())
476
                return NULL;
477
 
478
        return &ealg_list[idx];
479
}
480
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
481
 
482
/*
483
 * Probe for the availability of crypto algorithms, and set the available
484
 * flag for any algorithms found on the system.  This is typically called by
485
 * pfkey during userspace SA add, update or register.
486
 */
487
void xfrm_probe_algs(void)
488
{
489
#ifdef CONFIG_CRYPTO
490
        int i, status;
491
 
492
        BUG_ON(in_softirq());
493
 
494
        for (i = 0; i < aalg_entries(); i++) {
495
                status = crypto_has_hash(aalg_list[i].name, 0,
496
                                         CRYPTO_ALG_ASYNC);
497
                if (aalg_list[i].available != status)
498
                        aalg_list[i].available = status;
499
        }
500
 
501
        for (i = 0; i < ealg_entries(); i++) {
502
                status = crypto_has_blkcipher(ealg_list[i].name, 0,
503
                                              CRYPTO_ALG_ASYNC);
504
                if (ealg_list[i].available != status)
505
                        ealg_list[i].available = status;
506
        }
507
 
508
        for (i = 0; i < calg_entries(); i++) {
509
                status = crypto_has_comp(calg_list[i].name, 0,
510
                                         CRYPTO_ALG_ASYNC);
511
                if (calg_list[i].available != status)
512
                        calg_list[i].available = status;
513
        }
514
#endif
515
}
516
EXPORT_SYMBOL_GPL(xfrm_probe_algs);
517
 
518
int xfrm_count_auth_supported(void)
519
{
520
        int i, n;
521
 
522
        for (i = 0, n = 0; i < aalg_entries(); i++)
523
                if (aalg_list[i].available)
524
                        n++;
525
        return n;
526
}
527
EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
528
 
529
int xfrm_count_enc_supported(void)
530
{
531
        int i, n;
532
 
533
        for (i = 0, n = 0; i < ealg_entries(); i++)
534
                if (ealg_list[i].available)
535
                        n++;
536
        return n;
537
}
538
EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
539
 
540
/* Move to common area: it is shared with AH. */
541
 
542
int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
543
                 int offset, int len, icv_update_fn_t icv_update)
544
{
545
        int start = skb_headlen(skb);
546
        int i, copy = start - offset;
547
        int err;
548
        struct scatterlist sg;
549
 
550
        /* Checksum header. */
551
        if (copy > 0) {
552
                if (copy > len)
553
                        copy = len;
554
 
555
                sg_init_one(&sg, skb->data + offset, copy);
556
 
557
                err = icv_update(desc, &sg, copy);
558
                if (unlikely(err))
559
                        return err;
560
 
561
                if ((len -= copy) == 0)
562
                        return 0;
563
                offset += copy;
564
        }
565
 
566
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
567
                int end;
568
 
569
                BUG_TRAP(start <= offset + len);
570
 
571
                end = start + skb_shinfo(skb)->frags[i].size;
572
                if ((copy = end - offset) > 0) {
573
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
574
 
575
                        if (copy > len)
576
                                copy = len;
577
 
578
                        sg_init_table(&sg, 1);
579
                        sg_set_page(&sg, frag->page, copy,
580
                                    frag->page_offset + offset-start);
581
 
582
                        err = icv_update(desc, &sg, copy);
583
                        if (unlikely(err))
584
                                return err;
585
 
586
                        if (!(len -= copy))
587
                                return 0;
588
                        offset += copy;
589
                }
590
                start = end;
591
        }
592
 
593
        if (skb_shinfo(skb)->frag_list) {
594
                struct sk_buff *list = skb_shinfo(skb)->frag_list;
595
 
596
                for (; list; list = list->next) {
597
                        int end;
598
 
599
                        BUG_TRAP(start <= offset + len);
600
 
601
                        end = start + list->len;
602
                        if ((copy = end - offset) > 0) {
603
                                if (copy > len)
604
                                        copy = len;
605
                                err = skb_icv_walk(list, desc, offset-start,
606
                                                   copy, icv_update);
607
                                if (unlikely(err))
608
                                        return err;
609
                                if ((len -= copy) == 0)
610
                                        return 0;
611
                                offset += copy;
612
                        }
613
                        start = end;
614
                }
615
        }
616
        BUG_ON(len);
617
        return 0;
618
}
619
EXPORT_SYMBOL_GPL(skb_icv_walk);
620
 
621
#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
622
 
623
void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len)
624
{
625
        if (tail != skb) {
626
                skb->data_len += len;
627
                skb->len += len;
628
        }
629
        return skb_put(tail, len);
630
}
631
EXPORT_SYMBOL_GPL(pskb_put);
632
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.