X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=inc%2Fbearssl_ssl.h;h=8c8c86bdb50a6bf6b80fe32460b16cd7ab8bd521;hp=2ac9e258a79b1ed2053dccaa189d770f095ac033;hb=491a45337de8dc0a4c100abf33f5c0e187a08afd;hpb=968da0f646a43c69a2517a240c9963ff513981b3;ds=inline diff --git a/inc/bearssl_ssl.h b/inc/bearssl_ssl.h index 2ac9e25..8c8c86b 100644 --- a/inc/bearssl_ssl.h +++ b/inc/bearssl_ssl.h @@ -700,6 +700,110 @@ extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable; /* ===================================================================== */ +/** + * \brief Record decryption engine class, for CCM mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_in_ccm_class_ br_sslrec_in_ccm_class; +struct br_sslrec_in_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_in_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Record encryption engine class, for CCM mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_out_ccm_class_ br_sslrec_out_ccm_class; +struct br_sslrec_out_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_out_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Context structure for processing records with CCM. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_ccm_class *in; + const br_sslrec_out_ccm_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_ctrcbc_class *vtable; + br_aes_gen_ctrcbc_keys aes; + } bc; + unsigned char iv[4]; + size_t tag_len; +#endif +} br_sslrec_ccm_context; + +/** + * \brief Static, constant vtable for record decryption with CCM. + */ +extern const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable; + +/** + * \brief Static, constant vtable for record encryption with CCM. + */ +extern const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable; + +/* ===================================================================== */ + /** * \brief Type for session parameters, to be saved for session resumption. */ @@ -718,9 +822,9 @@ typedef struct { #ifndef BR_DOXYGEN_IGNORE /* - * Maximum numnber of cipher suites supported by a client or server. + * Maximum number of cipher suites supported by a client or server. */ -#define BR_MAX_CIPHER_SUITES 40 +#define BR_MAX_CIPHER_SUITES 48 #endif /** @@ -813,6 +917,7 @@ typedef struct { br_sslrec_in_cbc_context cbc; br_sslrec_gcm_context gcm; br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; } in; union { const br_sslrec_out_class *vtable; @@ -820,6 +925,7 @@ typedef struct { br_sslrec_out_cbc_context cbc; br_sslrec_gcm_context gcm; br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; } out; /* @@ -833,6 +939,14 @@ typedef struct { /* * Context RNG. + * + * rng_init_done is initially 0. It is set to 1 when the + * basic structure of the RNG is set, and 2 when some + * entropy has been pushed in. The value 2 marks the RNG + * as "properly seeded". + * + * rng_os_rand_done is initially 0. It is set to 1 when + * some seeding from the OS or hardware has been attempted. */ br_hmac_drbg_context rng; int rng_init_done; @@ -871,8 +985,8 @@ typedef struct { /* * Secure renegotiation (RFC 5746): 'reneg' can be: * 0 first handshake (server support is not known) - * 1 server does not support secure renegotiation - * 2 server supports secure renegotiation + * 1 peer does not support secure renegotiation + * 2 peer supports secure renegotiation * * The saved_finished buffer contains the client and the * server "Finished" values from the last handshake, in @@ -984,6 +1098,7 @@ typedef struct { const br_block_cbcenc_class *iaes_cbcenc; const br_block_cbcdec_class *iaes_cbcdec; const br_block_ctr_class *iaes_ctr; + const br_block_ctrcbc_class *iaes_ctrcbc; const br_block_cbcenc_class *ides_cbcenc; const br_block_cbcdec_class *ides_cbcdec; br_ghash ighash; @@ -995,6 +1110,8 @@ typedef struct { const br_sslrec_out_gcm_class *igcm_out; const br_sslrec_in_chapol_class *ichapol_in; const br_sslrec_out_chapol_class *ichapol_out; + const br_sslrec_in_ccm_class *iccm_in; + const br_sslrec_out_ccm_class *iccm_out; const br_ec_impl *iec; br_rsa_pkcs1_vrfy irsavrfy; br_ecdsa_vrfy iecdsa; @@ -1270,7 +1387,7 @@ br_ssl_engine_get_hash(br_ssl_engine_context *ctx, int id) /** * \brief Set the PRF implementation (for TLS 1.0 and 1.1). * - * This function sets (or removes, if `impl` is `NULL`) the implemenation + * This function sets (or removes, if `impl` is `NULL`) the implementation * for the PRF used in TLS 1.0 and 1.1. * * \param cc SSL engine context. @@ -1285,7 +1402,7 @@ br_ssl_engine_set_prf10(br_ssl_engine_context *cc, br_tls_prf_impl impl) /** * \brief Set the PRF implementation with SHA-256 (for TLS 1.2). * - * This function sets (or removes, if `impl` is `NULL`) the implemenation + * This function sets (or removes, if `impl` is `NULL`) the implementation * for the SHA-256 variant of the PRF used in TLS 1.2. * * \param cc SSL engine context. @@ -1300,7 +1417,7 @@ br_ssl_engine_set_prf_sha256(br_ssl_engine_context *cc, br_tls_prf_impl impl) /** * \brief Set the PRF implementation with SHA-384 (for TLS 1.2). * - * This function sets (or removes, if `impl` is `NULL`) the implemenation + * This function sets (or removes, if `impl` is `NULL`) the implementation * for the SHA-384 variant of the PRF used in TLS 1.2. * * \param cc SSL engine context. @@ -1443,6 +1560,31 @@ br_ssl_engine_set_poly1305(br_ssl_engine_context *cc, */ void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc); +/** + * \brief Set the AES/CTR+CBC implementation. + * + * \param cc SSL engine context. + * \param impl AES/CTR+CBC encryption/decryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_aes_ctrcbc(br_ssl_engine_context *cc, + const br_block_ctrcbc_class *impl) +{ + cc->iaes_ctrcbc = impl; +} + +/** + * \brief Set the "default" implementations for AES/CCM. + * + * This function configures in the engine the AES/CTR+CBC + * implementation that should provide best runtime performance on the local + * system, while still being safe (in particular, constant-time). It also + * sets the handlers for CCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc); + /** * \brief Set the record encryption and decryption engines for CBC + HMAC. * @@ -1475,6 +1617,22 @@ br_ssl_engine_set_gcm(br_ssl_engine_context *cc, cc->igcm_out = impl_out; } +/** + * \brief Set the record encryption and decryption engines for CCM. + * + * \param cc SSL engine context. + * \param impl_in record CCM decryption implementation (or `NULL`). + * \param impl_out record CCM encryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_ccm(br_ssl_engine_context *cc, + const br_sslrec_in_ccm_class *impl_in, + const br_sslrec_out_ccm_class *impl_out) +{ + cc->iccm_in = impl_in; + cc->iccm_out = impl_out; +} + /** * \brief Set the record encryption and decryption engines for * ChaCha20+Poly1305. @@ -1908,7 +2066,7 @@ br_ssl_engine_last_error(const br_ssl_engine_context *cc) * Informs the engine that 'len' bytes have been read from the buffer * (extract operation) or written to the buffer (inject operation). * The 'len' value MUST NOT be zero. The 'len' value MUST NOT exceed - * that which was obtained from a preceeding br_ssl_engine_xxx_buf() + * that which was obtained from a preceding br_ssl_engine_xxx_buf() * call. */ @@ -2063,8 +2221,9 @@ void br_ssl_engine_close(br_ssl_engine_context *cc); * * If the engine is failed or closed, or if the peer is known not to * support secure renegotiation (RFC 5746), or if renegotiations have - * been disabled with the `BR_OPT_NO_RENEGOTIATION` flag, then this - * function returns 0 and nothing else happens. + * been disabled with the `BR_OPT_NO_RENEGOTIATION` flag, or if there + * is buffered incoming application data, then this function returns 0 + * and nothing else happens. * * Otherwise, this function returns 1, and a renegotiation attempt is * triggered (if a handshake is already ongoing at that point, then @@ -2075,6 +2234,41 @@ void br_ssl_engine_close(br_ssl_engine_context *cc); */ int br_ssl_engine_renegotiate(br_ssl_engine_context *cc); +/** + * \brief Export key material from a connected SSL engine (RFC 5705). + * + * This calls compute a secret key of arbitrary length from the master + * secret of a connected SSL engine. If the provided context is not + * currently in "application data" state (initial handshake is not + * finished, another handshake is ongoing, or the connection failed or + * was closed), then this function returns 0. Otherwise, a secret key of + * length `len` bytes is computed and written in the buffer pointed to + * by `dst`, and 1 is returned. + * + * The computed key follows the specification described in RFC 5705. + * That RFC includes two key computations, with and without a "context + * value". If `context` is `NULL`, then the variant without context is + * used; otherwise, the `context_len` bytes located at the address + * pointed to by `context` are used in the computation. Note that it + * is possible to have a "with context" key with a context length of + * zero bytes, by setting `context` to a non-`NULL` value but + * `context_len` to 0. + * + * When context bytes are used, the context length MUST NOT exceed + * 65535 bytes. + * + * \param cc SSL engine context. + * \param dst destination buffer for exported key. + * \param len exported key length (in bytes). + * \param label disambiguation label. + * \param context context value (or `NULL`). + * \param context_len context length (in bytes). + * \return 1 on success, 0 on error. + */ +int br_ssl_key_export(br_ssl_engine_context *cc, + void *dst, size_t len, const char *label, + const void *context, size_t context_len); + /* * Pre-declaration for the SSL client context. */ @@ -2473,7 +2667,7 @@ struct br_ssl_client_context_ { * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, * or 2 to 6 for the SHA family). * - * - If ECDSA is suported with hash function of ID `x`, then bit `8+x` + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` * is set. * * - Newer algorithms are symbolic 16-bit identifiers that do not @@ -3184,6 +3378,19 @@ typedef struct { void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, unsigned char *store, size_t store_len); +/** + * \brief Forget an entry in an LRU session cache. + * + * The session cache context must have been initialised. The entry + * with the provided session ID (of exactly 32 bytes) is looked for + * in the cache; if located, it is disabled. + * + * \param cc session cache context. + * \param id session ID to forget. + */ +void br_ssl_session_cache_lru_forget( + br_ssl_session_cache_lru *cc, const unsigned char *id); + /** * \brief Context structure for a SSL server. * @@ -3507,7 +3714,7 @@ br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num) * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, * or 2 to 6 for the SHA family). * - * - If ECDSA is suported with hash function of ID `x`, then bit `8+x` + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` * is set. * * - Newer algorithms are symbolic 16-bit identifiers that do not @@ -4033,6 +4240,16 @@ int br_sslio_close(br_sslio_context *cc); #define BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 #define BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 +/* From RFC 6655 and 7251 */ +#define BR_TLS_RSA_WITH_AES_128_CCM 0xC09C +#define BR_TLS_RSA_WITH_AES_256_CCM 0xC09D +#define BR_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 +#define BR_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF + /* From RFC 7905 */ #define BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 #define BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9