feat(wps): sync esp32 wps code to esp8266

This commit is contained in:
Chen Wen
2019-09-09 13:20:12 +08:00
parent 21d8877663
commit 8c52206736
28 changed files with 2317 additions and 64 deletions

View File

@ -0,0 +1,799 @@
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __ESP_WIFI_CRYPTO_TYPES_H__
#define __ESP_WIFI_CRYPTO_TYPES_H__
/* This is an internal API header for configuring the implementation used for WiFi cryptographic
operations.
During normal operation, you don't need to use any of these types or functions in this header.
See esp_wifi.h & esp_wifi_types.h instead.
*/
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_WIFI_CRYPTO_VERSION 0x00000001
/*
* Enumeration for hash operations.
* When WPA2 is connecting, this enum is used to
* request a hash algorithm via crypto_hash_xxx functions.
*/
typedef enum {
ESP_CRYPTO_HASH_ALG_MD5, ESP_CRYPTO_HASH_ALG_SHA1,
ESP_CRYPTO_HASH_ALG_HMAC_MD5, ESP_CRYPTO_HASH_ALG_HMAC_SHA1,
ESP_CRYPTO_HASH_ALG_SHA256, ESP_CRYPTO_HASH_ALG_HMAC_SHA256
}esp_crypto_hash_alg_t;
/*
* Enumeration for block cipher operations.
* When WPA2 is connecting, this enum is used to request a block
* cipher algorithm via crypto_cipher_xxx functions.
*/
typedef enum {
ESP_CRYPTO_CIPHER_NULL, ESP_CRYPTO_CIPHER_ALG_AES, ESP_CRYPTO_CIPHER_ALG_3DES,
ESP_CRYPTO_CIPHER_ALG_DES, ESP_CRYPTO_CIPHER_ALG_RC2, ESP_CRYPTO_CIPHER_ALG_RC4
} esp_crypto_cipher_alg_t;
/*
* This structure is about the algorithm when do crypto_hash operation, for detail,
* please reference to the structure crypto_hash.
*/
typedef struct crypto_hash esp_crypto_hash_t;
/*
* This structure is about the algorithm when do crypto_cipher operation, for detail,
* please reference to the structure crypto_cipher.
*/
typedef struct crypto_cipher esp_crypto_cipher_t;
/**
* @brief The crypto callback function used in wpa enterprise hash operation when connect.
* Initialize a esp_crypto_hash_t structure.
*
* @param alg Hash algorithm.
* @param key Key for keyed hash (e.g., HMAC) or %NULL if not needed.
* @param key_len Length of the key in bytes
*
*/
typedef esp_crypto_hash_t * (*esp_crypto_hash_init_t)(esp_crypto_hash_alg_t alg, const unsigned char *key, int key_len);
/**
* @brief The crypto callback function used in wpa enterprise hash operation when connect.
* Add data to hash calculation.
*
* @param ctz Context pointer from esp_crypto_hash_init_t function.
* @param data Data buffer to add.
* @param len Length of the buffer.
*
*/
typedef void (*esp_crypto_hash_update_t)(esp_crypto_hash_t *ctx, const unsigned char *data, int len);
/**
* @brief The crypto callback function used in wpa enterprise hash operation when connect.
* Complete hash calculation.
*
* @param ctz Context pointer from esp_crypto_hash_init_t function.
* @param hash Buffer for hash value or %NULL if caller is just freeing the hash
* context.
* @param len Pointer to length of the buffer or %NULL if caller is just freeing the
* hash context; on return, this is set to the actual length of the hash value
* Returns: 0 on success, -1 if buffer is too small (len set to needed length),
* or -2 on other failures (including failed crypto_hash_update() operations)
*
*/
typedef int (*esp_crypto_hash_finish_t)(esp_crypto_hash_t *ctx, unsigned char *hash, int *len);
/**
* @brief The AES callback function when do WPS connect.
*
* @param key Encryption key.
* @param iv Encryption IV for CBC mode (16 bytes).
* @param data Data to encrypt in-place.
* @param data_len Length of data in bytes (must be divisible by 16)
*/
typedef int (*esp_aes_128_encrypt_t)(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len);
/**
* @brief The AES callback function when do WPS connect.
*
* @param key Decryption key.
* @param iv Decryption IV for CBC mode (16 bytes).
* @param data Data to decrypt in-place.
* @param data_len Length of data in bytes (must be divisible by 16)
*
*/
typedef int (*esp_aes_128_decrypt_t)(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len);
/**
* @brief The AES callback function when do STA connect.
*
* @param kek 16-octet Key encryption key (KEK).
* @param n Length of the plaintext key in 64-bit units;
* @param plain Plaintext key to be wrapped, n * 64 bits
* @param cipher Wrapped key, (n + 1) * 64 bits
*
*/
typedef int (*esp_aes_wrap_t)(const unsigned char *kek, int n, const unsigned char *plain, unsigned char *cipher);
/**
* @brief The AES callback function when do STA connect.
*
* @param kek 16-octet Key decryption key (KEK).
* @param n Length of the plaintext key in 64-bit units;
* @param cipher Wrapped key to be unwrapped, (n + 1) * 64 bits
* @param plain Plaintext key, n * 64 bits
*
*/
typedef int (*esp_aes_unwrap_t)(const unsigned char *kek, int n, const unsigned char *cipher, unsigned char *plain);
/**
* @brief The crypto callback function used in wpa enterprise cipher operation when connect.
* Initialize a esp_crypto_cipher_t structure.
*
* @param alg cipher algorithm.
* @param iv Initialization vector for block ciphers or %NULL for stream ciphers.
* @param key Cipher key
* @param key_len Length of key in bytes
*
*/
typedef esp_crypto_cipher_t * (*esp_crypto_cipher_init_t)(esp_crypto_cipher_alg_t alg, const unsigned char *iv, const unsigned char *key, int key_len);
/**
* @brief The crypto callback function used in wpa enterprise cipher operation when connect.
* Cipher encrypt.
*
* @param ctx Context pointer from esp_crypto_cipher_init_t callback function.
* @param plain Plaintext to cipher.
* @param crypt Resulting ciphertext.
* @param len Length of the plaintext.
*
*/
typedef int (*esp_crypto_cipher_encrypt_t)(esp_crypto_cipher_t *ctx,
const unsigned char *plain, unsigned char *crypt, int len);
/**
* @brief The crypto callback function used in wpa enterprise cipher operation when connect.
* Cipher decrypt.
*
* @param ctx Context pointer from esp_crypto_cipher_init_t callback function.
* @param crypt Ciphertext to decrypt.
* @param plain Resulting plaintext.
* @param len Length of the cipher text.
*
*/
typedef int (*esp_crypto_cipher_decrypt_t)(esp_crypto_cipher_t *ctx,
const unsigned char *crypt, unsigned char *plain, int len);
/**
* @brief The crypto callback function used in wpa enterprise cipher operation when connect.
* Free cipher context.
*
* @param ctx Context pointer from esp_crypto_cipher_init_t callback function.
*
*/
typedef void (*esp_crypto_cipher_deinit_t)(esp_crypto_cipher_t *ctx);
/**
* @brief The SHA256 callback function when do WPS connect.
*
* @param key Key for HMAC operations.
* @param key_len Length of the key in bytes.
* @param data Pointers to the data area.
* @param data_len Length of the data area.
* @param mac Buffer for the hash (20 bytes).
*
*/
typedef void (*esp_hmac_sha256_t)(const unsigned char *key, int key_len, const unsigned char *data,
int data_len, unsigned char *mac);
/**
* @brief The SHA256 callback function when do WPS connect.
*
* @param key Key for HMAC operations.
* @param key_len Length of the key in bytes.
* @param num_elem Number of elements in the data vector.
* @param addr Pointers to the data areas.
* @param len Lengths of the data blocks.
* @param mac Buffer for the hash (32 bytes).
*
*/
typedef void (*esp_hmac_sha256_vector_t)(const unsigned char *key, int key_len, int num_elem,
const unsigned char *addr[], const int *len, unsigned char *mac);
/**
* @brief The AES callback function when do STA connect.
*
* @param key Key for PRF.
* @param key_len Length of the key in bytes.
* @param label A unique label for each purpose of the PRF.
* @param data Extra data to bind into the key.
* @param data_len Length of the data.
* @param buf Buffer for the generated pseudo-random key.
* @param buf_len Number of bytes of key to generate.
*
*/
typedef void (*esp_sha256_prf_t)(const unsigned char *key, int key_len, const char *label,
const unsigned char *data, int data_len, unsigned char *buf, int buf_len);
/**
* @brief The SHA256 callback function when do WPS connect.
*
* @param num_elem Number of elements in the data vector.
* @param addr Pointers to the data areas.
* @param len Lengths of the data blocks.
* @paramac Buffer for the hash.
*
*/
typedef int (*esp_sha256_vector_t)(int num_elem, const unsigned char *addr[], const int *len,
unsigned char *mac);
/**
* @brief The bignum calculate callback function used when do connect.
* In WPS process, it used to calculate public key and private key.
*
* @param base Base integer (big endian byte array).
* @param base_len Length of base integer in bytes.
* @param power Power integer (big endian byte array).
* @param power_len Length of power integer in bytes.
* @param modulus Modulus integer (big endian byte array).
* @param modulus_len Length of modulus integer in bytes.
* @param result Buffer for the result.
* @param result_len Result length (max buffer size on input, real len on output).
*
*/
typedef int (*esp_crypto_mod_exp_t)(const unsigned char *base, int base_len,
const unsigned char *power, int power_len,
const unsigned char *modulus, int modulus_len,
unsigned char *result, unsigned int *result_len);
/**
* @brief HMAC-MD5 over data buffer (RFC 2104)'
*
* @key: Key for HMAC operations
* @key_len: Length of the key in bytes
* @data: Pointers to the data area
* @data_len: Length of the data area
* @mac: Buffer for the hash (16 bytes)
* Returns: 0 on success, -1 on failure
*/
typedef int (*esp_hmac_md5_t)(const unsigned char *key, unsigned int key_len, const unsigned char *data,
unsigned int data_len, unsigned char *mac);
/**
* @brief HMAC-MD5 over data vector (RFC 2104)
*
* @key: Key for HMAC operations
* @key_len: Length of the key in bytes
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash (16 bytes)
* Returns: 0 on success, -1 on failure
*/
typedef int (*esp_hmac_md5_vector_t)(const unsigned char *key, unsigned int key_len, unsigned int num_elem,
const unsigned char *addr[], const unsigned int *len, unsigned char *mac);
/**
* @brief HMAC-SHA1 over data buffer (RFC 2104)
*
* @key: Key for HMAC operations
* @key_len: Length of the key in bytes
* @data: Pointers to the data area
* @data_len: Length of the data area
* @mac: Buffer for the hash (20 bytes)
* Returns: 0 on success, -1 of failure
*/
typedef int (*esp_hmac_sha1_t)(const unsigned char *key, unsigned int key_len, const unsigned char *data,
unsigned int data_len, unsigned char *mac);
/**
* @brief HMAC-SHA1 over data vector (RFC 2104)
*
* @key: Key for HMAC operations
* @key_len: Length of the key in bytes
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash (20 bytes)
* Returns: 0 on success, -1 on failure
*/
typedef int (*esp_hmac_sha1_vector_t)(const unsigned char *key, unsigned int key_len, unsigned int num_elem,
const unsigned char *addr[], const unsigned int *len, unsigned char *mac);
/**
* @brief SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
*
* @key: Key for PRF
* @key_len: Length of the key in bytes
* @label: A unique label for each purpose of the PRF
* @data: Extra data to bind into the key
* @data_len: Length of the data
* @buf: Buffer for the generated pseudo-random key
* @buf_len: Number of bytes of key to generate
* Returns: 0 on success, -1 of failure
*
* This function is used to derive new, cryptographically separate keys from a
* given key (e.g., PMK in IEEE 802.11i).
*/
typedef int (*esp_sha1_prf_t)(const unsigned char *key, unsigned int key_len, const char *label,
const unsigned char *data, unsigned int data_len, unsigned char *buf, unsigned int buf_len);
/**
* @brief SHA-1 hash for data vector
*
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash
* Returns: 0 on success, -1 on failure
*/
typedef int (*esp_sha1_vector_t)(unsigned int num_elem, const unsigned char *addr[], const unsigned int *len,
unsigned char *mac);
/**
* @brief SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
*
* @passphrase: ASCII passphrase
* @ssid: SSID
* @ssid_len: SSID length in bytes
* @iterations: Number of iterations to run
* @buf: Buffer for the generated key
* @buflen: Length of the buffer in bytes
* Returns: 0 on success, -1 of failure
*
* This function is used to derive PSK for WPA-PSK. For this protocol,
* iterations is set to 4096 and buflen to 32. This function is described in
* IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
*/
typedef int (*esp_pbkdf2_sha1_t)(const char *passphrase, const char *ssid, unsigned int ssid_len,
int iterations, unsigned char *buf, unsigned int buflen);
/**
* @brief XOR RC4 stream to given data with skip-stream-start
*
* @key: RC4 key
* @keylen: RC4 key length
* @skip: number of bytes to skip from the beginning of the RC4 stream
* @data: data to be XOR'ed with RC4 stream
* @data_len: buf length
* Returns: 0 on success, -1 on failure
*
* Generate RC4 pseudo random stream for the given key, skip beginning of the
* stream, and XOR the end result with the data buffer to perform RC4
* encryption/decryption.
*/
typedef int (*esp_rc4_skip_t)(const unsigned char *key, unsigned int keylen, unsigned int skip,
unsigned char *data, unsigned int data_len);
/**
* @brief MD5 hash for data vector
*
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash
* Returns: 0 on success, -1 on failure
*/
typedef int (*esp_md5_vector_t)(unsigned int num_elem, const unsigned char *addr[], const unsigned int *len,
unsigned char *mac);
/**
* @brief Encrypt one AES block
*
* @ctx: Context pointer from aes_encrypt_init()
* @plain: Plaintext data to be encrypted (16 bytes)
* @crypt: Buffer for the encrypted data (16 bytes)
*/
typedef void (*esp_aes_encrypt_t)(void *ctx, const unsigned char *plain, unsigned char *crypt);
/**
* @brief Initialize AES for encryption
*
* @key: Encryption key
* @len: Key length in bytes (usually 16, i.e., 128 bits)
* Returns: Pointer to context data or %NULL on failure
*/
typedef void * (*esp_aes_encrypt_init_t)(const unsigned char *key, unsigned int len);
/**
* @brief Deinitialize AES encryption
*
* @ctx: Context pointer from aes_encrypt_init()
*/
typedef void (*esp_aes_encrypt_deinit_t)(void *ctx);
/**
* @brief Decrypt one AES block
*
* @ctx: Context pointer from aes_encrypt_init()
* @crypt: Encrypted data (16 bytes)
* @plain: Buffer for the decrypted data (16 bytes)
*/
typedef void (*esp_aes_decrypt_t)(void *ctx, const unsigned char *crypt, unsigned char *plain);
/**
* @brief Initialize AES for decryption
*
* @key: Decryption key
* @len: Key length in bytes (usually 16, i.e., 128 bits)
* Returns: Pointer to context data or %NULL on failure
*/
typedef void * (*esp_aes_decrypt_init_t)(const unsigned char *key, unsigned int len);
/**
* @brief Deinitialize AES decryption
*
* @ctx: Context pointer from aes_encrypt_init()
*/
typedef void (*esp_aes_decrypt_deinit_t)(void *ctx);
/**
* @brief Initialize TLS library
*
* @conf: Configuration data for TLS library
* Returns: Context data to be used as tls_ctx in calls to other functions,
* or %NULL on failure.
*
* Called once during program startup and once for each RSN pre-authentication
* session. In other words, there can be two concurrent TLS contexts. If global
* library initialization is needed (i.e., one that is shared between both
* authentication types), the TLS library wrapper should maintain a reference
* counter and do global initialization only when moving from 0 to 1 reference.
*/
typedef void * (*esp_tls_init_t)(void);
/**
* @brief Deinitialize TLS library
*
* @tls_ctx: TLS context data from tls_init()
*
* Called once during program shutdown and once for each RSN pre-authentication
* session. If global library deinitialization is needed (i.e., one that is
* shared between both authentication types), the TLS library wrapper should
* maintain a reference counter and do global deinitialization only when moving
* from 1 to 0 references.
*/
typedef void (*esp_tls_deinit_t)(void *tls_ctx);
/**
* @brief Add certificate and private key for connect
* @sm: eap state machine
*
* Returns: 0 for success, -1 state machine didn't exist, -2 short of certificate or key
*/
typedef int (*esp_eap_peer_blob_init_t)(void *sm);
/**
* @brief delete the certificate and private
*
* @sm: eap state machine
*
*/
typedef void (*esp_eap_peer_blob_deinit_t)(void *sm);
/**
* @brief Initialize the eap state machine
*
* @sm: eap state machine
* @private_key_passwd: the start address of private_key_passwd
* @private_key_passwd_len: length of private_key_password
*
* Returns: 0 is success, -1 state machine didn't exist, -2 short of parameters
*
*/
typedef int (*esp_eap_peer_config_init_t)(void *sm, unsigned char *private_key_passwd,int private_key_passwd_len);
/**
* @brief Deinit the eap state machine
*
* @sm: eap state machine
*
*/
typedef void (*esp_eap_peer_config_deinit_t)(void *sm);
/**
* @brief Register the eap method
*
* Note: ESP32 only support PEAP/TTLS/TLS three eap methods now.
*
*/
typedef int (*esp_eap_peer_register_methods_t)(void);
/**
* @brief remove the eap method
*
* Note: ESP32 only support PEAP/TTLS/TLS three eap methods now.
*
*/
typedef void (*esp_eap_peer_unregister_methods_t)(void);
/**
* @brief remove the eap method before build new connect
*
* @sm: eap state machine
* @txt: not used now
*/
typedef void (*esp_eap_deinit_prev_method_t)(void *sm, const char *txt);
/**
* @brief Get EAP method based on type number
*
* @vendor: EAP Vendor-Id (0 = IETF)
* @method: EAP type number
* Returns: Pointer to EAP method or %NULL if not found
*/
typedef const void * (*esp_eap_peer_get_eap_method_t)(int vendor, int method);
/**
* @brief Abort EAP authentication
*
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
*
* Release system resources that have been allocated for the authentication
* session without fully deinitializing the EAP state machine.
*/
typedef void (*esp_eap_sm_abort_t)(void *sm);
/**
* @brief Build EAP-NAK for the current network
*
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
* @type: EAP type of the fail reason
* @id: EAP identifier for the packet
*
* This function allocates and builds a nak packet for the
* current network. The caller is responsible for freeing the returned data.
*/
typedef void * (*esp_eap_sm_build_nak_t)(void *sm, int type, unsigned char id);
/**
* @brief Build EAP-Identity/Response for the current network
*
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
* @id: EAP identifier for the packet
* @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2)
* Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on
* failure
*
* This function allocates and builds an EAP-Identity/Response packet for the
* current network. The caller is responsible for freeing the returned data.
*/
typedef void * (*esp_eap_sm_build_identity_resp_t)(void *sm, unsigned char id, int encrypted);
/**
* @brief Allocate a buffer for an EAP message
*
* @vendor: Vendor-Id (0 = IETF)
* @type: EAP type
* @payload_len: Payload length in bytes (data after Type)
* @code: Message Code (EAP_CODE_*)
* @identifier: Identifier
* Returns: Pointer to the allocated message buffer or %NULL on error
*
* This function can be used to allocate a buffer for an EAP message and fill
* in the EAP header. This function is automatically using expanded EAP header
* if the selected Vendor-Id is not IETF. In other words, most EAP methods do
* not need to separately select which header type to use when using this
* function to allocate the message buffers. The returned buffer has room for
* payload_len bytes and has the EAP header and Type field already filled in.
*/
typedef void * (*esp_eap_msg_alloc_t)(int vendor, int type, unsigned int payload_len,
unsigned char code, unsigned char identifier);
/**
* @brief get the enrollee mac address
* @mac_addr: instore the mac address of enrollee
* @uuid: Universally Unique Identifer of the enrollee
*
*/
typedef void (*esp_uuid_gen_mac_addr_t)(const unsigned char *mac_addr, unsigned char *uuid);
/**
* @brief free the message after finish DH
*
*/
typedef void (*esp_dh5_free_t)(void *ctx);
/**
* @brief Build WPS IE for (Re)Association Request
*
* @req_type: Value for Request Type attribute
* Returns: WPS IE or %NULL on failure
*
* The caller is responsible for freeing the buffer.
*/
typedef void * (*esp_wps_build_assoc_req_ie_t)(int req_type);
/**
* @brief Build WPS IE for (Re)Association Response
*
* Returns: WPS IE or %NULL on failure
*
* The caller is responsible for freeing the buffer.
*/
typedef void * (*esp_wps_build_assoc_resp_ie_t)(void);
/**
* @brief Build WPS IE for Probe Request
*
* @pw_id: Password ID (DEV_PW_PUSHBUTTON for active PBC and DEV_PW_DEFAULT for
* most other use cases)
* @dev: Device attributes
* @uuid: Own UUID
* @req_type: Value for Request Type attribute
* @num_req_dev_types: Number of requested device types
* @req_dev_types: Requested device types (8 * num_req_dev_types octets) or
* %NULL if none
* Returns: WPS IE or %NULL on failure
*
* The caller is responsible for freeing the buffer.
*/
typedef void * (*esp_wps_build_probe_req_ie_t)(uint16_t pw_id, void *dev, const unsigned char *uuid,
int req_type, unsigned int num_req_dev_types, const unsigned char *req_dev_types);
/**
* @brief build public key for exchange in M1
*
*
*/
typedef int (*esp_wps_build_public_key_t)(void *wps, void *msg, int mode);
/**
* @brief get the wps information in exchange password
*
*
*/
typedef void * (*esp_wps_enrollee_get_msg_t)(void *wps, void *op_code);
/**
* @brief deal with the wps information in exchange password
*
*
*/
typedef int (*esp_wps_enrollee_process_msg_t)(void *wps, int op_code, const void *msg);
/**
* @brief Generate a random PIN
*
* Returns: Eight digit PIN (i.e., including the checksum digit)
*/
typedef unsigned int (*esp_wps_generate_pin_t)(void);
/**
* @brief Check whether WPS IE indicates active PIN
*
* @msg: WPS IE contents from Beacon or Probe Response frame
* Returns: 1 if PIN Registrar is active, 0 if not
*/
typedef int (*esp_wps_is_selected_pin_registrar_t)(const void *msg, unsigned char *bssid);
/**
* @brief Check whether WPS IE indicates active PBC
*
* @msg: WPS IE contents from Beacon or Probe Response frame
* Returns: 1 if PBC Registrar is active, 0 if not
*/
typedef int (*esp_wps_is_selected_pbc_registrar_t)(const void *msg, unsigned char *bssid);
/**
* @brief The crypto callback function structure used when do station security connect.
* The structure can be set as software crypto or the crypto optimized by ESP32
* hardware.
*/
typedef struct {
uint32_t size;
uint32_t version;
esp_aes_wrap_t aes_wrap; /**< station connect function used when send EAPOL frame */
esp_aes_unwrap_t aes_unwrap; /**< station connect function used when decrypt key data */
esp_hmac_sha256_vector_t hmac_sha256_vector; /**< station connect function used when check MIC */
esp_sha256_prf_t sha256_prf; /**< station connect function used when check MIC */
esp_hmac_md5_t hmac_md5;
esp_hmac_md5_vector_t hamc_md5_vector;
esp_hmac_sha1_t hmac_sha1;
esp_hmac_sha1_vector_t hmac_sha1_vector;
esp_sha1_prf_t sha1_prf;
esp_sha1_vector_t sha1_vector;
esp_pbkdf2_sha1_t pbkdf2_sha1;
esp_rc4_skip_t rc4_skip;
esp_md5_vector_t md5_vector;
esp_aes_encrypt_t aes_encrypt;
esp_aes_encrypt_init_t aes_encrypt_init;
esp_aes_encrypt_deinit_t aes_encrypt_deinit;
esp_aes_decrypt_t aes_decrypt;
esp_aes_decrypt_init_t aes_decrypt_init;
esp_aes_decrypt_deinit_t aes_decrypt_deinit;
}wpa_crypto_funcs_t;
/**
* @brief The crypto callback function structure used when do WPS process. The
* structure can be set as software crypto or the crypto optimized by ESP32
* hardware.
*/
typedef struct{
uint32_t size;
uint32_t version;
esp_aes_128_encrypt_t aes_128_encrypt; /**< function used to process message when do WPS */
esp_aes_128_decrypt_t aes_128_decrypt; /**< function used to process message when do WPS */
esp_crypto_mod_exp_t crypto_mod_exp; /**< function used to calculate public key and private key */
esp_hmac_sha256_t hmac_sha256; /**< function used to get attribute */
esp_hmac_sha256_vector_t hmac_sha256_vector; /**< function used to process message when do WPS */
esp_sha256_vector_t sha256_vector; /**< function used to process message when do WPS */
esp_uuid_gen_mac_addr_t uuid_gen_mac_addr;
esp_dh5_free_t dh5_free;
esp_wps_build_assoc_req_ie_t wps_build_assoc_req_ie;
esp_wps_build_assoc_resp_ie_t wps_build_assoc_resp_ie;
esp_wps_build_probe_req_ie_t wps_build_probe_req_ie;
esp_wps_build_public_key_t wps_build_public_key;
esp_wps_enrollee_get_msg_t wps_enrollee_get_msg;
esp_wps_enrollee_process_msg_t wps_enrollee_process_msg;
esp_wps_generate_pin_t wps_generate_pin;
esp_wps_is_selected_pin_registrar_t wps_is_selected_pin_registrar;
esp_wps_is_selected_pbc_registrar_t wps_is_selected_pbc_registrar;
esp_eap_msg_alloc_t eap_msg_alloc;
}wps_crypto_funcs_t;
/**
* @brief The crypto callback function structure used when do WPA enterprise connect.
* The structure can be set as software crypto or the crypto optimized by ESP32
* hardware.
*/
typedef struct {
uint32_t size;
uint32_t version;
esp_crypto_hash_init_t crypto_hash_init; /**< function used to initialize a crypto_hash structure when use TLSV1 */
esp_crypto_hash_update_t crypto_hash_update; /**< function used to calculate hash data when use TLSV1 */
esp_crypto_hash_finish_t crypto_hash_finish; /**< function used to finish the hash calculate when use TLSV1 */
esp_crypto_cipher_init_t crypto_cipher_init; /**< function used to initialize a crypt_cipher structure when use TLSV1 */
esp_crypto_cipher_encrypt_t crypto_cipher_encrypt; /**< function used to encrypt cipher when use TLSV1 */
esp_crypto_cipher_decrypt_t crypto_cipher_decrypt; /**< function used to decrypt cipher when use TLSV1 */
esp_crypto_cipher_deinit_t crypto_cipher_deinit; /**< function used to free context when use TLSV1 */
esp_crypto_mod_exp_t crypto_mod_exp; /**< function used to do key exchange when use TLSV1 */
esp_sha256_vector_t sha256_vector; /**< function used to do X.509v3 certificate parsing and processing */
esp_tls_init_t tls_init;
esp_tls_deinit_t tls_deinit;
esp_eap_peer_blob_init_t eap_peer_blob_init;
esp_eap_peer_blob_deinit_t eap_peer_blob_deinit;
esp_eap_peer_config_init_t eap_peer_config_init;
esp_eap_peer_config_deinit_t eap_peer_config_deinit;
esp_eap_peer_register_methods_t eap_peer_register_methods;
esp_eap_peer_unregister_methods_t eap_peer_unregister_methods;
esp_eap_deinit_prev_method_t eap_deinit_prev_method;
esp_eap_peer_get_eap_method_t eap_peer_get_eap_method;
esp_eap_sm_abort_t eap_sm_abort;
esp_eap_sm_build_nak_t eap_sm_build_nak;
esp_eap_sm_build_identity_resp_t eap_sm_build_identity_resp;
esp_eap_msg_alloc_t eap_msg_alloc;
} wpa2_crypto_funcs_t;
/**
* @brief The crypto callback function structure used in mesh vendor IE encryption. The
* structure can be set as software crypto or the crypto optimized by ESP32
* hardware.
*/
typedef struct{
esp_aes_128_encrypt_t aes_128_encrypt; /**< function used in mesh vendor IE encryption */
esp_aes_128_decrypt_t aes_128_decrypt; /**< function used in mesh vendor IE decryption */
} mesh_crypto_funcs_t;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -18,6 +18,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "esp_err.h" #include "esp_err.h"
#include "esp_wifi_crypto_types.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -53,6 +54,8 @@ typedef enum wps_type {
WPS_TYPE_MAX, WPS_TYPE_MAX,
} wps_type_t; } wps_type_t;
extern const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs;
#define WPS_MAX_MANUFACTURER_LEN 65 #define WPS_MAX_MANUFACTURER_LEN 65
#define WPS_MAX_MODEL_NUMBER_LEN 33 #define WPS_MAX_MODEL_NUMBER_LEN 33
#define WPS_MAX_MODEL_NAME_LEN 33 #define WPS_MAX_MODEL_NAME_LEN 33
@ -67,11 +70,13 @@ typedef struct {
typedef struct { typedef struct {
wps_type_t wps_type; wps_type_t wps_type;
const wps_crypto_funcs_t *crypto_funcs;
wps_factory_information_t factory_info; wps_factory_information_t factory_info;
} esp_wps_config_t; } esp_wps_config_t;
#define WPS_CONFIG_INIT_DEFAULT(type) { \ #define WPS_CONFIG_INIT_DEFAULT(type) { \
.wps_type = type, \ .wps_type = type, \
.crypto_funcs = &g_wifi_default_wps_crypto_funcs, \
.factory_info = { \ .factory_info = { \
.manufacturer = "ESPRESSIF", \ .manufacturer = "ESPRESSIF", \
.model_number = "ESP8266", \ .model_number = "ESP8266", \

View File

@ -0,0 +1,129 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "crypto/common.h"
#include "crypto/aes_wrap.h"
#include "crypto/sha256.h"
#include "crypto/crypto.h"
#include "crypto/md5.h"
#include "crypto/sha1.h"
#include "crypto/aes.h"
#include "crypto/dh_group5.h"
#include "wps/wps.h"
#include "wps/wps_i.h"
#include "eap/eap_defs.h"
#include "eap/eap_common.h"
#if 0
#include "wpa2/eap_peer/eap.h"
#include "wpa2/tls/tls.h"
#include "wpa2/eap_peer/eap_methods.h"
#include "wpa2/eap_peer/eap_i.h"
#include "wpa2/eap_peer/eap_common.h"
#endif
#include "esp_wifi_crypto_types.h"
/*
* The parameters is used to set the cyrpto callback function for station connect when in security mode,
* every callback function can register as fast_xxx or normal one, i.e, fast_aes_wrap or aes_wrap, the
* difference between them is the normal API is calculate by software, the fast one use the hardware
* crypto in it, can be faster than the normal one, so the callback function register in default is which
* we recommend, so as the API in WPS default and WPA2 default.
*/
const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = {
.size = sizeof(wpa_crypto_funcs_t),
.version = ESP_WIFI_CRYPTO_VERSION,
.aes_wrap = (esp_aes_wrap_t)fast_aes_wrap,
.aes_unwrap = (esp_aes_unwrap_t)fast_aes_unwrap,
.hmac_sha256_vector = (esp_hmac_sha256_vector_t)fast_hmac_sha256_vector,
.sha256_prf = (esp_sha256_prf_t)fast_sha256_prf,
.hmac_md5 = (esp_hmac_md5_t)hmac_md5,
.hamc_md5_vector = (esp_hmac_md5_vector_t)hmac_md5_vector,
.hmac_sha1 = (esp_hmac_sha1_t)hmac_sha1,
.hmac_sha1_vector = (esp_hmac_sha1_vector_t)hmac_sha1_vector,
.sha1_prf = (esp_sha1_prf_t)sha1_prf,
.sha1_vector = (esp_sha1_vector_t)sha1_vector,
.pbkdf2_sha1 = (esp_pbkdf2_sha1_t)pbkdf2_sha1,
.rc4_skip = (esp_rc4_skip_t)rc4_skip,
.md5_vector = (esp_md5_vector_t)md5_vector,
.aes_encrypt = (esp_aes_encrypt_t)aes_encrypt,
.aes_encrypt_init = (esp_aes_encrypt_init_t)aes_encrypt_init,
.aes_encrypt_deinit = (esp_aes_encrypt_deinit_t)aes_encrypt_deinit,
.aes_decrypt = (esp_aes_decrypt_t)aes_decrypt,
.aes_decrypt_init = (esp_aes_decrypt_init_t)aes_decrypt_init,
.aes_decrypt_deinit = (esp_aes_decrypt_deinit_t)aes_decrypt_deinit
};
const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs = {
.size = sizeof(wps_crypto_funcs_t),
.version = ESP_WIFI_CRYPTO_VERSION,
.aes_128_encrypt = (esp_aes_128_encrypt_t)fast_aes_128_cbc_encrypt,
.aes_128_decrypt = (esp_aes_128_decrypt_t)fast_aes_128_cbc_decrypt,
.crypto_mod_exp = (esp_crypto_mod_exp_t)fast_crypto_mod_exp,
.hmac_sha256 = (esp_hmac_sha256_t)fast_hmac_sha256,
.hmac_sha256_vector = (esp_hmac_sha256_vector_t)fast_hmac_sha256_vector,
.sha256_vector = (esp_sha256_vector_t)fast_sha256_vector,
.uuid_gen_mac_addr = (esp_uuid_gen_mac_addr_t)uuid_gen_mac_addr,
.dh5_free = (esp_dh5_free_t)dh5_free,
.wps_build_assoc_req_ie = (esp_wps_build_assoc_req_ie_t)wps_build_assoc_req_ie,
.wps_build_assoc_resp_ie = (esp_wps_build_assoc_resp_ie_t)wps_build_assoc_resp_ie,
.wps_build_probe_req_ie = (esp_wps_build_probe_req_ie_t)wps_build_probe_req_ie,
.wps_build_public_key = (esp_wps_build_public_key_t)wps_build_public_key,
.wps_enrollee_get_msg = (esp_wps_enrollee_get_msg_t)wps_enrollee_get_msg,
.wps_enrollee_process_msg = (esp_wps_enrollee_process_msg_t)wps_enrollee_process_msg,
.wps_generate_pin = (esp_wps_generate_pin_t)wps_generate_pin,
.wps_is_selected_pin_registrar = (esp_wps_is_selected_pin_registrar_t)wps_is_selected_pin_registrar,
.wps_is_selected_pbc_registrar = (esp_wps_is_selected_pbc_registrar_t)wps_is_selected_pbc_registrar,
.eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc
};
/*
* What should notice is that the cyrpto hash type function and crypto cipher type function can not register
* as different, i.e, if you use fast_crypto_hash_init, you should use fast_crypto_hash_update and
* fast_crypto_hash_finish for finish hash calculate, rather than call crypto_hash_update and
* crypto_hash_finish, so do crypto_cipher.
*/
#if 0
const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs = {
.size = sizeof(wpa2_crypto_funcs_t),
.version = ESP_WIFI_CRYPTO_VERSION,
.crypto_hash_init = (esp_crypto_hash_init_t)fast_crypto_hash_init,
.crypto_hash_update = (esp_crypto_hash_update_t)fast_crypto_hash_update,
.crypto_hash_finish = (esp_crypto_hash_finish_t)fast_crypto_hash_finish,
.crypto_cipher_init = (esp_crypto_cipher_init_t)fast_crypto_cipher_init,
.crypto_cipher_encrypt = (esp_crypto_cipher_encrypt_t)fast_crypto_cipher_encrypt,
.crypto_cipher_decrypt = (esp_crypto_cipher_decrypt_t)fast_crypto_cipher_decrypt,
.crypto_cipher_deinit = (esp_crypto_cipher_deinit_t)fast_crypto_cipher_deinit,
.crypto_mod_exp = (esp_crypto_mod_exp_t)crypto_mod_exp,
.sha256_vector = (esp_sha256_vector_t)fast_sha256_vector,
.tls_init = (esp_tls_init_t)tls_init,
.tls_deinit = (esp_tls_deinit_t)tls_deinit,
.eap_peer_blob_init = (esp_eap_peer_blob_init_t)eap_peer_blob_init,
.eap_peer_blob_deinit = (esp_eap_peer_blob_deinit_t)eap_peer_blob_deinit,
.eap_peer_config_init = (esp_eap_peer_config_init_t)eap_peer_config_init,
.eap_peer_config_deinit = (esp_eap_peer_config_deinit_t)eap_peer_config_deinit,
.eap_peer_register_methods = (esp_eap_peer_register_methods_t)eap_peer_register_methods,
.eap_peer_unregister_methods = (esp_eap_peer_unregister_methods_t)eap_peer_unregister_methods,
.eap_deinit_prev_method = (esp_eap_deinit_prev_method_t)eap_deinit_prev_method,
.eap_peer_get_eap_method = (esp_eap_peer_get_eap_method_t)eap_peer_get_eap_method,
.eap_sm_abort = (esp_eap_sm_abort_t)eap_sm_abort,
.eap_sm_build_nak = (esp_eap_sm_build_nak_t)eap_sm_build_nak,
.eap_sm_build_identity_resp = (esp_eap_sm_build_identity_resp_t)eap_sm_build_identity_resp,
.eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc
};
const mesh_crypto_funcs_t g_wifi_default_mesh_crypto_funcs = {
.aes_128_encrypt = (esp_aes_128_encrypt_t)fast_aes_128_cbc_encrypt,
.aes_128_decrypt = (esp_aes_128_decrypt_t)fast_aes_128_cbc_decrypt,
};
#endif

View File

@ -1,4 +1,4 @@
COMPONENT_ADD_INCLUDEDIRS := include port/include COMPONENT_ADD_INCLUDEDIRS := include include/wps port/include
COMPONENT_SRCDIRS := src/crypto src/wps port COMPONENT_SRCDIRS := src/crypto src/wps src/fast_crypto port
CFLAGS += -DEMBEDDED_SUPP -D__ets__ -DESPRESSIF_USE -DCONFIG_WPS2 -DCONFIG_WPS_PIN -DUSE_WPS_TASK -Wno-unused-but-set-variable -Wno-empty-body CFLAGS += -DEMBEDDED_SUPP -D__ets__ -DESPRESSIF_USE -DCONFIG_WPS2 -DCONFIG_WPS_PIN -DUSE_WPS_TASK -DESP8266_WORKAROUND -Wno-unused-but-set-variable -Wno-empty-body

View File

@ -44,5 +44,11 @@ int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
size_t data_len); size_t data_len);
int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
size_t data_len); size_t data_len);
int __must_check fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher);
int __must_check fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain);
int __must_check fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data,
size_t data_len);
int __must_check fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data,
size_t data_len);
#endif /* AES_WRAP_H */ #endif /* AES_WRAP_H */

