Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to BearSSL 0.6+ release, add AES_CCM modes #5164

Merged
merged 9 commits into from
Sep 28, 2018
31 changes: 30 additions & 1 deletion libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,37 @@ extern "C" {

// Some constants uses to init the server/client contexts
// Note that suites_P needs to be copied to RAM before use w/BearSSL!
// List copied verbatim from BearSSL/ssl_client_full.c
/*
* The "full" profile supports all implemented cipher suites.
*
* Rationale for suite order, from most important to least
* important rule:
*
* -- Don't use 3DES if AES or ChaCha20 is available.
* -- Try to have Forward Secrecy (ECDHE suite) if possible.
* -- When not using Forward Secrecy, ECDH key exchange is
* better than RSA key exchange (slightly more expensive on the
* client, but much cheaper on the server, and it implies smaller
* messages).
* -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller code).
* -- GCM is better than CCM and CBC. CCM is better than CBC.
* -- CCM is preferable over CCM_8 (with CCM_8, forgeries may succeed
* with probability 2^(-64)).
* -- AES-128 is preferred over AES-256 (AES-128 is already
* strong enough, and AES-256 is 40% more expensive).
*/
static const uint16_t suites_P[] PROGMEM = {
BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
Expand All @@ -677,6 +701,10 @@ extern "C" {
BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
BR_TLS_RSA_WITH_AES_128_GCM_SHA256,
BR_TLS_RSA_WITH_AES_256_GCM_SHA384,
BR_TLS_RSA_WITH_AES_128_CCM,
BR_TLS_RSA_WITH_AES_256_CCM,
BR_TLS_RSA_WITH_AES_128_CCM_8,
BR_TLS_RSA_WITH_AES_256_CCM_8,
BR_TLS_RSA_WITH_AES_128_CBC_SHA256,
BR_TLS_RSA_WITH_AES_256_CBC_SHA256,
BR_TLS_RSA_WITH_AES_128_CBC_SHA,
Expand Down Expand Up @@ -730,6 +758,7 @@ extern "C" {
br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf);
br_ssl_engine_set_default_aes_cbc(&cc->eng);
br_ssl_engine_set_default_aes_gcm(&cc->eng);
br_ssl_engine_set_default_aes_ccm(&cc->eng);
br_ssl_engine_set_default_des_cbc(&cc->eng);
br_ssl_engine_set_default_chapol(&cc->eng);
}
Expand Down Expand Up @@ -819,7 +848,7 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {

// If no cipher list yet set, use defaults
if (_cipher_list == NULL) {
br_ssl_client_base_init(_sc.get(), suites_P, sizeof(suites_P) / sizeof(uint16_t));
br_ssl_client_base_init(_sc.get(), suites_P, sizeof(suites_P) / sizeof(suites_P[0]));
} else {
br_ssl_client_base_init(_sc.get(), _cipher_list, _cipher_cnt);
}
Expand Down
2 changes: 2 additions & 0 deletions tools/sdk/include/bearssl/bearssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
* | :-------------- | :------------------------------------------------ |
* | bearssl_hash.h | Hash functions |
* | bearssl_hmac.h | HMAC |
* | bearssl_kdf.h | Key Derivation Functions |
* | bearssl_rand.h | Pseudorandom byte generators |
* | bearssl_prf.h | PRF implementations (for SSL/TLS) |
* | bearssl_block.h | Symmetric encryption |
Expand Down Expand Up @@ -125,6 +126,7 @@

#include "bearssl_hash.h"
#include "bearssl_hmac.h"
#include "bearssl_kdf.h"
#include "bearssl_rand.h"
#include "bearssl_prf.h"
#include "bearssl_block.h"
Expand Down
100 changes: 98 additions & 2 deletions tools/sdk/include/bearssl/bearssl_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,24 @@ typedef struct {
#endif
} br_aes_pwr8_ctr_keys;

/**
* \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption
* and decryption + CBC-MAC).
*
* First field is a pointer to the vtable; it is set by the initialisation
* function. Other fields are not supposed to be accessed by user code.
*/
typedef struct {
/** \brief Pointer to vtable for this context. */
const br_block_ctrcbc_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
union {
unsigned char skni[16 * 15];
} skey;
unsigned num_rounds;
#endif
} br_aes_pwr8_ctrcbc_keys;

/**
* \brief Class instance for AES CBC encryption (`aes_pwr8` implementation).
*
Expand Down Expand Up @@ -1947,6 +1965,16 @@ extern const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable;
*/
extern const br_block_ctr_class br_aes_pwr8_ctr_vtable;

/**
* \brief Class instance for AES CTR encryption/decryption + CBC-MAC
* (`aes_pwr8` implementation).
*
* Since this implementation might be omitted from the library, or the
* AES opcode unavailable on the current CPU, a pointer to this class
* instance should be obtained through `br_aes_pwr8_ctrcbc_get_vtable()`.
*/
extern const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable;

/**
* \brief Context initialisation (key schedule) for AES CBC encryption
* (`aes_pwr8` implementation).
Expand Down Expand Up @@ -1980,6 +2008,17 @@ void br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx,
void br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx,
const void *key, size_t len);

/**
* \brief Context initialisation (key schedule) for AES CTR + CBC-MAC
* (`aes_pwr8` implementation).
*
* \param ctx context to initialise.
* \param key secret key.
* \param len secret key length (in bytes).
*/
void br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx,
const void *key, size_t len);

/**
* \brief CBC encryption with AES (`aes_pwr8` implementation).
*
Expand Down Expand Up @@ -2015,6 +2054,52 @@ void br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, void *iv,
uint32_t br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx,
const void *iv, uint32_t cc, void *data, size_t len);

/**
* \brief CTR encryption + CBC-MAC with AES (`aes_pwr8` implementation).
*
* \param ctx context (already initialised).
* \param ctr counter for CTR (16 bytes, updated).
* \param cbcmac IV for CBC-MAC (updated).
* \param data data to encrypt (updated).
* \param len data length (in bytes, MUST be a multiple of 16).
*/
void br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx,
void *ctr, void *cbcmac, void *data, size_t len);

/**
* \brief CTR decryption + CBC-MAC with AES (`aes_pwr8` implementation).
*
* \param ctx context (already initialised).
* \param ctr counter for CTR (16 bytes, updated).
* \param cbcmac IV for CBC-MAC (updated).
* \param data data to decrypt (updated).
* \param len data length (in bytes, MUST be a multiple of 16).
*/
void br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx,
void *ctr, void *cbcmac, void *data, size_t len);

