X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=inc%2Fbearssl_ssl.h;h=21d162b71e1126013d72b54504b2a6b423358d10;hp=b0385006240ee5bc77f5656c0a85f735bb7e11e2;hb=ad6a51bde35d008521e3c667f64c43630351abec;hpb=e61ad42191511226309bad2cbde8cd9e8cc743cb diff --git a/inc/bearssl_ssl.h b/inc/bearssl_ssl.h index b038500..21d162b 100644 --- a/inc/bearssl_ssl.h +++ b/inc/bearssl_ssl.h @@ -35,6 +35,10 @@ #include "bearssl_rand.h" #include "bearssl_x509.h" +#ifdef __cplusplus +extern "C" { +#endif + /** \file bearssl_ssl.h * * # SSL @@ -495,7 +499,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 +528,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 +600,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 +812,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 +949,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 +984,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 +1089,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 +1170,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). * @@ -1109,6 +1325,18 @@ br_ssl_engine_set_aes_cbc(br_ssl_engine_context *cc, cc->iaes_cbcdec = impl_dec; } +/** + * \brief Set the "default" AES/CBC implementations. + * + * This function configures in the engine the AES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc); + /** * \brief Set the AES/CTR implementation. * @@ -1122,6 +1350,18 @@ br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc, cc->iaes_ctr = impl; } +/** + * \brief Set the "default" implementations for AES/GCM (AES/CTR + GHASH). + * + * This function configures in the engine the AES/CTR and GHASH + * 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 GCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc); + /** * \brief Set the DES/CBC implementations. * @@ -1138,6 +1378,18 @@ br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc, cc->ides_cbcdec = impl_dec; } +/** + * \brief Set the "default" DES/CBC implementations. + * + * This function configures in the engine the DES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc); + /** * \brief Set the GHASH implementation (used in GCM mode). * @@ -1150,6 +1402,44 @@ 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 "default" ChaCha20 and Poly1305 implementations. + * + * This function configures in the engine the ChaCha20 and Poly1305 + * implementations that should provide best runtime performance on the + * local system, while still being safe (in particular, constant-time). + * It also sets the handlers for ChaCha20+Poly1305 records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc); + /** * \brief Set the record encryption and decryption engines for CBC + HMAC. * @@ -1182,6 +1472,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. * @@ -1197,6 +1504,29 @@ br_ssl_engine_set_ec(br_ssl_engine_context *cc, const br_ec_impl *iec) cc->iec = iec; } +/** + * \brief Set the "default" EC implementation. + * + * This function sets the elliptic curve implementation for ECDH and + * ECDHE cipher suites, and for ECDSA support. It selects the fastest + * implementation on the current system. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc); + +/** + * \brief Get the EC implementation configured in the provided engine. + * + * \param cc SSL engine context. + * \return the EC implementation. + */ +static inline const br_ec_impl * +br_ssl_engine_get_ec(br_ssl_engine_context *cc) +{ + return cc->iec; +} + /** * \brief Set the RSA signature verification implementation. * @@ -1214,6 +1544,29 @@ br_ssl_engine_set_rsavrfy(br_ssl_engine_context *cc, br_rsa_pkcs1_vrfy irsavrfy) cc->irsavrfy = irsavrfy; } +/** + * \brief Set the "default" RSA implementation (signature verification). + * + * This function sets the RSA implementation (signature verification) + * to the fastest implementation available on the current platform. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc); + +/** + * \brief Get the RSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the RSA signature verification implementation. + */ +static inline br_rsa_pkcs1_vrfy +br_ssl_engine_get_rsavrfy(br_ssl_engine_context *cc) +{ + return cc->irsavrfy; +} + /* * \brief Set the ECDSA implementation (signature verification). * @@ -1235,6 +1588,31 @@ br_ssl_engine_set_ecdsa(br_ssl_engine_context *cc, br_ecdsa_vrfy iecdsa) cc->iecdsa = iecdsa; } +/** + * \brief Set the "default" ECDSA implementation (signature verification). + * + * This function sets the ECDSA implementation (signature verification) + * to the fastest implementation available on the current platform. This + * call also sets the elliptic curve implementation itself, there again + * to the fastest EC implementation available. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc); + +/** + * \brief Get the ECDSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the ECDSA signature verification implementation. + */ +static inline br_ecdsa_vrfy +br_ssl_engine_get_ecdsa(br_ssl_engine_context *cc) +{ + return cc->iecdsa; +} + /** * \brief Set the I/O buffer for the SSL engine. * @@ -1402,6 +1780,25 @@ br_ssl_engine_set_session_parameters(br_ssl_engine_context *cc, memcpy(&cc->session, pp, sizeof *pp); } +/** + * \brief Get identifier for the curve used for key exchange. + * + * If the cipher suite uses ECDHE, then this function returns the + * identifier for the curve used for transient parameters. This is + * defined during the course of the handshake, when the ServerKeyExchange + * is sent (on the server) or received (on the client). If the + * cipher suite does not use ECDHE (e.g. static ECDH, or RSA key + * exchange), then this value is indeterminate. + * + * @param cc SSL engine context. + * @return the ECDHE curve identifier. + */ +static inline int +br_ssl_engine_get_ecdhe_curve(br_ssl_engine_context *cc) +{ + return cc->ecdhe_curve; +} + /** * \brief Get the current engine state. * @@ -1881,12 +2278,13 @@ struct br_ssl_client_certificate_class_ { * structure was set to -1). * * In that situation, this callback is invoked to compute the - * client-side ECDH: the provided `data` (of length `len` bytes) + * client-side ECDH: the provided `data` (of length `*len` bytes) * is the server's public key point (as decoded from its * certificate), and the client shall multiply that point with * its own private key, and write back the X coordinate of the - * resulting point in the same buffer, starting at offset 1 - * (therefore, writing back the complete encoded point works). + * resulting point in the same buffer, starting at offset 0. + * The `*len` value shall be modified to designate the actual + * length of the X coordinate. * * The callback must uphold the following: * @@ -1903,11 +2301,11 @@ struct br_ssl_client_certificate_class_ { * * \param pctx certificate handler context. * \param data server public key point. - * \param len server public key point length (in bytes). + * \param len public key point length / X coordinate length. * \return 1 on success, 0 on error. */ uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx, - unsigned char *data, size_t len); + unsigned char *data, size_t *len); /** * \brief Perform a signature (client authentication). @@ -2022,7 +2420,7 @@ struct br_ssl_client_context_ { * Bit field for algoithms (hash + signature) supported by the * server when requesting a client certificate. */ - uint16_t hashes; + uint32_t hashes; /* * Server's public key curve. @@ -2066,15 +2464,33 @@ struct br_ssl_client_context_ { * \brief Get the hash functions and signature algorithms supported by * the server. * - * This is a field of bits: for hash function of ID x, bit x is set if - * the hash function is supported in RSA signatures, 8+x if it is supported - * with ECDSA. This information is conveyed by the server when requesting - * a client certificate. + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * 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` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. * * \param cc client context. - * \return the server-supported hash functions (for signatures). + * \return the server-supported hash functions and signature algorithms. */ -static inline uint16_t +static inline uint32_t br_ssl_client_get_server_hashes(const br_ssl_client_context *cc) { return cc->hashes; @@ -2164,6 +2580,17 @@ br_ssl_client_set_rsapub(br_ssl_client_context *cc, br_rsa_public irsapub) cc->irsapub = irsapub; } +/** + * \brief Set the "default" RSA implementation for public-key operations. + * + * This sets the RSA implementation in the client context (for encrypting + * the pre-master secret, in `TLS_RSA_*` cipher suites) to the fastest + * available on the current platform. + * + * \param cc client context. + */ +void br_ssl_client_set_default_rsapub(br_ssl_client_context *cc); + /** * \brief Set the minimum ClientHello length (RFC 7685 padding). * @@ -2399,18 +2826,47 @@ typedef struct { uint16_t cipher_suite; /** - * \brief Hash function for signing the ServerKeyExchange. - * - * This is the symbolic identifier for the hash function that - * will be used to sign the ServerKeyExchange message, for ECDHE - * cipher suites. This is ignored for RSA and ECDH cipher suites. - * - * Take care that with TLS 1.0 and 1.1, that value MUST match - * the protocol requirements: value must be 0 (MD5+SHA-1) for - * a RSA signature, or 2 (SHA-1) for an ECDSA signature. Only - * TLS 1.2 allows for other hash functions. - */ - int hash_id; + * \brief Hash function or algorithm for signing the ServerKeyExchange. + * + * This parameter is ignored for `TLS_RSA_*` and `TLS_ECDH_*` + * cipher suites; it is used only for `TLS_ECDHE_*` suites, in + * which the server _signs_ the ephemeral EC Diffie-Hellman + * parameters sent to the client. + * + * This identifier must be one of the following values: + * + * - `0xFF00 + id`, where `id` is a hash function identifier + * (0 for MD5+SHA-1, or 2 to 6 for one of the SHA functions); + * + * - a full 16-bit identifier, lower than `0xFF00`. + * + * If the first option is used, then the SSL engine will + * compute the hash of the data that is to be signed, with the + * designated hash function. The `do_sign()` method will be + * invoked with that hash value provided in the the `data` + * buffer. + * + * If the second option is used, then the SSL engine will NOT + * compute a hash on the data; instead, it will provide the + * to-be-signed data itself in `data`, i.e. the concatenation of + * the client random, server random, and encoded ECDH + * parameters. Furthermore, with TLS-1.2 and later, the 16-bit + * identifier will be used "as is" in the protocol, in the + * SignatureAndHashAlgorithm; for instance, `0x0401` stands for + * RSA PKCS#1 v1.5 signature (the `01`) with SHA-256 as hash + * function (the `04`). + * + * Take care that with TLS 1.0 and 1.1, the hash function is + * constrainted by the protocol: RSA signature must use + * MD5+SHA-1 (so use `0xFF00`), while ECDSA must use SHA-1 + * (`0xFF02`). Since TLS 1.0 and 1.1 don't include a + * SignatureAndHashAlgorithm field in their ServerKeyExchange + * messages, any value below `0xFF00` will be usable to send the + * raw ServerKeyExchange data to the `do_sign()` callback, but + * that callback must still follow the protocol requirements + * when generating the signature. + */ + unsigned algo_id; /** * \brief Certificate chain to send to the client. @@ -2489,12 +2945,12 @@ struct br_ssl_server_policy_class_ { * operation for a key exchange that is not ECDHE. This callback * uses the private key. * - * **For RSA key exchange**, the provided `data` (of length `len` + * **For RSA key exchange**, the provided `data` (of length `*len` * bytes) shall be decrypted with the server's private key, and * the 48-byte premaster secret copied back to the first 48 bytes * of `data`. * - * - The caller makes sure that `len` is at least 59 bytes. + * - The caller makes sure that `*len` is at least 59 bytes. * * - This callback MUST check that the provided length matches * that of the key modulus; it shall report an error otherwise. @@ -2511,12 +2967,11 @@ struct br_ssl_server_policy_class_ { * in the first 48 bytes of `data` is unimportant (the caller * will use random bytes instead). * - * **For ECDH key exchange**, the provided `data` (of length `len` + * **For ECDH key exchange**, the provided `data` (of length `*len` * bytes) is the elliptic curve point from the client. The * callback shall multiply it with its private key, and store - * the resulting X coordinate in `data`, starting at offset 1 - * (thus, simply encoding the point in compressed or uncompressed - * format in `data` is fine). + * the resulting X coordinate in `data`, starting at offset 0, + * and set `*len` to the length of the X coordinate. * * - If the input array does not have the proper length for * an encoded curve point, then an error (0) shall be reported. @@ -2535,38 +2990,50 @@ struct br_ssl_server_policy_class_ { * \return 1 on success, 0 on error. */ uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx, - unsigned char *data, size_t len); + unsigned char *data, size_t *len); /** * \brief Perform a signature (for a ServerKeyExchange message). * - * This callback function is invoked for ECDHE cipher suites. - * On input, the hash value to sign is in `data`, of size - * `hv_len`; the involved hash function is identified by - * `hash_id`. The signature shall be computed and written - * back into `data`; the total size of that buffer is `len` - * bytes. + * This callback function is invoked for ECDHE cipher suites. On + * input, the hash value or message to sign is in `data`, of + * size `hv_len`; the involved hash function or algorithm is + * identified by `algo_id`. The signature shall be computed and + * written back into `data`; the total size of that buffer is + * `len` bytes. * * This callback shall verify that the signature length does not * exceed `len` bytes, and abstain from writing the signature if * it does not fit. * - * For RSA signatures, the `hash_id` may be 0, in which case - * this is the special header-less signature specified in TLS 1.0 - * and 1.1, with a 36-byte hash value. Otherwise, normal PKCS#1 - * v1.5 signatures shall be computed. + * The `algo_id` value matches that which was written in the + * `choices` structures by the `choose()` callback. This will be + * one of the following: + * + * - `0xFF00 + id` for a hash function identifier `id`. In + * that case, the `data` buffer contains a hash value + * already computed over the data that is to be signed, + * of length `hv_len`. The `id` may be 0 to designate the + * special MD5+SHA-1 concatenation (old-style RSA signing). + * + * - Another value, lower than `0xFF00`. The `data` buffer + * then contains the raw, non-hashed data to be signed + * (concatenation of the client and server randoms and + * ECDH parameters). The callback is responsible to apply + * any relevant hashing as part of the signing process. * * Returned value is the signature length (in bytes), or 0 on error. * * \param pctx policy context. - * \param hash_id hash function identifier. - * \param hv_len hash value length (in bytes). - * \param data input/output buffer (hash value, then signature). + * \param algo_id hash function / algorithm identifier. + * \param data input/output buffer (message/hash, then signature). + * \param hv_len hash value or message length (in bytes). * \param len total buffer length (in bytes). * \return signature length (in bytes) on success, or 0 on error. */ size_t (*do_sign)(const br_ssl_server_policy_class **pctx, - int hash_id, size_t hv_len, unsigned char *data, size_t len); + unsigned algo_id, + unsigned char *data, size_t hv_len, size_t len); }; /** @@ -2751,9 +3218,10 @@ struct br_ssl_server_context_ { /* * Hash functions supported by the client, with ECDSA and RSA * (bit mask). For hash function with id 'x', set bit index is - * x for RSA, x+8 for ECDSA. + * x for RSA, x+8 for ECDSA. For newer algorithms, with ID + * 0x08**, bit 16+k is set for algorithm 0x0800+k. */ - uint16_t hashes; + uint32_t hashes; /* * Curves supported by the client (bit mask, for named curves). @@ -2764,7 +3232,7 @@ struct br_ssl_server_context_ { * Context for chain handler. */ const br_ssl_server_policy_class **policy_vtable; - unsigned char sign_hash_id; + uint16_t sign_hash_id; /* * For the core handlers, thus avoiding (in most cases) the @@ -2831,8 +3299,9 @@ struct br_ssl_server_context_ { * 3 = TLS 1.2 with SHA-384 * -- character 3: encryption * a = AES/CBC - * g = AES/GCM * d = 3DES/CBC + * g = AES/GCM + * c = ChaCha20+Poly1305 */ /** @@ -2964,6 +3433,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. * @@ -2994,16 +3495,36 @@ br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num) } /** - * \brief Get the hash functions supported by the client. + * \brief Get the hash functions and signature algorithms supported by + * the client. * - * This is a field of bits: for hash function of ID x, bit x is set if - * the hash function is supported in RSA signatures, 8+x if it is supported - * with ECDSA. + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * 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` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. * * \param cc server context. - * \return the client-supported hash functions (for signatures). + * \return the client-supported hash functions and signature algorithms. */ -static inline uint16_t +static inline uint32_t br_ssl_server_get_client_hashes(const br_ssl_server_context *cc) { return cc->hashes; @@ -3546,5 +4067,10 @@ 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 + +#ifdef __cplusplus +} +#endif #endif