Coverage Report

Created: 2025-08-29 06:25

/src/hostap/src/crypto/crypto_internal-cipher.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Crypto wrapper for internal crypto implementation - Cipher wrappers
3
 * Copyright (c) 2006-2009, 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 "aes.h"
14
#include "des_i.h"
15
16
17
struct crypto_cipher {
18
  enum crypto_cipher_alg alg;
19
  union {
20
    struct {
21
      size_t used_bytes;
22
      u8 key[16];
23
      size_t keylen;
24
    } rc4;
25
    struct {
26
      u8 cbc[32];
27
      void *ctx_enc;
28
      void *ctx_dec;
29
    } aes;
30
    struct {
31
      struct des3_key_s key;
32
      u8 cbc[8];
33
    } des3;
34
    struct {
35
      u32 ek[32];
36
      u32 dk[32];
37
      u8 cbc[8];
38
    } des;
39
  } u;
40
};
41
42
43
struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
44
            const u8 *iv, const u8 *key,
45
            size_t key_len)
46
794
{
47
794
  struct crypto_cipher *ctx;
48
49
794
  ctx = os_zalloc(sizeof(*ctx));
50
794
  if (ctx == NULL)
51
0
    return NULL;
52
53
794
  ctx->alg = alg;
54
55
794
  switch (alg) {
56
255
  case CRYPTO_CIPHER_ALG_RC4:
57
255
    if (key_len > sizeof(ctx->u.rc4.key)) {
58
0
      os_free(ctx);
59
0
      return NULL;
60
0
    }
61
255
    ctx->u.rc4.keylen = key_len;
62
255
    os_memcpy(ctx->u.rc4.key, key, key_len);
63
255
    break;
64
327
  case CRYPTO_CIPHER_ALG_AES:
65
327
    ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
66
327
    if (ctx->u.aes.ctx_enc == NULL) {
67
0
      os_free(ctx);
68
0
      return NULL;
69
0
    }
70
327
    ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
71
327
    if (ctx->u.aes.ctx_dec == NULL) {
72
0
      aes_encrypt_deinit(ctx->u.aes.ctx_enc);
73
0
      os_free(ctx);
74
0
      return NULL;
75
0
    }
76
327
    os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE);
77
327
    break;
78
212
  case CRYPTO_CIPHER_ALG_3DES:
79
212
    if (key_len != 24) {
80
0
      os_free(ctx);
81
0
      return NULL;
82
0
    }
83
212
    des3_key_setup(key, &ctx->u.des3.key);
84
212
    os_memcpy(ctx->u.des3.cbc, iv, 8);
85
212
    break;
86
0
  case CRYPTO_CIPHER_ALG_DES:
87
0
    if (key_len != 8) {
88
0
      os_free(ctx);
89
0
      return NULL;
90
0
    }
91
0
    des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
92
0
    os_memcpy(ctx->u.des.cbc, iv, 8);
93
0
    break;
94
0
  default:
95
0
    os_free(ctx);
96
0
    return NULL;
97
794
  }
98
99
794
  return ctx;
100
794
}
101
102
103
int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
104
        u8 *crypt, size_t len)
105
445
{
106
445
  size_t i, j, blocks;
107
108
445
  switch (ctx->alg) {
109
138
  case CRYPTO_CIPHER_ALG_RC4:
110
138
    if (plain != crypt)
111
0
      os_memcpy(crypt, plain, len);
112
138
    rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
113
138
       ctx->u.rc4.used_bytes, crypt, len);
114
138
    ctx->u.rc4.used_bytes += len;
115
138
    break;
116
194
  case CRYPTO_CIPHER_ALG_AES:
117
194
    if (len % AES_BLOCK_SIZE)
118
0
      return -1;
119
194
    blocks = len / AES_BLOCK_SIZE;
120
1.01k
    for (i = 0; i < blocks; i++) {
121
13.9k
      for (j = 0; j < AES_BLOCK_SIZE; j++)
122
13.1k
        ctx->u.aes.cbc[j] ^= plain[j];
123
822
      aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
124
822
            ctx->u.aes.cbc);
125
822
      os_memcpy(crypt, ctx->u.aes.cbc, AES_BLOCK_SIZE);
126
822
      plain += AES_BLOCK_SIZE;
127
822
      crypt += AES_BLOCK_SIZE;
128
822
    }
129
194
    break;
130
113
  case CRYPTO_CIPHER_ALG_3DES:
131
113
    if (len % 8)
132
0
      return -1;
133
113
    blocks = len / 8;
134
732
    for (i = 0; i < blocks; i++) {
135
5.57k
      for (j = 0; j < 8; j++)
136
4.95k
        ctx->u.des3.cbc[j] ^= plain[j];
137
619
      des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
138
619
             ctx->u.des3.cbc);
