• 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 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 #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
135 	size_t last_len = 0;
136 	uint8_t last[16];
137 #endif
138 	int n;
139 
140 	if (ctx->mode == LWS_GAESM_GCM) {
141 #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
142 		n = mbedtls_gcm_finish(&ctx->u.ctx_gcm, last, sizeof(last),
143 					&last_len, tag, tlen);
144 #else
145 		n = mbedtls_gcm_finish(&ctx->u.ctx_gcm, tag, tlen);
146 #endif
147 
148 		if (n)
149 			lwsl_notice("%s: mbedtls_gcm_finish: -0x%x\n",
150 				    __func__, -n);
151 		if (tag && ctx->op == MBEDTLS_AES_DECRYPT && !n) {
152 			if (lws_timingsafe_bcmp(ctx->tag, tag, (unsigned int)ctx->taglen)) {
153 				lwsl_err("%s: lws_genaes_crypt tag "
154 					 "mismatch (bad first)\n",
155 						__func__);
156 				lwsl_hexdump_notice(tag, tlen);
157 				lwsl_hexdump_notice(ctx->tag, (unsigned int)ctx->taglen);
158 				n = -1;
159 			}
160 		}
161 		mbedtls_gcm_free(&ctx->u.ctx_gcm);
162 		return n;
163 	}
164 	if (ctx->mode == LWS_GAESM_XTS)
165 #if defined(MBEDTLS_CIPHER_MODE_XTS)
166 		mbedtls_aes_xts_free(&ctx->u.ctx_xts);
167 #else
168 		return -1;
169 #endif
170 	else
171 		mbedtls_aes_free(&ctx->u.ctx);
172 
173 	return 0;
174 }
175 
176 #if defined(LWS_HAVE_mbedtls_internal_aes_encrypt)
177 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)178 lws_genaes_rfc3394_wrap(int wrap, int cek_bits, const uint8_t *kek,
179 			int kek_bits, const uint8_t *in, uint8_t *out)
180 {
181 	int n, m, ret = -1, c64 = cek_bits / 64;
182 	mbedtls_aes_context ctx;
183 	uint8_t a[8], b[16];
184 
185 	/*
186 	 * notice the KEK key used to perform the wrapping or unwrapping is
187 	 * always the size of the AES key used, eg, A128KW == 128 bits.  The
188 	 * key being wrapped or unwrapped may be larger and is set by the
189 	 * 'bits' parameter.
190 	 *
191 	 * If it's larger than the KEK key size bits, we iterate over it
192 	 */
193 
194 	mbedtls_aes_init(&ctx);
195 
196 	if (wrap) {
197 		/*
198 		 * The inputs to the key wrapping process are the KEK and the
199 		 * plaintext to be wrapped.  The plaintext consists of n 64-bit
200 		 * blocks, containing the key data being wrapped.
201 		 *
202 		 * Inputs:      Plaintext, n 64-bit values {P1, P2, ..., Pn},
203 		 *		and Key, K (the KEK).
204 		 * Outputs:     Ciphertext, (n+1) 64-bit values
205 		 *		{C0, C1, ..., Cn}.
206 		 *
207 		 * The default initial value (IV) is defined to be the
208 		 * hexadecimal constant:
209 		 *
210 		 * A[0] = IV = A6A6A6A6A6A6A6A6
211 		 */
212 		memset(out, 0xa6, 8);
213 		memcpy(out + 8, in, 8 * (unsigned int)c64);
214 		n = mbedtls_aes_setkey_enc(&ctx, kek, (unsigned int)kek_bits);
215 	} else {
216 		/*
217 		 * 2.2.2 Key Unwrap
218 		 *
219 		 * The inputs to the unwrap process are the KEK and (n+1)
220 		 * 64-bit blocks of ciphertext consisting of previously
221 		 * wrapped key.  It returns n blocks of plaintext consisting
222 		 * of the n 64-bit blocks of the decrypted key data.
223 		 *
224 		 * Inputs:  Ciphertext, (n+1) 64-bit values {C0, C1, ..., Cn},
225 		 * and Key, K (the KEK).
226 		 *
227 		 * Outputs: Plaintext, n 64-bit values {P1, P2, ..., Pn}.
228 		 */
229 		memcpy(a, in, 8);
230 		memcpy(out, in + 8, 8 * (unsigned int)c64);
231 		n = mbedtls_aes_setkey_dec(&ctx, kek, (unsigned int)kek_bits);
232 	}
233 
234 	if (n < 0) {
235 		lwsl_err("%s: setkey failed\n", __func__);
236 		goto bail;
237 	}
238 
239 	if (wrap) {
240 		for (n = 0; n <= 5; n++) {
241 			uint8_t *r = out + 8;
242 			for (m = 1; m <= c64; m++) {
243 				memcpy(b, out, 8);
244 				memcpy(b + 8, r, 8);
245 				if (mbedtls_internal_aes_encrypt(&ctx, b, b))
246 					goto bail;
247 
248 				memcpy(out, b, 8);
249 				out[7] ^= (uint8_t)(c64 * n + m);
250 				memcpy(r, b + 8, 8);
251 				r += 8;
252 			}
253 		}
254 		ret = 0;
255 	} else {
256 		/*
257 		 *
258 		 */
259 		for (n = 5; n >= 0; n--) {
260 			uint8_t *r = out + (c64 - 1) * 8;
261 			for (m = c64; m >= 1; m--) {
262 				memcpy(b, a, 8);
263 				b[7] ^= (uint8_t)(c64 * n + m);
264 				memcpy(b + 8, r, 8);
265 				if (mbedtls_internal_aes_decrypt(&ctx, b, b))
266 					goto bail;
267 
268 				memcpy(a, b, 8);
269 				memcpy(r, b + 8, 8);
270 				r -= 8;
271 			}
272 		}
273 
274 		ret = 0;
275 		for (n = 0; n < 8; n++)
276 			if (a[n] != 0xa6)
277 				ret = -1;
278 	}
279 
280 bail:
281 	if (ret)
282 		lwsl_notice("%s: failed\n", __func__);
283 	mbedtls_aes_free(&ctx);
284 
285 	return ret;
286 }
287 #endif
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, const uint8_t *in, size_t len,
291 		 uint8_t *out, uint8_t *iv_or_nonce_ctr_or_data_unit_16,
292 		 uint8_t *stream_block_16, size_t *nc_or_iv_off, int taglen)
293 {
294 	uint8_t iv[LWS_JWE_AES_IV_BYTES], sb[16];
295 	int n = 0;
296 
297 	switch (ctx->mode) {
298 	case LWS_GAESM_KW:
299 #if defined(LWS_HAVE_mbedtls_internal_aes_encrypt)
300 		/* a key of length ctx->k->len is wrapped by a 128-bit KEK */
301 		n = lws_genaes_rfc3394_wrap(ctx->op == MBEDTLS_AES_ENCRYPT,
302 				(ctx->op == MBEDTLS_AES_ENCRYPT ? (int)len * 8 :
303 						((int)len - 8) * 8), ctx->k->buf,
304 						(int)ctx->k->len * 8,
305 				in, out);
306 		break;
307 #else
308 		lwsl_err("%s: your mbedtls is too old\n", __func__);
309 		return -1;
310 #endif
311 	case LWS_GAESM_CBC:
312 		memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
313 
314 		/*
315 		 * If encrypting, we do the PKCS#7 padding.
316 		 * During decryption, the caller will need to unpad.
317 		 */
318 		if (ctx->padding && ctx->op == MBEDTLS_AES_ENCRYPT) {
319 			/*
320 			 * Since we don't want to burden the caller with
321 			 * the over-allocation at the end of the input,
322 			 * we have to allocate a temp with space for it
323 			 */
324 			uint8_t *padin = (uint8_t *)lws_malloc(
325 				lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN, len),
326 								__func__);
327 
328 			if (!padin)
329 				return -1;
330 
331 			memcpy(padin, in, len);
332 			len += _write_pkcs7_pad((uint8_t *)padin, (int)len);
333 			n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, (int)ctx->op, len, iv,
334 						  padin, out);
335 			lws_free(padin);
336 		} else
337 			n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, (int)ctx->op, len, iv,
338                                       in, out);
339 
340 		break;
341 
342 	case LWS_GAESM_CFB128:
343 		memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
344 		n = mbedtls_aes_crypt_cfb128(&ctx->u.ctx, (int)ctx->op, len,
345 					     nc_or_iv_off, iv, in, out);
346 		break;
347 
348 	case LWS_GAESM_CFB8:
349 		memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
350 		n = mbedtls_aes_crypt_cfb8(&ctx->u.ctx, (int)ctx->op, len, iv,
351 					   in, out);
352 		break;
353 
354 	case LWS_GAESM_CTR:
355 		memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
356 		memcpy(sb, stream_block_16, 16);
357 		n = mbedtls_aes_crypt_ctr(&ctx->u.ctx, len, nc_or_iv_off,
358 					  iv, sb, in, out);
359 		memcpy(iv_or_nonce_ctr_or_data_unit_16, iv, 16);
360 		memcpy(stream_block_16, sb, 16);
361 		break;
362 
363 	case LWS_GAESM_ECB:
364 		n = mbedtls_aes_crypt_ecb(&ctx->u.ctx, (int)ctx->op, in, out);
365 		break;
366 
367 	case LWS_GAESM_OFB:
368 #if defined(MBEDTLS_CIPHER_MODE_OFB)
369 		memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
370 		n = mbedtls_aes_crypt_ofb(&ctx->u.ctx, len, nc_or_iv_off, iv,
371 					  in, out);
372 		break;
373 #else
374 		return -1;
375 #endif
376 
377 	case LWS_GAESM_XTS:
378 #if defined(MBEDTLS_CIPHER_MODE_XTS)
379 		memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
380 		n = mbedtls_aes_crypt_xts(&ctx->u.ctx_xts, (int)ctx->op, len, iv,
381 					  in, out);
382 		break;
383 #else
384 		return -1;
385 #endif
386 	case LWS_GAESM_GCM:
387 		if (!ctx->underway) {
388 			ctx->underway = 1;
389 
390 			memcpy(ctx->tag, stream_block_16, (unsigned int)taglen);
391 			ctx->taglen = taglen;
392 
393 			/*
394 			 * iv:                   iv_or_nonce_ctr_or_data_unit_16
395 			 * iv_len:               *nc_or_iv_off
396 			 * stream_block_16:      pointer to tag
397 			 * additional data:      in
398 			 * additional data len:  len
399 			 */
400 
401 #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
402 			n = mbedtls_gcm_starts(&ctx->u.ctx_gcm, (int)ctx->op,
403 					       iv_or_nonce_ctr_or_data_unit_16,
404 					       *nc_or_iv_off);
405 			if (!n)
406 				n = mbedtls_gcm_update_ad(&ctx->u.ctx_gcm,
407 							  in, len);
408 #else
409 			n = mbedtls_gcm_starts(&ctx->u.ctx_gcm, (int)ctx->op,
410 					       iv_or_nonce_ctr_or_data_unit_16,
411 					       *nc_or_iv_off, in, len);
412 #endif
413 			if (n) {
414 				lwsl_notice("%s: mbedtls_gcm_starts: -0x%x\n",
415 					    __func__, -n);
416 
417 				return -1;
418 			}
419 			break;
420 		}
421 
422 #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
423 		{
424 			size_t al;
425 
426 			n = mbedtls_gcm_update(&ctx->u.ctx_gcm, in, len, out, len, &al);
427 		}
428 #else
429 		n = mbedtls_gcm_update(&ctx->u.ctx_gcm, len, in, out);
430 #endif
431 		if (n) {
432 			lwsl_notice("%s: mbedtls_gcm_update: -0x%x\n",
433 				    __func__, -n);
434 
435 			return -1;
436 		}
437 		break;
438 	}
439 
440 	if (n) {
441 		lwsl_notice("%s: failed: -0x%x, len %d\n", __func__, -n, (int)len);
442 
443 		return -1;
444 	}
445 
446 	return 0;
447 }
448