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 * 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/common.h"
25 #include "utils/includes.h"
26 #include "crypto.h"
27 #include "aes.h"
28 #if defined(CONFIG_DES) || defined(CONFIG_DES3)
29 #include "des_i.h"
30 #endif
31 #ifdef USE_MBEDTLS_CRYPTO
32 #include "mbedtls/aes.h"
33 #endif /* USE_MBEDTLS_CRYPTO */
34
35 struct crypto_cipher {
36 enum crypto_cipher_alg alg;
37 union {
38 struct {
39 size_t used_bytes;
40 u8 key[16];
41 size_t keylen;
42 } rc4;
43 struct {
44 u8 cbc[32];
45 #ifdef USE_MBEDTLS_CRYPTO
46 mbedtls_aes_context ctx_enc;
47 mbedtls_aes_context ctx_dec;
48 #else /* USE_MBEDTLS_CRYPTO */
49 void *ctx_enc;
50 void *ctx_dec;
51 #endif /* USE_MBEDTLS_CRYPTO */
52 } aes;
53 #ifdef CONFIG_DES3
54 struct {
55 struct des3_key_s key;
56 u8 cbc[8];
57 } des3;
58 #endif
59 #ifdef CONFIG_DES
60 struct {
61 u32 ek[32];
62 u32 dk[32];
63 u8 cbc[8];
64 } des;
65 #endif
66 } u;
67 };
68
69
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)70 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
71 const u8 *iv, const u8 *key,
72 size_t key_len)
73 {
74 struct crypto_cipher *ctx;
75
76 ctx = (struct crypto_cipher *)os_zalloc(sizeof(*ctx));
77 if (ctx == NULL)
78 return NULL;
79
80 ctx->alg = alg;
81
82 switch (alg) {
83 case CRYPTO_CIPHER_ALG_RC4:
84 if (key_len > sizeof(ctx->u.rc4.key)) {
85 os_free(ctx);
86 return NULL;
87 }
88 ctx->u.rc4.keylen = key_len;
89 os_memcpy(ctx->u.rc4.key, key, key_len);
90 break;
91 case CRYPTO_CIPHER_ALG_AES:
92 #ifdef USE_MBEDTLS_CRYPTO
93 mbedtls_aes_init(&(ctx->u.aes.ctx_enc));
94 mbedtls_aes_setkey_enc(&(ctx->u.aes.ctx_enc), key, key_len * 8);
95 mbedtls_aes_init(&(ctx->u.aes.ctx_dec));
96 mbedtls_aes_setkey_dec(&(ctx->u.aes.ctx_dec), key, key_len * 8);
97 #else /* USE_MBEDTLS_CRYPTO */
98 ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
99 if (ctx->u.aes.ctx_enc == NULL) {
100 os_free(ctx);
101 return NULL;
102 }
103 ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
104 if (ctx->u.aes.ctx_dec == NULL) {
105 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
106 os_free(ctx);
107 return NULL;
108 }
109 #endif /* USE_MBEDTLS_CRYPTO */
110 os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE);
111 break;
112 #ifdef CONFIG_DES3
113 case CRYPTO_CIPHER_ALG_3DES:
114 if (key_len != 24) {
115 os_free(ctx);
116 return NULL;
117 }
118 des3_key_setup(key, &ctx->u.des3.key);
119 os_memcpy(ctx->u.des3.cbc, iv, 8);
120 break;
121 #endif
122 #ifdef CONFIG_DES
123 case CRYPTO_CIPHER_ALG_DES:
124 if (key_len != 8) {
125 os_free(ctx);
126 return NULL;
127 }
128 des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
129 os_memcpy(ctx->u.des.cbc, iv, 8);
130 break;
131 #endif
132 default:
133 os_free(ctx);
134 return NULL;
135 }
136
137 return ctx;
138 }
139
140
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)141 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
142 u8 *crypt, size_t len)
143 {
144 size_t i, j, blocks;
145
146 switch (ctx->alg) {
147 case CRYPTO_CIPHER_ALG_RC4:
148 if (plain != crypt)
149 os_memcpy(crypt, plain, len);
150 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
151 ctx->u.rc4.used_bytes, crypt, len);
152 ctx->u.rc4.used_bytes += len;
153 break;
154 case CRYPTO_CIPHER_ALG_AES:
155 if (len % AES_BLOCK_SIZE)
156 return -1;
157 blocks = len / AES_BLOCK_SIZE;
158 for (i = 0; i < blocks; i++) {
159 for (j = 0; j < AES_BLOCK_SIZE; j++)
160 ctx->u.aes.cbc[j] ^= plain[j];
161 #ifdef USE_MBEDTLS_CRYPTO
162 if (mbedtls_internal_aes_encrypt(&(ctx->u.aes.ctx_enc),
163 ctx->u.aes.cbc, ctx->u.aes.cbc) != 0)
164 return -1;
165 #else /* USE_MBEDTLS_CRYPTO */
166 aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
167 ctx->u.aes.cbc);
168 #endif /* USE_MBEDTLS_CRYPTO */
169 os_memcpy(crypt, ctx->u.aes.cbc, AES_BLOCK_SIZE);
170 plain += AES_BLOCK_SIZE;
171 crypt += AES_BLOCK_SIZE;
172 }
173 break;
174 #ifdef CONFIG_DES3
175 case CRYPTO_CIPHER_ALG_3DES:
176 if (len % 8)
177 return -1;
178 blocks = len / 8;
179 for (i = 0; i < blocks; i++) {
180 for (j = 0; j < 8; j++)
181 ctx->u.des3.cbc[j] ^= plain[j];
182 des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
183 ctx->u.des3.cbc);
184 os_memcpy(crypt, ctx->u.des3.cbc, 8);
185 plain += 8;
186 crypt += 8;
187 }
188 break;
189 #endif
190 #ifdef CONFIG_DES
191 case CRYPTO_CIPHER_ALG_DES:
192 if (len % 8)
193 return -1;
194 blocks = len / 8;
195 for (i = 0; i < blocks; i++) {
196 for (j = 0; j < 8; j++)
197 ctx->u.des3.cbc[j] ^= plain[j];
198 des_block_encrypt(ctx->u.des.cbc, ctx->u.des.ek,
199 ctx->u.des.cbc);
200 os_memcpy(crypt, ctx->u.des.cbc, 8);
201 plain += 8;
202 crypt += 8;
203 }
204 break;
205 #endif
206 default:
207 return -1;
208 }
209
210 return 0;
211 }
212
213
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)214 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
215 u8 *plain, size_t len)
216 {
217 size_t i, j, blocks;
218 u8 tmp[32];
219
220 switch (ctx->alg) {
221 case CRYPTO_CIPHER_ALG_RC4:
222 if (plain != crypt)
223 os_memcpy(plain, crypt, len);
224 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
225 ctx->u.rc4.used_bytes, plain, len);
226 ctx->u.rc4.used_bytes += len;
227 break;
228 case CRYPTO_CIPHER_ALG_AES:
229 if (len % AES_BLOCK_SIZE)
230 return -1;
231 blocks = len / AES_BLOCK_SIZE;
232 for (i = 0; i < blocks; i++) {
233 os_memcpy(tmp, crypt, AES_BLOCK_SIZE);
234 #ifdef USE_MBEDTLS_CRYPTO
235 if (mbedtls_internal_aes_decrypt(&(ctx->u.aes.ctx_dec),
236 crypt, plain) != 0)
237 return -1;
238 #else /* USE_MBEDTLS_CRYPTO */
239 aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
240 #endif /* USE_MBEDTLS_CRYPTO */
241 for (j = 0; j < AES_BLOCK_SIZE; j++)
242 plain[j] ^= ctx->u.aes.cbc[j];
243 os_memcpy(ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE);
244 plain += AES_BLOCK_SIZE;
245 crypt += AES_BLOCK_SIZE;
246 }
247 break;
248 #ifdef CONFIG_DES3
249 case CRYPTO_CIPHER_ALG_3DES:
250 if (len % 8)
251 return -1;
252 blocks = len / 8;
253 for (i = 0; i < blocks; i++) {
254 os_memcpy(tmp, crypt, 8);
255 des3_decrypt(crypt, &ctx->u.des3.key, plain);
256 for (j = 0; j < 8; j++)
257 plain[j] ^= ctx->u.des3.cbc[j];
258 os_memcpy(ctx->u.des3.cbc, tmp, 8);
259 plain += 8;
260 crypt += 8;
261 }
262 break;
263 #endif
264 #ifdef CONFIG_DES
265 case CRYPTO_CIPHER_ALG_DES:
266 if (len % 8)
267 return -1;
268 blocks = len / 8;
269 for (i = 0; i < blocks; i++) {
270 os_memcpy(tmp, crypt, 8);
271 des_block_decrypt(crypt, ctx->u.des.dk, plain);
272 for (j = 0; j < 8; j++)
273 plain[j] ^= ctx->u.des.cbc[j];
274 os_memcpy(ctx->u.des.cbc, tmp, 8);
275 plain += 8;
276 crypt += 8;
277 }
278 break;
279 #endif
280 default:
281 return -1;
282 }
283
284 return 0;
285 }
286
287
crypto_cipher_deinit(struct crypto_cipher * ctx)288 void crypto_cipher_deinit(struct crypto_cipher *ctx)
289 {
290 switch (ctx->alg) {
291 case CRYPTO_CIPHER_ALG_AES:
292 #ifdef USE_MBEDTLS_CRYPTO
293 mbedtls_aes_free(&(ctx->u.aes.ctx_enc));
294 mbedtls_aes_free(&(ctx->u.aes.ctx_dec));
295 #else /* USE_MBEDTLS_CRYPTO */
296 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
297 aes_decrypt_deinit(ctx->u.aes.ctx_dec);
298 #endif /* USE_MBEDTLS_CRYPTO */
299 break;
300 #ifdef CONFIG_DES3
301 case CRYPTO_CIPHER_ALG_3DES:
302 break;
303 #endif
304 default:
305 break;
306 }
307 os_free(ctx);
308 }
309