/* ===================================================================== */
+/**
+ * \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;
/*
/*
* 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;
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.
*/
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.
* 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.
* 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
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.
*
* 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
#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