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