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