Coverage Report

Created: 2026-09-04 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}