Coverage Report

Created: 2025-10-28 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hostap/src/crypto/crypto_internal.c
Line
Count
Source
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
#include "includes.h"
10
11
#include "common.h"
12
#include "crypto.h"
13
#include "sha256_i.h"
14
#include "sha384_i.h"
15
#include "sha512_i.h"
16
#include "sha1_i.h"
17
#include "md5_i.h"
18
19
struct crypto_hash {
20
  enum crypto_hash_alg alg;
21
  union {
22
    struct MD5Context md5;
23
    struct SHA1Context sha1;
24
#ifdef CONFIG_SHA256
25
    struct sha256_state sha256;
26
#endif /* CONFIG_SHA256 */
27
#ifdef CONFIG_INTERNAL_SHA384
28
    struct sha384_state sha384;
29
#endif /* CONFIG_INTERNAL_SHA384 */
30
#ifdef CONFIG_INTERNAL_SHA512
31
    struct sha512_state sha512;
32
#endif /* CONFIG_INTERNAL_SHA512 */
33
  } u;
34
  u8 key[64];
35
  size_t key_len;
36
};
37
38
39
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
40
              size_t key_len)
41
0
{
42
0
  struct crypto_hash *ctx;
43
0
  u8 k_pad[64];
44
0
  u8 tk[32];
45
0
  size_t i;
46
47
0
  ctx = os_zalloc(sizeof(*ctx));
48
0
  if (ctx == NULL)
49
0
    return NULL;
50
51
0
  ctx->alg = alg;
52
53
0
  switch (alg) {
54
0
  case CRYPTO_HASH_ALG_MD5:
55
0
    MD5Init(&ctx->u.md5);
56
0
    break;
57
0
  case CRYPTO_HASH_ALG_SHA1:
58
0
    SHA1Init(&ctx->u.sha1);
59
0
    break;
60
0
#ifdef CONFIG_SHA256
61
0
  case CRYPTO_HASH_ALG_SHA256:
62
0
    sha256_init(&ctx->u.sha256);
63
0
    break;
64
0
#endif /* CONFIG_SHA256 */
65
0
#ifdef CONFIG_INTERNAL_SHA384
66
0
  case CRYPTO_HASH_ALG_SHA384:
67
0
    sha384_init(&ctx->u.sha384);
68
0
    break;
69
0
#endif /* CONFIG_INTERNAL_SHA384 */
70
#ifdef CONFIG_INTERNAL_SHA512
71
  case CRYPTO_HASH_ALG_SHA512:
72
    sha512_init(&ctx->u.sha512);
73
    break;
74
#endif /* CONFIG_INTERNAL_SHA512 */
75
0
  case CRYPTO_HASH_ALG_HMAC_MD5:
76
0
    if (key_len > sizeof(k_pad)) {
77
0
      MD5Init(&ctx->u.md5);
78
0
      MD5Update(&ctx->u.md5, key, key_len);
79
0
      MD5Final(tk, &ctx->u.md5);
80
0
      key = tk;
81
0
      key_len = 16;
82
0
    }
83
0
    os_memcpy(ctx->key, key, key_len);
84
0
    ctx->key_len = key_len;
85
86
0
    os_memcpy(k_pad, key, key_len);
87
0
    if (key_len < sizeof(k_pad))
88
0
      os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
89
0
    for (i = 0; i < sizeof(k_pad); i++)
90
0
      k_pad[i] ^= 0x36;
91
0
    MD5Init(&ctx->u.md5);
92
0
    MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
93
0
    break;
94
0
  case CRYPTO_HASH_ALG_HMAC_SHA1:
95
0
    if (key_len > sizeof(k_pad)) {
96
0
      SHA1Init(&ctx->u.sha1);
97
0
      SHA1Update(&ctx->u.sha1, key, key_len);
98
0
      SHA1Final(tk, &ctx->u.sha1);
99
0
      key = tk;
100
0
      key_len = 20;
101
0
    }
102
0
    os_memcpy(ctx->key, key, key_len);
103
0
    ctx->key_len = key_len;
104
105
0
    os_memcpy(k_pad, key, key_len);
106
0
    if (key_len < sizeof(k_pad))
107
0
      os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
108
0
    for (i = 0; i < sizeof(k_pad); i++)
109
0
      k_pad[i] ^= 0x36;
110
0
    SHA1Init(&ctx->u.sha1);
111
0
    SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
112
0
    break;
113
0
#ifdef CONFIG_SHA256
114
0
  case CRYPTO_HASH_ALG_HMAC_SHA256:
115
0
    if (key_len > sizeof(k_pad)) {
116
0
      sha256_init(&ctx->u.sha256);
117
0
      sha256_process(&ctx->u.sha256, key, key_len);
118
0
      sha256_done(&ctx->u.sha256, tk);
119
0
      key = tk;
120
0
      key_len = 32;
121
0
    }
122
0
    os_memcpy(ctx->key, key, key_len);
123
0
    ctx->key_len = key_len;
124
125
0
    os_memcpy(k_pad, key, key_len);
126
0
    if (key_len < sizeof(k_pad))
127
0
      os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
128
0
    for (i = 0; i < sizeof(k_pad); i++)
129
0
      k_pad[i] ^= 0x36;
130
0
    sha256_init(&ctx->u.sha256);
131
0
    sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad));
