store ESP keys in CHILD_SA

This commit is contained in:
Martin Willi
2008-10-15 08:37:56 +00:00
parent ff93a76cf1
commit 9f4e5f8c47
4 changed files with 78 additions and 57 deletions
+2 -2
View File
@@ -184,12 +184,12 @@ static void write_child(xmlTextWriterPtr writer, child_sa_t *child)
ipsec_mode_t mode; ipsec_mode_t mode;
encryption_algorithm_t encr; encryption_algorithm_t encr;
integrity_algorithm_t int_algo; integrity_algorithm_t int_algo;
size_t encr_len, int_len; chunk_t encr_key, int_key;
u_int32_t rekey, use_in, use_out, use_fwd; u_int32_t rekey, use_in, use_out, use_fwd;
child_cfg_t *config; child_cfg_t *config;
config = child->get_config(child); config = child->get_config(child);
child->get_stats(child, &mode, &encr, &encr_len, &int_algo, &int_len, child->get_stats(child, &mode, &encr, &encr_key, &int_algo, &int_key,
&rekey, &use_in, &use_out, &use_fwd); &rekey, &use_in, &use_out, &use_fwd);
xmlTextWriterStartElement(writer, "childsa"); xmlTextWriterStartElement(writer, "childsa");
+29 -19
View File
@@ -126,11 +126,11 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
u_int32_t use_in, use_out, use_fwd; u_int32_t use_in, use_out, use_fwd;
encryption_algorithm_t encr_alg; encryption_algorithm_t encr_alg;
integrity_algorithm_t int_alg; integrity_algorithm_t int_alg;
size_t encr_len, int_len; chunk_t encr_key, int_key;
ipsec_mode_t mode; ipsec_mode_t mode;
child_sa->get_stats(child_sa, &mode, &encr_alg, &encr_len, child_sa->get_stats(child_sa, &mode, &encr_alg, &encr_key,
&int_alg, &int_len, &rekey, &use_in, &use_out, &int_alg, &int_key, &rekey, &use_in, &use_out,
&use_fwd); &use_fwd);
fprintf(out, "%12s{%d}: %N, %N", fprintf(out, "%12s{%d}: %N, %N",
@@ -160,28 +160,38 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa), fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa),
child_sa->get_reqid(child_sa)); child_sa->get_reqid(child_sa));
if (child_sa->get_protocol(child_sa) == PROTO_ESP) if (child_sa->get_protocol(child_sa) == PROTO_ESP)
{ {
fprintf(out, "%N", encryption_algorithm_names, encr_alg); switch (encr_alg)
if (encr_len)
{ {
fprintf(out, "-%d", encr_len); /* Algorithms with variable key size.
} * GCM/CCM keys are actually shorted than their key data. */
if (int_alg != AUTH_UNDEFINED) case ENCR_AES_GCM_ICV8:
{ case ENCR_AES_GCM_ICV12:
fprintf(out, "/"); case ENCR_AES_GCM_ICV16:
encr_key.len -= 1;
/* FALL */
case ENCR_AES_CCM_ICV8:
case ENCR_AES_CCM_ICV12:
case ENCR_AES_CCM_ICV16:
encr_key.len -= 3;
/* FALL */
case ENCR_AES_CBC:
fprintf(out, "%N-%d", encryption_algorithm_names,
encr_alg, encr_key.len * 8);
break;
default:
fprintf(out, "%N", encryption_algorithm_names, encr_alg);
break;
} }
} }
switch (int_alg)
if (int_alg != AUTH_UNDEFINED)
{ {
fprintf(out, "%N", integrity_algorithm_names, int_alg); case AUTH_UNDEFINED:
if (int_len) break;
{ default:
fprintf(out, "-%d", int_len); fprintf(out, "/%N", integrity_algorithm_names, int_alg);
} break;
} }
fprintf(out, ", rekeying "); fprintf(out, ", rekeying ");
+43 -32
View File
@@ -117,9 +117,9 @@ struct private_child_sa_t {
u_int16_t enc_alg; u_int16_t enc_alg;
/** /**
* key size of enc_alg * Encryption key data
*/ */
u_int16_t enc_size; chunk_t enc_key;
/** /**
* integrity protection algorithm used for this SA * integrity protection algorithm used for this SA
@@ -127,9 +127,9 @@ struct private_child_sa_t {
u_int16_t int_alg; u_int16_t int_alg;
/** /**
* key size of int_alg * integrity key data
*/ */
u_int16_t int_size; chunk_t int_key;
/** /**
* time, on which SA was installed * time, on which SA was installed
@@ -302,8 +302,8 @@ static child_cfg_t* get_config(private_child_sa_t *this)
* Implementation of child_sa_t.get_stats. * Implementation of child_sa_t.get_stats.
*/ */
static void get_stats(private_child_sa_t *this, ipsec_mode_t *mode, static void get_stats(private_child_sa_t *this, ipsec_mode_t *mode,
encryption_algorithm_t *encr_algo, size_t *encr_len, encryption_algorithm_t *encr_algo, chunk_t *encr_key,
integrity_algorithm_t *int_algo, size_t *int_len, integrity_algorithm_t *int_algo, chunk_t *int_key,
u_int32_t *rekey, u_int32_t *use_in, u_int32_t *use_out, u_int32_t *rekey, u_int32_t *use_in, u_int32_t *use_out,
u_int32_t *use_fwd) u_int32_t *use_fwd)
{ {
@@ -335,9 +335,9 @@ static void get_stats(private_child_sa_t *this, ipsec_mode_t *mode,
*mode = this->mode; *mode = this->mode;
*encr_algo = this->enc_alg; *encr_algo = this->enc_alg;
*encr_len = this->enc_size; *encr_key = this->enc_key;
*int_algo = this->int_alg; *int_algo = this->int_alg;
*int_len = this->int_size; *int_key = this->int_key;
*rekey = this->rekey_time; *rekey = this->rekey_time;
*use_in = in; *use_in = in;
*use_out = out; *use_out = out;
@@ -585,8 +585,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
u_int32_t spi, cpi, soft, hard; u_int32_t spi, cpi, soft, hard;
host_t *src, *dst; host_t *src, *dst;
status_t status; status_t status;
chunk_t enc_key = chunk_empty, int_key = chunk_empty;
int add_keymat; int add_keymat;
u_int16_t enc_size, int_size;
this->protocol = proposal->get_protocol(proposal); this->protocol = proposal->get_protocol(proposal);
@@ -632,52 +632,63 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
/* select encryption algo, derive key */ /* select encryption algo, derive key */
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
&this->enc_alg, &this->enc_size)) &this->enc_alg, &enc_size))
{ {
DBG2(DBG_CHD, " using %N for encryption", DBG2(DBG_CHD, " using %N for encryption",
encryption_algorithm_names, this->enc_alg); encryption_algorithm_names, this->enc_alg);
} }
if (!this->enc_size) if (this->enc_alg != ENCR_UNDEFINED)
{
this->enc_size = lookup_keylen(keylen_enc, this->enc_alg);
}
if (this->enc_size && this->enc_alg != ENCR_UNDEFINED)
{ {
if (!enc_size)
{
enc_size = lookup_keylen(keylen_enc, this->enc_alg);
}
if (!enc_size)
{
DBG1(DBG_CHD, "no keylenth defined for %N",
encryption_algorithm_names, this->enc_alg);
return FAILED;
}
/* CCM/GCM needs additional keymat */ /* CCM/GCM needs additional keymat */
switch (this->enc_alg) switch (this->enc_alg)
{ {
case ENCR_AES_CCM_ICV8: case ENCR_AES_CCM_ICV8:
case ENCR_AES_CCM_ICV12: case ENCR_AES_CCM_ICV12:
case ENCR_AES_CCM_ICV16: case ENCR_AES_CCM_ICV16:
add_keymat = 3; enc_size += 24;
break; break;
case ENCR_AES_GCM_ICV8: case ENCR_AES_GCM_ICV8:
case ENCR_AES_GCM_ICV12: case ENCR_AES_GCM_ICV12:
case ENCR_AES_GCM_ICV16: case ENCR_AES_GCM_ICV16:
add_keymat = 4; enc_size += 32;
break; break;
default: default:
add_keymat = 0; add_keymat = 0;
break; break;
} }
prf_plus->allocate_bytes(prf_plus, this->enc_size / 8 + add_keymat, prf_plus->allocate_bytes(prf_plus, enc_size / 8, &this->enc_key);
&enc_key);
} }
/* select integrity algo, derive key */ /* select integrity algo, derive key */
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
&this->int_alg, &this->int_size)) &this->int_alg, &int_size))
{ {
DBG2(DBG_CHD, " using %N for integrity", DBG2(DBG_CHD, " using %N for integrity",
integrity_algorithm_names, this->int_alg); integrity_algorithm_names, this->int_alg);
} }
if (!this->int_size) if (this->int_alg != AUTH_UNDEFINED)
{ {
this->int_size = lookup_keylen(keylen_int, this->int_alg); if (!int_size)
} {
if (this->int_size && this->int_alg != AUTH_UNDEFINED) int_size = lookup_keylen(keylen_int, this->int_alg);
{ }
prf_plus->allocate_bytes(prf_plus, this->int_size / 8, &int_key); if (!enc_size)
{
DBG1(DBG_CHD, "no keylenth defined for %N",
integrity_algorithm_names, this->int_alg);
return FAILED;
}
prf_plus->allocate_bytes(prf_plus, int_size / 8, &this->int_key);
} }
/* send SA down to the kernel */ /* send SA down to the kernel */
@@ -697,11 +708,9 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal,
hard = this->config->get_lifetime(this->config, FALSE); hard = this->config->get_lifetime(this->config, FALSE);
status = charon->kernel_interface->add_sa(charon->kernel_interface, status = charon->kernel_interface->add_sa(charon->kernel_interface,
src, dst, spi, this->protocol, this->reqid, mine ? soft : 0, hard, src, dst, spi, this->protocol, this->reqid, mine ? soft : 0, hard,
this->enc_alg, enc_key, this->int_alg, int_key, this->enc_alg, this->enc_key, this->int_alg, this->int_key,
mode, IPCOMP_NONE, this->encap, mine); mode, IPCOMP_NONE, this->encap, mine);
chunk_clear(&enc_key);
chunk_clear(&int_key);
this->install_time = time(NULL); this->install_time = time(NULL);
this->rekey_time = this->install_time + soft; this->rekey_time = this->install_time + soft;
return status; return status;
@@ -1107,6 +1116,8 @@ static void destroy(private_child_sa_t *this)
} }
this->policies->destroy(this->policies); this->policies->destroy(this->policies);
chunk_clear(&this->enc_key);
chunk_clear(&this->int_key);
this->my_ts->destroy(this->my_ts); this->my_ts->destroy(this->my_ts);
this->other_ts->destroy(this->other_ts); this->other_ts->destroy(this->other_ts);
this->me.addr->destroy(this->me.addr); this->me.addr->destroy(this->me.addr);
@@ -1135,7 +1146,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi; this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi;
this->public.get_cpi = (u_int16_t(*)(child_sa_t*, bool))get_cpi; this->public.get_cpi = (u_int16_t(*)(child_sa_t*, bool))get_cpi;
this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol; this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol;
this->public.get_stats = (void(*)(child_sa_t*, ipsec_mode_t*,encryption_algorithm_t*,size_t*,integrity_algorithm_t*,size_t*,u_int32_t*,u_int32_t*,u_int32_t*,u_int32_t*))get_stats; this->public.get_stats = (void(*)(child_sa_t*, ipsec_mode_t*,encryption_algorithm_t*,chunk_t*,integrity_algorithm_t*,chunk_t*,u_int32_t*,u_int32_t*,u_int32_t*,u_int32_t*))get_stats;
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc; this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))add; this->public.add = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))add;
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))update; this->public.update = (status_t(*)(child_sa_t*,proposal_t*,ipsec_mode_t,prf_plus_t*))update;
@@ -1169,9 +1180,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
/* reuse old reqid if we are rekeying an existing CHILD_SA */ /* reuse old reqid if we are rekeying an existing CHILD_SA */
this->reqid = rekey ? rekey : ++reqid; this->reqid = rekey ? rekey : ++reqid;
this->enc_alg = ENCR_UNDEFINED; this->enc_alg = ENCR_UNDEFINED;
this->enc_size = 0; this->enc_key = chunk_empty;
this->int_alg = AUTH_UNDEFINED; this->int_alg = AUTH_UNDEFINED;
this->int_size = 0; this->int_key = chunk_empty;
this->policies = linked_list_create(); this->policies = linked_list_create();
this->my_ts = linked_list_create(); this->my_ts = linked_list_create();
this->other_ts = linked_list_create(); this->other_ts = linked_list_create();
+4 -4
View File
@@ -147,17 +147,17 @@ struct child_sa_t {
* *
* @param mode mode this IKE_SA uses * @param mode mode this IKE_SA uses
* @param encr_algo encryption algorithm used by this CHILD_SA. * @param encr_algo encryption algorithm used by this CHILD_SA.
* @param encr_len key length of the algorithm, if any * @param encr_key encryption key
* @param int_algo integrity algorithm used by this CHILD_SA * @param int_algo integrity algorithm used by this CHILD_SA
* @param int_len key length of the algorithm, if any * @param int_key integrity key
* @param rekey time when rekeying is scheduled * @param rekey time when rekeying is scheduled
* @param use_in time when last traffic was seen coming in * @param use_in time when last traffic was seen coming in
* @param use_out time when last traffic was seen going out * @param use_out time when last traffic was seen going out
* @param use_fwd time when last traffic was getting forwarded * @param use_fwd time when last traffic was getting forwarded
*/ */
void (*get_stats)(child_sa_t *this, ipsec_mode_t *mode, void (*get_stats)(child_sa_t *this, ipsec_mode_t *mode,
encryption_algorithm_t *encr, size_t *encr_len, encryption_algorithm_t *encr, chunk_t *encr_key,
integrity_algorithm_t *int_algo, size_t *int_len, integrity_algorithm_t *int_algo, chunk_t *int_key,
u_int32_t *rekey, u_int32_t *use_in, u_int32_t *use_out, u_int32_t *rekey, u_int32_t *use_in, u_int32_t *use_out,
u_int32_t *use_fwd); u_int32_t *use_fwd);