| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695 |
- /*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
- #include "private-lib-core.h"
- /*
- * These came from RFC7518 (JSON Web Algorithms) Section 3
- *
- * Cryptographic Algorithms for Digital Signatures and MACs
- */
- static const struct lws_jose_jwe_alg lws_gencrypto_jws_alg_map[] = {
- /*
- * JWSs MAY also be created that do not provide integrity protection.
- * Such a JWS is called an Unsecured JWS. An Unsecured JWS uses the
- * "alg" value "none" and is formatted identically to other JWSs, but
- * MUST use the empty octet sequence as its JWS Signature value.
- * Recipients MUST verify that the JWS Signature value is the empty
- * octet sequence.
- *
- * Implementations that support Unsecured JWSs MUST NOT accept such
- * objects as valid unless the application specifies that it is
- * acceptable for a specific object to not be integrity protected.
- * Implementations MUST NOT accept Unsecured JWSs by default. In order
- * to mitigate downgrade attacks, applications MUST NOT signal
- * acceptance of Unsecured JWSs at a global level, and SHOULD signal
- * acceptance on a per-object basis. See Section 8.5 for security
- * considerations associated with using this algorithm.
- */
- { /* optional */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_NONE,
- "none", NULL, 0, 0, 0
- },
- /*
- * HMAC with SHA-2 Functions
- *
- * The HMAC SHA-256 MAC for a JWS is validated by computing an HMAC
- * value per RFC 2104, using SHA-256 as the hash algorithm "H", using
- * the received JWS Signing Input as the "text" value, and using the
- * shared key. This computed HMAC value is then compared to the result
- * of base64url decoding the received encoded JWS Signature value. The
- * comparison of the computed HMAC value to the JWS Signature value MUST
- * be done in a constant-time manner to thwart timing attacks.
- *
- * Alternatively, the computed HMAC value can be base64url encoded and
- * compared to the received encoded JWS Signature value (also in a
- * constant-time manner), as this comparison produces the same result as
- * comparing the unencoded values. In either case, if the values match,
- * the HMAC has been validated.
- */
- { /* required: HMAC using SHA-256 */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_SHA256,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_NONE,
- "HS256", NULL, 0, 0, 0
- },
- { /* optional: HMAC using SHA-384 */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_SHA384,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_NONE,
- "HS384", NULL, 0, 0, 0
- },
- { /* optional: HMAC using SHA-512 */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_SHA512,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_NONE,
- "HS512", NULL, 0, 0, 0
- },
- /*
- * Digital Signature with RSASSA-PKCS1-v1_5
- *
- * This section defines the use of the RSASSA-PKCS1-v1_5 digital
- * signature algorithm as defined in Section 8.2 of RFC 3447 [RFC3447]
- * (commonly known as PKCS #1), using SHA-2 [SHS] hash functions.
- *
- * A key of size 2048 bits or larger MUST be used with these algorithms.
- *
- * The RSASSA-PKCS1-v1_5 SHA-256 digital signature is generated as
- * follows: generate a digital signature of the JWS Signing Input using
- * RSASSA-PKCS1-v1_5-SIGN and the SHA-256 hash function with the desired
- * private key. This is the JWS Signature value.
- *
- * The RSASSA-PKCS1-v1_5 SHA-256 digital signature for a JWS is
- * validated as follows: submit the JWS Signing Input, the JWS
- * Signature, and the public key corresponding to the private key used
- * by the signer to the RSASSA-PKCS1-v1_5-VERIFY algorithm using SHA-256
- * as the hash function.
- */
- { /* recommended: RSASSA-PKCS1-v1_5 using SHA-256 */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5,
- LWS_JOSE_ENCTYPE_NONE,
- "RS256", NULL, 2048, 4096, 0
- },
- { /* optional: RSASSA-PKCS1-v1_5 using SHA-384 */
- LWS_GENHASH_TYPE_SHA384,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5,
- LWS_JOSE_ENCTYPE_NONE,
- "RS384", NULL, 2048, 4096, 0
- },
- { /* optional: RSASSA-PKCS1-v1_5 using SHA-512 */
- LWS_GENHASH_TYPE_SHA512,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5,
- LWS_JOSE_ENCTYPE_NONE,
- "RS512", NULL, 2048, 4096, 0
- },
- /*
- * Digital Signature with ECDSA
- *
- * The ECDSA P-256 SHA-256 digital signature is generated as follows:
- *
- * 1. Generate a digital signature of the JWS Signing Input using ECDSA
- * P-256 SHA-256 with the desired private key. The output will be
- * the pair (R, S), where R and S are 256-bit unsigned integers.
- * 2. Turn R and S into octet sequences in big-endian order, with each
- * array being be 32 octets long. The octet sequence
- * representations MUST NOT be shortened to omit any leading zero
- * octets contained in the values.
- *
- * 3. Concatenate the two octet sequences in the order R and then S.
- * (Note that many ECDSA implementations will directly produce this
- * concatenation as their output.)
- *
- * 4. The resulting 64-octet sequence is the JWS Signature value.
- *
- * The ECDSA P-256 SHA-256 digital signature for a JWS is validated as
- * follows:
- *
- * 1. The JWS Signature value MUST be a 64-octet sequence. If it is
- * not a 64-octet sequence, the validation has failed.
- *
- * 2. Split the 64-octet sequence into two 32-octet sequences. The
- * first octet sequence represents R and the second S. The values R
- * and S are represented as octet sequences using the Integer-to-
- * OctetString Conversion defined in Section 2.3.7 of SEC1 [SEC1]
- * (in big-endian octet order).
- * 3. Submit the JWS Signing Input, R, S, and the public key (x, y) to
- * the ECDSA P-256 SHA-256 validator.
- */
- { /* Recommended+: ECDSA using P-256 and SHA-256 */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_ECDSA,
- LWS_JOSE_ENCTYPE_NONE,
- "ES256", "P-256", 256, 256, 0
- },
- { /* optional: ECDSA using P-384 and SHA-384 */
- LWS_GENHASH_TYPE_SHA384,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_ECDSA,
- LWS_JOSE_ENCTYPE_NONE,
- "ES384", "P-384", 384, 384, 0
- },
- { /* optional: ECDSA using P-521 and SHA-512 */
- LWS_GENHASH_TYPE_SHA512,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_ECDSA,
- LWS_JOSE_ENCTYPE_NONE,
- "ES512", "P-521", 521, 521, 0
- },
- #if 0
- Not yet supported
- /*
- * Digital Signature with RSASSA-PSS
- *
- * A key of size 2048 bits or larger MUST be used with this algorithm.
- *
- * The RSASSA-PSS SHA-256 digital signature is generated as follows:
- * generate a digital signature of the JWS Signing Input using RSASSA-
- * PSS-SIGN, the SHA-256 hash function, and the MGF1 mask generation
- * function with SHA-256 with the desired private key. This is the JWS
- * Signature value.
- *
- * The RSASSA-PSS SHA-256 digital signature for a JWS is validated as
- * follows: submit the JWS Signing Input, the JWS Signature, and the
- * public key corresponding to the private key used by the signer to the
- * RSASSA-PSS-VERIFY algorithm using SHA-256 as the hash function and
- * using MGF1 as the mask generation function with SHA-256.
- *
- */
- { /* optional: RSASSA-PSS using SHA-256 and MGF1 with SHA-256 */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS,
- LWS_JOSE_ENCTYPE_NONE,
- "PS256", NULL, 2048, 4096, 0
- },
- { /* optional: RSASSA-PSS using SHA-384 and MGF1 with SHA-384 */
- LWS_GENHASH_TYPE_SHA384,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS,
- LWS_JOSE_ENCTYPE_NONE,
- "PS384", NULL, 2048, 4096, 0
- },
- { /* optional: RSASSA-PSS using SHA-512 and MGF1 with SHA-512*/
- LWS_GENHASH_TYPE_SHA512,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS,
- LWS_JOSE_ENCTYPE_NONE,
- "PS512", NULL, 2048, 4096, 0
- },
- #endif
- /* list terminator */
- { 0, 0, 0, 0, NULL, NULL, 0, 0, 0}
- };
- /*
- * These came from RFC7518 (JSON Web Algorithms) Section 4
- *
- * Cryptographic Algorithms for Key Management
- *
- * JWE uses cryptographic algorithms to encrypt or determine the Content
- * Encryption Key (CEK).
- */
- static const struct lws_jose_jwe_alg lws_gencrypto_jwe_alg_map[] = {
- /*
- * This section defines the specifics of encrypting a JWE CEK with
- * RSAES-PKCS1-v1_5 [RFC3447]. The "alg" (algorithm) Header Parameter
- * value "RSA1_5" is used for this algorithm.
- *
- * A key of size 2048 bits or larger MUST be used with this algorithm.
- */
- { /* recommended-: RSAES-PKCS1-v1_5 */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5,
- LWS_JOSE_ENCTYPE_NONE,
- "RSA1_5", NULL, 2048, 4096, 0
- },
- { /* recommended+: RSAES OAEP using default parameters */
- LWS_GENHASH_TYPE_SHA1,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_OAEP,
- LWS_JOSE_ENCTYPE_NONE,
- "RSA-OAEP", NULL, 2048, 4096, 0
- },
- { /* recommended+: RSAES OAEP using SHA-256 and MGF1 SHA-256 */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_RSASSA_PKCS1_OAEP,
- LWS_JOSE_ENCTYPE_NONE,
- "RSA-OAEP-256", NULL, 2048, 4096, 0
- },
- /*
- * Key Wrapping with AES Key Wrap
- *
- * This section defines the specifics of encrypting a JWE CEK with the
- * Advanced Encryption Standard (AES) Key Wrap Algorithm [RFC3394] using
- * the default initial value specified in Section 2.2.3.1 of that
- * document.
- *
- *
- */
- { /* recommended: AES Key Wrap with AES Key Wrap with defaults
- using 128-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_AES_ECB,
- LWS_JOSE_ENCTYPE_NONE,
- "A128KW", NULL, 128, 128, 64
- },
- { /* optional: AES Key Wrap with AES Key Wrap with defaults
- using 192-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_AES_ECB,
- LWS_JOSE_ENCTYPE_NONE,
- "A192KW", NULL, 192, 192, 64
- },
- { /* recommended: AES Key Wrap with AES Key Wrap with defaults
- using 256-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_AES_ECB,
- LWS_JOSE_ENCTYPE_NONE,
- "A256KW", NULL, 256, 256, 64
- },
- /*
- * This section defines the specifics of directly performing symmetric
- * key encryption without performing a key wrapping step. In this case,
- * the shared symmetric key is used directly as the Content Encryption
- * Key (CEK) value for the "enc" algorithm. An empty octet sequence is
- * used as the JWE Encrypted Key value. The "alg" (algorithm) Header
- * Parameter value "dir" is used in this case.
- */
- { /* recommended */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_NONE,
- "dir", NULL, 0, 0, 0
- },
- /*
- * Key Agreement with Elliptic Curve Diffie-Hellman Ephemeral Static
- * (ECDH-ES)
- *
- * This section defines the specifics of key agreement with Elliptic
- * Curve Diffie-Hellman Ephemeral Static [RFC6090], in combination with
- * the Concat KDF, as defined in Section 5.8.1 of [NIST.800-56A]. The
- * key agreement result can be used in one of two ways:
- *
- * 1. directly as the Content Encryption Key (CEK) for the "enc"
- * algorithm, in the Direct Key Agreement mode, or
- *
- * 2. as a symmetric key used to wrap the CEK with the "A128KW",
- * "A192KW", or "A256KW" algorithms, in the Key Agreement with Key
- * Wrapping mode.
- *
- * A new ephemeral public key value MUST be generated for each key
- * agreement operation.
- *
- * In Direct Key Agreement mode, the output of the Concat KDF MUST be a
- * key of the same length as that used by the "enc" algorithm. In this
- * case, the empty octet sequence is used as the JWE Encrypted Key
- * value. The "alg" (algorithm) Header Parameter value "ECDH-ES" is
- * used in the Direct Key Agreement mode.
- *
- * In Key Agreement with Key Wrapping mode, the output of the Concat KDF
- * MUST be a key of the length needed for the specified key wrapping
- * algorithm. In this case, the JWE Encrypted Key is the CEK wrapped
- * with the agreed-upon key.
- */
- { /* recommended+: ECDH Ephemeral Static Key agreement Concat KDF */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_ECDHES,
- LWS_JOSE_ENCTYPE_NONE,
- "ECDH-ES", NULL, 128, 128, 0
- },
- { /* recommended: ECDH-ES + Concat KDF + wrapped by AES128KW */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_ECDHES,
- LWS_JOSE_ENCTYPE_AES_ECB,
- "ECDH-ES+A128KW", NULL, 128, 128, 0
- },
- { /* optional: ECDH-ES + Concat KDF + wrapped by AES192KW */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_ECDHES,
- LWS_JOSE_ENCTYPE_AES_ECB,
- "ECDH-ES+A192KW", NULL, 192, 192, 0
- },
- { /* recommended: ECDH-ES + Concat KDF + wrapped by AES256KW */
- LWS_GENHASH_TYPE_SHA256,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_ECDHES,
- LWS_JOSE_ENCTYPE_AES_ECB,
- "ECDH-ES+A256KW", NULL, 256, 256, 0
- },
- /*
- * Key Encryption with AES GCM
- *
- * This section defines the specifics of encrypting a JWE Content
- * Encryption Key (CEK) with Advanced Encryption Standard (AES) in
- * Galois/Counter Mode (GCM) ([AES] and [NIST.800-38D]).
- *
- * Use of an Initialization Vector (IV) of size 96 bits is REQUIRED with
- * this algorithm. The IV is represented in base64url-encoded form as
- * the "iv" (initialization vector) Header Parameter value.
- *
- * The Additional Authenticated Data value used is the empty octet
- * string.
- *
- * The requested size of the Authentication Tag output MUST be 128 bits,
- * regardless of the key size.
- *
- * The JWE Encrypted Key value is the ciphertext output.
- *
- * The Authentication Tag output is represented in base64url-encoded
- * form as the "tag" (authentication tag) Header Parameter value.
- *
- *
- * "iv" (Initialization Vector) Header Parameter
- *
- * The "iv" (initialization vector) Header Parameter value is the
- * base64url-encoded representation of the 96-bit IV value used for the
- * key encryption operation. This Header Parameter MUST be present and
- * MUST be understood and processed by implementations when these
- * algorithms are used.
- *
- * "tag" (Authentication Tag) Header Parameter
- *
- * The "tag" (authentication tag) Header Parameter value is the
- * base64url-encoded representation of the 128-bit Authentication Tag
- * value resulting from the key encryption operation. This Header
- * Parameter MUST be present and MUST be understood and processed by
- * implementations when these algorithms are used.
- */
- { /* optional: Key wrapping with AES GCM using 128-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_AES_ECB,
- LWS_JOSE_ENCTYPE_NONE,
- "A128GCMKW", NULL, 128, 128, 96
- },
- { /* optional: Key wrapping with AES GCM using 192-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_AES_ECB,
- LWS_JOSE_ENCTYPE_NONE,
- "A192GCMKW", NULL, 192, 192, 96
- },
- { /* optional: Key wrapping with AES GCM using 256-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_AES_ECB,
- LWS_JOSE_ENCTYPE_NONE,
- "A256GCMKW", NULL, 256, 256, 96
- },
- /* list terminator */
- { 0, 0, 0, 0, NULL, NULL }
- };
- /*
- * The "enc" (encryption algorithm) Header Parameter identifies the
- * content encryption algorithm used to perform authenticated encryption
- * on the plaintext to produce the ciphertext and the Authentication
- * Tag. This algorithm MUST be an AEAD algorithm with a specified key
- * length. The encrypted content is not usable if the "enc" value does
- * not represent a supported algorithm. "enc" values should either be
- * registered in the IANA "JSON Web Signature and Encryption Algorithms"
- * registry established by [JWA] or be a value that contains a
- * Collision-Resistant Name. The "enc" value is a case-sensitive ASCII
- * string containing a StringOrURI value. This Header Parameter MUST be
- * present and MUST be understood and processed by implementations.
- */
- static const struct lws_jose_jwe_alg lws_gencrypto_jwe_enc_map[] = {
- /*
- * AES_128_CBC_HMAC_SHA_256 / 512
- *
- * It uses the HMAC message authentication code [RFC2104] with the
- * SHA-256 hash function [SHS] to provide message authentication, with
- * the HMAC output truncated to 128 bits, corresponding to the
- * HMAC-SHA-256-128 algorithm defined in [RFC4868]. For encryption, it
- * uses AES in the CBC mode of operation as defined in Section 6.2 of
- * [NIST.800-38A], with PKCS #7 padding and a 128-bit IV value.
- *
- * The AES_CBC_HMAC_SHA2 parameters specific to AES_128_CBC_HMAC_SHA_256
- * are:
- *
- * The input key K is 32 octets long.
- * ENC_KEY_LEN is 16 octets.
- * MAC_KEY_LEN is 16 octets.
- * The SHA-256 hash algorithm is used for the HMAC.
- * The HMAC-SHA-256 output is truncated to T_LEN=16 octets, by
- * stripping off the final 16 octets.
- */
- { /* required */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_SHA256,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_AES_CBC,
- "A128CBC-HS256", NULL, 256, 256, 128
- },
- /*
- * AES_192_CBC_HMAC_SHA_384 is based on AES_128_CBC_HMAC_SHA_256, but
- * with the following differences:
- *
- * The input key K is 48 octets long instead of 32.
- * ENC_KEY_LEN is 24 octets instead of 16.
- * MAC_KEY_LEN is 24 octets instead of 16.
- * SHA-384 is used for the HMAC instead of SHA-256.
- * The HMAC SHA-384 value is truncated to T_LEN=24 octets instead of 16.
- */
- { /* required */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_SHA384,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_AES_CBC,
- "A192CBC-HS384", NULL, 384, 384, 192
- },
- /*
- * AES_256_CBC_HMAC_SHA_512 is based on AES_128_CBC_HMAC_SHA_256, but
- * with the following differences:
- *
- * The input key K is 64 octets long instead of 32.
- * ENC_KEY_LEN is 32 octets instead of 16.
- * MAC_KEY_LEN is 32 octets instead of 16.
- * SHA-512 is used for the HMAC instead of SHA-256.
- * The HMAC SHA-512 value is truncated to T_LEN=32 octets instead of 16.
- */
- { /* required */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_SHA512,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_AES_CBC,
- "A256CBC-HS512", NULL, 512, 512, 256
- },
- /*
- * The CEK is used as the encryption key.
- *
- * Use of an IV of size 96 bits is REQUIRED with this algorithm.
- *
- * The requested size of the Authentication Tag output MUST be 128 bits,
- * regardless of the key size.
- */
- { /* recommended: AES GCM using 128-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_AES_GCM,
- "A128GCM", NULL, 128, 128, 96
- },
- { /* optional: AES GCM using 192-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_AES_GCM,
- "A192GCM", NULL, 192, 192, 96
- },
- { /* recommended: AES GCM using 256-bit key */
- LWS_GENHASH_TYPE_UNKNOWN,
- LWS_GENHMAC_TYPE_UNKNOWN,
- LWS_JOSE_ENCTYPE_NONE,
- LWS_JOSE_ENCTYPE_AES_GCM,
- "A256GCM", NULL, 256, 256, 96
- },
- { 0, 0, 0, 0, NULL, NULL, 0, 0, 0 } /* sentinel */
- };
- int
- lws_gencrypto_jws_alg_to_definition(const char *alg,
- const struct lws_jose_jwe_alg **jose)
- {
- const struct lws_jose_jwe_alg *a = lws_gencrypto_jws_alg_map;
- while (a->alg) {
- if (!strcmp(alg, a->alg)) {
- *jose = a;
- return 0;
- }
- a++;
- }
- return 1;
- }
- int
- lws_gencrypto_jwe_alg_to_definition(const char *alg,
- const struct lws_jose_jwe_alg **jose)
- {
- const struct lws_jose_jwe_alg *a = lws_gencrypto_jwe_alg_map;
- while (a->alg) {
- if (!strcmp(alg, a->alg)) {
- *jose = a;
- return 0;
- }
- a++;
- }
- return 1;
- }
- int
- lws_gencrypto_jwe_enc_to_definition(const char *enc,
- const struct lws_jose_jwe_alg **jose)
- {
- const struct lws_jose_jwe_alg *e = lws_gencrypto_jwe_enc_map;
- while (e->alg) {
- if (!strcmp(enc, e->alg)) {
- *jose = e;
- return 0;
- }
- e++;
- }
- return 1;
- }
- size_t
- lws_genhash_size(enum lws_genhash_types type)
- {
- switch(type) {
- case LWS_GENHASH_TYPE_UNKNOWN:
- return 0;
- case LWS_GENHASH_TYPE_MD5:
- return 16;
- case LWS_GENHASH_TYPE_SHA1:
- return 20;
- case LWS_GENHASH_TYPE_SHA256:
- return 32;
- case LWS_GENHASH_TYPE_SHA384:
- return 48;
- case LWS_GENHASH_TYPE_SHA512:
- return 64;
- }
- return 0;
- }
- size_t
- lws_genhmac_size(enum lws_genhmac_types type)
- {
- switch(type) {
- case LWS_GENHMAC_TYPE_UNKNOWN:
- return 0;
- case LWS_GENHMAC_TYPE_SHA256:
- return 32;
- case LWS_GENHMAC_TYPE_SHA384:
- return 48;
- case LWS_GENHMAC_TYPE_SHA512:
- return 64;
- }
- return 0;
- }
- int
- lws_gencrypto_bits_to_bytes(int bits)
- {
- if (bits & 7)
- return (bits / 8) + 1;
- return bits / 8;
- }
- int
- lws_base64_size(int bytes)
- {
- return ((bytes * 4) / 3) + 6;
- }
- void
- lws_gencrypto_destroy_elements(struct lws_gencrypto_keyelem *el, int m)
- {
- int n;
- for (n = 0; n < m; n++)
- if (el[n].buf)
- lws_free_set_NULL(el[n].buf);
- }
- size_t lws_gencrypto_padded_length(size_t pad_block_size, size_t len)
- {
- return (len / pad_block_size + 1) * pad_block_size;
- }
|