View File

@ -102,6 +102,17 @@ int __must_check fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x,
int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
u8 *mac); u8 *mac);
/**
* fast_sha256_vector - fast SHA256 hash for data vector
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash
* Returns: 0 on success, -1 on failure
*/
int fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len,
uint8_t *mac);
/** /**
* des_encrypt - Encrypt one block with DES * des_encrypt - Encrypt one block with DES
* @clear: 8 octets (in) * @clear: 8 octets (in)
@ -453,6 +464,31 @@ int __must_check crypto_mod_exp(const u8 *base, size_t base_len,
const u8 *modulus, size_t modulus_len, const u8 *modulus, size_t modulus_len,
u8 *result, size_t *result_len); u8 *result, size_t *result_len);
/**
* fast_crypto_mod_exp - Modular exponentiation of large integers
* @base: Base integer (big endian byte array)
* @base_len: Length of base integer in bytes
* @power: Power integer (big endian byte array)
* @power_len: Length of power integer in bytes
* @modulus: Modulus integer (big endian byte array)
* @modulus_len: Length of modulus integer in bytes
* @result: Buffer for the result
* @result_len: Result length (max buffer size on input, real len on output)
* Returns: 0 on success, -1 on failure
*
* This function calculates result = base ^ power mod modulus. modules_len is
* used as the maximum size of modulus buffer. It is set to the used size on
* success.
*
* This function is only used with internal TLSv1 implementation
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
* to implement this.
*/
int __must_check fast_crypto_mod_exp(const uint8_t *base, size_t base_len,
const uint8_t *power, size_t power_len,
const uint8_t *modulus, size_t modulus_len,
uint8_t *result, size_t *result_len);
/** /**
* rc4_skip - XOR RC4 stream to given data with skip-stream-start * rc4_skip - XOR RC4 stream to given data with skip-stream-start
* @key: RC4 key * @key: RC4 key

View File

@ -15,6 +15,7 @@
#ifndef SHA1_I_H #ifndef SHA1_I_H
#define SHA1_I_H #define SHA1_I_H
#if 0
#include "sdkconfig.h" #include "sdkconfig.h"
#ifdef CONFIG_ESP_SHA #ifdef CONFIG_ESP_SHA
@ -37,5 +38,15 @@ void SHA1Update(struct SHA1Context *context, const void *data, u32 len);
void SHA1Final(unsigned char digest[20], struct SHA1Context *context); void SHA1Final(unsigned char digest[20], struct SHA1Context *context);
void SHA1Transform(u32 state[5], const unsigned char buffer[64]); void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
#endif /* CONFIG_ESP_SHA */ #endif /* CONFIG_ESP_SHA */
#endif
struct SHA1Context {
u32 state[5];
u32 count[2];
unsigned char buffer[64];
};
void SHA1Init(struct SHA1Context *context);
void SHA1Update(struct SHA1Context *context, const void *data, u32 len);
void SHA1Final(unsigned char digest[20], struct SHA1Context *context);
void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
#endif /* SHA1_I_H */ #endif /* SHA1_I_H */

