Skip to content

Commit 5137d4d

Browse files
Update to BearSSL 0.6+ release, add AES_CCM modes (#5164)
Pull in latest BearSSL head (0.6 + minor additions) release and add AES_CCM modes to the encryption options. Enable the aes_ccm initialization in client/server The EC mul20 and square20 code was identical in two different files, but because these copies were static, we ended up with an extra 6k of duplicated code. Updated BearSSL to make them shared, saving 6KB.
1 parent 5a5af55 commit 5137d4d

File tree

14 files changed

+1612
-22
lines changed

14 files changed

+1612
-22
lines changed

libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,13 +648,37 @@ extern "C" {
648648

649649
// Some constants uses to init the server/client contexts
650650
// Note that suites_P needs to be copied to RAM before use w/BearSSL!
651+
// List copied verbatim from BearSSL/ssl_client_full.c
652+
/*
653+
* The "full" profile supports all implemented cipher suites.
654+
*
655+
* Rationale for suite order, from most important to least
656+
* important rule:
657+
*
658+
* -- Don't use 3DES if AES or ChaCha20 is available.
659+
* -- Try to have Forward Secrecy (ECDHE suite) if possible.
660+
* -- When not using Forward Secrecy, ECDH key exchange is
661+
* better than RSA key exchange (slightly more expensive on the
662+
* client, but much cheaper on the server, and it implies smaller
663+
* messages).
664+
* -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller code).
665+
* -- GCM is better than CCM and CBC. CCM is better than CBC.
666+
* -- CCM is preferable over CCM_8 (with CCM_8, forgeries may succeed
667+
* with probability 2^(-64)).
668+
* -- AES-128 is preferred over AES-256 (AES-128 is already
669+
* strong enough, and AES-256 is 40% more expensive).
670+
*/
651671
static const uint16_t suites_P[] PROGMEM = {
652672
BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
653673
BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
654674
BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
655675
BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
656676
BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
657677
BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
678+
BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
679+
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
680+
BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
681+
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
658682
BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
659683
BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
660684
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
@@ -677,6 +701,10 @@ extern "C" {
677701
BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
678702
BR_TLS_RSA_WITH_AES_128_GCM_SHA256,
679703
BR_TLS_RSA_WITH_AES_256_GCM_SHA384,
704+
BR_TLS_RSA_WITH_AES_128_CCM,
705+
BR_TLS_RSA_WITH_AES_256_CCM,
706+
BR_TLS_RSA_WITH_AES_128_CCM_8,
707+
BR_TLS_RSA_WITH_AES_256_CCM_8,
680708
BR_TLS_RSA_WITH_AES_128_CBC_SHA256,
681709
BR_TLS_RSA_WITH_AES_256_CBC_SHA256,
682710
BR_TLS_RSA_WITH_AES_128_CBC_SHA,
@@ -730,6 +758,7 @@ extern "C" {
730758
br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf);
731759
br_ssl_engine_set_default_aes_cbc(&cc->eng);
732760
br_ssl_engine_set_default_aes_gcm(&cc->eng);
761+
br_ssl_engine_set_default_aes_ccm(&cc->eng);
733762
br_ssl_engine_set_default_des_cbc(&cc->eng);
734763
br_ssl_engine_set_default_chapol(&cc->eng);
735764
}
@@ -819,7 +848,7 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
819848

820849
// If no cipher list yet set, use defaults
821850
if (_cipher_list == NULL) {
822-
br_ssl_client_base_init(_sc.get(), suites_P, sizeof(suites_P) / sizeof(uint16_t));
851+
br_ssl_client_base_init(_sc.get(), suites_P, sizeof(suites_P) / sizeof(suites_P[0]));
823852
} else {
824853
br_ssl_client_base_init(_sc.get(), _cipher_list, _cipher_cnt);
825854
}

tools/sdk/include/bearssl/bearssl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
* | :-------------- | :------------------------------------------------ |
4040
* | bearssl_hash.h | Hash functions |
4141
* | bearssl_hmac.h | HMAC |
42+
* | bearssl_kdf.h | Key Derivation Functions |
4243
* | bearssl_rand.h | Pseudorandom byte generators |
4344
* | bearssl_prf.h | PRF implementations (for SSL/TLS) |
4445
* | bearssl_block.h | Symmetric encryption |
@@ -125,6 +126,7 @@
125126

126127
#include "bearssl_hash.h"
127128
#include "bearssl_hmac.h"
129+
#include "bearssl_kdf.h"
128130
#include "bearssl_rand.h"
129131
#include "bearssl_prf.h"
130132
#include "bearssl_block.h"

tools/sdk/include/bearssl/bearssl_block.h

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,24 @@ typedef struct {
19191919
#endif
19201920
} br_aes_pwr8_ctr_keys;
19211921

1922+
/**
1923+
* \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption
1924+
* and decryption + CBC-MAC).
1925+
*
1926+
* First field is a pointer to the vtable; it is set by the initialisation
1927+
* function. Other fields are not supposed to be accessed by user code.
1928+
*/
1929+
typedef struct {
1930+
/** \brief Pointer to vtable for this context. */
1931+
const br_block_ctrcbc_class *vtable;
1932+
#ifndef BR_DOXYGEN_IGNORE
1933+
union {
1934+
unsigned char skni[16 * 15];
1935+
} skey;
1936+
unsigned num_rounds;
1937+
#endif
1938+
} br_aes_pwr8_ctrcbc_keys;
1939+
19221940
/**
19231941
* \brief Class instance for AES CBC encryption (`aes_pwr8` implementation).
19241942
*
@@ -1947,6 +1965,16 @@ extern const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable;
19471965
*/
19481966
extern const br_block_ctr_class br_aes_pwr8_ctr_vtable;
19491967

1968+
/**
1969+
* \brief Class instance for AES CTR encryption/decryption + CBC-MAC
1970+
* (`aes_pwr8` implementation).
1971+
*
1972+
* Since this implementation might be omitted from the library, or the
1973+
* AES opcode unavailable on the current CPU, a pointer to this class
1974+
* instance should be obtained through `br_aes_pwr8_ctrcbc_get_vtable()`.
1975+
*/
1976+
extern const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable;
1977+
19501978
/**
19511979
* \brief Context initialisation (key schedule) for AES CBC encryption
19521980
* (`aes_pwr8` implementation).
@@ -1980,6 +2008,17 @@ void br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx,
19802008
void br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx,
19812009
const void *key, size_t len);
19822010

2011+
/**
2012+
* \brief Context initialisation (key schedule) for AES CTR + CBC-MAC
2013+
* (`aes_pwr8` implementation).
2014+
*
2015+
* \param ctx context to initialise.
2016+
* \param key secret key.
2017+
* \param len secret key length (in bytes).
2018+
*/
2019+
void br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx,
2020+
const void *key, size_t len);
2021+
19832022
/**
19842023
* \brief CBC encryption with AES (`aes_pwr8` implementation).
19852024
*
@@ -2015,6 +2054,52 @@ void br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, void *iv,
20152054
uint32_t br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx,
20162055
const void *iv, uint32_t cc, void *data, size_t len);
20172056

2057+
/**
2058+
* \brief CTR encryption + CBC-MAC with AES (`aes_pwr8` implementation).
2059+
*
2060+
* \param ctx context (already initialised).
2061+
* \param ctr counter for CTR (16 bytes, updated).
2062+
* \param cbcmac IV for CBC-MAC (updated).
2063+
* \param data data to encrypt (updated).
2064+
* \param len data length (in bytes, MUST be a multiple of 16).
2065+
*/
2066+
void br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx,
2067+
void *ctr, void *cbcmac, void *data, size_t len);
2068+
2069+
/**
2070+
* \brief CTR decryption + CBC-MAC with AES (`aes_pwr8` implementation).
2071+
*
2072+
* \param ctx context (already initialised).
2073+
* \param ctr counter for CTR (16 bytes, updated).
2074+
* \param cbcmac IV for CBC-MAC (updated).
2075+
* \param data data to decrypt (updated).
2076+
* \param len data length (in bytes, MUST be a multiple of 16).
2077+
*/
2078+
void br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx,
2079+
void *ctr, void *cbcmac, void *data, size_t len);
2080+
2081+
/**
2082+
* \brief CTR encryption/decryption with AES (`aes_pwr8` implementation).
2083+
*
2084+
* \param ctx context (already initialised).
2085+
* \param ctr counter for CTR (16 bytes, updated).
2086+
* \param data data to MAC (updated).
2087+
* \param len data length (in bytes, MUST be a multiple of 16).
2088+
*/
2089+
void br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx,
2090+
void *ctr, void *data, size_t len);
2091+
2092+
/**
2093+
* \brief CBC-MAC with AES (`aes_pwr8` implementation).
2094+
*
2095+
* \param ctx context (already initialised).
2096+
* \param cbcmac IV for CBC-MAC (updated).
2097+
* \param data data to MAC (unmodified).
2098+
* \param len data length (in bytes, MUST be a multiple of 16).
2099+
*/
2100+
void br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx,
2101+
void *cbcmac, const void *data, size_t len);
2102+
20182103
/**
20192104
* \brief Obtain the `aes_pwr8` AES-CBC (encryption) implementation, if
20202105
* available.
@@ -2053,6 +2138,19 @@ const br_block_cbcdec_class *br_aes_pwr8_cbcdec_get_vtable(void);
20532138
*/
20542139
const br_block_ctr_class *br_aes_pwr8_ctr_get_vtable(void);
20552140

