ia64/xen-unstable

view tools/vnet/vnet-module/sa.c @ 8740:3d7ea7972b39

Update patches for linux 2.6.15.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Thu Feb 02 17:16:00 2006 +0000 (2006-02-02)
parents 0a4b76b6b5a0
children 71b0f00f6344
line source
1 /*
2 * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free software Foundation, Inc.,
16 * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19 #include <linux/config.h>
20 #include <linux/kernel.h>
22 #include <net/ip.h>
23 #include <net/protocol.h>
24 #include <net/route.h>
25 #include <linux/skbuff.h>
27 #include <linux/in.h>
28 #include <linux/inet.h>
29 #include <linux/netdevice.h>
31 #include <sa.h>
32 #include <sa_algorithm.h>
33 #include "hash_table.h"
34 #include "allocate.h"
36 #define MODULE_NAME "IPSEC"
37 #define DEBUG 1
38 #undef DEBUG
39 #include "debug.h"
41 /** @file IPSEC Security Association (SA).
42 */
44 /** Maximum number of protocols.*/
45 #define INET_PROTOCOL_MAX 256
47 /** Table of SA types indexed by protocol. */
48 static SAType *sa_type[INET_PROTOCOL_MAX] = {};
50 /** Hash a protocol number.
51 *
52 * @param protocol protocol number
53 * @return hashcode
54 */
55 static inline unsigned char InetProtocol_hash(int protocol){
56 return (protocol) & (INET_PROTOCOL_MAX - 1);
57 }
59 /** Register an SA type.
60 * It is an error if an SA type is already registered for the protocol.
61 *
62 * @param type SA type
63 * @return 0 on success, error code otherwise
64 */
65 int SAType_add(SAType *type){
66 int err = -EINVAL;
67 int hash;
68 if(!type) goto exit;
69 hash = InetProtocol_hash(type->protocol);
70 if(sa_type[hash]) goto exit;
71 err = 0;
72 sa_type[hash] = type;
73 exit:
74 return err;
75 }
77 /** Deregister an SA type.
78 * It is an error if no SA type is registered for the protocol.
79 *
80 * @param type SA type
81 * @return 0 on success, error code otherwise
82 */
83 int SAType_del(SAType *type){
84 int err = -EINVAL;
85 int hash;
86 if(!type) goto exit;
87 hash = InetProtocol_hash(type->protocol);
88 if(!sa_type[hash]) goto exit;
89 err = 0;
90 sa_type[hash] = NULL;
91 exit:
92 return err;
93 }
95 int SAType_get(int protocol, SAType **type){
96 int err = -ENOENT;
97 int hash;
98 hash = InetProtocol_hash(protocol);
99 *type = sa_type[hash];
100 if(!*type) goto exit;
101 err = 0;
102 exit:
103 return err;
104 }
106 /* Defeat compiler warnings about unused functions. */
107 static int sa_key_check(SAKey *key, enum sa_alg_type type) __attribute__((unused));
108 static u32 random_spi(void) __attribute__((unused));
109 static u32 generate_key(u32 key, u32 offset, u32 spi) __attribute__((unused));
111 /** Check a key has an acceptable length for an algorithm.
112 *
113 * @param key key
114 * @param type algorithm
115 * @return 0 on success, error code otherwise
116 */
117 static int sa_key_check(SAKey *key, enum sa_alg_type type){
118 return 0;
119 }
121 static unsigned long sa_spi_counter = 0;
123 /** Generate a random spi.
124 * Uses a hashed counter.
125 *
126 * @return spi
127 */
128 static u32 random_spi(void){
129 unsigned long left, right = 0;
130 u32 spi;
131 do{
132 left = sa_spi_counter++;
133 pseudo_des(&left, &right);
134 spi = right;
135 } while(!spi);
136 return spi;
137 }
139 /** Mangle some input to generate output.
140 * This is used to derive spis and keying material from secrets,
141 * so it probably ought to be cryptographically strong.
142 * Probably ought to use a good hash (sha1) or cipher (aes).
143 *
144 * @param input input values
145 * @param n number of values
146 * @return mangled value
147 */
148 static u32 mangle(u32 input[], int n){
149 unsigned long left = 0, right = 0;
150 int i;
151 for(i=0; i<n; i++){
152 left ^= input[i];
153 pseudo_des(&left, &right);
154 }
155 return (u32)right;
156 }
158 /** Generate a spi for a given protocol and address, using a secret key.
159 * The offset is used when it is necessary to generate more than one spi
160 * for the same protocol and address.
161 *
162 * @param key key
163 * @param offset offset
164 * @param protocol protocol
165 * @param addr IP address
166 * @return spi
167 */
168 static u32 generate_spi(u32 key, u32 offset, u32 protocol, u32 addr){
169 u32 input[] = { key, offset, protocol, addr };
170 u32 spi;
171 dprintf(">\n");
172 spi = mangle(input, 4);
173 dprintf("< spi=%x\n", spi);
174 return spi;
175 }
177 /** Generate keying material for a given spi, based on a
178 * secret.
179 *
180 * @param key secret
181 * @param offset offset
182 * @param spi spi
183 * @return keying material
184 */
185 static u32 generate_key(u32 key, u32 offset, u32 spi){
186 u32 input[] = { key, offset, spi };
187 return mangle(input, 3);
188 }
190 /** Allocate a spi.
191 * Want to use random ones.
192 * So check for ones not in use.
193 *
194 * When using static keying, both ends need to agree on key.
195 * How does that work? Also, will suddenly get traffic using a spi,
196 * and will have to create SA then. Or need to create in advance.
197 * But can't do that because don't know peers.
198 * When get message on a spi that doesn't exist - do what?
199 * Use a spi related to the destination addr and a secret.
200 * Then receiver can check if spi is ok and create SA on demand.
201 * Use hash of key, protocol, addr to generate. Then have to check
202 * for in-use because of potential collisions. Receiver can do the
203 * same hash and check spi is in usable range. Then derive keys from
204 * the spi (using another secret).
205 *
206 * @param key spi generation key
207 * @param protocol protocol
208 * @param addr IP address
209 * @param spip return parameter for spi
210 * @return 0 on success, error code otherwise
211 */
212 int sa_spi_alloc(u32 key, u32 protocol, u32 addr, u32 *spip){
213 int err = 0;
214 int i = 0, n = 100;
215 u32 spi;
216 for(i = 0; i < n; i++, spi++){
217 spi = generate_spi(key, i, protocol, addr);
218 if(!spi) continue;
219 if(!sa_table_lookup_spi(spi, protocol, addr)){
220 *spip = spi;
221 goto exit;
222 }
223 }
224 err = -ENOMEM;
225 exit:
226 return err;
227 }
229 /** Table of SAs. Indexed by unique id and spi/protocol/addr triple.
230 */
231 static HashTable *sa_table = NULL;
233 static u32 sa_id = 1;
235 /** Hash an SA id.
236 *
237 * @param id SA id
238 * @return hashcode
239 */
240 static inline Hashcode sa_table_hash_id(u32 id){
241 return hash_ul(id);
242 }
244 /** Hash SA spi/protocol/addr.
245 *
246 * @param spi spi
247 * @param protocol protocol
248 * @param addr IP address
249 * @return hashcode
250 */
251 static inline Hashcode sa_table_hash_spi(u32 spi, u32 protocol, u32 addr){
252 Hashcode h = 0;
253 h = hash_2ul(spi, protocol);
254 h = hash_hul(h, addr);
255 return h;
256 }
258 /** Test if an SA entry has a given value.
259 *
260 * @param arg contains SA pointer
261 * @param table hashtable
262 * @param entry entry containing SA
263 * @return 1 if it does, 0 otherwise
264 */
265 static int sa_table_state_fn(TableArg arg, HashTable *table, HTEntry *entry){
266 return entry->value == arg.ptr;
267 }
269 /** Test if an SA entry has a given id.
270 *
271 * @param arg contains SA id
272 * @param table hashtable
273 * @param entry entry containing SA
274 * @return 1 if it does, 0 otherwise
275 */
276 static int sa_table_id_fn(TableArg arg, HashTable *table, HTEntry *entry){
277 SAState *state = entry->value;
278 u32 id = arg.ul;
279 return state->ident.id == id;
280 }
282 /** Test if an SA entry has a given spi/protocol/addr.
283 *
284 * @param arg contains SAIdent pointer
285 * @param table hashtable
286 * @param entry entry containing SA
287 * @return 1 if it does, 0 otherwise
288 */
289 static int sa_table_spi_fn(TableArg arg, HashTable *table, HTEntry *entry){
290 SAState *state = entry->value;
291 SAIdent *ident = arg.ptr;
292 return state->ident.spi == ident->spi
293 && state->ident.protocol == ident->protocol
294 && state->ident.addr == ident->addr;
295 }
297 /** Free an SA entry. Decrements the SA refcount and frees the entry.
298 *
299 * @param table containing table
300 * @param entry to free
301 */
302 void sa_table_free_fn(HashTable *table, HTEntry *entry){
303 if(!entry) return;
304 if(entry->value){
305 SAState *state = entry->value;
306 SAState_decref(state);
307 }
308 deallocate(entry);
309 }
311 /** Initialize the SA table.
312 *
313 * @return 0 on success, error code otherwise
314 */
315 int sa_table_init(void){
316 int err = 0;
317 sa_table = HashTable_new(0);
318 if(!sa_table){
319 err = -ENOMEM;
320 goto exit;
321 }
322 sa_table->entry_free_fn = sa_table_free_fn;
324 exit:
325 return err;
326 }
328 void sa_table_exit(void){
329 HashTable_free(sa_table);
330 }
332 /** Remove an SA from the table.
333 *
334 * @param state SA
335 */
336 int sa_table_delete(SAState *state){
337 int count = 0;
338 Hashcode h1, h2;
339 TableArg arg = { .ptr = state };
340 // Remove by id.
341 h1 = sa_table_hash_id(state->ident.id);
342 count += HashTable_remove_entry(sa_table, h1, sa_table_state_fn, arg);
343 // Remove by spi/protocol/addr if spi nonzero.
344 if(!state->ident.spi) goto exit;
345 h2 = sa_table_hash_spi(state->ident.spi, state->ident.protocol, state->ident.addr);
346 if(h1 == h2) goto exit;
347 count += HashTable_remove_entry(sa_table, h2, sa_table_state_fn, arg);
348 exit:
349 return count;
350 }
352 /** Add an SA to the table.
353 * The SA is indexed by id and spi/protocol/addr (if the spi is non-zero).
354 *
355 * @param state SA
356 * @return 0 on success, error code otherwise
357 */
358 int sa_table_add(SAState *state){
359 int err = 0;
360 Hashcode h1, h2;
361 int entries = 0;
363 dprintf(">\n");
364 // Index by id.
365 h1 = sa_table_hash_id(state->ident.id);
366 if(!HashTable_add_entry(sa_table, h1, HKEY(state->ident.id), state)){
367 err = -ENOMEM;
368 goto exit;
369 }
370 entries++;
371 SAState_incref(state);
372 // Index by spi/protocol/addr if spi non-zero.
373 if(state->ident.spi){
374 h2 = sa_table_hash_spi(state->ident.spi, state->ident.protocol, state->ident.addr);
375 if(h1 != h2){
376 if(!HashTable_add_entry(sa_table, h2, HKEY(state->ident.id), state)){
377 err = -ENOMEM;
378 goto exit;
379 }
380 entries++;
381 SAState_incref(state);
382 }
383 }
384 exit:
385 if(err && entries){
386 sa_table_delete(state);
387 }
388 dprintf("< err=%d\n", err);
389 return err;
390 }
393 /** Find an SA by spi/protocol/addr.
394 * Increments the SA refcount on success.
395 *
396 * @param spi spi
397 * @param protocol protocol
398 * @param addr IP address
399 * @return SA or NULL
400 */
401 SAState * sa_table_lookup_spi(u32 spi, u32 protocol, u32 addr){
402 SAState *state = NULL;
403 Hashcode h;
404 SAIdent id = {
405 .spi = spi,
406 .protocol = protocol,
407 .addr = addr };
408 TableArg arg = { .ptr = &id };
409 HTEntry *entry = NULL;
411 h = sa_table_hash_spi(spi, protocol, addr);
412 entry = HashTable_find_entry(sa_table, h, sa_table_spi_fn, arg);
413 if(entry){
414 state = entry->value;
415 SAState_incref(state);
416 }
417 return state;
418 }
420 /** Find an SA by unique id.
421 * Increments the SA refcount on success.
422 *
423 * @param id id
424 * @return SA or NULL
425 */
426 SAState * sa_table_lookup_id(u32 id){
427 Hashcode h;
428 TableArg arg = { .ul = id };
429 HTEntry *entry = NULL;
430 SAState *state = NULL;
432 dprintf("> id=%u\n", id);
433 h = sa_table_hash_id(id);
434 entry = HashTable_find_entry(sa_table, h, sa_table_id_fn, arg);
435 if(entry){
436 state = entry->value;
437 SAState_incref(state);
438 }
439 dprintf("< state=%p\n", state);
440 return state;
441 }
443 /** Replace an existing SA by another in the table.
444 * The existing SA is not removed if the new one cannot be added.
445 *
446 * @param existing SA to replace
447 * @param state new SA
448 * @return 0 on success, error code otherwise
449 */
450 static int sa_table_replace(SAState *existing, SAState *state){
451 int err = 0;
452 // Need check for in-use?
454 dprintf(">\n");
455 if(existing->keying.state != SA_STATE_ACQUIRE){
456 err = -EINVAL;
457 goto exit;
458 }
459 // replace it.
460 err = sa_table_add(state);
461 if(err) goto exit;
462 sa_table_delete(existing);
463 exit:
464 dprintf("< err=%d\n", err);
465 return err;
466 }
468 /** Allocate an SA.
469 *
470 * @return SA or NULL
471 */
472 SAState *SAState_alloc(void){
473 SAState *state;
475 dprintf(">\n");
476 state = kmalloc(sizeof(SAState), GFP_ATOMIC);
477 if(!state) goto exit;
478 *state = (SAState){};
479 atomic_set(&state->refcount, 1);
480 state->lock = SPIN_LOCK_UNLOCKED;
481 exit:
482 dprintf("< state=%p\n", state);
483 return state;
484 }
486 /** Create an SA in initial state.
487 * It has no spi and its keying state is acquire.
488 * It must have a unique id, protocol and address.
489 * At some point it should get updated with a complete SA.
490 *
491 * @param ident SA identifier
492 * @param statep return parameter for new SA
493 * @return 0 on success, error code otherwise
494 */
495 int SAState_init(SAIdent *ident, SAState **statep){
496 int err = 0;
497 SAState *state = NULL;
499 if(ident->spi || !ident->id){
500 err = -EINVAL;
501 goto exit;
502 }
503 state = SAState_alloc();
504 if (!state){
505 err = -ENOMEM;
506 goto exit;
507 }
508 state->ident = *ident;
509 state->keying.state = SA_STATE_ACQUIRE;
510 exit:
511 return err;
512 }
514 /** Create a complete SA, with spi and cipher suite.
515 *
516 * @param info SA parameters
517 * @param statep return parameter for new SA
518 * @return 0 on success, error code otherwise
519 */
520 int SAState_create(SAInfo *info, SAState **statep){
521 int err = 0;
522 SAState *state = NULL;
524 dprintf(">\n");
525 state = SAState_alloc();
526 if (!state){
527 err = -ENOMEM;
528 goto exit;
529 }
530 state->ident = info->ident;
531 state->limits = info->limits;
532 state->digest = info->digest;
533 state->cipher = info->cipher;
534 state->compress = info->compress;
535 state->security = info->security;
536 err = SAType_get(state->ident.protocol, &state->type);
537 if (err) goto exit;
538 err = state->type->init(state, NULL);
539 if (err) goto exit;
540 state->keying.state = SA_STATE_VALID;
541 exit:
542 if(err){
543 SAState_decref(state);
544 state = NULL;
545 }
546 *statep = state;
547 dprintf("< err=%d\n", err);
548 return err;
549 }
551 /** Create an SA for the given spi etc.
552 * For now we fix the cipher suite and the keys.
553 * Digest is SHA1 HMAC with a 128-bit key.
554 * Cipher is AES (Rijndael) in CBC mode with a 128-bit key.
555 *
556 * The cipher suite and keys should really come from policy, with the
557 * possibility of negotiating them with the peer (using IKE).
558 * Negotiation creates difficulties though - because the SA cannot
559 * be created immediately we have to be able to queue packets
560 * while the SA is being negotiated.
561 *
562 * @param spi spi
563 * @param protocol protocol
564 * @param addr address
565 * @param sa return parameter for SA
566 * @return 0 on success, error code otherwise
567 */
568 int sa_create(int security, u32 spi, u32 protocol, u32 addr, SAState **sa){
569 int err = 0;
570 SAInfo info = {};
571 char *digest_name = "sha1";
572 char *digest_key = "0123456789abcdef";
573 int digest_key_n = strlen(digest_key);
574 char *cipher_name= "aes";
575 char *cipher_key = "0123456789ABCDEF";
576 int cipher_key_n = strlen(cipher_key);
578 dprintf("> security=%d spi=%u protocol=%u addr=" IPFMT "\n",
579 security, spi, protocol, NIPQUAD(addr));
580 if(!spi){
581 spi = generate_spi(0, 0, protocol, addr);
582 }
583 dprintf("> info...\n");
584 info.ident.id = sa_id++;
585 info.ident.spi = spi;
586 info.ident.protocol = protocol;
587 info.ident.addr = addr;
588 info.security = security;
590 //sa_algorithm_probe_all();
592 dprintf("> digest name=%s key_n=%d\n", digest_name, digest_key_n);
593 strcpy(info.digest.name, digest_name);
594 info.digest.bits = digest_key_n * 8;
595 memcpy(info.digest.key, digest_key, digest_key_n);
597 if(security & SA_CONF){
598 dprintf("> cipher name=%s key_n=%d\n", cipher_name, cipher_key_n);
599 strcpy(info.cipher.name, cipher_name);
600 info.cipher.bits = cipher_key_n * 8;
601 memcpy(info.cipher.key, cipher_key, cipher_key_n);
602 } else {
603 dprintf("> cipher name=%s key_n=%d\n", "cipher_null", 0);
604 strcpy(info.cipher.name, "cipher_null");
605 info.cipher.bits = 0;
606 memset(info.cipher.key, 0, sizeof(info.cipher.key));
607 }
609 err = sa_set(&info, 0, sa);
610 dprintf("< err=%d\n", err);
611 return err;
612 }
614 /** Create or update an SA.
615 * The SA is added to the table.
616 *
617 * @param info SA parameters
618 * @param update create if zero, update otherwise
619 * @return 0 on success, error code otherwise
620 */
621 int sa_set(SAInfo *info, int update, SAState **val){
622 int err = 0;
623 SAState *state = NULL;
624 SAState *existing = NULL;
626 dprintf("> info=%p update=%d val=%p\n", info, update, val);
627 existing = sa_table_lookup_id(info->ident.id);
628 if(update && !existing){
629 err = -ENOENT;
630 } else if(!update && existing){
631 err = -EINVAL;
632 }
633 if(err) goto exit;
634 err = SAState_create(info, &state);
635 if (err) goto exit;
636 if(existing){
637 err = sa_table_replace(existing, state);
638 } else {
639 err = sa_table_add(state);
640 }
641 exit:
642 if(existing) SAState_decref(existing);
643 if(val && !err){
644 *val = state;
645 } else {
646 SAState_decref(state);
647 }
648 dprintf("< err=%d\n", err);
649 return err;
650 }
652 /** Delete an SA. Removes it from the SA table.
653 * It is an error if no SA with the given id exists.
654 *
655 * @param id SA id
656 * @return 0 on success, error code otherwise
657 */
658 int sa_delete(int id){
659 int err = 0;
660 SAState *state;
661 state = sa_table_lookup_id(id);
662 if (!state){
663 err = -ENOENT;
664 goto exit;
665 }
666 sa_table_delete(state);
667 SAState_decref(state);
668 exit:
669 return err;
670 }