View File

@ -23,5 +23,11 @@ void hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
size_t data_len, u8 *mac); size_t data_len, u8 *mac);
void sha256_prf(const u8 *key, size_t key_len, const char *label, void sha256_prf(const u8 *key, size_t key_len, const char *label,
const u8 *data, size_t data_len, u8 *buf, size_t buf_len); const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
void fast_hmac_sha256_vector(const uint8_t *key, size_t key_len, size_t num_elem,
const uint8_t *addr[], const size_t *len, uint8_t *mac);
void fast_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data,
size_t data_len, uint8_t *mac);
void fast_sha256_prf(const uint8_t *key, size_t key_len, const char *label,
const uint8_t *data, size_t data_len, uint8_t *buf, size_t buf_len);
#endif /* SHA256_H */ #endif /* SHA256_H */

View File

@ -232,9 +232,7 @@ enum wps_process_res wps_process_msg(struct wps_data *wps,
struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code); struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code);
int wps_is_selected_pbc_registrar(const struct wpabuf *msg, uint8_t *bssid); int wps_is_selected_pbc_registrar(const struct wpabuf *msg, uint8_t *bssid);
#ifdef CONFIG_WPS_PIN
int wps_is_selected_pin_registrar(const struct wpabuf *msg, uint8_t *bssid); int wps_is_selected_pin_registrar(const struct wpabuf *msg, uint8_t *bssid);
#endif
int wps_ap_priority_compar(const struct wpabuf *wps_a, int wps_ap_priority_compar(const struct wpabuf *wps_a,
const struct wpabuf *wps_b); const struct wpabuf *wps_b);
int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr, int wps_is_addr_authorized(const struct wpabuf *msg, const u8 *addr,
@ -802,9 +800,9 @@ int wps_build_credential_wrap(struct wpabuf *msg,
unsigned int wps_pin_checksum(unsigned int pin); unsigned int wps_pin_checksum(unsigned int pin);
unsigned int wps_pin_valid(unsigned int pin); unsigned int wps_pin_valid(unsigned int pin);
unsigned int wps_generate_pin(void);
int wps_pin_str_valid(const char *pin); int wps_pin_str_valid(const char *pin);
#endif #endif
unsigned int wps_generate_pin(void);
#ifdef CONFIG_WPS_OOB #ifdef CONFIG_WPS_OOB

View File

@ -11,6 +11,7 @@
#include "wps/wps.h" #include "wps/wps.h"
#include "wps/wps_attr_parse.h" #include "wps/wps_attr_parse.h"
#include "esp_wifi_crypto_types.h"
#ifdef CONFIG_WPS_NFC #ifdef CONFIG_WPS_NFC
struct wps_nfc_pw_token; struct wps_nfc_pw_token;
@ -149,9 +150,11 @@ typedef struct {
typedef struct { typedef struct {
WPS_TYPE_t wps_type; WPS_TYPE_t wps_type;
const wps_crypto_funcs_t *crypto_funcs;
esp_factory_information_t factory_info; esp_factory_information_t factory_info;
}esp_wps_config_t; }esp_wps_config_t;
wps_crypto_funcs_t wps_crypto_funcs;
/* wps_common.c */ /* wps_common.c */
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len, void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,

View File

@ -20,12 +20,12 @@
#include "crypto/md5.h" #include "crypto/md5.h"
#include "crypto/crypto.h" #include "crypto/crypto.h"
#ifndef CONFIG_ESP_SHA //#ifndef CONFIG_ESP_SHA
typedef struct SHA1Context SHA1_CTX; typedef struct SHA1Context SHA1_CTX;
void SHA1Transform(u32 state[5], const unsigned char buffer[64]); void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
#endif //#endif
/** /**
* sha1_vector - SHA-1 hash for data vector * sha1_vector - SHA-1 hash for data vector
@ -49,7 +49,7 @@ sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
} }
#ifndef CONFIG_ESP_SHA #if 1//ndef CONFIG_ESP_SHA
/* ===== start - public domain SHA1 implementation ===== */ /* ===== start - public domain SHA1 implementation ===== */
/* /*

View File

@ -0,0 +1,78 @@
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
#include "crypto/includes.h"
#include "crypto/common.h"
#include "crypto/aes.h"
#include "crypto/aes_wrap.h"
#include "mbedtls/aes.h"
/**
* fast_aes_128_cbc_encrypt - AES-128 CBC encryption
* @key: Encryption key
* @iv: Encryption IV for CBC mode (16 bytes)
* @data: Data to encrypt in-place
* @data_len: Length of data in bytes (must be divisible by 16)
* Returns: 0 on success, -1 on failure
*/
int
fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len)
{
int ret = 0;
mbedtls_aes_context ctx;
uint8_t cbc[AES_BLOCK_SIZE];
mbedtls_aes_init(&ctx);
ret = mbedtls_aes_setkey_enc(&ctx, key, 128);
if(ret < 0) {
mbedtls_aes_free(&ctx);
return ret;
}
os_memcpy(cbc, iv, AES_BLOCK_SIZE);
ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, data_len, cbc, data, data);
mbedtls_aes_free(&ctx);
return ret;
}
/**
* fast_aes_128_cbc_decrypt - AES-128 CBC decryption
* @key: Decryption key
* @iv: Decryption IV for CBC mode (16 bytes)
* @data: Data to decrypt in-place
* @data_len: Length of data in bytes (must be divisible by 16)
* Returns: 0 on success, -1 on failure
*/
int
fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len)
{
int ret = 0;
mbedtls_aes_context ctx;
uint8_t cbc[AES_BLOCK_SIZE];
mbedtls_aes_init(&ctx);
ret = mbedtls_aes_setkey_dec(&ctx, key, 128);
if(ret < 0) {
mbedtls_aes_free(&ctx);
return ret;
}
os_memcpy(cbc, iv, AES_BLOCK_SIZE);
ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, data_len, cbc, data, data);
mbedtls_aes_free(&ctx);
return ret;
}

