Coverage Report

Created: 2025-04-24 06:18

/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
0
{
47
0
  struct crypto_cipher *ctx;
48
49
0
  ctx = os_zalloc(sizeof(*ctx));
50
0
  if (ctx == NULL)
51
0
    return NULL;
52
53
0
  ctx->alg = alg;
54
55
0
  switch (alg) {
56
0
  case CRYPTO_CIPHER_ALG_RC4:
57
0
    if (key_len > sizeof(ctx->u.rc4.key)) {
58
0
      os_free(ctx);
59
0
      return NULL;
60
0
    }
61
0
    ctx->u.rc4.keylen = key_len;
62
0
    os_memcpy(ctx->u.rc4.key, key, key_len);
63
0
    break;
64
0
  case CRYPTO_CIPHER_ALG_AES:
65
0
    ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
66
0
    if (ctx->u.aes.ctx_enc == NULL) {
67
0
      os_free(ctx);
68
0
      return NULL;
69
0
    }
70
0
    ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
71
0
    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
0
    os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE);
77
0
    break;
78
0
  case CRYPTO_CIPHER_ALG_3DES:
79
0
    if (key_len != 24) {
80
0
      os_free(ctx);
81
0
      return NULL;
82
0
    }
83
0
    des3_key_setup(key, &ctx->u.des3.key);
84
0
    os_memcpy(ctx->u.des3.cbc, iv, 8);
85
0
    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
0
  }
98
99
0
  return ctx;
100
0
}
101
102
103
int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
104
        u8 *crypt, size_t len)
105
0
{
106
0
  size_t i, j, blocks;
107
108
0
  switch (ctx->alg) {
109
0
  case CRYPTO_CIPHER_ALG_RC4:
110
0
    if (plain != crypt)
111
0
      os_memcpy(crypt, plain, len);
112
0
    rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
113
0
       ctx->u.rc4.used_bytes, crypt, len);
114
0
    ctx->u.rc4.used_bytes += len;
115
0
    break;
116
0
  case CRYPTO_CIPHER_ALG_AES:
117
0
    if (len % AES_BLOCK_SIZE)
118
0
      return -1;
119
0
    blocks = len / AES_BLOCK_SIZE;
120
0
    for (i = 0; i < blocks; i++) {
121
0
      for (j = 0; j < AES_BLOCK_SIZE; j++)
122
0
        ctx->u.aes.cbc[j] ^= plain[j];
123
0
      aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
124
0
            ctx->u.aes.cbc);
125
0
      os_memcpy(crypt, ctx->u.aes.cbc, AES_BLOCK_SIZE);
126
0
      plain += AES_BLOCK_SIZE;
127
0
      crypt += AES_BLOCK_SIZE;
128
0
    }
129
0
    break;
130
0
  case CRYPTO_CIPHER_ALG_3DES:
131
0
    if (len % 8)
132
0
      return -1;
133
0
    blocks = len / 8;
134
0
    for (i = 0; i < blocks; i++) {
135
0
      for (j = 0; j < 8; j++)
136
0
        ctx->u.des3.cbc[j] ^= plain[j];
137
0
      des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
138
0
             ctx->u.des3.cbc);
139
0
      os_memcpy(crypt, ctx->u.des3.cbc, 8);
140
0
      plain += 8;
141
0
      crypt += 8;
142
0
    }
143
0
    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
0
  }
161
162
0
  return 0;
163
0
}
164
165
166
int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
167
        u8 *plain, size_t len)
168
0
{
169
0
  size_t i, j, blocks;
170
0
  u8 tmp[32];
171
172
0
  switch (ctx->alg) {
173
0
  case CRYPTO_CIPHER_ALG_RC4:
174
0
    if (plain != crypt)
175
0
      os_memcpy(plain, crypt, len);
176
0
    rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
177
0
       ctx->u.rc4.used_bytes, plain, len);
178
0
    ctx->u.rc4.used_bytes += len;
179
0
    break;
180
0
  case CRYPTO_CIPHER_ALG_AES:
181
0
    if (len % AES_BLOCK_SIZE)
182
0
      return -1;
183
0
    blocks = len / AES_BLOCK_SIZE;
184
0
    for (i = 0; i < blocks; i++) {
185
0
      os_memcpy(tmp, crypt, AES_BLOCK_SIZE);
186
0
      aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
187
0
      for (j = 0; j < AES_BLOCK_SIZE; j++)
188
0
        plain[j] ^= ctx->u.aes.cbc[j];
189
0
      os_memcpy(ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE);
190
0
      plain += AES_BLOCK_SIZE;
191
0
      crypt += AES_BLOCK_SIZE;
192
0
    }
193
0
    break;
194
0
  case CRYPTO_CIPHER_ALG_3DES:
195
0
    if (len % 8)
196
0
      return -1;
197
0
    blocks = len / 8;
198
0
    for (i = 0; i < blocks; i++) {
199
0
      os_memcpy(tmp, crypt, 8);
200
0
      des3_decrypt(crypt, &ctx->u.des3.key, plain);
201
0
      for (j = 0; j < 8; j++)
202
0
        plain[j] ^= ctx->u.des3.cbc[j];
203
0
      os_memcpy(ctx->u.des3.cbc, tmp, 8);
204
0
      plain += 8;
205
0
      crypt += 8;
206
0
    }
207
0
    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
0
  }
225
226
0
  return 0;
227
0
}
228
229
230
void crypto_cipher_deinit(struct crypto_cipher *ctx)
231
0
{
232
0
  switch (ctx->alg) {
233
0
  case CRYPTO_CIPHER_ALG_AES:
234
0
    aes_encrypt_deinit(ctx->u.aes.ctx_enc);
235
0
    aes_decrypt_deinit(ctx->u.aes.ctx_dec);
236
0
    break;
237
0
  case CRYPTO_CIPHER_ALG_3DES:
238
0
    break;
239
0
  default:
240
0
    break;
241
0
  }
242
0
  os_free(ctx);
243
0
}