#include "bearssl_rand.h"
#include "bearssl_x509.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** \file bearssl_ssl.h
*
* # SSL
/* ===================================================================== */
+/**
+ * \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.
*/
#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
/**
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;
br_sslrec_out_cbc_context cbc;
br_sslrec_gcm_context gcm;
br_sslrec_chapol_context chapol;
+ br_sslrec_ccm_context ccm;
} out;
/*
- * The "application data" flag. It is set when application data
- * can be exchanged, cleared otherwise.
+ * The "application data" flag. Value:
+ * 0 handshake is in process, no application data acceptable
+ * 1 application data can be sent and received
+ * 2 closing, no application data can be sent, but some
+ * can still be received (and discarded)
*/
unsigned char application_data;
/*
* 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;
/*
* 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
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;
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;
br_ssl_engine_set_versions(br_ssl_engine_context *cc,
unsigned version_min, unsigned version_max)
{
- cc->version_min = version_min;
- cc->version_max = version_max;
+ cc->version_min = (uint16_t)version_min;
+ cc->version_max = (uint16_t)version_max;
}
/**
const char **names, size_t num)
{
ctx->protocol_names = names;
- ctx->protocol_names_num = num;
+ ctx->protocol_names_num = (uint16_t)num;
}
/**
/**
* \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.
/**
* \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.
/**
* \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.
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.
*
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.
*
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).
*
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 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.
*
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.
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.
*
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).
*
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.
*
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.
*
* 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.
*/
/**
* \brief Get buffer for received application data.
*
- * If the engine has received application data from the peer, hen this
+ * If the engine has received application data from the peer, then this
* call returns a pointer to the buffer from where such data shall be
* read, and its length is written in `*len`. Otherwise, `*len` is set
* to 0 and `NULL` is returned.
*
* 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
*/
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.
*/
* 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:
*
*
* \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).
* 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.
* \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 supported 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;
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).
*
uint16_t cipher_suite;
/**
- * \brief Hash function for signing the ServerKeyExchange.
+ * \brief Hash function or algorithm 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.
+ * 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.
*
- * 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.
+ * 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.
*/
- int hash_id;
+ unsigned algo_id;
/**
* \brief Certificate chain to send to the client.
* 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.
* 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.
* \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);
};
/**
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.
*
/*
* 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).
* 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
* 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
*/
/**
}
/**
- * \brief Get the hash functions supported by the client.
+ * \brief Get the hash functions and signature algorithms supported by
+ * the client.
+ *
+ * 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).
*
- * 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.
+ * - 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
+ * 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;
#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
#define BR_ALERT_UNSUPPORTED_EXTENSION 110
#define BR_ALERT_NO_APPLICATION_PROTOCOL 120
+#ifdef __cplusplus
+}
+#endif
+
#endif