View File

@ -0,0 +1,84 @@
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "crypto/includes.h"
#include "crypto/common.h"
#include "mbedtls/aes.h"
/**
* fast_aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
* @kek: Key encryption key (KEK)
* @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
* bytes
* @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
* @plain: Plaintext key, n * 64 bits
* Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
*/
int
fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain)
{
uint8_t a[8], *r, b[16];
int32_t i, j;
int32_t ret = 0;
mbedtls_aes_context ctx;
/* 1) Initialize variables. */
os_memcpy(a, cipher, 8);
r = plain;
os_memcpy(r, cipher + 8, 8 * n);
mbedtls_aes_init(&ctx);
ret = mbedtls_aes_setkey_dec(&ctx, kek, 128);
if (ret < 0) {
mbedtls_aes_free(&ctx);
return ret;
}
/* 2) Compute intermediate values.
* For j = 5 to 0
* For i = n to 1
* B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
* A = MSB(64, B)
* R[i] = LSB(64, B)
*/
for (j = 5; j >= 0; j--) {
r = plain + (n - 1) * 8;
for (i = n; i >= 1; i--) {
os_memcpy(b, a, 8);
b[7] ^= n * j + i;
os_memcpy(b + 8, r, 8);
ret = mbedtls_internal_aes_decrypt(&ctx, b, b);
if (ret != 0) {
break;
}
os_memcpy(a, b, 8);
os_memcpy(r, b + 8, 8);
r -= 8;
}
}
mbedtls_aes_free(&ctx);
/* 3) Output results.
*
* These are already in @plain due to the location of temporary
* variables. Just verify that the IV matches with the expected value.
*/
for (i = 0; i < 8; i++) {
if (a[i] != 0xa6) {
return -1;
}
}
return ret;
}