/**
* \brief CTR encryption/decryption with AES (`aes_pwr8` implementation).
*
* \param ctx context (already initialised).
* \param ctr counter for CTR (16 bytes, updated).
* \param data data to MAC (updated).
* \param len data length (in bytes, MUST be a multiple of 16).
*/
void br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx,
void *ctr, void *data, size_t len);

/**
* \brief CBC-MAC with AES (`aes_pwr8` implementation).
*
* \param ctx context (already initialised).
* \param cbcmac IV for CBC-MAC (updated).
* \param data data to MAC (unmodified).
* \param len data length (in bytes, MUST be a multiple of 16).
*/
void br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx,
void *cbcmac, const void *data, size_t len);

/**
* \brief Obtain the `aes_pwr8` AES-CBC (encryption) implementation, if
* available.
Expand Down Expand Up @@ -2053,6 +2138,19 @@ const br_block_cbcdec_class *br_aes_pwr8_cbcdec_get_vtable(void);
*/
const br_block_ctr_class *br_aes_pwr8_ctr_get_vtable(void);

/**
* \brief Obtain the `aes_pwr8` AES-CTR + CBC-MAC implementation, if
* available.
*
* This function returns a pointer to `br_aes_pwr8_ctrcbc_vtable`, if
* that implementation was compiled in the library _and_ the POWER8 AES
* opcodes are available on the currently running CPU. If either of
* these conditions is not met, then this function returns `NULL`.
*
* \return the `aes_pwr8` AES-CTR implementation, or `NULL`.
*/
const br_block_ctrcbc_class *br_aes_pwr8_ctrcbc_get_vtable(void);

/**
* \brief Aggregate structure large enough to be used as context for
* subkeys (CBC encryption) for all AES implementations.
Expand Down Expand Up @@ -2105,10 +2203,8 @@ typedef union {
br_aes_small_ctrcbc_keys c_small;
br_aes_ct_ctrcbc_keys c_ct;
br_aes_ct64_ctrcbc_keys c_ct64;
/* FIXME
br_aes_x86ni_ctrcbc_keys c_x86ni;
br_aes_pwr8_ctrcbc_keys c_pwr8;
*/
} br_aes_gen_ctrcbc_keys;

/*
Expand Down
79 changes: 79 additions & 0 deletions tools/sdk/include/bearssl/bearssl_ec.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <stddef.h>
#include <stdint.h>

#include "bearssl_rand.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -797,6 +799,83 @@ br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void);
*/
br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void);

