ia64/xen-unstable

view tools/vnet/vnet-module/sa.c @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
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 }