1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-25 20:02:37 +03:00

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.
This commit is contained in:
Earle F. Philhower, III 2018-09-27 20:30:19 -07:00 committed by GitHub
parent 5a5af55d3a
commit 5137d4da11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1612 additions and 22 deletions

View File

@ -648,6 +648,26 @@ 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,
@ -655,6 +675,10 @@ extern "C" {
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,
@ -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,
@ -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);
}
@ -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);
}

View File

@ -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 |
@ -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"

View File

@ -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).
*
@ -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).
@ -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).
*
@ -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.
@ -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.
@ -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;
/*

View File

@ -28,6 +28,8 @@
#include <stddef.h>
#include <stdint.h>
#include "bearssl_rand.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -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

View File

@ -1,2 +1,2 @@
// Do not edit -- Automatically generated by tools/sdk/ssl/bearssl/Makefile
#define BEARSSL_GIT 6d1cefc
#define BEARSSL_GIT f55a6ad

View File

@ -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.
*
@ -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.
*

View File

@ -0,0 +1,284 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_KDF_H__
#define BR_BEARSSL_KDF_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
#include "bearssl_hmac.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_kdf.h
*
* # Key Derivation Functions
*
* KDF are functions that takes a variable length input, and provide a
* variable length output, meant to be used to derive subkeys from a
* master key.
*
* ## HKDF
*
* HKDF is a KDF defined by [RFC 5869](https://tools.ietf.org/html/rfc5869).
* It is based on HMAC, itself using an underlying hash function. Any
* hash function can be used, as long as it is compatible with the rules
* for the HMAC implementation (i.e. output size is 64 bytes or less, hash
* internal state size is 64 bytes or less, and the internal block length is
* a power of 2 between 16 and 256 bytes). HKDF has two phases:
*
* - HKDF-Extract: the input data in ingested, along with a "salt" value.
*
* - HKDF-Expand: the output is produced, from the result of processing
* the input and salt, and using an extra non-secret parameter called
* "info".
*
* The "salt" and "info" strings are non-secret and can be empty. Their role
* is normally to bind the input and output, respectively, to conventional
* identifiers that qualifu them within the used protocol or application.
*
* The implementation defined in this file uses the following functions:
*
* - `br_hkdf_init()`: initialize an HKDF context, with a hash function,
* and the salt. This starts the HKDF-Extract process.
*
* - `br_hkdf_inject()`: inject more input bytes. This function may be
* called repeatedly if the input data is provided by chunks.
*
* - `br_hkdf_flip()`: end the HKDF-Extract process, and start the
* HKDF-Expand process.
*
* - `br_hkdf_produce()`: get the next bytes of output. This function
* may be called several times to obtain the full output by chunks.
* For correct HKDF processing, the same "info" string must be
* provided for each call.
*
* Note that the HKDF total output size (the number of bytes that
* HKDF-Expand is willing to produce) is limited: if the hash output size
* is _n_ bytes, then the maximum output size is _255*n_.
*
* ## SHAKE
*
* SHAKE is defined in
* [FIPS 202](https://csrc.nist.gov/publications/detail/fips/202/final)
* under two versions: SHAKE128 and SHAKE256, offering an alleged
* "security level" of 128 and 256 bits, respectively (SHAKE128 is
* about 20 to 25% faster than SHAKE256). SHAKE internally relies on
* the Keccak family of sponge functions, not on any externally provided
* hash function. Contrary to HKDF, SHAKE does not have a concept of
* either a "salt" or an "info" string. The API consists in four
* functions:
*
* - `br_shake_init()`: initialize a SHAKE context for a given
* security level.
*
* - `br_shake_inject()`: inject more input bytes. This function may be
* called repeatedly if the input data is provided by chunks.
*
* - `br_shake_flip()`: end the data injection process, and start the
* data production process.
*
* - `br_shake_produce()`: get the next bytes of output. This function
* may be called several times to obtain the full output by chunks.
*/
/**
* \brief HKDF context.
*
* The HKDF context is initialized with a hash function implementation
* and a salt value. Contents are opaque (callers should not access them
* directly). The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
union {
br_hmac_context hmac_ctx;
br_hmac_key_context prk_ctx;
} u;
unsigned char buf[64];
size_t ptr;
size_t dig_len;
unsigned chunk_num;
#endif
} br_hkdf_context;
/**
* \brief HKDF context initialization.
*
* The underlying hash function and salt value are provided. Arbitrary
* salt lengths can be used.
*
* HKDF makes a difference between a salt of length zero, and an
* absent salt (the latter being equivalent to a salt consisting of
* bytes of value zero, of the same length as the hash function output).
* If `salt_len` is zero, then this function assumes that the salt is
* present but of length zero. To specify an _absent_ salt, use
* `BR_HKDF_NO_SALT` as `salt` parameter (`salt_len` is then ignored).
*
* \param hc HKDF context to initialise.
* \param digest_vtable pointer to the hash function implementation vtable.
* \param salt HKDF-Extract salt.
* \param salt_len HKDF-Extract salt length (in bytes).
*/
void br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable,
const void *salt, size_t salt_len);
/**
* \brief The special "absent salt" value for HKDF.
*/
#define BR_HKDF_NO_SALT (&br_hkdf_no_salt)
#ifndef BR_DOXYGEN_IGNORE
extern const unsigned char br_hkdf_no_salt;
#endif
/**
* \brief HKDF input injection (HKDF-Extract).
*
* This function injects some more input bytes ("key material") into
* HKDF. This function may be called several times, after `br_hkdf_init()`
* but before `br_hkdf_flip()`.
*
* \param hc HKDF context.
* \param ikm extra input bytes.
* \param ikm_len number of extra input bytes.
*/
void br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len);
/**
* \brief HKDF switch to the HKDF-Expand phase.
*
* This call terminates the HKDF-Extract process (input injection), and
* starts the HKDF-Expand process (output production).
*
* \param hc HKDF context.
*/
void br_hkdf_flip(br_hkdf_context *hc);
/**
* \brief HKDF output production (HKDF-Expand).
*
* Produce more output bytes from the current state. This function may be
* called several times, but only after `br_hkdf_flip()`.
*
* Returned value is the number of actually produced bytes. The total
* output length is limited to 255 times the output length of the
* underlying hash function.
*
* \param hc HKDF context.
* \param info application specific information string.
* \param info_len application specific information string length (in bytes).
* \param out destination buffer for the HKDF output.
* \param out_len the length of the requested output (in bytes).
* \return the produced output length (in bytes).
*/
size_t br_hkdf_produce(br_hkdf_context *hc,
const void *info, size_t info_len, void *out, size_t out_len);
/**
* \brief SHAKE context.
*
* The HKDF context is initialized with a "security level". The internal
* notion is called "capacity"; the capacity is twice the security level
* (for instance, SHAKE128 has capacity 256).
*
* The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
unsigned char dbuf[200];
size_t dptr;
size_t rate;
uint64_t A[25];
#endif
} br_shake_context;
/**
* \brief SHAKE context initialization.
*
* The context is initialized for the provided "security level".
* Internally, this sets the "capacity" to twice the security level;
* thus, for SHAKE128, the `security_level` parameter should be 128,
* which corresponds to a 256-bit capacity.
*
* Allowed security levels are all multiples of 32, from 32 to 768,
* inclusive. Larger security levels imply lower performance; levels
* beyond 256 bits don't make much sense. Standard levels are 128
* and 256 bits (for SHAKE128 and SHAKE256, respectively).
*
* \param sc SHAKE context to initialise.
* \param security_level security level (in bits).
*/
void br_shake_init(br_shake_context *sc, int security_level);
/**
* \brief SHAKE input injection.
*
* This function injects some more input bytes ("key material") into
* SHAKE. This function may be called several times, after `br_shake_init()`
* but before `br_shake_flip()`.
*
* \param sc SHAKE context.
* \param data extra input bytes.
* \param len number of extra input bytes.
*/
void br_shake_inject(br_shake_context *sc, const void *data, size_t len);
/**
* \brief SHAKE switch to production phase.
*
* This call terminates the input injection process, and starts the
* output production process.
*
* \param sc SHAKE context.
*/
void br_shake_flip(br_shake_context *hc);
/**
* \brief SHAKE output production.
*
* Produce more output bytes from the current state. This function may be
* called several times, but only after `br_shake_flip()`.
*
* There is no practical limit to the number of bytes that may be produced.
*
* \param sc SHAKE context.
* \param out destination buffer for the SHAKE output.
* \param len the length of the requested output (in bytes).
*/
void br_shake_produce(br_shake_context *sc, void *out, size_t len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -236,6 +236,57 @@ br_pem_decoder_name(br_pem_decoder_context *ctx)
return ctx->name;
}
/**
* \brief Encode an object in PEM.
*
* This function encodes the provided binary object (`data`, of length `len`
* bytes) into PEM. The `banner` text will be included in the header and
* footer (e.g. use `"CERTIFICATE"` to get a `"BEGIN CERTIFICATE"` header).
*
* The length (in characters) of the PEM output is returned; that length
* does NOT include the terminating zero, that this function nevertheless
* adds. If using the returned value for allocation purposes, the allocated
* buffer size MUST be at least one byte larger than the returned size.
*
* If `dest` is `NULL`, then the encoding does not happen; however, the
* length of the encoded object is still computed and returned.
*
* The `data` pointer may be `NULL` only if `len` is zero (when encoding
* an object of length zero, which is not very useful), or when `dest`
* is `NULL` (in that case, source data bytes are ignored).
*
* Some `flags` can be specified to alter the encoding behaviour:
*
* - If `BR_PEM_LINE64` is set, then line-breaking will occur after
* every 64 characters of output, instead of the default of 76.
*
* - If `BR_PEM_CRLF` is set, then end-of-line sequence will use
* CR+LF instead of a single LF.
*
* The `data` and `dest` buffers may overlap, in which case the source
* binary data is destroyed in the process. Note that the PEM-encoded output
* is always larger than the source binary.
*
* \param dest the destination buffer (or `NULL`).
* \param data the source buffer (can be `NULL` in some cases).
* \param len the source length (in bytes).
* \param banner the PEM banner expression.
* \param flags the behavioural flags.
* \return the PEM object length (in characters), EXCLUDING the final zero.
*/
size_t br_pem_encode(void *dest, const void *data, size_t len,
const char *banner, unsigned flags);
/**
* \brief PEM encoding flag: split lines at 64 characters.
*/
#define BR_PEM_LINE64 0x0001
/**
* \brief PEM encoding flag: use CR+LF line endings.
*/
#define BR_PEM_CRLF 0x0002
#ifdef __cplusplus
}
#endif

