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