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 abstraction api for AES 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 static int operation_map[] = { MBEDTLS_AES_ENCRYPT, MBEDTLS_AES_DECRYPT };
33
34 static unsigned int
_write_pkcs7_pad(uint8_t * p,int len)35 _write_pkcs7_pad(uint8_t *p, int len)
36 {
37 unsigned int n = 0, padlen = LWS_AES_CBC_BLOCKLEN * ((unsigned int)len /
38 LWS_AES_CBC_BLOCKLEN + 1) - (unsigned int)len;
39
40 p += len;
41
42 while (n++ < padlen)
43 *p++ = (uint8_t)padlen;
44
45 return padlen;
46 }
47
48 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)49 lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op,
50 enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el,
51 enum enum_aes_padding padding, void *engine)
52 {
53 int n = 0;
54
55 ctx->mode = mode;
56 ctx->k = el;
57 ctx->op = (enum enum_aes_operation)operation_map[op];
58 ctx->underway = 0;
59 ctx->padding = padding == LWS_GAESP_WITH_PADDING;
60
61 switch (ctx->mode) {
62 case LWS_GAESM_XTS:
63 #if defined(MBEDTLS_CIPHER_MODE_XTS)
64 mbedtls_aes_xts_init(&ctx->u.ctx_xts);
65 break;
66 #else
67 return -1;
68 #endif
69 case LWS_GAESM_GCM:
70 mbedtls_gcm_init(&ctx->u.ctx_gcm);
71 n = mbedtls_gcm_setkey(&ctx->u.ctx_gcm, MBEDTLS_CIPHER_ID_AES,
72 ctx->k->buf, ctx->k->len * 8);
73 if (n) {
74 lwsl_notice("%s: mbedtls_gcm_setkey: -0x%x\n",
75 __func__, -n);
76 return n;
77 }
78 return n;
79 default:
80 mbedtls_aes_init(&ctx->u.ctx);
81 break;
82 }
83
84 switch (op) {
85 case LWS_GAESO_ENC:
86 if (ctx->mode == LWS_GAESM_XTS)
87 #if defined(MBEDTLS_CIPHER_MODE_XTS)
88 n = mbedtls_aes_xts_setkey_enc(&ctx->u.ctx_xts,
89 ctx->k->buf,
90 ctx->k->len * 8);
91 #else
92 return -1;
93 #endif
94 else
95 n = mbedtls_aes_setkey_enc(&ctx->u.ctx, ctx->k->buf,
96 ctx->k->len * 8);
97 break;
98 case LWS_GAESO_DEC:
99 switch (ctx->mode) {
100 case LWS_GAESM_XTS:
101 #if defined(MBEDTLS_CIPHER_MODE_XTS)
102 n = mbedtls_aes_xts_setkey_dec(&ctx->u.ctx_xts,
103 ctx->k->buf,
104 ctx->k->len * 8);
105 break;
106 #else
107 return -1;
108 #endif
109
110 case LWS_GAESM_CFB128:
111 case LWS_GAESM_CFB8:
112 case LWS_GAESM_CTR:
113 case LWS_GAESM_OFB:
114 n = mbedtls_aes_setkey_enc(&ctx->u.ctx, ctx->k->buf,
115 ctx->k->len * 8);
116 break;
117 default:
118 n = mbedtls_aes_setkey_dec(&ctx->u.ctx, ctx->k->buf,
119 ctx->k->len * 8);
120 break;
121 }
122 break;
123 }
124
125 if (n)
126 lwsl_notice("%s: setting key: -0x%x\n", __func__, -n);
127
128 return n;
129 }
130
131 int
lws_genaes_destroy(struct lws_genaes_ctx * ctx,unsigned char * tag,size_t tlen)132 lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen)
133 {
134 int n;
135
136 if (ctx->mode == LWS_GAESM_GCM) {
137 n = mbedtls_gcm_finish(&ctx->u.ctx_gcm, tag, tlen);
138 if (n)
139 lwsl_notice("%s: mbedtls_gcm_finish: -0x%x\n",
140 __func__, -n);
141 if (tag && ctx->op == MBEDTLS_AES_DECRYPT && !n) {
142 if (lws_timingsafe_bcmp(ctx->tag, tag, (unsigned int)ctx->taglen)) {
143 lwsl_err("%s: lws_genaes_crypt tag "
144 "mismatch (bad first)\n",
145 __func__);
146 lwsl_hexdump_notice(tag, tlen);
147 lwsl_hexdump_notice(ctx->tag, (unsigned int)ctx->taglen);
148 n = -1;
149 }
150 }
151 mbedtls_gcm_free(&ctx->u.ctx_gcm);
152 return n;
153 }
154 if (ctx->mode == LWS_GAESM_XTS)
155 #if defined(MBEDTLS_CIPHER_MODE_XTS)
156 mbedtls_aes_xts_free(&ctx->u.ctx_xts);
157 #else
158 return -1;
159 #endif
160 else
161 mbedtls_aes_free(&ctx->u.ctx);
162
163 return 0;
164 }
165
166 #if defined(LWS_HAVE_mbedtls_internal_aes_encrypt)
167 static int
lws_genaes_rfc3394_wrap(int wrap,int cek_bits,const uint8_t * kek,int kek_bits,const uint8_t * in,uint8_t * out)168 lws_genaes_rfc3394_wrap(int wrap, int cek_bits, const uint8_t *kek,
169 int kek_bits, const uint8_t *in, uint8_t *out)
170 {
171 int n, m, ret = -1, c64 = cek_bits / 64;
172 mbedtls_aes_context ctx;
173 uint8_t a[8], b[16];
174
175 /*
176 * notice the KEK key used to perform the wrapping or unwrapping is
177 * always the size of the AES key used, eg, A128KW == 128 bits. The
178 * key being wrapped or unwrapped may be larger and is set by the
179 * 'bits' parameter.
180 *
181 * If it's larger than the KEK key size bits, we iterate over it
182 */
183
184 mbedtls_aes_init(&ctx);
185
186 if (wrap) {
187 /*
188 * The inputs to the key wrapping process are the KEK and the
189 * plaintext to be wrapped. The plaintext consists of n 64-bit
190 * blocks, containing the key data being wrapped.
191 *
192 * Inputs: Plaintext, n 64-bit values {P1, P2, ..., Pn},
193 * and Key, K (the KEK).
194 * Outputs: Ciphertext, (n+1) 64-bit values
195 * {C0, C1, ..., Cn}.
196 *
197 * The default initial value (IV) is defined to be the
198 * hexadecimal constant:
199 *
200 * A[0] = IV = A6A6A6A6A6A6A6A6
201 */
202 memset(out, 0xa6, 8);
203 memcpy(out + 8, in, 8 * (unsigned int)c64);
204 n = mbedtls_aes_setkey_enc(&ctx, kek, (unsigned int)kek_bits);
205 } else {
206 /*
207 * 2.2.2 Key Unwrap
208 *
209 * The inputs to the unwrap process are the KEK and (n+1)
210 * 64-bit blocks of ciphertext consisting of previously
211 * wrapped key. It returns n blocks of plaintext consisting
212 * of the n 64-bit blocks of the decrypted key data.
213 *
214 * Inputs: Ciphertext, (n+1) 64-bit values {C0, C1, ..., Cn},
215 * and Key, K (the KEK).
216 *
217 * Outputs: Plaintext, n 64-bit values {P1, P2, ..., Pn}.
218 */
219 memcpy(a, in, 8);
220 memcpy(out, in + 8, 8 * (unsigned int)c64);
221 n = mbedtls_aes_setkey_dec(&ctx, kek, (unsigned int)kek_bits);
222 }
223
224 if (n < 0) {
225 lwsl_err("%s: setkey failed\n", __func__);
226 goto bail;
227 }
228
229 if (wrap) {
230 for (n = 0; n <= 5; n++) {
231 uint8_t *r = out + 8;
232 for (m = 1; m <= c64; m++) {
233 memcpy(b, out, 8);
234 memcpy(b + 8, r, 8);
235 if (mbedtls_internal_aes_encrypt(&ctx, b, b))
236 goto bail;
237
238 memcpy(out, b, 8);
239 out[7] ^= (uint8_t)(c64 * n + m);
240 memcpy(r, b + 8, 8);
241 r += 8;
242 }
243 }
244 ret = 0;
245 } else {
246 /*
247 *
248 */
249 for (n = 5; n >= 0; n--) {
250 uint8_t *r = out + (c64 - 1) * 8;
251 for (m = c64; m >= 1; m--) {
252 memcpy(b, a, 8);
253 b[7] ^= (uint8_t)(c64 * n + m);
254 memcpy(b + 8, r, 8);
255 if (mbedtls_internal_aes_decrypt(&ctx, b, b))
256 goto bail;
257
258 memcpy(a, b, 8);
259 memcpy(r, b + 8, 8);
260 r -= 8;
261 }
262 }
263
264 ret = 0;
265 for (n = 0; n < 8; n++)
266 if (a[n] != 0xa6)
267 ret = -1;
268 }
269
270 bail:
271 if (ret)
272 lwsl_notice("%s: failed\n", __func__);
273 mbedtls_aes_free(&ctx);
274
275 return ret;
276 }
277 #endif
278
279 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)280 lws_genaes_crypt(struct lws_genaes_ctx *ctx, const uint8_t *in, size_t len,
281 uint8_t *out, uint8_t *iv_or_nonce_ctr_or_data_unit_16,
282 uint8_t *stream_block_16, size_t *nc_or_iv_off, int taglen)
283 {
284 uint8_t iv[LWS_JWE_AES_IV_BYTES], sb[16];
285 int n = 0;
286
287 switch (ctx->mode) {
288 case LWS_GAESM_KW:
289 #if defined(LWS_HAVE_mbedtls_internal_aes_encrypt)
290 /* a key of length ctx->k->len is wrapped by a 128-bit KEK */
291 n = lws_genaes_rfc3394_wrap(ctx->op == MBEDTLS_AES_ENCRYPT,
292 (ctx->op == MBEDTLS_AES_ENCRYPT ? (int)len * 8 :
293 ((int)len - 8) * 8), ctx->k->buf,
294 (int)ctx->k->len * 8,
295 in, out);
296 break;
297 #else
298 lwsl_err("%s: your mbedtls is too old\n", __func__);
299 return -1;
300 #endif
301 case LWS_GAESM_CBC:
302 memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
303
304 /*
305 * If encrypting, we do the PKCS#7 padding.
306 * During decryption, the caller will need to unpad.
307 */
308 if (ctx->padding && ctx->op == MBEDTLS_AES_ENCRYPT) {
309 /*
310 * Since we don't want to burden the caller with
311 * the over-allocation at the end of the input,
312 * we have to allocate a temp with space for it
313 */
314 uint8_t *padin = (uint8_t *)lws_malloc(
315 lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN, len),
316 __func__);
317
318 if (!padin)
319 return -1;
320
321 memcpy(padin, in, len);
322 len += _write_pkcs7_pad((uint8_t *)padin, (int)len);
323 n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, (int)ctx->op, len, iv,
324 padin, out);
325 lws_free(padin);
326 } else
327 n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, (int)ctx->op, len, iv,
328 in, out);
329
330 break;
331
332 case LWS_GAESM_CFB128:
333 memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
334 n = mbedtls_aes_crypt_cfb128(&ctx->u.ctx, (int)ctx->op, len,
335 nc_or_iv_off, iv, in, out);
336 break;
337
338 case LWS_GAESM_CFB8:
339 memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
340 n = mbedtls_aes_crypt_cfb8(&ctx->u.ctx, (int)ctx->op, len, iv,
341 in, out);
342 break;
343
344 case LWS_GAESM_CTR:
345 memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
346 memcpy(sb, stream_block_16, 16);
347 n = mbedtls_aes_crypt_ctr(&ctx->u.ctx, len, nc_or_iv_off,
348 iv, sb, in, out);
349 memcpy(iv_or_nonce_ctr_or_data_unit_16, iv, 16);
350 memcpy(stream_block_16, sb, 16);
351 break;
352
353 case LWS_GAESM_ECB:
354 n = mbedtls_aes_crypt_ecb(&ctx->u.ctx, (int)ctx->op, in, out);
355 break;
356
357 case LWS_GAESM_OFB:
358 #if defined(MBEDTLS_CIPHER_MODE_OFB)
359 memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
360 n = mbedtls_aes_crypt_ofb(&ctx->u.ctx, len, nc_or_iv_off, iv,
361 in, out);
362 break;
363 #else
364 return -1;
365 #endif
366
367 case LWS_GAESM_XTS:
368 #if defined(MBEDTLS_CIPHER_MODE_XTS)
369 memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
370 n = mbedtls_aes_crypt_xts(&ctx->u.ctx_xts, (int)ctx->op, len, iv,
371 in, out);
372 break;
373 #else
374 return -1;
375 #endif
376 case LWS_GAESM_GCM:
377 if (!ctx->underway) {
378 ctx->underway = 1;
379
380 memcpy(ctx->tag, stream_block_16, (unsigned int)taglen);
381 ctx->taglen = taglen;
382
383 /*
384 * iv: iv_or_nonce_ctr_or_data_unit_16
385 * iv_len: *nc_or_iv_off
386 * stream_block_16: pointer to tag
387 * additional data: in
388 * additional data len: len
389 */
390
391 n = mbedtls_gcm_starts(&ctx->u.ctx_gcm, (int)ctx->op,
392 iv_or_nonce_ctr_or_data_unit_16,
393 *nc_or_iv_off, in, len);
394 if (n) {
395 lwsl_notice("%s: mbedtls_gcm_starts: -0x%x\n",
396 __func__, -n);
397
398 return -1;
399 }
400 break;
401 }
402
403 n = mbedtls_gcm_update(&ctx->u.ctx_gcm, len, in, out);
404 if (n) {
405 lwsl_notice("%s: mbedtls_gcm_update: -0x%x\n",
406 __func__, -n);
407
408 return -1;
409 }
410 break;
411 }
412
413 if (n) {
414 lwsl_notice("%s: failed: -0x%x, len %d\n", __func__, -n, (int)len);
415
416 return -1;
417 }
418
419 return 0;
420 }
421