ie: fix ie_tlv_builder semantics

The TLV builder APIs were not very intuative, and in some (or all)
cases required access to the builder structure directly, either to
set the TLV buffer or to get the buffer at the end.

This change adds a new API, ie_tlv_builder_set_data, which both sets
the length for the current TLV and copies the TLV data in one go.
This will avoid the need for memcpy(ie_tlv_builder_get_data(...),...)

ie_tlv_builder_finalize was also changed to return a pointer to the
start of the build buffer. This will eliminate the need to access
builder.tlv after building the TLVs.

ie_tlv_builder_init was changed to take an optional buffer to hold
the TLV data. Passing NULL/0 will build the TLV in the internal
buffer. Passing in a pointer and length will build into the passed
in buffer.
This commit is contained in:
James Prestwood 2019-04-23 10:47:23 -07:00 committed by Denis Kenzior
parent 1521b57ec9
commit d2e7d47c84
4 changed files with 25 additions and 9 deletions

View File

@ -297,7 +297,7 @@ static size_t ap_build_beacon_pr_head(struct ap_state *ap,
l_put_le16(ap->beacon_interval, out_buf + 32); /* Beacon Interval */
l_put_le16(capability, out_buf + 34); /* Capability Info */
ie_tlv_builder_init(&builder);
ie_tlv_builder_init(&builder, NULL, 0);
builder.tlv = out_buf + 36;
/* SSID IE */

View File

@ -85,8 +85,7 @@ static void fils_erp_tx_func(const uint8_t *eap_data, size_t len,
l_put_le16(0, ptr);
ptr += 2;
ie_tlv_builder_init(&builder);
builder.tlv = ptr;
ie_tlv_builder_init(&builder, ptr, sizeof(data) - 4);
ie_tlv_builder_next(&builder, IE_TYPE_FILS_NONCE);
ie_tlv_builder_set_length(&builder, sizeof(fils->nonce));
@ -207,7 +206,7 @@ static void fils_erp_complete(enum erp_result result, const void *rmsk,
hmac_sha256(fils->ick, hash_len, data, ptr - data,
key_auth, hash_len);
ie_tlv_builder_init(&builder);
ie_tlv_builder_init(&builder, NULL, 0);
ie_tlv_builder_next(&builder, IE_TYPE_FILS_KEY_CONFIRMATION);
ie_tlv_builder_set_length(&builder, hash_len);

View File

@ -255,9 +255,10 @@ static bool ie_tlv_builder_init_recurse(struct ie_tlv_builder *builder,
return true;
}
bool ie_tlv_builder_init(struct ie_tlv_builder *builder)
bool ie_tlv_builder_init(struct ie_tlv_builder *builder, unsigned char *buf,
size_t len)
{
return ie_tlv_builder_init_recurse(builder, NULL, 0);
return ie_tlv_builder_init_recurse(builder, buf, len);
}
static void ie_tlv_builder_write_header(struct ie_tlv_builder *builder)
@ -314,6 +315,17 @@ unsigned char *ie_tlv_builder_get_data(struct ie_tlv_builder *builder)
(builder->tag >= 256 ? 1 : 0);
}
bool ie_tlv_builder_set_data(struct ie_tlv_builder *builder,
const void *data, size_t len)
{
if (!ie_tlv_builder_set_length(builder, len))
return false;
memcpy(ie_tlv_builder_get_data(builder), data, len);
return true;
}
bool ie_tlv_builder_recurse(struct ie_tlv_builder *builder,
struct ie_tlv_builder *recurse)
{
@ -328,7 +340,7 @@ bool ie_tlv_builder_recurse(struct ie_tlv_builder *builder,
return true;
}
void ie_tlv_builder_finalize(struct ie_tlv_builder *builder,
unsigned char *ie_tlv_builder_finalize(struct ie_tlv_builder *builder,
unsigned int *out_len)
{
unsigned int len = 0;
@ -342,6 +354,8 @@ void ie_tlv_builder_finalize(struct ie_tlv_builder *builder,
if (out_len)
*out_len = len;
return builder->tlv;
}
/*

View File

@ -395,14 +395,17 @@ void *ie_tlv_extract_wsc_payload(const uint8_t *ies, size_t len,
void *ie_tlv_encapsulate_wsc_payload(const uint8_t *data, size_t len,
size_t *out_len);
bool ie_tlv_builder_init(struct ie_tlv_builder *builder);
bool ie_tlv_builder_init(struct ie_tlv_builder *builder, unsigned char *buf,
size_t len);
bool ie_tlv_builder_set_length(struct ie_tlv_builder *builder,
unsigned int new_len);
bool ie_tlv_builder_next(struct ie_tlv_builder *builder, unsigned int new_tag);
unsigned char *ie_tlv_builder_get_data(struct ie_tlv_builder *builder);
bool ie_tlv_builder_set_data(struct ie_tlv_builder *builder,
const void *data, size_t len);
bool ie_tlv_builder_recurse(struct ie_tlv_builder *builder,
struct ie_tlv_builder *recurse);
void ie_tlv_builder_finalize(struct ie_tlv_builder *builder,
unsigned char *ie_tlv_builder_finalize(struct ie_tlv_builder *builder,
unsigned int *out_len);
uint32_t ie_rsn_cipher_suite_to_cipher(enum ie_rsn_cipher_suite suite);