2141+
/**
2142+
* \brief Obtain the `aes_pwr8` AES-CTR + CBC-MAC implementation, if
2143+
* available.
2144+
*
2145+
* This function returns a pointer to `br_aes_pwr8_ctrcbc_vtable`, if
2146+
* that implementation was compiled in the library _and_ the POWER8 AES
2147+
* opcodes are available on the currently running CPU. If either of
2148+
* these conditions is not met, then this function returns `NULL`.
2149+
*
2150+
* \return the `aes_pwr8` AES-CTR implementation, or `NULL`.
2151+
*/
2152+
const br_block_ctrcbc_class *br_aes_pwr8_ctrcbc_get_vtable(void);
2153+
20562154
/**
20572155
* \brief Aggregate structure large enough to be used as context for
20582156
* subkeys (CBC encryption) for all AES implementations.
@@ -2105,10 +2203,8 @@ typedef union {
21052203
br_aes_small_ctrcbc_keys c_small;
21062204
br_aes_ct_ctrcbc_keys c_ct;
21072205
br_aes_ct64_ctrcbc_keys c_ct64;
2108-
/* FIXME
21092206
br_aes_x86ni_ctrcbc_keys c_x86ni;
21102207
br_aes_pwr8_ctrcbc_keys c_pwr8;
2111-
*/
21122208
} br_aes_gen_ctrcbc_keys;
21132209

