• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  *  lws_genaes provides an AES abstraction api in lws that works the
25  *  same whether you are using openssl or mbedtls hash functions underneath.
26  */
27 #include "private-lib-core.h"
28 #if defined(LWS_WITH_JOSE)
29 #include "private-lib-jose.h"
30 #endif
31 
32 /*
33  * Care: many openssl apis return 1 for success.  These are translated to the
34  * lws convention of 0 for success.
35  */
36 
37 int
lws_genaes_create(struct lws_genaes_ctx * ctx,enum enum_aes_operation op,enum enum_aes_modes mode,struct lws_gencrypto_keyelem * el,enum enum_aes_padding padding,void * engine)38 lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op,
39 		  enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el,
40 		  enum enum_aes_padding padding, void *engine)
41 {
42 	int n = 0;
43 
44 	ctx->ctx = EVP_CIPHER_CTX_new();
45 	if (!ctx->ctx)
46 		return -1;
47 
48 	ctx->mode = mode;
49 	ctx->k = el;
50 	ctx->engine = engine;
51 	ctx->init = 0;
52 	ctx->op = op;
53 	ctx->padding = padding;
54 
55 	switch (ctx->k->len) {
56 	case 128 / 8:
57 		switch (mode) {
58 		case LWS_GAESM_KW:
59 #if defined(LWS_HAVE_EVP_aes_128_wrap)
60 			EVP_CIPHER_CTX_set_flags(ctx->ctx,
61 						EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
62 			ctx->cipher = EVP_aes_128_wrap();
63 			break;
64 #else
65 			lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
66 				 __func__);
67 			return -1;
68 #endif
69 		case LWS_GAESM_CBC:
70 			ctx->cipher = EVP_aes_128_cbc();
71 			break;
72 #if defined(LWS_HAVE_EVP_aes_128_cfb128)
73 		case LWS_GAESM_CFB128:
74 			ctx->cipher = EVP_aes_128_cfb128();
75 			break;
76 #endif
77 #if defined(LWS_HAVE_EVP_aes_128_cfb8)
78 		case LWS_GAESM_CFB8:
79 			ctx->cipher = EVP_aes_128_cfb8();
80 			break;
81 #endif
82 #if defined(LWS_HAVE_EVP_aes_128_ctr)
83 		case LWS_GAESM_CTR:
84 			ctx->cipher = EVP_aes_128_ctr();
85 			break;
86 #endif
87 #if defined(LWS_HAVE_EVP_aes_128_ecb)
88 		case LWS_GAESM_ECB:
89 			ctx->cipher = EVP_aes_128_ecb();
90 			break;
91 #endif
92 #if defined(LWS_HAVE_EVP_aes_128_ofb)
93 		case LWS_GAESM_OFB:
94 			ctx->cipher = EVP_aes_128_ofb();
95 			break;
96 #endif
97 #if defined(LWS_HAVE_EVP_aes_128_xts)
98 		case LWS_GAESM_XTS:
99 			lwsl_err("%s: AES XTS requires double-length key\n",
100 				 __func__);
101 			break;
102 #endif
103 		case LWS_GAESM_GCM:
104 			ctx->cipher = EVP_aes_128_gcm();
105 			break;
106 		default:
107 			goto bail;
108 		}
109 		break;
110 
111 	case 192 / 8:
112 		switch (mode) {
113 		case LWS_GAESM_KW:
114 #if defined(LWS_HAVE_EVP_aes_128_wrap)
115 			EVP_CIPHER_CTX_set_flags(ctx->ctx,
116 						EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
117 			ctx->cipher = EVP_aes_192_wrap();
118 			break;
119 #else
120                         lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
121                                  __func__);
122                         return -1;
123 #endif
124 		case LWS_GAESM_CBC:
125 			ctx->cipher = EVP_aes_192_cbc();
126 			break;
127 #if defined(LWS_HAVE_EVP_aes_192_cfb128)
128 		case LWS_GAESM_CFB128:
129 			ctx->cipher = EVP_aes_192_cfb128();
130 			break;
131 #endif
132 #if defined(LWS_HAVE_EVP_aes_192_cfb8)
133 		case LWS_GAESM_CFB8:
134 			ctx->cipher = EVP_aes_192_cfb8();
135 			break;
136 #endif
137 #if defined(LWS_HAVE_EVP_aes_128_ctr)
138 		case LWS_GAESM_CTR:
139 			ctx->cipher = EVP_aes_192_ctr();
140 			break;
141 #endif
142 #if defined(LWS_HAVE_EVP_aes_128_ecb)
143 		case LWS_GAESM_ECB:
144 			ctx->cipher = EVP_aes_192_ecb();
145 			break;
146 #endif
147 #if defined(LWS_HAVE_EVP_aes_128_ofb)
148 		case LWS_GAESM_OFB:
149 			ctx->cipher = EVP_aes_192_ofb();
150 			break;
151 #endif
152 #if defined(LWS_HAVE_EVP_aes_128_xts)
153 		case LWS_GAESM_XTS:
154 			lwsl_err("%s: AES XTS 192 invalid\n", __func__);
155 			goto bail;
156 #endif
157 		case LWS_GAESM_GCM:
158 			ctx->cipher = EVP_aes_192_gcm();
159 			break;
160 		default:
161 			goto bail;
162 		}
163 		break;
164 
165 	case 256 / 8:
166 		switch (mode) {
167 		case LWS_GAESM_KW:
168 #if defined(LWS_HAVE_EVP_aes_128_wrap)
169 			EVP_CIPHER_CTX_set_flags(ctx->ctx,
170 						EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
171 			ctx->cipher = EVP_aes_256_wrap();
172 			break;
173 #else
174                         lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
175                                  __func__);
176                         return -1;
177 #endif
178 		case LWS_GAESM_CBC:
179 			ctx->cipher = EVP_aes_256_cbc();
180 			break;
181 #if defined(LWS_HAVE_EVP_aes_256_cfb128)
182 		case LWS_GAESM_CFB128:
183 			ctx->cipher = EVP_aes_256_cfb128();
184 			break;
185 #endif
186 #if defined(LWS_HAVE_EVP_aes_256_cfb8)
187 		case LWS_GAESM_CFB8:
188 			ctx->cipher = EVP_aes_256_cfb8();
189 			break;
190 #endif
191 #if defined(LWS_HAVE_EVP_aes_128_ctr)
192 		case LWS_GAESM_CTR:
193 			ctx->cipher = EVP_aes_256_ctr();
194 			break;
195 #endif
196 #if defined(LWS_HAVE_EVP_aes_128_ecb)
197 		case LWS_GAESM_ECB:
198 			ctx->cipher = EVP_aes_256_ecb();
199 			break;
200 #endif
201 #if defined(LWS_HAVE_EVP_aes_128_ofb)
202 		case LWS_GAESM_OFB:
203 			ctx->cipher = EVP_aes_256_ofb();
204 			break;
205 #endif
206 #if defined(LWS_HAVE_EVP_aes_128_xts)
207 		case LWS_GAESM_XTS:
208 			ctx->cipher = EVP_aes_128_xts();
209 			break;
210 #endif
211 		case LWS_GAESM_GCM:
212 			ctx->cipher = EVP_aes_256_gcm();
213 			break;
214 		default:
215 			goto bail;
216 		}
217 		break;
218 
219 	case 512 / 8:
220 		switch (mode) {
221 #if defined(LWS_HAVE_EVP_aes_128_xts)
222 		case LWS_GAESM_XTS:
223 			ctx->cipher = EVP_aes_256_xts();
224 #endif
225 			break;
226 		default:
227 			goto bail;
228 		}
229 	break;
230 
231 	default:
232 		lwsl_err("%s: unsupported AES size %d bits\n", __func__,
233 			 ctx->k->len * 8);
234 		goto bail;
235 	}
236 
237 	switch (ctx->op) {
238 	case LWS_GAESO_ENC:
239 		n = EVP_EncryptInit_ex(ctx->ctx, ctx->cipher, ctx->engine,
240 				       NULL, NULL);
241 		EVP_CIPHER_CTX_set_padding(ctx->ctx, (int)padding);
242 		break;
243 	case LWS_GAESO_DEC:
244 		n = EVP_DecryptInit_ex(ctx->ctx, ctx->cipher, ctx->engine,
245 				       NULL, NULL);
246 		EVP_CIPHER_CTX_set_padding(ctx->ctx, (int)padding);
247 		break;
248 	}
249 	if (!n) {
250 		lwsl_err("%s: cipher init failed (cipher %p)\n", __func__,
251 			 ctx->cipher);
252 		lws_tls_err_describe_clear();
253 		goto bail;
254 	}
255 
256 	return 0;
257 bail:
258 	EVP_CIPHER_CTX_free(ctx->ctx);
259 	ctx->ctx = NULL;
260 	return -1;
261 }
262 
263 int
lws_genaes_destroy(struct lws_genaes_ctx * ctx,unsigned char * tag,size_t tlen)264 lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen)
265 {
266 	uint8_t buf[256];
267 	int outl = sizeof(buf), n = 0;
268 
269 	if (!ctx->ctx)
270 		return 0;
271 
272 	if (ctx->init) {
273 		switch (ctx->op) {
274 		case LWS_GAESO_ENC:
275 
276 			if (EVP_EncryptFinal_ex(ctx->ctx, buf, &outl) != 1) {
277 				lwsl_err("%s: enc final failed\n", __func__);
278 				n = -1;
279 			}
280 
281 			if (ctx->mode == LWS_GAESM_GCM) {
282 				if (EVP_CIPHER_CTX_ctrl(ctx->ctx,
283 						EVP_CTRL_GCM_GET_TAG,
284 						    ctx->taglen, tag) != 1) {
285 					lwsl_err("get tag ctrl failed\n");
286 					//lws_tls_err_describe_clear();
287 					n = 1;
288 				}
289 			}
290 			if (ctx->mode == LWS_GAESM_CBC)
291 				memcpy(tag, buf, (unsigned int)outl);
292 
293 			break;
294 
295 		case LWS_GAESO_DEC:
296 			if (EVP_DecryptFinal_ex(ctx->ctx, buf, &outl) != 1) {
297 				lwsl_err("%s: dec final failed\n", __func__);
298 				lws_tls_err_describe_clear();
299 				n = -1;
300 			}
301 
302 			break;
303 		}
304 		if (outl)
305 			lwsl_debug("%s: final len %d\n", __func__, outl);
306 	}
307 
308 	ctx->k = NULL;
309 	EVP_CIPHER_CTX_free(ctx->ctx);
310 	ctx->ctx = NULL;
311 
312 	return n;
313 }
314 
315 int
lws_genaes_crypt(struct lws_genaes_ctx * ctx,const uint8_t * in,size_t len,uint8_t * out,uint8_t * iv_or_nonce_ctr_or_data_unit_16,uint8_t * stream_block_16,size_t * nc_or_iv_off,int taglen)316 lws_genaes_crypt(struct lws_genaes_ctx *ctx,
317 		 const uint8_t *in, size_t len, uint8_t *out,
318 		 uint8_t *iv_or_nonce_ctr_or_data_unit_16,
319 		 uint8_t *stream_block_16, size_t *nc_or_iv_off, int taglen)
320 {
321 	int n = 0, outl, olen;
322 
323 	if (!ctx->init) {
324 
325 		EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)ctx->k->len);
326 
327 		if (ctx->mode == LWS_GAESM_GCM) {
328 			n = EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_GCM_SET_IVLEN,
329 					   (int)*nc_or_iv_off, NULL);
330 			if (n != 1) {
331 				lwsl_err("%s: SET_IVLEN failed\n", __func__);
332 				return -1;
333 			}
334 			memcpy(ctx->tag, stream_block_16, (unsigned int)taglen);
335 			ctx->taglen = taglen;
336 		}
337 
338 		switch (ctx->op) {
339 		case LWS_GAESO_ENC:
340 			n = EVP_EncryptInit_ex(ctx->ctx, NULL, NULL,
341 					       ctx->k->buf,
342 					       iv_or_nonce_ctr_or_data_unit_16);
343 			break;
344 		case LWS_GAESO_DEC:
345 			if (ctx->mode == LWS_GAESM_GCM)
346 				EVP_CIPHER_CTX_ctrl(ctx->ctx,
347 						    EVP_CTRL_GCM_SET_TAG,
348 						    ctx->taglen, ctx->tag);
349 			n = EVP_DecryptInit_ex(ctx->ctx, NULL, NULL,
350 					       ctx->k->buf,
351 					       iv_or_nonce_ctr_or_data_unit_16);
352 			break;
353 		}
354 
355 		if (!n) {
356 			lws_tls_err_describe_clear();
357 			lwsl_err("%s: init failed (cipher %p)\n",
358 				 __func__, ctx->cipher);
359 
360 			return -1;
361 		}
362 		ctx->init = 1;
363 	}
364 
365 	if (ctx->mode == LWS_GAESM_GCM && !out) {
366 		/* AAD */
367 
368 		if (!len)
369 			return 0;
370 
371 		switch (ctx->op) {
372 		case LWS_GAESO_ENC:
373 			n = EVP_EncryptUpdate(ctx->ctx, NULL, &olen, in, (int)len);
374 			break;
375 		case LWS_GAESO_DEC:
376 			n = EVP_DecryptUpdate(ctx->ctx, NULL, &olen, in, (int)len);
377 			break;
378 		default:
379 			return -1;
380 		}
381 		if (n != 1) {
382 			lwsl_err("%s: set AAD failed\n",  __func__);
383 			lws_tls_err_describe_clear();
384 			lwsl_hexdump_err(in, len);
385 			return -1;
386 		}
387 
388 		return 0;
389 	}
390 
391 	switch (ctx->op) {
392 	case LWS_GAESO_ENC:
393 		n = EVP_EncryptUpdate(ctx->ctx, out, &outl, in, (int)len);
394 		break;
395 	case LWS_GAESO_DEC:
396 		n = EVP_DecryptUpdate(ctx->ctx, out, &outl, in, (int)len);
397 		break;
398 	default:
399 		return -1;
400 	}
401 
402 	// lwsl_notice("discarding outl %d\n", (int)outl);
403 
404 	if (!n) {
405 		lwsl_notice("%s: update failed\n", __func__);
406 		lws_tls_err_describe_clear();
407 
408 		return -1;
409 	}
410 
411 	return 0;
412 }
413