View File

@ -0,0 +1,83 @@
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "crypto/includes.h"
#include "crypto/common.h"
#include "crypto/aes.h"
#include "crypto/aes_wrap.h"
#include "mbedtls/aes.h"
/**
* fast_aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
* @kek: 16-octet Key encryption key (KEK)
* @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
* bytes
* @plain: Plaintext key to be wrapped, n * 64 bits
* @cipher: Wrapped key, (n + 1) * 64 bits
* Returns: 0 on success, -1 on failure
*/
int fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher)
{
uint8_t *a, *r, b[16];
int32_t i, j;
int32_t ret = 0;
mbedtls_aes_context ctx;
a = cipher;
r = cipher + 8;
/* 1) Initialize variables. */
os_memset(a, 0xa6, 8);
os_memcpy(r, plain, 8 * n);
mbedtls_aes_init(&ctx);
ret = mbedtls_aes_setkey_enc(&ctx, kek, 128);
if (ret < 0) {
mbedtls_aes_free(&ctx);
return ret;
}
/* 2) Calculate intermediate values.
* For j = 0 to 5
* For i=1 to n
* B = AES(K, A | R[i])
* A = MSB(64, B) ^ t where t = (n*j)+i
* R[i] = LSB(64, B)
*/
for (j = 0; j <= 5; j++) {
r = cipher + 8;
for (i = 1; i <= n; i++) {
os_memcpy(b, a, 8);
os_memcpy(b + 8, r, 8);
ret = mbedtls_internal_aes_encrypt(&ctx, b, b);
if (ret != 0) {
break;
}
os_memcpy(a, b, 8);
a[7] ^= n * j + i;
os_memcpy(r, b + 8, 8);
r += 8;
}
}
mbedtls_aes_free(&ctx);
/* 3) Output the results.
*
* These are already in @cipher due to the location of temporary
* variables.
*/
return ret;
}

View File

@ -0,0 +1,287 @@
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//#include "wpa/includes.h"
//#include "wpa/common.h"
#include "crypto/common.h"
#include "crypto/crypto.h"
#include "crypto/aes.h"
#if defined(CONFIG_DES) || defined(CONFIG_DES3)
#include "crypto/des_i.h"
#endif
#include "mbedtls/aes.h"
struct fast_crypto_cipher {
enum crypto_cipher_alg alg;
union {
struct {
size_t used_bytes;
uint8_t key[16];
size_t keylen;
} rc4;
struct {
uint8_t cbc[32];
mbedtls_aes_context ctx_enc;
mbedtls_aes_context ctx_dec;
} aes;
#ifdef CONFIG_DES3
struct {
struct des3_key_s key;
uint8_t cbc[8];
} des3;
#endif
#ifdef CONFIG_DES
struct {
uint32_t ek[32];
uint32_t dk[32];
uint32_t cbc[8];
} des;
#endif
} u;
};
struct crypto_cipher * fast_crypto_cipher_init(enum crypto_cipher_alg alg,
const uint8_t *iv, const uint8_t *key,
size_t key_len)
{
struct fast_crypto_cipher *ctx;
ctx = (struct fast_crypto_cipher *)os_zalloc(sizeof(*ctx));
if (ctx == NULL) {
return NULL;
}
ctx->alg = alg;
switch (alg) {
case CRYPTO_CIPHER_ALG_RC4:
if (key_len > sizeof(ctx->u.rc4.key)) {
os_free(ctx);
return NULL;
}
ctx->u.rc4.keylen = key_len;
os_memcpy(ctx->u.rc4.key, key, key_len);
break;
case CRYPTO_CIPHER_ALG_AES:
mbedtls_aes_init(&(ctx->u.aes.ctx_enc));
mbedtls_aes_setkey_enc(&(ctx->u.aes.ctx_enc), key, key_len * 8);
mbedtls_aes_init(&(ctx->u.aes.ctx_dec));
mbedtls_aes_setkey_dec(&(ctx->u.aes.ctx_dec), key, key_len * 8);
os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE);
break;
#ifdef CONFIG_DES3
case CRYPTO_CIPHER_ALG_3DES:
if (key_len != 24) {
os_free(ctx);
return NULL;
}
des3_key_setup(key, &ctx->u.des3.key);
os_memcpy(ctx->u.des3.cbc, iv, 8);
break;
#endif
#ifdef CONFIG_DES
case CRYPTO_CIPHER_ALG_DES:
if (key_len != 8) {
os_free(ctx);
return NULL;
}
des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
os_memcpy(ctx->u.des.cbc, iv, 8);
break;
#endif
default:
os_free(ctx);
return NULL;
}
return (struct crypto_cipher *)ctx;
}
int fast_crypto_cipher_encrypt(struct crypto_cipher *ctx, const uint8_t *plain,
uint8_t *crypt, size_t len)
{
size_t i, j, blocks;
struct fast_crypto_cipher *fast_ctx;
fast_ctx = (struct fast_crypto_cipher *)ctx;
switch (fast_ctx->alg) {
case CRYPTO_CIPHER_ALG_RC4:
if (plain != crypt) {
os_memcpy(crypt, plain, len);
}
rc4_skip(fast_ctx->u.rc4.key, fast_ctx->u.rc4.keylen,
fast_ctx->u.rc4.used_bytes, crypt, len);
fast_ctx->u.rc4.used_bytes += len;
break;
case CRYPTO_CIPHER_ALG_AES:
if (len % AES_BLOCK_SIZE) {
return -1;
}
blocks = len / AES_BLOCK_SIZE;
for (i = 0; i < blocks; i++) {
for (j = 0; j < AES_BLOCK_SIZE; j++)
fast_ctx->u.aes.cbc[j] ^= plain[j];
if (mbedtls_internal_aes_encrypt(&(fast_ctx->u.aes.ctx_enc), fast_ctx->u.aes.cbc, fast_ctx->u.aes.cbc) != 0) {
return -1;
}
os_memcpy(crypt, fast_ctx->u.aes.cbc, AES_BLOCK_SIZE);
plain += AES_BLOCK_SIZE;
crypt += AES_BLOCK_SIZE;
}
break;
#ifdef CONFIG_DES3
case CRYPTO_CIPHER_ALG_3DES:
if (len % 8) {
return -1;
}
blocks = len / 8;
for (i = 0; i < blocks; i++) {
for (j = 0; j < 8; j++)
fast_ctx->u.des3.cbc[j] ^= plain[j];
des3_encrypt(fast_ctx->u.des3.cbc, &fast_ctx->u.des3.key,
fast_ctx->u.des3.cbc);
os_memcpy(crypt, fast_ctx->u.des3.cbc, 8);
plain += 8;
crypt += 8;
}
break;
#endif
#ifdef CONFIG_DES
case CRYPTO_CIPHER_ALG_DES:
if (len % 8) {
return -1;
}
blocks = len / 8;
for (i = 0; i < blocks; i++) {
for (j = 0; j < 8; j++)
fast_ctx->u.des3.cbc[j] ^= plain[j];
des_block_encrypt(fast_ctx->u.des.cbc, fast_ctx->u.des.ek,
fast_ctx->u.des.cbc);
os_memcpy(crypt, fast_ctx->u.des.cbc, 8);
plain += 8;
crypt += 8;
}
break;
#endif
default:
return -1;
}
return 0;
}
int fast_crypto_cipher_decrypt(struct crypto_cipher *ctx, const uint8_t *crypt,
uint8_t *plain, size_t len)
{
size_t i, j, blocks;
uint8_t tmp[32];
struct fast_crypto_cipher *fast_ctx;
fast_ctx = (struct fast_crypto_cipher *)ctx;
switch (fast_ctx->alg) {
case CRYPTO_CIPHER_ALG_RC4:
if (plain != crypt) {
os_memcpy(plain, crypt, len);
}
rc4_skip(fast_ctx->u.rc4.key, fast_ctx->u.rc4.keylen,
fast_ctx->u.rc4.used_bytes, plain, len);
fast_ctx->u.rc4.used_bytes += len;
break;
case CRYPTO_CIPHER_ALG_AES:
if (len % AES_BLOCK_SIZE) {
return -1;
}
blocks = len / AES_BLOCK_SIZE;
for (i = 0; i < blocks; i++) {
os_memcpy(tmp, crypt, AES_BLOCK_SIZE);
if (mbedtls_internal_aes_decrypt(&(fast_ctx->u.aes.ctx_dec), crypt, plain) != 0) {
return -1;
}
for (j = 0; j < AES_BLOCK_SIZE; j++)
plain[j] ^= fast_ctx->u.aes.cbc[j];
os_memcpy(fast_ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE);
plain += AES_BLOCK_SIZE;
crypt += AES_BLOCK_SIZE;
}
break;
#ifdef CONFIG_DES3
case CRYPTO_CIPHER_ALG_3DES:
if (len % 8) {
return -1;
}
blocks = len / 8;
for (i = 0; i < blocks; i++) {
os_memcpy(tmp, crypt, 8);
des3_decrypt(crypt, &fast_ctx->u.des3.key, plain);
for (j = 0; j < 8; j++) {
plain[j] ^= fast_ctx->u.des3.cbc[j];
}
os_memcpy(fast_ctx->u.des3.cbc, tmp, 8);
plain += 8;
crypt += 8;
}
break;
#endif
#ifdef CONFIG_DES
case CRYPTO_CIPHER_ALG_DES:
if (len % 8) {
return -1;
}
blocks = len / 8;
for (i = 0; i < blocks; i++) {
os_memcpy(tmp, crypt, 8);
des_block_decrypt(crypt, fast_ctx->u.des.dk, plain);
for (j = 0; j < 8; j++) {
plain[j] ^= fast_ctx->u.des.cbc[j];
}
os_memcpy(fast_ctx->u.des.cbc, tmp, 8);
plain += 8;
crypt += 8;
}
break;
#endif
default:
return -1;
}
return 0;
}
void fast_crypto_cipher_deinit(struct crypto_cipher *ctx)
{
struct fast_crypto_cipher *fast_ctx;
fast_ctx = (struct fast_crypto_cipher *)ctx;
switch (fast_ctx->alg) {
case CRYPTO_CIPHER_ALG_AES:
mbedtls_aes_free(&(fast_ctx->u.aes.ctx_enc));
mbedtls_aes_free(&(fast_ctx->u.aes.ctx_dec));
break;
#ifdef CONFIG_DES3
case CRYPTO_CIPHER_ALG_3DES:
break;
#endif
default:
break;
}
os_free(ctx);
}

View File

@ -0,0 +1,65 @@
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "crypto/includes.h"
#include "crypto/common.h"
#include "crypto/crypto.h"
#include "mbedtls/bignum.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
int
fast_crypto_mod_exp(const uint8_t *base, size_t base_len,
const uint8_t *power, size_t power_len,
const uint8_t *modulus, size_t modulus_len,
uint8_t *result, size_t *result_len)
{
mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result, bn_rinv;
int32_t ret = 0;
mbedtls_mpi_init(&bn_base);
mbedtls_mpi_init(&bn_exp);
mbedtls_mpi_init(&bn_modulus);
mbedtls_mpi_init(&bn_result);
mbedtls_mpi_init(&bn_rinv);
mbedtls_mpi_read_binary(&bn_base, base, base_len);
mbedtls_mpi_read_binary(&bn_exp, power, power_len);
mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len);
//printf("[%s]line:[%d]%d\r\n", __func__, __LINE__, xTaskGetTickCount());
ret = mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus, &bn_rinv);
//printf("[%s]line:[%d]%d\r\n", __func__, __LINE__, xTaskGetTickCount());
if (ret < 0) {
mbedtls_mpi_free(&bn_base);
mbedtls_mpi_free(&bn_exp);
mbedtls_mpi_free(&bn_modulus);
mbedtls_mpi_free(&bn_result);
mbedtls_mpi_free(&bn_rinv);
return ret;
}
ret = mbedtls_mpi_write_binary(&bn_result, result, *result_len);
mbedtls_mpi_free(&bn_base);
mbedtls_mpi_free(&bn_exp);
mbedtls_mpi_free(&bn_modulus);
mbedtls_mpi_free(&bn_result);
mbedtls_mpi_free(&bn_rinv);
return ret;
}

