• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * lws-api-test-jose - RFC7516 jwe tests
3  *
4  * Written in 2010-2020 by Andy Green <andy@warmcat.com>
5  *
6  * This file is made available under the Creative Commons CC0 1.0
7  * Universal Public Domain Dedication.
8  */
9 
10 #include <libwebsockets.h>
11 
12 /*
13  * These are the inputs and outputs from the worked example in RFC7516
14  * Appendix A.1   {"alg":"RSA-OAEP","enc":"A256GCM"}
15  */
16 
17 
18 static char
19 
20 *ex_a1_ptext =
21 	"The true sign of intelligence is not knowledge but imagination.",
22 
23 *ex_a1_compact =
24 	"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ."
25 	"OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe"
26 	"ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb"
27 	"Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV"
28 	"mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8"
29 	"1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi"
30 	"6UklfCpIMfIjf7iGdXKHzg."
31 	"48V1_ALb6US04U3b."
32 	"5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji"
33 	"SdiwkIr3ajwQzaBtQD_A."
34 	"XFBoMYUZodetZdvTiFvSkQ",
35 
36 	*ex_a1_jwk_json =
37 	"{\"kty\":\"RSA\","
38 	  "\"n\":\"oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW"
39 		"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S"
40 		"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a"
41 		"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS"
42 		"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj"
43 		"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw\","
44 	  "\"e\":\"AQAB\","
45 	  "\"d\":\"kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N"
46 		"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9"
47 		"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk"
48 		"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl"
49 		"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd"
50 		"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ\","
51 	  "\"p\":\"1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ-"
52 		"SWxkbkmoEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lf"
53 		"fNn03IXqWF5MDFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0\","
54 	  "\"q\":\"wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBm"
55 		"UDdaDYVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aX"
56 		"IWxKwd4gvxFImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc\","
57 	  "\"dp\":\"ZK-YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KL"
58 		"hMXvo-uz-KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827"
59 		"rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE\","
60 	  "\"dq\":\"Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCj"
61 		"ywcMlYYg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDB"
62 		"UfCAiJVeESOjJDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis\","
63 	  "\"qi\":\"VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8-ZW1FxU7"
64 		"AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3"
65 		"eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY\""
66 	"}"
67 ;
68 
69 static int
test_jwe_a1(struct lws_context * context)70 test_jwe_a1(struct lws_context *context)
71 {
72 	struct lws_jwe jwe;
73 	char temp[2048], compact[2048];
74 	int n, ret = -1, temp_len = sizeof(temp);
75 
76 	lws_jwe_init(&jwe, context);
77 
78 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, ex_a1_jwk_json,
79 			   strlen(ex_a1_jwk_json)) < 0) {
80 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
81 		goto bail;
82 	}
83 
84 	/* converts a compact serialization to jws b64 + decoded maps */
85 	if (lws_jws_compact_decode(ex_a1_compact, (int)strlen(ex_a1_compact),
86 				   &jwe.jws.map, &jwe.jws.map_b64, temp,
87 				   &temp_len) != 5) {
88 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
89 		goto bail;
90 	}
91 
92 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
93 				     &temp_len);
94 	if (n < 0) {
95 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
96 			 __func__);
97 		goto bail;
98 	}
99 
100 	/* allowing for trailing padding, confirm the plaintext */
101 	if (jwe.jws.map.len[LJWE_CTXT] < strlen(ex_a1_ptext) ||
102 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ex_a1_ptext,
103 			        (uint32_t)strlen(ex_a1_ptext))) {
104 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
105 		lwsl_hexdump_notice(ex_a1_ptext, strlen(ex_a1_ptext));
106 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
107 				    jwe.jws.map.len[LJWE_CTXT]);
108 		goto bail;
109 	}
110 
111 	/*
112 	 * Canned decrypt worked properly... let's also try encoding the
113 	 * plaintext ourselves and decoding that...
114 	 */
115 	lws_jwe_destroy(&jwe);
116 	temp_len = sizeof(temp);
117 	lws_jwe_init(&jwe, context);
118 
119 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, ex_a1_jwk_json,
120 			   strlen(ex_a1_jwk_json)) < 0) {
121 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
122 		goto bail;
123 	}
124 
125 	if (lws_gencrypto_jwe_alg_to_definition("RSA-OAEP", &jwe.jose.alg)) {
126 		lwsl_err("Unknown cipher alg \"RSA-OAEP\"\n");
127 		goto bail;
128 	}
129 	if (lws_gencrypto_jwe_enc_to_definition("A256GCM", &jwe.jose.enc_alg)) {
130 		lwsl_err("Unknown payload enc alg \"A256GCM\"\n");
131 		goto bail;
132 	}
133 
134 	/* we require a JOSE-formatted header to do the encryption */
135 
136 	jwe.jws.map.buf[LJWS_JOSE] = temp;
137 	jwe.jws.map.len[LJWS_JOSE] = (uint32_t)lws_snprintf(temp, (unsigned int)temp_len,
138 			"{\"alg\":\"%s\",\"enc\":\"%s\"}", "RSA-OAEP", "A256GCM");
139 	temp_len -= (int)jwe.jws.map.len[LJWS_JOSE];
140 
141 	/*
142 	 * dup the plaintext into the ciphertext element, it will be
143 	 * encrypted in-place to a ciphertext of the same length
144 	 */
145 
146 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_CTXT,
147 				lws_concat_temp(temp, temp_len), &temp_len,
148 				ex_a1_ptext, strlen(ex_a1_ptext), 0)) {
149 		lwsl_notice("%s: Not enough temp space for ptext\n", __func__);
150 		goto bail;
151 	}
152 
153 	/* CEK size is determined by hash / hmac size */
154 
155 	n = lws_gencrypto_bits_to_bytes(jwe.jose.enc_alg->keybits_fixed);
156 	if (lws_jws_randomize_element(context, &jwe.jws.map, LJWE_EKEY,
157 				      lws_concat_temp(temp, temp_len),
158 				      &temp_len, (unsigned int)n,
159 				      LWS_JWE_LIMIT_KEY_ELEMENT_BYTES)) {
160 		lwsl_err("Problem getting random\n");
161 		goto bail;
162 	}
163 
164 	n = lws_jwe_encrypt(&jwe, lws_concat_temp(temp, temp_len),
165 			    &temp_len);
166 	if (n < 0) {
167 		lwsl_err("%s: lws_jwe_encrypt failed\n", __func__);
168 		goto bail;
169 	}
170 	n = lws_jwe_render_compact(&jwe, compact, sizeof(compact));
171 	if (n < 0) {
172 		lwsl_err("%s: lws_jwe_render_compact failed: %d\n",
173 			 __func__, n);
174 		goto bail;
175 	}
176 
177 	// puts(compact);
178 
179 	/*
180 	 * Okay... what happens when we try to decode what we created?
181 	 */
182 
183 	lws_jwe_destroy(&jwe);
184 	lws_jwe_init(&jwe, context);
185 	temp_len = sizeof(temp);
186 
187 	/* converts a compact serialization to jws b64 + decoded maps */
188 	if (lws_jws_compact_decode(compact, (int)strlen(compact), &jwe.jws.map,
189 				   &jwe.jws.map_b64, temp, &temp_len) != 5) {
190 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
191 		goto bail;
192 	}
193 
194 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, ex_a1_jwk_json,
195 			   strlen(ex_a1_jwk_json)) < 0) {
196 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
197 		goto bail;
198 	}
199 
200 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
201 				     &temp_len);
202 	if (n < 0) {
203 		lwsl_err("%s: generated lws_jwe_auth_and_decrypt failed\n",
204 			 __func__);
205 		goto bail;
206 	}
207 
208 	ret = 0;
209 
210 bail:
211 	lws_jwe_destroy(&jwe);
212 	if (ret)
213 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
214 	else
215 		lwsl_notice("%s: selftest OK\n", __func__);
216 
217 	return ret;
218 }
219 
220 
221 /* A.2.  Example JWE using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256
222  *
223  * This example encrypts the plaintext "Live long and prosper." to the
224  * recipient using RSAES-PKCS1-v1_5 for key encryption and
225  * AES_128_CBC_HMAC_SHA_256 for content encryption.
226  */
227 
228 /* "Live long and prosper." */
229 static uint8_t
230 
231 ex_a2_ptext[] = {
232 	76, 105, 118, 101, 32, 108, 111, 110,
233 	103, 32, 97, 110, 100, 32,  112, 114,
234 	111, 115, 112, 101, 114, 46
235 }, *lws_jwe_ex_a2_jwk_json = (uint8_t *)
236 	"{"
237 	 "\"kty\":\"RSA\","
238 	 "\"n\":\"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl"
239 		 "UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre"
240 		 "cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_"
241 		 "7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI"
242 		 "Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU"
243 		 "7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw\","
244 	 "\"e\":\"AQAB\","
245 	 "\"d\":\"VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq"
246 		 "1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry"
247 		 "nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_"
248 		 "0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj"
249 		 "-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj"
250 		 "T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ\","
251 	 "\"p\":\"9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68"
252 		 "ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP"
253 		 "krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM\","
254 	 "\"q\":\"uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y"
255 		 "BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN"
256 		 "-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0\","
257 	 "\"dp\":\"w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv"
258 		 "ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra"
259 		 "Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs\","
260 	 "\"dq\":\"o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff"
261 		 "7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_"
262 		 "odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU\","
263 	 "\"qi\":\"eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC"
264 		 "tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ"
265 		 "B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo\""
266 	"}",
267 
268 *ex_a2_compact = (uint8_t *)
269 	"eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0"
270 	"."
271 	"UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm"
272 	"1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc"
273 	"HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF"
274 	"NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8"
275 	"rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv"
276 	"-B3oWh2TbqmScqXMR4gp_A"
277 	"."
278 	"AxY8DCtDaGlsbGljb3RoZQ"
279 	"."
280 	"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY"
281 	"."
282 	"9hH0vgRfYgPnAHOd8stkvw"
283 ;
284 
285 static int
test_jwe_a2(struct lws_context * context)286 test_jwe_a2(struct lws_context *context)
287 {
288 	struct lws_jwe jwe;
289 	char temp[2048];
290 	int n, ret = -1, temp_len = sizeof(temp);
291 
292 	lws_jwe_init(&jwe, context);
293 
294 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, (char *)lws_jwe_ex_a2_jwk_json,
295 			   strlen((char *)lws_jwe_ex_a2_jwk_json)) < 0) {
296 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
297 		goto bail;
298 	}
299 
300 	/* converts a compact serialization to jws b64 + decoded maps */
301 	if (lws_jws_compact_decode((const char *)ex_a2_compact,
302 				   (int)strlen((char *)ex_a2_compact),
303 				   &jwe.jws.map, &jwe.jws.map_b64,
304 				   (char *)temp, &temp_len) != 5) {
305 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
306 		goto bail;
307 	}
308 
309 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
310 				     &temp_len);
311 	if (n < 0) {
312 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
313 			 __func__);
314 		goto bail;
315 	}
316 
317 	/* allowing for trailing padding, confirm the plaintext */
318 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(ex_a2_ptext) ||
319 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ex_a2_ptext,
320 			        sizeof(ex_a2_ptext))) {
321 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
322 		lwsl_hexdump_notice(ex_a2_ptext, sizeof(ex_a2_ptext));
323 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
324 				    jwe.jws.map.len[LJWE_CTXT]);
325 		goto bail;
326 	}
327 
328 	ret = 0;
329 
330 bail:
331 	lws_jwe_destroy(&jwe);
332 	if (ret)
333 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
334 	else
335 		lwsl_notice("%s: selftest OK\n", __func__);
336 
337 	return ret;
338 }
339 
340 /* JWE creation using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256
341  *
342  * This example encrypts a different, larger plaintext using the jwk key from
343  * the test above, and AES_128_CBC_HMAC_SHA_256 for content encryption.
344  */
345 
346 static const char *rsa256a128_jose =
347 		"{ \"alg\":\"RSA1_5\",\"enc\":\"A128CBC-HS256\"}";
348 
349 static uint8_t
350 
351 	/* plaintext is 1024 bytes from /dev/urandom */
352 
353 ra_ptext_1024[] = {
354 		0xfe, 0xc6, 0x4f, 0x3e, 0x4a, 0x19, 0xe9, 0xd7,
355 		0xc2, 0x13, 0xe7, 0xc5, 0x78, 0x6e, 0x71, 0xf6,
356 		0x6e, 0xdd, 0x04, 0xaf, 0xaa, 0x4e, 0xa8, 0xad,
357 		0xd8, 0xe0, 0xb3, 0x32, 0x97, 0x43, 0x7c, 0xd8,
358 		0xd1, 0x5f, 0x56, 0xac, 0x70, 0xaf, 0x7d, 0x0b,
359 		0x40, 0xa1, 0x96, 0x71, 0x7c, 0xc4, 0x4a, 0x37,
360 		0x0b, 0xa6, 0x06, 0xb3, 0x8c, 0x87, 0xee, 0xb6,
361 		0x15, 0xfe, 0xaa, 0x60, 0x7e, 0x7f, 0xdc, 0xb0,
362 		0xff, 0x96, 0x4b, 0x30, 0x60, 0xcf, 0xc6, 0x5d,
363 		0x09, 0x6a, 0x6f, 0x66, 0x0c, 0x5f, 0xb0, 0x6f,
364 		0x61, 0xa6, 0x26, 0x02, 0xbd, 0x46, 0xda, 0xa3,
365 		0x73, 0x19, 0x17, 0xff, 0xe0, 0x5f, 0x30, 0x72,
366 		0x7d, 0x17, 0xd8, 0xb2, 0xbe, 0x84, 0x3e, 0x4d,
367 		0x76, 0xbd, 0x62, 0x5d, 0x63, 0xfe, 0x11, 0x32,
368 		0x11, 0x41, 0xdc, 0xed, 0x96, 0xfd, 0x31, 0x38,
369 		0x6a, 0x84, 0x55, 0x7a, 0x33, 0x3f, 0x37, 0xc3,
370 		0x37, 0x7b, 0xc1, 0xb7, 0x89, 0x00, 0x39, 0xa6,
371 		0x94, 0x91, 0xb7, 0x19, 0x6b, 0x1d, 0x99, 0xeb,
372 		0xf6, 0x10, 0xb9, 0xd2, 0xcd, 0x15, 0x0d, 0xbc,
373 		0x24, 0x34, 0x9a, 0x52, 0x64, 0x21, 0x72, 0x1e,
374 		0x9a, 0x00, 0xf2, 0xcf, 0xf1, 0x7d, 0x1a, 0x12,
375 		0x8d, 0x39, 0xbc, 0xf9, 0x09, 0xfd, 0xd9, 0x22,
376 		0x27, 0x28, 0xe1, 0x3a, 0x0b, 0x82, 0xba, 0x9a,
377 		0xe5, 0x9d, 0xa8, 0x12, 0x6e, 0xf5, 0x4b, 0xc7,
378 		0x2b, 0x9c, 0xdc, 0xfe, 0xf3, 0xe8, 0x74, 0x65,
379 		0x3d, 0xe0, 0xaa, 0x64, 0xf3, 0x43, 0xa4, 0x88,
380 		0xa8, 0xbe, 0x60, 0xdb, 0xfd, 0x2d, 0x3b, 0x84,
381 		0x82, 0x8f, 0x4d, 0xbb, 0xe4, 0xa9, 0x59, 0xe3,
382 		0x6c, 0x52, 0x45, 0xe4, 0x34, 0xdb, 0x28, 0x0e,
383 		0x4a, 0x44, 0xb6, 0x9a, 0x25, 0x9b, 0x3b, 0xae,
384 		0xe1, 0x12, 0x1d, 0x1c, 0x66, 0x7d, 0xb9, 0x5b,
385 		0x5f, 0xc2, 0x4a, 0xaa, 0xd2, 0xe9, 0x65, 0xe2,
386 		0x85, 0x6f, 0xf6, 0x67, 0x66, 0x8e, 0x0b, 0xd2,
387 		0x60, 0xf8, 0x43, 0x60, 0x04, 0x9b, 0xa9, 0x3a,
388 		0x6a, 0x3c, 0x02, 0x3c, 0x08, 0x9d, 0x60, 0x1c,
389 		0xc4, 0x27, 0x3e, 0xff, 0xd0, 0x70, 0x94, 0x43,
390 		0x3e, 0x9e, 0x69, 0x19, 0x22, 0xf0, 0xec, 0x26,
391 		0x2d, 0xa5, 0x71, 0xf3, 0x92, 0x61, 0x95, 0xce,
392 		0xc3, 0xc0, 0xa0, 0xc3, 0x98, 0x22, 0xdd, 0x32,
393 		0x3c, 0x48, 0xcb, 0xd1, 0x61, 0xa0, 0xaa, 0x9a,
394 		0x7e, 0x5a, 0xfa, 0x26, 0x46, 0x49, 0xfc, 0x9c,
395 		0xaa, 0x21, 0x06, 0x45, 0xf1, 0xa0, 0xc9, 0xef,
396 		0x6b, 0x89, 0xf2, 0x01, 0x20, 0x54, 0xfa, 0x0a,
397 		0x23, 0xff, 0xbd, 0x64, 0x35, 0x94, 0xfd, 0x35,
398 		0x70, 0x52, 0x94, 0x66, 0xc5, 0xd0, 0x27, 0xc1,
399 		0x8f, 0x6d, 0xc4, 0xa3, 0x34, 0xc2, 0xea, 0xf0,
400 		0xb3, 0x0d, 0x6c, 0x13, 0xb5, 0xc9, 0x6e, 0x5c,
401 		0xeb, 0x8b, 0x7b, 0xf5, 0x21, 0x4c, 0xe3, 0xb7,
402 		0x73, 0x6d, 0x07, 0xaa, 0x44, 0xc4, 0xba, 0xc5,
403 		0xa5, 0x0e, 0x75, 0x28, 0xb7, 0x50, 0x22, 0x54,
404 		0xa7, 0xe1, 0x2e, 0xfd, 0x20, 0xcd, 0xa4, 0x31,
405 		0xa3, 0xb2, 0x73, 0x98, 0x7c, 0x3c, 0x8f, 0xa3,
406 		0x40, 0x8a, 0xaf, 0x31, 0xfa, 0xf9, 0x70, 0x4d,
407 		0x83, 0x10, 0xc4, 0xa0, 0x9c, 0xd6, 0xa3, 0xd5,
408 		0x07, 0xaf, 0xaf, 0x35, 0x15, 0xd0, 0x84, 0x09,
409 		0x20, 0x36, 0x88, 0xac, 0x6f, 0x16, 0x5e, 0x03,
410 		0xa9, 0xfc, 0xb3, 0x2d, 0x01, 0x57, 0xb3, 0xed,
411 		0x4b, 0x55, 0x2b, 0xbc, 0x92, 0x87, 0x3e, 0x27,
412 		0xc4, 0x2c, 0x44, 0xac, 0x05, 0x5f, 0x26, 0xe7,
413 		0xe9, 0xb0, 0x2d, 0x6b, 0x3c, 0x8c, 0xd2, 0xb4,
414 		0x3c, 0xb4, 0x86, 0xfe, 0x68, 0x99, 0x2a, 0x42,
415 		0xac, 0xa4, 0xb3, 0x89, 0x61, 0xb3, 0xd1, 0xdf,
416 		0x9b, 0x58, 0xc7, 0x81, 0x62, 0x87, 0x26, 0x52,
417 		0x51, 0xe7, 0x7d, 0x7c, 0x37, 0x14, 0xe5, 0x19,
418 		0x28, 0x34, 0x3e, 0x95, 0x17, 0x36, 0x12, 0xf9,
419 		0x5e, 0xc1, 0x3c, 0x9c, 0x28, 0x70, 0x06, 0xdf,
420 		0xc4, 0x6d, 0x25, 0x04, 0x46, 0xe0, 0x95, 0xf0,
421 		0xc8, 0x57, 0x48, 0x27, 0x26, 0xf3, 0xf7, 0x19,
422 		0xbe, 0xea, 0xb4, 0xd4, 0x64, 0xaf, 0x67, 0x7c,
423 		0xf5, 0xa9, 0xfb, 0x85, 0x4a, 0x43, 0x9c, 0x62,
424 		0x06, 0x5e, 0x28, 0x2a, 0x7b, 0x1e, 0xb3, 0x07,
425 		0xe7, 0x19, 0x32, 0xa4, 0x4e, 0xb4, 0xce, 0xe0,
426 		0x92, 0x56, 0xf5, 0x10, 0xcb, 0x56, 0x34, 0x4b,
427 		0x0d, 0xe1, 0xd3, 0x6d, 0xfe, 0xf0, 0x44, 0xf7,
428 		0x22, 0x1d, 0x5e, 0x6b, 0xa7, 0xa5, 0x83, 0x2e,
429 		0xeb, 0x14, 0xf2, 0xd7, 0x27, 0x5a, 0x2a, 0xd2,
430 		0x55, 0x35, 0xe6, 0x7e, 0xd9, 0x3b, 0xac, 0x4e,
431 		0x5a, 0x22, 0x46, 0xd5, 0x7b, 0x57, 0x9c, 0x58,
432 		0xfe, 0xd0, 0xda, 0xbf, 0x7d, 0xe9, 0x8c, 0xb7,
433 		0xba, 0x88, 0xf1, 0xc3, 0x82, 0x53, 0xc3, 0x66,
434 		0x20, 0x51, 0x12, 0xd3, 0xf9, 0xaf, 0xe9, 0xcb,
435 		0xc1, 0x7a, 0xe6, 0x22, 0x44, 0xa5, 0xdf, 0x18,
436 		0xb3, 0x6e, 0x6c, 0xba, 0xf3, 0xc6, 0x24, 0x5a,
437 		0x1c, 0x67, 0xa6, 0xa5, 0xb4, 0xb1, 0x35, 0xdf,
438 		0x5a, 0x60, 0x5c, 0x0b, 0x66, 0xd3, 0x1f, 0x4e,
439 		0x7c, 0xcb, 0x93, 0x7e, 0x2f, 0x6d, 0xbd, 0xce,
440 		0x26, 0x52, 0x44, 0xee, 0xbb, 0xd8, 0x8f, 0xf2,
441 		0x67, 0x38, 0x0d, 0x3b, 0xaa, 0x21, 0x73, 0xf8,
442 		0x3b, 0x54, 0x9d, 0x4e, 0x5e, 0xf1, 0xa2, 0x18,
443 		0x5a, 0xf1, 0x6c, 0x32, 0xbf, 0x0a, 0x73, 0x14,
444 		0x48, 0x4f, 0x56, 0xc0, 0x87, 0x6d, 0x3b, 0x16,
445 		0xcc, 0x3f, 0x44, 0x19, 0x85, 0x22, 0x43, 0x5f,
446 		0x8c, 0x29, 0xbd, 0xa0, 0xce, 0x84, 0xd9, 0x4a,
447 		0xcf, 0x00, 0x6b, 0x37, 0x35, 0xe0, 0xb3, 0xc9,
448 		0xd1, 0x58, 0xd1, 0x1b, 0xc3, 0x6f, 0xe3, 0x50,
449 		0xdb, 0xa6, 0x5e, 0x03, 0x18, 0xe5, 0xe2, 0xc1,
450 		0x97, 0xd5, 0xf8, 0x42, 0x6f, 0xe6, 0x61, 0x80,
451 		0xc9, 0x7c, 0xc6, 0x83, 0xf0, 0xad, 0x70, 0x13,
452 		0x0e, 0x26, 0x75, 0xc0, 0x12, 0x23, 0x14, 0xef,
453 		0x1f, 0xdf, 0xfd, 0x47, 0x99, 0x9f, 0x22, 0xf3,
454 		0x57, 0x21, 0xdc, 0x38, 0xe4, 0x79, 0x87, 0x5b,
455 		0x67, 0x66, 0xdd, 0x0b, 0xe0, 0xae, 0xb5, 0x97,
456 		0xd8, 0xa6, 0x5d, 0x02, 0xcf, 0x6b, 0x84, 0x19,
457 		0xc1, 0xbb, 0x25, 0xd2, 0x10, 0xb9, 0x63, 0xeb,
458 		0x4b, 0x27, 0x8d, 0x05, 0x31, 0xce, 0x3b, 0x0c,
459 		0x5f, 0xd4, 0x83, 0x47, 0xa4, 0x8b, 0xc4, 0x76,
460 		0x33, 0x74, 0x1a, 0x07, 0xf8, 0x18, 0x82, 0x1c,
461 		0x8e, 0x01, 0x75, 0x78, 0xea, 0xd9, 0x72, 0x61,
462 		0x71, 0xa9, 0x09, 0x44, 0x7b, 0x0f, 0x12, 0xcf,
463 		0x4c, 0x76, 0x7b, 0x69, 0xc8, 0x64, 0x98, 0x60,
464 		0x45, 0xb6, 0xc7, 0x6b, 0xd8, 0x43, 0x99, 0x08,
465 		0xc9, 0xd3, 0x6f, 0x01, 0x4f, 0x57, 0x6f, 0x49,
466 		0x4f, 0x4f, 0x72, 0xa4, 0xa2, 0x45, 0xe1, 0x0e,
467 		0xf2, 0x08, 0x3e, 0x67, 0xc3, 0x83, 0x5b, 0xb1,
468 		0x24, 0xc0, 0xe0, 0x3a, 0xf5, 0x1f, 0xf2, 0x06,
469 		0x4b, 0xa7, 0x6f, 0xd2, 0xb2, 0x81, 0x96, 0x91,
470 		0x42, 0xb1, 0x53, 0x65, 0x3a, 0x12, 0xcd, 0x33,
471 		0xb3, 0x7e, 0x79, 0xc0, 0x46, 0xf6, 0xd8, 0x4a,
472 		0x22, 0x35, 0xb8, 0x3f, 0xe4, 0x08, 0x88, 0x49,
473 		0x3c, 0x73, 0x9a, 0x44, 0xe3, 0x3b, 0xcc, 0xc4,
474 		0xae, 0x7c, 0xbe, 0xfd, 0xa6, 0x4a, 0xd4, 0x26,
475 		0x52, 0x58, 0x81, 0x30, 0x66, 0x44, 0x54, 0xc8,
476 		0xe4, 0x7c, 0x5b, 0x63, 0x06, 0x60, 0x94, 0x62,
477 		0xe5, 0x47, 0x45, 0xfb, 0x58, 0xf5, 0x6a, 0x7c,
478 		0xb2, 0x35, 0x08, 0x03, 0x15, 0x68, 0xb3, 0x13,
479 		0xa5, 0xbd, 0xf2, 0x1e, 0x2e, 0x1c, 0x8f, 0xc6,
480 		0xc7, 0xd1, 0xa9, 0x64, 0x37, 0x2b, 0x23, 0xfa,
481 		0x7e, 0x56, 0x22, 0xf0, 0x8a, 0xbd, 0xeb, 0x04
482 },
483 
484 r256a128_cek[] = {
485 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
486 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
487 		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
488 		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
489 }
490 ;
491 
492 static int
test_jwe_ra_ptext_1024(struct lws_context * context,char * jwk_txt,int jwk_len)493 test_jwe_ra_ptext_1024(struct lws_context *context, char *jwk_txt, int jwk_len)
494 {
495 	char temp[4096], compact[4096];
496 	struct lws_jwe jwe;
497 	int n, ret = -1, temp_len = sizeof(temp);
498 
499 	lws_jwe_init(&jwe, context);
500 
501 	/* reuse the rsa private key from the JWE Appendix 2 test above */
502 
503 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, jwk_txt, (unsigned int)jwk_len) < 0) {
504 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
505 		goto bail;
506 	}
507 
508 	/* dup the plaintext, it will be replaced in-situ by the ciphertext */
509 
510 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_CTXT,
511 				lws_concat_temp(temp, temp_len), &temp_len,
512 				ra_ptext_1024, sizeof(ra_ptext_1024),
513 				lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN,
514 						      sizeof(ra_ptext_1024)))) {
515 		lwsl_notice("%s: Not enough temp space for ptext\n", __func__);
516 		goto bail;
517 	}
518 
519 	/* dup the cek, since it will be replaced by the encrypted key */
520 
521 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_EKEY,
522 				lws_concat_temp(temp, temp_len), &temp_len,
523 				r256a128_cek, sizeof(r256a128_cek),
524 				LWS_JWE_LIMIT_KEY_ELEMENT_BYTES)) {
525 		lwsl_notice("%s: Not enough temp space for EKEY\n", __func__);
526 		goto bail;
527 	}
528 
529 	jwe.jws.map.buf[LJWE_JOSE] = rsa256a128_jose;
530 	jwe.jws.map.len[LJWE_JOSE] = (uint32_t)strlen(rsa256a128_jose);
531 
532 	n = lws_jwe_parse_jose(&jwe.jose, jwe.jws.map.buf[LJWE_JOSE],
533 			       (int)jwe.jws.map.len[LJWE_JOSE],
534 			       lws_concat_temp(temp, temp_len), &temp_len);
535 	if (n < 0) {
536 		lwsl_err("%s: JOSE parse failed\n", __func__);
537 
538 		goto bail;
539 	}
540 
541 	n = lws_jwe_encrypt(&jwe, lws_concat_temp(temp, temp_len),
542 			    &temp_len);
543 	if (n < 0) {
544 		lwsl_err("%s: lws_jwe_encrypt failed\n", __func__);
545 		goto bail;
546 	}
547 
548 	n = lws_jwe_render_compact(&jwe, compact, sizeof(compact));
549 	if (n < 0) {
550 		lwsl_err("%s: lws_jwe_render_compact failed: %d\n", __func__, n);
551 		goto bail;
552 	}
553 
554 	// puts(compact);
555 
556 	lws_jwe_destroy(&jwe);
557 	lws_jwe_init(&jwe, context);
558 	temp_len = sizeof(temp);
559 
560 	/* now we created the encrypted version, see if we can decrypt it */
561 
562 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, jwk_txt, (unsigned int)jwk_len) < 0) {
563 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
564 		goto bail;
565 	}
566 
567 	if (lws_jws_compact_decode(compact, n, &jwe.jws.map, &jwe.jws.map_b64,
568 				   temp, &temp_len) != 5) {
569 		lwsl_err("%s: failed to parse generated compact\n", __func__);
570 
571 		goto bail;
572 	}
573 
574 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
575 				     &temp_len);
576 	if (n < 0) {
577 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
578 			 __func__);
579 		goto bail;
580 	}
581 
582 	/* allowing for trailing padding, confirm the plaintext */
583 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(ra_ptext_1024) ||
584 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ra_ptext_1024,
585 			        sizeof(ra_ptext_1024))) {
586 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
587 		lwsl_hexdump_notice(ra_ptext_1024, sizeof(ra_ptext_1024));
588 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
589 				    jwe.jws.map.len[LJWE_CTXT]);
590 		goto bail;
591 	}
592 
593 	ret = 0;
594 
595 bail:
596 	lws_jwe_destroy(&jwe);
597 
598 	if (ret)
599 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
600 	else
601 		lwsl_notice("%s: selftest OK\n", __func__);
602 
603 	return ret;
604 }
605 
606 static const char *rsa256a192_jose =
607 		"{ \"alg\":\"RSA1_5\",\"enc\":\"A192CBC-HS384\"}";
608 
609 static const uint8_t r256a192_cek[] = {
610 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
611 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
612 		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
613 		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
614 		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
615 		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
616 }
617 ;
618 
619 static int
test_jwe_r256a192_ptext(struct lws_context * context,char * jwk_txt,int jwk_len)620 test_jwe_r256a192_ptext(struct lws_context *context, char *jwk_txt, int jwk_len)
621 {
622 	struct lws_jwe jwe;
623 	char temp[4096], compact[4096];
624 	int n, ret = -1, temp_len = sizeof(temp);
625 
626 	lws_jwe_init(&jwe, context);
627 
628 	/* reuse the rsa private key from the JWE Appendix 2 test above */
629 
630 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, jwk_txt, (unsigned int)jwk_len) < 0) {
631 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
632 		goto bail;
633 	}
634 
635 	/*
636 	 * dup the plaintext into the ciphertext element, it will be
637 	 * encrypted in-place to a ciphertext of the same length + padding
638 	 */
639 
640 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_CTXT,
641 				lws_concat_temp(temp, temp_len), &temp_len,
642 				ra_ptext_1024, sizeof(ra_ptext_1024),
643 				lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN,
644 						      sizeof(ra_ptext_1024)))) {
645 		lwsl_notice("%s: Not enough temp space for ptext\n", __func__);
646 		goto bail;
647 	}
648 
649 	/* copy the cek, since it will be replaced by the encrypted key */
650 
651 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_EKEY,
652 				lws_concat_temp(temp, temp_len), &temp_len,
653 				r256a192_cek, sizeof(r256a192_cek),
654 				LWS_JWE_LIMIT_KEY_ELEMENT_BYTES)) {
655 		lwsl_err("Problem getting random\n");
656 		goto bail;
657 	}
658 
659 	jwe.jws.map.buf[LJWE_JOSE] = rsa256a192_jose;
660 	jwe.jws.map.len[LJWE_JOSE] = (uint32_t)strlen(rsa256a192_jose);
661 
662 	n = lws_jwe_parse_jose(&jwe.jose, jwe.jws.map.buf[LJWE_JOSE],
663 			       (int)jwe.jws.map.len[LJWE_JOSE],
664 			       lws_concat_temp(temp, temp_len), &temp_len);
665 	if (n < 0) {
666 		lwsl_err("%s: JOSE parse failed\n", __func__);
667 
668 		goto bail;
669 	}
670 
671 	n = lws_jwe_encrypt(&jwe, lws_concat_temp(temp, temp_len),
672 			    &temp_len);
673 	if (n < 0) {
674 		lwsl_err("%s: lws_jwe_encrypt failed\n", __func__);
675 		goto bail;
676 	}
677 
678 	n = lws_jwe_render_compact(&jwe, compact, sizeof(compact));
679 	if (n < 0) {
680 		lwsl_err("%s: lws_jwe_render_compact failed: %d\n", __func__, n);
681 		goto bail;
682 	}
683 
684 	// puts(compact);
685 
686 	/* now we created the encrypted version, see if we can decrypt it */
687 
688 	lws_jwe_destroy(&jwe);
689 	lws_jwe_init(&jwe, context);
690 
691 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, jwk_txt, (unsigned int)jwk_len) < 0) {
692 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
693 		goto bail;
694 	}
695 
696 	if (lws_jws_compact_decode(compact, n, &jwe.jws.map, &jwe.jws.map_b64,
697 				   temp, &temp_len) != 5) {
698 		lwsl_err("%s: failed to parse generated compact\n", __func__);
699 
700 		goto bail;
701 	}
702 
703 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
704 				     &temp_len);
705 	if (n < 0) {
706 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
707 			 __func__);
708 		goto bail;
709 	}
710 
711 	/* allowing for trailing padding, confirm the plaintext */
712 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(ra_ptext_1024) ||
713 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ra_ptext_1024,
714 			        sizeof(ra_ptext_1024))) {
715 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
716 		lwsl_hexdump_notice(ra_ptext_1024, sizeof(ra_ptext_1024));
717 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
718 				    jwe.jws.map.len[LJWE_CTXT]);
719 		goto bail;
720 	}
721 
722 	ret = 0;
723 
724 bail:
725 	lws_jwe_destroy(&jwe);
726 
727 	if (ret)
728 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
729 	else
730 		lwsl_notice("%s: selftest OK\n", __func__);
731 
732 	return ret;
733 }
734 
735 
736 static const char *rsa256a256_jose =
737 		"{ \"alg\":\"RSA1_5\",\"enc\":\"A256CBC-HS512\"}";
738 
739 static const uint8_t r256a256_cek[] = {
740 		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
741 		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
742 		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
743 		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
744 		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
745 		0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
746 		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
747 		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
748 }
749 ;
750 
751 static int
test_jwe_r256a256_ptext(struct lws_context * context,char * jwk_txt,int jwk_len)752 test_jwe_r256a256_ptext(struct lws_context *context, char *jwk_txt, int jwk_len)
753 {
754 	struct lws_jwe jwe;
755 	char temp[4096], compact[4096];
756 	int n, ret = -1, temp_len = sizeof(temp);
757 
758 	lws_jwe_init(&jwe, context);
759 
760 	/* reuse the rsa private key from the JWE Appendix 2 test above */
761 
762 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, jwk_txt, (unsigned int)jwk_len) < 0) {
763 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
764 		goto bail;
765 	}
766 
767 	/*
768 	 * dup the plaintext into the ciphertext element, it will be
769 	 * encrypted in-place to a ciphertext of the same length + padding
770 	 */
771 
772 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_CTXT,
773 				lws_concat_temp(temp, temp_len), &temp_len,
774 				ra_ptext_1024, sizeof(ra_ptext_1024),
775 				lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN,
776 						      sizeof(ra_ptext_1024)))) {
777 		lwsl_notice("%s: Not enough temp space for ptext\n", __func__);
778 		goto bail;
779 	}
780 
781 	/* copy the cek, since it will be replaced by the encrypted key */
782 
783 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_EKEY,
784 				lws_concat_temp(temp, temp_len), &temp_len,
785 				r256a256_cek, sizeof(r256a256_cek),
786 				LWS_JWE_LIMIT_KEY_ELEMENT_BYTES)) {
787 		lwsl_err("Problem getting random\n");
788 		goto bail;
789 	}
790 
791 	jwe.jws.map.buf[LJWE_JOSE] = rsa256a256_jose;
792 	jwe.jws.map.len[LJWE_JOSE] = (uint32_t)strlen(rsa256a256_jose);
793 
794 	n = lws_jwe_parse_jose(&jwe.jose, rsa256a256_jose,
795 			       (int)strlen(rsa256a256_jose),
796 			       lws_concat_temp(temp, temp_len), &temp_len);
797 	if (n < 0) {
798 		lwsl_err("%s: JOSE parse failed\n", __func__);
799 
800 		goto bail;
801 	}
802 
803 	n = lws_jwe_encrypt(&jwe, lws_concat_temp(temp, temp_len),
804 			    &temp_len);
805 	if (n < 0) {
806 		lwsl_err("%s: lws_jwe_encrypt failed\n", __func__);
807 		goto bail;
808 	}
809 
810 	n = lws_jwe_render_compact(&jwe, compact, sizeof(compact));
811 	if (n < 0) {
812 		lwsl_err("%s: lws_jwe_render_compact failed: %d\n", __func__, n);
813 		goto bail;
814 	}
815 
816 	// puts(compact);
817 
818 	/* now we created the encrypted version, see if we can decrypt it */
819 
820 	lws_jwe_destroy(&jwe);
821 	lws_jwe_init(&jwe, context);
822 
823 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, jwk_txt, (unsigned int)jwk_len) < 0) {
824 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
825 		goto bail;
826 	}
827 
828 	if (lws_jws_compact_decode(compact, n, &jwe.jws.map, &jwe.jws.map_b64,
829 				   temp, &temp_len) != 5) {
830 		lwsl_err("%s: failed to parse generated compact\n", __func__);
831 
832 		goto bail;
833 	}
834 
835 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
836 				     &temp_len);
837 	if (n < 0) {
838 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
839 			 __func__);
840 		goto bail;
841 	}
842 
843 	/* allowing for trailing padding, confirm the plaintext */
844 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(ra_ptext_1024) ||
845 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ra_ptext_1024,
846 			        sizeof(ra_ptext_1024))) {
847 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
848 		lwsl_hexdump_notice(ra_ptext_1024, sizeof(ra_ptext_1024));
849 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
850 				    jwe.jws.map.len[LJWE_CTXT]);
851 		goto bail;
852 	}
853 
854 	ret = 0;
855 
856 bail:
857 	lws_jwe_destroy(&jwe);
858 
859 	if (ret)
860 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
861 	else
862 		lwsl_notice("%s: selftest OK\n", __func__);
863 
864 	return ret;
865 }
866 
867 /* produced by running the minimal example `lws-crypto-jwk -t RSA -b 2048 -c` */
868 
869 static const char *rsa_key_2048 =
870 	"{"
871 		"\"e\":\"AQAB\","
872 		"\"kty\":\"RSA\","
873 		"\"n\":\"lBJdvUq-9_8hlcduIWuBjRb0tGzzAvS4foqoNCO7g-rOXMdeAcmq"
874 		 "aSzWTbkaGIc3L1I4-Q3TOZtxn2UhuDlShZRIhM6JCQuUVNVAF3TD7oXxHtZ"
875 		 "LJ7y_BqCUlrAmW31lu-nVmhY2G3xW26yXWUsDbCxz0hfLbVnXRSvVKLzYWm"
876 		 "_yyrFyEWfxB8peDocvKGh879z_aPCKE3PDOEl2AsgzYfpnWCLytkgnrTeL6"
877 		 "qY8HXxvvV-Jw-XMaRiwH0VldpIjs4DaoN35Kj1Ex7QOZznTkbYtMIqse8bR"
878 		 "LoR8Irkxbc5ncUAuX1KSV6lpPtelsA3RtEjJ4NHV-5eEABiYh8_CFQ\","
879 		"\"d\":\"DDpguQ9RVQFMoJC5z2hlkvq91kvsXPv2Y9Dcki256xYlg55H7Pre"
880 		 "p__hahrABR2Jg6QVJhArt5ABjUnDQ_JL69HH6VvLD6RVVBTQ-FRBZ_3HYKY"
881 		 "Oynx5BA7tJm1BRatF5FkBCvq27i8nAc4vfjAb22o9CFvEW3FLaKAgOCncQ3"
882 		 "Tnbz9CddH89n7DXw4kBFI8q5ugF_aRIg5-i42W_hQinLaBhZ_zhAuE-nvlt"
883 		 "ZnhDal8cX3T60lNoUrDOlirqEOXKO3gXCHpm3csZ6nabHYD1UCyHOmi2RsR"
884 		 "pzjaiqjXdPbwPzQoh2DcYpavNrf1mtHiqTwLZDTJIRHWHufJzHf-sw\","
885 		"\"p\":\"ySeC3FtvzduDEL-FX4JqbRN06PdBhUmosCkymmbBjriuLNpkGkG-"
886 		 "1ex7r-M8neUBZbctmDdih6cpLZ8hjZv3eEDZ4b5Z2LqZnja4QvVoWLUs4Fb"
887 		 "NN_PxJCR5H28uUfT6ThxqT0Nb2enb8Dyp0Qxvd7eJUeYz6jOt7pEK-ErTB4"
888 		 "M\","
889 		"\"q\":\"vHG2Pd6QUH7vFZjJtXwmlVnrz5tdJvUPQvz7ggeM69cqhf4vLajz"
890 		 "sqP9GhJr7bEkp6vKVdZGmfEdiFRD8cssIZq651oAO5Wr7zZd2mR_hG9jZx7"
891 		 "8Davfuxr4SZNN-bmoxO6dbDi-X2c7fvMI2YeJwL4groNKyiosdUYILTrYRI"
892 		 "c\","
893 		"\"dp\":\"h5Gqf2rcokgEQGBjuigCJDtNuskRjoxDNV6-rRL99nt_X9lcR9n"
894 		 "xjOnRvowOyXeTBoN7JjCFpllBxm6ORYtNMO28KomIsimo6NmGPBJ7XfXVJe"
895 		 "k6bDBrX-l4_HeJJ1FM9SHvgDYsjGQxh-rKpIqWAYBf-yOD758e5T85vndnX"
896 		 "JM\","
897 		"\"dq\":\"K9LiB-dfdmjenw4mMp-JtYfw8Bn4gtvQzcpZjzbETgB-8iRXwm2"
898 		 "dJvk-HjcUhHWCyb-I0YeAacKKFK9MEconHDWIq87haPn4vyvMjcJ7aUgiPN"
899 		 "QW1_MVl8TA4xNvudi0Z__5-jYEB9nRG0fX0gbUQU-19_-uf-9o4WkE88fQj"
900 		 "bc\","
901 		"\"qi\":\"LEkTRqmomn9UiASeRfAKw-Z5q7cye9CSL4luSexFvA3Du7Oin-s"
902 		 "L9a7F3nJN4CuYzhtNMxQ0hM7k6ExzhDhXDlNRHxnNEDt81-CFRV98v7GVWV"
903 		 "SH1KnaKf9wgegxSSm-x536ki2SI8EN4k4qkqRF0iLVHZK7CgnWMbtt6tnpp"
904 		 "3k\""
905 	"}";
906 /* produced by running the minimal example `lws-crypto-jwk -t RSA -b 4096 -c` */
907 
908 static const char *rsa_key_4096 =
909 	"{"
910 		"\"e\":\"AQAB\","
911 		"\"kty\":\"RSA\","
912 		"\"n\":\"uiLBz1SUgd4eQ0okg6tlPdk9QUhTsqXmiJXygWVFgzT45E5_Rfkq"
913 		 "vZ2fwAqQ8DvxkDTUWiKpeXMpPRNWG5GxuBuq9n7xdA1vn1eQi8LoekB28dg"
914 		 "3MwMfozVSKCzyxG1f81xPE5x3EMVhCcx6hshhlMEHkzNNhE07d-oRO87ZC0"
915 		 "z_5L3Vh03uJBXaDKVlsgHAazoHLhn6G4odqv-ro54T6Nx1eEtyTnMmFY5ND"
916 		 "V4rN0SjQvSefbZZtsrtby8Z0JmeyvynmDwOINj7FpmPmpFLoWGXntc2yxPP"
917 		 "8SHnqfT9ESh94fxCMxRhDNohgpegRHyiYwj3M5ZYY6reCZYfOQONSWmc8yp"
918 		 "NBMJqj4LuJ2bTMGAFS17ZP4ZZWm5RP9ax100Dgk0yxP1UrybG5dCfJRQvHC"
919 		 "ncxG_aL6cSQu2o4fXqlJsNHxk3FjHtV_CMZ3tqvGTvwrs4yxvKwKv6r3fRh"
920 		 "KL01bGOePzp9THkHW2-lzVj6kUwnxBdHGZE6fcAnczOdp8ZIEdV1w6ThimC"
921 		 "m3Bw_TIyl3tkuxRWXpc_d6Q4iiSVKGKCvUvfAlESpTA4tIhQkij-T9FEoj2"
922 		 "WE2H1D35AKmjcfLCh6yszu8cmDNedn862pwnawE2RvRFAyuI113fLQeCbCz"
923 		 "tQ1JHuD8cnQt0hpGzReTa5UJ8OEOGIlyXNdWZyTpk\","
924 		"\"d\":\"G2ZW582AT-6xvz-IiP5fuJ9EMloygeuEeEo0aMJO3X3cfoUknJkN"
925 		 "ZtyvYa5cgBSe3la8hKkyD9_5K9WvGP9VLTAbdk4g_m-k5QyXiU9PeAGJ0Nd"
926 		 "-Zqq4y0Zj2eil8u7Tz0fhFxay-zvG6VGZnsIcBTD2C7_jUwyoaqJA17A_CH"
927 		 "gU-ifMqS56VgMGdlKZmf7Cg7ZGzM1DoS6vZ9bbfgoczaw4OZVHlg9Cxa0NI"
928 		 "CDi1S-sJcTLGN_RLISKN5H0J54ZfzF6fUEn5kNykLTZrAvj2XV7g4UUOogn"
929 		 "1cvjJYRcBVzTzQKcfxbqo2DvymDGFZbQM6pj80rYJ5HFPh2EapjggPN8hXp"
930 		 "NlTNDEvC84QFv0lo2E-0nVWQqcyHtXd431O1JH2h5X822zKjXxkaztQSCj9"
931 		 "YP7AdAeoxIaWOa3aO1vcwURH2WWaNV-_KXVkPJNzfo9-bGYwblMw_RIqIkN"
932 		 "BDayTb8rBuQHTCE_tSEHgoSnkityGpr8j_vgA-Fa-SqmdqUlbklVpwA_Mq_"
933 		 "UH7RCaqe91dWxRhS_7c85tFMRFCKOcaRXkwxEpP2LD1AYe8yvVQlr0Se8_d"
934 		 "RefuQcC-BECwMW-TCgR3VxAuL7ExNTYe4bhBD8WYXsHP7wDXWX2Q4v7IRzj"
935 		 "cfVIdpTNYuWEd69PvXBCuy75hmDniSmS3Xps3ItGU\","
936 		"\"p\":\"961BtLSIZkHO7Vu1KfaA3urcwGpISKJiTSB5Nh6npxJr9mSjzv_f"
937 		 "e8VoxCX6CWGY0SEeQNUQ6ceTnAAxkSHtZJQGed598jBtxIexAWEE7oc9s9d"
938 		 "b0cWu4QWIVZYXrcOTEWmK1kWN4PXmnnQknrWQF49adn81BaOXqoL-tahe7f"
939 		 "faXzXe0RXuohK543ZKbuuHQ2TxqFG7CZpXiH_qn1Syao32u0V3iDFpmmCUV"
940 		 "h9O2JCzfo8sAosTrnQwC0pXz3Nvr_9Cnk6bMluJoMrwB1Ywg_DPQ1WvpYHO"
941 		 "URezEOqVC8Y3zrko199TMX2COKGNFgutVpnzxs2_h0PyINUmwrY4zQ\","
942 		"\"q\":\"wGQRaxy_gBafbrVJy4f32O0a2FQHzmS--WgHhoteDoF6ZAajLcV0"
943 		 "GEvb-AVmFER1Wii62BFaFJOYQIegELvnBFFzD6oHJRX7bM4m36G8J_TC1o9"
944 		 "T1IFnxOpaoFDf4JWf2k7DCXClGg_zueyOD8fj8F6j2nqpOfytuLmikHcWMc"
945 		 "dGTHTCRtQmvOk3pm0uk2qR0cQb5L3Ocv45tCKr55tMc6Zx3DKkMt1kmUwd2"
946 		 "HFfk_0WM6R7q4LNGIjwl8dwiERppLKA8xao9i3jOOdFEfAD-Zqv8H-32cyH"
947 		 "Mg6Guo4tPNAYSzcsz8nbEYPtKVVm-PDuM2cx0iaKnS8BIK2XTbzc_Q\","
948 		"\"dp\":\"ZXLWIwp_hEMYWyjhP9r0VlqlKTtfeEDrOuQ-Qei0iz6EclwurK8"
949 		 "p_yyRCSb1D7qmOaLzHWMollllINUDeIsJDdWEAY8cz4L-sy1RV1tCBeHnaC"
950 		 "6iMX5jb1Aw072y3T3qk4tDjxjWUHroh6bTCR8dckkJqNfaBAFKMlGNuyLIH"
951 		 "3kSPUV3ivUM1d4NvhnJyz02HmjOgz9W-Uv65rJei_zJR9P2aCbAG00CEHXW"
952 		 "zJ_uT86VdxV11WTaHu8Abt94sER8Tv6jbuyLrUjJSs9VGew32xNcEhya4ZQ"
953 		 "VyimG8zri6fu7CDXXgPS8wtzB5ihl_c2ypnJQ4_GKrgEqwEAOrFqvUQ\","
954 		"\"dq\":\"uzlmngcm8R6S3qi7fL7_2fG7uyPjSN5P3uR21l8QFCu6kFbJO8S"
955 		 "4muBP20hds4F_dlLGqXgRYo7TjpCtmztQsKoWv_ql41hGCfeAawa41WViqm"
956 		 "xmlxmrgzzRHsw1YhgZrNgTAz_E290EQT3Mbd0HnCZtbDMMNisIYAj_A3lwd"
957 		 "tbHOaYyXb0dSZ_nkSUVO05tQ2aGAo8Xtl5ih0NqaQR_XNhwW2pI0lsTB__D"
958 		 "15tU-O5FSdJaq2ip8KNrBzmF8IYrDKTNykKWAKRdSEX_uFoLdD8t0mxn3SM"
959 		 "luffa8vdjXJfh3GiASmHUt3HcPOooQEAufoWBPVJWeGqCvWtRH8yYfQ\","
960 		"\"qi\":\"h-e9es5J49OUF48gSXUI8cynZ8ydv5cThXc1deV3mil_7_7Hg8E"
961 		 "jV3gAErO4l-irHJplFmHFZvU1ud4zs1gtBt5TA-EeeepYOHMSssWDvDK3WI"
962 		 "zsM6C3vcNTSkT-ihaSFmPWHCVwJ1R3auWfeI2In3at0jd4t-OK-cCcGZXb7"
963 		 "90-EnyyDcdFTU9WfwVSOJffRGjoUYX8DexavClv7CBzPhpdUzGoeyarNaG4"
964 		 "z9MI8Q8txHyHgc_D70lZUum1cj0bZwgEj6yDzOPzSgUmICFJiLDDj93oPaI"
965 		 "v-5CQ_Ckju7icexc_kuuYTKBOLTj_vfaURnV3KCHul2UljUYOxkfeNQ\""
966 	"}";
967 
968 static const char *rsa_key_4096_no_optional =
969 	"{"
970 		"\"e\":\"AQAB\","
971 		"\"kty\":\"RSA\","
972 		"\"n\":\"uiLBz1SUgd4eQ0okg6tlPdk9QUhTsqXmiJXygWVFgzT45E5_Rfkq"
973 		 "vZ2fwAqQ8DvxkDTUWiKpeXMpPRNWG5GxuBuq9n7xdA1vn1eQi8LoekB28dg"
974 		 "3MwMfozVSKCzyxG1f81xPE5x3EMVhCcx6hshhlMEHkzNNhE07d-oRO87ZC0"
975 		 "z_5L3Vh03uJBXaDKVlsgHAazoHLhn6G4odqv-ro54T6Nx1eEtyTnMmFY5ND"
976 		 "V4rN0SjQvSefbZZtsrtby8Z0JmeyvynmDwOINj7FpmPmpFLoWGXntc2yxPP"
977 		 "8SHnqfT9ESh94fxCMxRhDNohgpegRHyiYwj3M5ZYY6reCZYfOQONSWmc8yp"
978 		 "NBMJqj4LuJ2bTMGAFS17ZP4ZZWm5RP9ax100Dgk0yxP1UrybG5dCfJRQvHC"
979 		 "ncxG_aL6cSQu2o4fXqlJsNHxk3FjHtV_CMZ3tqvGTvwrs4yxvKwKv6r3fRh"
980 		 "KL01bGOePzp9THkHW2-lzVj6kUwnxBdHGZE6fcAnczOdp8ZIEdV1w6ThimC"
981 		 "m3Bw_TIyl3tkuxRWXpc_d6Q4iiSVKGKCvUvfAlESpTA4tIhQkij-T9FEoj2"
982 		 "WE2H1D35AKmjcfLCh6yszu8cmDNedn862pwnawE2RvRFAyuI113fLQeCbCz"
983 		 "tQ1JHuD8cnQt0hpGzReTa5UJ8OEOGIlyXNdWZyTpk\","
984 		"\"d\":\"G2ZW582AT-6xvz-IiP5fuJ9EMloygeuEeEo0aMJO3X3cfoUknJkN"
985 		 "ZtyvYa5cgBSe3la8hKkyD9_5K9WvGP9VLTAbdk4g_m-k5QyXiU9PeAGJ0Nd"
986 		 "-Zqq4y0Zj2eil8u7Tz0fhFxay-zvG6VGZnsIcBTD2C7_jUwyoaqJA17A_CH"
987 		 "gU-ifMqS56VgMGdlKZmf7Cg7ZGzM1DoS6vZ9bbfgoczaw4OZVHlg9Cxa0NI"
988 		 "CDi1S-sJcTLGN_RLISKN5H0J54ZfzF6fUEn5kNykLTZrAvj2XV7g4UUOogn"
989 		 "1cvjJYRcBVzTzQKcfxbqo2DvymDGFZbQM6pj80rYJ5HFPh2EapjggPN8hXp"
990 		 "NlTNDEvC84QFv0lo2E-0nVWQqcyHtXd431O1JH2h5X822zKjXxkaztQSCj9"
991 		 "YP7AdAeoxIaWOa3aO1vcwURH2WWaNV-_KXVkPJNzfo9-bGYwblMw_RIqIkN"
992 		 "BDayTb8rBuQHTCE_tSEHgoSnkityGpr8j_vgA-Fa-SqmdqUlbklVpwA_Mq_"
993 		 "UH7RCaqe91dWxRhS_7c85tFMRFCKOcaRXkwxEpP2LD1AYe8yvVQlr0Se8_d"
994 		 "RefuQcC-BECwMW-TCgR3VxAuL7ExNTYe4bhBD8WYXsHP7wDXWX2Q4v7IRzj"
995 		 "cfVIdpTNYuWEd69PvXBCuy75hmDniSmS3Xps3ItGU\","
996 		"\"p\":\"961BtLSIZkHO7Vu1KfaA3urcwGpISKJiTSB5Nh6npxJr9mSjzv_f"
997 		 "e8VoxCX6CWGY0SEeQNUQ6ceTnAAxkSHtZJQGed598jBtxIexAWEE7oc9s9d"
998 		 "b0cWu4QWIVZYXrcOTEWmK1kWN4PXmnnQknrWQF49adn81BaOXqoL-tahe7f"
999 		 "faXzXe0RXuohK543ZKbuuHQ2TxqFG7CZpXiH_qn1Syao32u0V3iDFpmmCUV"
1000 		 "h9O2JCzfo8sAosTrnQwC0pXz3Nvr_9Cnk6bMluJoMrwB1Ywg_DPQ1WvpYHO"
1001 		 "URezEOqVC8Y3zrko199TMX2COKGNFgutVpnzxs2_h0PyINUmwrY4zQ\","
1002 		"\"q\":\"wGQRaxy_gBafbrVJy4f32O0a2FQHzmS--WgHhoteDoF6ZAajLcV0"
1003 		 "GEvb-AVmFER1Wii62BFaFJOYQIegELvnBFFzD6oHJRX7bM4m36G8J_TC1o9"
1004 		 "T1IFnxOpaoFDf4JWf2k7DCXClGg_zueyOD8fj8F6j2nqpOfytuLmikHcWMc"
1005 		 "dGTHTCRtQmvOk3pm0uk2qR0cQb5L3Ocv45tCKr55tMc6Zx3DKkMt1kmUwd2"
1006 		 "HFfk_0WM6R7q4LNGIjwl8dwiERppLKA8xao9i3jOOdFEfAD-Zqv8H-32cyH"
1007 		 "Mg6Guo4tPNAYSzcsz8nbEYPtKVVm-PDuM2cx0iaKnS8BIK2XTbzc_Q\""
1008 	"}";
1009 
1010 /* This is a compact JWE containing the plaintext ra_ptext_1024 for the key
1011  * lws_jwe_ex_a2_jwk_json... produced by  test test above running on OpenSSL.
1012  */
1013 
1014 static char *jwe_compact_rsa_cbc_openssl =
1015         "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0."
1016         "HgQBfAg2IUpExcs74-gtuSOciw6rxh2cc4x9MVRWDZKSvMqoBYKAxl6ebSxGTReHhbvhv2Rm8stKq"
1017         "OIROhWzTNGTQPnSRMzAm9x6ms39hAIGh1KCEZ47MRYkCN7hElfDVtczOCX3ZRsG9_qYEmzcY1aJ-4"
1018         "_LS3yeP0HfqKBmcfvjVLw-KqcUuHp5YXsZEvt28nA9uBlCN0ROWy_2Fs-zlQj8pDMWo5pZrffKTUX"
1019         "gUh_UJ9eC3qNyXtQSqUH-5vDeHPhxNnIJOsmJ5ZUAjxXPm-RJZRC9THg0DzGRZn9IqfP9qcanbcZ8"
1020         "iow7gjFh1EPp3MKlpZqDKbLLei1WZvz2_A."
1021         "q4STtyu4yxZfH1HNDYlYcA."
1022         "_uRfuwWO22_auSqXHORw_e_Q6PmbpC0sv0tefVKsj3Zqnh2qUBlj10kiWBMWoMMjqsClBO0nUoup4"
1023         "c7i1YSqxlCHliXru3athv_EYtg5qvC-z2co9NiFABHCHmBDrhj7CuKN5gqFDt1EbYMLwWtU3gOnQy"
1024         "dvnzfFcQs4_jKi6tRpQzbobrkkZ2p7Y_ltjA1Wmwqrp9O8DGSRnvcomqzGHcshuyxTkjLDzD8TSMR"
1025         "S1kp-miy5eDGAcp-ymWiUKN7gswy5FPjPQYzgs7Vc0n0R1ljepRHJiHaP61z_DKWXrCE6RqAVqnaw"
1026         "TjjVOXXKKF9pz9W7pZL8diLZ0Ueev6xk8wzRRsUChM5toQNzFLXsnzSDQSzfSKpRnLjYvosiEegyx"
1027         "RrwtQwEcNCXRj0aGxG6e_W79JdUJoi4blpTtrAVn_pk7SgRiU3aly1vso5tV_0kvMOcS6Hn38mqRQ"
1028         "PQxbdIpohi8C7FFabluZqGoiji8ZTM3v-2ib2vrBFj1YvoyPG1HXJsABINzo0xOkrMFNfN_oQrCSM"
1029         "Ij49N86GXmYOnu5jtZeSMXZIR2BAXnu0upXMsvtSjU8D-LJJChy0XNYoyuJar5P3YhDStdTfmn0z-"
1030         "XLwaIHWc1L9-rmW9CZey3HxCLKEnr7-FjXsXqzAArsFqn1X_sVR5HRHng5ioc7sUaRoC1S_k0XPVC"
1031         "qCjZvkbRry2cp2313DNwjl8SK-iZA0fVUZVPM7_eZfpEgB3bBTyamtAaqQeES6lcVEtpg176Mlh64"
1032         "3JCAjroJPP4eqAA3JHnDgwlO-XhlLPTNNQ5FMLBC_dp41A-H3HFlbQUR6jX3k_H4Ggqtit50EIye3"
1033         "nnKb3emFn9KVyeZCYaBecYbicEIMKW7sWLbcE_cDGqkHZcMGTOQKRiLp-xwyEu89oDGAcGBYpmC_f"
1034         "iQ2qyFfe6tQK_5nPZbtW2mudiYZ-d0YIURSTp58S_n6w3wLDUEcuZtv-nhCaFVy8oUbAztkBIK6pu"
1035         "VamKhHVLkCtOGIdNJYbLKAedhK1lQVPbrvfcSDPPkhxSx9AjKqhKA3ZPMA_UXQb6p9c33tgi_MdZX"
1036         "-jRGXwGKWBCrv4UjttFLV-a5U7NgxQIIjwfAoutXtYardFw2d5nTJRqBrw06PSqaLzQi616_b-U0g"
1037         "6bWxrFObIWrKODkGfQcXPXIQxW_4Vh6gR2GaHSi_A_5SGH0zsBtYxisbKXLK2HiZJOXBew4-am6c0"
1038         "R1jBh7QtOWpwrYWt0d_xxrWtKezeEp3FkrFkwWCgY9dT1uV8tKUuxeeGqshkrXifT4axttpkbi-qA"
1039         "eG_C6J-H29CPqScclD-A5LIg7k-KmA9hsWrXttAvoCSawNj1tv9JHq0jgP1yZytDW1DkWdCBY0au5"
1040         "4."
1041         "qqYQEaGx-lUHoO43fOXvKQ"
1042 ;
1043 
1044 
1045 static int
test_jwe_r256a128_jwe_openssl(struct lws_context * context)1046 test_jwe_r256a128_jwe_openssl(struct lws_context *context)
1047 {
1048 	struct lws_jwe jwe;
1049 	char temp[2048];
1050 	int n, ret = -1, temp_len = sizeof(temp);
1051 
1052 	lws_jwe_init(&jwe, context);
1053 
1054 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, (char *)lws_jwe_ex_a2_jwk_json,
1055 			   strlen((char *)lws_jwe_ex_a2_jwk_json)) < 0) {
1056 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
1057 		goto bail;
1058 	}
1059 
1060 	/* converts a compact serialization to jws b64 + decoded maps */
1061 	if (lws_jws_compact_decode((const char *)jwe_compact_rsa_cbc_openssl,
1062 				   (int)strlen((char *)jwe_compact_rsa_cbc_openssl),
1063 				   &jwe.jws.map, &jwe.jws.map_b64,
1064 				   temp, &temp_len) != 5) {
1065 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
1066 		goto bail;
1067 	}
1068 
1069 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
1070 				     &temp_len);
1071 	if (n < 0) {
1072 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
1073 			 __func__);
1074 		goto bail;
1075 	}
1076 
1077 	/* allowing for trailing padding, confirm the plaintext */
1078 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(ra_ptext_1024) ||
1079 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ra_ptext_1024,
1080 			        sizeof(ra_ptext_1024))) {
1081 		lwsl_err("%s: plaintext RSA/AES decrypt wrong\n", __func__);
1082 		lwsl_hexdump_notice(ra_ptext_1024, sizeof(ra_ptext_1024));
1083 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
1084 				    jwe.jws.map.len[LJWE_CTXT]);
1085 		goto bail;
1086 	}
1087 
1088 	ret = 0;
1089 
1090 bail:
1091 	lws_jwe_destroy(&jwe);
1092 	if (ret)
1093 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
1094 	else
1095 		lwsl_notice("%s: selftest OK\n", __func__);
1096 
1097 	return ret;
1098 }
1099 
1100 
1101 /* This is a compact JWE containing the plaintext ra_ptext_1024 for the key
1102  * lws_jwe_ex_a2_jwk_json... produced by  test test above running on mbedTLS.
1103  */
1104 
1105 static char
1106 *jwe_compact_rsa_cbc_mbedtls =
1107 	"eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.Ptg-RZjEhY1dWg7T"
1108 	"v72rqRoHXBeory9ePCC5cfASTz8BH7IdSLQcPeBWHQsmd13TXPjo-dxnmkWkx9AyKdvy"
1109 	"K0A6oCnsP7KfbGzPwTy5eadpaaDZ3UyXIGmusLgiXGgDZ4d13voirbRQV9nQTPsagG_k"
1110 	"FGRI5dKzenG2WcbUhKG-uCmypzYqjNM3LqUzdH42jjjHFOBkmK_sWSZL7Uxqq8s08hkO"
1111 	"aXeUQyeM7Z8wm1bsZAvIfGri5LMcBS8P70AyENchlchZpTeACIOWk19ddLPUt-ruEcm0"
1112 	"zZV7Gjap7uG06a0m3VyR3vMpKkXnBHQxko-RICU2PDmELVXg0pZWTw.-VaaDaUiynH_t"
1113 	"sh2HqKISQ.vVE8j1TQinb4anJk0ArV9ccYdlUIO20vnMa7b-JGfQ7CFi_WVt6xNaqytB"
1114 	"QqiTHLtAxBDIV4m9Kwid-8Kcx7BmRqu-memxHztBSvBNOYWVPTxy5I2ORGLNEbPVrFYp"
1115 	"c2nm3TnHfr-_2fuw6_HEnyqv_c6ZyzU0-lHZ1pE5Cs-lrjnj4ibNcK6XHhrO3nxUjPMZ"
1116 	"rO-2B_tZwCxzKsFAqD_XGROvNGWXEgxgIr09MyuwKJnw2oZ0xOF_d3FVYjK5XMONgWPo"
1117 	"lyDmbP_XLSIUXbHmLxpDB5NPLN8SKRHbMV3_qw5rFRlak2C_XlR58P-Im1PQ8gMg7lgE"
1118 	"IFz2DrqF4sJA5TYbQG5KCdas0SfONlP1V692dufH5D30RGsiWNSrhiyDmUNC0SeB8VqA"
1119 	"bmc02pPGgzZHxa5-_xIHKm4h6fmnZFScjliBQ5W6smxQ6m2Kby0MkOdqlRYFn8qLYLmF"
1120 	"vmVNe_Q5-iLNobx-hyyeeExRXfzNOY0HHEKw67ipBWwqA0JGIggCWAFa0fpA-Wt7sNl_"
1121 	"gPy96nbwuXIuRoC3wuboUlDp9k2F1vC7VY6R9jdRk1VXT_O3liBIiUIRhZiqZZ75H2RV"
1122 	"pLYXGrvL5G9THdRcbsg3XUt-kF4vvGQAdNmPdRmuIG1DfGDmOZnXfrG8ckTvxoKBXdQZ"
1123 	"gfwfAQFgeHjltiWZTCSBV4464sn2qLZ1MP3Ku9bOjb72RCpIF60Cqssb8gTQyXQf48ZR"
1124 	"OBd242Q7Ae6PePmb_TcnG3jOguNUgmhj8iTU7QUz0uJWpJjMRPJ8vK8SnYEguGHer4qT"
1125 	"EocdMzRTTZB-Pr4-Ey0Hm0zeiFvjU0Qy6crjna6SKrgms4VAJT9LiicTYFPsmFBFQ0L1"
1126 	"BVDiZ3NTBIv_ajvzRpBNZ0IxEH5t6W3OY0223xUF3cq8c9HhwIxMf9a2-PmZ3mVWIRnU"
1127 	"nGegoVkzd2l6el8aw57v5KKYas4-EkovHntCZZ_hkZ1uHtezKq0EvjnT5xGWjPFjOZnh"
1128 	"veiozAsaMSSyTny6mcI-hjvcgd--7qlqWpt_BEkp9XVkP2k7eHLM9v4rL6hhk_n6yK3w"
1129 	"qKi0xDboxU5xjuBiGKb-E8um1MUEjuLqZanKSBsgU-Vwvw0gx1r-MG6BSlrgUlT2if5k"
1130 	"-Wfs6iVdpK7x1zZSsetp3NEjT4DUrfmp_E_CTXhOEP0AgzpQ4Ukx5bFN3gm5gyBZw1E8"
1131 	"q20Hs01OBcMJ9wenLEQVMvO_IEIkRNBMWEgoZ148As14LNOgdh1UBrF6W4pAUjYvA3WG"
1132 	"Zp7uG9ooDB1RF2aaeBqoLJflqIegsvsfaNNBDJ-U6i_jLG1FSlttEhJVdXll0gMSYlXD"
1133 	"O3BBil4eiUPfiksfOmsbwoIxc-3yPTivU3DPM.O_IaktJRbdV66zfhD0LQmw"
1134 ;
1135 
1136 static int
test_jwe_r256a128_jwe_mbedtls(struct lws_context * context)1137 test_jwe_r256a128_jwe_mbedtls(struct lws_context *context)
1138 {
1139 	struct lws_jwe jwe;
1140 	char temp[2048];
1141 	int n, ret = -1, temp_len = sizeof(temp);
1142 
1143 	lws_jwe_init(&jwe, context);
1144 
1145 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, (char *)lws_jwe_ex_a2_jwk_json,
1146 			   strlen((char *)lws_jwe_ex_a2_jwk_json)) < 0) {
1147 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
1148 		goto bail;
1149 	}
1150 
1151 	/* converts a compact serialization to jws b64 + decoded maps */
1152 	if (lws_jws_compact_decode((const char *)jwe_compact_rsa_cbc_mbedtls,
1153 				   (int)strlen((char *)jwe_compact_rsa_cbc_mbedtls),
1154 				   &jwe.jws.map, &jwe.jws.map_b64,
1155 				   temp, &temp_len) != 5) {
1156 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
1157 		goto bail;
1158 	}
1159 
1160 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
1161 				     &temp_len);
1162 	if (n < 0) {
1163 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
1164 			 __func__);
1165 		goto bail;
1166 	}
1167 
1168 	/* allowing for trailing padding, confirm the plaintext */
1169 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(ra_ptext_1024) ||
1170 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ra_ptext_1024,
1171 			        sizeof(ra_ptext_1024))) {
1172 		lwsl_err("%s: plaintext RSA/AES decrypt wrong\n", __func__);
1173 		lwsl_hexdump_notice(ra_ptext_1024, sizeof(ra_ptext_1024));
1174 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
1175 				    jwe.jws.map.len[LJWE_CTXT]);
1176 		goto bail;
1177 	}
1178 
1179 	ret = 0;
1180 
1181 bail:
1182 	lws_jwe_destroy(&jwe);
1183 
1184 	if (ret)
1185 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
1186 	else
1187 		lwsl_notice("%s: selftest OK\n", __func__);
1188 
1189 	return ret;
1190 }
1191 
1192 
1193 
1194 /* A.3.  Example JWE Using AES Key Wrap and AES_128_CBC_HMAC_SHA_256
1195  *
1196  * This example encrypts the plaintext "Live long and prosper." to the
1197  * recipient using AES Key Wrap for key encryption and
1198  * AES_128_CBC_HMAC_SHA_256 for content encryption.
1199  */
1200 
1201 /* "Live long and prosper." */
1202 static uint8_t
1203 
1204 ex_a3_ptext[] = {
1205 	76, 105, 118, 101, 32, 108, 111, 110,
1206 	103, 32, 97, 110, 100, 32,  112, 114,
1207 	111, 115, 112, 101, 114, 46
1208 },
1209 
1210 *ex_a3_compact = (uint8_t *)
1211 	"eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0"
1212 	"."
1213 	"6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ"
1214 	"."
1215 	"AxY8DCtDaGlsbGljb3RoZQ"
1216 	"."
1217 	"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY"
1218 	"."
1219 	"U0m_YmjN04DJvceFICbCVQ",
1220 
1221 *ex_a3_key = (uint8_t *)
1222 	"{\"kty\":\"oct\","
1223 	   "\"k\":\"GawgguFyGrWKav7AX4VKUg\""
1224 	"}"
1225 ;
1226 
1227 static int
test_jwe_a3(struct lws_context * context)1228 test_jwe_a3(struct lws_context *context)
1229 {
1230 	struct lws_jwe jwe;
1231 	char temp[2048];
1232 	int n, ret = -1, temp_len = sizeof(temp);
1233 
1234 	lws_jwe_init(&jwe, context);
1235 
1236 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, (char *)ex_a3_key,
1237 			   strlen((char *)ex_a3_key)) < 0) {
1238 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
1239 		goto bail;
1240 	}
1241 
1242 	/* converts a compact serialization to jws b64 + decoded maps */
1243 	if (lws_jws_compact_decode((const char *)ex_a3_compact,
1244 				   (int)strlen((char *)ex_a3_compact),
1245 				   &jwe.jws.map, &jwe.jws.map_b64, temp,
1246 				   &temp_len)  != 5) {
1247 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
1248 		goto bail;
1249 	}
1250 
1251 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
1252 				     &temp_len);
1253 	if (n < 0) {
1254 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
1255 			 __func__);
1256 		goto bail;
1257 	}
1258 
1259 	/* allowing for trailing padding, confirm the plaintext */
1260 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(ex_a3_ptext) ||
1261 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], ex_a3_ptext,
1262 			        sizeof(ex_a3_ptext))) {
1263 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
1264 		lwsl_hexdump_notice(ex_a3_ptext, sizeof(ex_a3_ptext));
1265 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
1266 				    jwe.jws.map.len[LJWE_CTXT]);
1267 		goto bail;
1268 	}
1269 
1270 	ret = 0;
1271 
1272 bail:
1273 	lws_jwe_destroy(&jwe);
1274 	if (ret)
1275 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
1276 	else
1277 		lwsl_notice("%s: selftest OK\n", __func__);
1278 
1279 	return ret;
1280 }
1281 
1282 /* JWA B.2.  Test Cases for AES_192_CBC_HMAC_SHA_384
1283  *
1284  * Unfortunately JWA just gives this test case as hex literals, not
1285  * inside a JWE.  So we have to prepare the inputs "by hand".
1286  */
1287 
1288 static uint8_t
1289 
1290 jwa_b2_ptext[] = {
1291 	0x41, 0x20, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72,
1292 	0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
1293 	0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74,
1294 	0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75,
1295 	0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
1296 	0x62, 0x65, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65,
1297 	0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69,
1298 	0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62,
1299 	0x65, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74,
1300 	0x6f, 0x20, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x69,
1301 	0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20,
1302 	0x68, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x66,
1303 	0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x65,
1304 	0x6d, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f,
1305 	0x75, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6e,
1306 	0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x63, 0x65
1307 },
1308 
1309 jwa_b2_rawkey[] = {
1310 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1311 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1312 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1313 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1314 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1315 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
1316 },
1317 
1318 jwa_b2_iv[] = {
1319 	0x1a, 0xf3, 0x8c, 0x2d, 0xc2, 0xb9, 0x6f, 0xfd,
1320 	0xd8, 0x66, 0x94, 0x09, 0x23, 0x41, 0xbc, 0x04
1321 },
1322 
1323 jwa_b2_e[] = {
1324 	0xea, 0x65, 0xda, 0x6b, 0x59, 0xe6, 0x1e, 0xdb,
1325 	0x41, 0x9b, 0xe6, 0x2d, 0x19, 0x71, 0x2a, 0xe5,
1326 	0xd3, 0x03, 0xee, 0xb5, 0x00, 0x52, 0xd0, 0xdf,
1327 	0xd6, 0x69, 0x7f, 0x77, 0x22, 0x4c, 0x8e, 0xdb,
1328 	0x00, 0x0d, 0x27, 0x9b, 0xdc, 0x14, 0xc1, 0x07,
1329 	0x26, 0x54, 0xbd, 0x30, 0x94, 0x42, 0x30, 0xc6,
1330 	0x57, 0xbe, 0xd4, 0xca, 0x0c, 0x9f, 0x4a, 0x84,
1331 	0x66, 0xf2, 0x2b, 0x22, 0x6d, 0x17, 0x46, 0x21,
1332 	0x4b, 0xf8, 0xcf, 0xc2, 0x40, 0x0a, 0xdd, 0x9f,
1333 	0x51, 0x26, 0xe4, 0x79, 0x66, 0x3f, 0xc9, 0x0b,
1334 	0x3b, 0xed, 0x78, 0x7a, 0x2f, 0x0f, 0xfc, 0xbf,
1335 	0x39, 0x04, 0xbe, 0x2a, 0x64, 0x1d, 0x5c, 0x21,
1336 	0x05, 0xbf, 0xe5, 0x91, 0xba, 0xe2, 0x3b, 0x1d,
1337 	0x74, 0x49, 0xe5, 0x32, 0xee, 0xf6, 0x0a, 0x9a,
1338 	0xc8, 0xbb, 0x6c, 0x6b, 0x01, 0xd3, 0x5d, 0x49,
1339 	0x78, 0x7b, 0xcd, 0x57, 0xef, 0x48, 0x49, 0x27,
1340 	0xf2, 0x80, 0xad, 0xc9, 0x1a, 0xc0, 0xc4, 0xe7,
1341 	0x9c, 0x7b, 0x11, 0xef, 0xc6, 0x00, 0x54, 0xe3
1342 },
1343 
1344 jwa_b2_a[] = { /* "The second principle of Auguste Kerckhoffs" */
1345 	0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6f,
1346 	0x6e, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63,
1347 	0x69, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20,
1348 	0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x65, 0x20,
1349 	0x4b, 0x65, 0x72, 0x63, 0x6b, 0x68, 0x6f, 0x66,
1350 	0x66, 0x73
1351 },
1352 
1353 jwa_b2_tag[] = {
1354 	0x84, 0x90, 0xac, 0x0e, 0x58, 0x94, 0x9b, 0xfe,
1355 	0x51, 0x87, 0x5d, 0x73, 0x3f, 0x93, 0xac, 0x20,
1356 	0x75, 0x16, 0x80, 0x39, 0xcc, 0xc7, 0x33, 0xd7
1357 
1358 }
1359 ;
1360 
1361 static int
test_jwa_b2(struct lws_context * context)1362 test_jwa_b2(struct lws_context *context)
1363 {
1364 	struct lws_jwe jwe;
1365 	int n, ret = -1;
1366 	char buf[2048];
1367 
1368 	lws_jwe_init(&jwe, context);
1369 
1370 	/*
1371 	 * normally all this is interpreted from the JWE blob.  But we don't
1372 	 * have JWE test vectors for AES_256_CBC_HMAC_SHA_512, just a standalone
1373 	 * one.  So we have to create it all by hand.
1374 	 *
1375 	 * See test_jwe_a3 above for a more normal usage pattern.
1376 	 */
1377 
1378 	lws_jwk_dup_oct(&jwe.jwk, jwa_b2_rawkey, sizeof(jwa_b2_rawkey));
1379 
1380 	memcpy(buf, jwa_b2_e, sizeof(jwa_b2_e));
1381 
1382 	jwe.jws.map.buf[LJWE_IV] = (char *)jwa_b2_iv;
1383 	jwe.jws.map.len[LJWE_IV] = sizeof(jwa_b2_iv);
1384 
1385 	jwe.jws.map.buf[LJWE_CTXT] = buf;
1386 	jwe.jws.map.len[LJWE_CTXT] = sizeof(jwa_b2_e);
1387 
1388 	jwe.jws.map.buf[LJWE_ATAG] = (char *)jwa_b2_tag;
1389 	jwe.jws.map.len[LJWE_ATAG] = sizeof(jwa_b2_tag);
1390 
1391 	/*
1392 	 * Normally this comes from the JOSE header.  But this test vector
1393 	 * doesn't have one... so...
1394 	 */
1395 
1396 	if (lws_gencrypto_jwe_alg_to_definition("A128KW", &jwe.jose.alg))
1397 		goto bail;
1398 	if (lws_gencrypto_jwe_enc_to_definition("A192CBC-HS384",
1399 						&jwe.jose.enc_alg))
1400 		goto bail;
1401 
1402 	n = lws_jwe_auth_and_decrypt_cbc_hs(&jwe, jwa_b2_rawkey,
1403 						    jwa_b2_a, sizeof(jwa_b2_a));
1404 	if (n < 0) {
1405 		lwsl_err("%s: lws_jwe_a_cbc_hs_decrypt failed\n", __func__);
1406 
1407 		goto bail;
1408 	}
1409 
1410 	/* allowing for trailing padding, confirm the plaintext */
1411 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(jwa_b2_ptext) ||
1412 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT],jwa_b2_ptext,
1413 			        sizeof(jwa_b2_ptext))) {
1414 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
1415 		lwsl_hexdump_notice(jwa_b2_ptext, sizeof(jwa_b2_ptext));
1416 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
1417 				    jwe.jws.map.len[LJWE_CTXT]);
1418 		goto bail;
1419 	}
1420 
1421 	ret = 0;
1422 
1423 bail:
1424 	lws_jwe_destroy(&jwe);
1425 	if (ret)
1426 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
1427 	else
1428 		lwsl_notice("%s: selftest OK\n", __func__);
1429 
1430 	return ret;
1431 }
1432 
1433 
1434 
1435 /* JWA B.3.  Test Cases for AES_256_CBC_HMAC_SHA_512
1436  *
1437  * Unfortunately JWA just gives this test case as hex literals, not
1438  * inside a JWE.  So we have to prepare the inputs "by hand".
1439  */
1440 
1441 static uint8_t
1442 
1443 jwa_b3_ptext[] = {
1444 	0x41, 0x20, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72,
1445 	0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
1446 	0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74,
1447 	0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75,
1448 	0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
1449 	0x62, 0x65, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65,
1450 	0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69,
1451 	0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62,
1452 	0x65, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74,
1453 	0x6f, 0x20, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x69,
1454 	0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20,
1455 	0x68, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x66,
1456 	0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x65,
1457 	0x6d, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f,
1458 	0x75, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6e,
1459 	0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x63, 0x65
1460 },
1461 
1462 
1463 jwa_b3_rawkey[] = {
1464 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1465 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1466 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1467 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1468 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1469 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
1470 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
1471 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
1472 },
1473 
1474 jwa_b3_iv[] = {
1475 	0x1a, 0xf3, 0x8c, 0x2d, 0xc2, 0xb9, 0x6f, 0xfd,
1476 	0xd8, 0x66, 0x94, 0x09, 0x23, 0x41, 0xbc, 0x04
1477 },
1478 
1479 jwa_b3_e[] = {
1480 	0x4a, 0xff, 0xaa, 0xad, 0xb7, 0x8c, 0x31, 0xc5,
1481 	0xda, 0x4b, 0x1b, 0x59, 0x0d, 0x10, 0xff, 0xbd,
1482 	0x3d, 0xd8, 0xd5, 0xd3, 0x02, 0x42, 0x35, 0x26,
1483 	0x91, 0x2d, 0xa0, 0x37, 0xec, 0xbc, 0xc7, 0xbd,
1484 	0x82, 0x2c, 0x30, 0x1d, 0xd6, 0x7c, 0x37, 0x3b,
1485 	0xcc, 0xb5, 0x84, 0xad, 0x3e, 0x92, 0x79, 0xc2,
1486 	0xe6, 0xd1, 0x2a, 0x13, 0x74, 0xb7, 0x7f, 0x07,
1487 	0x75, 0x53, 0xdf, 0x82, 0x94, 0x10, 0x44, 0x6b,
1488 	0x36, 0xeb, 0xd9, 0x70, 0x66, 0x29, 0x6a, 0xe6,
1489 	0x42, 0x7e, 0xa7, 0x5c, 0x2e, 0x08, 0x46, 0xa1,
1490 	0x1a, 0x09, 0xcc, 0xf5, 0x37, 0x0d, 0xc8, 0x0b,
1491 	0xfe, 0xcb, 0xad, 0x28, 0xc7, 0x3f, 0x09, 0xb3,
1492 	0xa3, 0xb7, 0x5e, 0x66, 0x2a, 0x25, 0x94, 0x41,
1493 	0x0a, 0xe4, 0x96, 0xb2, 0xe2, 0xe6, 0x60, 0x9e,
1494 	0x31, 0xe6, 0xe0, 0x2c, 0xc8, 0x37, 0xf0, 0x53,
1495 	0xd2, 0x1f, 0x37, 0xff, 0x4f, 0x51, 0x95, 0x0b,
1496 	0xbe, 0x26, 0x38, 0xd0, 0x9d, 0xd7, 0xa4, 0x93,
1497 	0x09, 0x30, 0x80, 0x6d, 0x07, 0x03, 0xb1, 0xf6,
1498 },
1499 
1500 jwa_b3_a[] = { /* "The second principle of Auguste Kerckhoffs" */
1501 	0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6f,
1502 	0x6e, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63,
1503 	0x69, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20,
1504 	0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x65, 0x20,
1505 	0x4b, 0x65, 0x72, 0x63, 0x6b, 0x68, 0x6f, 0x66,
1506 	0x66, 0x73
1507 },
1508 
1509 jws_b3_tag[] = {
1510 	0x4d, 0xd3, 0xb4, 0xc0, 0x88, 0xa7, 0xf4, 0x5c,
1511 	0x21, 0x68, 0x39, 0x64, 0x5b, 0x20, 0x12, 0xbf,
1512 	0x2e, 0x62, 0x69, 0xa8, 0xc5, 0x6a, 0x81, 0x6d,
1513 	0xbc, 0x1b, 0x26, 0x77, 0x61, 0x95, 0x5b, 0xc5
1514 }
1515 ;
1516 
1517 static int
test_jwa_b3(struct lws_context * context)1518 test_jwa_b3(struct lws_context *context)
1519 {
1520 	struct lws_jwe jwe;
1521 	char buf[2048];
1522 	int n, ret = -1;
1523 
1524 	lws_jwe_init(&jwe, context);
1525 
1526 	/*
1527 	 * normally all this is interpreted from the JWE blob.  But we don't
1528 	 * have JWE test vectors for AES_256_CBC_HMAC_SHA_512, just a standalone
1529 	 * one.  So we have to create it all by hand.
1530 	 *
1531 	 * See test_jwe_a3 above for a more normal usage pattern.
1532 	 */
1533 
1534 	lws_jwk_dup_oct(&jwe.jwk, jwa_b3_rawkey, sizeof(jwa_b3_rawkey));
1535 
1536 	memcpy(buf, jwa_b3_e, sizeof(jwa_b3_e));
1537 
1538 	jwe.jws.map.buf[LJWE_IV] = (char *)jwa_b3_iv;
1539 	jwe.jws.map.len[LJWE_IV] = sizeof(jwa_b3_iv);
1540 
1541 	jwe.jws.map.buf[LJWE_CTXT] = buf;
1542 	jwe.jws.map.len[LJWE_CTXT] = sizeof(jwa_b3_e);
1543 
1544 	jwe.jws.map.buf[LJWE_ATAG] = (char *)jws_b3_tag;
1545 	jwe.jws.map.len[LJWE_ATAG] = sizeof(jws_b3_tag);
1546 
1547 	/*
1548 	 * Normally this comes from the JOSE header.  But this test vector
1549 	 * doesn't feature one...
1550 	 */
1551 
1552 	if (lws_gencrypto_jwe_alg_to_definition("A128KW", &jwe.jose.alg))
1553 		goto bail;
1554 	if (lws_gencrypto_jwe_enc_to_definition("A256CBC-HS512",
1555 						&jwe.jose.enc_alg))
1556 		goto bail;
1557 
1558 	n = lws_jwe_auth_and_decrypt_cbc_hs(&jwe, jwa_b3_rawkey,
1559 						    jwa_b3_a, sizeof(jwa_b3_a));
1560 	if (n < 0) {
1561 		lwsl_err("%s: lws_jwe_a_cbc_hs_decrypt failed\n", __func__);
1562 
1563 		goto bail;
1564 	}
1565 
1566 	/* allowing for trailing padding, confirm the plaintext */
1567 	if (jwe.jws.map.len[LJWE_CTXT] < sizeof(jwa_b3_ptext) ||
1568 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT],jwa_b3_ptext,
1569 			        sizeof(jwa_b3_ptext))) {
1570 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
1571 		lwsl_hexdump_notice(jwa_b3_ptext, sizeof(jwa_b3_ptext));
1572 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
1573 				    jwe.jws.map.len[LJWE_CTXT]);
1574 		goto bail;
1575 	}
1576 
1577 	ret = 0;
1578 
1579 bail:
1580 	lws_jwe_destroy(&jwe);
1581 
1582 	if (ret)
1583 		lwsl_err("%s: selftest failed ++++++++++++++++++++\n", __func__);
1584 	else
1585 		lwsl_notice("%s: selftest OK\n", __func__);
1586 
1587 	return ret;
1588 }
1589 
1590 /* JWA C.  Example ECDH-ES Key Agreement Computation
1591  *
1592  * This example uses ECDH-ES Key Agreement and the Concat KDF to derive
1593  * the CEK in the manner described in Section 4.6.  In this example, the
1594  * ECDH-ES Direct Key Agreement mode ("alg" value "ECDH-ES") is used to
1595  * produce an agreed-upon key for AES GCM with a 128-bit key ("enc"
1596  * value "A128GCM").
1597  *
1598  * In this example, a producer Alice is encrypting content to a consumer
1599  * Bob.  The producer (Alice) generates an ephemeral key for the key
1600  * agreement computation.
1601  *
1602  * JWA Appendix C where this comes from ONLY goes as far as to confirm the
1603  * direct derived key, it doesn't do any AES128-GCM.
1604  */
1605 
1606 static const char
1607 
1608 *ex_jwa_c_jose =
1609 	"{\"alg\":\"ECDH-ES\","
1610 	 "\"enc\":\"A128GCM\","
1611 	 "\"apu\":\"QWxpY2U\","	/* b64u("Alice") */
1612 	 "\"apv\":\"Qm9i\","	/* b64u("Bob") */
1613 	 "\"epk\":" /* public part of A's ephemeral key */
1614 	 "{\"kty\":\"EC\","
1615 	  "\"crv\":\"P-256\","
1616 	  "\"x\":\"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0\","
1617 	  "\"y\":\"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps\""
1618 	 "}"
1619 	"}"
1620 ;
1621 
1622 static uint8_t
1623 ex_jwa_c_z[] = {
1624 	158,  86, 217,  29, 129, 113,  53, 211,
1625 	114, 131,  66, 131, 191, 132,  38, 156,
1626 	251,  49, 110, 163, 218, 128, 106,  72,
1627 	246, 218, 167, 121, 140, 254, 144, 196
1628 },
1629 ex_jwa_c_derived_key[] = {
1630 	 86, 170, 141, 234, 248,  35, 109,  32,
1631 	 92,  34,  40, 205, 113, 167,  16,  26
1632 };
1633 
1634 
1635 static int
test_jwa_c(struct lws_context * context)1636 test_jwa_c(struct lws_context *context)
1637 {
1638 	struct lws_jwe jwe;
1639 	char temp[2048], *p;
1640 	int ret = -1, temp_len = sizeof(temp);
1641 
1642 	lws_jwe_init(&jwe, context);
1643 
1644 	/*
1645 	 * again the JWA Appendix C test vectors are not in the form of a
1646 	 * complete JWE, but just the JWE JOSE header, so we must fake up the
1647 	 * pieces and perform just the (normally internal) key agreement step
1648 	 * for this test.
1649 	 *
1650 	 * See test_jwe_a3 above for a more normal usage pattern.
1651 	 */
1652 
1653 	if (lws_jwe_parse_jose(&jwe.jose, ex_jwa_c_jose, (int)strlen(ex_jwa_c_jose),
1654 			       temp, &temp_len) < 0) {
1655 		lwsl_err("%s: JOSE parse failed\n", __func__);
1656 
1657 		goto bail;
1658 	}
1659 
1660 	/*
1661 	 * The ephemeral key has been parsed into a jwk "jwe.jose.jwk_ephemeral"
1662 	 *
1663 	 *  In this example, the ECDH-ES Direct Key Agreement mode ("alg" value
1664 	 *  "ECDH-ES") is used to produce an agreed-upon key for AES GCM with a
1665 	 *  128-bit key ("enc" value "A128GCM").
1666 	 */
1667 
1668 	p = lws_concat_temp(temp, temp_len);
1669 
1670 	if (lws_jwa_concat_kdf(&jwe, 1, (uint8_t *)p,
1671 			       ex_jwa_c_z, sizeof(ex_jwa_c_z))) {
1672 		lwsl_err("%s: lws_jwa_concat_kdf failed\n", __func__);
1673 
1674 		goto bail;
1675 	}
1676 
1677 	/* allowing for trailing padding, confirm the plaintext */
1678 	if (lws_timingsafe_bcmp(p, ex_jwa_c_derived_key,
1679 			        sizeof(ex_jwa_c_derived_key))) {
1680 		lwsl_err("%s: ECDH-ES direct derived key wrong\n", __func__);
1681 		lwsl_hexdump_notice(ex_jwa_c_derived_key,
1682 				    sizeof(ex_jwa_c_derived_key));
1683 		lwsl_hexdump_notice(p, sizeof(ex_jwa_c_derived_key));
1684 		goto bail;
1685 	}
1686 
1687 	ret = 0;
1688 
1689 bail:
1690 	lws_jwe_destroy(&jwe);
1691 
1692 	if (ret)
1693 		lwsl_err("%s: selftest failed +++++++++++++++++++\n", __func__);
1694 	else
1695 		lwsl_notice("%s: selftest OK\n", __func__);
1696 
1697 	return ret;
1698 }
1699 
1700 
1701 /*
1702  * ECDH-ES Homebrew Encryption test
1703  */
1704 
1705 static const char
1706 
1707 	/* peer key */
1708 
1709 *ecdhes_t1_peer_p256_public_key = /* as below but with d removed */
1710 	"{"
1711 	 "\"crv\":\"P-256\","
1712 	 "\"kty\":\"EC\","
1713 	 "\"x\":\"ySlIGttmXG80WPjDO01QaXg7oAzW3NE-a-GF0NDGk_E\","
1714 	 "\"y\":\"i08k5z4ppqgtnLK8lh5qw4qp2FhxPdGjovgilajluuw\""
1715 	"}",
1716 
1717 *ecdhes_t1_peer_p256_private_key = /* created by ./lws-crypto-jwk -t EC */
1718 	"{"
1719 	 "\"crv\":\"P-256\","
1720 	 "\"d\":\"ldszv0_cGFMkjxaPspGCP6X0NAaVCVeK48oH4RzT2T0\","
1721 	 "\"kty\":\"EC\","
1722 	 "\"x\":\"ySlIGttmXG80WPjDO01QaXg7oAzW3NE-a-GF0NDGk_E\","
1723 	 "\"y\":\"i08k5z4ppqgtnLK8lh5qw4qp2FhxPdGjovgilajluuw\""
1724 	"}",
1725 
1726 *ecdhes_t1_peer_p384_public_key = /* as below but with d removed */
1727 	"{\"crv\":\"P-384\","
1728 	 "\"kty\":\"EC\","
1729 	 "\"x\":\"injKcygDoG1AuP044ct88r_2DNinHr1CGqy4q2Sy5yo034Y"
1730 		 "7yQ5_NT-lEUXrzlIW\","
1731 	 "\"y\":\"y52QaJLhVm-ts8xa1jL8GkmwGm_dX6xV1PSq4s3pbwx2Hu9"
1732 		 "X29z5WYcTPFOCPtwJ\"}",
1733 
1734 *ecdhes_t1_peer_p384_private_key = /* created by ./lws-crypto-jwk -t EC -v "P-384" */
1735 	"{\"crv\":\"P-384\","
1736 	 "\"d\":\"jYGze6ZwZxrflVx_I2lYWNf9GkfbeQNRwQCdtZhBlb85lk-"
1737 		 "SAvaZuNiRUs_eWmPQ\","
1738 	 "\"kty\":\"EC\","
1739 	 "\"x\":\"injKcygDoG1AuP044ct88r_2DNinHr1CGqy4q2Sy5yo034Y"
1740 		 "7yQ5_NT-lEUXrzlIW\","
1741 	 "\"y\":\"y52QaJLhVm-ts8xa1jL8GkmwGm_dX6xV1PSq4s3pbwx2Hu9"
1742 		 "X29z5WYcTPFOCPtwJ\"}",
1743 
1744  *ecdhes_t1_peer_p521_public_key = /* as below but with d removed */
1745 	"{\"crv\":\"P-521\","
1746 	 "\"kty\":\"EC\","
1747 	 "\"x\":\"AYe0gAkPzzjeQW5Ek9tVrWdfi0u6k7LVUru-b2x7V9EM3d"
1748 		 "L4SbQiS1p2j2gmZ2a6aDoKDRU_2E4u9EQrlswlty-g\","
1749 	 "\"y\":\"AEAIIRkVL0WhtDlDSM7dciBtL1dOo5UPiW7ixIOv5K75Mo"
1750 		 "uFNWO7cFmcxaCOn9459ex0giVyptmX_956C_DWabG6\"}",
1751 
1752 *ecdhes_t1_peer_p521_private_key = /* created by ./lws-crypto-jwk -t EC -v "P-521" */
1753 	"{\"crv\":\"P-521\","
1754 	 "\"d\":\"AUer7_-qJtQtDWN6CMeGB20rzTa648kpsfidTOu3lnn6__"
1755 		 "yOXkMj1yTYUBjVOnUjGHiTU1rCGsw4CyF-1nDRe7SM\","
1756 	 "\"kty\":\"EC\","
1757 	 "\"x\":\"AYe0gAkPzzjeQW5Ek9tVrWdfi0u6k7LVUru-b2x7V9EM3d"
1758 		 "L4SbQiS1p2j2gmZ2a6aDoKDRU_2E4u9EQrlswlty-g\","
1759 	 "\"y\":\"AEAIIRkVL0WhtDlDSM7dciBtL1dOo5UPiW7ixIOv5K75Mo"
1760 		 "uFNWO7cFmcxaCOn9459ex0giVyptmX_956C_DWabG6\"}",
1761 
1762 *ecdhes_t1_jose_hdr_es_128 =
1763 	"{\"alg\":\"ECDH-ES\",\"enc\":\"A128CBC-HS256\"}",
1764 
1765 *ecdhes_t1_jose_hdr_es_192 =
1766 	"{\"alg\":\"ECDH-ES\",\"enc\":\"A192CBC-HS384\"}",
1767 
1768 *ecdhes_t1_jose_hdr_es_256 =
1769 	"{\"alg\":\"ECDH-ES\",\"enc\":\"A256CBC-HS512\"}",
1770 
1771 *ecdhes_t1_jose_hdr_esakw128_128 =
1772 	"{\"alg\":\"ECDH-ES+A128KW\",\"enc\":\"A128CBC-HS256\"}",
1773 
1774 *ecdhes_t1_jose_hdr_esakw192_192 =
1775 	"{\"alg\":\"ECDH-ES+A192KW\",\"enc\":\"A192CBC-HS384\"}",
1776 
1777 *ecdhes_t1_jose_hdr_esakw256_256 =
1778 	"{\"alg\":\"ECDH-ES+A256KW\",\"enc\":\"A256CBC-HS512\"}",
1779 
1780 *ecdhes_t1_plaintext =
1781 	"This test plaintext is exactly 64 bytes long when unencrypted..."
1782 ;
1783 
1784 static int
test_ecdhes_t1(struct lws_context * context,const char * jose_hdr,const char * peer_pubkey,const char * peer_privkey)1785 test_ecdhes_t1(struct lws_context *context, const char *jose_hdr,
1786 	       const char *peer_pubkey, const char *peer_privkey)
1787 {
1788 	char temp[3072], compact[2048];
1789 	int n, ret = -1, temp_len = sizeof(temp);
1790 	struct lws_jwe jwe;
1791 
1792 	lws_jwe_init(&jwe, context);
1793 
1794 	/* read and interpret our canned JOSE header, setting the algorithm */
1795 
1796 	if (lws_jws_dup_element(&jwe.jws.map, LJWS_JOSE,
1797 				lws_concat_temp(temp, temp_len), &temp_len,
1798 				jose_hdr, strlen(jose_hdr), 0))
1799 		goto bail;
1800 
1801 	if (lws_jwe_parse_jose(&jwe.jose, jose_hdr, (int)strlen(jose_hdr),
1802 			       temp, &temp_len) < 0) {
1803 		lwsl_err("%s: JOSE parse failed\n", __func__);
1804 
1805 		goto bail;
1806 	}
1807 
1808 	/* for ecdh-es encryption, we need the peer's pubkey */
1809 
1810 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, (char *)peer_pubkey,
1811 			   strlen((char *)peer_pubkey)) < 0) {
1812 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
1813 		goto bail;
1814 	}
1815 
1816 	/*
1817 	 * dup the plaintext into the ciphertext element, it will be
1818 	 * encrypted in-place to a ciphertext of the same length + padding
1819 	 */
1820 
1821 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_CTXT,
1822 				lws_concat_temp(temp, temp_len), &temp_len,
1823 				ecdhes_t1_plaintext,
1824 				strlen(ecdhes_t1_plaintext),
1825 				lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN,
1826 						strlen(ecdhes_t1_plaintext)))) {
1827 		lwsl_notice("%s: Not enough temp space for ptext\n", __func__);
1828 		goto bail;
1829 	}
1830 
1831 	/*
1832 	 * perform the actual encryption
1833 	 */
1834 
1835 	n = lws_jwe_encrypt(&jwe, lws_concat_temp(temp, temp_len), &temp_len);
1836 	if (n < 0) {
1837 		lwsl_err("%s: lws_jwe_encrypt failed\n", __func__);
1838 		goto bail;
1839 	}
1840 
1841 	/*
1842 	 * format for output
1843 	 */
1844 
1845 	n = lws_jwe_render_flattened(&jwe, compact, sizeof(compact));
1846 	if (n < 0) {
1847 		lwsl_err("%s: lws_jwe_render_compact failed: %d\n",
1848 			 __func__, n);
1849 		goto bail;
1850 	}
1851 
1852 	// puts(compact);
1853 
1854 	n = lws_jwe_render_compact(&jwe, compact, sizeof(compact));
1855 	if (n < 0) {
1856 		lwsl_err("%s: lws_jwe_render_compact failed: %d\n",
1857 			 __func__, n);
1858 		goto bail;
1859 	}
1860 
1861 	// puts(compact);
1862 
1863 	/* okay, let's try to decrypt the whole thing, as the recipient
1864 	 * getting the compact.  jws->jwk needs to be our private key.  */
1865 
1866 	lws_jwe_destroy(&jwe);
1867 	temp_len = sizeof(temp);
1868 	lws_jwe_init(&jwe, context);
1869 
1870 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, (char *)peer_privkey,
1871 			   strlen((char *)peer_privkey)) < 0) {
1872 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
1873 		goto bail;
1874 	}
1875 
1876 	/* converts a compact serialization to jws b64 + decoded maps */
1877 	if (lws_jws_compact_decode(compact, (int)strlen(compact), &jwe.jws.map,
1878 				   &jwe.jws.map_b64, temp, &temp_len) != 5) {
1879 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
1880 		goto bail;
1881 	}
1882 
1883 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len),
1884 				     &temp_len);
1885 	if (n < 0) {
1886 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
1887 			 __func__);
1888 		goto bail;
1889 	}
1890 
1891 	ret = 0;
1892 
1893 bail:
1894 	lws_jwe_destroy(&jwe);
1895 	if (ret)
1896 		lwsl_err("%s: %s selftest failed +++++++++++++++++++\n",
1897 			 __func__, jose_hdr);
1898 	else
1899 		lwsl_notice("%s: %s selftest OK\n", __func__, jose_hdr);
1900 
1901 	return ret;
1902 }
1903 
1904 /* AES Key Wrap and AES_XXX_CBC_HMAC_SHA_YYY variations
1905  *
1906  * These were created using the node-jose node.js package
1907  */
1908 static const char
1909 	*akw_ptext = "plaintext0123456",
1910 	*akw_ct_128_128 = "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Ii"
1911 	"wia2lkIjoiLTRXTEpQNWNrYUxBUFFFNXkwYXhLT0JUSTlFTngxUXBCa0toNkdOY2loOC"
1912 	"J9.h6oNSEgz3LwIMndEkPEa8H7_5zy0hh8TaU_1yWoNtu4Dh_WJpEgx9g.j7TYjj8wB0"
1913 	"RS6rclTWYmqw.zm3tPzuWhXoD7IsAWbA0xz-AJXvE9gydWPRBTaO40sQ.Okf7ttWDLPM"
1914 	"wIj1kUyUO_A",
1915 	*akw_ct_128_192 = "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTkyQ0JDLUhTMzg0Ii"
1916 	"wia2lkIjoiLTRXTEpQNWNrYUxBUFFFNXkwYXhLT0JUSTlFTngxUXBCa0toNkdOY2loOC"
1917 	"J9.XkRTu4nP3b0KZxXjkjdHEnbf6AWZUmFvpsqZLuLxKcrONqDUsnYasnVuo6U0QKRUm"
1918 	"cyBRtSPGW4.MzNxxoOp8JR2AHoLNve-vw.rdxgo6InRAxk3afG02_75l58u5m6KYHd3h"
1919 	"LH16ksnZE.v7BLKaRZIwhUPhhBRTd8yPwH0xa1fOft",
1920 	*akw_ct_128_256 = "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIi"
1921 	"wia2lkIjoiLTRXTEpQNWNrYUxBUFFFNXkwYXhLT0JUSTlFTngxUXBCa0toNkdOY2loOC"
1922 	"J9.mueR-8XzXs2RyvzzvghpIpGS1mGl7vkSjJDF5zqhH8-ektBpCXSd7R7MS5nh2-Xf_"
1923 	"8XDym1gn1QEQh5bDI3GPESnSN1TJR-h.g6plL_5L2BD8wcjZS7X79A.UTndfTFhGFaVZ"
1924 	"vWqPkV7dN00gckesd_7UylosVDqjwU.-rgi0jkYuCZDMwUVLxN6e6x8fXw2U0u4-vL8u"
1925 	"Kb__S8",
1926 	*akw_ct_192_128 = "eyJhbGciOiJBMTkyS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Ii"
1927 	"wia2lkIjoiai10RWp2Q2JyNVlUZWtKUXlES3kyQXh5cjBWeUlUWXk4S3IycjB0cy1USS"
1928 	"J9.mEURnj2NvPa3TU0uR8mcm2cMd33Y6iYYZ_LFrYS_Gz49gcdxZpdk1Q.v3csq81X9o"
1929 	"mI-bcp6i-FTQ.EgroRqmqNfeH7XC9msLap1IGcqvc09SlnI4PO6RQqS0.hDi57mXD3vX"
1930 	"dx2r4Kwnv9w",
1931 	*akw_ct_192_192 = "eyJhbGciOiJBMTkyS1ciLCJlbmMiOiJBMTkyQ0JDLUhTMzg0Ii"
1932 	"wia2lkIjoiai10RWp2Q2JyNVlUZWtKUXlES3kyQXh5cjBWeUlUWXk4S3IycjB0cy1USS"
1933 	"J9.QHgtusQdP7Zvw9tsCZNkJyEmzg6KUaaIyTb2BXB0ng9mxSUIQ7y_6oqasYKBUJgBn"
1934 	"Koru-3CXOE.ZZXcGY35mmlAb4-IgA5XlQ.AuG2GRPeYJ80_4XoYAUgXbVY65ZQ689Grn"
1935 	"x8RCNQdfc.UjfgDr4z3PGQBdftWT2gqx1Egfd9PUR4",
1936 	*akw_ct_192_256 = "eyJhbGciOiJBMTkyS1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIi"
1937 	"wia2lkIjoiai10RWp2Q2JyNVlUZWtKUXlES3kyQXh5cjBWeUlUWXk4S3IycjB0cy1USS"
1938 	"J9.G6DziymYyU3-6unIa-Oz-0lksH05OJFDZKkFuShMuoazEMZ5ZH2S_65qD-pjpf8aN"
1939 	"2thOVOYT0mdtgFM0ARUfx8ZLhRFCcn1.yEKK4eARZIo9WtGVcQmgDQ.ovan2NXDmt_Ka"
1940 	"SsVJmhIMQqVz6meqz1oExfVcY8vdzA.R3T4lQIKX5cc2Ktv42e9u5PR--v_w2uK7F4Wp"
1941 	"Sr5SQ8",
1942 	*akw_ct_256_128 = "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Ii"
1943 	"wia2lkIjoiSDVwSzRRUU81U0tHbDA3UXhIdk9YMzVqS2FJbzA2NXVLdWRubVZFZVpJYy"
1944 	"J9.ZLWrz5CE7Iav2db37VL9ZABeaRVrV9af-7-46Loc9M2D0SPSNtsxpg.ktk-VU8-5b"
1945 	"XRvW_A6IqDjQ.xZVIglOhadDBHUYuxPx6Wr_YzOo0qCDH24xVe58qP9Q.pO_tME930wO"
1946 	"u5fNJ8ubGrw",
1947 	*akw_ct_256_192 = "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMTkyQ0JDLUhTMzg0Ii"
1948 	"wia2lkIjoiSDVwSzRRUU81U0tHbDA3UXhIdk9YMzVqS2FJbzA2NXVLdWRubVZFZVpJYy"
1949 	"J9.fcblAVZ7VOXtyhymqxDBr-zgvId18p3AURNbhH5FmAvKNuUVU37xPkz6BrFopLP0J"
1950 	"jqXaTyyg1s.fprTe2e0esH2w7EnLEgBZQ.g1BI0U1aKSM_JBEp9jC4BxBaFXVG5BW4nl"
1951 	"bhX1MDeLo.XOLanrIkitLLDRONnfM05avahl_lJ_UY",
1952 	*akw_ct_256_256 = "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIi"
1953 	"wia2lkIjoiSDVwSzRRUU81U0tHbDA3UXhIdk9YMzVqS2FJbzA2NXVLdWRubVZFZVpJYy"
1954 	"J9.SpizfgtzQLJCCnYnUmNfiMMTyL8iIDi8OyUDrO00KJtfwJdNAcs-NuYQkLKx6PlDJ"
1955 	"IGjucT4-IuA8k_Oc752kq1BzTHMZ-Mo.go-e8xpQoCmLD5RBQw7ruA.WqkEdM6T1_z5F"
1956 	"C-8eGQfGjos7cHPy1ecZk1Ep-TYgXo.bZVHhIpe2PbjguQlK_afkYDlVmEtRAe3LUJUX"
1957 	"4STOtU",
1958 	*akw_key_128 = "{\"k\":\"JjVJVh8JsXvKf9qgHHWWBA\",\"kty\":\"oct\"}",
1959 	*akw_key_192 = "{\"k\":\"BYF6urCMDRMKFXXRxXrDSVtW71AUZghj\",\"kty\":\"oct\"}",
1960 	*akw_key_256 = "{\"k\":\"cSHyZXGEfnlgKud21cM6tAxRyXnK6xbWRTsyLUegTMk\",\"kty\":\"oct\"}"
1961 ;
1962 
1963 static int
test_akw_decrypt(struct lws_context * context,const char * test_name,const char * ciphertext,const char * key)1964 test_akw_decrypt(struct lws_context *context, const char *test_name,
1965 		 const char *ciphertext, const char *key)
1966 {
1967 	struct lws_jwe jwe;
1968 	char temp[2048];
1969 	int n, ret = -1, temp_len = sizeof(temp);
1970 
1971 	lws_jwe_init(&jwe, context);
1972 
1973 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, key, strlen(key)) < 0) {
1974 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
1975 		goto bail;
1976 	}
1977 
1978 	/* converts a compact serialization to jws b64 + decoded maps */
1979 	if (lws_jws_compact_decode(ciphertext, (int)strlen(ciphertext),
1980 				   &jwe.jws.map, &jwe.jws.map_b64,
1981 				   temp, &temp_len) != 5) {
1982 		lwsl_err("%s: lws_jws_compact_decode failed\n", __func__);
1983 		goto bail;
1984 	}
1985 
1986 	n = lws_jwe_auth_and_decrypt(&jwe, lws_concat_temp(temp, temp_len), &temp_len);
1987 	if (n < 0) {
1988 		lwsl_err("%s: lws_jwe_auth_and_decrypt failed\n",
1989 			 __func__);
1990 		goto bail;
1991 	}
1992 
1993 	/* allowing for trailing padding, confirm the plaintext */
1994 	if (jwe.jws.map.len[LJWE_CTXT] < strlen(akw_ptext) ||
1995 	    lws_timingsafe_bcmp(jwe.jws.map.buf[LJWE_CTXT], akw_ptext,
1996 			        (uint32_t)strlen(akw_ptext))) {
1997 		lwsl_err("%s: plaintext AES decrypt wrong\n", __func__);
1998 		lwsl_hexdump_notice(akw_ptext, strlen(akw_ptext));
1999 		lwsl_hexdump_notice(jwe.jws.map.buf[LJWE_CTXT],
2000 				    jwe.jws.map.len[LJWE_CTXT]);
2001 		goto bail;
2002 	}
2003 
2004 	ret = 0;
2005 
2006 bail:
2007 	lws_jwe_destroy(&jwe);
2008 	if (ret)
2009 		lwsl_err("%s: selftest %s failed +++++++++++++++++++\n",
2010 			__func__, test_name);
2011 	else
2012 		lwsl_notice("%s: selftest %s OK\n", __func__, test_name);
2013 
2014 	return ret;
2015 }
2016 
2017 static int
test_akw_encrypt(struct lws_context * context,const char * test_name,const char * alg,const char * enc,const char * ciphertext,const char * key,char * compact,int compact_len)2018 test_akw_encrypt(struct lws_context *context, const char *test_name,
2019 		 const char *alg, const char *enc, const char *ciphertext,
2020 		 const char *key, char *compact, int compact_len)
2021 {
2022 	struct lws_jwe jwe;
2023 	char temp[4096];
2024 	int ret = -1, n, temp_len = sizeof(temp);
2025 
2026 	lws_jwe_init(&jwe, context);
2027 
2028 	if (lws_jwk_import(&jwe.jwk, NULL, NULL, key, strlen(key)) < 0) {
2029 		lwsl_notice("%s: Failed to decode JWK test key\n", __func__);
2030 		goto bail;
2031 	}
2032 
2033 	if (lws_gencrypto_jwe_alg_to_definition(alg, &jwe.jose.alg)) {
2034 		lwsl_err("Unknown cipher alg %s\n", alg);
2035 		goto bail;
2036 	}
2037 	if (lws_gencrypto_jwe_enc_to_definition(enc, &jwe.jose.enc_alg)) {
2038 		lwsl_err("Unknown payload enc alg %s\n", enc);
2039 		goto bail;
2040 	}
2041 
2042 	/* we require a JOSE-formatted header to do the encryption */
2043 
2044 	jwe.jws.map.buf[LJWS_JOSE] = temp;
2045 	jwe.jws.map.len[LJWS_JOSE] = (uint32_t)lws_snprintf(temp, (unsigned int)temp_len,
2046 			"{\"alg\":\"%s\", \"enc\":\"%s\"}", alg, enc);
2047 	temp_len -= (int)jwe.jws.map.len[LJWS_JOSE];
2048 
2049 	/*
2050 	 * dup the plaintext into the ciphertext element, it will be
2051 	 * encrypted in-place to a ciphertext of the same length + padding
2052 	 */
2053 
2054 	if (lws_jws_dup_element(&jwe.jws.map, LJWE_CTXT,
2055 				lws_concat_temp(temp, temp_len), &temp_len,
2056 				akw_ptext, strlen(akw_ptext),
2057 				lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN,
2058 							  strlen(akw_ptext)))) {
2059 		lwsl_notice("%s: Not enough temp space for ptext\n", __func__);
2060 		goto bail;
2061 	}
2062 
2063 	/* CEK size is determined by hash / hmac size */
2064 
2065 	n = lws_gencrypto_bits_to_bytes(jwe.jose.enc_alg->keybits_fixed);
2066 	if (lws_jws_randomize_element(context, &jwe.jws.map, LJWE_EKEY,
2067 				      lws_concat_temp(temp, temp_len),
2068 				      &temp_len, (unsigned int)n,
2069 				      LWS_JWE_LIMIT_KEY_ELEMENT_BYTES)) {
2070 		lwsl_err("Problem getting random\n");
2071 		goto bail;
2072 	}
2073 
2074 	n = lws_jwe_encrypt(&jwe, lws_concat_temp(temp, temp_len),
2075 			    &temp_len);
2076 	if (n < 0) {
2077 		lwsl_err("%s: lws_jwe_encrypt failed\n", __func__);
2078 		goto bail;
2079 	}
2080 
2081 	n = lws_jwe_render_compact(&jwe, compact, (unsigned int)compact_len);
2082 	if (n < 0) {
2083 		lwsl_err("%s: lws_jwe_render_compact failed: %d\n",
2084 			 __func__, n);
2085 		goto bail;
2086 	}
2087 
2088 	ret = 0;
2089 bail:
2090 	lws_jwe_destroy(&jwe);
2091 	if (ret)
2092 		lwsl_err("%s: selftest %s failed +++++++++++++++++++\n",
2093 			__func__, test_name);
2094 	else
2095 		lwsl_notice("%s: selftest %s OK\n", __func__, test_name);
2096 
2097 	return ret;
2098 }
2099 
2100 /*
2101  * Check we can handle multi-recipient JWE
2102  */
2103 
2104 static char *complete =
2105     "{"
2106       "\"protected\":"
2107        "\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\","
2108       "\"unprotected\":"
2109        "{\"jku\":\"https://server.example.com/keys.jwks\"},"
2110       "\"recipients\":["
2111 
2112 	"{\"header\":"
2113          "{\"alg\":\"RSA1_5\",\"kid\":\"2011-04-29\"},"
2114         "\"encrypted_key\":"
2115          "\"UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-"
2116           "kFm1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKx"
2117           "GHZ7PcHALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3"
2118           "YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPh"
2119           "cCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPg"
2120           "wCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A\"},"
2121 
2122        "{\"header\":"
2123          "{\"alg\":\"A128KW\",\"kid\":\"7\"},"
2124         "\"encrypted_key\":"
2125          "\"6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ\"}],"
2126 
2127       "\"iv\":"
2128        "\"AxY8DCtDaGlsbGljb3RoZQ\","
2129       "\"ciphertext\":"
2130        "\"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY\","
2131       "\"tag\":"
2132        "\"Mz-VPPyU4RlcuYv1IwIvzw\""
2133      "}\""
2134 ;
2135 
2136 static int
test_jwe_json_complete(struct lws_context * context)2137 test_jwe_json_complete(struct lws_context *context)
2138 {
2139 	struct lws_jwe jwe;
2140 	char temp[4096];
2141 	int ret = -1, temp_len = sizeof(temp);
2142 
2143 	lws_jwe_init(&jwe, context);
2144 
2145 	if (lws_jwe_parse_jose(&jwe.jose, complete, (int)strlen(complete),
2146 			       temp, &temp_len) < 0) {
2147 		lwsl_err("%s: JOSE parse failed\n", __func__);
2148 
2149 		goto bail;
2150 	}
2151 
2152 	if (jwe.jose.recipients != 2) {
2153 		lwsl_err("%s: wrong recipients count %d\n", __func__,
2154 			 jwe.jose.recipients);
2155 		goto bail;
2156 	}
2157 
2158 	ret = 0;
2159 bail:
2160 	lws_jwe_destroy(&jwe);
2161 	if (ret)
2162 		lwsl_err("%s: selftest failed +++++++++++++++++++\n",
2163 			__func__);
2164 	else
2165 		lwsl_notice("%s: selftest OK\n", __func__);
2166 
2167 	return ret;
2168 }
2169 
2170 int
test_jwe(struct lws_context * context)2171 test_jwe(struct lws_context *context)
2172 {
2173 	char compact[4096];
2174 	int n = 0;
2175 
2176 	n |= test_jwe_json_complete(context);
2177 
2178 	n |= test_ecdhes_t1(context, ecdhes_t1_jose_hdr_es_128,
2179 			    ecdhes_t1_peer_p256_public_key,
2180 			    ecdhes_t1_peer_p256_private_key);
2181 	n |= test_ecdhes_t1(context, ecdhes_t1_jose_hdr_es_192,
2182 			    ecdhes_t1_peer_p384_public_key,
2183 			    ecdhes_t1_peer_p384_private_key);
2184 	n |= test_ecdhes_t1(context, ecdhes_t1_jose_hdr_es_256,
2185 			    ecdhes_t1_peer_p521_public_key,
2186 			    ecdhes_t1_peer_p521_private_key);
2187 
2188 	n |= test_ecdhes_t1(context, ecdhes_t1_jose_hdr_esakw128_128,
2189 			    ecdhes_t1_peer_p256_public_key,
2190 			    ecdhes_t1_peer_p256_private_key);
2191 	n |= test_ecdhes_t1(context, ecdhes_t1_jose_hdr_esakw192_192,
2192 			    ecdhes_t1_peer_p384_public_key,
2193 			    ecdhes_t1_peer_p384_private_key);
2194 	n |= test_ecdhes_t1(context, ecdhes_t1_jose_hdr_esakw256_256,
2195 			    ecdhes_t1_peer_p521_public_key,
2196 			    ecdhes_t1_peer_p521_private_key);
2197 
2198 	n |= test_jwe_a1(context);
2199 
2200 	n |= test_jwe_a2(context);
2201 
2202 	n |= test_jwe_ra_ptext_1024(context, (char *)lws_jwe_ex_a2_jwk_json,
2203 				    (int)strlen((char *)lws_jwe_ex_a2_jwk_json));
2204 	n |= test_jwe_r256a192_ptext(context, (char *)lws_jwe_ex_a2_jwk_json,
2205 			(int)strlen((char *)lws_jwe_ex_a2_jwk_json));
2206 	n |= test_jwe_r256a256_ptext(context, (char *)lws_jwe_ex_a2_jwk_json,
2207 			(int)strlen((char *)lws_jwe_ex_a2_jwk_json));
2208 	n |= test_jwe_ra_ptext_1024(context, (char *)rsa_key_2048,
2209 			(int)strlen((char *)rsa_key_2048));
2210 	n |= test_jwe_r256a192_ptext(context, (char *)rsa_key_2048,
2211 			(int)strlen((char *)rsa_key_2048));
2212 	n |= test_jwe_r256a256_ptext(context, (char *)rsa_key_2048,
2213 			(int)strlen((char *)rsa_key_2048));
2214 	n |= test_jwe_ra_ptext_1024(context, (char *)rsa_key_4096,
2215 			(int)strlen((char *)rsa_key_4096));
2216 	n |= test_jwe_r256a192_ptext(context, (char *)rsa_key_4096,
2217 			(int)strlen((char *)rsa_key_4096));
2218 	n |= test_jwe_r256a256_ptext(context, (char *)rsa_key_4096,
2219 			(int)strlen((char *)rsa_key_4096));
2220 	n |= test_jwe_ra_ptext_1024(context, (char *)rsa_key_4096_no_optional,
2221 			(int)strlen((char *)rsa_key_4096_no_optional));
2222 	n |= test_jwe_r256a192_ptext(context, (char *)rsa_key_4096_no_optional,
2223 			(int)strlen((char *)rsa_key_4096_no_optional));
2224 	n |= test_jwe_r256a256_ptext(context, (char *)rsa_key_4096_no_optional,
2225 			(int)strlen((char *)rsa_key_4096_no_optional));
2226 
2227 	/* AESKW decrypt all variations */
2228 
2229 	n |= test_akw_decrypt(context, "d-a128kw_128", akw_ct_128_128, akw_key_128);
2230 	n |= test_akw_decrypt(context, "d-a128kw_192", akw_ct_128_192, akw_key_128);
2231 	n |= test_akw_decrypt(context, "d-a128kw_256", akw_ct_128_256, akw_key_128);
2232 	n |= test_akw_decrypt(context, "d-a192kw_128", akw_ct_192_128, akw_key_192);
2233 	n |= test_akw_decrypt(context, "d-a192kw_192", akw_ct_192_192, akw_key_192);
2234 	n |= test_akw_decrypt(context, "d-a192kw_256", akw_ct_192_256, akw_key_192);
2235 	n |= test_akw_decrypt(context, "d-a256kw_128", akw_ct_256_128, akw_key_256);
2236 	n |= test_akw_decrypt(context, "d-a256kw_192", akw_ct_256_192, akw_key_256);
2237 	n |= test_akw_decrypt(context, "d-a256kw_256", akw_ct_256_256, akw_key_256);
2238 
2239 	/* AESKW encrypt then confirm decrypt */
2240 
2241 	if (!test_akw_encrypt(context, "ed-128kw_128", "A128KW", "A128CBC-HS256",
2242 			akw_ptext, akw_key_128, compact, sizeof(compact)))
2243 		n |= test_akw_decrypt(context, "ed-128kw_128", compact, akw_key_128);
2244 	else
2245 		n = -1;
2246 	if (!test_akw_encrypt(context, "ed-128kw_192", "A128KW", "A192CBC-HS384",
2247 			akw_ptext, akw_key_128, compact, sizeof(compact)))
2248 		n |= test_akw_decrypt(context, "ed-128kw_192", compact, akw_key_128);
2249 	else
2250 		n = -1;
2251 	if (!test_akw_encrypt(context, "ed-128kw_256", "A128KW", "A256CBC-HS512",
2252 			akw_ptext, akw_key_128, compact, sizeof(compact)))
2253 		n |= test_akw_decrypt(context, "ed-128kw_256", compact, akw_key_128);
2254 	else
2255 		n = -1;
2256 
2257 	if (!test_akw_encrypt(context, "ed-192kw_128", "A192KW", "A128CBC-HS256",
2258 			akw_ptext, akw_key_192, compact, sizeof(compact)))
2259 		n |= test_akw_decrypt(context, "ed-192kw_128", compact, akw_key_192);
2260 	else
2261 		n = -1;
2262 	if (!test_akw_encrypt(context, "ed-192kw_192", "A192KW", "A192CBC-HS384",
2263 			akw_ptext, akw_key_192, compact, sizeof(compact)))
2264 		n |= test_akw_decrypt(context, "ed-192kw_192", compact, akw_key_192);
2265 	else
2266 		n = -1;
2267 	if (!test_akw_encrypt(context, "ed-192kw_256", "A192KW", "A256CBC-HS512",
2268 			akw_ptext, akw_key_192, compact, sizeof(compact)))
2269 		n |= test_akw_decrypt(context, "ed-192kw_256", compact, akw_key_192);
2270 	else
2271 		n = -1;
2272 
2273 	if (!test_akw_encrypt(context, "ed-256kw_128", "A256KW", "A128CBC-HS256",
2274 			akw_ptext, akw_key_256, compact, sizeof(compact)))
2275 		n |= test_akw_decrypt(context, "ed-256kw_128", compact, akw_key_256);
2276 	else
2277 		n = -1;
2278 	if (!test_akw_encrypt(context, "ed-256kw_192", "A256KW", "A192CBC-HS384",
2279 			akw_ptext, akw_key_256, compact, sizeof(compact)))
2280 		n |= test_akw_decrypt(context, "ed-256kw_192", compact, akw_key_256);
2281 	else
2282 		n = -1;
2283 	if (!test_akw_encrypt(context, "ed-256kw_256", "A256KW", "A256CBC-HS512",
2284 			akw_ptext, akw_key_256, compact, sizeof(compact)))
2285 		n |= test_akw_decrypt(context, "ed-256kw_256", compact, akw_key_256);
2286 	else
2287 		n = -1;
2288 
2289 	n |= test_jwe_r256a128_jwe_openssl(context);
2290 	n |= test_jwe_r256a128_jwe_mbedtls(context);
2291 	n |= test_jwe_a3(context);
2292 	n |= test_jwa_b2(context);
2293 	n |= test_jwa_b3(context);
2294 	n |= test_jwa_c(context);
2295 
2296 	return n;
2297 }
2298