1 /*
2  * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 
8 #ifndef __ESP_WIFI_CRYPTO_TYPES_H__
9 #define __ESP_WIFI_CRYPTO_TYPES_H__
10 
11 /* This is an internal API header for configuring the implementation used for WiFi cryptographic
12    operations.
13 
14    During normal operation, you don't need to use any of these types or functions in this header.
15    See esp_wifi.h & esp_wifi_types.h instead.
16 */
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 #define ESP_WIFI_CRYPTO_VERSION 0x00000001
23 
24 /*
25  * Enumeration for hash operations.
26  * When WPA2 is connecting, this enum is used to
27  * request a hash algorithm via crypto_hash_xxx functions.
28  */
29 typedef enum {
30     ESP_CRYPTO_HASH_ALG_MD5, ESP_CRYPTO_HASH_ALG_SHA1,
31     ESP_CRYPTO_HASH_ALG_HMAC_MD5, ESP_CRYPTO_HASH_ALG_HMAC_SHA1,
32     ESP_CRYPTO_HASH_ALG_SHA256, ESP_CRYPTO_HASH_ALG_HMAC_SHA256
33 }esp_crypto_hash_alg_t;
34 
35 /*
36  * Enumeration for block cipher operations.
37  * When WPA2 is connecting, this enum is used to request a block
38  * cipher algorithm via crypto_cipher_xxx functions.
39  */
40 typedef enum {
41     ESP_CRYPTO_CIPHER_NULL, ESP_CRYPTO_CIPHER_ALG_AES, ESP_CRYPTO_CIPHER_ALG_3DES,
42     ESP_CRYPTO_CIPHER_ALG_DES, ESP_CRYPTO_CIPHER_ALG_RC2, ESP_CRYPTO_CIPHER_ALG_RC4
43 } esp_crypto_cipher_alg_t;
44 
45 /*
46  * This structure is about the algorithm when do crypto_hash operation, for detail,
47  * please reference to the structure crypto_hash.
48  */
49 typedef struct crypto_hash esp_crypto_hash_t;
50 
51 /*
52  * This structure is about the algorithm when do crypto_cipher operation, for detail,
53  * please reference to the structure crypto_cipher.
54  */
55 typedef struct crypto_cipher esp_crypto_cipher_t;
56 
57 /**
58   * @brief The AES callback function when do WPS connect.
59   *
60   * @param key  Encryption key.
61   * @param iv  Encryption IV for CBC mode (16 bytes).
62   * @param data  Data to encrypt in-place.
63   * @param data_len  Length of data in bytes (must be divisible by 16)
64   */
65 typedef int (*esp_aes_128_encrypt_t)(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len);
66 
67 /**
68   * @brief The AES callback function when do WPS connect.
69   *
70   * @param key  Decryption key.
71   * @param iv  Decryption IV for CBC mode (16 bytes).
72   * @param data  Data to decrypt in-place.
73   * @param data_len  Length of data in bytes (must be divisible by 16)
74   *
75   */
76 typedef int (*esp_aes_128_decrypt_t)(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len);
77 
78 /**
79   * @brief The AES callback function when do STA connect.
80   *
81   * @param kek  16-octet Key encryption key (KEK).
82   * @param n  Length of the plaintext key in 64-bit units;
83   * @param plain  Plaintext key to be wrapped, n * 64 bits
84   * @param cipher  Wrapped key, (n + 1) * 64 bits
85   *
86   */
87 typedef int (*esp_aes_wrap_t)(const unsigned char *kek, int n, const unsigned char *plain, unsigned char *cipher);
88 
89 /**
90   * @brief The AES callback function when do STA connect.
91   *
92   * @param kek  16-octet Key decryption key (KEK).
93   * @param n  Length of the plaintext key in 64-bit units;
94   * @param cipher  Wrapped key to be unwrapped, (n + 1) * 64 bits
95   * @param plain  Plaintext key, n * 64 bits
96   *
97   */
98 typedef int (*esp_aes_unwrap_t)(const unsigned char *kek, int n, const unsigned char *cipher, unsigned char *plain);
99 
100 /**
101   * @brief The SHA256 callback function when do WPS connect.
102   *
103   * @param key  Key for HMAC operations.
104   * @param key_len  Length of the key in bytes.
105   * @param num_elem  Number of elements in the data vector.
106   * @param addr  Pointers to the data areas.
107   * @param len  Lengths of the data blocks.
108   * @param mac  Buffer for the hash (32 bytes).
109   *
110   */
111 typedef int (*esp_hmac_sha256_vector_t)(const unsigned char *key, int key_len, int num_elem,
112 			                   const unsigned char *addr[], const int *len, unsigned char *mac);
113 
114 /**
115   * @brief The AES callback function when do STA connect.
116   *
117   * @param key  Key for PRF.
118   * @param key_len  Length of the key in bytes.
119   * @param label  A unique label for each purpose of the PRF.
120   * @param data  Extra data to bind into the key.
121   * @param data_len  Length of the data.
122   * @param buf  Buffer for the generated pseudo-random key.
123   * @param buf_len  Number of bytes of key to generate.
124   *
125   */
126 typedef int (*esp_sha256_prf_t)(const unsigned char *key, int key_len, const char *label,
127 	                           const unsigned char *data, int data_len, unsigned char *buf, int buf_len);
128 
129 /**
130  * @brief HMAC-MD5 over data buffer (RFC 2104)'
131  *
132  * @key: Key for HMAC operations
133  * @key_len: Length of the key in bytes
134  * @data: Pointers to the data area
135  * @data_len: Length of the data area
136  * @mac: Buffer for the hash (16 bytes)
137  * Returns: 0 on success, -1 on failure
138  */
139 typedef int (*esp_hmac_md5_t)(const unsigned char *key, unsigned int key_len, const unsigned char *data,
140                               unsigned int data_len, unsigned char *mac);
141 
142 /**
143  * @brief HMAC-MD5 over data vector (RFC 2104)
144  *
145  * @key: Key for HMAC operations
146  * @key_len: Length of the key in bytes
147  * @num_elem: Number of elements in the data vector
148  * @addr: Pointers to the data areas
149  * @len: Lengths of the data blocks
150  * @mac: Buffer for the hash (16 bytes)
151  * Returns: 0 on success, -1 on failure
152  */
153 typedef int (*esp_hmac_md5_vector_t)(const unsigned char *key, unsigned int key_len, unsigned int num_elem,
154                               const unsigned char *addr[], const unsigned int *len, unsigned char *mac);
155 
156 /**
157  * @brief HMAC-SHA1 over data buffer (RFC 2104)
158  *
159  * @key: Key for HMAC operations
160  * @key_len: Length of the key in bytes
161  * @data: Pointers to the data area
162  * @data_len: Length of the data area
163  * @mac: Buffer for the hash (20 bytes)
164  * Returns: 0 on success, -1 of failure
165  */
166 typedef int (*esp_hmac_sha1_t)(const unsigned char *key, unsigned int key_len, const unsigned char *data,
167                               unsigned int data_len, unsigned char *mac);
168 
169 /**
170  * @brief HMAC-SHA1 over data vector (RFC 2104)
171  *
172  * @key: Key for HMAC operations
173  * @key_len: Length of the key in bytes
174  * @num_elem: Number of elements in the data vector
175  * @addr: Pointers to the data areas
176  * @len: Lengths of the data blocks
177  * @mac: Buffer for the hash (20 bytes)
178  * Returns: 0 on success, -1 on failure
179  */
180 typedef int (*esp_hmac_sha1_vector_t)(const unsigned char *key, unsigned int key_len, unsigned int num_elem,
181                               const unsigned char *addr[], const unsigned int *len, unsigned char *mac);
182 
183 /**
184  * @brief SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
185  *
186  * @key: Key for PRF
187  * @key_len: Length of the key in bytes
188  * @label: A unique label for each purpose of the PRF
189  * @data: Extra data to bind into the key
190  * @data_len: Length of the data
191  * @buf: Buffer for the generated pseudo-random key
192  * @buf_len: Number of bytes of key to generate
193  * Returns: 0 on success, -1 of failure
194  *
195  * This function is used to derive new, cryptographically separate keys from a
196  * given key (e.g., PMK in IEEE 802.11i).
197  */
198 typedef int (*esp_sha1_prf_t)(const unsigned char *key, unsigned int key_len, const char *label,
199                               const unsigned char *data, unsigned int data_len, unsigned char *buf, unsigned int buf_len);
200 
201 /**
202  * @brief SHA-1 hash for data vector
203  *
204  * @num_elem: Number of elements in the data vector
205  * @addr: Pointers to the data areas
206  * @len: Lengths of the data blocks
207  * @mac: Buffer for the hash
208  * Returns: 0 on success, -1 on failure
209  */
210 typedef int (*esp_sha1_vector_t)(unsigned int num_elem, const unsigned char *addr[], const unsigned int *len,
211                               unsigned char *mac);
212 
213 /**
214  * @brief SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
215  *
216  * @passphrase: ASCII passphrase
217  * @ssid: SSID
218  * @ssid_len: SSID length in bytes
219  * @iterations: Number of iterations to run
220  * @buf: Buffer for the generated key
221  * @buflen: Length of the buffer in bytes
222  * Returns: 0 on success, -1 of failure
223  *
224  * This function is used to derive PSK for WPA-PSK. For this protocol,
225  * iterations is set to 4096 and buflen to 32. This function is described in
226  * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
227  */
228 typedef int (*esp_pbkdf2_sha1_t)(const char *passphrase, const char *ssid, unsigned int ssid_len,
229                               int iterations, unsigned char *buf, unsigned int buflen);
230 
231 /**
232  * @brief XOR RC4 stream to given data with skip-stream-start
233  *
234  * @key: RC4 key
235  * @keylen: RC4 key length
236  * @skip: number of bytes to skip from the beginning of the RC4 stream
237  * @data: data to be XOR'ed with RC4 stream
238  * @data_len: buf length
239  * Returns: 0 on success, -1 on failure
240  *
241  * Generate RC4 pseudo random stream for the given key, skip beginning of the
242  * stream, and XOR the end result with the data buffer to perform RC4
243  * encryption/decryption.
244  */
245 typedef int (*esp_rc4_skip_t)(const unsigned char *key, unsigned int keylen, unsigned int skip,
246                               unsigned char *data, unsigned int data_len);
247 
248 /**
249  * @brief MD5 hash for data vector
250  *
251  * @num_elem: Number of elements in the data vector
252  * @addr: Pointers to the data areas
253  * @len: Lengths of the data blocks
254  * @mac: Buffer for the hash
255  * Returns: 0 on success, -1 on failure
256  */
257 typedef int (*esp_md5_vector_t)(unsigned int num_elem, const unsigned char *addr[], const unsigned int *len,
258                               unsigned char *mac);
259 
260 /**
261  * @brief Encrypt one AES block
262  *
263  * @ctx: Context pointer from aes_encrypt_init()
264  * @plain: Plaintext data to be encrypted (16 bytes)
265  * @crypt: Buffer for the encrypted data (16 bytes)
266  */
267 typedef void (*esp_aes_encrypt_t)(void *ctx, const unsigned char *plain, unsigned char *crypt);
268 
269 /**
270  * @brief Initialize AES for encryption
271  *
272  * @key: Encryption key
273  * @len: Key length in bytes (usually 16, i.e., 128 bits)
274  * Returns: Pointer to context data or %NULL on failure
275  */
276 typedef void * (*esp_aes_encrypt_init_t)(const unsigned char *key,  unsigned int len);
277 
278 /**
279  * @brief Deinitialize AES encryption
280  *
281  * @ctx: Context pointer from aes_encrypt_init()
282  */
283 typedef void (*esp_aes_encrypt_deinit_t)(void *ctx);
284 
285 /**
286  * @brief Decrypt one AES block
287  *
288  * @ctx: Context pointer from aes_encrypt_init()
289  * @crypt: Encrypted data (16 bytes)
290  * @plain: Buffer for the decrypted data (16 bytes)
291  */
292 typedef void (*esp_aes_decrypt_t)(void *ctx, const unsigned char *crypt, unsigned char *plain);
293 
294 /**
295  * @brief Initialize AES for decryption
296  *
297  * @key: Decryption key
298  * @len: Key length in bytes (usually 16, i.e., 128 bits)
299  * Returns: Pointer to context data or %NULL on failure
300  */
301 typedef void * (*esp_aes_decrypt_init_t)(const unsigned char *key, unsigned int len);
302 
303 /**
304  * @brief Deinitialize AES decryption
305  *
306  * @ctx: Context pointer from aes_encrypt_init()
307  */
308 typedef void (*esp_aes_decrypt_deinit_t)(void *ctx);
309 
310 /**
311  * @brief One-Key CBC MAC (OMAC1) hash with AES-128 for MIC computation
312  *
313  * @key: 128-bit key for the hash operation
314  * @data: Data buffer for which a MIC is computed
315  * @data_len: Length of data buffer in bytes
316  * @mic: Buffer for MIC (128 bits, i.e., 16 bytes)
317  * Returns: 0 on success, -1 on failure
318  */
319 typedef int (*esp_omac1_aes_128_t)(const uint8_t *key, const uint8_t *data, size_t data_len,
320                                    uint8_t *mic);
321 
322 /**
323  * @brief Decrypt data using CCMP (Counter Mode CBC-MAC Protocol OR
324  *        Counter Mode Cipher Block Chaining Message Authentication
325  *        Code Protocol) which is used in IEEE 802.11i RSN standard.
326  * @tk: 128-bit Temporal Key for obtained during 4-way handshake
327  * @hdr: Pointer to IEEE802.11 frame headeri needed for AAD
328  * @data: Pointer to encrypted data buffer
329  * @data_len: Encrypted data length in bytes
330  * @decrypted_len: Length of decrypted data
331  * @espnow_pkt: Indicates if it's an ESPNOW packet
332  * Returns: Pointer to decrypted data on success, NULL on failure
333  */
334 typedef uint8_t * (*esp_ccmp_decrypt_t)(const uint8_t *tk, const uint8_t *ieee80211_hdr,
335                                         const uint8_t *data, size_t data_len,
336                                         size_t *decrypted_len, bool espnow_pkt);
337 
338 /**
339  * @brief Encrypt data using CCMP (Counter Mode CBC-MAC Protocol OR
340  *        Counter Mode Cipher Block Chaining Message Authentication
341  *        Code Protocol) which is used in IEEE 802.11i RSN standard.
342  * @tk: 128-bit Temporal Key for obtained during 4-way handshake
343  * @frame: Pointer to IEEE802.11 frame including header
344  * @len: Length of the frame including header
345  * @hdrlen: Length of the header
346  * @pn: Packet Number counter
347  * @keyid: Key ID to be mentioned in CCMP Vector
348  * @encrypted_len: Length of the encrypted frame including header
349  */
350 typedef uint8_t * (*esp_ccmp_encrypt_t)(const uint8_t *tk, uint8_t *frame, size_t len, size_t hdrlen,
351                                         uint8_t *pn, int keyid, size_t *encrypted_len);
352 
353 /**
354  * @brief One-Key GMAC hash with AES for MIC computation
355  *
356  * @key: key for the hash operation
357  * @keylen: key length
358  * @iv: initialization vector
359  * @iv_len: initialization vector length
360  * @aad: aad
361  * @aad_len: aad length
362  * @mic: Buffer for MIC (128 bits, i.e., 16 bytes)
363  * Returns: 0 on success, -1 on failure
364  */
365 typedef int (*esp_aes_gmac_t)(const uint8_t *key, size_t keylen, const uint8_t *iv, size_t iv_len,
366                               const uint8_t *aad, size_t aad_len, uint8_t *mic);
367 
368 /**
369   * @brief The crypto callback function structure used when do station security connect.
370   *        The structure can be set as software crypto or the crypto optimized by ESP32
371   *        hardware.
372   */
373 typedef struct {
374     uint32_t size;
375     uint32_t version;
376     esp_aes_wrap_t aes_wrap;                         /**< station connect function used when send EAPOL frame */
377     esp_aes_unwrap_t aes_unwrap;                     /**< station connect function used when decrypt key data */
378     esp_hmac_sha256_vector_t hmac_sha256_vector;     /**< station connect function used when check MIC */
379     esp_sha256_prf_t sha256_prf;                     /**< station connect function used when check MIC */
380     esp_hmac_md5_t hmac_md5;
381     esp_hmac_md5_vector_t hamc_md5_vector;
382     esp_hmac_sha1_t hmac_sha1;
383     esp_hmac_sha1_vector_t hmac_sha1_vector;
384     esp_sha1_prf_t sha1_prf;
385     esp_sha1_vector_t sha1_vector;
386     esp_pbkdf2_sha1_t pbkdf2_sha1;
387     esp_rc4_skip_t rc4_skip;
388     esp_md5_vector_t md5_vector;
389     esp_aes_encrypt_t aes_encrypt;
390     esp_aes_encrypt_init_t aes_encrypt_init;
391     esp_aes_encrypt_deinit_t aes_encrypt_deinit;
392     esp_aes_decrypt_t aes_decrypt;
393     esp_aes_decrypt_init_t aes_decrypt_init;
394     esp_aes_decrypt_deinit_t aes_decrypt_deinit;
395     esp_aes_128_encrypt_t aes_128_encrypt;
396     esp_aes_128_decrypt_t aes_128_decrypt;
397     esp_omac1_aes_128_t omac1_aes_128;
398     esp_ccmp_decrypt_t ccmp_decrypt;
399     esp_ccmp_encrypt_t ccmp_encrypt;
400     esp_aes_gmac_t aes_gmac;
401 }wpa_crypto_funcs_t;
402 
403 /**
404   * @brief The crypto callback function structure used in mesh vendor IE encryption. The
405   *        structure can be set as software crypto or the crypto optimized by ESP32
406   *        hardware.
407   */
408 typedef struct{
409     esp_aes_128_encrypt_t aes_128_encrypt;          /**< function used in mesh vendor IE encryption */
410     esp_aes_128_decrypt_t aes_128_decrypt;          /**< function used in mesh vendor IE decryption */
411 } mesh_crypto_funcs_t;
412 
413 #ifdef __cplusplus
414 }
415 #endif
416 #endif
417