View File

@ -28,6 +28,9 @@
#include <stddef.h>
#include <stdint.h>
#include "bearssl_block.h"
#include "bearssl_hash.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -93,6 +96,32 @@ extern "C" {
* no currently known security penalty for exceeding the NIST limits,
* and, in any case, HMAC_DRBG usage in implementing SSL/TLS always
* stays much below these thresholds.
*
*
* ## AESCTR_DRBG
*
* AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is
* meant to be used only in situations where you are desperate for
* speed, and have an hardware-optimized AES/CTR implementation. Whether
* this will yield perceptible improvements depends on what you use the
* pseudorandom bytes for, and how many you want; for instance, RSA key
* pair generation uses a substantial amount of randomness, and using
* AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key
* generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz).
*
* Internally, it uses CTR mode with successive counter values, starting
* at zero (counter value expressed over 128 bits, big-endian convention).
* The counter is not allowed to reach 32768; thus, every 32768*16 bytes
* at most, the `update()` function is run (on an empty seed, if none is
* provided). The `update()` function computes the new AES-128 key by
* applying a custom hash function to the concatenation of a state-dependent
* word (encryption of an all-one block with the current key) and the new
* seed. The custom hash function uses Hirose's construction over AES-256;
* see the comments in `aesctr_drbg.c` for details.
*
* This DRBG does not follow an existing standard, and thus should be
* considered as inadequate for production use until it has been properly
* analysed.
*/
/**
@ -288,6 +317,79 @@ typedef int (*br_prng_seeder)(const br_prng_class **ctx);
*/
br_prng_seeder br_prng_seeder_system(const char **name);
/**
* \brief Context for AESCTR_DRBG.
*
* The context contents are opaque, except the first field, which
* supports OOP.
*/
typedef struct {
/**
* \brief Pointer to the vtable.
*
* This field is set with the initialisation method/function.
*/
const br_prng_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
br_aes_gen_ctr_keys sk;
uint32_t cc;
#endif
} br_aesctr_drbg_context;
/**
* \brief Statically allocated, constant vtable for AESCTR_DRBG.
*/
extern const br_prng_class br_aesctr_drbg_vtable;
/**
* \brief AESCTR_DRBG initialisation.
*
* The context to initialise is provided as a pointer to its first field
* (the vtable pointer); this function sets that first field to a
* pointer to the vtable.
*
* The internal AES key is first set to the all-zero key; then, the
* `br_aesctr_drbg_update()` function is called with the provided `seed`.
* The call is performed even if the seed length (`seed_len`) is zero.
*
* The `aesctr` parameter defines the underlying AES/CTR implementation.
*
* \param ctx AESCTR_DRBG context to initialise.
* \param aesctr vtable for the AES/CTR implementation.
* \param seed initial seed (can be `NULL` if `seed_len` is zero).
* \param seed_len initial seed length (in bytes).
*/
void br_aesctr_drbg_init(br_aesctr_drbg_context *ctx,
const br_block_ctr_class *aesctr, const void *seed, size_t seed_len);
/**
* \brief Random bytes generation with AESCTR_DRBG.
*
* This method produces `len` pseudorandom bytes, in the `out`
* buffer. The context is updated accordingly.
*
* \param ctx AESCTR_DRBG context.
* \param out output buffer.
* \param len number of pseudorandom bytes to produce.
*/
void br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx,
void *out, size_t len);
/**
* \brief Inject additional seed bytes in AESCTR_DRBG.
*
* The provided seed bytes are added into the AESCTR_DRBG internal
* entropy pool. The process does not _replace_ existing entropy,
* thus pushing non-random bytes (i.e. bytes which are known to the
* attackers) does not degrade the overall quality of generated bytes.
*
* \param ctx AESCTR_DRBG context.
* \param seed additional seed.
* \param seed_len additional seed length (in bytes).
*/
void br_aesctr_drbg_update(br_aesctr_drbg_context *ctx,
const void *seed, size_t seed_len);
#ifdef __cplusplus
}
#endif

