1 /*
2  *  Copyright 2008-2024 NXP
3  *
4  *  SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 /** @file wmcrypto.h
9  *
10  *  @brief Crypto Functions
11  *
12  *  This provides crypto wrapper functions that selectively call the WMSDKA or
13  *  mbed TLS crypto functions based on the selected configuration.
14  */
15 
16 #ifndef WMCRYPTO_H
17 #define WMCRYPTO_H
18 
19 #include <stdint.h>
20 
21 #include <wmlog.h>
22 
23 #define crypto_e(...) wmlog_e("crypt", ##__VA_ARGS__)
24 #define crypto_w(...) wmlog_w("crypt", ##__VA_ARGS__)
25 
26 #if CONFIG_CRYPTO_DEBUG
27 #define crypto_d(...) wmlog("crypt", ##__VA_ARGS__)
28 #else
29 #define crypto_d(...)
30 #endif /* ! CONFIG_CRYPTO_DEBUG */
31 
32 /* To do: find a way to get these digest and block size */
33 /** Digest size */
34 #define SHA256_DIGEST_SIZE (256 / 8)
35 /** Block size  */
36 #define SHA256_BLOCK_SIZE (512 / 8)
37 
38 #define SHA1_MAC_LEN 20
39 #define MD5_MAC_LEN  16
40 
41 /**
42  *  * Diffie-Hellman parameters.
43  *   */
44 typedef struct
45 {
46     /** prime */
47     unsigned char *prime;
48     /** length of prime */
49     unsigned int primeLen;
50     /** generator */
51     unsigned char *generator;
52     /** length of generator */
53     unsigned int generatorLen;
54 } DH_PG_PARAMS;
55 
56 /**********************************************************
57  *****     Diffie-Hellman Shared Key Generation       *****
58  **********************************************************/
59 /**
60  *  @brief  Sets up Diffie-Hellman key agreement.
61  *
62  *  @param public_key       Pointers to public key generated
63  *  @param public_len       Length of public key
64  *  @param private_key      Pointers to private key generated randomly
65  *  @param private_len      Length of private key
66  *  @param dh_params        Parameters for DH algorithm
67  *
68  *  @return                 0 on success, -1 on failure
69  */
70 void *nxp_dh_setup_key(
71     uint8_t *public_key, uint32_t public_len, uint8_t *private_key, uint32_t private_len, DH_PG_PARAMS *dh_params);
72 
73 /**
74  *  @brief  Computes agreed shared key from the public value,
75  *          private value, and Diffie-Hellman parameters.
76  *
77  *  @param dh		    DH key
78  *  @param shared_key       Pointer to agreed shared key generated
79  *  @param shared_len       Length of agreed shared key
80  *  @param public_key       Pointer to public key generated
81  *  @param public_len       Length of public key
82  *  @param private_key      Pointer to private key generated randomly
83  *  @param private_len      Length of private key
84  *  @param dh_params        Parameters for DH algorithm
85  *
86  *  @return                 0 on success, -1 on failure
87  */
88 int nxp_dh_compute_key(void *dh,
89                        uint8_t *shared_key,
90                        uint32_t shared_len,
91                        uint8_t *public_key,
92                        uint32_t public_len,
93                        uint8_t *private_key,
94                        uint32_t private_len,
95                        DH_PG_PARAMS *dh_params);
96 
97 /**
98  * @brief  Free allocated DH key
99  *
100  * @param dh_context	   DH key
101  *
102  * @return		   None
103  */
104 void nxp_dh_free(void *dh_context);
105 
106 /**
107  *  @brief  SHA-1 hash for data vector
108  *
109  *  @param nmsg		    Number of elements in the data vector
110  *  @param msg		    Pointers to the data areas
111  *  @param msglen	    Lengths of the data blocks
112  *  @param mac		    Buffer for the hash
113  *  @param maclen	    Length of hash buffer
114  *
115  *  @return		    0 on success, -1 of failure
116  */
117 uint32_t nxp_sha1_vector(size_t nmsg, const uint8_t *msg[], const size_t msglen[], uint8_t *mac, size_t maclen);
118 
119 /**********************************************************
120  ***   HMAC-SHA256
121  **********************************************************/
122 /**
123  *  @brief  SHA-256 hash for data vector
124  *
125  *  @param nmsg		    Number of elements in the data vector
126  *  @param msg              Pointers to the data areas
127  *  @param msglen           Lengths of the data blocks
128  *  @param mac              Buffer for the hash
129  *  @param maclen	    Length of hash buffer
130  *
131  *  @return                 0 on success, -1 on failure
132  */
133 uint32_t nxp_sha256_vector(size_t nmsg, const uint8_t *msg[], const size_t msglen[], uint8_t *mac, size_t maclen);
134 
135 /**
136  *  @brief  Wrapper function for SHA256 hash
137  *
138  *  @param num_elem	    Number of elements in the data vector
139  *  @param addr             Pointers to the data areas
140  *  @param len              Lengths of the data blocks
141  *  @param mac		    Buffer for the hash
142  *
143  *  @return                 0 on success, -1 on failure
144  */
145 
146 void nxp_sha256(size_t num_elem, const uint8_t *addr[], const size_t *len, uint8_t *mac);
147 
148 /**
149  *  @brief  Wrapper function for HMAC-SHA256 (RFC 2104)
150  *
151  *  @param key              Key for HMAC operations
152  *  @param keylen          Length of the key in bytes
153  *  @param msg		    Pointers to the data areas
154  *  @param msglen	    Lengths of the data blocks
155  *  @param mac              Buffer for the hash (32 bytes)
156  *  @param maclen           Length of hash buffer
157  *
158  *  @return                 0 on success, -1 on failure
159  */
160 uint32_t nxp_hmac_sha256(
161     const uint8_t *key, uint32_t keylen, uint8_t *msg, uint32_t msglen, uint8_t *mac, uint32_t maclen);
162 
163 /**
164  *  @brief Key derivation function to generate Authentication
165  *         Key and Key Wrap Key used in WPS registration protocol
166  *
167  *  @param key		    Input key to generate authentication key (KDK)
168  *  @param key_len          Length of input key
169  *  @param result           result buffer
170  *  @param result_len       Length of result buffer
171  *
172  * @return		    0 on success, 1 otherwise
173  */
174 int nxp_kdf(uint8_t *key, uint32_t key_len, uint8_t *result, uint32_t result_len);
175 
176 /**********************************************************
177  *  ***   AES Key Wrap Key
178  **********************************************************/
179 /**
180  *  @brief  Wrap keys with AES Key Wrap Algorithm (128-bit KEK)
181  *
182  *  @param plain_txt	    Plaintext key to be wrapped
183  *  @param txt_len          Length of the plain key in bytes (16 bytes)
184  *  @param cip_txt          Wrapped key
185  *  @param kek              Key encryption key (KEK)
186  *  @param kek_len          Length of KEK in bytes (must be divisible by 16)
187  *  @param iv               Encryption IV for CBC mode (16 bytes)
188  *
189  *  @return                 0 on success, -1 on failure
190  */
191 int nxp_aes_wrap(uint8_t *plain_txt, uint32_t txt_len, uint8_t *cip_txt, uint8_t *kek, uint32_t kek_len, uint8_t *iv);
192 
193 /**
194  *  @brief  Unwrap key with AES Key Wrap Algorithm (128-bit KEK)
195  *
196  *  @param cip_txt          Wrapped key to be unwrapped
197  *  @param txt_len          Length of the wrapped key in bytes (16 bytes)
198  *  @param plain_txt        Plaintext key
199  *  @param kek              Key encryption key (KEK)
200  *  @param kek_len          Length of KEK in bytes (must be divisible by 16)
201  *  @param iv               Encryption IV for CBC mode (16 bytes)
202  *
203  *  @return                 0 on success, -1 on failure
204  */
205 int nxp_aes_unwrap(uint8_t *cip_txt, uint32_t txt_len, uint8_t *plain_txt, uint8_t *kek, uint32_t kek_len, uint8_t *iv);
206 
207 /**********************************************************
208  *  ***   Extended AES Key Wrap Key
209  **********************************************************/
210 /**
211  *  @brief  Wrap keys with Extended AES Key Wrap Algorithm (128-bit KEK)
212  *
213  *  @param plain_txt	    Plaintext key to be wrapped
214  *  @param plain_len       Length of the plain key in bytes (16 bytes)
215  *  @param cip_txt          Wrapped key
216  *  @param kek              Key encryption key (KEK)
217  *  @param kek_Len          Length of KEK in bytes (must be divisible by 16)
218  *  @param iv               Encryption IV for CBC mode (16 bytes)
219  *
220  *  @return                 0 on success, -1 on failure
221  */
222 int nxp_aes_wrap_ext(
223     uint8_t *plain_txt, uint32_t plain_len, uint8_t *cip_txt, uint8_t *kek, uint32_t kek_Len, uint8_t *iv);
224 
225 /**
226  *  @brief  Unwrap key with Extended AES Key Wrap Algorithm (128-bit KEK)
227  *
228  *  @param cip_txt          Wrapped key to be unwrapped
229  *  @param cip_Len          Length of the wrapped key in bytes (16 bytes)
230  *  @param plain_txt        Plaintext key
231  *  @param kek              Key encryption key (KEK)
232  *  @param key_len          Length of KEK in bytes (must be divisible by 16)
233  *  @param iv               Encryption IV for CBC mode (16 bytes)
234  *
235  *  @return                 0 on success, -1 on failure
236  */
237 int nxp_aes_unwrap_ext(
238     uint8_t *cip_txt, uint32_t cip_Len, uint8_t *plain_txt, uint8_t *kek, uint32_t key_len, uint8_t *iv);
239 
240 /**
241  *  @brief  Wrapper function for HMAC-MD5
242  *
243  *  @param input            Pointer to input data
244  *  @param len              Length of input data
245  *  @param hash		    Pointer to hash
246  *  @param hash_key	    Pointer to hash key
247  *
248  *  @return                 None
249  */
250 void nxp_crypto_hmac_md5(uint8_t *input, int len, uint8_t *hash, char *hash_key);
251 
252 /**
253  *  @brief  Wrapper function for MD5
254  *
255  *  @param input            Pointer to input data
256  *  @param len              Length of input data
257  *  @param hash	            Pointer to hash
258  *  @param hlen		    Pointer to hash len
259  *
260  *  @return                 None
261  */
262 void nxp_crypto_md5(uint8_t *input, int len, uint8_t *hash, int hlen);
263 
264 /**
265  *  @brief  Wrapper function for PBKDF2
266  *
267  *  @param password         Pointer to password
268  *  @param ssid             Pointer to ssid
269  *  @param ssidlength	    Length of ssid
270  *  @param iterations	    No if iterations
271  *  @param output_len       Length of output data
272  *  @param output           Pointer to output data
273  *
274  *  @return                 None
275  */
276 void nxp_crypto_pass_to_key(
277     char *password, unsigned char *ssid, int ssidlength, int iterations, int output_len, unsigned char *output);
278 
279 int nxp_sha1_prf(const uint8_t *key,
280                  size_t key_len,
281                  const char *label,
282                  const uint8_t *data,
283                  size_t data_len,
284                  uint8_t *buf,
285                  size_t buf_len);
286 
287 int aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher);
288 
289 int aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain);
290 
291 int hmac_sha1(const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, uint8_t *mac, size_t maclen);
292 
293 int nxp_tls_prf(const uint8_t *secret,
294                 size_t secret_len,
295                 const char *label,
296                 const uint8_t *seed,
297                 size_t seed_len,
298                 uint8_t *out,
299                 size_t outlen);
300 
301 void nxp_hmac_md5(
302     const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, uint8_t *mac, size_t maclen);
303 
304 int nxp_generate_psk(const char *ssid, int ssid_len, const char *passphrase, char *output);
305 
306 #endif
307