/src/libwebsockets/lib/tls/lws-gencrypto-common.c
Line | Count | Source |
1 | | /* |
2 | | * libwebsockets - small server side websockets and web server implementation |
3 | | * |
4 | | * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | | * of this software and associated documentation files (the "Software"), to |
8 | | * deal in the Software without restriction, including without limitation the |
9 | | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
10 | | * sell copies of the Software, and to permit persons to whom the Software is |
11 | | * furnished to do so, subject to the following conditions: |
12 | | * |
13 | | * The above copyright notice and this permission notice shall be included in |
14 | | * all copies or substantial portions of the Software. |
15 | | * |
16 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
22 | | * IN THE SOFTWARE. |
23 | | */ |
24 | | |
25 | | #include "private-lib-core.h" |
26 | | |
27 | | /* |
28 | | * These came from RFC7518 (JSON Web Algorithms) Section 3 |
29 | | * |
30 | | * Cryptographic Algorithms for Digital Signatures and MACs |
31 | | */ |
32 | | |
33 | | static const struct lws_jose_jwe_alg lws_gencrypto_jws_alg_map[] = { |
34 | | |
35 | | /* |
36 | | * JWSs MAY also be created that do not provide integrity protection. |
37 | | * Such a JWS is called an Unsecured JWS. An Unsecured JWS uses the |
38 | | * "alg" value "none" and is formatted identically to other JWSs, but |
39 | | * MUST use the empty octet sequence as its JWS Signature value. |
40 | | * Recipients MUST verify that the JWS Signature value is the empty |
41 | | * octet sequence. |
42 | | * |
43 | | * Implementations that support Unsecured JWSs MUST NOT accept such |
44 | | * objects as valid unless the application specifies that it is |
45 | | * acceptable for a specific object to not be integrity protected. |
46 | | * Implementations MUST NOT accept Unsecured JWSs by default. In order |
47 | | * to mitigate downgrade attacks, applications MUST NOT signal |
48 | | * acceptance of Unsecured JWSs at a global level, and SHOULD signal |
49 | | * acceptance on a per-object basis. See Section 8.5 for security |
50 | | * considerations associated with using this algorithm. |
51 | | */ |
52 | | { /* optional */ |
53 | | LWS_GENHASH_TYPE_UNKNOWN, |
54 | | LWS_GENHMAC_TYPE_UNKNOWN, |
55 | | LWS_JOSE_ENCTYPE_NONE, |
56 | | LWS_JOSE_ENCTYPE_NONE, |
57 | | "none", NULL, 0, 0, 0 |
58 | | }, |
59 | | |
60 | | /* |
61 | | * HMAC with SHA-2 Functions |
62 | | * |
63 | | * The HMAC SHA-256 MAC for a JWS is validated by computing an HMAC |
64 | | * value per RFC 2104, using SHA-256 as the hash algorithm "H", using |
65 | | * the received JWS Signing Input as the "text" value, and using the |
66 | | * shared key. This computed HMAC value is then compared to the result |
67 | | * of base64url decoding the received encoded JWS Signature value. The |
68 | | * comparison of the computed HMAC value to the JWS Signature value MUST |
69 | | * be done in a constant-time manner to thwart timing attacks. |
70 | | * |
71 | | * Alternatively, the computed HMAC value can be base64url encoded and |
72 | | * compared to the received encoded JWS Signature value (also in a |
73 | | * constant-time manner), as this comparison produces the same result as |
74 | | * comparing the unencoded values. In either case, if the values match, |
75 | | * the HMAC has been validated. |
76 | | */ |
77 | | |
78 | | { /* required: HMAC using SHA-256 */ |
79 | | LWS_GENHASH_TYPE_UNKNOWN, |
80 | | LWS_GENHMAC_TYPE_SHA256, |
81 | | LWS_JOSE_ENCTYPE_NONE, |
82 | | LWS_JOSE_ENCTYPE_NONE, |
83 | | "HS256", NULL, 0, 0, 0 |
84 | | }, |
85 | | { /* optional: HMAC using SHA-384 */ |
86 | | LWS_GENHASH_TYPE_UNKNOWN, |
87 | | LWS_GENHMAC_TYPE_SHA384, |
88 | | LWS_JOSE_ENCTYPE_NONE, |
89 | | LWS_JOSE_ENCTYPE_NONE, |
90 | | "HS384", NULL, 0, 0, 0 |
91 | | }, |
92 | | { /* optional: HMAC using SHA-512 */ |
93 | | LWS_GENHASH_TYPE_UNKNOWN, |
94 | | LWS_GENHMAC_TYPE_SHA512, |
95 | | LWS_JOSE_ENCTYPE_NONE, |
96 | | LWS_JOSE_ENCTYPE_NONE, |
97 | | "HS512", NULL, 0, 0, 0 |
98 | | }, |
99 | | |
100 | | /* |
101 | | * Digital Signature with RSASSA-PKCS1-v1_5 |
102 | | * |
103 | | * This section defines the use of the RSASSA-PKCS1-v1_5 digital |
104 | | * signature algorithm as defined in Section 8.2 of RFC 3447 [RFC3447] |
105 | | * (commonly known as PKCS #1), using SHA-2 [SHS] hash functions. |
106 | | * |
107 | | * A key of size 2048 bits or larger MUST be used with these algorithms. |
108 | | * |
109 | | * The RSASSA-PKCS1-v1_5 SHA-256 digital signature is generated as |
110 | | * follows: generate a digital signature of the JWS Signing Input using |
111 | | * RSASSA-PKCS1-v1_5-SIGN and the SHA-256 hash function with the desired |
112 | | * private key. This is the JWS Signature value. |
113 | | * |
114 | | * The RSASSA-PKCS1-v1_5 SHA-256 digital signature for a JWS is |
115 | | * validated as follows: submit the JWS Signing Input, the JWS |
116 | | * Signature, and the public key corresponding to the private key used |
117 | | * by the signer to the RSASSA-PKCS1-v1_5-VERIFY algorithm using SHA-256 |
118 | | * as the hash function. |
119 | | */ |
120 | | |
121 | | { /* recommended: RSASSA-PKCS1-v1_5 using SHA-256 */ |
122 | | LWS_GENHASH_TYPE_SHA256, |
123 | | LWS_GENHMAC_TYPE_UNKNOWN, |
124 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5, |
125 | | LWS_JOSE_ENCTYPE_NONE, |
126 | | "RS256", NULL, 2048, 4096, 0 |
127 | | }, |
128 | | { /* optional: RSASSA-PKCS1-v1_5 using SHA-384 */ |
129 | | LWS_GENHASH_TYPE_SHA384, |
130 | | LWS_GENHMAC_TYPE_UNKNOWN, |
131 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5, |
132 | | LWS_JOSE_ENCTYPE_NONE, |
133 | | "RS384", NULL, 2048, 4096, 0 |
134 | | }, |
135 | | { /* optional: RSASSA-PKCS1-v1_5 using SHA-512 */ |
136 | | LWS_GENHASH_TYPE_SHA512, |
137 | | LWS_GENHMAC_TYPE_UNKNOWN, |
138 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5, |
139 | | LWS_JOSE_ENCTYPE_NONE, |
140 | | "RS512", NULL, 2048, 4096, 0 |
141 | | }, |
142 | | |
143 | | /* |
144 | | * Digital Signature with ECDSA |
145 | | * |
146 | | * The ECDSA P-256 SHA-256 digital signature is generated as follows: |
147 | | * |
148 | | * 1. Generate a digital signature of the JWS Signing Input using ECDSA |
149 | | * P-256 SHA-256 with the desired private key. The output will be |
150 | | * the pair (R, S), where R and S are 256-bit unsigned integers. |
151 | | * 2. Turn R and S into octet sequences in big-endian order, with each |
152 | | * array being be 32 octets long. The octet sequence |
153 | | * representations MUST NOT be shortened to omit any leading zero |
154 | | * octets contained in the values. |
155 | | * |
156 | | * 3. Concatenate the two octet sequences in the order R and then S. |
157 | | * (Note that many ECDSA implementations will directly produce this |
158 | | * concatenation as their output.) |
159 | | * |
160 | | * 4. The resulting 64-octet sequence is the JWS Signature value. |
161 | | * |
162 | | * The ECDSA P-256 SHA-256 digital signature for a JWS is validated as |
163 | | * follows: |
164 | | * |
165 | | * 1. The JWS Signature value MUST be a 64-octet sequence. If it is |
166 | | * not a 64-octet sequence, the validation has failed. |
167 | | * |
168 | | * 2. Split the 64-octet sequence into two 32-octet sequences. The |
169 | | * first octet sequence represents R and the second S. The values R |
170 | | * and S are represented as octet sequences using the Integer-to- |
171 | | * OctetString Conversion defined in Section 2.3.7 of SEC1 [SEC1] |
172 | | * (in big-endian octet order). |
173 | | * 3. Submit the JWS Signing Input, R, S, and the public key (x, y) to |
174 | | * the ECDSA P-256 SHA-256 validator. |
175 | | */ |
176 | | |
177 | | { /* Recommended+: ECDSA using P-256 and SHA-256 */ |
178 | | LWS_GENHASH_TYPE_SHA256, |
179 | | LWS_GENHMAC_TYPE_UNKNOWN, |
180 | | LWS_JOSE_ENCTYPE_ECDSA, |
181 | | LWS_JOSE_ENCTYPE_NONE, |
182 | | "ES256", "P-256", 256, 256, 0 |
183 | | }, |
184 | | { /* optional: ECDSA using P-384 and SHA-384 */ |
185 | | LWS_GENHASH_TYPE_SHA384, |
186 | | LWS_GENHMAC_TYPE_UNKNOWN, |
187 | | LWS_JOSE_ENCTYPE_ECDSA, |
188 | | LWS_JOSE_ENCTYPE_NONE, |
189 | | "ES384", "P-384", 384, 384, 0 |
190 | | }, |
191 | | { /* optional: ECDSA using P-521 and SHA-512 */ |
192 | | LWS_GENHASH_TYPE_SHA512, |
193 | | LWS_GENHMAC_TYPE_UNKNOWN, |
194 | | LWS_JOSE_ENCTYPE_ECDSA, |
195 | | LWS_JOSE_ENCTYPE_NONE, |
196 | | "ES512", "P-521", 521, 521, 0 |
197 | | }, |
198 | | { /* Recommended+: EdDSA using Ed25519 and Ed448 */ |
199 | | LWS_GENHASH_TYPE_UNKNOWN, |
200 | | LWS_GENHMAC_TYPE_UNKNOWN, |
201 | | LWS_JOSE_ENCTYPE_EDDSA, |
202 | | LWS_JOSE_ENCTYPE_NONE, |
203 | | "EdDSA", NULL, 0, 0, 0 |
204 | | }, |
205 | | #if 0 |
206 | | Not yet supported |
207 | | |
208 | | /* |
209 | | * Digital Signature with RSASSA-PSS |
210 | | * |
211 | | * A key of size 2048 bits or larger MUST be used with this algorithm. |
212 | | * |
213 | | * The RSASSA-PSS SHA-256 digital signature is generated as follows: |
214 | | * generate a digital signature of the JWS Signing Input using RSASSA- |
215 | | * PSS-SIGN, the SHA-256 hash function, and the MGF1 mask generation |
216 | | * function with SHA-256 with the desired private key. This is the JWS |
217 | | * Signature value. |
218 | | * |
219 | | * The RSASSA-PSS SHA-256 digital signature for a JWS is validated as |
220 | | * follows: submit the JWS Signing Input, the JWS Signature, and the |
221 | | * public key corresponding to the private key used by the signer to the |
222 | | * RSASSA-PSS-VERIFY algorithm using SHA-256 as the hash function and |
223 | | * using MGF1 as the mask generation function with SHA-256. |
224 | | * |
225 | | */ |
226 | | { /* optional: RSASSA-PSS using SHA-256 and MGF1 with SHA-256 */ |
227 | | LWS_GENHASH_TYPE_SHA256, |
228 | | LWS_GENHMAC_TYPE_UNKNOWN, |
229 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS, |
230 | | LWS_JOSE_ENCTYPE_NONE, |
231 | | "PS256", NULL, 2048, 4096, 0 |
232 | | }, |
233 | | { /* optional: RSASSA-PSS using SHA-384 and MGF1 with SHA-384 */ |
234 | | LWS_GENHASH_TYPE_SHA384, |
235 | | LWS_GENHMAC_TYPE_UNKNOWN, |
236 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS, |
237 | | LWS_JOSE_ENCTYPE_NONE, |
238 | | "PS384", NULL, 2048, 4096, 0 |
239 | | }, |
240 | | { /* optional: RSASSA-PSS using SHA-512 and MGF1 with SHA-512*/ |
241 | | LWS_GENHASH_TYPE_SHA512, |
242 | | LWS_GENHMAC_TYPE_UNKNOWN, |
243 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS, |
244 | | LWS_JOSE_ENCTYPE_NONE, |
245 | | "PS512", NULL, 2048, 4096, 0 |
246 | | }, |
247 | | #endif |
248 | | /* list terminator */ |
249 | | { 0, 0, 0, 0, NULL, NULL, 0, 0, 0} |
250 | | }; |
251 | | |
252 | | /* |
253 | | * These came from RFC7518 (JSON Web Algorithms) Section 4 |
254 | | * |
255 | | * Cryptographic Algorithms for Key Management |
256 | | * |
257 | | * JWE uses cryptographic algorithms to encrypt or determine the Content |
258 | | * Encryption Key (CEK). |
259 | | */ |
260 | | |
261 | | static const struct lws_jose_jwe_alg lws_gencrypto_jwe_alg_map[] = { |
262 | | |
263 | | /* |
264 | | * This section defines the specifics of encrypting a JWE CEK with |
265 | | * RSAES-PKCS1-v1_5 [RFC3447]. The "alg" (algorithm) Header Parameter |
266 | | * value "RSA1_5" is used for this algorithm. |
267 | | * |
268 | | * A key of size 2048 bits or larger MUST be used with this algorithm. |
269 | | */ |
270 | | |
271 | | |
272 | | { /* recommended+: RSAES OAEP using default parameters */ |
273 | | LWS_GENHASH_TYPE_SHA1, |
274 | | LWS_GENHMAC_TYPE_UNKNOWN, |
275 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_OAEP, |
276 | | LWS_JOSE_ENCTYPE_NONE, |
277 | | "RSA-OAEP", NULL, 2048, 4096, 0 |
278 | | }, |
279 | | { /* recommended+: RSAES OAEP using SHA-256 and MGF1 SHA-256 */ |
280 | | LWS_GENHASH_TYPE_SHA256, |
281 | | LWS_GENHMAC_TYPE_UNKNOWN, |
282 | | LWS_JOSE_ENCTYPE_RSASSA_PKCS1_OAEP, |
283 | | LWS_JOSE_ENCTYPE_NONE, |
284 | | "RSA-OAEP-256", NULL, 2048, 4096, 0 |
285 | | }, |
286 | | |
287 | | /* |
288 | | * Key Wrapping with AES Key Wrap |
289 | | * |
290 | | * This section defines the specifics of encrypting a JWE CEK with the |
291 | | * Advanced Encryption Standard (AES) Key Wrap Algorithm [RFC3394] using |
292 | | * the default initial value specified in Section 2.2.3.1 of that |
293 | | * document. |
294 | | * |
295 | | * |
296 | | */ |
297 | | { /* recommended: AES Key Wrap with AES Key Wrap with defaults |
298 | | using 128-bit key */ |
299 | | LWS_GENHASH_TYPE_UNKNOWN, |
300 | | LWS_GENHMAC_TYPE_UNKNOWN, |
301 | | LWS_JOSE_ENCTYPE_AES_ECB, |
302 | | LWS_JOSE_ENCTYPE_NONE, |
303 | | "A128KW", NULL, 128, 128, 64 |
304 | | }, |
305 | | |
306 | | { /* optional: AES Key Wrap with AES Key Wrap with defaults |
307 | | using 192-bit key */ |
308 | | LWS_GENHASH_TYPE_UNKNOWN, |
309 | | LWS_GENHMAC_TYPE_UNKNOWN, |
310 | | LWS_JOSE_ENCTYPE_AES_ECB, |
311 | | LWS_JOSE_ENCTYPE_NONE, |
312 | | "A192KW", NULL, 192, 192, 64 |
313 | | }, |
314 | | |
315 | | { /* recommended: AES Key Wrap with AES Key Wrap with defaults |
316 | | using 256-bit key */ |
317 | | LWS_GENHASH_TYPE_UNKNOWN, |
318 | | LWS_GENHMAC_TYPE_UNKNOWN, |
319 | | LWS_JOSE_ENCTYPE_AES_ECB, |
320 | | LWS_JOSE_ENCTYPE_NONE, |
321 | | "A256KW", NULL, 256, 256, 64 |
322 | | }, |
323 | | |
324 | | /* |
325 | | * This section defines the specifics of directly performing symmetric |
326 | | * key encryption without performing a key wrapping step. In this case, |
327 | | * the shared symmetric key is used directly as the Content Encryption |
328 | | * Key (CEK) value for the "enc" algorithm. An empty octet sequence is |
329 | | * used as the JWE Encrypted Key value. The "alg" (algorithm) Header |
330 | | * Parameter value "dir" is used in this case. |
331 | | */ |
332 | | { /* recommended */ |
333 | | LWS_GENHASH_TYPE_UNKNOWN, |
334 | | LWS_GENHMAC_TYPE_UNKNOWN, |
335 | | LWS_JOSE_ENCTYPE_NONE, |
336 | | LWS_JOSE_ENCTYPE_NONE, |
337 | | "dir", NULL, 0, 0, 0 |
338 | | }, |
339 | | |
340 | | /* |
341 | | * Key Agreement with Elliptic Curve Diffie-Hellman Ephemeral Static |
342 | | * (ECDH-ES) |
343 | | * |
344 | | * This section defines the specifics of key agreement with Elliptic |
345 | | * Curve Diffie-Hellman Ephemeral Static [RFC6090], in combination with |
346 | | * the Concat KDF, as defined in Section 5.8.1 of [NIST.800-56A]. The |
347 | | * key agreement result can be used in one of two ways: |
348 | | * |
349 | | * 1. directly as the Content Encryption Key (CEK) for the "enc" |
350 | | * algorithm, in the Direct Key Agreement mode, or |
351 | | * |
352 | | * 2. as a symmetric key used to wrap the CEK with the "A128KW", |
353 | | * "A192KW", or "A256KW" algorithms, in the Key Agreement with Key |
354 | | * Wrapping mode. |
355 | | * |
356 | | * A new ephemeral public key value MUST be generated for each key |
357 | | * agreement operation. |
358 | | * |
359 | | * In Direct Key Agreement mode, the output of the Concat KDF MUST be a |
360 | | * key of the same length as that used by the "enc" algorithm. In this |
361 | | * case, the empty octet sequence is used as the JWE Encrypted Key |
362 | | * value. The "alg" (algorithm) Header Parameter value "ECDH-ES" is |
363 | | * used in the Direct Key Agreement mode. |
364 | | * |
365 | | * In Key Agreement with Key Wrapping mode, the output of the Concat KDF |
366 | | * MUST be a key of the length needed for the specified key wrapping |
367 | | * algorithm. In this case, the JWE Encrypted Key is the CEK wrapped |
368 | | * with the agreed-upon key. |
369 | | */ |
370 | | |
371 | | { /* recommended+: ECDH Ephemeral Static Key agreement Concat KDF */ |
372 | | LWS_GENHASH_TYPE_SHA256, |
373 | | LWS_GENHMAC_TYPE_UNKNOWN, |
374 | | LWS_JOSE_ENCTYPE_ECDHES, |
375 | | LWS_JOSE_ENCTYPE_NONE, |
376 | | "ECDH-ES", NULL, 128, 128, 0 |
377 | | }, |
378 | | { /* recommended: ECDH-ES + Concat KDF + wrapped by AES128KW */ |
379 | | LWS_GENHASH_TYPE_SHA256, |
380 | | LWS_GENHMAC_TYPE_UNKNOWN, |
381 | | LWS_JOSE_ENCTYPE_ECDHES, |
382 | | LWS_JOSE_ENCTYPE_AES_ECB, |
383 | | "ECDH-ES+A128KW", NULL, 128, 128, 0 |
384 | | }, |
385 | | { /* optional: ECDH-ES + Concat KDF + wrapped by AES192KW */ |
386 | | LWS_GENHASH_TYPE_SHA256, |
387 | | LWS_GENHMAC_TYPE_UNKNOWN, |
388 | | LWS_JOSE_ENCTYPE_ECDHES, |
389 | | LWS_JOSE_ENCTYPE_AES_ECB, |
390 | | "ECDH-ES+A192KW", NULL, 192, 192, 0 |
391 | | }, |
392 | | { /* recommended: ECDH-ES + Concat KDF + wrapped by AES256KW */ |
393 | | LWS_GENHASH_TYPE_SHA256, |
394 | | LWS_GENHMAC_TYPE_UNKNOWN, |
395 | | LWS_JOSE_ENCTYPE_ECDHES, |
396 | | LWS_JOSE_ENCTYPE_AES_ECB, |
397 | | "ECDH-ES+A256KW", NULL, 256, 256, 0 |
398 | | }, |
399 | | |
400 | | /* |
401 | | * Key Encryption with AES GCM |
402 | | * |
403 | | * This section defines the specifics of encrypting a JWE Content |
404 | | * Encryption Key (CEK) with Advanced Encryption Standard (AES) in |
405 | | * Galois/Counter Mode (GCM) ([AES] and [NIST.800-38D]). |
406 | | * |
407 | | * Use of an Initialization Vector (IV) of size 96 bits is REQUIRED with |
408 | | * this algorithm. The IV is represented in base64url-encoded form as |
409 | | * the "iv" (initialization vector) Header Parameter value. |
410 | | * |
411 | | * The Additional Authenticated Data value used is the empty octet |
412 | | * string. |
413 | | * |
414 | | * The requested size of the Authentication Tag output MUST be 128 bits, |
415 | | * regardless of the key size. |
416 | | * |
417 | | * The JWE Encrypted Key value is the ciphertext output. |
418 | | * |
419 | | * The Authentication Tag output is represented in base64url-encoded |
420 | | * form as the "tag" (authentication tag) Header Parameter value. |
421 | | * |
422 | | * |
423 | | * "iv" (Initialization Vector) Header Parameter |
424 | | * |
425 | | * The "iv" (initialization vector) Header Parameter value is the |
426 | | * base64url-encoded representation of the 96-bit IV value used for the |
427 | | * key encryption operation. This Header Parameter MUST be present and |
428 | | * MUST be understood and processed by implementations when these |
429 | | * algorithms are used. |
430 | | * |
431 | | * "tag" (Authentication Tag) Header Parameter |
432 | | * |
433 | | * The "tag" (authentication tag) Header Parameter value is the |
434 | | * base64url-encoded representation of the 128-bit Authentication Tag |
435 | | * value resulting from the key encryption operation. This Header |
436 | | * Parameter MUST be present and MUST be understood and processed by |
437 | | * implementations when these algorithms are used. |
438 | | */ |
439 | | { /* optional: Key wrapping with AES GCM using 128-bit key */ |
440 | | LWS_GENHASH_TYPE_UNKNOWN, |
441 | | LWS_GENHMAC_TYPE_UNKNOWN, |
442 | | LWS_JOSE_ENCTYPE_AES_ECB, |
443 | | LWS_JOSE_ENCTYPE_NONE, |
444 | | "A128GCMKW", NULL, 128, 128, 96 |
445 | | }, |
446 | | |
447 | | { /* optional: Key wrapping with AES GCM using 192-bit key */ |
448 | | LWS_GENHASH_TYPE_UNKNOWN, |
449 | | LWS_GENHMAC_TYPE_UNKNOWN, |
450 | | LWS_JOSE_ENCTYPE_AES_ECB, |
451 | | LWS_JOSE_ENCTYPE_NONE, |
452 | | "A192GCMKW", NULL, 192, 192, 96 |
453 | | }, |
454 | | |
455 | | { /* optional: Key wrapping with AES GCM using 256-bit key */ |
456 | | LWS_GENHASH_TYPE_UNKNOWN, |
457 | | LWS_GENHMAC_TYPE_UNKNOWN, |
458 | | LWS_JOSE_ENCTYPE_AES_ECB, |
459 | | LWS_JOSE_ENCTYPE_NONE, |
460 | | "A256GCMKW", NULL, 256, 256, 96 |
461 | | }, |
462 | | |
463 | | /* list terminator */ |
464 | | { 0, 0, 0, 0, NULL, NULL, 0, 0, 0 } |
465 | | }; |
466 | | |
467 | | /* |
468 | | * The "enc" (encryption algorithm) Header Parameter identifies the |
469 | | * content encryption algorithm used to perform authenticated encryption |
470 | | * on the plaintext to produce the ciphertext and the Authentication |
471 | | * Tag. This algorithm MUST be an AEAD algorithm with a specified key |
472 | | * length. The encrypted content is not usable if the "enc" value does |
473 | | * not represent a supported algorithm. "enc" values should either be |
474 | | * registered in the IANA "JSON Web Signature and Encryption Algorithms" |
475 | | * registry established by [JWA] or be a value that contains a |
476 | | * Collision-Resistant Name. The "enc" value is a case-sensitive ASCII |
477 | | * string containing a StringOrURI value. This Header Parameter MUST be |
478 | | * present and MUST be understood and processed by implementations. |
479 | | */ |
480 | | |
481 | | static const struct lws_jose_jwe_alg lws_gencrypto_jwe_enc_map[] = { |
482 | | /* |
483 | | * AES_128_CBC_HMAC_SHA_256 / 512 |
484 | | * |
485 | | * It uses the HMAC message authentication code [RFC2104] with the |
486 | | * SHA-256 hash function [SHS] to provide message authentication, with |
487 | | * the HMAC output truncated to 128 bits, corresponding to the |
488 | | * HMAC-SHA-256-128 algorithm defined in [RFC4868]. For encryption, it |
489 | | * uses AES in the CBC mode of operation as defined in Section 6.2 of |
490 | | * [NIST.800-38A], with PKCS #7 padding and a 128-bit IV value. |
491 | | * |
492 | | * The AES_CBC_HMAC_SHA2 parameters specific to AES_128_CBC_HMAC_SHA_256 |
493 | | * are: |
494 | | * |
495 | | * The input key K is 32 octets long. |
496 | | * ENC_KEY_LEN is 16 octets. |
497 | | * MAC_KEY_LEN is 16 octets. |
498 | | * The SHA-256 hash algorithm is used for the HMAC. |
499 | | * The HMAC-SHA-256 output is truncated to T_LEN=16 octets, by |
500 | | * stripping off the final 16 octets. |
501 | | */ |
502 | | { /* required */ |
503 | | LWS_GENHASH_TYPE_UNKNOWN, |
504 | | LWS_GENHMAC_TYPE_SHA256, |
505 | | LWS_JOSE_ENCTYPE_NONE, |
506 | | LWS_JOSE_ENCTYPE_AES_CBC, |
507 | | "A128CBC-HS256", NULL, 256, 256, 128 |
508 | | }, |
509 | | /* |
510 | | * AES_192_CBC_HMAC_SHA_384 is based on AES_128_CBC_HMAC_SHA_256, but |
511 | | * with the following differences: |
512 | | * |
513 | | * The input key K is 48 octets long instead of 32. |
514 | | * ENC_KEY_LEN is 24 octets instead of 16. |
515 | | * MAC_KEY_LEN is 24 octets instead of 16. |
516 | | * SHA-384 is used for the HMAC instead of SHA-256. |
517 | | * The HMAC SHA-384 value is truncated to T_LEN=24 octets instead of 16. |
518 | | */ |
519 | | { /* required */ |
520 | | LWS_GENHASH_TYPE_UNKNOWN, |
521 | | LWS_GENHMAC_TYPE_SHA384, |
522 | | LWS_JOSE_ENCTYPE_NONE, |
523 | | LWS_JOSE_ENCTYPE_AES_CBC, |
524 | | "A192CBC-HS384", NULL, 384, 384, 192 |
525 | | }, |
526 | | /* |
527 | | * AES_256_CBC_HMAC_SHA_512 is based on AES_128_CBC_HMAC_SHA_256, but |
528 | | * with the following differences: |
529 | | * |
530 | | * The input key K is 64 octets long instead of 32. |
531 | | * ENC_KEY_LEN is 32 octets instead of 16. |
532 | | * MAC_KEY_LEN is 32 octets instead of 16. |
533 | | * SHA-512 is used for the HMAC instead of SHA-256. |
534 | | * The HMAC SHA-512 value is truncated to T_LEN=32 octets instead of 16. |
535 | | */ |
536 | | { /* required */ |
537 | | LWS_GENHASH_TYPE_UNKNOWN, |
538 | | LWS_GENHMAC_TYPE_SHA512, |
539 | | LWS_JOSE_ENCTYPE_NONE, |
540 | | LWS_JOSE_ENCTYPE_AES_CBC, |
541 | | "A256CBC-HS512", NULL, 512, 512, 256 |
542 | | }, |
543 | | |
544 | | /* |
545 | | * The CEK is used as the encryption key. |
546 | | * |
547 | | * Use of an IV of size 96 bits is REQUIRED with this algorithm. |
548 | | * |
549 | | * The requested size of the Authentication Tag output MUST be 128 bits, |
550 | | * regardless of the key size. |
551 | | */ |
552 | | { /* recommended: AES GCM using 128-bit key */ |
553 | | LWS_GENHASH_TYPE_UNKNOWN, |
554 | | LWS_GENHMAC_TYPE_UNKNOWN, |
555 | | LWS_JOSE_ENCTYPE_NONE, |
556 | | LWS_JOSE_ENCTYPE_AES_GCM, |
557 | | "A128GCM", NULL, 128, 128, 96 |
558 | | }, |
559 | | { /* optional: AES GCM using 192-bit key */ |
560 | | LWS_GENHASH_TYPE_UNKNOWN, |
561 | | LWS_GENHMAC_TYPE_UNKNOWN, |
562 | | LWS_JOSE_ENCTYPE_NONE, |
563 | | LWS_JOSE_ENCTYPE_AES_GCM, |
564 | | "A192GCM", NULL, 192, 192, 96 |
565 | | }, |
566 | | { /* recommended: AES GCM using 256-bit key */ |
567 | | LWS_GENHASH_TYPE_UNKNOWN, |
568 | | LWS_GENHMAC_TYPE_UNKNOWN, |
569 | | LWS_JOSE_ENCTYPE_NONE, |
570 | | LWS_JOSE_ENCTYPE_AES_GCM, |
571 | | "A256GCM", NULL, 256, 256, 96 |
572 | | }, |
573 | | { 0, 0, 0, 0, NULL, NULL, 0, 0, 0 } /* sentinel */ |
574 | | }; |
575 | | |
576 | | int |
577 | | lws_gencrypto_jws_alg_to_definition(const char *alg, |
578 | | const struct lws_jose_jwe_alg **jose) |
579 | 0 | { |
580 | 0 | const struct lws_jose_jwe_alg *a = lws_gencrypto_jws_alg_map; |
581 | |
|
582 | 0 | while (a->alg) { |
583 | 0 | if (!strcmp(alg, a->alg)) { |
584 | 0 | *jose = a; |
585 | |
|
586 | 0 | return 0; |
587 | 0 | } |
588 | 0 | a++; |
589 | 0 | } |
590 | | |
591 | 0 | return 1; |
592 | 0 | } |
593 | | |
594 | | int |
595 | | lws_gencrypto_jwe_alg_to_definition(const char *alg, |
596 | | const struct lws_jose_jwe_alg **jose) |
597 | 0 | { |
598 | 0 | const struct lws_jose_jwe_alg *a = lws_gencrypto_jwe_alg_map; |
599 | |
|
600 | 0 | while (a->alg) { |
601 | 0 | if (!strcmp(alg, a->alg)) { |
602 | 0 | *jose = a; |
603 | |
|
604 | 0 | return 0; |
605 | 0 | } |
606 | 0 | a++; |
607 | 0 | } |
608 | | |
609 | 0 | return 1; |
610 | 0 | } |
611 | | |
612 | | int |
613 | | lws_gencrypto_jwe_enc_to_definition(const char *enc, |
614 | | const struct lws_jose_jwe_alg **jose) |
615 | 0 | { |
616 | 0 | const struct lws_jose_jwe_alg *e = lws_gencrypto_jwe_enc_map; |
617 | |
|
618 | 0 | while (e->alg) { |
619 | 0 | if (!strcmp(enc, e->alg)) { |
620 | 0 | *jose = e; |
621 | |
|
622 | 0 | return 0; |
623 | 0 | } |
624 | 0 | e++; |
625 | 0 | } |
626 | | |
627 | 0 | return 1; |
628 | 0 | } |
629 | | |
630 | | size_t |
631 | | lws_genhash_size(enum lws_genhash_types type) |
632 | 0 | { |
633 | 0 | switch(type) { |
634 | 0 | case LWS_GENHASH_TYPE_UNKNOWN: |
635 | 0 | return 0; |
636 | 0 | case LWS_GENHASH_TYPE_MD5: |
637 | 0 | return 16; |
638 | 0 | case LWS_GENHASH_TYPE_SHA1: |
639 | 0 | return 20; |
640 | 0 | case LWS_GENHASH_TYPE_SHA256: |
641 | 0 | return 32; |
642 | 0 | case LWS_GENHASH_TYPE_SHA384: |
643 | 0 | return 48; |
644 | 0 | case LWS_GENHASH_TYPE_SHA512: |
645 | 0 | return 64; |
646 | 0 | } |
647 | | |
648 | 0 | return 0; |
649 | 0 | } |
650 | | |
651 | | size_t |
652 | | lws_genhmac_size(enum lws_genhmac_types type) |
653 | 0 | { |
654 | 0 | switch(type) { |
655 | 0 | case LWS_GENHMAC_TYPE_UNKNOWN: |
656 | 0 | return 0; |
657 | 0 | case LWS_GENHMAC_TYPE_SHA1: |
658 | 0 | return 20; |
659 | 0 | case LWS_GENHMAC_TYPE_SHA256: |
660 | 0 | return 32; |
661 | 0 | case LWS_GENHMAC_TYPE_SHA384: |
662 | 0 | return 48; |
663 | 0 | case LWS_GENHMAC_TYPE_SHA512: |
664 | 0 | return 64; |
665 | 0 | } |
666 | | |
667 | 0 | return 0; |
668 | 0 | } |
669 | | |
670 | | int |
671 | | lws_gencrypto_bits_to_bytes(int bits) |
672 | 0 | { |
673 | 0 | if (bits & 7) |
674 | 0 | return (bits / 8) + 1; |
675 | | |
676 | 0 | return bits / 8; |
677 | 0 | } |
678 | | |
679 | | int |
680 | | lws_base64_size(int bytes) |
681 | 0 | { |
682 | 0 | return ((bytes * 4) / 3) + 6; |
683 | 0 | } |
684 | | |
685 | | void |
686 | | lws_gencrypto_destroy_elements(struct lws_gencrypto_keyelem *el, int m) |
687 | 0 | { |
688 | 0 | int n; |
689 | |
|
690 | 0 | for (n = 0; n < m; n++) |
691 | 0 | if (el[n].buf) |
692 | 0 | lws_free_set_NULL(el[n].buf); |
693 | 0 | } |
694 | | |
695 | | void |
696 | | lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el) |
697 | 0 | { |
698 | 0 | lws_gencrypto_destroy_elements(el, LWS_GENCRYPTO_RSA_KEYEL_COUNT); |
699 | 0 | } |
700 | | |
701 | | size_t lws_gencrypto_padded_length(size_t pad_block_size, size_t len) |
702 | 0 | { |
703 | 0 | return (len / pad_block_size + 1) * pad_block_size; |
704 | 0 | } |
705 | | |
706 | | int |
707 | | lws_genhash_render(enum lws_genhash_types type, const uint8_t *hash, char *out, size_t out_len) |
708 | 0 | { |
709 | 0 | size_t hs = lws_genhash_size(type); |
710 | 0 | size_t i; |
711 | |
|
712 | 0 | if (!hs) { |
713 | 0 | if (out_len) |
714 | 0 | out[0] = '\0'; |
715 | 0 | return -1; |
716 | 0 | } |
717 | | |
718 | 0 | if (out_len < (hs * 2) + 1) { |
719 | | /* Needs truncation with ellipsis? */ |
720 | 0 | if (out_len > 4) { |
721 | 0 | for (i = 0; i < (out_len - 4) / 2; i++) |
722 | 0 | lws_snprintf(out + (i * 2), 3, "%02x", hash[i]); |
723 | 0 | lws_strncpy(out + (i * 2), "...", out_len - (i * 2)); |
724 | 0 | return 0; |
725 | 0 | } |
726 | 0 | if (out_len) |
727 | 0 | out[0] = '\0'; |
728 | 0 | return -1; |
729 | 0 | } |
730 | | |
731 | 0 | for (i = 0; i < hs; i++) |
732 | 0 | lws_snprintf(out + (i * 2), 3, "%02x", hash[i]); |
733 | |
|
734 | 0 | out[i * 2] = '\0'; |
735 | |
|
736 | 0 | return 0; |
737 | 0 | } |
738 | | |
739 | | int |
740 | | lws_genhash_render_prefixed(enum lws_genhash_types type, const uint8_t *hash, char *out, size_t out_len) |
741 | 0 | { |
742 | 0 | const char *t; |
743 | 0 | int n; |
744 | |
|
745 | 0 | switch (type) { |
746 | 0 | case LWS_GENHASH_TYPE_MD5: t = "MD5"; break; |
747 | 0 | case LWS_GENHASH_TYPE_SHA1: t = "SHA1"; break; |
748 | 0 | case LWS_GENHASH_TYPE_SHA256: t = "SHA256"; break; |
749 | 0 | case LWS_GENHASH_TYPE_SHA384: t = "SHA384"; break; |
750 | 0 | case LWS_GENHASH_TYPE_SHA512: t = "SHA512"; break; |
751 | 0 | default: return -1; |
752 | 0 | } |
753 | | |
754 | 0 | n = lws_snprintf(out, out_len, "%s:", t); |
755 | 0 | if (n < 0 || (size_t)n >= out_len) |
756 | 0 | return -1; |
757 | | |
758 | 0 | return lws_genhash_render(type, hash, out + n, out_len - (size_t)n); |
759 | 0 | } |
760 | | |
761 | | int |
762 | | lws_genhkdf_extract(enum lws_genhmac_types type, const uint8_t *salt, |
763 | | size_t salt_len, const uint8_t *ikm, size_t ikm_len, |
764 | | uint8_t *prk) |
765 | 0 | { |
766 | 0 | struct lws_genhmac_ctx ctx; |
767 | 0 | int ret = -1; |
768 | 0 | size_t hs; |
769 | 0 | uint8_t z[LWS_GENHASH_LARGEST]; |
770 | |
|
771 | 0 | hs = lws_genhmac_size(type); |
772 | 0 | if (!hs) |
773 | 0 | return -1; |
774 | | |
775 | 0 | if (!salt || !salt_len) { |
776 | 0 | memset(z, 0, hs); |
777 | 0 | salt = z; |
778 | 0 | salt_len = hs; |
779 | 0 | } |
780 | |
|
781 | 0 | if (lws_genhmac_init(&ctx, type, salt, salt_len)) |
782 | 0 | return -1; |
783 | | |
784 | 0 | if (ikm_len && lws_genhmac_update(&ctx, ikm, ikm_len)) |
785 | 0 | goto bail; |
786 | | |
787 | 0 | if (lws_genhmac_destroy(&ctx, prk)) |
788 | 0 | return -1; |
789 | | |
790 | 0 | return 0; |
791 | | |
792 | 0 | bail: |
793 | 0 | lws_genhmac_destroy(&ctx, NULL); |
794 | 0 | return ret; |
795 | 0 | } |
796 | | |
797 | | int |
798 | | lws_genhkdf_expand(enum lws_genhmac_types type, const uint8_t *prk, |
799 | | size_t prk_len, const uint8_t *info, size_t info_len, |
800 | | uint8_t *okm, size_t okm_len) |
801 | 0 | { |
802 | 0 | struct lws_genhmac_ctx ctx; |
803 | 0 | uint8_t t[LWS_GENHASH_LARGEST]; |
804 | 0 | size_t hs = lws_genhmac_size(type); |
805 | 0 | size_t t_len = 0, remain = okm_len, copy_len; |
806 | 0 | uint8_t count = 1; |
807 | 0 | int ret = -1; |
808 | |
|
809 | 0 | if (!hs || !okm_len || !prk || !okm) |
810 | 0 | return -1; |
811 | | |
812 | 0 | while (remain) { |
813 | 0 | if (lws_genhmac_init(&ctx, type, prk, prk_len)) |
814 | 0 | return -1; |
815 | | |
816 | 0 | if (t_len && lws_genhmac_update(&ctx, t, t_len)) |
817 | 0 | goto bail; |
818 | | |
819 | 0 | if (info && info_len && lws_genhmac_update(&ctx, info, info_len)) |
820 | 0 | goto bail; |
821 | | |
822 | 0 | if (lws_genhmac_update(&ctx, &count, 1)) |
823 | 0 | goto bail; |
824 | | |
825 | 0 | if (lws_genhmac_destroy(&ctx, t)) |
826 | 0 | return -1; |
827 | | |
828 | 0 | t_len = hs; |
829 | 0 | copy_len = remain > hs ? hs : remain; |
830 | 0 | memcpy(okm, t, copy_len); |
831 | 0 | okm += copy_len; |
832 | 0 | remain -= copy_len; |
833 | 0 | count++; |
834 | 0 | } |
835 | | |
836 | 0 | return 0; |
837 | | |
838 | 0 | bail: |
839 | 0 | lws_genhmac_destroy(&ctx, NULL); |
840 | 0 | return ret; |
841 | 0 | } |
842 | | |
843 | | int |
844 | | lws_genhkdf_expand_label(enum lws_genhmac_types type, const uint8_t *prk, |
845 | | size_t prk_len, const char *label, |
846 | | const uint8_t *context, size_t context_len, |
847 | | uint8_t *okm, size_t okm_len) |
848 | 0 | { |
849 | 0 | uint8_t info[256 + 256 + 4]; |
850 | 0 | size_t info_len = 0; |
851 | 0 | size_t label_len; |
852 | |
|
853 | 0 | if (!label) |
854 | 0 | return -1; |
855 | | |
856 | 0 | label_len = strlen(label); |
857 | | /* "tls13 " length is 6, so label_len + 6 must be <= 255 */ |
858 | 0 | if (label_len + 6 > 255 || context_len > 255) |
859 | 0 | return -1; |
860 | | |
861 | | /* Length (uint16) */ |
862 | 0 | info[info_len++] = (okm_len >> 8) & 0xff; |
863 | 0 | info[info_len++] = okm_len & 0xff; |
864 | | |
865 | | /* Label length (uint8) */ |
866 | 0 | info[info_len++] = (uint8_t)(label_len + 6); |
867 | 0 | memcpy(&info[info_len], "tls13 ", 6); |
868 | 0 | info_len += 6; |
869 | 0 | memcpy(&info[info_len], label, label_len); |
870 | 0 | info_len += label_len; |
871 | | |
872 | | /* Context length (uint8) */ |
873 | 0 | info[info_len++] = (uint8_t)context_len; |
874 | 0 | if (context_len && context) { |
875 | 0 | memcpy(&info[info_len], context, context_len); |
876 | 0 | info_len += context_len; |
877 | 0 | } |
878 | |
|
879 | 0 | return lws_genhkdf_expand(type, prk, prk_len, info, info_len, okm, okm_len); |
880 | 0 | } |