mka: Clean up key allocation
Assign cs in ieee802_1x_mka_decode_dist_sak_body and reuse it. Cleanup of key allocation: ieee802_1x_kay_generate_new_sak() and ieee802_1x_mka_decode_dist_sak_body() both allocate a struct key_conf, fill it, and ask ieee802_1x_kay_init_data_key() to allocate and set up a struct data_key. They also allocate multiple key buffers and copy the same data around. Stop moving data from buffer to buffer, and just allocate what we really need. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
This commit is contained in:
parent
95e9460d6a
commit
7dcec24881
2 changed files with 66 additions and 135 deletions
|
@ -1402,7 +1402,7 @@ ieee802_1x_mka_get_dist_sak_length(
|
||||||
int length = MKA_HDR_LEN;
|
int length = MKA_HDR_LEN;
|
||||||
unsigned int cs_index = participant->kay->macsec_csindex;
|
unsigned int cs_index = participant->kay->macsec_csindex;
|
||||||
|
|
||||||
if (participant->advised_desired) {
|
if (participant->advised_desired && cs_index < CS_TABLE_SIZE) {
|
||||||
length = sizeof(struct ieee802_1x_mka_dist_sak_body);
|
length = sizeof(struct ieee802_1x_mka_dist_sak_body);
|
||||||
if (cs_index != DEFAULT_CS_INDEX)
|
if (cs_index != DEFAULT_CS_INDEX)
|
||||||
length += CS_ID_LEN;
|
length += CS_ID_LEN;
|
||||||
|
@ -1444,6 +1444,8 @@ ieee802_1x_mka_encode_dist_sak_body(
|
||||||
body->kn = host_to_be32(sak->key_identifier.kn);
|
body->kn = host_to_be32(sak->key_identifier.kn);
|
||||||
cs_index = participant->kay->macsec_csindex;
|
cs_index = participant->kay->macsec_csindex;
|
||||||
sak_pos = 0;
|
sak_pos = 0;
|
||||||
|
if (cs_index >= CS_TABLE_SIZE)
|
||||||
|
return -1;
|
||||||
if (cs_index != DEFAULT_CS_INDEX) {
|
if (cs_index != DEFAULT_CS_INDEX) {
|
||||||
be64 cs;
|
be64 cs;
|
||||||
|
|
||||||
|
@ -1467,39 +1469,13 @@ ieee802_1x_mka_encode_dist_sak_body(
|
||||||
/**
|
/**
|
||||||
* ieee802_1x_kay_init_data_key -
|
* ieee802_1x_kay_init_data_key -
|
||||||
*/
|
*/
|
||||||
static struct data_key *
|
static void ieee802_1x_kay_init_data_key(struct data_key *pkey)
|
||||||
ieee802_1x_kay_init_data_key(const struct key_conf *conf)
|
|
||||||
{
|
{
|
||||||
struct data_key *pkey;
|
pkey->transmits = TRUE;
|
||||||
|
pkey->receives = TRUE;
|
||||||
if (!conf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
pkey = os_zalloc(sizeof(*pkey));
|
|
||||||
if (pkey == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkey->key = os_zalloc(conf->key_len);
|
|
||||||
if (pkey->key == NULL) {
|
|
||||||
wpa_printf(MSG_ERROR, "%s: out of memory", __func__);
|
|
||||||
os_free(pkey);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memcpy(pkey->key, conf->key, conf->key_len);
|
|
||||||
os_memcpy(&pkey->key_identifier, &conf->ki,
|
|
||||||
sizeof(pkey->key_identifier));
|
|
||||||
pkey->confidentiality_offset = conf->offset;
|
|
||||||
pkey->an = conf->an;
|
|
||||||
pkey->transmits = conf->tx;
|
|
||||||
pkey->receives = conf->rx;
|
|
||||||
os_get_time(&pkey->created_time);
|
os_get_time(&pkey->created_time);
|
||||||
|
|
||||||
pkey->user = 1;
|
pkey->user = 1;
|
||||||
|
|
||||||
return pkey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1516,9 +1492,7 @@ ieee802_1x_mka_decode_dist_sak_body(
|
||||||
struct ieee802_1x_kay_peer *peer;
|
struct ieee802_1x_kay_peer *peer;
|
||||||
struct macsec_ciphersuite *cs;
|
struct macsec_ciphersuite *cs;
|
||||||
size_t body_len;
|
size_t body_len;
|
||||||
struct key_conf *conf;
|
|
||||||
struct data_key *sa_key = NULL;
|
struct data_key *sa_key = NULL;
|
||||||
struct ieee802_1x_mka_ki sak_ki;
|
|
||||||
int sak_len;
|
int sak_len;
|
||||||
u8 *wrap_sak;
|
u8 *wrap_sak;
|
||||||
u8 *unwrap_sak;
|
u8 *unwrap_sak;
|
||||||
|
@ -1597,6 +1571,7 @@ ieee802_1x_mka_decode_dist_sak_body(
|
||||||
sak_len = DEFAULT_SA_KEY_LEN;
|
sak_len = DEFAULT_SA_KEY_LEN;
|
||||||
wrap_sak = body->sak;
|
wrap_sak = body->sak;
|
||||||
kay->macsec_csindex = DEFAULT_CS_INDEX;
|
kay->macsec_csindex = DEFAULT_CS_INDEX;
|
||||||
|
cs = &cipher_suite_tbl[kay->macsec_csindex];
|
||||||
} else {
|
} else {
|
||||||
cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak);
|
cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak);
|
||||||
if (!cs) {
|
if (!cs) {
|
||||||
|
@ -1622,61 +1597,36 @@ ieee802_1x_mka_decode_dist_sak_body(
|
||||||
}
|
}
|
||||||
wpa_hexdump(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len);
|
wpa_hexdump(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len);
|
||||||
|
|
||||||
conf = os_zalloc(sizeof(*conf));
|
sa_key = os_zalloc(sizeof(*sa_key));
|
||||||
if (!conf) {
|
|
||||||
wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
|
|
||||||
os_free(unwrap_sak);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
conf->key_len = sak_len;
|
|
||||||
|
|
||||||
conf->key = os_zalloc(conf->key_len);
|
|
||||||
if (!conf->key) {
|
|
||||||
wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
|
|
||||||
os_free(unwrap_sak);
|
|
||||||
os_free(conf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memcpy(conf->key, unwrap_sak, conf->key_len);
|
|
||||||
|
|
||||||
os_memcpy(&sak_ki.mi, &participant->current_peer_id.mi,
|
|
||||||
sizeof(sak_ki.mi));
|
|
||||||
sak_ki.kn = be_to_host32(body->kn);
|
|
||||||
|
|
||||||
os_memcpy(conf->ki.mi, sak_ki.mi, MI_LEN);
|
|
||||||
conf->ki.kn = sak_ki.kn;
|
|
||||||
conf->an = body->dan;
|
|
||||||
conf->offset = body->confid_offset;
|
|
||||||
conf->rx = TRUE;
|
|
||||||
conf->tx = TRUE;
|
|
||||||
|
|
||||||
sa_key = ieee802_1x_kay_init_data_key(conf);
|
|
||||||
if (!sa_key) {
|
if (!sa_key) {
|
||||||
os_free(unwrap_sak);
|
os_free(unwrap_sak);
|
||||||
os_free(conf->key);
|
|
||||||
os_free(conf);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
os_memcpy(&sa_key->key_identifier.mi, &participant->current_peer_id.mi,
|
||||||
|
MI_LEN);
|
||||||
|
sa_key->key_identifier.kn = be_to_host32(body->kn);
|
||||||
|
|
||||||
|
sa_key->key = unwrap_sak;
|
||||||
|
sa_key->key_len = sak_len;
|
||||||
|
|
||||||
|
sa_key->confidentiality_offset = body->confid_offset;
|
||||||
|
sa_key->an = body->dan;
|
||||||
|
ieee802_1x_kay_init_data_key(sa_key);
|
||||||
|
|
||||||
dl_list_add(&participant->sak_list, &sa_key->list);
|
dl_list_add(&participant->sak_list, &sa_key->list);
|
||||||
|
|
||||||
ieee802_1x_cp_set_ciphersuite(kay->cp,
|
ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id);
|
||||||
cipher_suite_tbl[kay->macsec_csindex].id);
|
|
||||||
ieee802_1x_cp_sm_step(kay->cp);
|
ieee802_1x_cp_sm_step(kay->cp);
|
||||||
ieee802_1x_cp_set_offset(kay->cp, body->confid_offset);
|
ieee802_1x_cp_set_offset(kay->cp, body->confid_offset);
|
||||||
ieee802_1x_cp_sm_step(kay->cp);
|
ieee802_1x_cp_sm_step(kay->cp);
|
||||||
ieee802_1x_cp_set_distributedki(kay->cp, &sak_ki);
|
ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier);
|
||||||
ieee802_1x_cp_set_distributedan(kay->cp, body->dan);
|
ieee802_1x_cp_set_distributedan(kay->cp, body->dan);
|
||||||
ieee802_1x_cp_signal_newsak(kay->cp);
|
ieee802_1x_cp_signal_newsak(kay->cp);
|
||||||
ieee802_1x_cp_sm_step(kay->cp);
|
ieee802_1x_cp_sm_step(kay->cp);
|
||||||
|
|
||||||
participant->to_use_sak = TRUE;
|
participant->to_use_sak = TRUE;
|
||||||
|
|
||||||
os_free(unwrap_sak);
|
|
||||||
os_free(conf->key);
|
|
||||||
os_free(conf);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1949,11 +1899,13 @@ static int
|
||||||
ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
|
ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
|
||||||
{
|
{
|
||||||
struct data_key *sa_key = NULL;
|
struct data_key *sa_key = NULL;
|
||||||
struct key_conf *conf;
|
|
||||||
struct ieee802_1x_kay_peer *peer;
|
struct ieee802_1x_kay_peer *peer;
|
||||||
struct ieee802_1x_kay *kay = participant->kay;
|
struct ieee802_1x_kay *kay = participant->kay;
|
||||||
int ctx_len, ctx_offset;
|
int ctx_len, ctx_offset;
|
||||||
u8 *context;
|
u8 *context;
|
||||||
|
unsigned int key_len;
|
||||||
|
u8 *key;
|
||||||
|
struct macsec_ciphersuite *cs;
|
||||||
|
|
||||||
/* check condition for generating a fresh SAK:
|
/* check condition for generating a fresh SAK:
|
||||||
* must have one live peer
|
* must have one live peer
|
||||||
|
@ -1980,40 +1932,29 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf = os_zalloc(sizeof(*conf));
|
cs = &cipher_suite_tbl[kay->macsec_csindex];
|
||||||
if (!conf) {
|
key_len = cs->sak_len;
|
||||||
wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
|
key = os_zalloc(key_len);
|
||||||
return -1;
|
if (!key) {
|
||||||
}
|
|
||||||
conf->key_len = cipher_suite_tbl[kay->macsec_csindex].sak_len;
|
|
||||||
|
|
||||||
conf->key = os_zalloc(conf->key_len);
|
|
||||||
if (!conf->key) {
|
|
||||||
os_free(conf);
|
|
||||||
wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
|
wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx_len = conf->key_len + sizeof(kay->dist_kn);
|
ctx_len = key_len + sizeof(kay->dist_kn);
|
||||||
dl_list_for_each(peer, &participant->live_peers,
|
dl_list_for_each(peer, &participant->live_peers,
|
||||||
struct ieee802_1x_kay_peer, list)
|
struct ieee802_1x_kay_peer, list)
|
||||||
ctx_len += sizeof(peer->mi);
|
ctx_len += sizeof(peer->mi);
|
||||||
ctx_len += sizeof(participant->mi);
|
ctx_len += sizeof(participant->mi);
|
||||||
|
|
||||||
context = os_zalloc(ctx_len);
|
context = os_zalloc(ctx_len);
|
||||||
if (!context) {
|
if (!context)
|
||||||
os_free(conf->key);
|
goto fail;
|
||||||
os_free(conf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ctx_offset = 0;
|
ctx_offset = 0;
|
||||||
if (os_get_random(context + ctx_offset, conf->key_len) < 0) {
|
if (os_get_random(context + ctx_offset, key_len) < 0)
|
||||||
os_free(context);
|
goto fail;
|
||||||
os_free(conf->key);
|
|
||||||
os_free(conf);
|
ctx_offset += key_len;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ctx_offset += conf->key_len;
|
|
||||||
dl_list_for_each(peer, &participant->live_peers,
|
dl_list_for_each(peer, &participant->live_peers,
|
||||||
struct ieee802_1x_kay_peer, list) {
|
struct ieee802_1x_kay_peer, list) {
|
||||||
os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi));
|
os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi));
|
||||||
|
@ -2024,46 +1965,44 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
|
||||||
ctx_offset += sizeof(participant->mi);
|
ctx_offset += sizeof(participant->mi);
|
||||||
os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn));
|
os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn));
|
||||||
|
|
||||||
if (conf->key_len == 16) {
|
if (key_len == 16) {
|
||||||
ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
|
ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
|
||||||
context, ctx_len, conf->key);
|
context, ctx_len, key);
|
||||||
} else if (conf->key_len == 32) {
|
} else if (key_len == 32) {
|
||||||
ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
|
ieee802_1x_sak_128bits_aes_cmac(participant->cak.key,
|
||||||
context, ctx_len, conf->key);
|
context, ctx_len, key);
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_ERROR, "KaY: SAK Length not support");
|
wpa_printf(MSG_ERROR, "KaY: SAK Length not support");
|
||||||
os_free(conf->key);
|
goto fail;
|
||||||
os_free(conf);
|
|
||||||
os_free(context);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK",
|
wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK", key, key_len);
|
||||||
conf->key, conf->key_len);
|
os_free(context);
|
||||||
|
context = NULL;
|
||||||
|
|
||||||
os_memcpy(conf->ki.mi, participant->mi, MI_LEN);
|
sa_key = os_zalloc(sizeof(*sa_key));
|
||||||
conf->ki.kn = kay->dist_kn;
|
|
||||||
conf->an = kay->dist_an;
|
|
||||||
conf->offset = kay->macsec_confidentiality;
|
|
||||||
conf->rx = TRUE;
|
|
||||||
conf->tx = TRUE;
|
|
||||||
|
|
||||||
sa_key = ieee802_1x_kay_init_data_key(conf);
|
|
||||||
if (!sa_key) {
|
if (!sa_key) {
|
||||||
os_free(conf->key);
|
wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__);
|
||||||
os_free(conf);
|
goto fail;
|
||||||
os_free(context);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sa_key->key = key;
|
||||||
|
sa_key->key_len = key_len;
|
||||||
|
os_memcpy(sa_key->key_identifier.mi, participant->mi, MI_LEN);
|
||||||
|
sa_key->key_identifier.kn = kay->dist_kn;
|
||||||
|
|
||||||
|
sa_key->confidentiality_offset = kay->macsec_confidentiality;
|
||||||
|
sa_key->an = kay->dist_an;
|
||||||
|
ieee802_1x_kay_init_data_key(sa_key);
|
||||||
|
|
||||||
participant->new_key = sa_key;
|
participant->new_key = sa_key;
|
||||||
|
|
||||||
dl_list_add(&participant->sak_list, &sa_key->list);
|
dl_list_add(&participant->sak_list, &sa_key->list);
|
||||||
ieee802_1x_cp_set_ciphersuite(kay->cp,
|
ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id);
|
||||||
cipher_suite_tbl[kay->macsec_csindex].id);
|
|
||||||
ieee802_1x_cp_sm_step(kay->cp);
|
ieee802_1x_cp_sm_step(kay->cp);
|
||||||
ieee802_1x_cp_set_offset(kay->cp, conf->offset);
|
ieee802_1x_cp_set_offset(kay->cp, kay->macsec_confidentiality);
|
||||||
ieee802_1x_cp_sm_step(kay->cp);
|
ieee802_1x_cp_sm_step(kay->cp);
|
||||||
ieee802_1x_cp_set_distributedki(kay->cp, &conf->ki);
|
ieee802_1x_cp_set_distributedki(kay->cp, &sa_key->key_identifier);
|
||||||
ieee802_1x_cp_set_distributedan(kay->cp, conf->an);
|
ieee802_1x_cp_set_distributedan(kay->cp, sa_key->an);
|
||||||
ieee802_1x_cp_signal_newsak(kay->cp);
|
ieee802_1x_cp_signal_newsak(kay->cp);
|
||||||
ieee802_1x_cp_sm_step(kay->cp);
|
ieee802_1x_cp_sm_step(kay->cp);
|
||||||
|
|
||||||
|
@ -2078,10 +2017,12 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
|
||||||
|
|
||||||
kay->dist_time = time(NULL);
|
kay->dist_time = time(NULL);
|
||||||
|
|
||||||
os_free(conf->key);
|
|
||||||
os_free(conf);
|
|
||||||
os_free(context);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
os_free(key);
|
||||||
|
os_free(context);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,16 +54,6 @@ struct ieee802_1x_kay_peer {
|
||||||
struct dl_list list;
|
struct dl_list list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct key_conf {
|
|
||||||
u8 *key;
|
|
||||||
struct ieee802_1x_mka_ki ki;
|
|
||||||
enum confidentiality_offset offset;
|
|
||||||
u8 an;
|
|
||||||
Boolean tx;
|
|
||||||
Boolean rx;
|
|
||||||
int key_len; /* unit: byte */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct data_key {
|
struct data_key {
|
||||||
u8 *key;
|
u8 *key;
|
||||||
int key_len;
|
int key_len;
|
||||||
|
|
Loading…
Reference in a new issue