View File

@ -0,0 +1,282 @@
/*
* Crypto wrapper for internal crypto implementation
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
*
* Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "crypto/includes.h"
#include "crypto/common.h"
#include "crypto/crypto.h"
#include "crypto/sha1_i.h"
#include "crypto/md5_i.h"
#include "mbedtls/sha256.h"
#ifdef MEMLEAK_DEBUG
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
#endif
struct fast_crypto_hash {
enum crypto_hash_alg alg;
union {
struct MD5Context md5;
struct SHA1Context sha1;
#ifdef CONFIG_SHA256
mbedtls_sha256_context sha256;
#endif /* CONFIG_SHA256 */
} u;
u8 key[64];
size_t key_len;
};
struct crypto_hash * fast_crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
size_t key_len)
{
struct fast_crypto_hash *ctx;
u8 k_pad[64];
u8 tk[32];
size_t i;
ctx = (struct fast_crypto_hash *)os_zalloc(sizeof(*ctx));
if (ctx == NULL)
return NULL;
ctx->alg = alg;
switch (alg) {
case CRYPTO_HASH_ALG_MD5:
MD5Init(&ctx->u.md5);
break;
case CRYPTO_HASH_ALG_SHA1:
SHA1Init(&ctx->u.sha1);
break;
#ifdef CONFIG_SHA256
case CRYPTO_HASH_ALG_SHA256:
mbedtls_sha256_init(&ctx->u.sha256);
mbedtls_sha256_starts(&ctx->u.sha256, 0);
break;
#endif /* CONFIG_SHA256 */
case CRYPTO_HASH_ALG_HMAC_MD5:
if (key_len > sizeof(k_pad)) {
MD5Init(&ctx->u.md5);
MD5Update(&ctx->u.md5, key, key_len);
MD5Final(tk, &ctx->u.md5);
key = tk;
key_len = 16;
}
os_memcpy(ctx->key, key, key_len);
ctx->key_len = key_len;
os_memcpy(k_pad, key, key_len);
if (key_len < sizeof(k_pad))
os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
for (i = 0; i < sizeof(k_pad); i++)
k_pad[i] ^= 0x36;
MD5Init(&ctx->u.md5);
MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
break;
case CRYPTO_HASH_ALG_HMAC_SHA1:
if (key_len > sizeof(k_pad)) {
SHA1Init(&ctx->u.sha1);
SHA1Update(&ctx->u.sha1, key, key_len);
SHA1Final(tk, &ctx->u.sha1);
key = tk;
key_len = 20;
}
os_memcpy(ctx->key, key, key_len);
ctx->key_len = key_len;
os_memcpy(k_pad, key, key_len);
if (key_len < sizeof(k_pad))
os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
for (i = 0; i < sizeof(k_pad); i++)
k_pad[i] ^= 0x36;
SHA1Init(&ctx->u.sha1);
SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
break;
#ifdef CONFIG_SHA256
case CRYPTO_HASH_ALG_HMAC_SHA256:
if (key_len > sizeof(k_pad)) {
mbedtls_sha256_init(&ctx->u.sha256);
mbedtls_sha256_starts(&ctx->u.sha256, 0);
mbedtls_sha256_update(&ctx->u.sha256, key, key_len);
mbedtls_sha256_finish(&ctx->u.sha256, tk);
mbedtls_sha256_free(&ctx->u.sha256);
key = tk;
key_len = 32;
}
os_memcpy(ctx->key, key, key_len);
ctx->key_len = key_len;
os_memcpy(k_pad, key, key_len);
if (key_len < sizeof(k_pad))
os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
for (i = 0; i < sizeof(k_pad); i++)
k_pad[i] ^= 0x36;
mbedtls_sha256_init(&ctx->u.sha256);
mbedtls_sha256_starts(&ctx->u.sha256, 0);
mbedtls_sha256_update(&ctx->u.sha256, k_pad, sizeof(k_pad));
break;
#endif /* CONFIG_SHA256 */
default:
os_free(ctx);
return NULL;
}
return (struct crypto_hash *)ctx;
}
void fast_crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
{
struct fast_crypto_hash *fast_ctx;
fast_ctx = (struct fast_crypto_hash *)ctx;
if (fast_ctx == NULL)
return;
switch (fast_ctx->alg) {
case CRYPTO_HASH_ALG_MD5:
case CRYPTO_HASH_ALG_HMAC_MD5:
MD5Update(&fast_ctx->u.md5, data, len);
break;
case CRYPTO_HASH_ALG_SHA1:
case CRYPTO_HASH_ALG_HMAC_SHA1:
SHA1Update(&fast_ctx->u.sha1, data, len);
break;
#ifdef CONFIG_SHA256
case CRYPTO_HASH_ALG_SHA256:
case CRYPTO_HASH_ALG_HMAC_SHA256:
mbedtls_sha256_update(&fast_ctx->u.sha256, data, len);
break;
#endif /* CONFIG_SHA256 */
default:
break;
}
}
int fast_crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
{
u8 k_pad[64];
size_t i;
struct fast_crypto_hash *fast_ctx;
if (ctx == NULL)
return -2;
fast_ctx = (struct fast_crypto_hash *)ctx;
if (mac == NULL || len == NULL) {
os_free(fast_ctx);
return 0;
}
switch (fast_ctx->alg) {
case CRYPTO_HASH_ALG_MD5:
if (*len < 16) {
*len = 16;
os_free(fast_ctx);
return -1;
}
*len = 16;
MD5Final(mac, &fast_ctx->u.md5);
break;
case CRYPTO_HASH_ALG_SHA1:
if (*len < 20) {
*len = 20;
os_free(fast_ctx);
return -1;
}
*len = 20;
SHA1Final(mac, &fast_ctx->u.sha1);
break;
#ifdef CONFIG_SHA256
case CRYPTO_HASH_ALG_SHA256:
if (*len < 32) {
*len = 32;
os_free(fast_ctx);
return -1;
}
*len = 32;
mbedtls_sha256_finish(&fast_ctx->u.sha256, mac);
mbedtls_sha256_free(&fast_ctx->u.sha256);
break;
#endif /* CONFIG_SHA256 */
case CRYPTO_HASH_ALG_HMAC_MD5:
if (*len < 16) {
*len = 16;
os_free(fast_ctx);
return -1;
}
*len = 16;
MD5Final(mac, &fast_ctx->u.md5);
os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len);
os_memset(k_pad + fast_ctx->key_len, 0,
sizeof(k_pad) - fast_ctx->key_len);
for (i = 0; i < sizeof(k_pad); i++)
k_pad[i] ^= 0x5c;
MD5Init(&fast_ctx->u.md5);
MD5Update(&fast_ctx->u.md5, k_pad, sizeof(k_pad));
MD5Update(&fast_ctx->u.md5, mac, 16);
MD5Final(mac, &fast_ctx->u.md5);
break;
case CRYPTO_HASH_ALG_HMAC_SHA1:
if (*len < 20) {
*len = 20;
os_free(ctx);
return -1;
}
*len = 20;
SHA1Final(mac, &fast_ctx->u.sha1);
os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len);
os_memset(k_pad + fast_ctx->key_len, 0,
sizeof(k_pad) - fast_ctx->key_len);
for (i = 0; i < sizeof(k_pad); i++)
k_pad[i] ^= 0x5c;
SHA1Init(&fast_ctx->u.sha1);
SHA1Update(&fast_ctx->u.sha1, k_pad, sizeof(k_pad));
SHA1Update(&fast_ctx->u.sha1, mac, 20);
SHA1Final(mac, &fast_ctx->u.sha1);
break;
#ifdef CONFIG_SHA256
case CRYPTO_HASH_ALG_HMAC_SHA256:
if (*len < 32) {
*len = 32;
os_free(fast_ctx);
return -1;
}
*len = 32;
mbedtls_sha256_finish(&fast_ctx->u.sha256, mac);
mbedtls_sha256_free(&fast_ctx->u.sha256);
os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len);
os_memset(k_pad + fast_ctx->key_len, 0,
sizeof(k_pad) - fast_ctx->key_len);
for (i = 0; i < sizeof(k_pad); i++)
k_pad[i] ^= 0x5c;
mbedtls_sha256_init(&fast_ctx->u.sha256);
mbedtls_sha256_starts(&fast_ctx->u.sha256, 0);
mbedtls_sha256_update(&fast_ctx->u.sha256, k_pad, sizeof(k_pad));
mbedtls_sha256_update(&fast_ctx->u.sha256, mac, 32);
mbedtls_sha256_finish(&fast_ctx->u.sha256, mac);
mbedtls_sha256_free(&fast_ctx->u.sha256);
break;
#endif /* CONFIG_SHA256 */
default:
os_free(fast_ctx);
return -1;
}
os_free(fast_ctx);
return 0;
}

View File

@ -0,0 +1,58 @@
// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "crypto/includes.h"
#include "crypto/common.h"
#include "mbedtls/sha256.h"
/**
* fast_sha256_vector - SHA256 hash for data vector
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash
* Returns: 0 on success, -1 of failure
*/
int
fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len,
uint8_t *mac)
{
int ret = 0;
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) {
ret = -1;
goto out;
}
for(size_t index = 0; index < num_elem; index++) {
if (mbedtls_sha256_update_ret(&ctx, addr[index], len[index]) != 0) {
ret = -1;
goto out;
}
}
if (mbedtls_sha256_finish_ret(&ctx, mac) != 0) {
ret = -1;
goto out;
}
out:
mbedtls_sha256_free(&ctx);
return ret;
}

View File