View File

@ -28,6 +28,9 @@
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
#include "bearssl_rand.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -84,7 +87,7 @@ extern "C" {
* random masking, but "true" constant-time code.
*
* - They support only private keys with two prime factors. RSA private
* key with three or more prime factors are nominally supported, but
* keys with three or more prime factors are nominally supported, but
* rarely used; they may offer faster operations, at the expense of
* more code and potentially a reduction in security if there are
* "too many" prime factors.
@ -92,7 +95,7 @@ extern "C" {
* - The public exponent may have arbitrary length. Of course, it is
* a good idea to keep public exponents small, so that public key
* operations are fast; but, contrary to some widely deployed
* implementations, BearSSL has no problem with public exponent
* implementations, BearSSL has no problem with public exponents
* longer than 32 bits.
*
* - The two prime factors of the modulus need not have the same length
@ -170,7 +173,7 @@ typedef struct {
/**
* \brief RSA private key.
*
* The structure references the primvate factors, reduced private
* The structure references the private factors, reduced private
* exponents, and CRT coefficient. It also contains the bit length of
* the modulus. The big integers use unsigned big-endian representation;
* extra leading bytes of value 0 are allowed. However, the modulus bit
@ -277,6 +280,55 @@ typedef uint32_t (*br_rsa_pkcs1_vrfy)(const unsigned char *x, size_t xlen,
const unsigned char *hash_oid, size_t hash_len,
const br_rsa_public_key *pk, unsigned char *hash_out);
/**
* \brief Type for a RSA signature verification engine (PSS).
*
* Parameters are:
*
* - The signature itself. The provided array is NOT modified.
*
* - The hash function which was used to hash the message.
*
* - The hash function to use with MGF1 within the PSS padding. This
* is not necessarily the same hash function as the one which was
* used to hash the signed message.
*
* - The hashed message (as an array of bytes).
*
* - The PSS salt length (in bytes).
*
* - The public key.
*
* **Constraints:**
*
* - Hash message length MUST be no more than 64 bytes.
*
* Note that, contrary to PKCS#1 v1.5 signature, the hash value of the
* signed data cannot be extracted from the signature; it must be
* provided to the verification function.
*
* This function verifies that the signature length (`xlen`) matches the
* modulus length (this function returns 0 on mismatch). If the modulus
* size exceeds the maximum supported RSA size, then the function also
* returns 0.
*
* Returned value is 1 on success, 0 on error.
*
* Implementations of this type need not be constant-time.
*
* \param x signature buffer.
* \param xlen signature length (in bytes).
* \param hf_data hash function applied on the message.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hash value of the signed message.
* \param salt_len PSS salt length (in bytes).
* \param pk RSA public key.
* \return 1 on success, 0 on error.
*/
typedef uint32_t (*br_rsa_pss_vrfy)(const unsigned char *x, size_t xlen,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const void *hash, size_t salt_len, const br_rsa_public_key *pk);
/**
* \brief Type for a RSA encryption engine (OAEP).
*
@ -383,6 +435,53 @@ typedef uint32_t (*br_rsa_pkcs1_sign)(const unsigned char *hash_oid,
const unsigned char *hash, size_t hash_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief Type for a RSA signature generation engine (PSS).
*
* Parameters are:
*
* - An initialized PRNG for salt generation. If the salt length is
* zero (`salt_len` parameter), then the PRNG is optional (this is
* not the typical case, as the security proof of RSA/PSS is
* tighter when a non-empty salt is used).
*
* - The hash function which was used to hash the message.
*
* - The hash function to use with MGF1 within the PSS padding. This
* is not necessarily the same function as the one used to hash the
* message.
*
* - The hashed message.
*
* - The salt length, in bytes.
*
* - The RSA private key.
*
* - The output buffer, that receives the signature.
*
* Returned value is 1 on success, 0 on error. Error conditions include
* a too small modulus for the provided hash and salt lengths, or some
* invalid key parameters. The signature length is exactly
* `(sk->n_bitlen+7)/8` bytes.
*
* This function is expected to be constant-time with regards to the
* private key bytes (lengths of the modulus and the individual factors
* may leak, though) and to the hashed data.
*
* \param rng PRNG for salt generation (`NULL` if `salt_len` is zero).
* \param hf_data hash function used to hash the signed data.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hashed message.
* \param salt_len salt length (in bytes).
* \param sk RSA private key.
* \param x output buffer for the signature value.
* \return 1 on success, 0 on error.
*/
typedef uint32_t (*br_rsa_pss_sign)(const br_prng_class **rng,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const unsigned char *hash_value, size_t salt_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief Encoded OID for SHA-1 (in RSA PKCS#1 signatures).
*/
@ -474,7 +573,7 @@ uint32_t br_rsa_i32_public(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
/**
* \brief RSA signature verification engine "i32".
* \brief RSA signature verification engine "i32" (PKCS#1 v1.5 signatures).
*
* \see br_rsa_pkcs1_vrfy
*
@ -490,6 +589,24 @@ uint32_t br_rsa_i32_pkcs1_vrfy(const unsigned char *x, size_t xlen,
const unsigned char *hash_oid, size_t hash_len,
const br_rsa_public_key *pk, unsigned char *hash_out);
/**
* \brief RSA signature verification engine "i32" (PSS signatures).
*
* \see br_rsa_pss_vrfy
*
* \param x signature buffer.
* \param xlen signature length (in bytes).
* \param hf_data hash function applied on the message.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hash value of the signed message.
* \param salt_len PSS salt length (in bytes).
* \param pk RSA public key.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i32_pss_vrfy(const unsigned char *x, size_t xlen,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const void *hash, size_t salt_len, const br_rsa_public_key *pk);
/**
* \brief RSA private key engine "i32".
*
@ -503,7 +620,7 @@ uint32_t br_rsa_i32_private(unsigned char *x,
const br_rsa_private_key *sk);
/**
* \brief RSA signature generation engine "i32".
* \brief RSA signature generation engine "i32" (PKCS#1 v1.5 signatures).
*
* \see br_rsa_pkcs1_sign
*
@ -518,6 +635,25 @@ uint32_t br_rsa_i32_pkcs1_sign(const unsigned char *hash_oid,
const unsigned char *hash, size_t hash_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief RSA signature generation engine "i32" (PSS signatures).
*
* \see br_rsa_pss_sign
*
* \param rng PRNG for salt generation (`NULL` if `salt_len` is zero).
* \param hf_data hash function used to hash the signed data.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hashed message.
* \param salt_len salt length (in bytes).
* \param sk RSA private key.
* \param x output buffer for the signature value.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i32_pss_sign(const br_prng_class **rng,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const unsigned char *hash_value, size_t salt_len,
const br_rsa_private_key *sk, unsigned char *x);
/*
* RSA "i31" engine. Similar to i32, but only 31 bits are used per 32-bit
* word. This uses slightly more stack space (about 4% more) and code
@ -538,7 +674,7 @@ uint32_t br_rsa_i31_public(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
/**
* \brief RSA signature verification engine "i31".
* \brief RSA signature verification engine "i31" (PKCS#1 v1.5 signatures).
*
* \see br_rsa_pkcs1_vrfy
*
@ -554,6 +690,24 @@ uint32_t br_rsa_i31_pkcs1_vrfy(const unsigned char *x, size_t xlen,
const unsigned char *hash_oid, size_t hash_len,
const br_rsa_public_key *pk, unsigned char *hash_out);
/**
* \brief RSA signature verification engine "i31" (PSS signatures).
*
* \see br_rsa_pss_vrfy
*
* \param x signature buffer.
* \param xlen signature length (in bytes).
* \param hf_data hash function applied on the message.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hash value of the signed message.
* \param salt_len PSS salt length (in bytes).
* \param pk RSA public key.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i31_pss_vrfy(const unsigned char *x, size_t xlen,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const void *hash, size_t salt_len, const br_rsa_public_key *pk);
/**
* \brief RSA private key engine "i31".
*
@ -567,7 +721,7 @@ uint32_t br_rsa_i31_private(unsigned char *x,
const br_rsa_private_key *sk);
/**
* \brief RSA signature generation engine "i31".
* \brief RSA signature generation engine "i31" (PKCS#1 v1.5 signatures).
*
* \see br_rsa_pkcs1_sign
*
@ -582,6 +736,25 @@ uint32_t br_rsa_i31_pkcs1_sign(const unsigned char *hash_oid,
const unsigned char *hash, size_t hash_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief RSA signature generation engine "i31" (PSS signatures).
*
* \see br_rsa_pss_sign
*
* \param rng PRNG for salt generation (`NULL` if `salt_len` is zero).
* \param hf_data hash function used to hash the signed data.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hashed message.
* \param salt_len salt length (in bytes).
* \param sk RSA private key.
* \param x output buffer for the signature value.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i31_pss_sign(const br_prng_class **rng,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const unsigned char *hash_value, size_t salt_len,
const br_rsa_private_key *sk, unsigned char *x);
/*
* RSA "i62" engine. Similar to i31, but internal multiplication use
* 64x64->128 multiplications. This is available only on architecture
@ -606,7 +779,7 @@ uint32_t br_rsa_i62_public(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
/**
* \brief RSA signature verification engine "i62".
* \brief RSA signature verification engine "i62" (PKCS#1 v1.5 signatures).
*
* This function is defined only on architecture that offer a 64x64->128
* opcode. Use `br_rsa_i62_pkcs1_vrfy_get()` to dynamically obtain a pointer
@ -626,6 +799,28 @@ uint32_t br_rsa_i62_pkcs1_vrfy(const unsigned char *x, size_t xlen,
const unsigned char *hash_oid, size_t hash_len,
const br_rsa_public_key *pk, unsigned char *hash_out);
/**
* \brief RSA signature verification engine "i62" (PSS signatures).
*
* This function is defined only on architecture that offer a 64x64->128
* opcode. Use `br_rsa_i62_pss_vrfy_get()` to dynamically obtain a pointer
* to that function.
*
* \see br_rsa_pss_vrfy
*
* \param x signature buffer.
* \param xlen signature length (in bytes).
* \param hf_data hash function applied on the message.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hash value of the signed message.
* \param salt_len PSS salt length (in bytes).
* \param pk RSA public key.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i62_pss_vrfy(const unsigned char *x, size_t xlen,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const void *hash, size_t salt_len, const br_rsa_public_key *pk);
/**
* \brief RSA private key engine "i62".
*
@ -643,7 +838,7 @@ uint32_t br_rsa_i62_private(unsigned char *x,
const br_rsa_private_key *sk);
/**
* \brief RSA signature generation engine "i62".
* \brief RSA signature generation engine "i62" (PKCS#1 v1.5 signatures).
*
* This function is defined only on architecture that offer a 64x64->128
* opcode. Use `br_rsa_i62_pkcs1_sign_get()` to dynamically obtain a pointer
@ -662,6 +857,29 @@ uint32_t br_rsa_i62_pkcs1_sign(const unsigned char *hash_oid,
const unsigned char *hash, size_t hash_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief RSA signature generation engine "i62" (PSS signatures).
*
* This function is defined only on architecture that offer a 64x64->128
* opcode. Use `br_rsa_i62_pss_sign_get()` to dynamically obtain a pointer
* to that function.
*
* \see br_rsa_pss_sign
*
* \param rng PRNG for salt generation (`NULL` if `salt_len` is zero).
* \param hf_data hash function used to hash the signed data.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hashed message.
* \param salt_len salt length (in bytes).
* \param sk RSA private key.
* \param x output buffer for the signature value.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i62_pss_sign(const br_prng_class **rng,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const unsigned char *hash_value, size_t salt_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief Get the RSA "i62" implementation (public key operations),
* if available.
@ -671,13 +889,21 @@ uint32_t br_rsa_i62_pkcs1_sign(const unsigned char *hash_oid,
br_rsa_public br_rsa_i62_public_get(void);
/**
* \brief Get the RSA "i62" implementation (PKCS#1 signature verification),
* \brief Get the RSA "i62" implementation (PKCS#1 v1.5 signature verification),
* if available.
*
* \return the implementation, or 0.
*/
br_rsa_pkcs1_vrfy br_rsa_i62_pkcs1_vrfy_get(void);
/**
* \brief Get the RSA "i62" implementation (PSS signature verification),
* if available.
*
* \return the implementation, or 0.
*/
br_rsa_pss_vrfy br_rsa_i62_pss_vrfy_get(void);
/**
* \brief Get the RSA "i62" implementation (private key operations),
* if available.
@ -687,13 +913,21 @@ br_rsa_pkcs1_vrfy br_rsa_i62_pkcs1_vrfy_get(void);
br_rsa_private br_rsa_i62_private_get(void);
/**
* \brief Get the RSA "i62" implementation (PKCS#1 signature generation),
* \brief Get the RSA "i62" implementation (PKCS#1 v1.5 signature generation),
* if available.
*
* \return the implementation, or 0.
*/
br_rsa_pkcs1_sign br_rsa_i62_pkcs1_sign_get(void);
/**
* \brief Get the RSA "i62" implementation (PSS signature generation),
* if available.
*
* \return the implementation, or 0.
*/
br_rsa_pss_sign br_rsa_i62_pss_sign_get(void);
/**
* \brief Get the RSA "i62" implementation (OAEP encryption),
* if available.
@ -730,7 +964,7 @@ uint32_t br_rsa_i15_public(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
/**
* \brief RSA signature verification engine "i15".
* \brief RSA signature verification engine "i15" (PKCS#1 v1.5 signatures).
*
* \see br_rsa_pkcs1_vrfy
*
@ -746,6 +980,24 @@ uint32_t br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen,
const unsigned char *hash_oid, size_t hash_len,
const br_rsa_public_key *pk, unsigned char *hash_out);
/**
* \brief RSA signature verification engine "i15" (PSS signatures).
*
* \see br_rsa_pss_vrfy
*
* \param x signature buffer.
* \param xlen signature length (in bytes).
* \param hf_data hash function applied on the message.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hash value of the signed message.
* \param salt_len PSS salt length (in bytes).
* \param pk RSA public key.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i15_pss_vrfy(const unsigned char *x, size_t xlen,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const void *hash, size_t salt_len, const br_rsa_public_key *pk);
/**
* \brief RSA private key engine "i15".
*
@ -759,7 +1011,7 @@ uint32_t br_rsa_i15_private(unsigned char *x,
const br_rsa_private_key *sk);
/**
* \brief RSA signature generation engine "i15".
* \brief RSA signature generation engine "i15" (PKCS#1 v1.5 signatures).
*
* \see br_rsa_pkcs1_sign
*
@ -774,6 +1026,25 @@ uint32_t br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid,
const unsigned char *hash, size_t hash_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief RSA signature generation engine "i15" (PSS signatures).
*
* \see br_rsa_pss_sign
*
* \param rng PRNG for salt generation (`NULL` if `salt_len` is zero).
* \param hf_data hash function used to hash the signed data.
* \param hf_mgf1 hash function to use with MGF1.
* \param hash hashed message.
* \param salt_len salt length (in bytes).
* \param sk RSA private key.
* \param x output buffer for the signature value.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i15_pss_sign(const br_prng_class **rng,
const br_hash_class *hf_data, const br_hash_class *hf_mgf1,
const unsigned char *hash_value, size_t salt_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief Get "default" RSA implementation (public-key operations).
*
@ -795,7 +1066,7 @@ br_rsa_public br_rsa_public_get_default(void);
br_rsa_private br_rsa_private_get_default(void);
/**
* \brief Get "default" RSA implementation (PKCS#1 signature verification).
* \brief Get "default" RSA implementation (PKCS#1 v1.5 signature verification).
*
* This returns the preferred implementation of RSA (signature verification)
* on the current system.
@ -805,7 +1076,17 @@ br_rsa_private br_rsa_private_get_default(void);
br_rsa_pkcs1_vrfy br_rsa_pkcs1_vrfy_get_default(void);
/**
* \brief Get "default" RSA implementation (PKCS#1 signature generation).
* \brief Get "default" RSA implementation (PSS signature verification).
*
* This returns the preferred implementation of RSA (signature verification)
* on the current system.
*
* \return the default implementation.
*/
br_rsa_pss_vrfy br_rsa_pss_vrfy_get_default(void);
/**
* \brief Get "default" RSA implementation (PKCS#1 v1.5 signature generation).
*
* This returns the preferred implementation of RSA (signature generation)
* on the current system.
@ -814,6 +1095,16 @@ br_rsa_pkcs1_vrfy br_rsa_pkcs1_vrfy_get_default(void);
*/
br_rsa_pkcs1_sign br_rsa_pkcs1_sign_get_default(void);
/**
* \brief Get "default" RSA implementation (PSS signature generation).
*
* This returns the preferred implementation of RSA (signature generation)
* on the current system.
*
* \return the default implementation.
*/
br_rsa_pss_sign br_rsa_pss_sign_get_default(void);
/**
* \brief Get "default" RSA implementation (OAEP encryption).
*
@ -1032,6 +1323,331 @@ uint32_t br_rsa_i62_oaep_decrypt(
const br_hash_class *dig, const void *label, size_t label_len,
const br_rsa_private_key *sk, void *data, size_t *len);
/**
* \brief Get buffer size to hold RSA private key elements.
*
* This macro returns the length (in bytes) of the buffer needed to
* receive the elements of a RSA private key, as generated by one of
* the `br_rsa_*_keygen()` functions. If the provided size is a constant
* expression, then the whole macro evaluates to a constant expression.
*
* \param size target key size (modulus size, in bits)
* \return the length of the private key buffer, in bytes.
*/
#define BR_RSA_KBUF_PRIV_SIZE(size) (5 * (((size) + 15) >> 4))
/**
* \brief Get buffer size to hold RSA public key elements.
*
* This macro returns the length (in bytes) of the buffer needed to
* receive the elements of a RSA public key, as generated by one of
* the `br_rsa_*_keygen()` functions. If the provided size is a constant
* expression, then the whole macro evaluates to a constant expression.
*
* \param size target key size (modulus size, in bits)
* \return the length of the public key buffer, in bytes.
*/
#define BR_RSA_KBUF_PUB_SIZE(size) (4 + (((size) + 7) >> 3))
/**
* \brief Type for RSA key pair generator implementation.
*
* This function generates a new RSA key pair whose modulus has bit
* length `size` bits. The private key elements are written in the
* `kbuf_priv` buffer, and pointer values and length fields to these
* elements are populated in the provided private key structure `sk`.
* Similarly, the public key elements are written in `kbuf_pub`, with
* pointers and lengths set in `pk`.
*
* If `pk` is `NULL`, then `kbuf_pub` may be `NULL`, and only the
* private key is set.
*
* If `pubexp` is not zero, then its value will be used as public
* exponent. Valid RSA public exponent values are odd integers
* greater than 1. If `pubexp` is zero, then the public exponent will
* have value 3.
*
* The provided PRNG (`rng_ctx`) must have already been initialized
* and seeded.
*
* Returned value is 1 on success, 0 on error. An error is reported
* if the requested range is outside of the supported key sizes, or
* if an invalid non-zero public exponent value is provided. Supported
* range starts at 512 bits, and up to an implementation-defined
* maximum (by default 4096 bits). Note that key sizes up to 768 bits
* have been broken in practice, and sizes lower than 2048 bits are
* usually considered to be weak and should not be used.
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
typedef uint32_t (*br_rsa_keygen)(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief RSA key pair generation with the "i15" engine.
*
* \see br_rsa_keygen
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
uint32_t br_rsa_i15_keygen(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief RSA key pair generation with the "i31" engine.
*
* \see br_rsa_keygen
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
uint32_t br_rsa_i31_keygen(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief RSA key pair generation with the "i62" engine.
*
* This function is defined only on architecture that offer a 64x64->128
* opcode. Use `br_rsa_i62_keygen_get()` to dynamically obtain a pointer
* to that function.
*
* \see br_rsa_keygen
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
uint32_t br_rsa_i62_keygen(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief Get the RSA "i62" implementation (key pair generation),
* if available.
*
* \return the implementation, or 0.
*/
br_rsa_keygen br_rsa_i62_keygen_get(void);
/**
* \brief Get "default" RSA implementation (key pair generation).
*
* This returns the preferred implementation of RSA (key pair generation)
* on the current system.
*
* \return the default implementation.
*/
br_rsa_keygen br_rsa_keygen_get_default(void);
/**
* \brief Type for a modulus computing function.
*
* Such a function computes the public modulus from the private key. The
* encoded modulus (unsigned big-endian) is written on `n`, and the size
* (in bytes) is returned. If `n` is `NULL`, then the size is returned but
* the modulus itself is not computed.
*
* If the key size exceeds an internal limit, 0 is returned.
*
* \param n destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the modulus length (in bytes), or 0.
*/
typedef size_t (*br_rsa_compute_modulus)(void *n, const br_rsa_private_key *sk);
/**
* \brief Recompute RSA modulus ("i15" engine).
*
* \see br_rsa_compute_modulus
*
* \param n destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the modulus length (in bytes), or 0.
*/
size_t br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk);
/**
* \brief Recompute RSA modulus ("i31" engine).
*
* \see br_rsa_compute_modulus
*
* \param n destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the modulus length (in bytes), or 0.
*/
size_t br_rsa_i31_compute_modulus(void *n, const br_rsa_private_key *sk);
/**
* \brief Get "default" RSA implementation (recompute modulus).
*
* This returns the preferred implementation of RSA (recompute modulus)
* on the current system.
*
* \return the default implementation.
*/
br_rsa_compute_modulus br_rsa_compute_modulus_get_default(void);
/**
* \brief Type for a public exponent computing function.
*
* Such a function recomputes the public exponent from the private key.
* 0 is returned if any of the following occurs:
*
* - Either `p` or `q` is not equal to 3 modulo 4.
*
* - The public exponent does not fit on 32 bits.
*
* - An internal limit is exceeded.
*
* - The private key is invalid in some way.
*
* For all private keys produced by the key generator functions
* (`br_rsa_keygen` type), this function succeeds and returns the true
* public exponent. The public exponent is always an odd integer greater
* than 1.
*
* \return the public exponent, or 0.
*/
typedef uint32_t (*br_rsa_compute_pubexp)(const br_rsa_private_key *sk);
/**
* \brief Recompute RSA public exponent ("i15" engine).
*
* \see br_rsa_compute_pubexp
*
* \return the public exponent, or 0.
*/
uint32_t br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk);
/**
* \brief Recompute RSA public exponent ("i31" engine).
*
* \see br_rsa_compute_pubexp
*
* \return the public exponent, or 0.
*/
uint32_t br_rsa_i31_compute_pubexp(const br_rsa_private_key *sk);
/**
* \brief Get "default" RSA implementation (recompute public exponent).
*
* This returns the preferred implementation of RSA (recompute public
* exponent) on the current system.
*
* \return the default implementation.
*/
br_rsa_compute_pubexp br_rsa_compute_pubexp_get_default(void);
/**
* \brief Type for a private exponent computing function.
*
* An RSA private key (`br_rsa_private_key`) contains two reduced
* private exponents, which are sufficient to perform private key
* operations. However, standard encoding formats for RSA private keys
* require also a copy of the complete private exponent (non-reduced),
* which this function recomputes.
*
* This function suceeds if all the following conditions hold:
*
* - Both private factors `p` and `q` are equal to 3 modulo 4.
*
* - The provided public exponent `pubexp` is correct, and, in particular,
* is odd, relatively prime to `p-1` and `q-1`, and greater than 1.
*
* - No internal storage limit is exceeded.
*
* For all private keys produced by the key generator functions
* (`br_rsa_keygen` type), this function succeeds. Note that the API
* restricts the public exponent to a maximum size of 32 bits.
*
* The encoded private exponent is written in `d` (unsigned big-endian
* convention), and the length (in bytes) is returned. If `d` is `NULL`,
* then the exponent is not written anywhere, but the length is still
* returned. On error, 0 is returned.
*
* Not all error conditions are detected when `d` is `NULL`; therefore, the
* returned value shall be checked also when actually producing the value.
*
* \param d destination buffer (or `NULL`).
* \param sk RSA private key.
* \param pubexp the public exponent.
* \return the private exponent length (in bytes), or 0.
*/
typedef size_t (*br_rsa_compute_privexp)(void *d,
const br_rsa_private_key *sk, uint32_t pubexp);
/**
* \brief Recompute RSA private exponent ("i15" engine).
*
* \see br_rsa_compute_privexp
*
* \param d destination buffer (or `NULL`).
* \param sk RSA private key.
* \param pubexp the public exponent.
* \return the private exponent length (in bytes), or 0.
*/
size_t br_rsa_i15_compute_privexp(void *d,
const br_rsa_private_key *sk, uint32_t pubexp);
/**
* \brief Recompute RSA private exponent ("i31" engine).
*
* \see br_rsa_compute_privexp
*
* \param d destination buffer (or `NULL`).
* \param sk RSA private key.
* \param pubexp the public exponent.
* \return the private exponent length (in bytes), or 0.
*/
size_t br_rsa_i31_compute_privexp(void *d,
const br_rsa_private_key *sk, uint32_t pubexp);
/**
* \brief Get "default" RSA implementation (recompute private exponent).
*
* This returns the preferred implementation of RSA (recompute private
* exponent) on the current system.
*
* \return the default implementation.
*/
br_rsa_compute_privexp br_rsa_compute_privexp_get_default(void);
#ifdef __cplusplus
}
#endif

View File

@ -700,6 +700,110 @@ extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable;
/* ===================================================================== */
/**
* \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.
*/
@ -718,9 +822,9 @@ typedef struct {
#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
/**
@ -813,6 +917,7 @@ typedef struct {
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;
@ -820,6 +925,7 @@ typedef struct {
br_sslrec_out_cbc_context cbc;
br_sslrec_gcm_context gcm;
br_sslrec_chapol_context chapol;
br_sslrec_ccm_context ccm;
} out;
/*
@ -992,6 +1098,7 @@ typedef struct {
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;
@ -1003,6 +1110,8 @@ typedef struct {
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;
@ -1451,6 +1560,31 @@ br_ssl_engine_set_poly1305(br_ssl_engine_context *cc,
*/
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.
*
@ -1483,6 +1617,22 @@ br_ssl_engine_set_gcm(br_ssl_engine_context *cc,
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.
@ -4090,6 +4240,16 @@ int br_sslio_close(br_sslio_context *cc);
#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

View File

@ -1444,6 +1444,147 @@ br_pkey_decoder_get_ec(const br_pkey_decoder_context *ctx)
}
}
/**
* \brief Encode an RSA private key (raw DER format).
*
* This function encodes the provided key into the "raw" format specified
* in PKCS#1 (RFC 8017, Appendix C, type `RSAPrivateKey`), with DER
* encoding rules.
*
* The key elements are:
*
* - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`)
*
* - `pk`: the public key (`n` and `e`)
*
* - `d` (size: `dlen` bytes): the private exponent
*
* The public key elements, and the private exponent `d`, can be
* recomputed from the private key (see `br_rsa_compute_modulus()`,
* `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`).
*
* If `dest` is not `NULL`, then the encoded key is written at that
* address, and the encoded length (in bytes) is returned. If `dest` is
* `NULL`, then nothing is written, but the encoded length is still
* computed and returned.
*
* \param dest the destination buffer (or `NULL`).
* \param sk the RSA private key.
* \param pk the RSA public key.
* \param d the RSA private exponent.
* \param dlen the RSA private exponent length (in bytes).
* \return the encoded key length (in bytes).
*/
size_t br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk,
const br_rsa_public_key *pk, const void *d, size_t dlen);
/**
* \brief Encode an RSA private key (PKCS#8 DER format).
*
* This function encodes the provided key into the PKCS#8 format
* (RFC 5958, type `OneAsymmetricKey`). It wraps around the "raw DER"
* format for the RSA key, as implemented by `br_encode_rsa_raw_der()`.
*
* The key elements are:
*
* - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`)
*
* - `pk`: the public key (`n` and `e`)
*
* - `d` (size: `dlen` bytes): the private exponent
*
* The public key elements, and the private exponent `d`, can be
* recomputed from the private key (see `br_rsa_compute_modulus()`,
* `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`).
*
* If `dest` is not `NULL`, then the encoded key is written at that
* address, and the encoded length (in bytes) is returned. If `dest` is
* `NULL`, then nothing is written, but the encoded length is still
* computed and returned.
*
* \param dest the destination buffer (or `NULL`).
* \param sk the RSA private key.
* \param pk the RSA public key.
* \param d the RSA private exponent.
* \param dlen the RSA private exponent length (in bytes).
* \return the encoded key length (in bytes).
*/
size_t br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk,
const br_rsa_public_key *pk, const void *d, size_t dlen);
/**
* \brief Encode an EC private key (raw DER format).
*
* This function encodes the provided key into the "raw" format specified
* in RFC 5915 (type `ECPrivateKey`), with DER encoding rules.
*
* The private key is provided in `sk`, the public key being `pk`. If
* `pk` is `NULL`, then the encoded key will not include the public key
* in its `publicKey` field (which is nominally optional).
*
* If `dest` is not `NULL`, then the encoded key is written at that
* address, and the encoded length (in bytes) is returned. If `dest` is
* `NULL`, then nothing is written, but the encoded length is still
* computed and returned.
*
* If the key cannot be encoded (e.g. because there is no known OBJECT
* IDENTIFIER for the used curve), then 0 is returned.
*
* \param dest the destination buffer (or `NULL`).
* \param sk the EC private key.
* \param pk the EC public key (or `NULL`).
* \return the encoded key length (in bytes), or 0.
*/
size_t br_encode_ec_raw_der(void *dest,
const br_ec_private_key *sk, const br_ec_public_key *pk);
/**
* \brief Encode an EC private key (PKCS#8 DER format).
*
* This function encodes the provided key into the PKCS#8 format
* (RFC 5958, type `OneAsymmetricKey`). The curve is identified
* by an OID provided as parameters to the `privateKeyAlgorithm`
* field. The private key value (contents of the `privateKey` field)
* contains the DER encoding of the `ECPrivateKey` type defined in
* RFC 5915, without the `parameters` field (since they would be
* redundant with the information in `privateKeyAlgorithm`).
*
* The private key is provided in `sk`, the public key being `pk`. If
* `pk` is not `NULL`, then the encoded public key is included in the
* `publicKey` field of the private key value (but not in the `publicKey`
* field of the PKCS#8 `OneAsymmetricKey` wrapper).
*
* If `dest` is not `NULL`, then the encoded key is written at that
* address, and the encoded length (in bytes) is returned. If `dest` is
* `NULL`, then nothing is written, but the encoded length is still
* computed and returned.
*
* If the key cannot be encoded (e.g. because there is no known OBJECT
* IDENTIFIER for the used curve), then 0 is returned.
*
* \param dest the destination buffer (or `NULL`).
* \param sk the EC private key.
* \param pk the EC public key (or `NULL`).
* \return the encoded key length (in bytes), or 0.
*/
size_t br_encode_ec_pkcs8_der(void *dest,
const br_ec_private_key *sk, const br_ec_public_key *pk);
/**
* \brief PEM banner for RSA private key (raw).
*/
#define BR_ENCODE_PEM_RSA_RAW "RSA PRIVATE KEY"
/**
* \brief PEM banner for EC private key (raw).
*/
#define BR_ENCODE_PEM_EC_RAW "EC PRIVATE KEY"
/**
* \brief PEM banner for an RSA or EC private key in PKCS#8 format.
*/
#define BR_ENCODE_PEM_PKCS8 "PRIVATE KEY"
#ifdef __cplusplus
}
#endif

Binary file not shown.

@ -1 +1 @@
Subproject commit 6d1cefcf70fcfefb4628047b7376a7147f2130cf
Subproject commit f55a6adabc4175c67d94b1f4e14fa098c1aeb0b5