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 #include "private-lib-jose.h"
29
30 /*
31 * Care: many openssl apis return 1 for success. These are translated to the
32 * lws convention of 0 for success.
33 */
34
35 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)36 lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op,
37 enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el,
38 enum enum_aes_padding padding, void *engine)
39 {
40 int n = 0;
41
42 ctx->ctx = EVP_CIPHER_CTX_new();
43 if (!ctx->ctx)
44 return -1;
45
46 ctx->mode = mode;
47 ctx->k = el;
48 ctx->engine = engine;
49 ctx->init = 0;
50 ctx->op = op;
51 ctx->padding = padding;
52
53 switch (ctx->k->len) {
54 case 128 / 8:
55 switch (mode) {
56 case LWS_GAESM_KW:
57 #if defined(LWS_HAVE_EVP_aes_128_wrap)
58 EVP_CIPHER_CTX_set_flags(ctx->ctx,
59 EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
60 ctx->cipher = EVP_aes_128_wrap();
61 break;
62 #else
63 lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
64 __func__);
65 return -1;
66 #endif
67 case LWS_GAESM_CBC:
68 ctx->cipher = EVP_aes_128_cbc();
69 break;
70 #if defined(LWS_HAVE_EVP_aes_128_cfb128)
71 case LWS_GAESM_CFB128:
72 ctx->cipher = EVP_aes_128_cfb128();
73 break;
74 #endif
75 #if defined(LWS_HAVE_EVP_aes_128_cfb8)
76 case LWS_GAESM_CFB8:
77 ctx->cipher = EVP_aes_128_cfb8();
78 break;
79 #endif
80 case LWS_GAESM_CTR:
81 ctx->cipher = EVP_aes_128_ctr();
82 break;
83 case LWS_GAESM_ECB:
84 ctx->cipher = EVP_aes_128_ecb();
85 break;
86 case LWS_GAESM_OFB:
87 ctx->cipher = EVP_aes_128_ofb();
88 break;
89 case LWS_GAESM_XTS:
90 lwsl_err("%s: AES XTS requires double-length key\n",
91 __func__);
92 break;
93 case LWS_GAESM_GCM:
94 ctx->cipher = EVP_aes_128_gcm();
95 break;
96 default:
97 goto bail;
98 }
99 break;
100
101 case 192 / 8:
102 switch (mode) {
103 case LWS_GAESM_KW:
104 #if defined(LWS_HAVE_EVP_aes_128_wrap)
105 EVP_CIPHER_CTX_set_flags(ctx->ctx,
106 EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
107 ctx->cipher = EVP_aes_192_wrap();
108 break;
109 #else
110 lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
111 __func__);
112 return -1;
113 #endif
114 case LWS_GAESM_CBC:
115 ctx->cipher = EVP_aes_192_cbc();
116 break;
117 #if defined(LWS_HAVE_EVP_aes_192_cfb128)
118 case LWS_GAESM_CFB128:
119 ctx->cipher = EVP_aes_192_cfb128();
120 break;
121 #endif
122 #if defined(LWS_HAVE_EVP_aes_192_cfb8)
123 case LWS_GAESM_CFB8:
124 ctx->cipher = EVP_aes_192_cfb8();
125 break;
126 #endif
127 case LWS_GAESM_CTR:
128 ctx->cipher = EVP_aes_192_ctr();
129 break;
130 case LWS_GAESM_ECB:
131 ctx->cipher = EVP_aes_192_ecb();
132 break;
133 case LWS_GAESM_OFB:
134 ctx->cipher = EVP_aes_192_ofb();
135 break;
136 case LWS_GAESM_XTS:
137 lwsl_err("%s: AES XTS 192 invalid\n", __func__);
138 goto bail;
139 case LWS_GAESM_GCM:
140 ctx->cipher = EVP_aes_192_gcm();
141 break;
142 default:
143 goto bail;
144 }
145 break;
146
147 case 256 / 8:
148 switch (mode) {
149 case LWS_GAESM_KW:
150 #if defined(LWS_HAVE_EVP_aes_128_wrap)
151 EVP_CIPHER_CTX_set_flags(ctx->ctx,
152 EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
153 ctx->cipher = EVP_aes_256_wrap();
154 break;
155 #else
156 lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
157 __func__);
158 return -1;
159 #endif
160 case LWS_GAESM_CBC:
161 ctx->cipher = EVP_aes_256_cbc();
162 break;
163 #if defined(LWS_HAVE_EVP_aes_256_cfb128)
164 case LWS_GAESM_CFB128:
165 ctx->cipher = EVP_aes_256_cfb128();
166 break;
167 #endif
168 #if defined(LWS_HAVE_EVP_aes_256_cfb8)
169 case LWS_GAESM_CFB8:
170 ctx->cipher = EVP_aes_256_cfb8();
171 break;
172 #endif
173 case LWS_GAESM_CTR:
174 ctx->cipher = EVP_aes_256_ctr();
175 break;
176 case LWS_GAESM_ECB:
177 ctx->cipher = EVP_aes_256_ecb();
178 break;
179 case LWS_GAESM_OFB:
180 ctx->cipher = EVP_aes_256_ofb();
181 break;
182 #if defined(LWS_HAVE_EVP_aes_128_xts)
183 case LWS_GAESM_XTS:
184 ctx->cipher = EVP_aes_128_xts();
185 break;
186 #endif
187 case LWS_GAESM_GCM:
188 ctx->cipher = EVP_aes_256_gcm();
189 break;
190 default:
191 goto bail;
192 }
193 break;
194
195 case 512 / 8:
196 switch (mode) {
197 case LWS_GAESM_XTS:
198 ctx->cipher = EVP_aes_256_xts();
199 break;
200 default:
201 goto bail;
202 }
203 break;
204
205 default:
206 lwsl_err("%s: unsupported AES size %d bits\n", __func__,
207 ctx->k->len * 8);
208 goto bail;
209 }
210
211 switch (ctx->op) {
212 case LWS_GAESO_ENC:
213 n = EVP_EncryptInit_ex(ctx->ctx, ctx->cipher, ctx->engine,
214 NULL, NULL);
215 EVP_CIPHER_CTX_set_padding(ctx->ctx, padding);
216 break;
217 case LWS_GAESO_DEC:
218 n = EVP_DecryptInit_ex(ctx->ctx, ctx->cipher, ctx->engine,
219 NULL, NULL);
220 EVP_CIPHER_CTX_set_padding(ctx->ctx, padding);
221 break;
222 }
223 if (!n) {
224 lwsl_err("%s: cipher init failed (cipher %p)\n", __func__,
225 ctx->cipher);
226 lws_tls_err_describe_clear();
227 goto bail;
228 }
229
230 return 0;
231 bail:
232 EVP_CIPHER_CTX_free(ctx->ctx);
233 ctx->ctx = NULL;
234 return -1;
235 }
236
237 int
lws_genaes_destroy(struct lws_genaes_ctx * ctx,unsigned char * tag,size_t tlen)238 lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen)
239 {
240 uint8_t buf[256];
241 int outl = sizeof(buf), n = 0;
242
243 if (!ctx->ctx)
244 return 0;
245
246 if (ctx->init) {
247 switch (ctx->op) {
248 case LWS_GAESO_ENC:
249
250 if (EVP_EncryptFinal_ex(ctx->ctx, buf, &outl) != 1) {
251 lwsl_err("%s: enc final failed\n", __func__);
252 n = -1;
253 }
254
255 if (ctx->mode == LWS_GAESM_GCM) {
256 if (EVP_CIPHER_CTX_ctrl(ctx->ctx,
257 EVP_CTRL_GCM_GET_TAG,
258 ctx->taglen, tag) != 1) {
259 lwsl_err("get tag ctrl failed\n");
260 //lws_tls_err_describe_clear();
261 n = 1;
262 }
263 }
264 if (ctx->mode == LWS_GAESM_CBC)
265 memcpy(tag, buf, outl);
266
267 break;
268
269 case LWS_GAESO_DEC:
270 if (EVP_DecryptFinal_ex(ctx->ctx, buf, &outl) != 1) {
271 lwsl_err("%s: dec final failed\n", __func__);
272 lws_tls_err_describe_clear();
273 n = -1;
274 }
275
276 break;
277 }
278 if (outl)
279 lwsl_debug("%s: final len %d\n", __func__, outl);
280 }
281
282 ctx->k = NULL;
283 EVP_CIPHER_CTX_free(ctx->ctx);
284 ctx->ctx = NULL;
285
286 return n;
287 }
288
289 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)290 lws_genaes_crypt(struct lws_genaes_ctx *ctx,
291 const uint8_t *in, size_t len, uint8_t *out,
292 uint8_t *iv_or_nonce_ctr_or_data_unit_16,
293 uint8_t *stream_block_16, size_t *nc_or_iv_off, int taglen)
294 {
295 int n = 0, outl, olen;
296
297 if (!ctx->init) {
298
299 EVP_CIPHER_CTX_set_key_length(ctx->ctx, ctx->k->len);
300
301 if (ctx->mode == LWS_GAESM_GCM) {
302 n = EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_GCM_SET_IVLEN,
303 (int)*nc_or_iv_off, NULL);
304 if (n != 1) {
305 lwsl_err("%s: SET_IVLEN failed\n", __func__);
306 return -1;
307 }
308 memcpy(ctx->tag, stream_block_16, taglen);
309 ctx->taglen = taglen;
310 }
311
312 switch (ctx->op) {
313 case LWS_GAESO_ENC:
314 n = EVP_EncryptInit_ex(ctx->ctx, NULL, NULL,
315 ctx->k->buf,
316 iv_or_nonce_ctr_or_data_unit_16);
317 break;
318 case LWS_GAESO_DEC:
319 if (ctx->mode == LWS_GAESM_GCM)
320 EVP_CIPHER_CTX_ctrl(ctx->ctx,
321 EVP_CTRL_GCM_SET_TAG,
322 ctx->taglen, ctx->tag);
323 n = EVP_DecryptInit_ex(ctx->ctx, NULL, NULL,
324 ctx->k->buf,
325 iv_or_nonce_ctr_or_data_unit_16);
326 break;
327 }
328
329 if (!n) {
330 lws_tls_err_describe_clear();
331 lwsl_err("%s: init failed (cipher %p)\n",
332 __func__, ctx->cipher);
333
334 return -1;
335 }
336 ctx->init = 1;
337 }
338
339 if (ctx->mode == LWS_GAESM_GCM && !out) {
340 /* AAD */
341
342 if (!len)
343 return 0;
344
345 switch (ctx->op) {
346 case LWS_GAESO_ENC:
347 n = EVP_EncryptUpdate(ctx->ctx, NULL, &olen, in, (int)len);
348 break;
349 case LWS_GAESO_DEC:
350 n = EVP_DecryptUpdate(ctx->ctx, NULL, &olen, in, (int)len);
351 break;
352 default:
353 return -1;
354 }
355 if (n != 1) {
356 lwsl_err("%s: set AAD failed\n", __func__);
357 lws_tls_err_describe_clear();
358 lwsl_hexdump_err(in, len);
359 return -1;
360 }
361
362 return 0;
363 }
364
365 switch (ctx->op) {
366 case LWS_GAESO_ENC:
367 n = EVP_EncryptUpdate(ctx->ctx, out, &outl, in, (int)len);
368 break;
369 case LWS_GAESO_DEC:
370 n = EVP_DecryptUpdate(ctx->ctx, out, &outl, in, (int)len);
371 break;
372 default:
373 return -1;
374 }
375
376 // lwsl_notice("discarding outl %d\n", (int)outl);
377
378 if (!n) {
379 lwsl_notice("%s: update failed\n", __func__);
380 lws_tls_err_describe_clear();
381
382 return -1;
383 }
384
385 return 0;
386 }
387