@ -0,0 +1,165 @@
/*
* SHA-256 hash implementation and interface functions
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "crypto/includes.h"
#include "crypto/common.h"
#include "crypto/sha256.h"
#include "crypto/crypto.h"
/**
* fast_hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)
* @key: Key for HMAC operations
* @key_len: Length of the key in bytes
* @num_elem: Number of elements in the data vector
* @addr: Pointers to the data areas
* @len: Lengths of the data blocks
* @mac: Buffer for the hash (32 bytes)
*/
void
fast_hmac_sha256_vector(const uint8_t *key, size_t key_len, size_t num_elem,
const uint8_t *addr[], const size_t *len, uint8_t *mac)
{
uint8_t k_pad[64]; /* padding - key XORd with ipad/opad */
uint8_t tk[32];
const uint8_t *_addr[6];
size_t _len[6], i;
if (num_elem > 5) {
/*
* Fixed limit on the number of fragments to avoid having to
* allocate memory (which could fail).
*/
return;
}
/* if key is longer than 64 bytes reset it to key = SHA256(key) */
if (key_len > 64) {
fast_sha256_vector(1, &key, &key_len, tk);
key = tk;
key_len = 32;
}
/* the HMAC_SHA256 transform looks like:
*
* SHA256(K XOR opad, SHA256(K XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected
*/
/* start out by storing key in ipad */
os_memset(k_pad, 0, sizeof(k_pad));
os_memcpy(k_pad, key, key_len);
/* XOR key with ipad values */
for (i = 0; i < 64; i++) {
k_pad[i] ^= 0x36;
}
/* perform inner SHA256 */
_addr[0] = k_pad;
_len[0] = 64;
for (i = 0; i < num_elem; i++) {
_addr[i + 1] = addr[i];
_len[i + 1] = len[i];
}
fast_sha256_vector(1 + num_elem, _addr, _len, mac);
os_memset(k_pad, 0, sizeof(k_pad));
os_memcpy(k_pad, key, key_len);
/* XOR key with opad values */
for (i = 0; i < 64; i++) {
k_pad[i] ^= 0x5c;
}
/* perform outer SHA256 */
_addr[0] = k_pad;
_len[0] = 64;
_addr[1] = mac;
_len[1] = SHA256_MAC_LEN;
fast_sha256_vector(2, _addr, _len, mac);
}
/**
* fast_hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104)
* @key: Key for HMAC operations
* @key_len: Length of the key in bytes
* @data: Pointers to the data area
* @data_len: Length of the data area
* @mac: Buffer for the hash (20 bytes)
*/
void
fast_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data,
size_t data_len, uint8_t *mac)
{
fast_hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
}
/**
* fast_sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
* @key: Key for PRF
* @key_len: Length of the key in bytes
* @label: A unique label for each purpose of the PRF
* @data: Extra data to bind into the key
* @data_len: Length of the data
* @buf: Buffer for the generated pseudo-random key
* @buf_len: Number of bytes of key to generate
*
* This function is used to derive new, cryptographically separate keys from a
* given key.
*/
void
fast_sha256_prf(const uint8_t *key, size_t key_len, const char *label,
const uint8_t *data, size_t data_len, uint8_t *buf, size_t buf_len)
{
uint16_t counter = 1;
size_t pos, plen;
uint8_t hash[SHA256_MAC_LEN];
const uint8_t *addr[4];
size_t len[4];
uint8_t counter_le[2], length_le[2];
addr[0] = counter_le;
len[0] = 2;
addr[1] = (uint8_t *) label;
len[1] = os_strlen(label);
addr[2] = data;
len[2] = data_len;
addr[3] = length_le;
len[3] = sizeof(length_le);
WPA_PUT_LE16(length_le, buf_len * 8);
pos = 0;
while (pos < buf_len) {
plen = buf_len - pos;
WPA_PUT_LE16(counter_le, counter);
if (plen >= SHA256_MAC_LEN) {
fast_hmac_sha256_vector(key, key_len, 4, addr, len,
&buf[pos]);
pos += SHA256_MAC_LEN;
} else {
fast_hmac_sha256_vector(key, key_len, 4, addr, len, hash);
os_memcpy(&buf[pos], hash, plen);
break;
}
counter++;
}
}

View File

@ -5,7 +5,6 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/utils/uuid.h" #include "wps/utils/uuid.h"

View File

@ -5,19 +5,22 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wps/asm/irqflags.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wpa/wpa_debug.h" #include "wpa/wpa_debug.h"
#include "wpa/ieee802_11_defs.h"
#include "wps/wps_i.h"
#include "crypto/aes_wrap.h" #include "crypto/aes_wrap.h"
#include "crypto/crypto.h" #include "crypto/crypto.h"
#include "crypto/dh_group5.h" #include "crypto/dh_group5.h"
#include "crypto/sha256.h" #include "crypto/sha256.h"
#include "crypto/random.h" #include "crypto/random.h"
#include "esp_wifi_osi.h"
#include "wpa/ieee802_11_defs.h"
#include "wps/wps_i.h"
#ifdef CONFIG_IDF_TARGET_ESP8266
#include "wps/asm/irqflags.h"
#define API_MUTEX_DECLARE(t) local_irq_declare(t) #define API_MUTEX_DECLARE(t) local_irq_declare(t)
#define API_MUTEX_TAKE(t) local_irq_save(t) #define API_MUTEX_TAKE(t) local_irq_save(t)
@ -25,6 +28,7 @@
extern bool system_overclock(void); extern bool system_overclock(void);
extern bool system_restoreclock(void); extern bool system_restoreclock(void);
#endif
int ICACHE_FLASH_ATTR wps_build_public_key(struct wps_data* wps, struct wpabuf* msg, wps_key_mode_t mode) int ICACHE_FLASH_ATTR wps_build_public_key(struct wps_data* wps, struct wpabuf* msg, wps_key_mode_t mode)
{ {
@ -55,21 +59,23 @@ int ICACHE_FLASH_ATTR wps_build_public_key(struct wps_data* wps, struct wpabuf*
dh5_free(wps->dh_ctx); dh5_free(wps->dh_ctx);
wpa_printf(MSG_DEBUG, "build public key start"); wpa_printf(MSG_DEBUG, "build public key start");
#ifdef CONFIG_IDF_TARGET_ESP8266
API_MUTEX_DECLARE(c_tmp); API_MUTEX_DECLARE(c_tmp);
API_MUTEX_TAKE(c_tmp); API_MUTEX_TAKE(c_tmp);
//pp_soft_wdt_stop(); //pp_soft_wdt_stop();
system_overclock(); system_overclock();
//REG_SET_BIT(0x3ff00014, BIT(0)); //change CPU to 160Mhz //REG_SET_BIT(0x3ff00014, BIT(0)); //change CPU to 160Mhz
//ets_update_cpu_frequency(160); //ets_update_cpu_frequency(160);
#endif
wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey); wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey);
#ifdef CONFIG_IDF_TARGET_ESP8266
system_restoreclock(); system_restoreclock();
//REG_CLR_BIT(0x3ff00014, BIT(0)); //change CPU to 80Mhz //REG_CLR_BIT(0x3ff00014, BIT(0)); //change CPU to 80Mhz
//ets_update_cpu_frequency(80); //ets_update_cpu_frequency(80);
//pp_soft_wdt_restart(); //pp_soft_wdt_restart();
API_MUTEX_GIVE(c_tmp); API_MUTEX_GIVE(c_tmp);
#endif
wpa_printf(MSG_DEBUG, "build public key finish"); wpa_printf(MSG_DEBUG, "build public key finish");
pubkey = wpabuf_zeropad(pubkey, 192); pubkey = wpabuf_zeropad(pubkey, 192);
@ -185,8 +191,14 @@ int ICACHE_FLASH_ATTR wps_build_authenticator(struct wps_data* wps, struct wpabu
len[0] = wpabuf_len(wps->last_msg); len[0] = wpabuf_len(wps->last_msg);
addr[1] = wpabuf_head(msg); addr[1] = wpabuf_head(msg);
len[1] = wpabuf_len(msg); len[1] = wpabuf_len(msg);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash); //hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, (int *)len, hash);
ets_printf("test wps\n");
} else {
wpa_printf(MSG_ERROR, "Fail to register hmac sha256 vector!\r\n");
return -1;
}
wpa_printf(MSG_DEBUG, "WPS: * Authenticator"); wpa_printf(MSG_DEBUG, "WPS: * Authenticator");
wpabuf_put_be16(msg, ATTR_AUTHENTICATOR); wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN); wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
@ -347,9 +359,16 @@ int ICACHE_FLASH_ATTR wps_build_key_wrap_auth(struct wps_data* wps, struct wpabu
u8 hash[SHA256_MAC_LEN]; u8 hash[SHA256_MAC_LEN];
wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator"); wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator");
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg), /* hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
wpabuf_len(msg), hash); wpabuf_len(msg), hash);
*/
if (wps_crypto_funcs.hmac_sha256) {
wps_crypto_funcs.hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
wpabuf_len(msg), hash);
} else {
wpa_printf(MSG_ERROR, "Fail to register hmac sha256 function!\r\n");
return -1;
}
wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH); wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
wpabuf_put_be16(msg, WPS_KWA_LEN); wpabuf_put_be16(msg, WPS_KWA_LEN);
wpabuf_put_data(msg, hash, WPS_KWA_LEN); wpabuf_put_data(msg, hash, WPS_KWA_LEN);
@ -382,9 +401,17 @@ int ICACHE_FLASH_ATTR wps_build_encr_settings(struct wps_data* wps, struct wpabu
data = wpabuf_put(msg, 0); data = wpabuf_put(msg, 0);
wpabuf_put_buf(msg, plain); wpabuf_put_buf(msg, plain);
if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain))) { /* if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain))) {
return -1; return -1;
} } */
wpa_printf(MSG_DEBUG, "WPS: * AES 128 Encrypted Settings");
if (wps_crypto_funcs.aes_128_encrypt) {
if (wps_crypto_funcs.aes_128_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain)))
return -1;
} else {
wpa_printf(MSG_ERROR, "Fail to register aes_128_encrypt function!\r\n");
return -1;
}
return 0; return 0;
} }
@ -401,8 +428,14 @@ int ICACHE_FLASH_ATTR wps_build_oob_dev_pw(struct wpabuf* msg, u16 dev_pw_id,
addr[0] = wpabuf_head(pubkey); addr[0] = wpabuf_head(pubkey);
hash_len = wpabuf_len(pubkey); hash_len = wpabuf_len(pubkey);
sha256_vector(1, addr, &hash_len, pubkey_hash); /* sha256_vector(1, addr, &hash_len, pubkey_hash); */
if (wps_crypto_funcs.sha256_vector) {
wps_crypto_funcs.sha256_vector(1, addr, &hash_len, pubkey_hash);
} else {
wpa_printf(MSG_ERROR, "Fail to register sha256 vector function!\r\n");
return -1;
}
wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD); wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD);
wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len); wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len);
wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);

View File

@ -5,7 +5,6 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/wps_defs.h" #include "wps/wps_defs.h"

View File

