X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=inc%2Fbearssl_ssl.h;h=5ea257f9aa76e3e9d19fb011bfea4c1239ca4514;hp=b0385006240ee5bc77f5656c0a85f735bb7e11e2;hb=05ac106834fa8889cf55ee462fe4108d4712040a;hpb=e61ad42191511226309bad2cbde8cd9e8cc743cb diff --git a/inc/bearssl_ssl.h b/inc/bearssl_ssl.h index b038500..5ea257f 100644 --- a/inc/bearssl_ssl.h +++ b/inc/bearssl_ssl.h @@ -495,7 +495,7 @@ extern const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable; * This class type extends the decryption engine class with an * initialisation method that receives the parameters needed * for GCM processing: block cipher implementation, block cipher key, - * GHASH implementtion, and 4-byte IV. + * GHASH implementation, and 4-byte IV. */ typedef struct br_sslrec_in_gcm_class_ br_sslrec_in_gcm_class; struct br_sslrec_in_gcm_class_ { @@ -524,12 +524,12 @@ struct br_sslrec_in_gcm_class_ { }; /** - * \brief Record decryption engine class, for GCM mode. + * \brief Record encryption engine class, for GCM mode. * - * This class type extends the decryption engine class with an + * This class type extends the encryption engine class with an * initialisation method that receives the parameters needed * for GCM processing: block cipher implementation, block cipher key, - * GHASH implementtion, and 4-byte IV. + * GHASH implementation, and 4-byte IV. */ typedef struct br_sslrec_out_gcm_class_ br_sslrec_out_gcm_class; struct br_sslrec_out_gcm_class_ { @@ -596,6 +596,106 @@ extern const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable; /* ===================================================================== */ +/** + * \brief Record decryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_in_chapol_class_ br_sslrec_in_chapol_class; +struct br_sslrec_in_chapol_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 ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_in_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Record encryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_out_chapol_class_ br_sslrec_out_chapol_class; +struct br_sslrec_out_chapol_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 ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_out_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Context structure for processing records with ChaCha20+Poly1305. + * + * 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_chapol_class *in; + const br_sslrec_out_chapol_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + unsigned char key[32]; + unsigned char iv[12]; + br_chacha20_run ichacha; + br_poly1305_run ipoly; +#endif +} br_sslrec_chapol_context; + +/** + * \brief Static, constant vtable for record decryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable; + +/** + * \brief Static, constant vtable for record encryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable; + +/* ===================================================================== */ + /** * \brief Type for session parameters, to be saved for session resumption. */ @@ -708,12 +808,14 @@ typedef struct { const br_sslrec_in_class *vtable; br_sslrec_in_cbc_context cbc; br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; } in; union { const br_sslrec_out_class *vtable; br_sslrec_out_clear_context clear; br_sslrec_out_cbc_context cbc; br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; } out; /* @@ -843,6 +945,27 @@ typedef struct { const unsigned char *cert_cur; size_t cert_len; + /* + * List of supported protocol names (ALPN extension). If unset, + * (number of names is 0), then: + * - the client sends no ALPN extension; + * - the server ignores any incoming ALPN extension. + * + * Otherwise: + * - the client sends an ALPN extension with all the names; + * - the server selects the first protocol in its list that + * the client also supports, or fails (fatal alert 120) + * if the client sends an ALPN extension and there is no + * match. + * + * The 'selected_protocol' field contains 1+n if the matching + * name has index n in the list (the value is 0 if no match was + * performed, e.g. the peer did not send an ALPN extension). + */ + const char **protocol_names; + uint16_t protocol_names_num; + uint16_t selected_protocol; + /* * Pointers to implementations; left to NULL for unsupported * functions. For the raw hash functions, implementations are @@ -857,10 +980,14 @@ typedef struct { const br_block_cbcenc_class *ides_cbcenc; const br_block_cbcdec_class *ides_cbcdec; br_ghash ighash; + br_chacha20_run ichacha; + br_poly1305_run ipoly; const br_sslrec_in_cbc_class *icbc_in; const br_sslrec_out_cbc_class *icbc_out; const br_sslrec_in_gcm_class *igcm_in; 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_ec_impl *iec; br_rsa_pkcs1_vrfy irsavrfy; br_ecdsa_vrfy iecdsa; @@ -958,6 +1085,32 @@ br_ssl_engine_remove_flags(br_ssl_engine_context *cc, uint32_t flags) */ #define BR_OPT_TOLERATE_NO_CLIENT_AUTH ((uint32_t)1 << 2) +/** + * \brief Behavioural flag: fail on application protocol mismatch. + * + * The ALPN extension ([RFC 7301](https://tools.ietf.org/html/rfc7301)) + * allows the client to send a list of application protocol names, and + * the server to select one. A mismatch is one of the following occurrences: + * + * - On the client: the client sends a list of names, the server + * responds with a protocol name which is _not_ part of the list of + * names sent by the client. + * + * - On the server: the client sends a list of names, and the server + * is also configured with a list of names, but there is no common + * protocol name between the two lists. + * + * Normal behaviour in case of mismatch is to report no matching name + * (`br_ssl_engine_get_selected_protocol()` returns `NULL`) and carry on. + * If the flag is set, then a mismatch implies a protocol failure (if + * the mismatch is detected by the server, it will send a fatal alert). + * + * Note: even with this flag, `br_ssl_engine_get_selected_protocol()` + * may still return `NULL` if the client or the server does not send an + * ALPN extension at all. + */ +#define BR_OPT_FAIL_ON_ALPN_MISMATCH ((uint32_t)1 << 3) + /** * \brief Set the minimum and maximum supported protocol versions. * @@ -1013,6 +1166,65 @@ br_ssl_engine_set_x509(br_ssl_engine_context *cc, const br_x509_class **x509ctx) cc->x509ctx = x509ctx; } +/** + * \brief Set the supported protocol names. + * + * Protocol names are part of the ALPN extension ([RFC + * 7301](https://tools.ietf.org/html/rfc7301)). Each protocol name is a + * character string, containing no more than 255 characters (256 with the + * terminating zero). When names are set, then: + * + * - The client will send an ALPN extension, containing the names. If + * the server responds with an ALPN extension, the client will verify + * that the response contains one of its name, and report that name + * through `br_ssl_engine_get_selected_protocol()`. + * + * - The server will parse incoming ALPN extension (from clients), and + * try to find a common protocol; if none is found, the connection + * is aborted with a fatal alert. On match, a response ALPN extension + * is sent, and name is reported through + * `br_ssl_engine_get_selected_protocol()`. + * + * The provided array is linked in, and must remain valid while the + * connection is live. + * + * Names MUST NOT be empty. Names MUST NOT be longer than 255 characters + * (excluding the terminating 0). + * + * \param ctx SSL engine context. + * \param names list of protocol names (zero-terminated). + * \param num number of protocol names (MUST be 1 or more). + */ +static inline void +br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx, + const char **names, size_t num) +{ + ctx->protocol_names = names; + ctx->protocol_names_num = num; +} + +/** + * \brief Get the selected protocol. + * + * If this context was initialised with a non-empty list of protocol + * names, and both client and server sent ALPN extensions during the + * handshake, and a common name was found, then that name is returned. + * Otherwise, `NULL` is returned. + * + * The returned pointer is one of the pointers provided to the context + * with `br_ssl_engine_set_protocol_names()`. + * + * \return the selected protocol, or `NULL`. + */ +static inline const char * +br_ssl_engine_get_selected_protocol(br_ssl_engine_context *ctx) +{ + unsigned k; + + k = ctx->selected_protocol; + return (k == 0 || k == 0xFFFF) ? NULL : ctx->protocol_names[k - 1]; +} + /** * \brief Set a hash function implementation (by ID). * @@ -1150,6 +1362,32 @@ br_ssl_engine_set_ghash(br_ssl_engine_context *cc, br_ghash impl) cc->ighash = impl; } +/** + * \brief Set the ChaCha20 implementation. + * + * \param cc SSL engine context. + * \param ichacha ChaCha20 implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_chacha20(br_ssl_engine_context *cc, + br_chacha20_run ichacha) +{ + cc->ichacha = ichacha; +} + +/** + * \brief Set the Poly1305 implementation. + * + * \param cc SSL engine context. + * \param ipoly Poly1305 implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_poly1305(br_ssl_engine_context *cc, + br_poly1305_run ipoly) +{ + cc->ipoly = ipoly; +} + /** * \brief Set the record encryption and decryption engines for CBC + HMAC. * @@ -1182,6 +1420,23 @@ br_ssl_engine_set_gcm(br_ssl_engine_context *cc, cc->igcm_out = impl_out; } +/** + * \brief Set the record encryption and decryption engines for + * ChaCha20+Poly1305. + * + * \param cc SSL engine context. + * \param impl_in record ChaCha20 decryption implementation (or `NULL`). + * \param impl_out record ChaCha20 encryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_chapol(br_ssl_engine_context *cc, + const br_sslrec_in_chapol_class *impl_in, + const br_sslrec_out_chapol_class *impl_out) +{ + cc->ichapol_in = impl_in; + cc->ichapol_out = impl_out; +} + /** * \brief Set the EC implementation. * @@ -2964,6 +3219,38 @@ void br_ssl_server_init_minv2g(br_ssl_server_context *cc, const br_x509_certificate *chain, size_t chain_len, const br_ec_private_key *sk); +/** + * \brief SSL server profile: mine2c. + * + * This profile uses only TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is RSA, and ECDHE key exchange is used. This suite + * provides forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_mine2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: minf2c. + * + * This profile uses only TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is EC, and ECDHE key exchange is used. This suite provides + * forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minf2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + /** * \brief Get the supported client suites. * @@ -3546,5 +3833,6 @@ int br_sslio_close(br_sslio_context *cc); #define BR_ALERT_USER_CANCELED 90 #define BR_ALERT_NO_RENEGOTIATION 100 #define BR_ALERT_UNSUPPORTED_EXTENSION 110 +#define BR_ALERT_NO_APPLICATION_PROTOCOL 120 #endif