132
0
    break;
133
0
#endif /* CONFIG_SHA256 */
134
0
  default:
135
0
    os_free(ctx);
136
0
    return NULL;
137
0
  }
138
139
0
  return ctx;
140
0
}
141
142
143
void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
144
0
{
145
0
  if (ctx == NULL)
146
0
    return;
147
148
0
  switch (ctx->alg) {
149
0
  case CRYPTO_HASH_ALG_MD5:
150
0
  case CRYPTO_HASH_ALG_HMAC_MD5:
151
0
    MD5Update(&ctx->u.md5, data, len);
152
0
    break;
153
0
  case CRYPTO_HASH_ALG_SHA1:
154
0
  case CRYPTO_HASH_ALG_HMAC_SHA1:
155
0
    SHA1Update(&ctx->u.sha1, data, len);
156
0
    break;
157
0
#ifdef CONFIG_SHA256
158
0
  case CRYPTO_HASH_ALG_SHA256:
159
0
  case CRYPTO_HASH_ALG_HMAC_SHA256:
160
0
    sha256_process(&ctx->u.sha256, data, len);
161
0
    break;
162
0
#endif /* CONFIG_SHA256 */
163
0
#ifdef CONFIG_INTERNAL_SHA384
164
0
  case CRYPTO_HASH_ALG_SHA384:
165
0
    sha384_process(&ctx->u.sha384, data, len);
166
0
    break;
167
0
#endif /* CONFIG_INTERNAL_SHA384 */
168
#ifdef CONFIG_INTERNAL_SHA512
169
  case CRYPTO_HASH_ALG_SHA512:
170
    sha512_process(&ctx->u.sha512, data, len);
171
    break;
172
#endif /* CONFIG_INTERNAL_SHA512 */
173
0
  default:
174
0
    break;
175
0
  }
176
0
}
177
178
179
int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
180
0
{
181
0
  u8 k_pad[64];
182
0
  size_t i;
183
184
0
  if (ctx == NULL)
185
0
    return -2;
186
187
0
  if (mac == NULL || len == NULL) {
188
0
    os_free(ctx);
189
0
    return 0;
190
0
  }
191
192
0
  switch (ctx->alg) {
193
0
  case CRYPTO_HASH_ALG_MD5:
194
0
    if (*len < 16) {
195
0
      *len = 16;
196
0
      os_free(ctx);
197
0
      return -1;
198
0
    }
199
0
    *len = 16;
200
0
    MD5Final(mac, &ctx->u.md5);
201
0
    break;
202
0
  case CRYPTO_HASH_ALG_SHA1:
203
0
    if (*len < 20) {
204
0
      *len = 20;
205
0
      os_free(ctx);
206
0
      return -1;
207
0
    }
208
0
    *len = 20;
209
0
    SHA1Final(mac, &ctx->u.sha1);
210
0
    break;
211
0
#ifdef CONFIG_SHA256
212
0
  case CRYPTO_HASH_ALG_SHA256:
213
0
    if (*len < 32) {
214
0
      *len = 32;
215
0
      os_free(ctx);
216
0
      return -1;
217
0
    }
218
0
    *len = 32;
219
0
    sha256_done(&ctx->u.sha256, mac);
220
0
    break;
221
0
#endif /* CONFIG_SHA256 */
222
0
#ifdef CONFIG_INTERNAL_SHA384
223
0
  case CRYPTO_HASH_ALG_SHA384:
224
0
    if (*len < 48) {
225
0
      *len = 48;
226
0
      os_free(ctx);
227
0
      return -1;
228
0
    }
229
0
    *len = 48;
230
0
    sha384_done(&ctx->u.sha384, mac);
231
0
    break;
232
0
#endif /* CONFIG_INTERNAL_SHA384 */
233
#ifdef CONFIG_INTERNAL_SHA512
234
  case CRYPTO_HASH_ALG_SHA512:
235
    if (*len < 64) {
236
      *len = 64;
237
      os_free(ctx);
238
      return -1;
239
    }
240
    *len = 64;
241
    sha512_done(&ctx->u.sha512, mac);
242
    break;
243
#endif /* CONFIG_INTERNAL_SHA512 */
244
0
  case CRYPTO_HASH_ALG_HMAC_MD5:
245
0
    if (*len < 16) {
246
0
      *len = 16;
247
0
      os_free(ctx);
248
0
      return -1;
249
0
    }
250
0
    *len = 16;
251
252
0
    MD5Final(mac, &ctx->u.md5);
253
254
0
    os_memcpy(k_pad, ctx->key, ctx->key_len);
255
0
    os_memset(k_pad + ctx->key_len, 0,
256
0
        sizeof(k_pad) - ctx->key_len);
257
0
    for (i = 0; i < sizeof(k_pad); i++)
258
0
      k_pad[i] ^= 0x5c;
259
0
    MD5Init(&ctx->u.md5);
260
0
    MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
261
0
    MD5Update(&ctx->u.md5, mac, 16);
262
0
    MD5Final(mac, &ctx->u.md5);
263
0
    break;
264
0
  case CRYPTO_HASH_ALG_HMAC_SHA1:
265
0
    if (*len < 20) {
266
0
      *len = 20;
267
0
      os_free(ctx);
268
0
      return -1;
269
0
    }
270
0
    *len = 20;
271
272
0
    SHA1Final(mac, &ctx->u.sha1);
273
274
0
    os_memcpy(k_pad, ctx->key, ctx->key_len);
275
0
    os_memset(k_pad + ctx->key_len, 0,
276
0
        sizeof(k_pad) - ctx->key_len);
277
0
    for (i = 0; i < sizeof(k_pad); i++)
278
0
      k_pad[i] ^= 0x5c;
279
0
    SHA1Init(&ctx->u.sha1);
280
0
    SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
281
0
    SHA1Update(&ctx->u.sha1, mac, 20);
282
0
    SHA1Final(mac, &ctx->u.sha1);
283
0
    break;
284
0
#ifdef CONFIG_SHA256
285
0
  case CRYPTO_HASH_ALG_HMAC_SHA256:
286
0
    if (*len < 32) {
287
0
      *len = 32;
288
0
      os_free(ctx);
289
0
      return -1;
290
0
    }
291
0
    *len = 32;
292
293
0
    sha256_done(&ctx->u.sha256, mac);
294
295
0
    os_memcpy(k_pad, ctx->key, ctx->key_len);
296
0
    os_memset(k_pad + ctx->key_len, 0,
297
0
        sizeof(k_pad) - ctx->key_len);
298
0
    for (i = 0; i < sizeof(k_pad); i++)
299
0
      k_pad[i] ^= 0x5c;
300
0
    sha256_init(&ctx->u.sha256);
301
0
    sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad));
302
0
    sha256_process(&ctx->u.sha256, mac, 32);
303
0
    sha256_done(&ctx->u.sha256, mac);
304
0
    break;
305
0
#endif /* CONFIG_SHA256 */
306
0
  default:
307
0
    os_free(ctx);
308
0
    return -1;
309
0
  }
310
311
0
  os_free(ctx);
312
313
0
  if (TEST_FAIL())
314
0
    return -1;
315
316
0
  return 0;
317
0
}
318
319
320
int crypto_global_init(void)
321
3.76k
{
322
3.76k
  return 0;
323
3.76k
}
324
325
326
void crypto_global_deinit(void)
327
3.76k
{
328
3.76k
}
329
330
331
void crypto_unload(void)
332
0
{
333
0
}