139
619
      os_memcpy(crypt, ctx->u.des3.cbc, 8);
140
619
      plain += 8;
141
619
      crypt += 8;
142
619
    }
143
113
    break;
144
0
  case CRYPTO_CIPHER_ALG_DES:
145
0
    if (len % 8)
146
0
      return -1;
147
0
    blocks = len / 8;
148
0
    for (i = 0; i < blocks; i++) {
149
0
      for (j = 0; j < 8; j++)
150
0
        ctx->u.des3.cbc[j] ^= plain[j];
151
0
      des_block_encrypt(ctx->u.des.cbc, ctx->u.des.ek,
152
0
            ctx->u.des.cbc);
153
0
      os_memcpy(crypt, ctx->u.des.cbc, 8);
154
0
      plain += 8;
155
0
      crypt += 8;
156
0
    }
157
0
    break;
158
0
  default:
159
0
    return -1;
160
445
  }
161
162
445
  return 0;
163
445
}
164
165
166
int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
167
        u8 *plain, size_t len)
168
16.4k
{
169
16.4k
  size_t i, j, blocks;
170
16.4k
  u8 tmp[32];
171
172
16.4k
  switch (ctx->alg) {
173
8.68k
  case CRYPTO_CIPHER_ALG_RC4:
174
8.68k
    if (plain != crypt)
175
8.68k
      os_memcpy(plain, crypt, len);
176
8.68k
    rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
177
8.68k
       ctx->u.rc4.used_bytes, plain, len);
178
8.68k
    ctx->u.rc4.used_bytes += len;
179
8.68k
    break;
180
5.05k
  case CRYPTO_CIPHER_ALG_AES:
181
5.05k
    if (len % AES_BLOCK_SIZE)
182
345
      return -1;
183
4.70k
    blocks = len / AES_BLOCK_SIZE;
184
19.0k
    for (i = 0; i < blocks; i++) {
185
14.3k
      os_memcpy(tmp, crypt, AES_BLOCK_SIZE);
186
14.3k
      aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
187
244k
      for (j = 0; j < AES_BLOCK_SIZE; j++)
188
230k
        plain[j] ^= ctx->u.aes.cbc[j];
189
14.3k
      os_memcpy(ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE);
190
14.3k
      plain += AES_BLOCK_SIZE;
191
14.3k
      crypt += AES_BLOCK_SIZE;
192
14.3k
    }
193
4.70k
    break;
194
2.69k
  case CRYPTO_CIPHER_ALG_3DES:
195
2.69k
    if (len % 8)
196
206
      return -1;
197
2.48k
    blocks = len / 8;
198
11.3k
    for (i = 0; i < blocks; i++) {
199
8.87k
      os_memcpy(tmp, crypt, 8);
200
8.87k
      des3_decrypt(crypt, &ctx->u.des3.key, plain);
201
79.9k
      for (j = 0; j < 8; j++)
202
71.0k
        plain[j] ^= ctx->u.des3.cbc[j];
203
8.87k
      os_memcpy(ctx->u.des3.cbc, tmp, 8);
204
8.87k
      plain += 8;
205
8.87k
      crypt += 8;
206
8.87k
    }
207
2.48k
    break;
208
0
  case CRYPTO_CIPHER_ALG_DES:
209
0
    if (len % 8)
210
0
      return -1;
211
0
    blocks = len / 8;
212
0
    for (i = 0; i < blocks; i++) {
213
0
      os_memcpy(tmp, crypt, 8);
214
0
      des_block_decrypt(crypt, ctx->u.des.dk, plain);
215
0
      for (j = 0; j < 8; j++)
216
0
        plain[j] ^= ctx->u.des.cbc[j];
217
0
      os_memcpy(ctx->u.des.cbc, tmp, 8);
218
0
      plain += 8;
219
0
      crypt += 8;
220
0
    }
221
0
    break;
222
0
  default:
223
0
    return -1;
224
16.4k
  }
225
226
15.8k
  return 0;
227
16.4k
}
228
229
230
void crypto_cipher_deinit(struct crypto_cipher *ctx)
231
794
{
232
794
  switch (ctx->alg) {
233
327
  case CRYPTO_CIPHER_ALG_AES:
234
327
    aes_encrypt_deinit(ctx->u.aes.ctx_enc);
235
327
    aes_decrypt_deinit(ctx->u.aes.ctx_dec);
236
327
    break;
237
212
  case CRYPTO_CIPHER_ALG_3DES:
238
212
    break;
239
255
  default:
240
255
    break;
241
794
  }
242
794
  os_free(ctx);
243
794
}