/**
* \brief Maximum size for EC private key element buffer.
*
* This is the largest number of bytes that `br_ec_keygen()` may need or
* ever return.
*/
#define BR_EC_KBUF_PRIV_MAX_SIZE 72

/**
* \brief Maximum size for EC public key element buffer.
*
* This is the largest number of bytes that `br_ec_compute_public()` may
* need or ever return.
*/
#define BR_EC_KBUF_PUB_MAX_SIZE 145

/**
* \brief Generate a new EC private key.
*
* If the specified `curve` is not supported by the elliptic curve
* implementation (`impl`), then this function returns zero.
*
* The `sk` structure fields are set to the new private key data. In
* particular, `sk.x` is made to point to the provided key buffer (`kbuf`),
* in which the actual private key data is written. That buffer is assumed
* to be large enough. The `BR_EC_KBUF_PRIV_MAX_SIZE` defines the maximum
* size for all supported curves.
*
* The number of bytes used in `kbuf` is returned. If `kbuf` is `NULL`, then
* the private key is not actually generated, and `sk` may also be `NULL`;
* the minimum length for `kbuf` is still computed and returned.
*
* If `sk` is `NULL` but `kbuf` is not `NULL`, then the private key is
* still generated and stored in `kbuf`.
*
* \param rng_ctx source PRNG context (already initialized).
* \param impl the elliptic curve implementation.
* \param sk the private key structure to fill, or `NULL`.
* \param kbuf the key element buffer, or `NULL`.
* \param curve the curve identifier.
* \return the key data length (in bytes), or zero.
*/
size_t br_ec_keygen(const br_prng_class **rng_ctx,
const br_ec_impl *impl, br_ec_private_key *sk,
void *kbuf, int curve);

/**
* \brief Compute EC public key from EC private key.
*
* This function uses the provided elliptic curve implementation (`impl`)
* to compute the public key corresponding to the private key held in `sk`.
* The public key point is written into `kbuf`, which is then linked from
* the `*pk` structure. The size of the public key point, i.e. the number
* of bytes used in `kbuf`, is returned.
*
* If `kbuf` is `NULL`, then the public key point is NOT computed, and
* the public key structure `*pk` is unmodified (`pk` may be `NULL` in
* that case). The size of the public key point is still returned.
*
* If `pk` is `NULL` but `kbuf` is not `NULL`, then the public key
* point is computed and stored in `kbuf`, and its size is returned.
*
* If the curve used by the private key is not supported by the curve
* implementation, then this function returns zero.
*
* The private key MUST be valid. An off-range private key value is not
* necessarily detected, and leads to unpredictable results.
*
* \param impl the elliptic curve implementation.
* \param pk the public key structure to fill (or `NULL`).
* \param kbuf the public key point buffer (or `NULL`).
* \param sk the source private key.
* \return the public key point length (in bytes), or zero.
*/
size_t br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk,
void *kbuf, const br_ec_private_key *sk);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion tools/sdk/include/bearssl/bearssl_git.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Do not edit -- Automatically generated by tools/sdk/ssl/bearssl/Makefile
#define BEARSSL_GIT 6d1cefc
#define BEARSSL_GIT f55a6ad
30 changes: 30 additions & 0 deletions tools/sdk/include/bearssl/bearssl_hmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,21 @@ typedef struct {
void br_hmac_key_init(br_hmac_key_context *kc,
const br_hash_class *digest_vtable, const void *key, size_t key_len);

/*
* \brief Get the underlying hash function.
*
* This function returns a pointer to the implementation vtable of the
* hash function used for this HMAC key context.
*
* \param kc HMAC key context.
* \return the hash function implementation.
*/
static inline const br_hash_class *br_hmac_key_get_digest(
const br_hmac_key_context *kc)
{
return kc->dig_vtable;
}

/**
* \brief HMAC computation context.
*
Expand Down Expand Up @@ -142,6 +157,21 @@ br_hmac_size(br_hmac_context *ctx)
return ctx->out_len;
}

/*
* \brief Get the underlying hash function.
*
* This function returns a pointer to the implementation vtable of the
* hash function used for this HMAC context.
*
* \param hc HMAC context.
* \return the hash function implementation.
*/
static inline const br_hash_class *br_hmac_get_digest(
const br_hmac_context *hc)
{
return hc->dig.vtable;
}

/**
* \brief Inject some bytes in HMAC.
*
Expand Down
Loading