1 /*
2  * Crypto wrapper for internal crypto implementation
3  * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 /*
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Hardware crypto support Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 #include "utils/includes.h"
25 #include "utils/common.h"
26 #include "crypto.h"
27 #include "sha1_i.h"
28 #include "md5_i.h"
29 #ifdef USE_MBEDTLS_CRYPTO
30 #include "mbedtls/sha256.h"
31 #else
32 #include "sha256_i.h"
33 #endif
34 
35 struct crypto_hash {
36 	enum crypto_hash_alg alg;
37 	union {
38 		struct MD5Context md5;
39 		struct SHA1Context sha1;
40 #ifdef CONFIG_SHA256
41 #ifdef USE_MBEDTLS_CRYPTO
42 		mbedtls_sha256_context sha256;
43 #else /* USE_MBEDTLS_CRYPTO */
44 		struct sha256_state sha256;
45 #endif /* USE_MBEDTLS_CRYPTO */
46 #endif /* CONFIG_SHA256 */
47 	} u;
48 	u8 key[64];
49 	size_t key_len;
50 };
51 
52 
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)53 struct crypto_hash *  crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
54 				      size_t key_len)
55 {
56 	struct crypto_hash *ctx;
57 	u8 k_pad[64];
58 	u8 tk[32];
59 	size_t i;
60 
61 	ctx = (struct crypto_hash *)os_zalloc(sizeof(*ctx));
62 	if (ctx == NULL)
63 		return NULL;
64 
65 	ctx->alg = alg;
66 
67 	switch (alg) {
68 	case CRYPTO_HASH_ALG_MD5:
69 		MD5Init(&ctx->u.md5);
70 		break;
71 	case CRYPTO_HASH_ALG_SHA1:
72 		SHA1Init(&ctx->u.sha1);
73 		break;
74 #ifdef CONFIG_SHA256
75 	case CRYPTO_HASH_ALG_SHA256:
76 #ifdef USE_MBEDTLS_CRYPTO
77 		mbedtls_sha256_init(&ctx->u.sha256);
78 		mbedtls_sha256_starts_ret(&ctx->u.sha256, 0);
79 #else /* USE_MBEDTLS_CRYPTO */
80 		sha256_init(&ctx->u.sha256);
81 #endif /* USE_MBEDTLS_CRYPTO */
82 		break;
83 #endif /* CONFIG_SHA256 */
84 	case CRYPTO_HASH_ALG_HMAC_MD5:
85 		if (key_len > sizeof(k_pad)) {
86 			MD5Init(&ctx->u.md5);
87 			MD5Update(&ctx->u.md5, key, key_len);
88 			MD5Final(tk, &ctx->u.md5);
89 			key = tk;
90 			key_len = 16;
91 		}
92 		os_memcpy(ctx->key, key, key_len);
93 		ctx->key_len = key_len;
94 
95 		os_memcpy(k_pad, key, key_len);
96 		if (key_len < sizeof(k_pad))
97 			os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
98 		for (i = 0; i < sizeof(k_pad); i++)
99 			k_pad[i] ^= 0x36;
100 		MD5Init(&ctx->u.md5);
101 		MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
102 		break;
103 	case CRYPTO_HASH_ALG_HMAC_SHA1:
104 		if (key_len > sizeof(k_pad)) {
105 			SHA1Init(&ctx->u.sha1);
106 			SHA1Update(&ctx->u.sha1, key, key_len);
107 			SHA1Final(tk, &ctx->u.sha1);
108 			key = tk;
109 			key_len = 20;
110 		}
111 		os_memcpy(ctx->key, key, key_len);
112 		ctx->key_len = key_len;
113 
114 		os_memcpy(k_pad, key, key_len);
115 		if (key_len < sizeof(k_pad))
116 			os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
117 		for (i = 0; i < sizeof(k_pad); i++)
118 			k_pad[i] ^= 0x36;
119 		SHA1Init(&ctx->u.sha1);
120 		SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
121 		break;
122 #ifdef CONFIG_SHA256
123 	case CRYPTO_HASH_ALG_HMAC_SHA256:
124 		if (key_len > sizeof(k_pad)) {
125 #ifdef USE_MBEDTLS_CRYPTO
126 			mbedtls_sha256_init(&ctx->u.sha256);
127 			mbedtls_sha256_starts_ret(&ctx->u.sha256, 0);
128 			mbedtls_sha256_update_ret(&ctx->u.sha256, key, key_len);
129 			mbedtls_sha256_finish_ret(&ctx->u.sha256, tk);
130 			mbedtls_sha256_free(&ctx->u.sha256);
131 #else /* USE_MBEDTLS_CRYPTO */
132 			sha256_init(&ctx->u.sha256);
133 			sha256_process(&ctx->u.sha256, key, key_len);
134 			sha256_done(&ctx->u.sha256, tk);
135 #endif /* USE_MBEDTLS_CRYPTO */
136 			key = tk;
137 			key_len = 32;
138 		}
139 		os_memcpy(ctx->key, key, key_len);
140 		ctx->key_len = key_len;
141 
142 		os_memcpy(k_pad, key, key_len);
143 		if (key_len < sizeof(k_pad))
144 			os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
145 		for (i = 0; i < sizeof(k_pad); i++)
146 			k_pad[i] ^= 0x36;
147 #ifdef USE_MBEDTLS_CRYPTO
148 		mbedtls_sha256_init(&ctx->u.sha256);
149 		mbedtls_sha256_starts_ret(&ctx->u.sha256, 0);
150 		mbedtls_sha256_update_ret(&ctx->u.sha256, k_pad, sizeof(k_pad));
151 #else /* USE_MBEDTLS_CRYPTO */
152 		sha256_init(&ctx->u.sha256);
153 		sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad));
154 #endif /* USE_MBEDTLS_CRYPTO */
155 		break;
156 #endif /* CONFIG_SHA256 */
157 	default:
158 		os_free(ctx);
159 		return NULL;
160 	}
161 
162 	return ctx;
163 }
164 
165 
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)166 void  crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
167 {
168 	if (ctx == NULL)
169 		return;
170 
171 	switch (ctx->alg) {
172 	case CRYPTO_HASH_ALG_MD5:
173 	case CRYPTO_HASH_ALG_HMAC_MD5:
174 		MD5Update(&ctx->u.md5, data, len);
175 		break;
176 	case CRYPTO_HASH_ALG_SHA1:
177 	case CRYPTO_HASH_ALG_HMAC_SHA1:
178 		SHA1Update(&ctx->u.sha1, data, len);
179 		break;
180 #ifdef CONFIG_SHA256
181 	case CRYPTO_HASH_ALG_SHA256:
182 	case CRYPTO_HASH_ALG_HMAC_SHA256:
183 #ifdef USE_MBEDTLS_CRYPTO
184 		mbedtls_sha256_update_ret(&ctx->u.sha256, data, len);
185 #else /* USE_MBEDTLS_CRYPTO */
186 		sha256_process(&ctx->u.sha256, data, len);
187 #endif /* USE_MBEDTLS_CRYPTO */
188 		break;
189 #endif /* CONFIG_SHA256 */
190 	default:
191 		break;
192 	}
193 }
194 
195 
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)196 int  crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
197 {
198 	u8 k_pad[64];
199 	size_t i;
200 
201 	if (ctx == NULL)
202 		return -2;
203 
204 	if (mac == NULL || len == NULL) {
205 		os_free(ctx);
206 		return 0;
207 	}
208 
209 	switch (ctx->alg) {
210 	case CRYPTO_HASH_ALG_MD5:
211 		if (*len < 16) {
212 			*len = 16;
213 			os_free(ctx);
214 			return -1;
215 		}
216 		*len = 16;
217 		MD5Final(mac, &ctx->u.md5);
218 		break;
219 	case CRYPTO_HASH_ALG_SHA1:
220 		if (*len < 20) {
221 			*len = 20;
222 			os_free(ctx);
223 			return -1;
224 		}
225 		*len = 20;
226 		SHA1Final(mac, &ctx->u.sha1);
227 		break;
228 #ifdef CONFIG_SHA256
229 	case CRYPTO_HASH_ALG_SHA256:
230 		if (*len < 32) {
231 			*len = 32;
232 			os_free(ctx);
233 			return -1;
234 		}
235 		*len = 32;
236 #ifdef USE_MBEDTLS_CRYPTO
237 		mbedtls_sha256_finish_ret(&ctx->u.sha256, mac);
238 		mbedtls_sha256_free(&ctx->u.sha256);
239 #else /* USE_MBEDTLS_CRYPTO */
240 		sha256_done(&ctx->u.sha256, mac);
241 #endif /* USE_MBEDTLS_CRYPTO */
242 		break;
243 #endif /* CONFIG_SHA256 */
244 	case CRYPTO_HASH_ALG_HMAC_MD5:
245 		if (*len < 16) {
246 			*len = 16;
247 			os_free(ctx);
248 			return -1;
249 		}
250 		*len = 16;
251 
252 		MD5Final(mac, &ctx->u.md5);
253 
254 		os_memcpy(k_pad, ctx->key, ctx->key_len);
255 		os_memset(k_pad + ctx->key_len, 0,
256 			  sizeof(k_pad) - ctx->key_len);
257 		for (i = 0; i < sizeof(k_pad); i++)
258 			k_pad[i] ^= 0x5c;
259 		MD5Init(&ctx->u.md5);
260 		MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
261 		MD5Update(&ctx->u.md5, mac, 16);
262 		MD5Final(mac, &ctx->u.md5);
263 		break;
264 	case CRYPTO_HASH_ALG_HMAC_SHA1:
265 		if (*len < 20) {
266 			*len = 20;
267 			os_free(ctx);
268 			return -1;
269 		}
270 		*len = 20;
271 
272 		SHA1Final(mac, &ctx->u.sha1);
273 
274 		os_memcpy(k_pad, ctx->key, ctx->key_len);
275 		os_memset(k_pad + ctx->key_len, 0,
276 			  sizeof(k_pad) - ctx->key_len);
277 		for (i = 0; i < sizeof(k_pad); i++)
278 			k_pad[i] ^= 0x5c;
279 		SHA1Init(&ctx->u.sha1);
280 		SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
281 		SHA1Update(&ctx->u.sha1, mac, 20);
282 		SHA1Final(mac, &ctx->u.sha1);
283 		break;
284 #ifdef CONFIG_SHA256
285 	case CRYPTO_HASH_ALG_HMAC_SHA256:
286 		if (*len < 32) {
287 			*len = 32;
288 			os_free(ctx);
289 			return -1;
290 		}
291 		*len = 32;
292 
293 #ifdef USE_MBEDTLS_CRYPTO
294 		mbedtls_sha256_finish_ret(&ctx->u.sha256, mac);
295 		mbedtls_sha256_free(&ctx->u.sha256);
296 #else /* USE_MBEDTLS_CRYPTO */
297 		sha256_done(&ctx->u.sha256, mac);
298 #endif /* USE_MBEDTLS_CRYPTO */
299 
300 		os_memcpy(k_pad, ctx->key, ctx->key_len);
301 		os_memset(k_pad + ctx->key_len, 0,
302 			  sizeof(k_pad) - ctx->key_len);
303 		for (i = 0; i < sizeof(k_pad); i++)
304 			k_pad[i] ^= 0x5c;
305 #ifdef USE_MBEDTLS_CRYPTO
306 		mbedtls_sha256_init(&ctx->u.sha256);
307 		mbedtls_sha256_starts_ret(&ctx->u.sha256, 0);
308 		mbedtls_sha256_update_ret(&ctx->u.sha256, k_pad, sizeof(k_pad));
309 		mbedtls_sha256_update_ret(&ctx->u.sha256, mac, 32);
310 		mbedtls_sha256_finish_ret(&ctx->u.sha256, mac);
311 		mbedtls_sha256_free(&ctx->u.sha256);
312 #else /* USE_MBEDTLS_CRYPTO */
313 		sha256_init(&ctx->u.sha256);
314 		sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad));
315 		sha256_process(&ctx->u.sha256, mac, 32);
316 		sha256_done(&ctx->u.sha256, mac);
317 #endif /* USE_MBEDTLS_CRYPTO */
318 		break;
319 #endif /* CONFIG_SHA256 */
320 	default:
321 		os_free(ctx);
322 		return -1;
323 	}
324 
325 	os_free(ctx);
326 
327 	return 0;
328 }
329 
330 
crypto_global_init(void)331 int  crypto_global_init(void)
332 {
333 	return 0;
334 }
335 
336 
crypto_global_deinit(void)337 void  crypto_global_deinit(void)
338 {
339 }
340