21142210
/*

tools/sdk/include/bearssl/bearssl_ec.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <stddef.h>
2929
#include <stdint.h>
3030

31+
#include "bearssl_rand.h"
32+
3133
#ifdef __cplusplus
3234
extern "C" {
3335
#endif
@@ -797,6 +799,83 @@ br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void);
797799
*/
798800
br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void);
799801

802+
/**
803+
* \brief Maximum size for EC private key element buffer.
804+
*
805+
* This is the largest number of bytes that `br_ec_keygen()` may need or
806+
* ever return.
807+
*/
808+
#define BR_EC_KBUF_PRIV_MAX_SIZE 72
809+
810+
/**
811+
* \brief Maximum size for EC public key element buffer.
812+
*
813+
* This is the largest number of bytes that `br_ec_compute_public()` may
814+
* need or ever return.
815+
*/
816+
#define BR_EC_KBUF_PUB_MAX_SIZE 145
817+
818+
/**
819+
* \brief Generate a new EC private key.
820+
*
821+
* If the specified `curve` is not supported by the elliptic curve
822+
* implementation (`impl`), then this function returns zero.
823+
*
824+
* The `sk` structure fields are set to the new private key data. In
825+
* particular, `sk.x` is made to point to the provided key buffer (`kbuf`),
826+
* in which the actual private key data is written. That buffer is assumed
827+
* to be large enough. The `BR_EC_KBUF_PRIV_MAX_SIZE` defines the maximum
828+
* size for all supported curves.
829+
*
830+
* The number of bytes used in `kbuf` is returned. If `kbuf` is `NULL`, then
831+
* the private key is not actually generated, and `sk` may also be `NULL`;
832+
* the minimum length for `kbuf` is still computed and returned.
833+
*
834+
* If `sk` is `NULL` but `kbuf` is not `NULL`, then the private key is
835+
* still generated and stored in `kbuf`.
836+
*
837+
* \param rng_ctx source PRNG context (already initialized).
838+
* \param impl the elliptic curve implementation.
839+
* \param sk the private key structure to fill, or `NULL`.
840+
* \param kbuf the key element buffer, or `NULL`.
841+
* \param curve the curve identifier.
842+
* \return the key data length (in bytes), or zero.
843+
*/
844+
size_t br_ec_keygen(const br_prng_class **rng_ctx,
845+
const br_ec_impl *impl, br_ec_private_key *sk,
846+
void *kbuf, int curve);
847+
848+
/**
849+
* \brief Compute EC public key from EC private key.
850+
*
851+
* This function uses the provided elliptic curve implementation (`impl`)
852+
* to compute the public key corresponding to the private key held in `sk`.
853+
* The public key point is written into `kbuf`, which is then linked from
854+
* the `*pk` structure. The size of the public key point, i.e. the number
855+
* of bytes used in `kbuf`, is returned.
856+
*
857+
* If `kbuf` is `NULL`, then the public key point is NOT computed, and
858+
* the public key structure `*pk` is unmodified (`pk` may be `NULL` in
859+
* that case). The size of the public key point is still returned.
860+
*
861+
* If `pk` is `NULL` but `kbuf` is not `NULL`, then the public key
862+
* point is computed and stored in `kbuf`, and its size is returned.
863+
*
864+
* If the curve used by the private key is not supported by the curve
865+
* implementation, then this function returns zero.
866+
*
867+
* The private key MUST be valid. An off-range private key value is not
868+
* necessarily detected, and leads to unpredictable results.
869+
*
870+
* \param impl the elliptic curve implementation.
871+
* \param pk the public key structure to fill (or `NULL`).
872+
* \param kbuf the public key point buffer (or `NULL`).
873+
* \param sk the source private key.
874+
* \return the public key point length (in bytes), or zero.
875+
*/
876+
size_t br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk,
877+
void *kbuf, const br_ec_private_key *sk);
878+
800879
#ifdef __cplusplus
801880
}
802881
#endif
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// Do not edit -- Automatically generated by tools/sdk/ssl/bearssl/Makefile
2-
#define BEARSSL_GIT 6d1cefc
2+
#define BEARSSL_GIT f55a6ad

