From d2e7d47c846ec5214741b091c6d89b601306b1fc Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Tue, 23 Apr 2019 10:47:23 -0700 Subject: [PATCH] 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. --- src/ap.c | 2 +- src/fils.c | 5 ++--- src/ie.c | 20 +++++++++++++++++--- src/ie.h | 7 +++++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/ap.c b/src/ap.c index b6a95594..5f92c61d 100644 --- a/src/ap.c +++ b/src/ap.c @@ -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 */ diff --git a/src/fils.c b/src/fils.c index 7fd00bf7..73073dd4 100644 --- a/src/fils.c +++ b/src/fils.c @@ -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); diff --git a/src/ie.c b/src/ie.c index 51b4faf9..239cb2c8 100644 --- a/src/ie.c +++ b/src/ie.c @@ -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; } /* diff --git a/src/ie.h b/src/ie.h index 4b35626e..723ea61c 100644 --- a/src/ie.h +++ b/src/ie.h @@ -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);