2 * Modular extensions service and registration functions
4 * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
8 * $Id: ipsec_alg.c,v 1.3 2004-08-02 03:42:17 gerg Exp $
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 #define __NO_VERSION__
22 #include <linux/module.h>
23 #include <linux/kernel.h> /* printk() */
25 #include <linux/netdevice.h> /* struct device, and other headers */
26 #include <linux/etherdevice.h> /* eth_type_trans */
27 #include <linux/ip.h> /* struct iphdr */
28 #include <linux/skbuff.h>
29 #include <linux/socket.h>
31 #include <linux/types.h>
32 #include <linux/string.h> /* memcmp() */
33 #include <linux/random.h> /* get_random_bytes() */
34 #include <linux/errno.h> /* error codes */
37 # include <linux/spinlock.h> /* *lock* */
38 # else /* SPINLOCK_23 */
39 # include <asm/spinlock.h> /* *lock* */
40 # endif /* SPINLOCK_23 */
43 # include <asm/uaccess.h>
44 # include <linux/in6.h>
45 # define proto_priv cb
47 #include "ipsec_param.h"
50 #include "ipsec_encap.h"
51 #include "ipsec_radij.h"
52 #include "ipsec_netlink.h"
53 #include "ipsec_xform.h"
54 #include "ipsec_tunnel.h"
55 #include "ipsec_rcv.h"
56 #if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
57 # include "ipsec_ah.h"
58 #endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
59 #ifdef CONFIG_IPSEC_ESP
60 # include "ipsec_esp.h"
61 #endif /* !CONFIG_IPSEC_ESP */
62 #ifdef CONFIG_IPSEC_IPCOMP
64 #endif /* CONFIG_IPSEC_COMP */
70 #include "ipsec_alg.h"
72 #if SADB_EALG_MAX < 255
73 #warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
76 static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
77 #define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
78 static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
80 /* Old gcc's will fail here */
81 #define barf_out(fmt, args...) do { printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixt->ixt_name , ## args)\
82 ; goto out; } while(0)
85 * Must be already protected by lock
87 static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
89 __MOD_INC_USE_COUNT(ixt->ixt_module);
90 atomic_inc(&ixt->ixt_refcnt);
92 static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
93 atomic_dec(&ixt->ixt_refcnt);
95 __MOD_DEC_USE_COUNT(ixt->ixt_module);
98 * simple hash function, optimized for 0-hash (1 list) special
101 #if IPSEC_ALG_HASHSZ > 1
102 static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
103 return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
106 #define ipsec_alg_hashfn(x,y) (0)
109 /*****************************************************************
111 * INTERNAL table handling: insert, delete, find
113 *****************************************************************/
116 * hash table initialization, called from ipsec_alg_init()
118 static void ipsec_alg_hash_init(void) {
119 struct list_head *head = ipsec_alg_hash_table;
120 int i = IPSEC_ALG_HASHSZ;
122 INIT_LIST_HEAD(head);
128 * hash list lookup by {alg_type, alg_id} and table head,
129 * must be already protected by lock
131 static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
133 struct ipsec_alg *ixt=NULL;
134 for (p=head->next; p!=head; p=p->next) {
135 ixt = list_entry(p, struct ipsec_alg, ixt_list);
136 if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
145 * inserts (in front) a new entry in hash table,
146 * called from ipsec_alg_register() when new algorithm is registered.
148 static int ipsec_alg_insert(struct ipsec_alg *ixt) {
150 unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
151 struct list_head *head= ipsec_alg_hash_table + hashval;
152 /* new element must be virgin ... */
153 if (ixt->ixt_list.next != &ixt->ixt_list ||
154 ixt->ixt_list.prev != &ixt->ixt_list) {
155 printk(KERN_ERR "%s: ixt object \"%s\" "
156 "list head not initialized\n",
157 __FUNCTION__, ixt->ixt_name);
160 write_lock_bh(&ipsec_alg_lock);
161 if (__ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head))
162 barf_out(KERN_WARNING "ipsec_alg for alg_type=%d, alg_id=%d already exist."
163 "Not loaded (ret=%d).\n",
165 ixt->ixt_alg_id, ret=-EEXIST);
166 list_add(&ixt->ixt_list, head);
169 write_unlock_bh(&ipsec_alg_lock);
173 * deletes an existing entry in hash table,
174 * called from ipsec_alg_unregister() when algorithm is unregistered.
176 static int ipsec_alg_delete(struct ipsec_alg *ixt) {
177 write_lock_bh(&ipsec_alg_lock);
178 list_del(&ixt->ixt_list);
179 write_unlock_bh(&ipsec_alg_lock);
183 * here @user context (read-only when @kernel bh context)
186 * called from ipsec_sa_init() -> ipsec_alg_sa_init()
188 static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id) {
189 unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
190 struct list_head *head= ipsec_alg_hash_table + hashval;
191 struct ipsec_alg *ixt;
192 read_lock(&ipsec_alg_lock);
193 ixt=__ipsec_alg_find(alg_type, alg_id, head);
194 if (ixt) __ipsec_alg_usage_inc(ixt);
195 read_unlock(&ipsec_alg_lock);
199 static void ipsec_alg_put(struct ipsec_alg *ixt) {
200 __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
203 /*****************************************************************
205 * INTERFACE for ENC services: key creation, encrypt function
207 *****************************************************************/
210 * main encrypt service entry point
211 * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
212 * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
214 int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat, int ilen, const __u8 * iv, int encrypt) {
216 struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
217 KLIPS_PRINT(debug_rcv||debug_tunnel,
218 "klips_debug:ipsec_alg_esp_encrypt: "
219 "entering with encalg=%d, ixt_e=%p\n",
220 sa_p->ips_encalg, ixt_e);
222 KLIPS_PRINT(debug_rcv||debug_tunnel,
223 "klips_debug:ipsec_alg_esp_encrypt: "
224 "NULL ipsec_alg_enc object\n");
227 KLIPS_PRINT(debug_rcv||debug_tunnel,
228 "klips_debug:ipsec_alg_esp_encrypt: "
229 "calling cbc_encrypt encalg=%d "
230 "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
232 sa_p->ips_key_e, idat, ilen, iv, encrypt);
233 ret=ixt_e->ixt_e_cbc_encrypt(sa_p->ips_key_e, idat, idat, ilen, iv, encrypt);
234 KLIPS_PRINT(debug_rcv||debug_tunnel,
235 "klips_debug:ipsec_alg_esp_encrypt: "
241 * encryption key context creation function
242 * called from pfkey_v2_parser.c:pfkey_ips_init()
244 int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
246 int keyminbits, keymaxbits;
248 struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
250 KLIPS_PRINT(debug_pfkey,
251 "klips_debug:ipsec_alg_enc_key_create: "
252 "entering with encalg=%d ixt_e=%p\n",
253 sa_p->ips_encalg, ixt_e);
255 KLIPS_PRINT(debug_pfkey,
256 "klips_debug:ipsec_alg_enc_key_create: "
257 "NULL ipsec_alg_enc object\n");
260 if (ixt_e->ixt_e_validate_key) {
261 if ((ret=ixt_e->ixt_e_validate_key(sa_p)) < 0) {
262 KLIPS_PRINT(debug_pfkey,
263 "klips_debug:pfkey_ipsec_sa_init: "
264 "error calling validate_key() "
266 sa_p->ips_key_bits_e);
270 keyminbits=ixt_e->ixt_keyminbits;
271 keymaxbits=ixt_e->ixt_keymaxbits;
272 if(sa_p->ips_key_bits_e<keyminbits ||
273 sa_p->ips_key_bits_e>keymaxbits) {
274 KLIPS_PRINT(debug_pfkey,
275 "klips_debug:ipsec_alg_enc_key_create: "
276 "incorrect encryption key size: %d bits -- "
277 "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
278 sa_p->ips_key_bits_e, keyminbits, keymaxbits);
283 /* save encryption key pointer */
284 ekp = sa_p->ips_key_e;
286 if((sa_p->ips_key_e = (caddr_t)
287 kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
288 GFP_ATOMIC)) == NULL) {
293 memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
295 /* I cast here to allow more decoupling in alg module */
296 KLIPS_PRINT(debug_pfkey,
297 "klips_debug:ipsec_alg_enc_key_create: about to call:"
298 "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
299 (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
300 ret = ixt_e->ixt_e_set_key((caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
302 memset(ekp, 0, sa_p->ips_key_bits_e/8);
308 #ifdef USE_IXP4XX_CRYPTO
309 /* cipher block size extraction function */
310 void ipsec_alg_enc_blksize_create(struct ipsec_sa *sa_p) {
311 struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
313 /* Set cipher block size */
314 sa_p->ips_enc_blksize = ixt_e->ixt_blocksize;
316 #endif /* USE_IXP4XX_CRYPTO */
318 /***************************************************************
320 * INTERFACE for AUTH services: key creation, hash functions
322 ***************************************************************/
325 * auth key context creation function
326 * called from pfkey_v2_parser.c:pfkey_ips_init()
328 int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
330 struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
331 int keyminbits, keymaxbits;
332 #ifndef USE_IXP4XX_CRYPTO
335 #endif /* USE_IXP4XX_CRYPTO */
336 KLIPS_PRINT(debug_pfkey,
337 "klips_debug:ipsec_alg_auth_key_create: "
338 "entering with authalg=%d ixt_a=%p\n",
339 sa_p->ips_authalg, ixt_a);
341 KLIPS_PRINT(debug_pfkey,
342 "klips_debug:ipsec_alg_auth_key_create: "
343 "NULL ipsec_alg_auth object\n");
346 keyminbits=ixt_a->ixt_keyminbits;
347 keymaxbits=ixt_a->ixt_keymaxbits;
348 if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
349 KLIPS_PRINT(debug_pfkey,
350 "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
351 "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
352 sa_p->ips_key_bits_a, keyminbits, keymaxbits);
356 /* save auth key pointer */
357 sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
358 #ifndef USE_IXP4XX_CRYPTO
359 akp = sa_p->ips_key_a;
360 aks = sa_p->ips_key_a_size;
362 /* will hold: 2 ctx and a blocksize buffer: kb */
363 sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
364 if((sa_p->ips_key_a =
365 (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
369 ixt_a->ixt_a_hmac_set_key(sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
374 #endif /* USE_IXP4XX_CRYPTO */
378 int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) {
379 struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
381 KLIPS_PRINT(debug_pfkey,
382 "klips_debug:ipsec_sa_esp_hash: "
383 "NULL ipsec_alg_auth object\n");
386 KLIPS_PRINT(debug_tunnel|debug_rcv,
387 "klips_debug:ipsec_sa_esp_hash: "
388 "hashing %p (%d bytes) to %p (%d bytes)\n",
391 ixt_a->ixt_a_hmac_hash(sa_p->ips_key_a,
397 /***************************************************************
399 * INTERFACE for module loading,testing, and unloading
401 ***************************************************************/
403 /* validation for registering (enc) module */
404 static int check_enc(struct ipsec_alg_enc *ixt) {
406 if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX)
407 barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX);
408 if (ixt->ixt_blocksize==0) /* || ixt->ixt_blocksize%2) need for ESP_NULL */
409 barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
410 if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0)
412 if (ixt->ixt_keyminbits==0)
413 barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
414 if (ixt->ixt_keymaxbits==0)
415 barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
416 if (ixt->ixt_e_keylen==0)
417 barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
419 if (ixt->ixt_e_ctx_size==0)
420 barf_out(KERN_ERR "invalid key_e_size=%d\n", ixt->ixt_e_ctx_size);
421 if (ixt->ixt_e_cbc_encrypt==NULL)
422 barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
428 /* validation for registering (auth) module */
429 static int check_auth(struct ipsec_alg_auth *ixt) {
431 if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX)
432 barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX);
433 if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2)
434 barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
435 if (ixt->ixt_blocksize>AH_BLKLEN_MAX)
436 barf_out(KERN_ERR "sorry blocksize=%d > %d. "
437 "Please increase AH_BLKLEN_MAX and recompile\n",
440 if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0)
442 if (ixt->ixt_keyminbits==0)
443 barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
444 if (ixt->ixt_keymaxbits==0)
445 barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
446 if (ixt->ixt_keymaxbits!=ixt->ixt_keyminbits)
447 barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
448 if (ixt->ixt_a_keylen==0)
449 barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
451 if (ixt->ixt_a_ctx_size==0)
452 barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
453 if (ixt->ixt_a_hmac_set_key==NULL)
454 barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
455 if (ixt->ixt_a_hmac_hash==NULL)
456 barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
463 * Generic (enc, auth) registration entry point
465 int register_ipsec_alg(struct ipsec_alg *ixt) {
469 barf_out("NULL ipsec_alg object passed\n");
470 if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
471 barf_out("incorrect version: %d.%d.%d-%d, "
472 "must be %d.%d.%d[-%d]\n",
473 IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
474 IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
475 switch(ixt->ixt_alg_type) {
476 case IPSEC_ALG_TYPE_AUTH:
477 if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
480 case IPSEC_ALG_TYPE_ENCRYPT:
481 if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
483 if (ixt->ixt_ivlen == 0)
484 ixt->ixt_ivlen = ixt->ixt_blocksize*8;
487 barf_out("alg_type=%d not supported", ixt->ixt_alg_type);
489 INIT_LIST_HEAD(&ixt->ixt_list);
490 ret = ipsec_alg_insert(ixt);
492 barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
493 "Not loaded (ret=%d).\n",
494 ixt->ixt_alg_id, ret);
496 ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
498 ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
499 /* send register event to userspace */
500 pfkey_register_reply(SADB_SATYPE_ESP, NULL);
502 printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
503 "Loading anyway.\n", ret);
510 * unregister ipsec_alg object from own tables, if
511 * success => calls pfkey_list_remove_supported()
513 int unregister_ipsec_alg(struct ipsec_alg *ixt) {
515 switch(ixt->ixt_alg_type) {
516 case IPSEC_ALG_TYPE_AUTH:
517 case IPSEC_ALG_TYPE_ENCRYPT:
520 /* this is not a typo :) */
521 barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
525 ret=ipsec_alg_delete(ixt);
526 if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
527 ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
528 pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
529 /* send register event to userspace */
530 pfkey_register_reply(SADB_SATYPE_ESP, NULL);
537 * Must be called from user context
538 * used at module load type for testing algo implementation
540 static int ipsec_alg_test_encrypt(int enc_alg, int test) {
543 int iv_size, keysize, key_e_size;
544 struct ipsec_alg_enc *ixt_e;
547 #define test_enc (buf+MARGIN)
548 #define test_dec (test_enc+BUFSZ+MARGIN)
549 #define test_tmp (test_dec+BUFSZ+MARGIN)
550 #define test_key_e (test_tmp+BUFSZ+MARGIN)
551 #define test_iv (test_key_e+key_e_size+MARGIN)
552 #define test_key (test_iv+iv_size+MARGIN)
553 #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
554 ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
558 "encalg=%d object not found\n",
559 __FUNCTION__, enc_alg);
563 iv_size=ixt_e->ixt_blocksize;
564 key_e_size=ixt_e->ixt_e_ctx_size;
565 keysize=ixt_e->ixt_e_keylen;
568 "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
569 __FUNCTION__, enc_alg, iv_size, key_e_size, keysize);
570 if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
574 get_random_bytes(test_key, keysize);
575 get_random_bytes(test_iv, iv_size);
576 ixt_e->ixt_e_set_key(test_key_e, test_key, keysize);
577 get_random_bytes(test_enc, BUFSZ);
578 memcpy(test_tmp, test_enc, BUFSZ);
579 ret=ixt_e->ixt_e_cbc_encrypt(test_key_e, test_enc, test_enc, BUFSZ, test_iv, 1);
582 "cbc_encrypt=1 ret=%d\n",
584 ret=memcmp(test_enc, test_tmp, BUFSZ);
587 "memcmp(enc, tmp) ret=%d: %s\n", ret,
589 ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
590 memcpy(test_dec, test_enc, BUFSZ);
591 ret=ixt_e->ixt_e_cbc_encrypt(test_key_e, test_dec, test_dec, BUFSZ, test_iv, 0);
594 "cbc_encrypt=0 ret=%d\n", __FUNCTION__, ret);
595 ret=memcmp(test_dec, test_tmp, BUFSZ);
598 "memcmp(dec,tmp) ret=%d: %s\n", __FUNCTION__, ret,
599 ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
601 /* Shamelessly taken from drivers/md sources O:) */
605 for (encrypt=0; encrypt <2;encrypt ++) {
606 for (i = 0; i < 5; i++) {
609 while (jiffies == now) {
611 ixt_e->ixt_e_cbc_encrypt(test_key_e, test_tmp, test_tmp, BUFSZ, test_iv, encrypt);
619 speed = max * (HZ * BUFSZ / 1024);
622 "%s %s speed=%d KB/s\n",
623 __FUNCTION__, ixt_e->ixt_name,
624 encrypt? "encrypt": "decrypt", speed);
628 ipsec_alg_put((struct ipsec_alg *)ixt_e);
640 * Must be called from user context
641 * used at module load type for testing algo implementation
643 static int ipsec_alg_test_auth(int auth_alg, int test) {
646 int blocksize, keysize, key_a_size;
647 struct ipsec_alg_auth *ixt_a;
650 #define test_auth (buf+MARGIN)
651 #define test_key_a (test_auth+BUFSZ+MARGIN)
652 #define test_key (test_key_a+key_a_size+MARGIN)
653 #define test_hash (test_key+keysize+MARGIN)
654 #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
655 ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
659 "encalg=%d object not found\n",
660 __FUNCTION__, auth_alg);
664 blocksize=ixt_a->ixt_blocksize;
665 key_a_size=ixt_a->ixt_a_ctx_size;
666 keysize=ixt_a->ixt_a_keylen;
669 "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
670 __FUNCTION__, auth_alg, blocksize, key_a_size, keysize);
671 if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
675 get_random_bytes(test_key, keysize);
676 ixt_a->ixt_a_hmac_set_key(test_key_a, test_key, keysize);
677 get_random_bytes(test_auth, BUFSZ);
678 ret=ixt_a->ixt_a_hmac_hash(test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
681 "ret=%d\n", __FUNCTION__, ret);
683 /* Shamelessly taken from drivers/md sources O:) */
687 for (i = 0; i < 5; i++) {
690 while (jiffies == now) {
692 ixt_a->ixt_a_hmac_hash(test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
700 speed = max * (HZ * BUFSZ / 1024);
703 "%s hash speed=%d KB/s\n",
704 __FUNCTION__, ixt_a->ixt_name,
708 ipsec_alg_put((struct ipsec_alg *)ixt_a);
717 int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
719 case IPSEC_ALG_TYPE_ENCRYPT:
720 return ipsec_alg_test_encrypt(alg_id, test);
722 case IPSEC_ALG_TYPE_AUTH:
723 return ipsec_alg_test_auth(alg_id, test);
726 printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
727 "alg_type=%d alg_id=%d\n",
731 int ipsec_alg_init(void) {
732 KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
733 "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
734 IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
735 SADB_EALG_MAX, SADB_AALG_MAX);
736 /* Initialize tables */
737 write_lock_bh(&ipsec_alg_lock);
738 ipsec_alg_hash_init();
739 write_unlock_bh(&ipsec_alg_lock);
740 /* Initialize static algos */
741 KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
742 "calling ipsec_alg_static_init()\n");
743 ipsec_alg_static_init();
747 /**********************************************
749 * INTERFACE for ipsec_sa init and wipe
751 **********************************************/
754 * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
756 int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
757 struct ipsec_alg_enc *ixt_e;
758 struct ipsec_alg_auth *ixt_a;
760 /* Only ESP for now ... */
761 if (sa_p->ips_said.proto != IPPROTO_ESP)
762 return -EPROTONOSUPPORT;
763 KLIPS_PRINT(debug_pfkey, "klips_debug: %s() :"
764 "entering for encalg=%d, authalg=%d\n",
765 __FUNCTION__, sa_p->ips_encalg, sa_p->ips_authalg);
766 if ((ixt_e=(struct ipsec_alg_enc *)
767 ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
768 KLIPS_PRINT(debug_pfkey,
769 "klips_debug: %s() :"
770 "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
771 __FUNCTION__, ixt_e, sa_p->ips_encalg);
772 sa_p->ips_alg_enc=ixt_e;
774 if ((ixt_a=(struct ipsec_alg_auth *)
775 ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
776 KLIPS_PRINT(debug_pfkey,
777 "klips_debug: %s() :"
778 "found ipsec_alg (ixt_a=%p) for auth=%d\n",
779 __FUNCTION__, ixt_a, sa_p->ips_authalg);
780 sa_p->ips_alg_auth=ixt_a;
786 * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
788 int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
789 struct ipsec_alg *ixt;
790 if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
791 KLIPS_PRINT(debug_pfkey, "klips_debug: %s() :"
792 "unlinking for encalg=%d\n",
793 __FUNCTION__, ixt->ixt_alg_id);
796 if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
797 KLIPS_PRINT(debug_pfkey, "klips_debug: %s() :"
798 "unlinking for authalg=%d\n",
799 __FUNCTION__, ixt->ixt_alg_id);
805 * As the author of this module, I ONLY ALLOW using it from
806 * GPL (or same LICENSE TERMS as kernel source) modules.
808 * In respect to hardware crypto engines this means:
809 * * Closed-source device drivers ARE NOT ALLOWED to use
811 * * Closed-source VHDL/Verilog firmware running on
812 * the crypto hardware device IS ALLOWED to use this interface
813 * via a GPL (or same LICENSE TERMS as kernel source) device driver.
814 * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
818 * These symbols can only be used from GPL modules
819 * for now, I'm disabling this because it creates false
820 * symbol problems for old modutils.
823 /* #ifndef EXPORT_SYMBOL_GPL */
824 #undef EXPORT_SYMBOL_GPL
825 #define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
827 EXPORT_SYMBOL_GPL(register_ipsec_alg);
828 EXPORT_SYMBOL_GPL(unregister_ipsec_alg);
829 EXPORT_SYMBOL_GPL(ipsec_alg_test);