tools/sdk/include/bearssl/bearssl_hmac.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,21 @@ typedef struct {
8484
void br_hmac_key_init(br_hmac_key_context *kc,
8585
const br_hash_class *digest_vtable, const void *key, size_t key_len);
8686

87+
/*
88+
* \brief Get the underlying hash function.
89+
*
90+
* This function returns a pointer to the implementation vtable of the
91+
* hash function used for this HMAC key context.
92+
*
93+
* \param kc HMAC key context.
94+
* \return the hash function implementation.
95+
*/
96+
static inline const br_hash_class *br_hmac_key_get_digest(
97+
const br_hmac_key_context *kc)
98+
{
99+
return kc->dig_vtable;
100+
}
101+
87102
/**
88103
* \brief HMAC computation context.
89104
*
@@ -142,6 +157,21 @@ br_hmac_size(br_hmac_context *ctx)
142157
return ctx->out_len;
143158
}
144159

160+
/*
161+
* \brief Get the underlying hash function.
162+
*
163+
* This function returns a pointer to the implementation vtable of the
164+
* hash function used for this HMAC context.
165+
*
166+
* \param hc HMAC context.
167+
* \return the hash function implementation.
168+
*/
169+
static inline const br_hash_class *br_hmac_get_digest(
170+
const br_hmac_context *hc)
171+
{
172+
return hc->dig.vtable;
173+
}
174+
145175
/**
146176
* \brief Inject some bytes in HMAC.
147177
*

0 commit comments

Comments
 (0)