@ -5,7 +5,6 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/wps_i.h" #include "wps/wps_i.h"
@ -37,7 +36,14 @@ int ICACHE_FLASH_ATTR wps_process_authenticator(struct wps_data* wps, const u8*
len[0] = wpabuf_len(wps->last_msg); len[0] = wpabuf_len(wps->last_msg);
addr[1] = wpabuf_head(msg); addr[1] = wpabuf_head(msg);
len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN; len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "Fail to register hmac_sha256_vector function!\r\n");
return -1;
}
if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) { if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator"); wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
@ -69,8 +75,15 @@ int ICACHE_FLASH_ATTR wps_process_key_wrap_auth(struct wps_data* wps, struct wpa
return -1; return -1;
} }
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash); /* hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256) {
wps_crypto_funcs.hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
} else {
wpa_printf(MSG_ERROR, "Fail to register hmac sha256 function!\r\n");
return -1;
}
if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) { if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Invalid KWA"); wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
return -1; return -1;

View File

@ -7,10 +7,8 @@
*/ */
#include <string.h> #include <string.h>
#include "rom/ets_sys.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/wps_i.h"
#include "crypto/aes_wrap.h" #include "crypto/aes_wrap.h"
#include "crypto/crypto.h" #include "crypto/crypto.h"
@ -19,7 +17,10 @@
#include "crypto/sha256.h" #include "crypto/sha256.h"
#include "crypto/random.h" #include "crypto/random.h"
#include "wps/wps_i.h"
#ifdef CONFIG_IDF_TARGET_ESP8266
#include "esp_system.h" #include "esp_system.h"
#endif
#ifdef MEMLEAK_DEBUG #ifdef MEMLEAK_DEBUG
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
@ -52,7 +53,13 @@ void ICACHE_FLASH_ATTR wps_kdf(const u8* key, const u8* label_prefix, size_t lab
for (i = 1; i <= iter; i++) { for (i = 1; i <= iter; i++) {
WPA_PUT_BE32(i_buf, i); WPA_PUT_BE32(i_buf, i);
hmac_sha256_vector(key, SHA256_MAC_LEN, 4, addr, len, hash); /* hmac_sha256_vector(key, SHA256_MAC_LEN, 4, addr, len, hash); */
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(key, SHA256_MAC_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to reigster hmac sha256 vector function!\r\n", __FUNCTION__);
return ;
}
if (i < iter) { if (i < iter) {
os_memcpy(opos, hash, SHA256_MAC_LEN); os_memcpy(opos, hash, SHA256_MAC_LEN);
@ -100,15 +107,29 @@ int ICACHE_FLASH_ATTR wps_derive_keys(struct wps_data* wps)
} }
/* Own DH private key is not needed anymore */ /* Own DH private key is not needed anymore */
/*
* due to the public key calculated when wps start, it will not calculate anymore even when we build M1 message, also calculate the key need take a long time
* which would cause WPS fail, so we clean the key after WPS finished .
*/
#if !defined(ESP8266_WORKAROUND) && !defined(ESP32_WORKAROUND)
wpabuf_free(wps->dh_privkey); wpabuf_free(wps->dh_privkey);
wps->dh_privkey = NULL; wps->dh_privkey = NULL;
#endif //ESP32_WORKAROUND
wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared); wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared);
/* DHKey = SHA-256(g^AB mod p) */ /* DHKey = SHA-256(g^AB mod p) */
addr[0] = wpabuf_head(dh_shared); addr[0] = wpabuf_head(dh_shared);
len[0] = wpabuf_len(dh_shared); len[0] = wpabuf_len(dh_shared);
sha256_vector(1, addr, len, dhkey); /* sha256_vector(1, addr, len, dhkey);
*/
if (wps_crypto_funcs.sha256_vector) {
wps_crypto_funcs.sha256_vector(1, addr, (int *)len, dhkey);
} else {
wpa_printf(MSG_ERROR, "In function %s, Fail to register sha256 vector function!\r\n", __FUNCTION__);
return -1;
}
wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey)); wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey));
wpabuf_free(dh_shared); wpabuf_free(dh_shared);
@ -119,7 +140,14 @@ int ICACHE_FLASH_ATTR wps_derive_keys(struct wps_data* wps)
len[1] = ETH_ALEN; len[1] = ETH_ALEN;
addr[2] = wps->nonce_r; addr[2] = wps->nonce_r;
len[2] = WPS_NONCE_LEN; len[2] = WPS_NONCE_LEN;
hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk); /* hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, (int *)len, kdk);
} else {
wpa_printf(MSG_ERROR, "In function %s, Fail to register hmac sha256 vector function!\r\n", __FUNCTION__);
return -1;
}
wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk)); wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk));
@ -148,9 +176,18 @@ void ICACHE_FLASH_ATTR wps_derive_psk(struct wps_data* wps, const u8* dev_passwd
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd, hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd,
(dev_passwd_len + 1) / 2, hash); (dev_passwd_len + 1) / 2, hash);
os_memcpy(wps->psk1, hash, WPS_PSK_LEN); os_memcpy(wps->psk1, hash, WPS_PSK_LEN);
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, /* hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN,
dev_passwd + (dev_passwd_len + 1) / 2, dev_passwd + (dev_passwd_len + 1) / 2,
dev_passwd_len / 2, hash); dev_passwd_len / 2, hash); */
if (wps_crypto_funcs.hmac_sha256) {
wps_crypto_funcs.hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN,
dev_passwd + (dev_passwd_len + 1) / 2,
dev_passwd_len / 2, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256 function!\r\n", __FUNCTION__);
return ;
}
os_memcpy(wps->psk2, hash, WPS_PSK_LEN); os_memcpy(wps->psk2, hash, WPS_PSK_LEN);
wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password", wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password",
@ -183,11 +220,21 @@ struct wpabuf* ICACHE_FLASH_ATTR wps_decrypt_encr_settings(struct wps_data* wps,
wpa_hexdump(MSG_MSGDUMP, "WPS: Encrypted Settings", encr, encr_len); wpa_hexdump(MSG_MSGDUMP, "WPS: Encrypted Settings", encr, encr_len);
wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size); wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size);
if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted), /* if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted),
wpabuf_len(decrypted))) { wpabuf_len(decrypted))) {
wpabuf_free(decrypted); wpabuf_free(decrypted);
return NULL; return NULL;
} } */
if (wps_crypto_funcs.aes_128_decrypt) {
if (wps_crypto_funcs.aes_128_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted),
wpabuf_len(decrypted))) {
wpabuf_free(decrypted);
return NULL;
}
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register aes 128 decrypt function!\r\n", __FUNCTION__);
return NULL;
}
wpa_hexdump_buf_key(MSG_MSGDUMP, "WPS: Decrypted Encrypted Settings", wpa_hexdump_buf_key(MSG_MSGDUMP, "WPS: Decrypted Encrypted Settings",
decrypted); decrypted);
@ -257,10 +304,17 @@ unsigned int ICACHE_FLASH_ATTR wps_generate_pin(void)
/* Generate seven random digits for the PIN */ /* Generate seven random digits for the PIN */
//if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) { //if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) {
#ifdef CONFIG_IDF_TARGET_ESP8266
struct os_time now; struct os_time now;
os_get_time(&now); os_get_time(&now);
val = esp_random() ^ now.sec ^ now.usec; val = esp_random() ^ now.sec ^ now.usec;
//} //}
#else
/* Generate seven random digits for the PIN */
if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) {
return -1;
}
#endif
val %= 10000000; val %= 10000000;
/* Append checksum digit */ /* Append checksum digit */

View File

@ -5,8 +5,6 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/wps_i.h" #include "wps/wps_i.h"

View File

@ -5,9 +5,7 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wps/asm/irqflags.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/wps_i.h" #include "wps/wps_i.h"
@ -19,7 +17,8 @@
#include "crypto/random.h" #include "crypto/random.h"
//#include "pp/mac_register_v6.h" //#include "pp/mac_register_v6.h"
#ifdef CONFIG_IDF_TARGET_ESP8266
#include "wps/asm/irqflags.h"
#include "esp_wifi_osi.h" #include "esp_wifi_osi.h"
#ifdef MEMLEAK_DEBUG #ifdef MEMLEAK_DEBUG
@ -30,10 +29,10 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
#define API_MUTEX_TAKE(t) local_irq_save(t) #define API_MUTEX_TAKE(t) local_irq_save(t)
#define API_MUTEX_GIVE(t) local_irq_restore(t) #define API_MUTEX_GIVE(t) local_irq_restore(t)
extern struct wps_sm* gWpsSm;
extern bool system_overclock(void); extern bool system_overclock(void);
extern bool system_restoreclock(void); extern bool system_restoreclock(void);
#endif
static int ICACHE_FLASH_ATTR wps_build_mac_addr(struct wps_data* wps, struct wpabuf* msg) static int ICACHE_FLASH_ATTR wps_build_mac_addr(struct wps_data* wps, struct wpabuf* msg)
{ {
@ -97,7 +96,15 @@ static int ICACHE_FLASH_ATTR wps_build_e_hash(struct wps_data* wps, struct wpabu
len[2] = wpabuf_len(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r); addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN); wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
wpa_printf(MSG_DEBUG, "WPS: * E-Hash2"); wpa_printf(MSG_DEBUG, "WPS: * E-Hash2");
@ -107,7 +114,15 @@ static int ICACHE_FLASH_ATTR wps_build_e_hash(struct wps_data* wps, struct wpabu
/* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */ /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN; addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
addr[1] = wps->psk2; addr[1] = wps->psk2;
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN); wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
return 0; return 0;
@ -587,15 +602,15 @@ static int ICACHE_FLASH_ATTR wps_process_pubkey(struct wps_data* wps, const u8*
} }
wpa_printf(MSG_DEBUG, "process pubkey start"); wpa_printf(MSG_DEBUG, "process pubkey start");
#ifdef CONFIG_IDF_TARGET_ESP8266
API_MUTEX_DECLARE(c_tmp); API_MUTEX_DECLARE(c_tmp);
API_MUTEX_TAKE(c_tmp); API_MUTEX_TAKE(c_tmp);
//pp_soft_wdt_stop(); //pp_soft_wdt_stop();
//REG_SET_BIT(0x3ff00014, BIT(0)); //change CPU to 160Mhz //REG_SET_BIT(0x3ff00014, BIT(0)); //change CPU to 160Mhz
//ets_update_cpu_frequency(160); //ets_update_cpu_frequency(160);
//printf("[%s]line:[%d]%d\r\n", __func__, __LINE__, REG_READ(0x3ff20c00)); printf("[%s]line:[%d]%d\r\n", __func__, __LINE__, REG_READ(0x3ff20c00));
system_overclock(); system_overclock();
if (wps_derive_keys(wps) < 0) { if (wps_derive_keys(wps) < 0) {
//REG_CLR_BIT(0x3ff00014, BIT(0)); //change CPU to 80Mhz //REG_CLR_BIT(0x3ff00014, BIT(0)); //change CPU to 80Mhz
//ets_update_cpu_frequency(80); //ets_update_cpu_frequency(80);
@ -606,12 +621,17 @@ static int ICACHE_FLASH_ATTR wps_process_pubkey(struct wps_data* wps, const u8*
} }
system_restoreclock(); system_restoreclock();
//printf("[%s]line:[%d]%d\r\n", __func__, __LINE__, REG_READ(0x3ff20c00)); printf("[%s]line:[%d]%d\r\n", __func__, __LINE__, REG_READ(0x3ff20c00));
//REG_CLR_BIT(0x3ff00014, BIT(0)); //change CPU to 80Mhz //REG_CLR_BIT(0x3ff00014, BIT(0)); //change CPU to 80Mhz
//ets_update_cpu_frequency(80); //ets_update_cpu_frequency(80);
//pp_soft_wdt_restart(); //pp_soft_wdt_restart();
API_MUTEX_GIVE(c_tmp); API_MUTEX_GIVE(c_tmp);
#else
if (wps_derive_keys(wps) < 0) {
return -1;
}
#endif
wpa_printf(MSG_DEBUG, "process pubkey finish"); wpa_printf(MSG_DEBUG, "process pubkey finish");
@ -670,7 +690,13 @@ static int ICACHE_FLASH_ATTR wps_process_r_snonce1(struct wps_data* wps, const u
len[2] = wpabuf_len(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r); addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); */
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does " wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
@ -710,8 +736,15 @@ static int ICACHE_FLASH_ATTR wps_process_r_snonce2(struct wps_data* wps, const u
len[2] = wpabuf_len(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r); addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to regiset hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does " wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
"not match with the pre-committed value"); "not match with the pre-committed value");
@ -1341,6 +1374,8 @@ _out:
return res; return res;
} }
extern struct wps_sm *gWpsSm;
static enum wps_process_res ICACHE_FLASH_ATTR wps_process_wsc_start(struct wps_data* wps, static enum wps_process_res ICACHE_FLASH_ATTR wps_process_wsc_start(struct wps_data* wps,
const struct wpabuf* msg) const struct wpabuf* msg)
{ {

View File

@ -5,12 +5,12 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/utils/uuid.h" #include "wps/utils/uuid.h"
#include "wpa/list.h" #include "wpa/list.h"
#include "wpa/ieee802_11_defs.h" #include "wpa/ieee802_11_defs.h"
#include "wps/wps_i.h" #include "wps/wps_i.h"
#include "wps/wps_dev_attr.h" #include "wps/wps_dev_attr.h"
@ -1605,7 +1605,14 @@ static int ICACHE_FLASH_ATTR wps_build_r_hash(struct wps_data* wps, struct wpabu
len[2] = wpabuf_len(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r); addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); */
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN); wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
wpa_printf(MSG_DEBUG, "WPS: * R-Hash2"); wpa_printf(MSG_DEBUG, "WPS: * R-Hash2");
@ -1615,7 +1622,15 @@ static int ICACHE_FLASH_ATTR wps_build_r_hash(struct wps_data* wps, struct wpabu
/* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */ /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN; addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
addr[1] = wps->psk2; addr[1] = wps->psk2;
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN); wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
return 0; return 0;
@ -2433,7 +2448,14 @@ static int ICACHE_FLASH_ATTR wps_process_e_snonce1(struct wps_data* wps, const u
len[2] = wpabuf_len(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r); addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does " wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
@ -2473,8 +2495,15 @@ static int ICACHE_FLASH_ATTR wps_process_e_snonce2(struct wps_data* wps, const u
len[2] = wpabuf_len(wps->dh_pubkey_e); len[2] = wpabuf_len(wps->dh_pubkey_e);
addr[3] = wpabuf_head(wps->dh_pubkey_r); addr[3] = wpabuf_head(wps->dh_pubkey_r);
len[3] = wpabuf_len(wps->dh_pubkey_r); len[3] = wpabuf_len(wps->dh_pubkey_r);
hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); /* hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
*/
if (wps_crypto_funcs.hmac_sha256_vector) {
wps_crypto_funcs.hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, (int *)len, hash);
} else {
wpa_printf(MSG_ERROR, "In function %s, fail to register hmac_sha256_vector function!\r\n", __FUNCTION__);
return -1;
}
if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does " wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
"not match with the pre-committed value"); "not match with the pre-committed value");

View File

@ -5,8 +5,6 @@
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
*/ */
#include "rom/ets_sys.h"
#include "wpa/includes.h" #include "wpa/includes.h"
#include "wpa/common.h" #include "wpa/common.h"
#include "wps/wps_i.h" #include "wps/wps_i.h"