From 633389f2f4ac78a88949a7b7e09182cd72d6a999 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 30 Aug 2016 14:43:49 -0500 Subject: [PATCH] eap-wsc: Add utility to decrypt EncryptedSettings --- src/eap-wsc.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/eap-wsc.c b/src/eap-wsc.c index ea7224cf..370fc849 100644 --- a/src/eap-wsc.c +++ b/src/eap-wsc.c @@ -134,6 +134,59 @@ static inline bool keywrap_authenticator_check(struct eap_wsc_state *wsc, return true; } +static uint8_t *encrypted_settings_decrypt(struct eap_wsc_state *wsc, + const uint8_t *pdu, + size_t len, + size_t *out_len) +{ + size_t encrypted_len; + uint8_t *decrypted; + unsigned int i; + uint8_t pad; + + /* WSC 2.0.5, Section 12, Encrypted Settings: + * "The Data field of the Encrypted Settings attribute includes an + * initialization vector (IV) followed by a set of encrypted Wi-Fi + * Simple Configuration TLV attributes." + * + * Account for the IV being in the beginning 16 bytes + */ + if (len < 16 ) + return NULL; + + encrypted_len = len - 16; + if (encrypted_len < 16 || encrypted_len % 16) + return NULL; + + decrypted = l_malloc(encrypted_len); + + l_cipher_set_iv(wsc->aes_cbc_128, pdu, 16); + + if (!l_cipher_decrypt(wsc->aes_cbc_128, pdu + 16, + decrypted, encrypted_len)) + goto fail; + + /* Check that the pad value is sane */ + pad = decrypted[encrypted_len - 1]; + if (pad > encrypted_len) + goto fail; + + for (i = 0; i < pad; i++) { + if (decrypted[encrypted_len - pad + i] == pad) + continue; + + goto fail; + } + + *out_len = encrypted_len - pad; + + return decrypted; + +fail: + l_free(decrypted); + return NULL; +} + static int eap_wsc_probe(struct eap_state *eap, const char *name) { struct eap_wsc_state *wsc;