xref: /aosp_15_r20/external/libwebsockets/lib/tls/openssl/lws-genaes.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker  /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  *
24*1c60b9acSAndroid Build Coastguard Worker  *  lws_genaes provides an AES abstraction api in lws that works the
25*1c60b9acSAndroid Build Coastguard Worker  *  same whether you are using openssl or mbedtls hash functions underneath.
26*1c60b9acSAndroid Build Coastguard Worker  */
27*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
28*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_JOSE)
29*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-jose.h"
30*1c60b9acSAndroid Build Coastguard Worker #endif
31*1c60b9acSAndroid Build Coastguard Worker 
32*1c60b9acSAndroid Build Coastguard Worker /*
33*1c60b9acSAndroid Build Coastguard Worker  * Care: many openssl apis return 1 for success.  These are translated to the
34*1c60b9acSAndroid Build Coastguard Worker  * lws convention of 0 for success.
35*1c60b9acSAndroid Build Coastguard Worker  */
36*1c60b9acSAndroid Build Coastguard Worker 
37*1c60b9acSAndroid Build Coastguard Worker 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*1c60b9acSAndroid Build Coastguard Worker lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op,
39*1c60b9acSAndroid Build Coastguard Worker 		  enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el,
40*1c60b9acSAndroid Build Coastguard Worker 		  enum enum_aes_padding padding, void *engine)
41*1c60b9acSAndroid Build Coastguard Worker {
42*1c60b9acSAndroid Build Coastguard Worker 	int n = 0;
43*1c60b9acSAndroid Build Coastguard Worker 
44*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx = EVP_CIPHER_CTX_new();
45*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->ctx)
46*1c60b9acSAndroid Build Coastguard Worker 		return -1;
47*1c60b9acSAndroid Build Coastguard Worker 
48*1c60b9acSAndroid Build Coastguard Worker 	ctx->mode = mode;
49*1c60b9acSAndroid Build Coastguard Worker 	ctx->k = el;
50*1c60b9acSAndroid Build Coastguard Worker 	ctx->engine = engine;
51*1c60b9acSAndroid Build Coastguard Worker 	ctx->init = 0;
52*1c60b9acSAndroid Build Coastguard Worker 	ctx->op = op;
53*1c60b9acSAndroid Build Coastguard Worker 	ctx->padding = padding;
54*1c60b9acSAndroid Build Coastguard Worker 
55*1c60b9acSAndroid Build Coastguard Worker 	switch (ctx->k->len) {
56*1c60b9acSAndroid Build Coastguard Worker 	case 128 / 8:
57*1c60b9acSAndroid Build Coastguard Worker 		switch (mode) {
58*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_KW:
59*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_wrap)
60*1c60b9acSAndroid Build Coastguard Worker 			EVP_CIPHER_CTX_set_flags(ctx->ctx,
61*1c60b9acSAndroid Build Coastguard Worker 						EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
62*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_wrap();
63*1c60b9acSAndroid Build Coastguard Worker 			break;
64*1c60b9acSAndroid Build Coastguard Worker #else
65*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
66*1c60b9acSAndroid Build Coastguard Worker 				 __func__);
67*1c60b9acSAndroid Build Coastguard Worker 			return -1;
68*1c60b9acSAndroid Build Coastguard Worker #endif
69*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CBC:
70*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_cbc();
71*1c60b9acSAndroid Build Coastguard Worker 			break;
72*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_cfb128)
73*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CFB128:
74*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_cfb128();
75*1c60b9acSAndroid Build Coastguard Worker 			break;
76*1c60b9acSAndroid Build Coastguard Worker #endif
77*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_cfb8)
78*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CFB8:
79*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_cfb8();
80*1c60b9acSAndroid Build Coastguard Worker 			break;
81*1c60b9acSAndroid Build Coastguard Worker #endif
82*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ctr)
83*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CTR:
84*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_ctr();
85*1c60b9acSAndroid Build Coastguard Worker 			break;
86*1c60b9acSAndroid Build Coastguard Worker #endif
87*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ecb)
88*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_ECB:
89*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_ecb();
90*1c60b9acSAndroid Build Coastguard Worker 			break;
91*1c60b9acSAndroid Build Coastguard Worker #endif
92*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ofb)
93*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_OFB:
94*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_ofb();
95*1c60b9acSAndroid Build Coastguard Worker 			break;
96*1c60b9acSAndroid Build Coastguard Worker #endif
97*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_xts)
98*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_XTS:
99*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: AES XTS requires double-length key\n",
100*1c60b9acSAndroid Build Coastguard Worker 				 __func__);
101*1c60b9acSAndroid Build Coastguard Worker 			break;
102*1c60b9acSAndroid Build Coastguard Worker #endif
103*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_GCM:
104*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_gcm();
105*1c60b9acSAndroid Build Coastguard Worker 			break;
106*1c60b9acSAndroid Build Coastguard Worker 		default:
107*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
108*1c60b9acSAndroid Build Coastguard Worker 		}
109*1c60b9acSAndroid Build Coastguard Worker 		break;
110*1c60b9acSAndroid Build Coastguard Worker 
111*1c60b9acSAndroid Build Coastguard Worker 	case 192 / 8:
112*1c60b9acSAndroid Build Coastguard Worker 		switch (mode) {
113*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_KW:
114*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_wrap)
115*1c60b9acSAndroid Build Coastguard Worker 			EVP_CIPHER_CTX_set_flags(ctx->ctx,
116*1c60b9acSAndroid Build Coastguard Worker 						EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
117*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_wrap();
118*1c60b9acSAndroid Build Coastguard Worker 			break;
119*1c60b9acSAndroid Build Coastguard Worker #else
120*1c60b9acSAndroid Build Coastguard Worker                         lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
121*1c60b9acSAndroid Build Coastguard Worker                                  __func__);
122*1c60b9acSAndroid Build Coastguard Worker                         return -1;
123*1c60b9acSAndroid Build Coastguard Worker #endif
124*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CBC:
125*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_cbc();
126*1c60b9acSAndroid Build Coastguard Worker 			break;
127*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_192_cfb128)
128*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CFB128:
129*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_cfb128();
130*1c60b9acSAndroid Build Coastguard Worker 			break;
131*1c60b9acSAndroid Build Coastguard Worker #endif
132*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_192_cfb8)
133*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CFB8:
134*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_cfb8();
135*1c60b9acSAndroid Build Coastguard Worker 			break;
136*1c60b9acSAndroid Build Coastguard Worker #endif
137*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ctr)
138*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CTR:
139*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_ctr();
140*1c60b9acSAndroid Build Coastguard Worker 			break;
141*1c60b9acSAndroid Build Coastguard Worker #endif
142*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ecb)
143*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_ECB:
144*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_ecb();
145*1c60b9acSAndroid Build Coastguard Worker 			break;
146*1c60b9acSAndroid Build Coastguard Worker #endif
147*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ofb)
148*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_OFB:
149*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_ofb();
150*1c60b9acSAndroid Build Coastguard Worker 			break;
151*1c60b9acSAndroid Build Coastguard Worker #endif
152*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_xts)
153*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_XTS:
154*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: AES XTS 192 invalid\n", __func__);
155*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
156*1c60b9acSAndroid Build Coastguard Worker #endif
157*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_GCM:
158*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_192_gcm();
159*1c60b9acSAndroid Build Coastguard Worker 			break;
160*1c60b9acSAndroid Build Coastguard Worker 		default:
161*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
162*1c60b9acSAndroid Build Coastguard Worker 		}
163*1c60b9acSAndroid Build Coastguard Worker 		break;
164*1c60b9acSAndroid Build Coastguard Worker 
165*1c60b9acSAndroid Build Coastguard Worker 	case 256 / 8:
166*1c60b9acSAndroid Build Coastguard Worker 		switch (mode) {
167*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_KW:
168*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_wrap)
169*1c60b9acSAndroid Build Coastguard Worker 			EVP_CIPHER_CTX_set_flags(ctx->ctx,
170*1c60b9acSAndroid Build Coastguard Worker 						EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
171*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_wrap();
172*1c60b9acSAndroid Build Coastguard Worker 			break;
173*1c60b9acSAndroid Build Coastguard Worker #else
174*1c60b9acSAndroid Build Coastguard Worker                         lwsl_err("%s: your OpenSSL lacks AES wrap apis, update it\n",
175*1c60b9acSAndroid Build Coastguard Worker                                  __func__);
176*1c60b9acSAndroid Build Coastguard Worker                         return -1;
177*1c60b9acSAndroid Build Coastguard Worker #endif
178*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CBC:
179*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_cbc();
180*1c60b9acSAndroid Build Coastguard Worker 			break;
181*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_256_cfb128)
182*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CFB128:
183*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_cfb128();
184*1c60b9acSAndroid Build Coastguard Worker 			break;
185*1c60b9acSAndroid Build Coastguard Worker #endif
186*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_256_cfb8)
187*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CFB8:
188*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_cfb8();
189*1c60b9acSAndroid Build Coastguard Worker 			break;
190*1c60b9acSAndroid Build Coastguard Worker #endif
191*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ctr)
192*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_CTR:
193*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_ctr();
194*1c60b9acSAndroid Build Coastguard Worker 			break;
195*1c60b9acSAndroid Build Coastguard Worker #endif
196*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ecb)
197*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_ECB:
198*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_ecb();
199*1c60b9acSAndroid Build Coastguard Worker 			break;
200*1c60b9acSAndroid Build Coastguard Worker #endif
201*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_ofb)
202*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_OFB:
203*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_ofb();
204*1c60b9acSAndroid Build Coastguard Worker 			break;
205*1c60b9acSAndroid Build Coastguard Worker #endif
206*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_xts)
207*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_XTS:
208*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_128_xts();
209*1c60b9acSAndroid Build Coastguard Worker 			break;
210*1c60b9acSAndroid Build Coastguard Worker #endif
211*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_GCM:
212*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_gcm();
213*1c60b9acSAndroid Build Coastguard Worker 			break;
214*1c60b9acSAndroid Build Coastguard Worker 		default:
215*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
216*1c60b9acSAndroid Build Coastguard Worker 		}
217*1c60b9acSAndroid Build Coastguard Worker 		break;
218*1c60b9acSAndroid Build Coastguard Worker 
219*1c60b9acSAndroid Build Coastguard Worker 	case 512 / 8:
220*1c60b9acSAndroid Build Coastguard Worker 		switch (mode) {
221*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVP_aes_128_xts)
222*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESM_XTS:
223*1c60b9acSAndroid Build Coastguard Worker 			ctx->cipher = EVP_aes_256_xts();
224*1c60b9acSAndroid Build Coastguard Worker #endif
225*1c60b9acSAndroid Build Coastguard Worker 			break;
226*1c60b9acSAndroid Build Coastguard Worker 		default:
227*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
228*1c60b9acSAndroid Build Coastguard Worker 		}
229*1c60b9acSAndroid Build Coastguard Worker 	break;
230*1c60b9acSAndroid Build Coastguard Worker 
231*1c60b9acSAndroid Build Coastguard Worker 	default:
232*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unsupported AES size %d bits\n", __func__,
233*1c60b9acSAndroid Build Coastguard Worker 			 ctx->k->len * 8);
234*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
235*1c60b9acSAndroid Build Coastguard Worker 	}
236*1c60b9acSAndroid Build Coastguard Worker 
237*1c60b9acSAndroid Build Coastguard Worker 	switch (ctx->op) {
238*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GAESO_ENC:
239*1c60b9acSAndroid Build Coastguard Worker 		n = EVP_EncryptInit_ex(ctx->ctx, ctx->cipher, ctx->engine,
240*1c60b9acSAndroid Build Coastguard Worker 				       NULL, NULL);
241*1c60b9acSAndroid Build Coastguard Worker 		EVP_CIPHER_CTX_set_padding(ctx->ctx, (int)padding);
242*1c60b9acSAndroid Build Coastguard Worker 		break;
243*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GAESO_DEC:
244*1c60b9acSAndroid Build Coastguard Worker 		n = EVP_DecryptInit_ex(ctx->ctx, ctx->cipher, ctx->engine,
245*1c60b9acSAndroid Build Coastguard Worker 				       NULL, NULL);
246*1c60b9acSAndroid Build Coastguard Worker 		EVP_CIPHER_CTX_set_padding(ctx->ctx, (int)padding);
247*1c60b9acSAndroid Build Coastguard Worker 		break;
248*1c60b9acSAndroid Build Coastguard Worker 	}
249*1c60b9acSAndroid Build Coastguard Worker 	if (!n) {
250*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: cipher init failed (cipher %p)\n", __func__,
251*1c60b9acSAndroid Build Coastguard Worker 			 ctx->cipher);
252*1c60b9acSAndroid Build Coastguard Worker 		lws_tls_err_describe_clear();
253*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
254*1c60b9acSAndroid Build Coastguard Worker 	}
255*1c60b9acSAndroid Build Coastguard Worker 
256*1c60b9acSAndroid Build Coastguard Worker 	return 0;
257*1c60b9acSAndroid Build Coastguard Worker bail:
258*1c60b9acSAndroid Build Coastguard Worker 	EVP_CIPHER_CTX_free(ctx->ctx);
259*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx = NULL;
260*1c60b9acSAndroid Build Coastguard Worker 	return -1;
261*1c60b9acSAndroid Build Coastguard Worker }
262*1c60b9acSAndroid Build Coastguard Worker 
263*1c60b9acSAndroid Build Coastguard Worker int
lws_genaes_destroy(struct lws_genaes_ctx * ctx,unsigned char * tag,size_t tlen)264*1c60b9acSAndroid Build Coastguard Worker lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen)
265*1c60b9acSAndroid Build Coastguard Worker {
266*1c60b9acSAndroid Build Coastguard Worker 	uint8_t buf[256];
267*1c60b9acSAndroid Build Coastguard Worker 	int outl = sizeof(buf), n = 0;
268*1c60b9acSAndroid Build Coastguard Worker 
269*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->ctx)
270*1c60b9acSAndroid Build Coastguard Worker 		return 0;
271*1c60b9acSAndroid Build Coastguard Worker 
272*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->init) {
273*1c60b9acSAndroid Build Coastguard Worker 		switch (ctx->op) {
274*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESO_ENC:
275*1c60b9acSAndroid Build Coastguard Worker 
276*1c60b9acSAndroid Build Coastguard Worker 			if (EVP_EncryptFinal_ex(ctx->ctx, buf, &outl) != 1) {
277*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: enc final failed\n", __func__);
278*1c60b9acSAndroid Build Coastguard Worker 				n = -1;
279*1c60b9acSAndroid Build Coastguard Worker 			}
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker 			if (ctx->mode == LWS_GAESM_GCM) {
282*1c60b9acSAndroid Build Coastguard Worker 				if (EVP_CIPHER_CTX_ctrl(ctx->ctx,
283*1c60b9acSAndroid Build Coastguard Worker 						EVP_CTRL_GCM_GET_TAG,
284*1c60b9acSAndroid Build Coastguard Worker 						    ctx->taglen, tag) != 1) {
285*1c60b9acSAndroid Build Coastguard Worker 					lwsl_err("get tag ctrl failed\n");
286*1c60b9acSAndroid Build Coastguard Worker 					//lws_tls_err_describe_clear();
287*1c60b9acSAndroid Build Coastguard Worker 					n = 1;
288*1c60b9acSAndroid Build Coastguard Worker 				}
289*1c60b9acSAndroid Build Coastguard Worker 			}
290*1c60b9acSAndroid Build Coastguard Worker 			if (ctx->mode == LWS_GAESM_CBC)
291*1c60b9acSAndroid Build Coastguard Worker 				memcpy(tag, buf, (unsigned int)outl);
292*1c60b9acSAndroid Build Coastguard Worker 
293*1c60b9acSAndroid Build Coastguard Worker 			break;
294*1c60b9acSAndroid Build Coastguard Worker 
295*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESO_DEC:
296*1c60b9acSAndroid Build Coastguard Worker 			if (EVP_DecryptFinal_ex(ctx->ctx, buf, &outl) != 1) {
297*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: dec final failed\n", __func__);
298*1c60b9acSAndroid Build Coastguard Worker 				lws_tls_err_describe_clear();
299*1c60b9acSAndroid Build Coastguard Worker 				n = -1;
300*1c60b9acSAndroid Build Coastguard Worker 			}
301*1c60b9acSAndroid Build Coastguard Worker 
302*1c60b9acSAndroid Build Coastguard Worker 			break;
303*1c60b9acSAndroid Build Coastguard Worker 		}
304*1c60b9acSAndroid Build Coastguard Worker 		if (outl)
305*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: final len %d\n", __func__, outl);
306*1c60b9acSAndroid Build Coastguard Worker 	}
307*1c60b9acSAndroid Build Coastguard Worker 
308*1c60b9acSAndroid Build Coastguard Worker 	ctx->k = NULL;
309*1c60b9acSAndroid Build Coastguard Worker 	EVP_CIPHER_CTX_free(ctx->ctx);
310*1c60b9acSAndroid Build Coastguard Worker 	ctx->ctx = NULL;
311*1c60b9acSAndroid Build Coastguard Worker 
312*1c60b9acSAndroid Build Coastguard Worker 	return n;
313*1c60b9acSAndroid Build Coastguard Worker }
314*1c60b9acSAndroid Build Coastguard Worker 
315*1c60b9acSAndroid Build Coastguard Worker 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*1c60b9acSAndroid Build Coastguard Worker lws_genaes_crypt(struct lws_genaes_ctx *ctx,
317*1c60b9acSAndroid Build Coastguard Worker 		 const uint8_t *in, size_t len, uint8_t *out,
318*1c60b9acSAndroid Build Coastguard Worker 		 uint8_t *iv_or_nonce_ctr_or_data_unit_16,
319*1c60b9acSAndroid Build Coastguard Worker 		 uint8_t *stream_block_16, size_t *nc_or_iv_off, int taglen)
320*1c60b9acSAndroid Build Coastguard Worker {
321*1c60b9acSAndroid Build Coastguard Worker 	int n = 0, outl, olen;
322*1c60b9acSAndroid Build Coastguard Worker 
323*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->init) {
324*1c60b9acSAndroid Build Coastguard Worker 
325*1c60b9acSAndroid Build Coastguard Worker 		EVP_CIPHER_CTX_set_key_length(ctx->ctx, (int)ctx->k->len);
326*1c60b9acSAndroid Build Coastguard Worker 
327*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->mode == LWS_GAESM_GCM) {
328*1c60b9acSAndroid Build Coastguard Worker 			n = EVP_CIPHER_CTX_ctrl(ctx->ctx, EVP_CTRL_GCM_SET_IVLEN,
329*1c60b9acSAndroid Build Coastguard Worker 					   (int)*nc_or_iv_off, NULL);
330*1c60b9acSAndroid Build Coastguard Worker 			if (n != 1) {
331*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: SET_IVLEN failed\n", __func__);
332*1c60b9acSAndroid Build Coastguard Worker 				return -1;
333*1c60b9acSAndroid Build Coastguard Worker 			}
334*1c60b9acSAndroid Build Coastguard Worker 			memcpy(ctx->tag, stream_block_16, (unsigned int)taglen);
335*1c60b9acSAndroid Build Coastguard Worker 			ctx->taglen = taglen;
336*1c60b9acSAndroid Build Coastguard Worker 		}
337*1c60b9acSAndroid Build Coastguard Worker 
338*1c60b9acSAndroid Build Coastguard Worker 		switch (ctx->op) {
339*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESO_ENC:
340*1c60b9acSAndroid Build Coastguard Worker 			n = EVP_EncryptInit_ex(ctx->ctx, NULL, NULL,
341*1c60b9acSAndroid Build Coastguard Worker 					       ctx->k->buf,
342*1c60b9acSAndroid Build Coastguard Worker 					       iv_or_nonce_ctr_or_data_unit_16);
343*1c60b9acSAndroid Build Coastguard Worker 			break;
344*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESO_DEC:
345*1c60b9acSAndroid Build Coastguard Worker 			if (ctx->mode == LWS_GAESM_GCM)
346*1c60b9acSAndroid Build Coastguard Worker 				EVP_CIPHER_CTX_ctrl(ctx->ctx,
347*1c60b9acSAndroid Build Coastguard Worker 						    EVP_CTRL_GCM_SET_TAG,
348*1c60b9acSAndroid Build Coastguard Worker 						    ctx->taglen, ctx->tag);
349*1c60b9acSAndroid Build Coastguard Worker 			n = EVP_DecryptInit_ex(ctx->ctx, NULL, NULL,
350*1c60b9acSAndroid Build Coastguard Worker 					       ctx->k->buf,
351*1c60b9acSAndroid Build Coastguard Worker 					       iv_or_nonce_ctr_or_data_unit_16);
352*1c60b9acSAndroid Build Coastguard Worker 			break;
353*1c60b9acSAndroid Build Coastguard Worker 		}
354*1c60b9acSAndroid Build Coastguard Worker 
355*1c60b9acSAndroid Build Coastguard Worker 		if (!n) {
356*1c60b9acSAndroid Build Coastguard Worker 			lws_tls_err_describe_clear();
357*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: init failed (cipher %p)\n",
358*1c60b9acSAndroid Build Coastguard Worker 				 __func__, ctx->cipher);
359*1c60b9acSAndroid Build Coastguard Worker 
360*1c60b9acSAndroid Build Coastguard Worker 			return -1;
361*1c60b9acSAndroid Build Coastguard Worker 		}
362*1c60b9acSAndroid Build Coastguard Worker 		ctx->init = 1;
363*1c60b9acSAndroid Build Coastguard Worker 	}
364*1c60b9acSAndroid Build Coastguard Worker 
365*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->mode == LWS_GAESM_GCM && !out) {
366*1c60b9acSAndroid Build Coastguard Worker 		/* AAD */
367*1c60b9acSAndroid Build Coastguard Worker 
368*1c60b9acSAndroid Build Coastguard Worker 		if (!len)
369*1c60b9acSAndroid Build Coastguard Worker 			return 0;
370*1c60b9acSAndroid Build Coastguard Worker 
371*1c60b9acSAndroid Build Coastguard Worker 		switch (ctx->op) {
372*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESO_ENC:
373*1c60b9acSAndroid Build Coastguard Worker 			n = EVP_EncryptUpdate(ctx->ctx, NULL, &olen, in, (int)len);
374*1c60b9acSAndroid Build Coastguard Worker 			break;
375*1c60b9acSAndroid Build Coastguard Worker 		case LWS_GAESO_DEC:
376*1c60b9acSAndroid Build Coastguard Worker 			n = EVP_DecryptUpdate(ctx->ctx, NULL, &olen, in, (int)len);
377*1c60b9acSAndroid Build Coastguard Worker 			break;
378*1c60b9acSAndroid Build Coastguard Worker 		default:
379*1c60b9acSAndroid Build Coastguard Worker 			return -1;
380*1c60b9acSAndroid Build Coastguard Worker 		}
381*1c60b9acSAndroid Build Coastguard Worker 		if (n != 1) {
382*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: set AAD failed\n",  __func__);
383*1c60b9acSAndroid Build Coastguard Worker 			lws_tls_err_describe_clear();
384*1c60b9acSAndroid Build Coastguard Worker 			lwsl_hexdump_err(in, len);
385*1c60b9acSAndroid Build Coastguard Worker 			return -1;
386*1c60b9acSAndroid Build Coastguard Worker 		}
387*1c60b9acSAndroid Build Coastguard Worker 
388*1c60b9acSAndroid Build Coastguard Worker 		return 0;
389*1c60b9acSAndroid Build Coastguard Worker 	}
390*1c60b9acSAndroid Build Coastguard Worker 
391*1c60b9acSAndroid Build Coastguard Worker 	switch (ctx->op) {
392*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GAESO_ENC:
393*1c60b9acSAndroid Build Coastguard Worker 		n = EVP_EncryptUpdate(ctx->ctx, out, &outl, in, (int)len);
394*1c60b9acSAndroid Build Coastguard Worker 		break;
395*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GAESO_DEC:
396*1c60b9acSAndroid Build Coastguard Worker 		n = EVP_DecryptUpdate(ctx->ctx, out, &outl, in, (int)len);
397*1c60b9acSAndroid Build Coastguard Worker 		break;
398*1c60b9acSAndroid Build Coastguard Worker 	default:
399*1c60b9acSAndroid Build Coastguard Worker 		return -1;
400*1c60b9acSAndroid Build Coastguard Worker 	}
401*1c60b9acSAndroid Build Coastguard Worker 
402*1c60b9acSAndroid Build Coastguard Worker 	// lwsl_notice("discarding outl %d\n", (int)outl);
403*1c60b9acSAndroid Build Coastguard Worker 
404*1c60b9acSAndroid Build Coastguard Worker 	if (!n) {
405*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: update failed\n", __func__);
406*1c60b9acSAndroid Build Coastguard Worker 		lws_tls_err_describe_clear();
407*1c60b9acSAndroid Build Coastguard Worker 
408*1c60b9acSAndroid Build Coastguard Worker 		return -1;
409*1c60b9acSAndroid Build Coastguard Worker 	}
410*1c60b9acSAndroid Build Coastguard Worker 
411*1c60b9acSAndroid Build Coastguard Worker 	return 0;
412*1c60b9acSAndroid Build Coastguard Worker }
413