More optimisations for EC P-256 "i15" (specialised squaring function, mixed coordinat...
[BearSSL] / inc / bearssl_ssl.h
index b038500..5ea257f 100644 (file)
@@ -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