Initial import.
This commit is contained in:
commit
3210f38e04
292 changed files with 58526 additions and 0 deletions
42
inc/bearssl.h
Normal file
42
inc/bearssl.h
Normal 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
476
inc/bearssl_block.h
Normal 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
220
inc/bearssl_ec.h
Normal 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
424
inc/bearssl_hash.h
Normal 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
148
inc/bearssl_hmac.h
Normal 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
125
inc/bearssl_pem.h
Normal 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
66
inc/bearssl_prf.h
Normal 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
149
inc/bearssl_rand.h
Normal 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
227
inc/bearssl_rsa.h
Normal 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
1856
inc/bearssl_ssl.h
Normal file
File diff suppressed because it is too large
Load diff
733
inc/bearssl_x509.h
Normal file
733
inc/bearssl_x509.h
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue