Initial import.

This commit is contained in:
Thomas Pornin 2016-11-02 19:01:13 -04:00
commit 3210f38e04
292 changed files with 58526 additions and 0 deletions

42
inc/bearssl.h Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016 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_H__
#define BR_BEARSSL_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
#include "bearssl_hmac.h"
#include "bearssl_rand.h"
#include "bearssl_prf.h"
#include "bearssl_block.h"
#include "bearssl_rsa.h"
#include "bearssl_ec.h"
#include "bearssl_ssl.h"
#include "bearssl_x509.h"
#include "bearssl_pem.h"
#endif

476
inc/bearssl_block.h Normal file
View file

@ -0,0 +1,476 @@
/*
* Copyright (c) 2016 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_BLOCK_H__
#define BR_BEARSSL_BLOCK_H__
#include <stddef.h>
#include <stdint.h>
/*
* Block Ciphers
* -------------
*
* For a block cipher implementation, up to three separate sets of
* functions are provided, for CBC encryption, CBC decryption, and CTR
* encryption/decryption. Each set has its own context structure,
* initialized with the encryption key. Each set of functions is
* provided both as named functions, and through an OOP interface.
*
* For CBC encryption and decryption, the data to encrypt or decrypt is
* referenced as a sequence of blocks. The implementations assume that
* there is no partial block; no padding is applied or removed. The
* caller is responsible for handling any kind of padding.
*
* Function for CTR encryption are defined only for block ciphers with
* blocks of 16 bytes or more (i.e. AES, but not DES/3DES).
*
* Each implemented block cipher is identified by an "internal name"
* from which are derived the names of structures and functions that
* implement the cipher. For the block cipher of internal name "xxx",
* the following are defined:
*
* br_xxx_BLOCK_SIZE
* A macro that evaluates to the block size (in bytes) of the
* cipher. For all implemented block ciphers, this value is a
* power of two.
*
* br_xxx_cbcenc_keys
* Context structure that contains the subkeys resulting from the key
* expansion. These subkeys are appropriate for CBC encryption. The
* structure first field is called 'vtable' and points to the
* appropriate OOP structure.
*
* br_xxx_cbcenc_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)
* Perform key expansion: subkeys for CBC encryption are computed and
* written in the provided context structure. The key length MUST be
* adequate for the implemented block cipher. This function also sets
* the 'vtable' field.
*
* br_xxx_cbcenc_run(const br_xxx_cbcenc_keys *ctx,
* void *iv, void *data, size_t len)
* Perform CBC encryption of 'len' bytes, in place. The encrypted data
* replaces the cleartext. 'len' MUST be a multiple of the block length
* (if it is not, the function may loop forever or overflow a buffer).
* The IV is provided with the 'iv' pointer; it is also updated with
* a copy of the last encrypted block.
*
* br_xxx_cbcdec_keys
* Context structure that contains the subkeys resulting from the key
* expansion. These subkeys are appropriate for CBC decryption. The
* structure first field is called 'vtable' and points to the
* appropriate OOP structure.
*
* br_xxx_cbcdec_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)
* Perform key expansion: subkeys for CBC decryption are computed and
* written in the provided context structure. The key length MUST be
* adequate for the implemented block cipher. This function also sets
* the 'vtable' field.
*
* br_xxx_cbcdec_run(const br_xxx_cbcdec_keys *ctx,
* void *iv, void *data, size_t num_blocks)
* Perform CBC decryption of 'len' bytes, in place. The decrypted data
* replaces the ciphertext. 'len' MUST be a multiple of the block length
* (if it is not, the function may loop forever or overflow a buffer).
* The IV is provided with the 'iv' pointer; it is also updated with
* a copy of the last encrypted block.
*
* br_xxx_ctr_keys
* Context structure that contains the subkeys resulting from the key
* expansion. These subkeys are appropriate for CTR encryption and
* decryption. The structure first field is called 'vtable' and
* points to the appropriate OOP structure.
*
* br_xxx_ctr_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)
* Perform key expansion: subkeys for CTR encryption and decryption
* are computed and written in the provided context structure. The
* key length MUST be adequate for the implemented block cipher. This
* function also sets the 'vtable' field.
*
* br_xxx_ctr_run(const br_xxx_ctr_keys *ctx, const void *iv,
* uint32_t cc, void *data, size_t len) [returns uint32_t]
* Perform CTR encryption/decryption of some data. Processing is done
* "in place" (the output data replaces the input data). This function
* implements the "standard incrementing function" from NIST SP800-38A,
* annex B: the IV length shall be 4 bytes less than the block size
* (i.e. 12 bytes for AES) and the counter is the 32-bit value starting
* with 'cc'. The data length ('len') is not necessarily a multiple of
* the block size. The new counter value is returned, which supports
* chunked processing, provided that each chunk length (except possibly
* the last one) is a multiple of the block size.
*
*
* It shall be noted that the key expansion functions return 'void'. If
* the provided key length is not allowed, then there will be no error
* reporting; implementations need not validate the key length, thus an
* invalid key length may result in undefined behaviour (e.g. buffer
* overflow).
*
* Subkey structures contain no interior pointer, and no external
* resources are allocated upon key expansion. They can thus be
* discarded without any explicit deallocation.
*
*
* Object-oriented API: each context structure begins with a field
* (called 'vtable') that points to an instance of a structure that
* references the relevant functions through pointers. Each such
* structure contains the following:
*
* context_size size (in bytes) of the context structure for subkeys
* block_size cipher block size (in bytes)
* log_block_size base-2 logarithm of cipher block size
* init pointer to the key expansion function
* run pointer to the encryption/decryption function
*
* Static, constant instances of these structures are defined, under
* the names:
*
* br_xxx_cbcenc_vtable
* br_xxx_cbcdec_vtable
* br_xxx_ctr_vtable
*
*
* Implemented Block Ciphers
* -------------------------
*
* Function Name Allowed key lengths (bytes)
*
* AES aes_ct 16, 24 and 32
* AES aes_ct64 16, 24 and 32
* AES aes_big 16, 24 and 32
* AES aes_small 16, 24 and 32
* DES des_ct 8, 16 and 24
* DES des_tab 8, 16 and 24
*
* 'aes_big' is a "classical" AES implementation, using tables. It
* is fast but not constant-time, since it makes data-dependent array
* accesses.
*
* 'aes_small' is an AES implementation optimized for code size. It
* is substantially slower than 'aes_big'; it is not constant-time
* either.
*
* 'aes_ct' is a constant-time implementation of AES; its code is about
* as big as that of 'aes_big', while its performance is comparable to
* that of 'aes_small'. However, it is constant-time. This
* implementation should thus be considered to be the "default" AES in
* BearSSL, to be used unless the operational context guarantees that a
* non-constant-time implementation is safe, or an architecture-specific
* constant-time implementation can be used (e.g. using dedicated
* hardware opcodes).
*
* 'aes_ct64' is another constant-time implementation of AES. It is
* similar to 'aes_ct' but uses 64-bit values, for faster processing
* on 64-bit machines.
*
* 'des_tab' is a classic, table-based implementation of DES/3DES. It
* is not constant-time.
*
* 'des_ct' is an constant-time implementation of DES/3DES. It is
* substantially slower than 'des_tab'.
*/
typedef struct br_block_cbcenc_class_ br_block_cbcenc_class;
struct br_block_cbcenc_class_ {
size_t context_size;
unsigned block_size;
unsigned log_block_size;
void (*init)(const br_block_cbcenc_class **ctx,
const void *key, size_t key_len);
void (*run)(const br_block_cbcenc_class *const *ctx,
void *iv, void *data, size_t len);
};
typedef struct br_block_cbcdec_class_ br_block_cbcdec_class;
struct br_block_cbcdec_class_ {
size_t context_size;
unsigned block_size;
unsigned log_block_size;
void (*init)(const br_block_cbcdec_class **ctx,
const void *key, size_t key_len);
void (*run)(const br_block_cbcdec_class *const *ctx,
void *iv, void *data, size_t len);
};
typedef struct br_block_ctr_class_ br_block_ctr_class;
struct br_block_ctr_class_ {
size_t context_size;
unsigned block_size;
unsigned log_block_size;
void (*init)(const br_block_ctr_class **ctx,
const void *key, size_t key_len);
uint32_t (*run)(const br_block_ctr_class *const *ctx,
const void *iv, uint32_t cc, void *data, size_t len);
};
/*
* Traditional, table-based AES implementation. It is fast, but uses
* internal tables (in particular a 1 kB table for encryption, another
* 1 kB table for decryption, and a 256-byte table for key schedule),
* and it is not constant-time. In contexts where cache-timing attacks
* apply, this implementation may leak the secret key.
*/
#define br_aes_big_BLOCK_SIZE 16
typedef struct {
const br_block_cbcenc_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_big_cbcenc_keys;
typedef struct {
const br_block_cbcdec_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_big_cbcdec_keys;
typedef struct {
const br_block_ctr_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_big_ctr_keys;
extern const br_block_cbcenc_class br_aes_big_cbcenc_vtable;
extern const br_block_cbcdec_class br_aes_big_cbcdec_vtable;
extern const br_block_ctr_class br_aes_big_ctr_vtable;
void br_aes_big_cbcenc_init(br_aes_big_cbcenc_keys *ctx,
const void *key, size_t len);
void br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx,
const void *key, size_t len);
void br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx,
const void *key, size_t len);
void br_aes_big_cbcenc_run(const br_aes_big_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
void br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
uint32_t br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx,
const void *iv, uint32_t cc, void *data, size_t len);
/*
* AES implementation optimized for size. It is slower than the
* traditional table-based AES implementation, but requires much less
* code. It still uses data-dependent table accesses (albeit within a
* much smaller 256-byte table), which makes it conceptually vulnerable
* to cache-timing attacks.
*/
#define br_aes_small_BLOCK_SIZE 16
typedef struct {
const br_block_cbcenc_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_small_cbcenc_keys;
typedef struct {
const br_block_cbcdec_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_small_cbcdec_keys;
typedef struct {
const br_block_ctr_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_small_ctr_keys;
extern const br_block_cbcenc_class br_aes_small_cbcenc_vtable;
extern const br_block_cbcdec_class br_aes_small_cbcdec_vtable;
extern const br_block_ctr_class br_aes_small_ctr_vtable;
void br_aes_small_cbcenc_init(br_aes_small_cbcenc_keys *ctx,
const void *key, size_t len);
void br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx,
const void *key, size_t len);
void br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx,
const void *key, size_t len);
void br_aes_small_cbcenc_run(const br_aes_small_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
void br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
uint32_t br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx,
const void *iv, uint32_t cc, void *data, size_t len);
/*
* Constant-time AES implementation. Its size is similar to that of
* 'aes_big', and its performance is similar to that of 'aes_small' (faster
* decryption, slower encryption). However, it is constant-time, i.e.
* immune to cache-timing and similar attacks.
*/
#define br_aes_ct_BLOCK_SIZE 16
typedef struct {
const br_block_cbcenc_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_ct_cbcenc_keys;
typedef struct {
const br_block_cbcdec_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_ct_cbcdec_keys;
typedef struct {
const br_block_ctr_class *vtable;
uint32_t skey[60];
unsigned num_rounds;
} br_aes_ct_ctr_keys;
extern const br_block_cbcenc_class br_aes_ct_cbcenc_vtable;
extern const br_block_cbcdec_class br_aes_ct_cbcdec_vtable;
extern const br_block_ctr_class br_aes_ct_ctr_vtable;
void br_aes_ct_cbcenc_init(br_aes_ct_cbcenc_keys *ctx,
const void *key, size_t len);
void br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx,
const void *key, size_t len);
void br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx,
const void *key, size_t len);
void br_aes_ct_cbcenc_run(const br_aes_ct_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
void br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
uint32_t br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx,
const void *iv, uint32_t cc, void *data, size_t len);
/*
* 64-bit constant-time AES implementation. It is similar to 'aes_ct'
* but uses 64-bit registers, making it about twice faster than 'aes_ct'
* on 64-bit platforms, while remaining constant-time and with a similar
* code size. (The doubling in performance is only for CBC decryption
* and CTR mode; CBC encryption is non-parallel and cannot benefit from
* the larger registers.)
*/
#define br_aes_ct64_BLOCK_SIZE 16
typedef struct {
const br_block_cbcenc_class *vtable;
uint64_t skey[30];
unsigned num_rounds;
} br_aes_ct64_cbcenc_keys;
typedef struct {
const br_block_cbcdec_class *vtable;
uint64_t skey[30];
unsigned num_rounds;
} br_aes_ct64_cbcdec_keys;
typedef struct {
const br_block_ctr_class *vtable;
uint64_t skey[30];
unsigned num_rounds;
} br_aes_ct64_ctr_keys;
extern const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable;
extern const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable;
extern const br_block_ctr_class br_aes_ct64_ctr_vtable;
void br_aes_ct64_cbcenc_init(br_aes_ct64_cbcenc_keys *ctx,
const void *key, size_t len);
void br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx,
const void *key, size_t len);
void br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx,
const void *key, size_t len);
void br_aes_ct64_cbcenc_run(const br_aes_ct64_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
void br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
uint32_t br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx,
const void *iv, uint32_t cc, void *data, size_t len);
/*
* These structures are large enough to accommodate subkeys for all
* AES implementations.
*/
typedef union {
const br_block_cbcenc_class *vtable;
br_aes_big_cbcenc_keys big;
br_aes_small_cbcenc_keys small;
br_aes_ct_cbcenc_keys ct;
br_aes_ct64_cbcenc_keys ct64;
} br_aes_gen_cbcenc_keys;
typedef union {
const br_block_cbcdec_class *vtable;
br_aes_big_cbcdec_keys big;
br_aes_small_cbcdec_keys small;
br_aes_ct_cbcdec_keys ct;
br_aes_ct64_cbcdec_keys ct64;
} br_aes_gen_cbcdec_keys;
typedef union {
const br_block_ctr_class *vtable;
br_aes_big_ctr_keys big;
br_aes_small_ctr_keys small;
br_aes_ct_ctr_keys ct;
br_aes_ct64_ctr_keys ct64;
} br_aes_gen_ctr_keys;
/*
* Traditional, table-based implementation for DES/3DES. Since tables are
* used, cache-timing attacks are conceptually possible.
*/
#define br_des_tab_BLOCK_SIZE 8
typedef struct {
const br_block_cbcenc_class *vtable;
uint32_t skey[96];
unsigned num_rounds;
} br_des_tab_cbcenc_keys;
typedef struct {
const br_block_cbcdec_class *vtable;
uint32_t skey[96];
unsigned num_rounds;
} br_des_tab_cbcdec_keys;
extern const br_block_cbcenc_class br_des_tab_cbcenc_vtable;
extern const br_block_cbcdec_class br_des_tab_cbcdec_vtable;
void br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx,
const void *key, size_t len);
void br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx,
const void *key, size_t len);
void br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
/*
* Constant-time implementation for DES/3DES. It is substantially slower
* (by a factor of about 4x), but also immune to cache-timing attacks.
*/
#define br_des_ct_BLOCK_SIZE 8
typedef struct {
const br_block_cbcenc_class *vtable;
uint32_t skey[96];
unsigned num_rounds;
} br_des_ct_cbcenc_keys;
typedef struct {
const br_block_cbcdec_class *vtable;
uint32_t skey[96];
unsigned num_rounds;
} br_des_ct_cbcdec_keys;
extern const br_block_cbcenc_class br_des_ct_cbcenc_vtable;
extern const br_block_cbcdec_class br_des_ct_cbcdec_vtable;
void br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx,
const void *key, size_t len);
void br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx,
const void *key, size_t len);
void br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
/*
* These structures are large enough to accommodate subkeys for all
* DES/3DES implementations.
*/
typedef union {
const br_block_cbcenc_class *vtable;
br_des_tab_cbcenc_keys tab;
br_des_ct_cbcenc_keys ct;
} br_des_gen_cbcenc_keys;
typedef union {
const br_block_cbcdec_class *vtable;
br_des_tab_cbcdec_keys tab;
br_des_ct_cbcdec_keys ct;
} br_des_gen_cbcdec_keys;
#endif

220
inc/bearssl_ec.h Normal file
View file

@ -0,0 +1,220 @@
/*
* Copyright (c) 2016 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_EC_H__
#define BR_BEARSSL_EC_H__
#include <stddef.h>
#include <stdint.h>
/*
* Elliptic Curves
* ---------------
*
* ECDSA signatures have two standard formats, called "raw" and "asn1".
* Internally, such a signature is a pair of modular integers (r,s).
* The "raw" format is the concatenation of the unsigned big-endian
* encodings of these two integers, possibly left-padded with zeros so
* that they have the same encoded length. The "asn1" format is the
* DER encoding of an ASN.1 structure that contains the two integer
* values:
*
* ECDSASignature ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
* Low-level implementations defined here work on the "raw" format.
* Conversion functions are provided.
*
* Note that for a given signature, the "raw" format is not fully
* deterministic, in that it does not enforce a minimal common length.
* The functions below MUST ensure, when producing signatures, that
* the signature length never exceeds 2*qlen, where qlen is the length,
* in bytes, of the minimal unsigned big-endian encoding of the curve
* subgroup order.
*
* Conversion of a "raw" format signature into "asn1" may enlarge a
* signature by no more than 9 bytes for all supported curves.
*/
/*
* Standard curve ID. These ID are equal to the assigned numerical
* identifiers assigned to these curves for TLS:
* http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
*/
#define BR_EC_sect163k1 1
#define BR_EC_sect163r1 2
#define BR_EC_sect163r2 3
#define BR_EC_sect193r1 4
#define BR_EC_sect193r2 5
#define BR_EC_sect233k1 6
#define BR_EC_sect233r1 7
#define BR_EC_sect239k1 8
#define BR_EC_sect283k1 9
#define BR_EC_sect283r1 10
#define BR_EC_sect409k1 11
#define BR_EC_sect409r1 12
#define BR_EC_sect571k1 13
#define BR_EC_sect571r1 14
#define BR_EC_secp160k1 15
#define BR_EC_secp160r1 16
#define BR_EC_secp160r2 17
#define BR_EC_secp192k1 18
#define BR_EC_secp192r1 19
#define BR_EC_secp224k1 20
#define BR_EC_secp224r1 21
#define BR_EC_secp256k1 22
#define BR_EC_secp256r1 23
#define BR_EC_secp384r1 24
#define BR_EC_secp521r1 25
#define BR_EC_brainpoolP256r1 26
#define BR_EC_brainpoolP384r1 27
#define BR_EC_brainpoolP512r1 28
/*
* Structure for an EC public key.
*/
typedef struct {
int curve;
unsigned char *q;
size_t qlen;
} br_ec_public_key;
/*
* Structure for an EC private key.
*/
typedef struct {
int curve;
unsigned char *x;
size_t xlen;
} br_ec_private_key;
/*
* Type for an EC implementation.
*
* supported_curves
* Bit mask for supported curves: if curve 'id' is supported, then
* bit '1 << id' is set.
*
* generator
* Get a pointer to the conventional generator for a given curve.
*
* order
* Get a pointer to the curve order (minimal unsigned big-endian
* encoding).
*
* mul
* Compute x*G. Provided point G (encoded size Glen) must be valid and
* distinct from the point at infinity. 'x' must be non-zero and less
* than the curve order. On error, 0 is returned; an invalid G (or
* point at infinity) is always detected, as well as a case of x = 0.
* However, if x is a non-zero multiple of the curve order, then it is
* not guaranteed that an error is reported.
*
* muladd
* compute x*A+y*B, result being written over A. Points and multipliers
* must fulfill the same conditions as for mul().
*/
typedef struct {
uint32_t supported_curves;
const unsigned char *(*generator)(int curve, size_t *len);
const unsigned char *(*order)(int curve, size_t *len);
uint32_t (*mul)(unsigned char *G, size_t Glen,
const unsigned char *x, size_t xlen, int curve);
uint32_t (*muladd)(unsigned char *A, const unsigned char *B, size_t len,
const unsigned char *x, size_t xlen,
const unsigned char *y, size_t ylen, int curve);
} br_ec_impl;
/*
* The 'i31' implementation for elliptic curves. It supports secp256r1,
* secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521).
*/
extern const br_ec_impl br_ec_prime_i31;
/*
* Convert a signature from "raw" to "asn1". Conversion is done "in
* place" and the new length is returned. Conversion may enlarge the
* signature, but by no more than 9 bytes at most. On error, 0 is
* returned (error conditions include an odd raw signature length, or an
* oversized integer).
*/
size_t br_ecdsa_raw_to_asn1(void *sig, size_t sig_len);
/*
* Convert a signature from "asn1" to "raw". Conversion is done "in
* place" and the new length is returned. Conversion in that direction
* always reduced signature length. On error, 0 is returned (error
* conditions include an invalid signature format or an oversized
* integer).
*/
size_t br_ecdsa_asn1_to_raw(void *sig, size_t sig_len);
/*
* Type for an ECDSA signer function. A pointer to the EC implementation
* is provided. The hash value is assumed to have the length inferred
* from the designated hash function class.
*
* Signature is written in the buffer pointed to by 'sig', and the length
* (in bytes) is returned. On error, nothing is written in the buffer,
* and 0 is returned.
*
* The signature format is either "raw" or "asn1", depending on the
* implementation; maximum length is predictable from the implemented
* curve:
*
* curve raw asn1
* NIST P-256 64 72
* NIST P-384 96 104
* NIST P-521 132 139
*/
typedef size_t (*br_ecdsa_sign)(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/*
* Verify ECDSA signature. Returned value is 1 on success, 0 on error.
*/
typedef uint32_t (*br_ecdsa_vrfy)(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/*
* ECDSA implementation using the "i31" integers.
*/
size_t br_ecdsa_i31_sign_asn1(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
size_t br_ecdsa_i31_sign_raw(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
uint32_t br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
#endif

424
inc/bearssl_hash.h Normal file
View file

@ -0,0 +1,424 @@
/*
* Copyright (c) 2016 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_HASH_H__
#define BR_BEARSSL_HASH_H__
#include <stddef.h>
#include <stdint.h>
#include <string.h>
/*
* Hash Functions
* --------------
*
* For hash function 'xxx', the following elements are defined:
*
* br_xxx_vtable
* An externally defined instance of br_hash_class.
*
* br_xxx_SIZE
* A macro that evaluates to the output size (in bytes) of the
* hash function.
*
* br_xxx_ID
* A macro that evaluates to a symbolic identifier for the hash
* function. Such identifiers are used with HMAC and signature
* algorithm implementations.
* NOTE: the numerical value of these identifiers MUST match the
* constants for hash function identification in TLS 1.2 (see RFC
* 5246, section 7.4.1.4.1). These are values 1 to 6, for MD5,
* SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512, respectively.
*
* br_xxx_context
* Context for an ongoing computation. It is allocated by the
* caller, and a pointer to it is passed to all functions. A
* context contains no interior pointer, so it can be moved around
* and cloned (with a simple memcpy() or equivalent) in order to
* capture the function state at some point. Computations that use
* distinct context structures are independent of each other. The
* first field of br_xxx_context is always a pointer to the
* br_xxx_vtable structure; br_xxx_init() sets that pointer.
*
* br_xxx_init(br_xxx_context *ctx)
* Initialize the provided context. Previous contents of the structure
* are ignored. This calls resets the context to the start of a new
* hash computation.
*
* br_xxx_update(br_xxx_context *ctx, const void *data, size_t len)
* Add some more bytes to the hash computation represented by the
* provided context.
*
* br_xxx_out(const br_xxx_context *ctx, void *out)
* Complete the hash computation and write the result in the provided
* buffer. The output buffer MUST be large enough to accomodate the
* result. The context is NOT modified by this operation, so this
* function can be used to get a "partial hash" while still keeping
* the possibility of adding more bytes to the input.
*
* br_xxx_state(const br_xxx_context *ctx, void *out)
* Get a copy of the "current state" for the computation so far. For
* MD functions (MD5, SHA-1, SHA-2 family), this is the running state
* resulting from the processing of the last complete input block.
* Returned value is the current input length (in bytes).
*
* br_xxx_set_state(br_xxx_context *ctx, const void *stb, uint64_t count)
* Set the internal state to the provided values. The 'stb' and 'count'
* values shall match that which was obtained from br_xxx_state(). This
* restores the hash state only if the state values were at an
* appropriate block boundary. This does NOT set the 'vtable' pointer
* in the context.
*
* Context structures can be discarded without any explicit deallocation.
* Hash function implementations are purely software and don't reserve
* any resources outside of the context structure itself.
*
* Implemented hash functions are:
*
* Function Name Output length State length
*
* MD5 md5 16 16
* SHA-1 sha1 20 20
* SHA-224 sha224 28 32
* SHA-256 sha256 32 32
* SHA-384 sha384 48 64
* SHA-512 sha512 64 64
* MD5+SHA-1 md5sha1 36 36
*
* (MD5+SHA-1 is the concatenation of MD5 and SHA-1 computed over the
* same input; in the implementation, the internal data buffer is
* shared, thus making it more memory-efficient than separate MD5 and
* SHA-1. It can be useful in implementing SSL 3.0, TLS 1.0 and TLS
* 1.1.)
*
*
* An object-oriented API is also available: the first field of the
* context is a pointer to a br_hash_class structure, that has the
* following contents:
*
* context_size total size of the required context structure
* desc descriptor (see below)
* init context initialization or reset (function pointer)
* update process some more bytes (function pointer)
* out get hash output so far (function pointer)
* state get copy of internal state (function pointer)
* set_state reset the internal state (function pointer)
*
* The descriptor is a combination of the following elements:
* bits 0 to 7 hash algorithm identifier
* bits 8 to 14 hash output size (in bytes)
* bits 15 to 22 hash internal state size (in bytes)
* bits 23 to 26 log (base 2) of hash internal block size (in bytes)
* bit 28 1 if using MD padding, 0 otherwise
* bit 29 1 if MD padding uses a 128-bit bit length, 0 otherwise
* bit 30 1 if MD padding is big-endian, 0 otherwise
*
* For function 'xxx', the br_xxx_init() function sets the first field
* to a pointer to the relevant br_hash_class instance (i.e.
* br_xxx_vtable).
*
* Users of this object-oriented API may make the following assumptions:
* Hash output size is no more than 64 bytes.
* Hash internal state size is no more than 64 bytes.
* Internal block size is a power of two, no less than 2^4 and no more
* than 2^8.
* For functions that do not have an internal block size that is a
* power of 2, the relevant element is 0.
*/
typedef struct br_hash_class_ br_hash_class;
struct br_hash_class_ {
size_t context_size;
uint32_t desc;
void (*init)(const br_hash_class **ctx);
void (*update)(const br_hash_class **ctx, const void *data, size_t len);
void (*out)(const br_hash_class *const *ctx, void *dst);
uint64_t (*state)(const br_hash_class *const *ctx, void *dst);
void (*set_state)(const br_hash_class **ctx,
const void *stb, uint64_t count);
};
#define BR_HASHDESC_ID(id) ((uint32_t)(id) << BR_HASHDESC_ID_OFF)
#define BR_HASHDESC_ID_OFF 0
#define BR_HASHDESC_ID_MASK 0xFF
#define BR_HASHDESC_OUT(size) ((uint32_t)(size) << BR_HASHDESC_OUT_OFF)
#define BR_HASHDESC_OUT_OFF 8
#define BR_HASHDESC_OUT_MASK 0x7F
#define BR_HASHDESC_STATE(size) ((uint32_t)(size) << BR_HASHDESC_STATE_OFF)
#define BR_HASHDESC_STATE_OFF 15
#define BR_HASHDESC_STATE_MASK 0xFF
#define BR_HASHDESC_LBLEN(ls) ((uint32_t)(ls) << BR_HASHDESC_LBLEN_OFF)
#define BR_HASHDESC_LBLEN_OFF 23
#define BR_HASHDESC_LBLEN_MASK 0x0F
#define BR_HASHDESC_MD_PADDING ((uint32_t)1 << 28)
#define BR_HASHDESC_MD_PADDING_128 ((uint32_t)1 << 29)
#define BR_HASHDESC_MD_PADDING_BE ((uint32_t)1 << 30)
/*
* Specific hash functions.
*
* Rules for contexts:
* -- No interior pointer.
* -- No pointer to external dynamically allocated resources.
* -- First field is called 'vtable' and is a pointer to a
* const-qualified br_hash_class instance (pointer is set by init()).
* -- SHA-224 and SHA-256 contexts are identical.
* -- SHA-384 and SHA-512 contexts are identical.
*
* Thus, contexts can be moved and cloned to capture the hash function
* current state; and there is no need for any explicit "release" function.
*/
#define br_md5_ID 1
#define br_md5_SIZE 16
extern const br_hash_class br_md5_vtable;
typedef struct {
const br_hash_class *vtable;
unsigned char buf[64];
uint64_t count;
uint32_t val[4];
} br_md5_context;
void br_md5_init(br_md5_context *ctx);
void br_md5_update(br_md5_context *ctx, const void *data, size_t len);
void br_md5_out(const br_md5_context *ctx, void *out);
uint64_t br_md5_state(const br_md5_context *ctx, void *out);
void br_md5_set_state(br_md5_context *ctx, const void *stb, uint64_t count);
#define br_sha1_ID 2
#define br_sha1_SIZE 20
extern const br_hash_class br_sha1_vtable;
typedef struct {
const br_hash_class *vtable;
unsigned char buf[64];
uint64_t count;
uint32_t val[5];
} br_sha1_context;
void br_sha1_init(br_sha1_context *ctx);
void br_sha1_update(br_sha1_context *ctx, const void *data, size_t len);
void br_sha1_out(const br_sha1_context *ctx, void *out);
uint64_t br_sha1_state(const br_sha1_context *ctx, void *out);
void br_sha1_set_state(br_sha1_context *ctx, const void *stb, uint64_t count);
#define br_sha224_ID 3
#define br_sha224_SIZE 28
extern const br_hash_class br_sha224_vtable;
typedef struct {
const br_hash_class *vtable;
unsigned char buf[64];
uint64_t count;
uint32_t val[8];
} br_sha224_context;
void br_sha224_init(br_sha224_context *ctx);
void br_sha224_update(br_sha224_context *ctx, const void *data, size_t len);
void br_sha224_out(const br_sha224_context *ctx, void *out);
uint64_t br_sha224_state(const br_sha224_context *ctx, void *out);
void br_sha224_set_state(br_sha224_context *ctx,
const void *stb, uint64_t count);
#define br_sha256_ID 4
#define br_sha256_SIZE 32
extern const br_hash_class br_sha256_vtable;
typedef br_sha224_context br_sha256_context;
void br_sha256_init(br_sha256_context *ctx);
#define br_sha256_update br_sha224_update
void br_sha256_out(const br_sha256_context *ctx, void *out);
#define br_sha256_state br_sha224_state
#define br_sha256_set_state br_sha224_set_state
#define br_sha384_ID 5
#define br_sha384_SIZE 48
extern const br_hash_class br_sha384_vtable;
typedef struct {
const br_hash_class *vtable;
unsigned char buf[128];
uint64_t count;
uint64_t val[8];
} br_sha384_context;
void br_sha384_init(br_sha384_context *ctx);
void br_sha384_update(br_sha384_context *ctx, const void *data, size_t len);
void br_sha384_out(const br_sha384_context *ctx, void *out);
uint64_t br_sha384_state(const br_sha384_context *ctx, void *out);
void br_sha384_set_state(br_sha384_context *ctx,
const void *stb, uint64_t count);
#define br_sha512_ID 6
#define br_sha512_SIZE 64
extern const br_hash_class br_sha512_vtable;
typedef br_sha384_context br_sha512_context;
void br_sha512_init(br_sha512_context *ctx);
#define br_sha512_update br_sha384_update
void br_sha512_out(const br_sha512_context *ctx, void *out);
#define br_sha512_state br_sha384_state
#define br_sha512_set_state br_sha384_set_state
/*
* "md5sha1" is a special hash function that computes both MD5 and SHA-1
* on the same input, and produces a 36-byte output (MD5 and SHA-1
* concatenation, in that order). State size is also 36 bytes.
*/
#define br_md5sha1_ID 0
#define br_md5sha1_SIZE 36
extern const br_hash_class br_md5sha1_vtable;
typedef struct {
const br_hash_class *vtable;
unsigned char buf[64];
uint64_t count;
uint32_t val_md5[4];
uint32_t val_sha1[5];
} br_md5sha1_context;
void br_md5sha1_init(br_md5sha1_context *ctx);
void br_md5sha1_update(br_md5sha1_context *ctx, const void *data, size_t len);
void br_md5sha1_out(const br_md5sha1_context *ctx, void *out);
uint64_t br_md5sha1_state(const br_md5sha1_context *ctx, void *out);
void br_md5sha1_set_state(br_md5sha1_context *ctx,
const void *stb, uint64_t count);
/*
* The br_hash_compat_context type is a type which is large enough to
* serve as context for all standard hash functions defined above.
*/
typedef union {
const br_hash_class *vtable;
br_md5_context md5;
br_sha1_context sha1;
br_sha224_context sha224;
br_sha256_context sha256;
br_sha384_context sha384;
br_sha512_context sha512;
} br_hash_compat_context;
/*
* The multi-hasher is a construct that handles hashing of the same input
* data with several hash functions, with a single shared input buffer.
* It can handle MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512
* simultaneously, though which functions are activated depends on
* the set implementation pointers.
*/
typedef struct {
unsigned char buf[128];
uint64_t count;
uint32_t val_32[25];
uint64_t val_64[16];
const br_hash_class *impl[6];
} br_multihash_context;
/*
* Clear a complete multihash context. This should always be called once
* on a given context, before setting implementation pointers.
*/
void br_multihash_zero(br_multihash_context *ctx);
/*
* Set a hash function implementation, identified by ID.
*/
static inline void
br_multihash_setimpl(br_multihash_context *ctx,
int id, const br_hash_class *impl)
{
/*
* This code relies on hash functions ID being values 1 to 6,
* in the MD5 to SHA-512 order.
*/
ctx->impl[id - 1] = impl;
}
/*
* Get the configured hash implementation, identified by ID. This returns
* NULL for unsupported hash implementations. The hash identifier MUST
* be a valid one (from br_md5_ID to br_sha512_ID, inclusive).
*/
static inline const br_hash_class *
br_multihash_getimpl(const br_multihash_context *ctx, int id)
{
return ctx->impl[id - 1];
}
/*
* Reset a multihash context. The hash functions for which implementation
* pointers have been set are reset and initialized.
*/
void br_multihash_init(br_multihash_context *ctx);
/*
* Input some bytes into the context.
*/
void br_multihash_update(br_multihash_context *ctx,
const void *data, size_t len);
/*
* Get the hash of the bytes injected so far, with the specified hash
* function. The hash function is given by ID (e.g. br_md5_ID for MD5).
* The hash output is written on 'dst'. The hash length is returned (in
* bytes); if the specified hash function is not implemented by this
* context, then this function returns 0.
*
* Obtaining the hash output does not invalidate the current hashing
* operation, thus "partial hashes" can be obtained.
*/
size_t br_multihash_out(const br_multihash_context *ctx, int id, void *dst);
/*
* Type for a GHASH implementation. GHASH is a sort of keyed hash meant
* to be used to implement GCM in combination with a block cipher (with
* 16-byte blocks).
*
* The y[] array has length 16 bytes and is used for input and output; in
* a complete GHASH run, it starts with an all-zero value. h[] is a 16-byte
* value that serves as key (it is derived from the encryption key in GCM,
* using the block cipher). The data length (len) is expressed in bytes.
*
* If the data length is not a multiple of 16, then the data is implicitly
* padded with zeros up to the next multiple of 16. Thus, when using GHASH
* in GCM, this method may be called twice, for the associated data and
* for the ciphertext, respectively; the zero-padding implements exactly
* the GCM rules.
*/
typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len);
/*
* Implementation of GHASH using normal 32x32->64 multiplications. It is
* constant-time (if multiplications are constant-time).
*/
void br_ghash_ctmul(void *y, const void *h, const void *data, size_t len);
/*
* Implementation of GHASH using normal 32x32->32 multiplications; this
* may be faster than br_ghash_ctmul() on platforms for which the inner
* multiplication opcode does not yield the upper 32 bits of the product.
* It is constant-time (if multiplications are constant-time).
*/
void br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len);
/*
* Implementation of GHASH using 64x64->64 multiplications. It is
* constant-time (if multiplications are constant-time).
*/
void br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len);
#endif

148
inc/bearssl_hmac.h Normal file
View file

@ -0,0 +1,148 @@
/*
* Copyright (c) 2016 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_HMAC_H__
#define BR_BEARSSL_HMAC_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
/*
* HMAC
* ----
*
* HMAC is initialized with a key and an underlying hash function; it
* then fills a "key context". That context contains the processed
* key.
*
* With the key context, a HMAC context can be initialized to process
* the input bytes and obtain the MAC output. The key context is not
* modified during that process, and can be reused.
*
* IMPORTANT: HMAC shall be used only with functions that have the
* following properties:
* hash output size does not exceed 64 bytes
* hash internal state size does not exceed 64 bytes
* internal block length is a power of 2 between 16 and 256 bytes
*/
/*
* Key context.
*/
typedef struct {
const br_hash_class *dig_vtable;
unsigned char ksi[64], kso[64];
} br_hmac_key_context;
/*
* Initialize the key context with the provided key, using the hash function
* identified by digest_class.
*/
void br_hmac_key_init(br_hmac_key_context *kc,
const br_hash_class *digest_class, const void *key, size_t key_len);
/*
* A helper structure that is big enough to accommodate all context
* structures for all hash functions for which HMAC is supported.
*/
typedef union {
const br_hash_class *vtable;
br_md5_context md5;
br_sha1_context sha1;
br_sha224_context sha224;
br_sha256_context sha256;
br_sha384_context sha384;
br_sha512_context sha512;
} br_hmac_allhash_context;
/*
* Context for an HMAC computation.
*/
typedef struct {
br_hmac_allhash_context dig;
unsigned char kso[64];
size_t out_len;
} br_hmac_context;
/*
* Initialize a HMAC context with a key context. The key context is
* unmodified. Relevant data from the key context is immediately copied;
* the key context can thus be independently reused, modified or released
* without impacting this HMAC computation.
*
* An explicit output length can be specified; the actual output length
* will be the minimum of that value and the natural HMAC output length.
* If out_len is 0, then the natural HMAC output length is selected.
*/
void br_hmac_init(br_hmac_context *ctx,
const br_hmac_key_context *kc, size_t out_len);
/*
* Get the MAC output size. The context must have been initialized.
*/
#define br_hmac_size(ctx) ((ctx)->out_len)
/*
* Process some more bytes.
*/
void br_hmac_update(br_hmac_context *ctx, const void *data, size_t len);
/*
* Compute the HMAC output. The destination buffer MUST be large enough
* to accomodate the result. The context is NOT modified; further bytes
* may be processed. Thus, "partial HMAC" values can be efficiently
* obtained.
*
* Returned value is the output length (in bytes).
*/
size_t br_hmac_out(const br_hmac_context *ctx, void *out);
/*
* Compute the HMAC output in constant time. Some extra input bytes are
* processed, then the output is computed. The extra input consists in
* the 'len' bytes pointed to by 'data'. The 'len' parameter must lie
* between 'min_len' and 'max_len' (inclusive); max_len bytes are
* actually read from 'data'. Computing time (and memory access pattern)
* will not depend upon the data bytes or the value of 'len'.
*
* The output is written in the 'out' buffer, that MUST be large enough
* to receive it.
*
* The difference max_len-min_len MUST be less than 2^30.
*
* This function computes the output properly only if the underlying
* hash function uses MD padding (i.e. MD5, SHA-1, SHA-224, SHA-256,
* SHA-384 or SHA-512).
*
* The provided context is NOT modified.
*
* Returned value is the MAC length (in bytes).
*/
size_t br_hmac_outCT(const br_hmac_context *ctx,
const void *data, size_t len, size_t min_len, size_t max_len,
void *out);
#endif

125
inc/bearssl_pem.h Normal file
View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2016 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_PEM_H__
#define BR_BEARSSL_PEM_H__
#include <stddef.h>
#include <stdint.h>
/*
* Context for a PEM decoder.
*/
typedef struct {
/* CPU for the T0 virtual machine. */
struct {
uint32_t *dp;
uint32_t *rp;
const unsigned char *ip;
} cpu;
uint32_t dp_stack[32];
uint32_t rp_stack[32];
int err;
const unsigned char *hbuf;
size_t hlen;
void (*dest)(void *dest_ctx, const void *src, size_t len);
void *dest_ctx;
unsigned char event;
char name[128];
unsigned char buf[255];
size_t ptr;
} br_pem_decoder_context;
/*
* Initialise a PEM decoder structure.
*/
void br_pem_decoder_init(br_pem_decoder_context *ctx);
/*
* Push some bytes into the decoder. Returned value is the number of
* bytes actually consumed; this may be less than the number of provided
* bytes if an event is produced. When an event is produced, it must
* be read (with br_pem_decoder_event()); until the event is read, this
* function will return 0.
*/
size_t br_pem_decoder_push(br_pem_decoder_context *ctx,
const void *data, size_t len);
/*
* Set the receiver for decoded data. The provided function (with opaque
* context pointer) will be called with successive data chunks.
*/
static inline void
br_pem_decoder_setdest(br_pem_decoder_context *ctx,
void (*dest)(void *dest_ctx, const void *src, size_t len),
void *dest_ctx)
{
ctx->dest = dest;
ctx->dest_ctx = dest_ctx;
}
/*
* Get the last event. This is 0 if no event has been produced. Calling
* ths function clears the event and allows new source bytes to be
* processed.
*/
int br_pem_decoder_event(br_pem_decoder_context *ctx);
/*
* This event is called when the start of a new object has been detected.
* The object name (normalised to uppercase) can be accessed with
* br_pem_decoder_name(). The caller MUST provide an appropriate receiver
* (with br_pem_decoder_setdest()) before sending new data bytes.
*/
#define BR_PEM_BEGIN_OBJ 1
/*
* This event is called when the end of the current object is reached
* (normally).
*/
#define BR_PEM_END_OBJ 2
/*
* This event is called when decoding fails while decoding an object.
* This formally closes the current object and brings the decoder back
* to the "out of any object" state. The offending line in the source
* is consumed.
*/
#define BR_PEM_ERROR 3
/*
* Get the name of the encountered object. That name is normalised to
* uppercase (for ASCII characters).
*/
static inline const char *
br_pem_decoder_name(br_pem_decoder_context *ctx)
{
return ctx->name;
}
#endif

66
inc/bearssl_prf.h Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2016 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_PRF_H__
#define BR_BEARSSL_PRF_H__
#include <stddef.h>
#include <stdint.h>
/*
* The TLS PRF
* -----------
*
* TLS 1.0 and 1.1 define a PRF that is based on both MD5 and SHA-1. This
* is implemented by the br_tls10_prf() function.
*
* TLS 1.2 redefines the PRF, using an explicit hash function. The
* br_tls12_sha256_prf() and br_tls12_sha384_prf() functions apply that
* PRF with, respectively, SHA-256 and SHA-384.
*
* The PRF always uses as input three parameters: a "secret" (some
* bytes), a "label" (ASCII string), and a "seed" (again some bytes).
* An arbitrary output length can be produced.
*/
void br_tls10_prf(void *dst, size_t len,
const void *secret, size_t secret_len,
const char *label, const void *seed, size_t seed_len);
void br_tls12_sha256_prf(void *dst, size_t len,
const void *secret, size_t secret_len,
const char *label, const void *seed, size_t seed_len);
void br_tls12_sha384_prf(void *dst, size_t len,
const void *secret, size_t secret_len,
const char *label, const void *seed, size_t seed_len);
/*
* A convenient type name for a PRF implementation.
*/
typedef void (*br_tls_prf_impl)(void *dst, size_t len,
const void *secret, size_t secret_len,
const char *label, const void *seed, size_t seed_len);
#endif

149
inc/bearssl_rand.h Normal file
View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2016 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_RAND_H__
#define BR_BEARSSL_RAND_H__
#include <stddef.h>
#include <stdint.h>
/*
* Pseudo-Random Generators
* ------------------------
*
* A PRNG is a state-based engine that outputs pseudo-random bytes on
* demand. It is initialized with an initial seed, and additional seed
* bytes can be added afterwards. Bytes produced depend on the seeds
* and also on the exact sequence of calls (including sizes requested
* for each call).
*
* An object-oriented API is defined, with rules similar to that of
* hash functions. The context structure for a PRNG must start with
* a pointer to the vtable. The vtable contains the following fields:
*
* context_size size of the context structure for this PRNG
* init initialize context with an initial seed
* generate produce some pseudo-random bytes
* update insert some additional seed
*
* Note that the init() method may accept additional parameters, provided
* as a 'const void *' pointer at API level. These additional parameters
* depend on the implemented PRNG.
*/
typedef struct br_prng_class_ br_prng_class;
struct br_prng_class_ {
size_t context_size;
void (*init)(const br_prng_class **ctx, const void *params,
const void *seed, size_t seed_len);
void (*generate)(const br_prng_class **ctx, void *out, size_t len);
void (*update)(const br_prng_class **ctx,
const void *seed, size_t seed_len);
};
/*
* HMAC_DRBG is a pseudo-random number generator based on HMAC (with
* an underlying hash function). HMAC_DRBG is specified in NIST Special
* Publication 800-90A. It works as a stateful machine:
* -- It has an internal state.
* -- The state can be updated with additional "entropy" (some bytes
* provided from the outside).
* -- Each request is for some bits (up to some limit). For each request,
* an internal "reseed counter" is incremented.
* -- When the reseed counter reaches a given threshold, a reseed is
* necessary.
*
* Standard limits are quite high: each request can produce up to 2^19
* bits (i.e. 64 kB of data), and the threshold for the reseed counter
* is 2^48. In practice, we cannot really reach that reseed counter, so
* the implementation simply omits the counter. Similarly, we consider
* that it is up to callers NOT to ask for more than 64 kB of randomness
* in one go. Under these conditions, this implementation cannot fail,
* and thus functions need not return any status code.
*
* (Asking for more than 64 kB of data in one generate() call won't make
* the implementation fail, and, as far as we know, it will not induce
* any actual weakness; this is "merely" out of the formal usage range
* defined for HMAC_DRBG.)
*
* A dedicated context structure (caller allocated, as usual) contains
* the current PRNG state.
*
* For the OOP interface, the "additional parameters" are a pointer to
* the class of the hash function to use.
*/
typedef struct {
const br_prng_class *vtable;
unsigned char K[64];
unsigned char V[64];
const br_hash_class *digest_class;
} br_hmac_drbg_context;
extern const br_prng_class br_hmac_drbg_vtable;
/*
* Initialize a HMAC_DRBG instance, with the provided initial seed (of
* 'len' bytes). The 'seed' used here is what is called, in SP 800-90A
* terminology, the concatenation of the "seed", "nonce" and
* "personalization string", in that order.
*
* Formally, the underlying digest can only be SHA-1 or one of the SHA-2
* functions. This implementation also works with any other implemented
* hash function (e.g. MD5), but such usage is non-standard and not
* recommended.
*/
void br_hmac_drbg_init(br_hmac_drbg_context *ctx,
const br_hash_class *digest_class, const void *seed, size_t len);
/*
* Obtain some pseudorandom bits from HMAC_DRBG. The provided context
* is updated. The output bits are written in 'out' ('len' bytes). The
* size of the requested chunk of pseudorandom bits MUST NOT exceed
* 64 kB (the function won't fail if more bytes are requested, but
* the usage will be outside of the HMAC_DRBG specification limits).
*/
void br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len);
/*
* Update an HMAC_DRBG instance with some new entropy. The extra 'seed'
* complements the current state but does not completely replace any
* previous seed. The process is such that pushing new entropy, even of
* questionable quality, will not make the output "less random" in any
* practical way.
*/
void br_hmac_drbg_update(br_hmac_drbg_context *ctx,
const void *seed, size_t len);
/*
* Get the hash function implementation used by a given instance of
* HMAC_DRBG.
*/
static inline const br_hash_class *
br_hmac_drbg_get_hash(const br_hmac_drbg_context *ctx)
{
return ctx->digest_class;
}
#endif

227
inc/bearssl_rsa.h Normal file
View file

@ -0,0 +1,227 @@
/*
* Copyright (c) 2016 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_RSA_H__
#define BR_BEARSSL_RSA_H__
#include <stddef.h>
#include <stdint.h>
/*
* RSA
* ---
*
* A RSA engine consists in two functions, for public-key and private-key
* operations (modular exponentiations). In both cases, the same buffer is
* used as source and destination.
*
* Key elements are provided as arrays of bytes, in big-endian unsigned
* encoding (leading zeros are correctly skipped, hence signed encodings
* can also be used). The source/destination array (x[]) is an array of
* bytes that, per PKCS#1 rules, MUST have the same length as the modulus,
* exactly: missing or extra leading bytes, even of value 0x00, are not
* tolerated for x[].
*
* Parameter validation: the engine MUST gracefully handle incorrect key
* parameters (e.g. an even modulus); it needs not detect all cases of
* incorrect key parameters. For public key operations, the engine MUST
* validate the length of x[] (it must match the numerical length, in
* bytes, of the modulus); it MUST also check that the provided x[]
* decodes to an integer that is numerically less than the modulus. For
* private key operation, the engine may assume that the length and
* contents of x[] are appropriate (it MUST NOT allow an invalid value
* to result in a buffer overflow, but an invalid input x[] may result
* in an undetected invalid output).
*
* Constant-time requirements: the following information may leak through
* execution time and memory access pattern:
* -- the actual bit length of the modulus;
* -- the actual bit length of each prime factor;
* -- the byte lengths as provided to the function calls.
*/
/*
* A structure type for a RSA public key, consisting in a modulus and
* a public exponent, encoded in unsigned big-endian format. The two
* arrays may be larger than needed; functions that accept a RSA public
* key are supposed to check the actual modulus length when needed.
*/
typedef struct {
unsigned char *n;
size_t nlen;
unsigned char *e;
size_t elen;
} br_rsa_public_key;
/*
* A structure type for a RSA private key. The key elements are:
* n_bitlen modulus bit length
* p prime modulus factor
* q other prime modulus factor (may be greater or lower than p)
* dp private exponent, reduced modulo p-1
* dq private exponent, reduced modulo q-1
* iq CRT coefficient: q*iq = 1 mod p.
*/
typedef struct {
uint32_t n_bitlen;
unsigned char *p;
size_t plen;
unsigned char *q;
size_t qlen;
unsigned char *dp;
size_t dplen;
unsigned char *dq;
size_t dqlen;
unsigned char *iq;
size_t iqlen;
} br_rsa_private_key;
/*
* Type for a public-key engine. The source buffer x[], of size xlen,
* is modified in place.
*
* Returned value is 1 on success, 0 on error.
*
* If the source buffer length (xlen) does not exactly match the modulus
* length, then an error is reported and x[] is unmodified.
*/
typedef uint32_t (*br_rsa_public)(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
/*
* Type for a RSA signature verification engine (PKCS#1 v1.5 signatures).
* Parameters are:
* -- The signature itself. The provided array is NOT modified.
* -- The encoded OID for the hash function. The provided array must begin
* with a single byte that contains the length of the OID value (in
* bytes), followed by exactly that many bytes.
* This parameter may be NULL, in which case the raw hash value should
* be used with the PKCS#1 v1.5 "type 1" padding (used in SSL/TLS up
* to TLS-1.1, with a 36-byte hash value).
* -- The hash output length, in bytes.
* -- The public key.
* -- An output buffer for the hash value. The caller must still compare
* it with the hash of the data over which the signature is computed.
*
* CONSTRAINTS:
* -- Hash length MUST be no more than 64 bytes.
* -- OID value length MUST be no more than 32 bytes (i.e. hash_oid[0]
* must have a value in the 0..32 range, inclusive).
*
* 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.
*/
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);
/*
* Type for a private-key engine. The x[] buffer is modified in place, and
* its length is inferred from the modulus length (x[] is assumed to have
* a length of (sk->n_bitlen+7)/8 bytes).
*
* Returned value is 1 on success, 0 on error.
*/
typedef uint32_t (*br_rsa_private)(unsigned char *x,
const br_rsa_private_key *sk);
/*
* Type for a RSA signature generation engine (PKCS#1 v1.5 signatures).
* Parameters are:
* -- The encoded OID for the hash function. The provided array must begin
* with a single byte that contains the length of the OID value (in
* bytes), followed by exactly that many bytes.
* This parameter may be NULL, in which case the raw hash value should
* be used with the PKCS#1 v1.5 "type 1" padding (used in SSL/TLS up
* to TLS-1.1, with a 36-byte hash value).
* -- The hashed data, and length (in bytes).
* -- The private key.
* -- The output buffer.
*
* Returned value is 1 on success, 0 on error. Error conditions include
* a too small modulus for the provided hash OID and value, 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.
*/
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);
/*
* RSA "i32" engine. Integers are internally represented as arrays of
* 32-bit integers, and the core multiplication primitive is the
* 32x32->64 multiplication.
*/
uint32_t br_rsa_i32_public(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
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);
uint32_t br_rsa_i32_private(unsigned char *x,
const br_rsa_private_key *sk);
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);
/*
* 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
* space, but it quite faster.
*/
uint32_t br_rsa_i31_public(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
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);
uint32_t br_rsa_i31_private(unsigned char *x,
const br_rsa_private_key *sk);
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);
/*
* Perform RSA decryption for SSL/TLS. This function uses the provided core
* and private key to decrypt the message in data[] of size 'len'. The
* buffer is modified; the decryption result MUST have length 48, and
* is written into the first 48 bytes of data[].
*
* In success, this rturns 1. On error, 0 is returned, and the buffer
* contents are indeterminate.
*/
uint32_t br_rsa_ssl_decrypt(br_rsa_private core, const br_rsa_private_key *sk,
unsigned char *data, size_t len);
#endif

1856
inc/bearssl_ssl.h Normal file

File diff suppressed because it is too large Load diff

733
inc/bearssl_x509.h Normal file
View file

@ -0,0 +1,733 @@
/*
* Copyright (c) 2016 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_X509_H__
#define BR_BEARSSL_X509_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_ec.h"
#include "bearssl_hash.h"
#include "bearssl_rsa.h"
/*
* X.509 Certificate Chain Processing
* ----------------------------------
*
* An X.509 processing engine receives an X.509 chain, chunk by chunk,
* as received from a SSL/TLS client or server (the client receives the
* server's certificate chain, and the server receives the client's
* certificate chain if it requested a client certificate). The chain
* is thus injected in the engine in SSL order (end-entity first).
*
* The engine's job is to return the public key to use for SSL/TLS.
* How exactly that key is obtained and verified is entirely up to the
* engine.
*/
/*
* X.509 error codes are in the 32..63 range.
*/
/* Validation was successful; this is not actually an error. */
#define BR_ERR_X509_OK 32
/* Invalid value in an ASN.1 structure. */
#define BR_ERR_X509_INVALID_VALUE 33
/* Truncated certificate. */
#define BR_ERR_X509_TRUNCATED 34
/* Empty certificate chain (no certificate at all). */
#define BR_ERR_X509_EMPTY_CHAIN 35
/* Decoding error: inner element extends beyond outer element size. */
#define BR_ERR_X509_INNER_TRUNC 36
/* Decoding error: unsupported tag class (application or private). */
#define BR_ERR_X509_BAD_TAG_CLASS 37
/* Decoding error: unsupported tag value. */
#define BR_ERR_X509_BAD_TAG_VALUE 38
/* Decoding error: indefinite length. */
#define BR_ERR_X509_INDEFINITE_LENGTH 39
/* Decoding error: extraneous element. */
#define BR_ERR_X509_EXTRA_ELEMENT 40
/* Decoding error: unexpected element. */
#define BR_ERR_X509_UNEXPECTED 41
/* Decoding error: expected constructed element, but is primitive. */
#define BR_ERR_X509_NOT_CONSTRUCTED 42
/* Decoding error: expected primitive element, but is constructed. */
#define BR_ERR_X509_NOT_PRIMITIVE 43
/* Decoding error: BIT STRING length is not multiple of 8. */
#define BR_ERR_X509_PARTIAL_BYTE 44
/* Decoding error: BOOLEAN value has invalid length. */
#define BR_ERR_X509_BAD_BOOLEAN 45
/* Decoding error: value is off-limits. */
#define BR_ERR_X509_OVERFLOW 46
/* Invalid distinguished name. */
#define BR_ERR_X509_BAD_DN 47
/* Invalid date/time representation. */
#define BR_ERR_X509_BAD_TIME 48
/* Certificate contains unsupported features that cannot be ignored. */
#define BR_ERR_X509_UNSUPPORTED 49
/* Key or signature size exceeds internal limits. */
#define BR_ERR_X509_LIMIT_EXCEEDED 50
/* Key type does not match that which was expected. */
#define BR_ERR_X509_WRONG_KEY_TYPE 51
/* Signature is invalid. */
#define BR_ERR_X509_BAD_SIGNATURE 52
/* Validation time is unknown. */
#define BR_ERR_X509_TIME_UNKNOWN 53
/* Certificate is expired or not yet valid. */
#define BR_ERR_X509_EXPIRED 54
/* Issuer/Subject DN mismatch in the chain. */
#define BR_ERR_X509_DN_MISMATCH 55
/* Expected server name was not found in the chain. */
#define BR_ERR_X509_BAD_SERVER_NAME 56
/* Unknown critical extension in certificate. */
#define BR_ERR_X509_CRITICAL_EXTENSION 57
/* Not a CA, or path length constraint violation */
#define BR_ERR_X509_NOT_CA 58
/* Key Usage extension prohibits intended usage. */
#define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59
/* Public key found in certificate is too small. */
#define BR_ERR_X509_WEAK_PUBLIC_KEY 60
/* Chain could not be linked to a trust anchor. */
#define BR_ERR_X509_NOT_TRUSTED 62
/*
* A structure to encode public keys.
*/
typedef struct {
unsigned char key_type;
union {
br_rsa_public_key rsa;
br_ec_public_key ec;
} key;
} br_x509_pkey;
/*
* A trust anchor consists in:
* -- an encoded DN
* -- a public key
* -- flags
*/
typedef struct {
unsigned char *dn;
size_t dn_len;
/* unsigned char hashed_DN[64]; */
unsigned flags;
br_x509_pkey pkey;
} br_x509_trust_anchor;
/* Trust anchor flag: trust anchor is a CA and thus acceptable for
signing other certificates. Without this flag, the trust anchor
is only for direct trust (name and key match EE certificate). */
#define BR_X509_TA_CA 0x0001
/*
* Key type: combination of a basic key type (low 4 bits) and some
* optional flags.
*
* For a public key, the basic key type only is set.
*
* For an expected key type, the flags indicate the intended purpose(s)
* for the key; the basic key type may be set to 0 to indicate that any
* key type compatible with the indicated purpose is acceptable.
*/
#define BR_KEYTYPE_RSA 1
#define BR_KEYTYPE_EC 2
#define BR_KEYTYPE_KEYX 0x10 /* key is for key exchange or encryption */
#define BR_KEYTYPE_SIGN 0x20 /* key is for verifying signatures */
/*
* start_chain Called when a new chain is started. If 'server_name'
* is not NULL and non-empty, then it is a name that
* should be looked for in the EE certificate (in the
* SAN extension as dNSName, or in the subjectDN's CN
* if there is no SAN extension).
* The caller ensures that the provided 'server_name'
* pointer remains valid throughout validation.
*
* start_cert Begins a new certificate in the chain. The provided
* length is in bytes; this is the total certificate length.
*
* append Get some additional bytes for the current certificate.
*
* end_cert Ends the current certificate.
*
* end_chain Called at the end of the chain. Returned value is
* 0 on success, or a non-zero error code.
*
* get_pkey Returns the EE certificate public key.
*
* For a complete chain, start_chain() and end_chain() are always
* called. For each certificate, start_cert(), some append() calls, then
* end_cert() are called, in that order. There may be no append() call
* at all if the certificate is empty (which is not valid but may happen
* if the peer sends exactly that).
*
* get_pkey() shall return a pointer to a structure that is valid as
* long as a new chain is not started. This may be a sub-structure
* within the context for the engine. This function MAY return a valid
* pointer to a public key even in some cases of validation failure,
* depending on the validation engine.
*/
typedef struct br_x509_class_ br_x509_class;
struct br_x509_class_ {
size_t context_size;
void (*start_chain)(const br_x509_class **ctx,
unsigned expected_key_type,
const char *server_name);
void (*start_cert)(const br_x509_class **ctx, uint32_t length);
void (*append)(const br_x509_class **ctx,
const unsigned char *buf, size_t len);
void (*end_cert)(const br_x509_class **ctx);
unsigned (*end_chain)(const br_x509_class **ctx);
const br_x509_pkey *(*get_pkey)(const br_x509_class *const *ctx);
};
/*
* The "known key" X.509 engine is a trivial engine that completely
* ignores the certificates, and instead reports an externally
* configured public key.
*/
typedef struct {
const br_x509_class *vtable;
br_x509_pkey pkey;
} br_x509_knownkey_context;
extern const br_x509_class br_x509_knownkey_vtable;
/*
* Initialize a "known key" X.509 engine with a known RSA public key.
* The provided pointers are linked in, not copied, so they must
* remain valid while the public key may be in usage (i.e. at least up
* to the end of the handshake -- and since there may be renegotiations,
* these buffers should stay until the connection is finished).
*/
void br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx,
const br_rsa_public_key *pk);
/*
* Initialize a "known key" X.509 engine with a known EC public key.
* The provided pointers are linked in, not copied, so they must
* remain valid while the public key may be in usage (i.e. at least up
* to the end of the handshake -- and since there may be renegotiations,
* these buffers should stay until the connection is finished).
*/
void br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx,
const br_ec_public_key *pk);
/*
* The minimal X.509 engine has some state buffers which must be large
* enough to simultaneously accommodate:
* -- the public key extracted from the current certificate;
* -- the signature on the current certificate or on the previous
* certificate;
* -- the public key extracted from the EE certificate.
*
* We store public key elements in their raw unsigned big-endian
* encoding. We want to support up to RSA-4096 with a short (up to 64
* bits) public exponent, thus a buffer for a public key must have
* length at least 520 bytes. Similarly, a RSA-4096 signature has length
* 512 bytes.
*
* Though RSA public exponents can formally be as large as the modulus
* (mathematically, even larger exponents would work, but PKCS#1 forbids
* them), exponents that do not fit on 32 bits are extremely rare,
* notably because some widespread implementation (e.g. Microsoft's
* CryptoAPI) don't support them. Moreover, large public exponent do not
* seem to imply any tangible security benefit, and they increase the
* cost of public key operations.
*
* EC public keys are shorter than RSA public keys; even with curve
* NIST P-521 (the largest curve we care to support), a public key is
* encoded over 133 bytes only.
*/
#define BR_X509_BUFSIZE_KEY 520
#define BR_X509_BUFSIZE_SIG 512
/*
* The "minimal" X.509 engine performs basic decoding of certificates and
* some validations:
* -- DN matching
* -- signatures
* -- validity dates
* -- Basic Constraints extension
* -- Server name check against SAN extension
*/
typedef struct {
const br_x509_class *vtable;
/* Structure for returning the EE public key. */
br_x509_pkey pkey;
/* CPU for the T0 virtual machine. */
struct {
uint32_t *dp;
uint32_t *rp;
const unsigned char *ip;
} cpu;
uint32_t dp_stack[32];
uint32_t rp_stack[32];
int err;
/* Server name to match with the SAN / CN of the EE certificate. */
const char *server_name;
/* Expected EE key type and usage. */
unsigned char expected_key_type;
/* Explicitly set date and time. */
uint32_t days, seconds;
/* Current certificate length (in bytes). Set to 0 when the
certificate has been fully processed. */
uint32_t cert_length;
/* Number of certificates processed so far in the current chain.
It is incremented at the end of the processing of a certificate,
so it is 0 for the EE. */
uint32_t num_certs;
/* Certificate data chunk. */
const unsigned char *hbuf;
size_t hlen;
/* The pad serves as destination for various operations. */
unsigned char pad[256];
/* Buffer for EE public key data. */
unsigned char ee_pkey_data[BR_X509_BUFSIZE_KEY];
/* Buffer for currently decoded public key. */
unsigned char pkey_data[BR_X509_BUFSIZE_KEY];
/* Signature type: signer key type, offset to the hash
function OID (in the T0 data block) and hash function
output length (TBS hash length). */
unsigned char cert_signer_key_type;
uint16_t cert_sig_hash_oid;
unsigned char cert_sig_hash_len;
/* Current/last certificate signature. */
unsigned char cert_sig[BR_X509_BUFSIZE_SIG];
uint16_t cert_sig_len;
/* Minimum RSA key length (difference in bytes from 128). */
int16_t min_rsa_size;
/* Configured trust anchors. */
const br_x509_trust_anchor *trust_anchors;
size_t trust_anchors_num;
/*
* Multi-hasher for the TBS.
*/
unsigned char do_mhash;
br_multihash_context mhash;
unsigned char tbs_hash[64];
/*
* Simple hasher for the subject/issuer DN.
*/
unsigned char do_dn_hash;
const br_hash_class *dn_hash_impl;
br_hash_compat_context dn_hash;
unsigned char current_dn_hash[64];
unsigned char next_dn_hash[64];
unsigned char saved_dn_hash[64];
/*
* Public key cryptography implementations (signature verification).
*/
br_rsa_pkcs1_vrfy irsa;
br_ecdsa_vrfy iecdsa;
const br_ec_impl *iec;
} br_x509_minimal_context;
extern const br_x509_class br_x509_minimal_vtable;
/*
* Initialize a "minimal" X.509 engine. Parameters are:
* -- context to initialize
* -- hash function to use for hashing normalized DN
* -- list of trust anchors
*
* After initialization, some hash function implementations for signature
* verification MUST be added.
*/
void br_x509_minimal_init(br_x509_minimal_context *ctx,
const br_hash_class *dn_hash_impl,
const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num);
/*
* Set a hash function implementation, identified by ID, for purposes of
* verifying signatures on certificates. This must be called after
* br_x509_minimal_init().
*/
static inline void
br_x509_minimal_set_hash(br_x509_minimal_context *ctx,
int id, const br_hash_class *impl)
{
br_multihash_setimpl(&ctx->mhash, id, impl);
}
/*
* Set a RSA implementation, for purposes of verifying signatures on
* certificates. This must be called after br_x509_minimal_init().
*/
static inline void
br_x509_minimal_set_rsa(br_x509_minimal_context *ctx,
br_rsa_pkcs1_vrfy irsa)
{
ctx->irsa = irsa;
}
/*
* Set an ECDSA implementation, for purposes of verifying signatures on
* certificates. This must be called after br_x509_minimal_init().
*/
static inline void
br_x509_minimal_set_ecdsa(br_x509_minimal_context *ctx,
const br_ec_impl *iec, br_ecdsa_vrfy iecdsa)
{
ctx->iecdsa = iecdsa;
ctx->iec = iec;
}
/*
* Set the validation time, normally to the current date and time.
* This consists in two 32-bit counts:
*
* -- Days are counted in a proleptic Gregorian calendar since
* January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD";
* it is also traditionally known as "1 BC".
*
* -- Seconds are counted since midnight, from 0 to 86400 (a count of
* 86400 is possible only if a leap second happened).
*
* If the validation date and time are not explicitly set, but BearSSL
* was compiled with support for the system clock on the underlying
* platform, then the current time will automatically be used. Otherwise,
* validation will fail (except in case of direct trust of the EE key).
*/
static inline void
br_x509_minimal_set_time(br_x509_minimal_context *ctx,
uint32_t days, uint32_t seconds)
{
ctx->days = days;
ctx->seconds = seconds;
}
/*
* Set the minimal acceptable length for RSA keys, in bytes. Default
* is 128 bytes, which means RSA keys of 1017 bits or more. This setting
* applies to keys extracted from certificates (EE and intermediate CA).
* It does _not_ apply to "CA" trust anchors.
*/
static inline void
br_x509_minimal_set_minrsa(br_x509_minimal_context *ctx, int byte_length)
{
ctx->min_rsa_size = (int16_t)(byte_length - 128);
}
/*
* An X.509 decoder context. This is not for X.509 validation, but for
* using certificates as trust anchors (e.g. self-signed certificates
* read from files).
*/
typedef struct {
/* Structure for returning the public key. */
br_x509_pkey pkey;
/* CPU for the T0 virtual machine. */
struct {
uint32_t *dp;
uint32_t *rp;
const unsigned char *ip;
} cpu;
uint32_t dp_stack[32];
uint32_t rp_stack[32];
int err;
/* The pad serves as destination for various operations. */
unsigned char pad[256];
/* Flag set when decoding succeeds. */
unsigned char decoded;
/* Validity dates. */
uint32_t notbefore_days, notbefore_seconds;
uint32_t notafter_days, notafter_seconds;
/* The "CA" flag. This is set to true if the certificate contains
a Basic Constraints extension that asserts CA status. */
unsigned char isCA;
/* DN processing: the subject DN is extracted and pushed to the
provided callback. */
unsigned char copy_dn;
void *append_dn_ctx;
void (*append_dn)(void *ctx, const void *buf, size_t len);
/* Certificate data chunk. */
const unsigned char *hbuf;
size_t hlen;
/* Buffer for decoded public key. */
unsigned char pkey_data[BR_X509_BUFSIZE_KEY];
/* Type of key and hash function used in the certificate signature. */
unsigned char signer_key_type;
unsigned char signer_hash_id;
} br_x509_decoder_context;
/*
* Initialise an X.509 decoder context for processing a new certificate.
*/
void br_x509_decoder_init(br_x509_decoder_context *ctx,
void (*append_dn)(void *ctx, const void *buf, size_t len),
void *append_dn_ctx);
/*
* Push some certificate bytes into a decoder context.
*/
void br_x509_decoder_push(br_x509_decoder_context *ctx,
const void *data, size_t len);
/*
* Obtain the decoded public key. Returned value is a pointer to a
* structure internal to the decoder context; releasing or reusing the
* decoder context invalidates that structure.
*
* If decoding was not finished, or failed, then NULL is returned.
*/
static inline br_x509_pkey *
br_x509_decoder_get_pkey(br_x509_decoder_context *ctx)
{
if (ctx->decoded && ctx->err == 0) {
return &ctx->pkey;
} else {
return NULL;
}
}
/*
* Get decoder error. If no error was reported yet but the certificate
* decoding is not finished, then the error code is BR_ERR_X509_TRUNCATED.
* If decoding was successful, then 0 is returned.
*/
static inline int
br_x509_decoder_last_error(br_x509_decoder_context *ctx)
{
if (ctx->err != 0) {
return ctx->err;
}
if (!ctx->decoded) {
return BR_ERR_X509_TRUNCATED;
}
return 0;
}
/*
* Get the "isCA" flag from an X.509 decoder context. This flag is set
* if the decoded certificate claims to be a CA through a Basic
* Constraints extension.
*/
static inline int
br_x509_decoder_isCA(br_x509_decoder_context *ctx)
{
return ctx->isCA;
}
/*
* Get the issuing CA key type (type of key used to sign the decoded
* certificate). This is BR_KEYTYPE_RSA or BR_KEYTYPE_EC. The value 0
* is returned if the signature type was not recognised.
*/
static inline int
br_x509_decoder_get_signer_key_type(br_x509_decoder_context *ctx)
{
return ctx->signer_key_type;
}
/*
* Get the identifier for the hash function used to sign the decoded
* certificate. This is 0 if the hash function was not recognised.
*/
static inline int
br_x509_decoder_get_signer_hash_id(br_x509_decoder_context *ctx)
{
return ctx->signer_hash_id;
}
/*
* Type for an X.509 certificate (DER-encoded).
*/
typedef struct {
unsigned char *data;
size_t data_len;
} br_x509_certificate;
/*
* Private key decoder context.
*/
typedef struct {
/* Structure for returning the private key. */
union {
br_rsa_private_key rsa;
br_ec_private_key ec;
} key;
/* CPU for the T0 virtual machine. */
struct {
uint32_t *dp;
uint32_t *rp;
const unsigned char *ip;
} cpu;
uint32_t dp_stack[32];
uint32_t rp_stack[32];
int err;
/* Private key data chunk. */
const unsigned char *hbuf;
size_t hlen;
/* The pad serves as destination for various operations. */
unsigned char pad[256];
/* Decoded key type; 0 until decoding is complete. */
unsigned char key_type;
/* Buffer for the private key elements. It shall be large enough
to accommodate all elements for a RSA-4096 private key (roughly
five 2048-bit integers, possibly a bit more). */
unsigned char key_data[3 * BR_X509_BUFSIZE_SIG];
} br_skey_decoder_context;
/*
* Initialise a private key decoder context.
*/
void br_skey_decoder_init(br_skey_decoder_context *ctx);
/*
* Push some data bytes into a private key decoder context.
*/
void br_skey_decoder_push(br_skey_decoder_context *ctx,
const void *data, size_t len);
/*
* Get the decoding status for a private key. This is either 0 on success,
* or a non-zero error code.
*/
static inline int
br_skey_decoder_last_error(const br_skey_decoder_context *ctx)
{
if (ctx->err != 0) {
return ctx->err;
}
if (ctx->key_type == 0) {
return BR_ERR_X509_TRUNCATED;
}
return 0;
}
/*
* Get the decoded private key type. This is 0 if decoding is not finished
* or failed.
*/
static inline int
br_skey_decoder_key_type(const br_skey_decoder_context *ctx)
{
if (ctx->err == 0) {
return ctx->key_type;
} else {
return 0;
}
}
/*
* Get the decoded RSA private key. This function returns NULL if the
* decoding failed, or is not finished, or the key is not RSA. The returned
* pointer references structures within the context that can become
* invalid if the context is reused or released.
*/
static inline const br_rsa_private_key *
br_skey_decoder_get_rsa(const br_skey_decoder_context *ctx)
{
if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) {
return &ctx->key.rsa;
} else {
return NULL;
}
}
/*
* Get the decoded EC private key. This function returns NULL if the
* decoding failed, or is not finished, or the key is not EC. The returned
* pointer references structures within the context that can become
* invalid if the context is reused or released.
*/
static inline const br_ec_private_key *
br_skey_decoder_get_ec(const br_skey_decoder_context *ctx)
{
if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) {
return &ctx->key.ec;
} else {
return NULL;
}
}
#endif