diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-06-23 11:25:24 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2009-06-23 11:25:24 +0000 |
commit | 41787e147279ff0695e9d759487266a60b80867b (patch) | |
tree | 8f28566c8fd7106c80d2536d2df540dbb4499cc5 /src/pluto/kernel_alg.c | |
parent | c3e7f611ea8273c6b3909cb006ade4903a74aad0 (diff) | |
download | vyos-strongswan-41787e147279ff0695e9d759487266a60b80867b.tar.gz vyos-strongswan-41787e147279ff0695e9d759487266a60b80867b.zip |
[svn-upgrade] Integrating new upstream version, strongswan (4.3.2)
Diffstat (limited to 'src/pluto/kernel_alg.c')
-rw-r--r-- | src/pluto/kernel_alg.c | 1163 |
1 files changed, 552 insertions, 611 deletions
diff --git a/src/pluto/kernel_alg.c b/src/pluto/kernel_alg.c index 571d9cc9b..1590bdf02 100644 --- a/src/pluto/kernel_alg.c +++ b/src/pluto/kernel_alg.c @@ -1,5 +1,6 @@ /* Kernel runtime algorithm handling interface - * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> + * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> + * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -10,8 +11,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * - * RCSID $Id: kernel_alg.c 3252 2007-10-06 21:24:50Z andreas $ */ #include <stdio.h> @@ -27,7 +26,6 @@ #include <pfkey.h> #include <freeswan.h> -#include <ipsec_policy.h> #include "constants.h" #include "defs.h" @@ -38,22 +36,10 @@ #include "kernel.h" #include "kernel_alg.h" #include "alg_info.h" - -#ifndef NO_PLUTO #include "log.h" #include "whack.h" #include "db_ops.h" -#else -/* - * macros/functions for compilation without pluto (eg: spi for manual conns) - */ -extern int debug; -#include <assert.h> -#define passert(x) assert(x) -#define DBG(cond, action) { if (debug) { action ; } } -#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args); -#define plog(x, args...) fprintf(stderr, x "\n" , ##args); -#endif /* NO_PLUTO */ + /* ALG storage */ static struct sadb_alg esp_aalg[SADB_AALG_MAX+1]; static struct sadb_alg esp_ealg[SADB_EALG_MAX+1]; @@ -62,714 +48,669 @@ static int esp_aalg_num = 0; #define ESP_EALG_PRESENT(algo) (((algo)<=SADB_EALG_MAX)&&(esp_ealg[(algo)].sadb_alg_id==(algo))) #define ESP_EALG_FOR_EACH_UPDOWN(algo) \ - for (algo=SADB_EALG_MAX; algo >0 ; algo--) \ - if (ESP_EALG_PRESENT(algo)) + for (algo=SADB_EALG_MAX; algo >0 ; algo--) \ + if (ESP_EALG_PRESENT(algo)) #define ESP_AALG_PRESENT(algo) ((algo<=SADB_AALG_MAX)&&(esp_aalg[(algo)].sadb_alg_id==(algo))) #define ESP_AALG_FOR_EACH_UPDOWN(algo) \ - for (algo=SADB_AALG_MAX; algo >0 ; algo--) \ - if (ESP_AALG_PRESENT(algo)) + for (algo=SADB_AALG_MAX; algo >0 ; algo--) \ + if (ESP_AALG_PRESENT(algo)) -static struct sadb_alg* -sadb_alg_ptr (int satype, int exttype, int alg_id, int rw) +static struct sadb_alg* sadb_alg_ptr (int satype, int exttype, int alg_id, + int rw) { - struct sadb_alg *alg_p = NULL; - - switch (exttype) - { - case SADB_EXT_SUPPORTED_AUTH: - if (alg_id > SADB_AALG_MAX) - return NULL; - break; - case SADB_EXT_SUPPORTED_ENCRYPT: - if (alg_id > SADB_EALG_MAX) - return NULL; - break; - default: - return NULL; - } - - switch (satype) - { - case SADB_SATYPE_ESP: - alg_p = (exttype == SADB_EXT_SUPPORTED_ENCRYPT)? - &esp_ealg[alg_id] : &esp_aalg[alg_id]; - /* get for write: increment elem count */ - if (rw) + struct sadb_alg *alg_p = NULL; + + switch (exttype) { - (exttype == SADB_EXT_SUPPORTED_ENCRYPT)? - esp_ealg_num++ : esp_aalg_num++; + case SADB_EXT_SUPPORTED_AUTH: + if (alg_id > SADB_AALG_MAX) + return NULL; + break; + case SADB_EXT_SUPPORTED_ENCRYPT: + if (alg_id > SADB_EALG_MAX) + return NULL; + break; + default: + return NULL; } - break; - case SADB_SATYPE_AH: - default: - return NULL; - } - - return alg_p; + + switch (satype) + { + case SADB_SATYPE_ESP: + alg_p = (exttype == SADB_EXT_SUPPORTED_ENCRYPT)? + &esp_ealg[alg_id] : &esp_aalg[alg_id]; + /* get for write: increment elem count */ + if (rw) + { + (exttype == SADB_EXT_SUPPORTED_ENCRYPT)? + esp_ealg_num++ : esp_aalg_num++; + } + break; + case SADB_SATYPE_AH: + default: + return NULL; + } + + return alg_p; } -const struct sadb_alg * -kernel_alg_sadb_alg_get(int satype, int exttype, int alg_id) +const struct sadb_alg* kernel_alg_sadb_alg_get(int satype, int exttype, + int alg_id) { - return sadb_alg_ptr(satype, exttype, alg_id, 0); + return sadb_alg_ptr(satype, exttype, alg_id, 0); } /* - * Forget previous registration + * Forget previous registration */ -static void -kernel_alg_init(void) +static void kernel_alg_init(void) { - DBG(DBG_KLIPS, - DBG_log("alg_init(): memset(%p, 0, %d) memset(%p, 0, %d)", - &esp_aalg, (int)sizeof (esp_aalg), - &esp_ealg, (int)sizeof (esp_ealg)) - ) - memset (&esp_aalg, 0, sizeof (esp_aalg)); - memset (&esp_ealg, 0, sizeof (esp_ealg)); - esp_ealg_num=esp_aalg_num = 0; + DBG(DBG_KLIPS, + DBG_log("alg_init(): memset(%p, 0, %d) memset(%p, 0, %d)", + &esp_aalg, (int)sizeof (esp_aalg), + &esp_ealg, (int)sizeof (esp_ealg)) + ) + memset (&esp_aalg, 0, sizeof (esp_aalg)); + memset (&esp_ealg, 0, sizeof (esp_ealg)); + esp_ealg_num=esp_aalg_num = 0; } -static int -kernel_alg_add(int satype, int exttype, const struct sadb_alg *sadb_alg) +static int kernel_alg_add(int satype, int exttype, + const struct sadb_alg *sadb_alg) { - struct sadb_alg *alg_p = NULL; - int alg_id = sadb_alg->sadb_alg_id; - - DBG(DBG_KLIPS, - DBG_log("kernel_alg_add(): satype=%d, exttype=%d, alg_id=%d", - satype, exttype, sadb_alg->sadb_alg_id) - ) - if (!(alg_p = sadb_alg_ptr(satype, exttype, alg_id, 1))) - return -1; - - /* This logic "mimics" KLIPS: first algo implementation will be used */ - if (alg_p->sadb_alg_id) - { + struct sadb_alg *alg_p = NULL; + int alg_id = sadb_alg->sadb_alg_id; + DBG(DBG_KLIPS, - DBG_log("kernel_alg_add(): discarding already setup " - "satype=%d, exttype=%d, alg_id=%d", - satype, exttype, sadb_alg->sadb_alg_id) + DBG_log("kernel_alg_add(): satype=%d, exttype=%d, alg_id=%d", + satype, exttype, sadb_alg->sadb_alg_id) ) - return 0; - } - *alg_p = *sadb_alg; - return 1; + if (!(alg_p = sadb_alg_ptr(satype, exttype, alg_id, 1))) + return -1; + + /* This logic "mimics" KLIPS: first algo implementation will be used */ + if (alg_p->sadb_alg_id) + { + DBG(DBG_KLIPS, + DBG_log("kernel_alg_add(): discarding already setup " + "satype=%d, exttype=%d, alg_id=%d", + satype, exttype, sadb_alg->sadb_alg_id) + ) + return 0; + } + *alg_p = *sadb_alg; + return 1; } -bool -kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len, - struct alg_info_esp *alg_info __attribute__((unused))) +bool kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len, + struct alg_info_esp *alg_info __attribute__((unused))) { - struct sadb_alg *alg_p = NULL; - - /* - * test #1: encrypt algo must be present - */ - int ret = ESP_EALG_PRESENT(alg_id); - if (!ret) goto out; - - alg_p = &esp_ealg[alg_id]; - - /* - * test #2: if key_len specified, it must be in range - */ - if (key_len - && (key_len < alg_p->sadb_alg_minbits || key_len > alg_p->sadb_alg_maxbits)) - { - plog("kernel_alg_db_add() key_len not in range: alg_id=%d, " - "key_len=%d, alg_minbits=%d, alg_maxbits=%d" - , alg_id, key_len - , alg_p->sadb_alg_minbits - , alg_p->sadb_alg_maxbits); - ret = FALSE; - } + struct sadb_alg *alg_p = NULL; + + /* + * test #1: encrypt algo must be present + */ + int ret = ESP_EALG_PRESENT(alg_id); + if (!ret) goto out; + + alg_p = &esp_ealg[alg_id]; + + /* + * test #2: if key_len specified, it must be in range + */ + if (key_len + && (key_len < alg_p->sadb_alg_minbits || key_len > alg_p->sadb_alg_maxbits)) + { + plog("kernel_alg_db_add() key_len not in range: alg_id=%d, " + "key_len=%d, alg_minbits=%d, alg_maxbits=%d" + , alg_id, key_len + , alg_p->sadb_alg_minbits + , alg_p->sadb_alg_maxbits); + ret = FALSE; + } out: - if (ret) - { - DBG(DBG_KLIPS, - DBG_log("kernel_alg_esp_enc_ok(%d,%d): " - "alg_id=%d, " - "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, " - "res=%d, ret=%d" - , alg_id, key_len - , alg_p->sadb_alg_id - , alg_p->sadb_alg_ivlen - , alg_p->sadb_alg_minbits - , alg_p->sadb_alg_maxbits - , alg_p->sadb_alg_reserved - , ret); - ) - } - else - { - DBG(DBG_KLIPS, - DBG_log("kernel_alg_esp_enc_ok(%d,%d): NO", alg_id, key_len); - ) - } - return ret; + if (ret) + { + DBG(DBG_KLIPS, + DBG_log("kernel_alg_esp_enc_ok(%d,%d): " + "alg_id=%d, " + "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, " + "res=%d, ret=%d" + , alg_id, key_len + , alg_p->sadb_alg_id + , alg_p->sadb_alg_ivlen + , alg_p->sadb_alg_minbits + , alg_p->sadb_alg_maxbits + , alg_p->sadb_alg_reserved + , ret); + ) + } + else + { + DBG(DBG_KLIPS, + DBG_log("kernel_alg_esp_enc_ok(%d,%d): NO", alg_id, key_len); + ) + } + return ret; } /* * ML: make F_STRICT logic consider enc,auth algorithms */ -#ifndef NO_PLUTO -bool -kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg, struct alg_info_esp *alg_info) +bool kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg, + struct alg_info_esp *alg_info) { - int ealg_insecure; - - /* - * key_len passed comes from esp_attrs read from peer - * For many older algoritms (eg 3DES) this key_len is fixed - * and get passed as 0. - * ... then get default key_len - */ - if (key_len == 0) - key_len = kernel_alg_esp_enc_keylen(ealg) * BITS_PER_BYTE; - - /* - * simple test to toss low key_len, will accept it only - * if specified in "esp" string - */ - ealg_insecure = (key_len < 128) ; - - if (ealg_insecure - || (alg_info && alg_info->alg_info_flags & ALG_INFO_F_STRICT)) - { - int i; - struct esp_info *esp_info; + int ealg_insecure; - if (alg_info) + /* + * key_len passed comes from esp_attrs read from peer + * For many older algoritms (eg 3DES) this key_len is fixed + * and get passed as 0. + * ... then get default key_len + */ + if (key_len == 0) + key_len = kernel_alg_esp_enc_keylen(ealg) * BITS_PER_BYTE; + + /* + * simple test to toss low key_len, will accept it only + * if specified in "esp" string + */ + ealg_insecure = (key_len < 128) ; + + if (ealg_insecure + || (alg_info && alg_info->alg_info_flags & ALG_INFO_F_STRICT)) { - ALG_INFO_ESP_FOREACH(alg_info, esp_info, i) - { - if (esp_info->esp_ealg_id == ealg - && (esp_info->esp_ealg_keylen == 0 || key_len == 0 - || esp_info->esp_ealg_keylen == key_len) - && esp_info->esp_aalg_id == aalg) + int i; + struct esp_info *esp_info; + + if (alg_info) { - if (ealg_insecure) - { - loglog(RC_LOG_SERIOUS - , "You should NOT use insecure ESP algorithms [%s (%d)]!" - , enum_name(&esp_transformid_names, ealg), key_len); - } - return TRUE; + ALG_INFO_ESP_FOREACH(alg_info, esp_info, i) + { + if (esp_info->esp_ealg_id == ealg + && (esp_info->esp_ealg_keylen == 0 || key_len == 0 + || esp_info->esp_ealg_keylen == key_len) + && esp_info->esp_aalg_id == aalg) + { + if (ealg_insecure) + { + loglog(RC_LOG_SERIOUS + , "You should NOT use insecure ESP algorithms [%s (%d)]!" + , enum_name(&esp_transformid_names, ealg), key_len); + } + return TRUE; + } + } } - } + plog("IPSec Transform [%s (%d), %s] refused due to %s", + enum_name(&esp_transformid_names, ealg), key_len, + enum_name(&auth_alg_names, aalg), + ealg_insecure ? "insecure key_len and enc. alg. not listed in \"esp\" string" : "strict flag"); + return FALSE; } - plog("IPSec Transform [%s (%d), %s] refused due to %s", - enum_name(&esp_transformid_names, ealg), key_len, - enum_name(&auth_alg_names, aalg), - ealg_insecure ? "insecure key_len and enc. alg. not listed in \"esp\" string" : "strict flag"); - return FALSE; - } - return TRUE; + return TRUE; } -#endif /* NO_PLUTO */ -/* - * Load kernel_alg arrays from /proc - * used in manual mode from klips/utils/spi.c +/** + * Load kernel_alg arrays from /proc used in manual mode from klips/utils/spi.c */ -int -kernel_alg_proc_read(void) +int kernel_alg_proc_read(void) { - int satype; - int supp_exttype; - int alg_id, ivlen, minbits, maxbits; - struct sadb_alg sadb_alg; - int ret; - char buf[128]; + int satype; + int supp_exttype; + int alg_id, ivlen, minbits, maxbits; + struct sadb_alg sadb_alg; + int ret; + char buf[128]; - FILE *fp=fopen("/proc/net/pf_key_supported", "r"); + FILE *fp=fopen("/proc/net/pf_key_supported", "r"); - if (!fp) - return -1; + if (!fp) + return -1; - kernel_alg_init(); + kernel_alg_init(); - while (fgets(buf, sizeof(buf), fp)) - { - if (buf[0] != ' ') /* skip titles */ - continue; + while (fgets(buf, sizeof(buf), fp)) + { + if (buf[0] != ' ') /* skip titles */ + continue; - sscanf(buf, "%d %d %d %d %d %d" - ,&satype, &supp_exttype - , &alg_id, &ivlen - , &minbits, &maxbits); + sscanf(buf, "%d %d %d %d %d %d" + ,&satype, &supp_exttype + , &alg_id, &ivlen + , &minbits, &maxbits); - switch (satype) - { - case SADB_SATYPE_ESP: - switch(supp_exttype) - { - case SADB_EXT_SUPPORTED_AUTH: - case SADB_EXT_SUPPORTED_ENCRYPT: - sadb_alg.sadb_alg_id = alg_id; - sadb_alg.sadb_alg_ivlen = ivlen; - sadb_alg.sadb_alg_minbits = minbits; - sadb_alg.sadb_alg_maxbits = maxbits; - ret = kernel_alg_add(satype, supp_exttype, &sadb_alg); - DBG(DBG_CRYPT, - DBG_log("kernel_alg_proc_read() alg_id=%d, " - "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, " - "ret=%d" - , sadb_alg.sadb_alg_id - , sadb_alg.sadb_alg_ivlen - , sadb_alg.sadb_alg_minbits - , sadb_alg.sadb_alg_maxbits - , ret) - ) - } - default: - continue; + switch (satype) + { + case SADB_SATYPE_ESP: + switch(supp_exttype) + { + case SADB_EXT_SUPPORTED_AUTH: + case SADB_EXT_SUPPORTED_ENCRYPT: + sadb_alg.sadb_alg_id = alg_id; + sadb_alg.sadb_alg_ivlen = ivlen; + sadb_alg.sadb_alg_minbits = minbits; + sadb_alg.sadb_alg_maxbits = maxbits; + ret = kernel_alg_add(satype, supp_exttype, &sadb_alg); + DBG(DBG_CRYPT, + DBG_log("kernel_alg_proc_read() alg_id=%d, " + "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, " + "ret=%d" + , sadb_alg.sadb_alg_id + , sadb_alg.sadb_alg_ivlen + , sadb_alg.sadb_alg_minbits + , sadb_alg.sadb_alg_maxbits + , ret) + ) + } + default: + continue; + } } - } - fclose(fp); - return 0; + fclose(fp); + return 0; } -/* - * Load kernel_alg arrays pluto's SADB_REGISTER - * user by pluto/kernel.c +/** + * Load kernel_alg arrays pluto's SADB_REGISTER user by pluto/kernel.c */ - -void -kernel_alg_register_pfkey(const struct sadb_msg *msg_buf, int buflen) +void kernel_alg_register_pfkey(const struct sadb_msg *msg_buf, int buflen) { - /* Trick: one 'type-mangle-able' pointer to ease offset/assign */ - union { - const struct sadb_msg *msg; - const struct sadb_supported *supported; - const struct sadb_ext *ext; - const struct sadb_alg *alg; - const char *ch; - } sadb; - - int satype; - int msglen; - int i = 0; - - /* Initialize alg arrays */ - kernel_alg_init(); - satype = msg_buf->sadb_msg_satype; - sadb.msg = msg_buf; - msglen = sadb.msg->sadb_msg_len*IPSEC_PFKEYv2_ALIGN; - msglen -= sizeof(struct sadb_msg); - buflen -= sizeof(struct sadb_msg); - passert(buflen > 0); - - sadb.msg++; - - while(msglen) - { - int supp_exttype = sadb.supported->sadb_supported_exttype; - int supp_len = sadb.supported->sadb_supported_len*IPSEC_PFKEYv2_ALIGN; - - DBG(DBG_KLIPS, - DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: " - "sadb_msg_len=%d sadb_supported_len=%d" - , satype==SADB_SATYPE_ESP? "ESP" : "AH" - , msg_buf->sadb_msg_len, supp_len) - ) - sadb.supported++; - msglen -= supp_len; - buflen -= supp_len; - passert(buflen >= 0); - - for (supp_len -= sizeof(struct sadb_supported); - supp_len; - supp_len -= sizeof(struct sadb_alg), sadb.alg++,i++) + /* Trick: one 'type-mangle-able' pointer to ease offset/assign */ + union { + const struct sadb_msg *msg; + const struct sadb_supported *supported; + const struct sadb_ext *ext; + const struct sadb_alg *alg; + const char *ch; + } sadb; + + int satype; + int msglen; + int i = 0; + + /* Initialize alg arrays */ + kernel_alg_init(); + satype = msg_buf->sadb_msg_satype; + sadb.msg = msg_buf; + msglen = sadb.msg->sadb_msg_len*IPSEC_PFKEYv2_ALIGN; + msglen -= sizeof(struct sadb_msg); + buflen -= sizeof(struct sadb_msg); + passert(buflen > 0); + + sadb.msg++; + + while(msglen) { - int ret = kernel_alg_add(satype, supp_exttype, sadb.alg); - - DBG(DBG_KLIPS, - DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: " - "alg[%d], exttype=%d, satype=%d, alg_id=%d, " - "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, " - "res=%d, ret=%d" - , satype==SADB_SATYPE_ESP? "ESP" : "AH" - , i - , supp_exttype - , satype - , sadb.alg->sadb_alg_id - , sadb.alg->sadb_alg_ivlen - , sadb.alg->sadb_alg_minbits - , sadb.alg->sadb_alg_maxbits - , sadb.alg->sadb_alg_reserved - , ret) - ) + int supp_exttype = sadb.supported->sadb_supported_exttype; + int supp_len = sadb.supported->sadb_supported_len*IPSEC_PFKEYv2_ALIGN; + + DBG(DBG_KLIPS, + DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: " + "sadb_msg_len=%d sadb_supported_len=%d" + , satype==SADB_SATYPE_ESP? "ESP" : "AH" + , msg_buf->sadb_msg_len, supp_len) + ) + sadb.supported++; + msglen -= supp_len; + buflen -= supp_len; + passert(buflen >= 0); + + for (supp_len -= sizeof(struct sadb_supported); + supp_len; + supp_len -= sizeof(struct sadb_alg), sadb.alg++,i++) + { + int ret = kernel_alg_add(satype, supp_exttype, sadb.alg); + + DBG(DBG_KLIPS, + DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: " + "alg[%d], exttype=%d, satype=%d, alg_id=%d, " + "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, " + "res=%d, ret=%d" + , satype==SADB_SATYPE_ESP? "ESP" : "AH" + , i + , supp_exttype + , satype + , sadb.alg->sadb_alg_id + , sadb.alg->sadb_alg_ivlen + , sadb.alg->sadb_alg_minbits + , sadb.alg->sadb_alg_maxbits + , sadb.alg->sadb_alg_reserved + , ret) + ) + } } - } } -u_int -kernel_alg_esp_enc_keylen(u_int alg_id) +u_int kernel_alg_esp_enc_keylen(u_int alg_id) { - u_int keylen = 0; + u_int keylen = 0; - if (!ESP_EALG_PRESENT(alg_id)) - goto none; + if (!ESP_EALG_PRESENT(alg_id)) + goto none; - keylen = esp_ealg[alg_id].sadb_alg_maxbits/BITS_PER_BYTE; + keylen = esp_ealg[alg_id].sadb_alg_maxbits/BITS_PER_BYTE; - switch (alg_id) - { - /* - * this is veryUgly[TM] - * Peer should have sent KEY_LENGTH attribute for ESP_AES - * but if not do force it to 128 instead of using sadb_alg_maxbits - * from kernel. - */ - case ESP_AES: - keylen = 128/BITS_PER_BYTE; - break; - } - -none: - DBG(DBG_KLIPS, - DBG_log("kernel_alg_esp_enc_keylen():" - "alg_id=%d, keylen=%d", - alg_id, keylen) - ) - return keylen; + switch (alg_id) + { + /* + * this is veryUgly[TM] + * Peer should have sent KEY_LENGTH attribute for ESP_AES + * but if not do force it to 128 instead of using sadb_alg_maxbits + * from kernel. + */ + case ESP_AES: + keylen = 128/BITS_PER_BYTE; + break; + } + +none: + DBG(DBG_KLIPS, + DBG_log("kernel_alg_esp_enc_keylen():" + "alg_id=%d, keylen=%d", + alg_id, keylen) + ) + return keylen; } -struct sadb_alg * -kernel_alg_esp_sadb_alg(u_int alg_id) +struct sadb_alg* kernel_alg_esp_sadb_alg(u_int alg_id) { - struct sadb_alg *sadb_alg = (ESP_EALG_PRESENT(alg_id)) - ? &esp_ealg[alg_id] : NULL; - - DBG(DBG_KLIPS, - DBG_log("kernel_alg_esp_sadb_alg(): alg_id=%d, sadb_alg=%p" - , alg_id, sadb_alg) - ) - return sadb_alg; + struct sadb_alg *sadb_alg = (ESP_EALG_PRESENT(alg_id)) + ? &esp_ealg[alg_id] : NULL; + + DBG(DBG_KLIPS, + DBG_log("kernel_alg_esp_sadb_alg(): alg_id=%d, sadb_alg=%p" + , alg_id, sadb_alg) + ) + return sadb_alg; } -#ifndef NO_PLUTO void kernel_alg_list(void) { - u_int sadb_id; - - whack_log(RC_COMMENT, " "); - whack_log(RC_COMMENT, "List of registered ESP Encryption Algorithms:"); - whack_log(RC_COMMENT, " "); - - for (sadb_id = 1; sadb_id <= SADB_EALG_MAX; sadb_id++) - { - if (ESP_EALG_PRESENT(sadb_id)) + char buf[BUF_LEN]; + char *pos; + int n, len; + u_int sadb_id; + + whack_log(RC_COMMENT, " "); + whack_log(RC_COMMENT, "List of registered ESP Algorithms:"); + whack_log(RC_COMMENT, " "); + + pos = buf; + *pos = '\0'; + len = BUF_LEN; + for (sadb_id = 1; sadb_id <= SADB_EALG_MAX; sadb_id++) { - struct sadb_alg *alg_p = &esp_ealg[sadb_id]; - - whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d" - , sadb_id - , enum_name(&esp_transformid_names, sadb_id) - , alg_p->sadb_alg_ivlen - , alg_p->sadb_alg_minbits - , alg_p->sadb_alg_maxbits - ); + if (ESP_EALG_PRESENT(sadb_id)) + { + n = snprintf(pos, len, " %s", + enum_name(&esp_transformid_names, sadb_id)); + pos += n; + len -= n; + if (len <= 0) + { + break; + } + } } - } - - whack_log(RC_COMMENT, " "); - whack_log(RC_COMMENT, "List of registered ESP Authentication Algorithms:"); - whack_log(RC_COMMENT, " "); - - for (sadb_id = 1; sadb_id <= SADB_AALG_MAX; sadb_id++) - { - if (ESP_AALG_PRESENT(sadb_id)) + whack_log(RC_COMMENT, " encryption:%s", buf); + + pos = buf; + *pos = '\0'; + len = BUF_LEN; + for (sadb_id = 1; sadb_id <= SADB_AALG_MAX; sadb_id++) { - u_int aaid = alg_info_esp_sadb2aa(sadb_id); - struct sadb_alg *alg_p = &esp_aalg[sadb_id]; - - whack_log(RC_COMMENT, "#%-5d %s, keylen: %d-%d" - , aaid - , enum_name(&auth_alg_names, aaid) - , alg_p->sadb_alg_minbits - , alg_p->sadb_alg_maxbits - ); + if (ESP_AALG_PRESENT(sadb_id)) + { + u_int aaid = alg_info_esp_sadb2aa(sadb_id); + + n = snprintf(pos, len, " %s", enum_name(&auth_alg_names, aaid)); + pos += n; + len -= n; + if (len <= 0) + { + break; + } + } } - } + whack_log(RC_COMMENT, " integrity: %s", buf); } -void -kernel_alg_show_connection(struct connection *c, const char *instance) +void kernel_alg_show_connection(struct connection *c, const char *instance) { - char buf[256]; - struct state *st; - - if (c->alg_info_esp) - { - alg_info_snprint(buf, sizeof(buf), (struct alg_info *)c->alg_info_esp); - whack_log(RC_COMMENT - , "\"%s\"%s: ESP algorithms wanted: %s" - , c->name - , instance - , buf); - } - if (c->alg_info_esp) - { - alg_info_snprint_esp(buf, sizeof(buf), c->alg_info_esp); - whack_log(RC_COMMENT - , "\"%s\"%s: ESP algorithms loaded: %s" - , c->name - , instance - , buf); - } - st = state_with_serialno(c->newest_ipsec_sa); - if (st && st->st_esp.present) - whack_log(RC_COMMENT - , "\"%s\"%s: ESP algorithm newest: %s_%d-%s; pfsgroup=%s" - , c->name - , instance - , enum_show(&esp_transformid_names, st->st_esp.attrs.transid) - +4 /* strlen("ESP_") */ - , st->st_esp.attrs.key_len - , enum_show(&auth_alg_names, st->st_esp.attrs.auth)+ - +15 /* strlen("AUTH_ALGORITHM_") */ - , c->policy & POLICY_PFS ? - c->alg_info_esp->esp_pfsgroup ? - enum_show(&oakley_group_names, - c->alg_info_esp->esp_pfsgroup) - +13 /*strlen("OAKLEY_GROUP_")*/ - : "<Phase1>" - : "<N/A>" - ); + struct state *st = state_with_serialno(c->newest_ipsec_sa); + + if (st && st->st_esp.present) + { + const char *aalg_name, *pfsgroup_name; + + aalg_name = (c->policy & POLICY_AUTHENTICATE) ? + enum_show(&ah_transformid_names, st->st_ah.attrs.transid): + enum_show(&auth_alg_names, st->st_esp.attrs.auth); + + pfsgroup_name = (c->policy & POLICY_PFS) ? + (c->alg_info_esp->esp_pfsgroup) ? + enum_show(&oakley_group_names, + c->alg_info_esp->esp_pfsgroup) : + "<Phase1>" : "<N/A>"; + + if (st->st_esp.attrs.key_len) + { + whack_log(RC_COMMENT, "\"%s\"%s: ESP%s proposal: %s_%u/%s/%s", + c->name, instance, + (st->st_ah.present) ? "/AH" : "", + enum_show(&esp_transformid_names, st->st_esp.attrs.transid), + st->st_esp.attrs.key_len, aalg_name, pfsgroup_name); + } + else + { + whack_log(RC_COMMENT, "\"%s\"%s: ESP%s proposal: %s/%s/%s", + c->name, instance, + (st->st_ah.present) ? "/AH" : "", + enum_show(&esp_transformid_names, st->st_esp.attrs.transid), + aalg_name, pfsgroup_name); + } + } } -#endif /* NO_PLUTO */ -bool -kernel_alg_esp_auth_ok(u_int auth, - struct alg_info_esp *alg_info __attribute__((unused))) +bool kernel_alg_esp_auth_ok(u_int auth, + struct alg_info_esp *alg_info __attribute__((unused))) { - return ESP_AALG_PRESENT(alg_info_esp_aa2sadb(auth)); + return ESP_AALG_PRESENT(alg_info_esp_aa2sadb(auth)); } -u_int -kernel_alg_esp_auth_keylen(u_int auth) +u_int kernel_alg_esp_auth_keylen(u_int auth) { - u_int sadb_aalg = alg_info_esp_aa2sadb(auth); + u_int sadb_aalg = alg_info_esp_aa2sadb(auth); - u_int a_keylen = (sadb_aalg) - ? esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE - : 0; + u_int a_keylen = (sadb_aalg) + ? esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE + : 0; - DBG(DBG_CONTROL | DBG_CRYPT | DBG_PARSING, - DBG_log("kernel_alg_esp_auth_keylen(auth=%d, sadb_aalg=%d): " - "a_keylen=%d", auth, sadb_aalg, a_keylen) - ) - return a_keylen; + DBG(DBG_CONTROL | DBG_CRYPT | DBG_PARSING, + DBG_log("kernel_alg_esp_auth_keylen(auth=%d, sadb_aalg=%d): " + "a_keylen=%d", auth, sadb_aalg, a_keylen) + ) + return a_keylen; } -struct esp_info * -kernel_alg_esp_info(int transid, int auth) +struct esp_info* kernel_alg_esp_info(int transid, int auth) { - int sadb_aalg, sadb_ealg; - static struct esp_info ei_buf; - - sadb_ealg = transid; - sadb_aalg = alg_info_esp_aa2sadb(auth); - - if (!ESP_EALG_PRESENT(sadb_ealg)) - goto none; - if (!ESP_AALG_PRESENT(sadb_aalg)) - goto none; - - memset(&ei_buf, 0, sizeof (ei_buf)); - ei_buf.transid = transid; - ei_buf.auth = auth; - - /* don't return "default" keylen because this value is used from - * setup_half_ipsec_sa() to "validate" keylen - * In effect, enckeylen will be used as "max" value - */ - ei_buf.enckeylen = esp_ealg[sadb_ealg].sadb_alg_maxbits/BITS_PER_BYTE; - ei_buf.authkeylen = esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE; - ei_buf.encryptalg = sadb_ealg; - ei_buf.authalg = sadb_aalg; - - DBG(DBG_PARSING, - DBG_log("kernel_alg_esp_info():" - "transid=%d, auth=%d, ei=%p, " - "enckeylen=%d, authkeylen=%d, encryptalg=%d, authalg=%d", - transid, auth, &ei_buf, - (int)ei_buf.enckeylen, (int)ei_buf.authkeylen, - ei_buf.encryptalg, ei_buf.authalg) - ) - return &ei_buf; + int sadb_aalg, sadb_ealg; + static struct esp_info ei_buf; + + sadb_ealg = transid; + sadb_aalg = alg_info_esp_aa2sadb(auth); + + if (!ESP_EALG_PRESENT(sadb_ealg)) + goto none; + if (!ESP_AALG_PRESENT(sadb_aalg)) + goto none; + + memset(&ei_buf, 0, sizeof (ei_buf)); + ei_buf.transid = transid; + ei_buf.auth = auth; + + /* don't return "default" keylen because this value is used from + * setup_half_ipsec_sa() to "validate" keylen + * In effect, enckeylen will be used as "max" value + */ + ei_buf.enckeylen = esp_ealg[sadb_ealg].sadb_alg_maxbits/BITS_PER_BYTE; + ei_buf.authkeylen = esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE; + ei_buf.encryptalg = sadb_ealg; + ei_buf.authalg = sadb_aalg; + + DBG(DBG_PARSING, + DBG_log("kernel_alg_esp_info():" + "transid=%d, auth=%d, ei=%p, " + "enckeylen=%d, authkeylen=%d, encryptalg=%d, authalg=%d", + transid, auth, &ei_buf, + (int)ei_buf.enckeylen, (int)ei_buf.authkeylen, + ei_buf.encryptalg, ei_buf.authalg) + ) + return &ei_buf; none: - DBG(DBG_PARSING, - DBG_log("kernel_alg_esp_info():" - "transid=%d, auth=%d, ei=NULL", - transid, auth) - ) - return NULL; + DBG(DBG_PARSING, + DBG_log("kernel_alg_esp_info():" + "transid=%d, auth=%d, ei=NULL", + transid, auth) + ) + return NULL; } -#ifndef NO_PLUTO -static void -kernel_alg_policy_algorithms(struct esp_info *esp_info) +static void kernel_alg_policy_algorithms(struct esp_info *esp_info) { - u_int ealg_id = esp_info->esp_ealg_id; - - switch(ealg_id) - { - case 0: - case ESP_DES: - case ESP_3DES: - case ESP_NULL: - case ESP_CAST: - break; - default: - if (!esp_info->esp_ealg_keylen) + u_int ealg_id = esp_info->esp_ealg_id; + + switch(ealg_id) { - /* algos that need KEY_LENGTH - * - * Note: this is a very dirty hack ;-) - * Idea: Add a key_length_needed attribute to - * esp_ealg ?? - */ - esp_info->esp_ealg_keylen = esp_ealg[ealg_id].sadb_alg_maxbits; + case 0: + case ESP_DES: + case ESP_3DES: + case ESP_NULL: + case ESP_CAST: + break; + default: + if (!esp_info->esp_ealg_keylen) + { + /* algos that need KEY_LENGTH + * + * Note: this is a very dirty hack ;-) + * Idea: Add a key_length_needed attribute to + * esp_ealg ?? + */ + esp_info->esp_ealg_keylen = esp_ealg[ealg_id].sadb_alg_maxbits; + } } - } } -static bool -kernel_alg_db_add(struct db_context *db_ctx, struct esp_info *esp_info, lset_t policy) +static bool kernel_alg_db_add(struct db_context *db_ctx, + struct esp_info *esp_info, lset_t policy) { - u_int ealg_id, aalg_id; - - ealg_id = esp_info->esp_ealg_id; + u_int ealg_id, aalg_id; - if (!ESP_EALG_PRESENT(ealg_id)) - { - DBG_log("kernel_alg_db_add() kernel enc ealg_id=%d not present", ealg_id); - return FALSE; - } - - if (!(policy & POLICY_AUTHENTICATE)) /* skip ESP auth attrs for AH */ - { - aalg_id = alg_info_esp_aa2sadb(esp_info->esp_aalg_id); + ealg_id = esp_info->esp_ealg_id; - if (!ESP_AALG_PRESENT(aalg_id)) + if (!ESP_EALG_PRESENT(ealg_id)) { - DBG_log("kernel_alg_db_add() kernel auth " - "aalg_id=%d not present", aalg_id); - return FALSE; + DBG_log("kernel_alg_db_add() kernel enc ealg_id=%d not present", ealg_id); + return FALSE; } - } + + if (!(policy & POLICY_AUTHENTICATE)) /* skip ESP auth attrs for AH */ + { + aalg_id = alg_info_esp_aa2sadb(esp_info->esp_aalg_id); - /* do algo policy */ - kernel_alg_policy_algorithms(esp_info); + if (!ESP_AALG_PRESENT(aalg_id)) + { + DBG_log("kernel_alg_db_add() kernel auth " + "aalg_id=%d not present", aalg_id); + return FALSE; + } + } - /* open new transformation */ - db_trans_add(db_ctx, ealg_id); + /* do algo policy */ + kernel_alg_policy_algorithms(esp_info); - /* add ESP auth attr */ - if (!(policy & POLICY_AUTHENTICATE)) - db_attr_add_values(db_ctx, AUTH_ALGORITHM, esp_info->esp_aalg_id); + /* open new transformation */ + db_trans_add(db_ctx, ealg_id); - /* add keylegth if specified in esp= string */ - if (esp_info->esp_ealg_keylen) - db_attr_add_values(db_ctx, KEY_LENGTH, esp_info->esp_ealg_keylen); - - return TRUE; + /* add ESP auth attr */ + if (!(policy & POLICY_AUTHENTICATE)) + db_attr_add_values(db_ctx, AUTH_ALGORITHM, esp_info->esp_aalg_id); + + /* add keylegth if specified in esp= string */ + if (esp_info->esp_ealg_keylen) + db_attr_add_values(db_ctx, KEY_LENGTH, esp_info->esp_ealg_keylen); + + return TRUE; } -/* - * Create proposal with runtime kernel algos, merging - * with passed proposal if not NULL +/* + * Create proposal with runtime kernel algos, merging + * with passed proposal if not NULL * - * for now this function does free() previous returned - * malloced pointer (this quirk allows easier spdb.c change) + * for now this function does free() previous returned + * malloced pointer (this quirk allows easier spdb.c change) */ -struct db_context * -kernel_alg_db_new(struct alg_info_esp *alg_info, lset_t policy ) +struct db_context* kernel_alg_db_new(struct alg_info_esp *alg_info, + lset_t policy ) { - const struct esp_info *esp_info; - struct esp_info tmp_esp_info; - struct db_context *ctx_new=NULL; - struct db_trans *t; - struct db_prop *prop; - u_int trans_cnt; - int tn = 0; - - if (!(policy & POLICY_ENCRYPT)) /* not possible, I think */ - return NULL; + const struct esp_info *esp_info; + struct esp_info tmp_esp_info; + struct db_context *ctx_new = NULL; + struct db_prop *prop; + u_int trans_cnt = esp_ealg_num * esp_aalg_num; - trans_cnt = esp_ealg_num * esp_aalg_num; - DBG(DBG_EMITTING, - DBG_log("kernel_alg_db_prop_new() initial trans_cnt=%d" - , trans_cnt) - ) - - /* pass aprox. number of transforms and attributes */ - ctx_new = db_prop_new(PROTO_IPSEC_ESP, trans_cnt, trans_cnt * 2); + if (!(policy & POLICY_ENCRYPT)) /* not possible, I think */ + { + return NULL; + } - /* - * Loop: for each element (struct esp_info) of alg_info, - * if kernel support is present then build the transform (and attrs) - * if NULL alg_info, propose everything ... - */ + /* pass aprox. number of transforms and attributes */ + ctx_new = db_prop_new(PROTO_IPSEC_ESP, trans_cnt, trans_cnt * 2); - if (alg_info) - { - int i; + /* + * Loop: for each element (struct esp_info) of alg_info, + * if kernel support is present then build the transform (and attrs) + * if NULL alg_info, propose everything ... + */ - ALG_INFO_ESP_FOREACH(alg_info, esp_info, i) + if (alg_info) { - tmp_esp_info = *esp_info; - kernel_alg_db_add(ctx_new, &tmp_esp_info, policy); + int i; + + ALG_INFO_ESP_FOREACH(alg_info, esp_info, i) + { + tmp_esp_info = *esp_info; + kernel_alg_db_add(ctx_new, &tmp_esp_info, policy); + } } - } - else - { - u_int ealg_id; - - ESP_EALG_FOR_EACH_UPDOWN(ealg_id) + else { - u_int aalg_id; - - tmp_esp_info.esp_ealg_id = ealg_id; - tmp_esp_info.esp_ealg_keylen = 0; - - for (aalg_id = 1; aalg_id <= SADB_AALG_MAX; aalg_id++) - { - if (ESP_AALG_PRESENT(aalg_id)) + u_int ealg_id; + + ESP_EALG_FOR_EACH_UPDOWN(ealg_id) { - tmp_esp_info.esp_aalg_id = alg_info_esp_sadb2aa(aalg_id); - tmp_esp_info.esp_aalg_keylen = 0; - kernel_alg_db_add(ctx_new, &tmp_esp_info, policy); + u_int aalg_id; + + tmp_esp_info.esp_ealg_id = ealg_id; + tmp_esp_info.esp_ealg_keylen = 0; + + for (aalg_id = 1; aalg_id <= SADB_AALG_MAX; aalg_id++) + { + if (ESP_AALG_PRESENT(aalg_id)) + { + tmp_esp_info.esp_aalg_id = alg_info_esp_sadb2aa(aalg_id); + tmp_esp_info.esp_aalg_keylen = 0; + kernel_alg_db_add(ctx_new, &tmp_esp_info, policy); + } + } } - } } - } - - prop = db_prop_get(ctx_new); - - DBG(DBG_CONTROL|DBG_EMITTING, - DBG_log("kernel_alg_db_prop_new() " - "will return p_new->protoid=%d, p_new->trans_cnt=%d" - , prop->protoid, prop->trans_cnt) - ) - - for (t = prop->trans, tn = 0; tn < prop->trans_cnt; tn++) - { - DBG(DBG_CONTROL|DBG_EMITTING, - DBG_log("kernel_alg_db_prop_new() " - " trans[%d]: transid=%d, attr_cnt=%d, " - "attrs[0].type=%d, attrs[0].val=%d" - , tn - , t[tn].transid, t[tn].attr_cnt - , t[tn].attrs[0].type, t[tn].attrs[0].val) - ) - } - return ctx_new; + prop = db_prop_get(ctx_new); + return ctx_new; } -#endif /* NO_PLUTO */ + |