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