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