Added ChaCha20+Poly1305 support (stand-alone, cipher suites).
This commit is contained in:
parent
9e71c0673a
commit
b42bd5972f
26 changed files with 1952 additions and 523 deletions
|
|
@ -30,9 +30,10 @@
|
|||
|
||||
/** \file bearssl_block.h
|
||||
*
|
||||
* # Block Ciphers
|
||||
* # Block Ciphers and Symmetric Ciphers
|
||||
*
|
||||
* This file documents the API for block ciphers.
|
||||
* This file documents the API for block ciphers and other symmetric
|
||||
* ciphers.
|
||||
*
|
||||
*
|
||||
* ## Procedural API
|
||||
|
|
@ -227,6 +228,27 @@
|
|||
*
|
||||
* `des_ct` is an constant-time implementation of DES/3DES. It is
|
||||
* substantially slower than `des_tab`.
|
||||
*
|
||||
* ## ChaCha20 and Poly1305
|
||||
*
|
||||
* ChaCha20 is a stream cipher. Poly1305 is a MAC algorithm. They
|
||||
* are described in [RFC 7539](https://tools.ietf.org/html/rfc7539).
|
||||
*
|
||||
* Two function pointer types are defined:
|
||||
*
|
||||
* - `br_chacha20_run` describes a function that implements ChaCha20
|
||||
* only.
|
||||
*
|
||||
* - `br_poly1305_run` describes an implementation of Poly1305,
|
||||
* in the AEAD combination with ChaCha20 specified in RFC 7539
|
||||
* (the ChaCha20 implementation is provided as a function pointer).
|
||||
*
|
||||
* `chacha20_ct` is a straightforward implementation of ChaCha20 in
|
||||
* plain C; it is constant-time, small, and reasonably fast.
|
||||
*
|
||||
* `poly1305_ctmul` is an implementation of the ChaCha20+Poly1305 AEAD
|
||||
* construction, where the Poly1305 part is performed with mixed 32-bit
|
||||
* multiplications (operands are 32-bit, result is 64-bit).
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -1217,4 +1239,88 @@ typedef union {
|
|||
br_des_ct_cbcdec_keys ct;
|
||||
} br_des_gen_cbcdec_keys;
|
||||
|
||||
/**
|
||||
* \brief Type for a ChaCha20 implementation.
|
||||
*
|
||||
* An implementation follows the description in RFC 7539:
|
||||
*
|
||||
* - Key is 256 bits (`key` points to exactly 32 bytes).
|
||||
*
|
||||
* - IV is 96 bits (`iv` points to exactly 12 bytes).
|
||||
*
|
||||
* - Block counter is oveer 32 bits and starts at value `cc`; the
|
||||
* resulting value is returned.
|
||||
*
|
||||
* Data (pointed to by `data`, of length `len`) is encrypted/decrypted
|
||||
* in place. If `len` is not a multiple of 64, then the excess bytes from
|
||||
* the last block processing are dropped (therefore, "chunked" processing
|
||||
* works only as long as each non-final chunk has a length multiple of 64).
|
||||
*
|
||||
* \param key secret key (32 bytes).
|
||||
* \param iv IV (12 bytes).
|
||||
* \param cc initial counter value.
|
||||
* \param data data to encrypt or decrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
typedef uint32_t (*br_chacha20_run)(const void *key,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief ChaCha20 implementation (straightforward C code, constant-time).
|
||||
*
|
||||
* \see br_chacha20_run
|
||||
*
|
||||
* \param key secret key (32 bytes).
|
||||
* \param iv IV (12 bytes).
|
||||
* \param cc initial counter value.
|
||||
* \param data data to encrypt or decrypt.
|
||||
* \param len data length (in bytes).
|
||||
*/
|
||||
uint32_t br_chacha20_ct_run(const void *key,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Type for a ChaCha20+Poly1305 AEAD implementation.
|
||||
*
|
||||
* The provided data is encrypted or decrypted with ChaCha20. The
|
||||
* authentication tag is computed on the concatenation of the
|
||||
* additional data and the ciphertext, with the padding and lengths
|
||||
* as described in RFC 7539 (section 2.8).
|
||||
*
|
||||
* After decryption, the caller is responsible for checking that the
|
||||
* computed tag matches the expected value.
|
||||
*
|
||||
* \param key secret key (32 bytes).
|
||||
* \param iv nonce (12 bytes).
|
||||
* \param data data to encrypt or decrypt.
|
||||
* \param len data length (in bytes).
|
||||
* \param aad additional authenticated data.
|
||||
* \param aad_len length of additional authenticated data (in bytes).
|
||||
* \param tag output buffer for the authentication tag.
|
||||
* \param ichacha implementation of ChaCha20.
|
||||
* \param encrypt non-zero for encryption, zero for decryption.
|
||||
*/
|
||||
typedef void (*br_poly1305_run)(const void *key, const void *iv,
|
||||
void *data, size_t len, const void *aad, size_t aad_len,
|
||||
void *tag, br_chacha20_run ichacha, int encrypt);
|
||||
|
||||
/**
|
||||
* \brief ChaCha20+Poly1305 AEAD implementation (mixed 32-bit multiplications).
|
||||
*
|
||||
* \see br_poly1305_run
|
||||
*
|
||||
* \param key secret key (32 bytes).
|
||||
* \param iv nonce (12 bytes).
|
||||
* \param data data to encrypt or decrypt.
|
||||
* \param len data length (in bytes).
|
||||
* \param aad additional authenticated data.
|
||||
* \param aad_len length of additional authenticated data (in bytes).
|
||||
* \param tag output buffer for the authentication tag.
|
||||
* \param ichacha implementation of ChaCha20.
|
||||
* \param encrypt non-zero for encryption, zero for decryption.
|
||||
*/
|
||||
void br_poly1305_ctmul_run(const void *key, const void *iv,
|
||||
void *data, size_t len, const void *aad, size_t aad_len,
|
||||
void *tag, br_chacha20_run ichacha, int encrypt);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
@ -857,10 +959,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;
|
||||
|
|
@ -1150,6 +1256,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 +1314,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 +3113,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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue