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