mirror of
https://github.com/status-im/BearSSL.git
synced 2025-02-23 07:58:08 +00:00
Added AES+GHASH implementation using AES-NI opcodes; also ARM-Thumb assembly for faster Montgomery multiplication on Cortex-M0+. Added selection functions for "default" implementations.
This commit is contained in:
parent
556e525d62
commit
5f045c7599
@ -53,7 +53,7 @@ LDDLLOUT = -o
|
||||
|
||||
# Static linker.
|
||||
LD = gcc
|
||||
LDFLAGS =
|
||||
LDFLAGS =
|
||||
LDOUT = -o
|
||||
|
||||
# C# compiler; we assume usage of Mono.
|
||||
|
12
conf/Unix32.mk
Normal file
12
conf/Unix32.mk
Normal file
@ -0,0 +1,12 @@
|
||||
# Example configuration file for compiling on a Unix-like system with
|
||||
# GCC, targeting a 32-bit output. Moreover, it enables the "LOMUL" setting
|
||||
# to make the code select the "small" integer implementations (i15, m15,
|
||||
# ctmul32...), which is not necessarily a good idea for performance, but
|
||||
# handy for tests.
|
||||
|
||||
include conf/Unix.mk
|
||||
|
||||
BUILD = build32
|
||||
CFLAGS = -W -Wall -Os -fPIC -m32 -DBR_LOMUL
|
||||
LDFLAGS = -m32
|
||||
LDDLLFLAGS = -shared -m32
|
9
conf/UnixClang.mk
Normal file
9
conf/UnixClang.mk
Normal file
@ -0,0 +1,9 @@
|
||||
# Example configuration file for compiling on a Unix-like system with
|
||||
# clang as compiler instead of gcc.
|
||||
|
||||
# We are on a Unix system so we assume a Single Unix compatible 'make'
|
||||
# utility, and Unix defaults.
|
||||
include conf/Unix.mk
|
||||
|
||||
BUILD = bclang
|
||||
CC = clang
|
@ -10,7 +10,7 @@ BUILD = samd20
|
||||
|
||||
# C compiler, linker, and static library builder.
|
||||
CC = arm-none-eabi-gcc
|
||||
CFLAGS = -W -Wall -Os -mthumb -ffunction-sections -fdata-sections -mcpu=cortex-m0plus
|
||||
CFLAGS = -W -Wall -Os -mthumb -ffunction-sections -fdata-sections -mcpu=cortex-m0plus -DBR_ARMEL_CORTEXM_GCC
|
||||
LD = arm-none-eabi-gcc
|
||||
AR = arm-none-eabi-ar
|
||||
|
||||
|
@ -191,6 +191,7 @@
|
||||
* | aes_small | AES | 16 | 16, 24 and 32 |
|
||||
* | aes_ct | AES | 16 | 16, 24 and 32 |
|
||||
* | aes_ct64 | AES | 16 | 16, 24 and 32 |
|
||||
* | aes_x86ni | AES | 16 | 16, 24 and 32 |
|
||||
* | des_ct | DES/3DES | 8 | 8, 16 and 24 |
|
||||
* | des_tab | DES/3DES | 8 | 8, 16 and 24 |
|
||||
*
|
||||
@ -223,6 +224,11 @@
|
||||
* is typically twice faster than `aes_ct` for modes that allow parallel
|
||||
* operations (i.e. CTR, and CBC decryption, but not CBC encryption).
|
||||
*
|
||||
* `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It
|
||||
* uses the AES-NI opcodes when available; if the opcodes are not present,
|
||||
* then it automatically fall backs on an appropriate constant-time
|
||||
* implementation (`aes_ct` for 32-bit, `aes_ct64` for 64-bit).
|
||||
*
|
||||
* `des_tab` is a classic, table-based implementation of DES/3DES. It
|
||||
* is not constant-time.
|
||||
*
|
||||
@ -994,6 +1000,219 @@ void br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, void *iv,
|
||||
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);
|
||||
|
||||
/*
|
||||
* AES implementation using AES-NI opcode (x86 platform). When the
|
||||
* opcodes are not present, this falls back to "ct" or "ct64" (depending
|
||||
* on architecture).
|
||||
*/
|
||||
|
||||
/** \brief AES block size (16 bytes). */
|
||||
#define br_aes_x86ni_BLOCK_SIZE 16
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_x86ni` implementation, CBC encryption).
|
||||
*
|
||||
* First field is a pointer to the vtable; it is set by the initialisation
|
||||
* function. Other fields are not supposed to be accessed by user code.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Pointer to vtable for this context. */
|
||||
const br_block_cbcenc_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
struct {
|
||||
uint32_t skey[60];
|
||||
} fallback_ct;
|
||||
struct {
|
||||
uint64_t skey[30];
|
||||
} fallback_ct64;
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_x86ni_cbcenc_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_x86ni` implementation, CBC decryption).
|
||||
*
|
||||
* First field is a pointer to the vtable; it is set by the initialisation
|
||||
* function. Other fields are not supposed to be accessed by user code.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Pointer to vtable for this context. */
|
||||
const br_block_cbcdec_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
struct {
|
||||
uint32_t skey[60];
|
||||
} fallback_ct;
|
||||
struct {
|
||||
uint64_t skey[30];
|
||||
} fallback_ct64;
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_x86ni_cbcdec_keys;
|
||||
|
||||
/**
|
||||
* \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption
|
||||
* and decryption).
|
||||
*
|
||||
* First field is a pointer to the vtable; it is set by the initialisation
|
||||
* function. Other fields are not supposed to be accessed by user code.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Pointer to vtable for this context. */
|
||||
const br_block_ctr_class *vtable;
|
||||
#ifndef BR_DOXYGEN_IGNORE
|
||||
union {
|
||||
unsigned char skni[16 * 15];
|
||||
struct {
|
||||
uint32_t skey[60];
|
||||
} fallback_ct;
|
||||
struct {
|
||||
uint64_t skey[30];
|
||||
} fallback_ct64;
|
||||
} skey;
|
||||
unsigned num_rounds;
|
||||
#endif
|
||||
} br_aes_x86ni_ctr_keys;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC encryption (`aes_x86ni` implementation).
|
||||
*
|
||||
* Since this implementation might be omitted from the library, or the
|
||||
* AES opcode unavailable on the current CPU, a pointer to this class
|
||||
* instance should be obtained through `br_aes_x86ni_cbcenc_get_vtable()`.
|
||||
*/
|
||||
extern const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CBC decryption (`aes_x86ni` implementation).
|
||||
*
|
||||
* Since this implementation might be omitted from the library, or the
|
||||
* AES opcode unavailable on the current CPU, a pointer to this class
|
||||
* instance should be obtained through `br_aes_x86ni_cbcdec_get_vtable()`.
|
||||
*/
|
||||
extern const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable;
|
||||
|
||||
/**
|
||||
* \brief Class instance for AES CTR encryption and decryption
|
||||
* (`aes_x86ni` implementation).
|
||||
*
|
||||
* Since this implementation might be omitted from the library, or the
|
||||
* AES opcode unavailable on the current CPU, a pointer to this class
|
||||
* instance should be obtained through `br_aes_x86ni_ctr_get_vtable()`.
|
||||
*/
|
||||
extern const br_block_ctr_class br_aes_x86ni_ctr_vtable;
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC encryption
|
||||
* (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CBC decryption
|
||||
* (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Context initialisation (key schedule) for AES CTR encryption
|
||||
* and decryption (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context to initialise.
|
||||
* \param key secret key.
|
||||
* \param len secret key length (in bytes).
|
||||
*/
|
||||
void br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx,
|
||||
const void *key, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC encryption with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param iv IV (updated).
|
||||
* \param data data to encrypt (updated).
|
||||
* \param len data length (in bytes, MUST be multiple of 16).
|
||||
*/
|
||||
void br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx, void *iv,
|
||||
void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CBC decryption with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param iv IV (updated).
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes, MUST be multiple of 16).
|
||||
*/
|
||||
void br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, void *iv,
|
||||
void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief CTR encryption and decryption with AES (`aes_x86ni` implementation).
|
||||
*
|
||||
* \param ctx context (already initialised).
|
||||
* \param iv IV (constant, 12 bytes).
|
||||
* \param cc initial block counter value.
|
||||
* \param data data to decrypt (updated).
|
||||
* \param len data length (in bytes).
|
||||
* \return new block counter value.
|
||||
*/
|
||||
uint32_t br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx,
|
||||
const void *iv, uint32_t cc, void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_x86ni` AES-CBC (encryption) implementation, if
|
||||
* available.
|
||||
*
|
||||
* This function returns a pointer to `br_aes_x86ni_cbcenc_vtable`, if
|
||||
* that implementation was compiled in the library _and_ the x86 AES
|
||||
* opcodes are available on the currently running CPU. If either of
|
||||
* these conditions is not met, then this function returns `NULL`.
|
||||
*
|
||||
* \return the `aes_x868ni` AES-CBC (encryption) implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_cbcenc_class *br_aes_x86ni_cbcenc_get_vtable(void);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_x86ni` AES-CBC (decryption) implementation, if
|
||||
* available.
|
||||
*
|
||||
* This function returns a pointer to `br_aes_x86ni_cbcdec_vtable`, if
|
||||
* that implementation was compiled in the library _and_ the x86 AES
|
||||
* opcodes are available on the currently running CPU. If either of
|
||||
* these conditions is not met, then this function returns `NULL`.
|
||||
*
|
||||
* \return the `aes_x868ni` AES-CBC (decryption) implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `aes_x86ni` AES-CTR implementation, if available.
|
||||
*
|
||||
* This function returns a pointer to `br_aes_x86ni_ctr_vtable`, if
|
||||
* that implementation was compiled in the library _and_ the x86 AES
|
||||
* opcodes are available on the currently running CPU. If either of
|
||||
* these conditions is not met, then this function returns `NULL`.
|
||||
*
|
||||
* \return the `aes_x868ni` AES-CTR implementation, or `NULL`.
|
||||
*/
|
||||
const br_block_ctr_class *br_aes_x86ni_ctr_get_vtable(void);
|
||||
|
||||
/**
|
||||
* \brief Aggregate structure large enough to be used as context for
|
||||
* subkeys (CBC encryption) for all AES implementations.
|
||||
@ -1004,6 +1223,7 @@ typedef union {
|
||||
br_aes_small_cbcenc_keys c_small;
|
||||
br_aes_ct_cbcenc_keys c_ct;
|
||||
br_aes_ct64_cbcenc_keys c_ct64;
|
||||
br_aes_x86ni_cbcenc_keys c_x86ni;
|
||||
} br_aes_gen_cbcenc_keys;
|
||||
|
||||
/**
|
||||
@ -1016,6 +1236,7 @@ typedef union {
|
||||
br_aes_small_cbcdec_keys c_small;
|
||||
br_aes_ct_cbcdec_keys c_ct;
|
||||
br_aes_ct64_cbcdec_keys c_ct64;
|
||||
br_aes_x86ni_cbcdec_keys c_x86ni;
|
||||
} br_aes_gen_cbcdec_keys;
|
||||
|
||||
/**
|
||||
@ -1028,6 +1249,7 @@ typedef union {
|
||||
br_aes_small_ctr_keys c_small;
|
||||
br_aes_ct_ctr_keys c_ct;
|
||||
br_aes_ct64_ctr_keys c_ct64;
|
||||
br_aes_x86ni_ctr_keys c_x86ni;
|
||||
} br_aes_gen_ctr_keys;
|
||||
|
||||
/*
|
||||
|
@ -512,6 +512,27 @@ extern const br_ec_impl br_ec_c25519_m31;
|
||||
*/
|
||||
extern const br_ec_impl br_ec_all_m15;
|
||||
|
||||
/**
|
||||
* \brief Aggregate EC implementation "m31".
|
||||
*
|
||||
* This implementation is a wrapper for:
|
||||
*
|
||||
* - `br_ec_c25519_m31` for Curve25519
|
||||
* - `br_ec_p256_m31` for NIST P-256
|
||||
* - `br_ec_prime_i31` for other curves (NIST P-384 and NIST-P512)
|
||||
*/
|
||||
extern const br_ec_impl br_ec_all_m31;
|
||||
|
||||
/**
|
||||
* \brief Get the "default" EC implementation for the current system.
|
||||
*
|
||||
* This returns a pointer to the preferred implementation on the
|
||||
* current system.
|
||||
*
|
||||
* \return the default EC implementation.
|
||||
*/
|
||||
const br_ec_impl *br_ec_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief Convert a signature from "raw" to "asn1".
|
||||
*
|
||||
@ -732,4 +753,44 @@ uint32_t br_ecdsa_i15_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);
|
||||
|
||||
/**
|
||||
* \brief Get "default" ECDSA implementation (signer, asn1 format).
|
||||
*
|
||||
* This returns the preferred implementation of ECDSA signature generation
|
||||
* ("asn1" output format) on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_ecdsa_sign br_ecdsa_sign_asn1_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief Get "default" ECDSA implementation (signer, raw format).
|
||||
*
|
||||
* This returns the preferred implementation of ECDSA signature generation
|
||||
* ("raw" output format) on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_ecdsa_sign br_ecdsa_sign_raw_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief Get "default" ECDSA implementation (verifier, asn1 format).
|
||||
*
|
||||
* This returns the preferred implementation of ECDSA signature verification
|
||||
* ("asn1" output format) on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief Get "default" ECDSA implementation (verifier, raw format).
|
||||
*
|
||||
* This returns the preferred implementation of ECDSA signature verification
|
||||
* ("raw" output format) on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void);
|
||||
|
||||
#endif
|
||||
|
@ -1279,4 +1279,34 @@ void br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len);
|
||||
*/
|
||||
void br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief GHASH implementation using the `pclmulqdq` opcode (part of the
|
||||
* AES-NI instructions).
|
||||
*
|
||||
* This implementation is available only on x86 platforms where the
|
||||
* compiler supports the relevant intrinsic functions. Even if the
|
||||
* compiler supports these functions, the local CPU might not support
|
||||
* the `pclmulqdq` opcode, meaning that a call will fail with an
|
||||
* illegal instruction exception. To safely obtain a pointer to this
|
||||
* function when supported (or 0 otherwise), use `br_ghash_pclmul_get()`.
|
||||
*
|
||||
* \param y the array to update.
|
||||
* \param h the GHASH key.
|
||||
* \param data the input data (may be `NULL` if `len` is zero).
|
||||
* \param len the input data length (in bytes).
|
||||
*/
|
||||
void br_ghash_pclmul(void *y, const void *h, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Obtain the `pclmul` GHASH implementation, if available.
|
||||
*
|
||||
* If the `pclmul` implementation was compiled in the library (depending
|
||||
* on the compiler abilities) _and_ the local CPU appears to support the
|
||||
* opcode, then this function will return a pointer to the
|
||||
* `br_ghash_pclmul()` function. Otherwise, it will return `0`.
|
||||
*
|
||||
* \return the `pclmul` GHASH implementation, or `0`.
|
||||
*/
|
||||
br_ghash br_ghash_pclmul_get(void);
|
||||
|
||||
#endif
|
||||
|
@ -515,6 +515,46 @@ uint32_t br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
const br_rsa_private_key *sk, unsigned char *x);
|
||||
|
||||
/**
|
||||
* \brief Get "default" RSA implementation (public-key operations).
|
||||
*
|
||||
* This returns the preferred implementation of RSA (public-key operations)
|
||||
* on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_rsa_public br_rsa_public_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief Get "default" RSA implementation (private-key operations).
|
||||
*
|
||||
* This returns the preferred implementation of RSA (private-key operations)
|
||||
* on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_rsa_private br_rsa_private_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief Get "default" RSA implementation (PKCS#1 signature verification).
|
||||
*
|
||||
* This returns the preferred implementation of RSA (signature verification)
|
||||
* on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_rsa_pkcs1_vrfy br_rsa_pkcs1_vrfy_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief Get "default" RSA implementation (PKCS#1 signature generation).
|
||||
*
|
||||
* This returns the preferred implementation of RSA (signature generation)
|
||||
* on the current system.
|
||||
*
|
||||
* \return the default implementation.
|
||||
*/
|
||||
br_rsa_pkcs1_sign br_rsa_pkcs1_sign_get_default(void);
|
||||
|
||||
/**
|
||||
* \brief RSA decryption helper, for SSL/TLS.
|
||||
*
|
||||
|
@ -1321,6 +1321,18 @@ br_ssl_engine_set_aes_cbc(br_ssl_engine_context *cc,
|
||||
cc->iaes_cbcdec = impl_dec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" AES/CBC implementations.
|
||||
*
|
||||
* This function configures in the engine the AES implementations that
|
||||
* should provide best runtime performance on the local system, while
|
||||
* still being safe (in particular, constant-time). It also sets the
|
||||
* handlers for CBC records.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
*/
|
||||
void br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Set the AES/CTR implementation.
|
||||
*
|
||||
@ -1334,6 +1346,18 @@ br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc,
|
||||
cc->iaes_ctr = impl;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" implementations for AES/GCM (AES/CTR + GHASH).
|
||||
*
|
||||
* This function configures in the engine the AES/CTR and GHASH
|
||||
* implementation that should provide best runtime performance on the local
|
||||
* system, while still being safe (in particular, constant-time). It also
|
||||
* sets the handlers for GCM records.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
*/
|
||||
void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Set the DES/CBC implementations.
|
||||
*
|
||||
@ -1350,6 +1374,18 @@ br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc,
|
||||
cc->ides_cbcdec = impl_dec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" DES/CBC implementations.
|
||||
*
|
||||
* This function configures in the engine the DES implementations that
|
||||
* should provide best runtime performance on the local system, while
|
||||
* still being safe (in particular, constant-time). It also sets the
|
||||
* handlers for CBC records.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
*/
|
||||
void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Set the GHASH implementation (used in GCM mode).
|
||||
*
|
||||
@ -1388,6 +1424,18 @@ br_ssl_engine_set_poly1305(br_ssl_engine_context *cc,
|
||||
cc->ipoly = ipoly;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" ChaCha20 and Poly1305 implementations.
|
||||
*
|
||||
* This function configures in the engine the ChaCha20 and Poly1305
|
||||
* implementations that should provide best runtime performance on the
|
||||
* local system, while still being safe (in particular, constant-time).
|
||||
* It also sets the handlers for ChaCha20+Poly1305 records.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
*/
|
||||
void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Set the record encryption and decryption engines for CBC + HMAC.
|
||||
*
|
||||
@ -1452,6 +1500,29 @@ br_ssl_engine_set_ec(br_ssl_engine_context *cc, const br_ec_impl *iec)
|
||||
cc->iec = iec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" EC implementation.
|
||||
*
|
||||
* This function sets the elliptic curve implementation for ECDH and
|
||||
* ECDHE cipher suites, and for ECDSA support. It selects the fastest
|
||||
* implementation on the current system.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
*/
|
||||
void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Get the EC implementation configured in the provided engine.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
* \return the EC implementation.
|
||||
*/
|
||||
static inline const br_ec_impl *
|
||||
br_ssl_engine_get_ec(br_ssl_engine_context *cc)
|
||||
{
|
||||
return cc->iec;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the RSA signature verification implementation.
|
||||
*
|
||||
@ -1469,6 +1540,29 @@ br_ssl_engine_set_rsavrfy(br_ssl_engine_context *cc, br_rsa_pkcs1_vrfy irsavrfy)
|
||||
cc->irsavrfy = irsavrfy;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" RSA implementation (signature verification).
|
||||
*
|
||||
* This function sets the RSA implementation (signature verification)
|
||||
* to the fastest implementation available on the current platform.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
*/
|
||||
void br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Get the RSA implementation (signature verification) configured
|
||||
* in the provided engine.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
* \return the RSA signature verification implementation.
|
||||
*/
|
||||
static inline br_rsa_pkcs1_vrfy
|
||||
br_ssl_engine_get_rsavrfy(br_ssl_engine_context *cc)
|
||||
{
|
||||
return cc->irsavrfy;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Set the ECDSA implementation (signature verification).
|
||||
*
|
||||
@ -1490,6 +1584,31 @@ br_ssl_engine_set_ecdsa(br_ssl_engine_context *cc, br_ecdsa_vrfy iecdsa)
|
||||
cc->iecdsa = iecdsa;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" ECDSA implementation (signature verification).
|
||||
*
|
||||
* This function sets the ECDSA implementation (signature verification)
|
||||
* to the fastest implementation available on the current platform. This
|
||||
* call also sets the elliptic curve implementation itself, there again
|
||||
* to the fastest EC implementation available.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
*/
|
||||
void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Get the ECDSA implementation (signature verification) configured
|
||||
* in the provided engine.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
* \return the ECDSA signature verification implementation.
|
||||
*/
|
||||
static inline br_ecdsa_vrfy
|
||||
br_ssl_engine_get_ecdsa(br_ssl_engine_context *cc)
|
||||
{
|
||||
return cc->iecdsa;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the I/O buffer for the SSL engine.
|
||||
*
|
||||
@ -2457,6 +2576,17 @@ br_ssl_client_set_rsapub(br_ssl_client_context *cc, br_rsa_public irsapub)
|
||||
cc->irsapub = irsapub;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the "default" RSA implementation for public-key operations.
|
||||
*
|
||||
* This sets the RSA implementation in the client context (for encrypting
|
||||
* the pre-master secret, in `TLS_RSA_*` cipher suites) to the fastest
|
||||
* available on the current platform.
|
||||
*
|
||||
* \param cc client context.
|
||||
*/
|
||||
void br_ssl_client_set_default_rsapub(br_ssl_client_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Set the minimum ClientHello length (RFC 7685 padding).
|
||||
*
|
||||
@ -3165,8 +3295,9 @@ struct br_ssl_server_context_ {
|
||||
* 3 = TLS 1.2 with SHA-384
|
||||
* -- character 3: encryption
|
||||
* a = AES/CBC
|
||||
* g = AES/GCM
|
||||
* d = 3DES/CBC
|
||||
* g = AES/GCM
|
||||
* c = ChaCha20+Poly1305
|
||||
*/
|
||||
|
||||
/**
|
||||
|
68
mk/Rules.mk
68
mk/Rules.mk
File diff suppressed because one or more lines are too long
@ -70,6 +70,7 @@ coresrc=" \
|
||||
src/ec/ec_c25519_m15.c \
|
||||
src/ec/ec_c25519_m31.c \
|
||||
src/ec/ec_curve25519.c \
|
||||
src/ec/ec_default.c \
|
||||
src/ec/ec_p256_m15.c \
|
||||
src/ec/ec_p256_m31.c \
|
||||
src/ec/ec_prime_i15.c \
|
||||
@ -78,6 +79,10 @@ coresrc=" \
|
||||
src/ec/ec_secp384r1.c \
|
||||
src/ec/ec_secp521r1.c \
|
||||
src/ec/ecdsa_atr.c \
|
||||
src/ec/ecdsa_default_sign_asn1.c \
|
||||
src/ec/ecdsa_default_sign_raw.c \
|
||||
src/ec/ecdsa_default_vrfy_asn1.c \
|
||||
src/ec/ecdsa_default_vrfy_raw.c \
|
||||
src/ec/ecdsa_i15_bits.c \
|
||||
src/ec/ecdsa_i15_sign_asn1.c \
|
||||
src/ec/ecdsa_i15_sign_raw.c \
|
||||
@ -94,6 +99,7 @@ coresrc=" \
|
||||
src/hash/ghash_ctmul.c \
|
||||
src/hash/ghash_ctmul32.c \
|
||||
src/hash/ghash_ctmul64.c \
|
||||
src/hash/ghash_pclmul.c \
|
||||
src/hash/md5.c \
|
||||
src/hash/md5sha1.c \
|
||||
src/hash/multihash.c \
|
||||
@ -155,6 +161,10 @@ coresrc=" \
|
||||
src/mac/hmac.c \
|
||||
src/mac/hmac_ct.c \
|
||||
src/rand/hmac_drbg.c \
|
||||
src/rsa/rsa_default_pkcs1_sign.c \
|
||||
src/rsa/rsa_default_pkcs1_vrfy.c \
|
||||
src/rsa/rsa_default_priv.c \
|
||||
src/rsa/rsa_default_pub.c \
|
||||
src/rsa/rsa_i15_pkcs1_sign.c \
|
||||
src/rsa/rsa_i15_pkcs1_vrfy.c \
|
||||
src/rsa/rsa_i15_priv.c \
|
||||
@ -177,8 +187,16 @@ coresrc=" \
|
||||
src/ssl/ssl_ccert_single_ec.c \
|
||||
src/ssl/ssl_ccert_single_rsa.c \
|
||||
src/ssl/ssl_client.c \
|
||||
src/ssl/ssl_client_default_rsapub.c \
|
||||
src/ssl/ssl_client_full.c \
|
||||
src/ssl/ssl_engine.c \
|
||||
src/ssl/ssl_engine_default_aescbc.c \
|
||||
src/ssl/ssl_engine_default_aesgcm.c \
|
||||
src/ssl/ssl_engine_default_chapol.c \
|
||||
src/ssl/ssl_engine_default_descbc.c \
|
||||
src/ssl/ssl_engine_default_ec.c \
|
||||
src/ssl/ssl_engine_default_ecdsa.c \
|
||||
src/ssl/ssl_engine_default_rsavrfy.c \
|
||||
src/ssl/ssl_hashes.c \
|
||||
src/ssl/ssl_hs_client.c \
|
||||
src/ssl/ssl_hs_server.c \
|
||||
@ -222,6 +240,10 @@ coresrc=" \
|
||||
src/symcipher/aes_small_ctr.c \
|
||||
src/symcipher/aes_small_dec.c \
|
||||
src/symcipher/aes_small_enc.c \
|
||||
src/symcipher/aes_x86ni.c \
|
||||
src/symcipher/aes_x86ni_cbcdec.c \
|
||||
src/symcipher/aes_x86ni_cbcenc.c \
|
||||
src/symcipher/aes_x86ni_ctr.c \
|
||||
src/symcipher/chacha20_ct.c \
|
||||
src/symcipher/des_ct.c \
|
||||
src/symcipher/des_ct_cbcdec.c \
|
||||
|
@ -53,6 +53,8 @@ example_client_profile(br_ssl_client_context *cc
|
||||
* by BearSSL; trim it done to your needs.
|
||||
*/
|
||||
static const uint16_t suites[] = {
|
||||
BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
@ -133,6 +135,15 @@ example_client_profile(br_ssl_client_context *cc
|
||||
* -- With TLS 1.2, cipher suites with a name ending in "SHA"
|
||||
* require both SHA-256 and SHA-1.
|
||||
*
|
||||
* Moreover, these hash functions are also used to compute
|
||||
* hashes supporting signatures on the server side (for ECDHE_*
|
||||
* cipher suites), and on the client side (for client
|
||||
* certificates, except in the case of full static ECDH). In TLS
|
||||
* 1.0 and 1.1, SHA-1 (and also MD5) will be used, but with TLS
|
||||
* 1.2 these hash functions are negotiated between client and
|
||||
* server; SHA-256 and/or SHA-384 should be sufficient in
|
||||
* practice.
|
||||
*
|
||||
* Note that with current implementations, SHA-224 and SHA-256
|
||||
* share the same file, so if you use one, you may have the other
|
||||
* one with no additional overhead. Similarly, SHA-384 and SHA-512
|
||||
@ -168,14 +179,46 @@ example_client_profile(br_ssl_client_context *cc
|
||||
* cipher suites).
|
||||
*
|
||||
* -- ECDSA signature verification is needed for "ECDHE_ECDSA"
|
||||
* cipher suites (but not for ECDH_ECDSA or ECDH_RSA).
|
||||
* cipher suites (but not for ECDHE_RSA, ECDH_ECDSA or ECDH_RSA).
|
||||
*
|
||||
* The RSA code comes in two variants, called "i31" and "i32".
|
||||
* Right now, the "i31" is somewhat faster.
|
||||
* The RSA code comes in three variants, called "i15", "i31" and
|
||||
* "i32". The "i31" code is somewhat faster than the "i32" code.
|
||||
* Usually, "i31" is faster than "i15", except on some specific
|
||||
* architectures (ARM Cortex M0, M0+, M1 and M3) where the "i15"
|
||||
* should be prefered (the "i15" code is constant-time, while
|
||||
* the "i31" is not, and the "i15" code is faster anyway).
|
||||
*
|
||||
* ECDSA code also comes in "i15" and "i31" variants. As in the
|
||||
* case of RSA, the "i31" code is faster, except on the small
|
||||
* ARM Cortex M, where the "i15" code is faster and safer.
|
||||
*
|
||||
* There are no less than 10 elliptic curve implementations:
|
||||
*
|
||||
* - ec_c25519_i15, ec_c25519_i31, ec_c25519_m15 and ec_c25519_m31
|
||||
* implement Curve25519.
|
||||
*
|
||||
* - ec_p256_m15 and ec_p256_m31 implement NIST curve P-256.
|
||||
*
|
||||
* - ec_prime_i15 and ec_prime_i31 implement NIST curves P-256,
|
||||
* P-384 and P-521.
|
||||
*
|
||||
* - ec_all_m15 is an aggregate implementation that uses
|
||||
* ec_c25519_m15, ec_p256_m15 and ec_prime_i15.
|
||||
*
|
||||
* - ec_all_m31 is an aggregate implementation that uses
|
||||
* ec_c25519_m31, ec_p256_m31 and ec_prime_i31.
|
||||
*
|
||||
* For a given curve, "m15" is faster than "i15" (but possibly
|
||||
* with a larger code footprint) and "m31" is faster than "i31"
|
||||
* (there again with a larger code footprint). For best
|
||||
* performance, use ec_all_m31, except on the small ARM Cortex M
|
||||
* where ec_all_m15 should be used. Referencing the other
|
||||
* implementations directly will result in smaller code, but
|
||||
* support for fewer curves and possibly lower performance.
|
||||
*/
|
||||
br_ssl_client_set_rsapub(cc, &br_rsa_i31_public);
|
||||
br_ssl_client_set_rsavrfy(cc, &br_rsa_i31_pkcs1_vrfy);
|
||||
br_ssl_engine_set_ec(&cc->eng, &br_ec_prime_i31);
|
||||
br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m31);
|
||||
br_ssl_client_set_ecdsa(cc, &br_ecdsa_i31_vrfy_asn1);
|
||||
|
||||
/*
|
||||
@ -184,6 +227,8 @@ example_client_profile(br_ssl_client_context *cc
|
||||
* need the CBC record handler ("set_cbc").
|
||||
* -- Cipher suites in AES_128_GCM and AES_256_GCM need the GCM
|
||||
* record handler ("set_gcm").
|
||||
* -- Cipher suites in CHACHA20_POLY1305 need the ChaCha20+Poly1305
|
||||
* record handler ("set_chapol").
|
||||
*/
|
||||
br_ssl_engine_set_cbc(&cc->eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
@ -191,6 +236,9 @@ example_client_profile(br_ssl_client_context *cc
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_chapol(&cc->eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
|
||||
/*
|
||||
* Symmetric encryption:
|
||||
@ -230,6 +278,9 @@ example_client_profile(br_ssl_client_context *cc
|
||||
* is decently fast and still resonably compact,
|
||||
* but it is not constant-time.
|
||||
*
|
||||
* aes_x86ni Very fast implementation that uses the AES-NI
|
||||
* opcodes on recent x86 CPU.
|
||||
*
|
||||
* Whether having constant-time implementations is absolutely
|
||||
* required for security depends on the context (in particular
|
||||
* whether the target architecture actually has cache memory),
|
||||
|
35
src/config.h
35
src/config.h
@ -41,6 +41,16 @@
|
||||
#define BR_64 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* When BR_LOMUL is enabled, then multiplications of 32-bit values whose
|
||||
* result are truncated to the low 32 bits are assumed to be
|
||||
* substantially more efficient than 32-bit multiplications that yield
|
||||
* 64-bit results. This is typically the case on low-end ARM Cortex M
|
||||
* systems (M0, M0+, M1, and arguably M3 and M4 as well).
|
||||
*
|
||||
#define BR_LOMUL 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* When BR_SLOW_MUL is enabled, multiplications are assumed to be
|
||||
* substantially slow with regards to other integer operations, thus
|
||||
@ -127,4 +137,29 @@
|
||||
#define BR_USE_WIN32_TIME 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* When BR_ARMEL_CORTEXM_GCC is enabled, some operations are replaced with
|
||||
* inline assembly which is shorter and/or faster. This should be used
|
||||
* only when all of the following are true:
|
||||
* - target architecture is ARM in Thumb mode
|
||||
* - target endianness is little-endian
|
||||
* - compiler is GCC (or GCC-compatible for inline assembly syntax)
|
||||
*
|
||||
* This is meant for the low-end cores (Cortex M0, M0+, M1, M3).
|
||||
* Note: if BR_LOMUL is not explicitly enabled or disabled, then
|
||||
* enabling BR_ARMEL_CORTEXM_GCC also enables BR_LOMUL.
|
||||
*
|
||||
#define BR_ARMEL_CORTEXM_GCC 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* When BR_AES_X86NI is enabled, the AES implementation using the x86 "NI"
|
||||
* instructions (dedicated AES opcodes) will be compiled. If this is not
|
||||
* enabled explicitly, then that AES implementation will be compiled only
|
||||
* if a compatible compiler is detected. If set explicitly to 0, the
|
||||
* implementation will not be compiled at all.
|
||||
*
|
||||
#define BR_AES_X86NI 1
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
36
src/ec/ec_default.c
Normal file
36
src/ec/ec_default.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ec.h */
|
||||
const br_ec_impl *
|
||||
br_ec_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_ec_all_m15;
|
||||
#else
|
||||
return &br_ec_all_m31;
|
||||
#endif
|
||||
}
|
36
src/ec/ecdsa_default_sign_asn1.c
Normal file
36
src/ec/ecdsa_default_sign_asn1.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ec.h */
|
||||
br_ecdsa_sign
|
||||
br_ecdsa_sign_asn1_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_ecdsa_i15_sign_asn1;
|
||||
#else
|
||||
return &br_ecdsa_i31_sign_asn1;
|
||||
#endif
|
||||
}
|
36
src/ec/ecdsa_default_sign_raw.c
Normal file
36
src/ec/ecdsa_default_sign_raw.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ec.h */
|
||||
br_ecdsa_sign
|
||||
br_ecdsa_sign_raw_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_ecdsa_i15_sign_raw;
|
||||
#else
|
||||
return &br_ecdsa_i31_sign_raw;
|
||||
#endif
|
||||
}
|
36
src/ec/ecdsa_default_vrfy_asn1.c
Normal file
36
src/ec/ecdsa_default_vrfy_asn1.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ec.h */
|
||||
br_ecdsa_vrfy
|
||||
br_ecdsa_vrfy_asn1_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_ecdsa_i15_vrfy_asn1;
|
||||
#else
|
||||
return &br_ecdsa_i31_vrfy_asn1;
|
||||
#endif
|
||||
}
|
36
src/ec/ecdsa_default_vrfy_raw.c
Normal file
36
src/ec/ecdsa_default_vrfy_raw.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ec.h */
|
||||
br_ecdsa_vrfy
|
||||
br_ecdsa_vrfy_raw_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_ecdsa_i15_vrfy_raw;
|
||||
#else
|
||||
return &br_ecdsa_i31_vrfy_raw;
|
||||
#endif
|
||||
}
|
253
src/hash/ghash_pclmul.c
Normal file
253
src/hash/ghash_pclmul.c
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/*
|
||||
* This is the GHASH implementation that leverages the pclmulqdq opcode
|
||||
* (from the AES-NI instructions).
|
||||
*/
|
||||
|
||||
#if BR_AES_X86NI
|
||||
|
||||
#if BR_AES_X86NI_GCC
|
||||
/* #pragma GCC target "sse2,ssse3,pclmul" */
|
||||
#include <tmmintrin.h>
|
||||
#include <wmmintrin.h>
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#if BR_AES_X86NI_MSC
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
/* see bearssl_hash.h */
|
||||
BR_TARGET("ssse3,pclmul")
|
||||
void
|
||||
br_ghash_pclmul(void *y, const void *h, const void *data, size_t len)
|
||||
{
|
||||
/*
|
||||
* TODO: loop below processes one 16-bit word at a time. We
|
||||
* could parallelize, using:
|
||||
* ((y+x0)*h+x1)*h = (y+x0)*(h^2) + x1*h
|
||||
* i.e. precompute h^2, then handle two words at a time, mostly
|
||||
* in parallel (this may extend to more words as well...).
|
||||
*/
|
||||
|
||||
const unsigned char *buf;
|
||||
__m128i yx, hx;
|
||||
__m128i h0, h1, h2;
|
||||
__m128i byteswap_index;
|
||||
|
||||
byteswap_index = _mm_set_epi8(
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
||||
yx = _mm_loadu_si128(y);
|
||||
hx = _mm_loadu_si128(h);
|
||||
yx = _mm_shuffle_epi8(yx, byteswap_index);
|
||||
hx = _mm_shuffle_epi8(hx, byteswap_index);
|
||||
|
||||
/*
|
||||
* We byte-swap y and h for full big-endian interpretation
|
||||
* (see below).
|
||||
*/
|
||||
|
||||
h0 = hx;
|
||||
h1 = _mm_shuffle_epi32(hx, 0x0E);
|
||||
h2 = _mm_xor_si128(h0, h1);
|
||||
|
||||
buf = data;
|
||||
while (len > 0) {
|
||||
__m128i x;
|
||||
__m128i t0, t1, t2, v0, v1, v2, v3;
|
||||
__m128i y0, y1, y2;
|
||||
|
||||
/*
|
||||
* Load next 128-bit word. If there are not enough bytes
|
||||
* for the next word, we pad it with zeros (as per the
|
||||
* API for this function; it's also what is useful for
|
||||
* implementation of GCM).
|
||||
*/
|
||||
if (len >= 16) {
|
||||
x = _mm_loadu_si128((const void *)buf);
|
||||
buf += 16;
|
||||
len -= 16;
|
||||
} else {
|
||||
unsigned char tmp[16];
|
||||
|
||||
memcpy(tmp, buf, len);
|
||||
memset(tmp + len, 0, (sizeof tmp) - len);
|
||||
x = _mm_loadu_si128((void *)tmp);
|
||||
len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Specification of GCM is basically "full little-endian",
|
||||
* i.e. leftmost bit is most significant; but decoding
|
||||
* performed by _mm_loadu_si128 is "mixed endian" (leftmost
|
||||
* _byte_ is least significant, but within each byte, the
|
||||
* leftmost _bit_ is most significant). We could reverse
|
||||
* bits in each byte; however, it is more efficient to
|
||||
* swap the bytes and thus emulate full big-endian
|
||||
* decoding.
|
||||
*
|
||||
* Big-endian works here because multiplication in
|
||||
* GF[2](X) is "carry-less", thereby allowing reversal:
|
||||
* if rev_n(x) consists in reversing the order of bits
|
||||
* in x, then:
|
||||
* rev_128(A)*rev_128(B) = rev_255(A*B)
|
||||
* so we can compute A*B by using rev_128(A) and rev_128(B),
|
||||
* and an extra shift at the end (because 255 != 256). Bit
|
||||
* reversal is exactly what happens when converting from
|
||||
* full little-endian to full big-endian.
|
||||
*/
|
||||
x = _mm_shuffle_epi8(x, byteswap_index);
|
||||
yx = _mm_xor_si128(yx, x);
|
||||
|
||||
/*
|
||||
* We want the product to be broken down into four
|
||||
* 64-bit values, because there is no SSE* opcode that
|
||||
* can do a shift on a 128-bit value.
|
||||
*/
|
||||
y0 = yx;
|
||||
y1 = _mm_shuffle_epi32(yx, 0x0E);
|
||||
y2 = _mm_xor_si128(y0, y1);
|
||||
t0 = _mm_clmulepi64_si128(y0, h0, 0x00);
|
||||
t1 = _mm_clmulepi64_si128(yx, hx, 0x11);
|
||||
t2 = _mm_clmulepi64_si128(y2, h2, 0x00);
|
||||
t2 = _mm_xor_si128(t2, _mm_xor_si128(t0, t1));
|
||||
v0 = t0;
|
||||
v1 = _mm_xor_si128(_mm_shuffle_epi32(t0, 0x0E), t2);
|
||||
v2 = _mm_xor_si128(t1, _mm_shuffle_epi32(t2, 0x0E));
|
||||
v3 = _mm_shuffle_epi32(t1, 0x0E);
|
||||
|
||||
/*
|
||||
* Do the corrective 1-bit shift (255->256).
|
||||
*/
|
||||
v3 = _mm_or_si128(
|
||||
_mm_slli_epi64(v3, 1),
|
||||
_mm_srli_epi64(v2, 63));
|
||||
v2 = _mm_or_si128(
|
||||
_mm_slli_epi64(v2, 1),
|
||||
_mm_srli_epi64(v1, 63));
|
||||
v1 = _mm_or_si128(
|
||||
_mm_slli_epi64(v1, 1),
|
||||
_mm_srli_epi64(v0, 63));
|
||||
v0 = _mm_slli_epi64(v0, 1);
|
||||
|
||||
/*
|
||||
* Perform polynomial reduction into GF(2^128).
|
||||
*/
|
||||
v2 = _mm_xor_si128(
|
||||
v2,
|
||||
_mm_xor_si128(
|
||||
_mm_xor_si128(
|
||||
v0,
|
||||
_mm_srli_epi64(v0, 1)),
|
||||
_mm_xor_si128(
|
||||
_mm_srli_epi64(v0, 2),
|
||||
_mm_srli_epi64(v0, 7))));
|
||||
v1 = _mm_xor_si128(
|
||||
_mm_xor_si128(
|
||||
v1,
|
||||
_mm_slli_epi64(v0, 63)),
|
||||
_mm_xor_si128(
|
||||
_mm_slli_epi64(v0, 62),
|
||||
_mm_slli_epi64(v0, 57)));
|
||||
v3 = _mm_xor_si128(
|
||||
v3,
|
||||
_mm_xor_si128(
|
||||
_mm_xor_si128(
|
||||
v1,
|
||||
_mm_srli_epi64(v1, 1)),
|
||||
_mm_xor_si128(
|
||||
_mm_srli_epi64(v1, 2),
|
||||
_mm_srli_epi64(v1, 7))));
|
||||
v2 = _mm_xor_si128(
|
||||
_mm_xor_si128(
|
||||
v2,
|
||||
_mm_slli_epi64(v1, 63)),
|
||||
_mm_xor_si128(
|
||||
_mm_slli_epi64(v1, 62),
|
||||
_mm_slli_epi64(v1, 57)));
|
||||
|
||||
/*
|
||||
* We reduced toward the high words (v2 and v3), which
|
||||
* are the new value for y.
|
||||
*/
|
||||
yx = _mm_unpacklo_epi64(v2, v3);
|
||||
}
|
||||
|
||||
yx = _mm_shuffle_epi8(yx, byteswap_index);
|
||||
_mm_storeu_si128(y, yx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test CPU support for PCLMULQDQ.
|
||||
*/
|
||||
static int
|
||||
pclmul_supported(void)
|
||||
{
|
||||
/*
|
||||
* Bit mask for features in ECX:
|
||||
* 1 PCLMULQDQ support
|
||||
*/
|
||||
#define MASK 0x00000002
|
||||
|
||||
#if BR_AES_X86NI_GCC
|
||||
unsigned eax, ebx, ecx, edx;
|
||||
|
||||
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
|
||||
return (ecx & MASK) == MASK;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif BR_AES_X86NI_MSC
|
||||
int info[4];
|
||||
|
||||
__cpuid(info, 1);
|
||||
return ((uint32_t)info[2] & MASK) == MASK;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#undef MASK
|
||||
}
|
||||
|
||||
/* see bearssl_hash.h */
|
||||
br_ghash
|
||||
br_ghash_pclmul_get(void)
|
||||
{
|
||||
return pclmul_supported() ? &br_ghash_pclmul : 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* see bearssl_hash.h */
|
||||
br_ghash
|
||||
br_ghash_pclmul_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
74
src/inner.h
74
src/inner.h
@ -105,6 +105,55 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set BR_LOMUL on platforms where it makes sense.
|
||||
*/
|
||||
#ifndef BR_LOMUL
|
||||
#if BR_ARMEL_CORTEX_GCC
|
||||
#define BR_LOMUL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine whether x86 AES instructions are understood by the compiler.
|
||||
*/
|
||||
#ifndef BR_AES_X86NI
|
||||
|
||||
#if (__i386__ || __x86_64__) \
|
||||
&& ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) \
|
||||
|| (__clang_major__ > 3 \
|
||||
|| (__clang_major__ == 3 && __clang_minor__ >= 7)))
|
||||
#define BR_AES_X86NI 1
|
||||
#elif (_M_IX86 || _M_X64) && (_MSC_VER >= 1700)
|
||||
#define BR_AES_X86NI 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we use x86 AES instruction, determine the compiler brand.
|
||||
*/
|
||||
#if BR_AES_X86NI
|
||||
#ifndef BR_AES_X86NI_GCC
|
||||
#if __GNUC__
|
||||
#define BR_AES_X86NI_GCC 1
|
||||
#endif
|
||||
#endif
|
||||
#ifndef BR_AES_X86NI_MSC
|
||||
#if _MSC_VER >= 1700
|
||||
#define BR_AES_X86NI_MSC 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A macro to tag a function with a "target" attribute (for GCC and Clang).
|
||||
*/
|
||||
#if BR_AES_X86NI_GCC
|
||||
#define BR_TARGET(x) __attribute__((target(x)))
|
||||
#else
|
||||
#define BR_TARGET(x)
|
||||
#endif
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Encoding/decoding functions.
|
||||
@ -1077,6 +1126,10 @@ void br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b);
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
/*
|
||||
* FIXME: document "i15" functions.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
br_i15_zero(uint16_t *x, uint16_t bit_len)
|
||||
{
|
||||
@ -1424,6 +1477,27 @@ unsigned br_aes_ct64_keysched(uint64_t *comp_skey,
|
||||
void br_aes_ct64_skey_expand(uint64_t *skey,
|
||||
unsigned num_rounds, const uint64_t *comp_skey);
|
||||
|
||||
/*
|
||||
* Test support for AES-NI opcodes.
|
||||
*/
|
||||
int br_aes_x86ni_supported(void);
|
||||
|
||||
/*
|
||||
* AES key schedule, using x86 AES-NI instructions. This yields the
|
||||
* subkeys in the encryption direction. Number of rounds is returned.
|
||||
* Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned.
|
||||
*/
|
||||
unsigned br_aes_x86ni_keysched_enc(unsigned char *skni,
|
||||
const void *key, size_t len);
|
||||
|
||||
/*
|
||||
* AES key schedule, using x86 AES-NI instructions. This yields the
|
||||
* subkeys in the decryption direction. Number of rounds is returned.
|
||||
* Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned.
|
||||
*/
|
||||
unsigned br_aes_x86ni_keysched_dec(unsigned char *skni,
|
||||
const void *key, size_t len);
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* RSA.
|
||||
|
@ -41,6 +41,7 @@ br_i15_modpow_opt(uint16_t *x,
|
||||
*/
|
||||
mwlen = (m[0] + 31) >> 4;
|
||||
mlen = mwlen * sizeof m[0];
|
||||
mwlen += (mwlen & 1);
|
||||
t1 = tmp;
|
||||
t2 = tmp + mwlen;
|
||||
|
||||
@ -86,7 +87,7 @@ br_i15_modpow_opt(uint16_t *x,
|
||||
* one word-sized shift.
|
||||
*/
|
||||
br_i15_zero(x, m[0]);
|
||||
x[mwlen - 1] = 1;
|
||||
x[(m[0] + 15) >> 4] = 1;
|
||||
br_i15_muladd_small(x, 0, m);
|
||||
|
||||
/*
|
||||
|
@ -42,7 +42,99 @@ br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y,
|
||||
xu = x[u + 1];
|
||||
f = MUL15((d[1] + MUL15(x[u + 1], y[1])) & 0x7FFF, m0i)
|
||||
& 0x7FFF;
|
||||
#if BR_ARMEL_CORTEXM_GCC
|
||||
if (len4 != 0) {
|
||||
uint16_t *limit;
|
||||
|
||||
limit = d + len4;
|
||||
asm volatile (
|
||||
"\n\
|
||||
@ carry: r=r2 \n\
|
||||
@ multipliers: xu=r3 f=r4 \n\
|
||||
@ base registers: d+v=r5 y+v=r6 m+v=r7 \n\
|
||||
@ r8 contains 0x7FFF \n\
|
||||
@ r9 contains d+len4 \n\
|
||||
ldr r0, %[limit] \n\
|
||||
ldr r3, %[xu] \n\
|
||||
mov r9, r0 \n\
|
||||
ldr r4, %[f] \n\
|
||||
eor r2, r2 \n\
|
||||
ldr r5, %[d] \n\
|
||||
sub r1, r2, #1 \n\
|
||||
ldr r6, %[y] \n\
|
||||
lsr r1, r1, #17 \n\
|
||||
ldr r7, %[m] \n\
|
||||
mov r8, r1 \n\
|
||||
loop%=: \n\
|
||||
ldrh r0, [r6, #2] \n\
|
||||
ldrh r1, [r7, #2] \n\
|
||||
mul r0, r3 \n\
|
||||
mul r1, r4 \n\
|
||||
add r2, r0, r2 \n\
|
||||
ldrh r0, [r5, #2] \n\
|
||||
add r2, r1, r2 \n\
|
||||
mov r1, r8 \n\
|
||||
add r2, r0, r2 \n\
|
||||
and r1, r2 \n\
|
||||
lsr r2, r2, #15 \n\
|
||||
strh r1, [r5, #0] \n\
|
||||
\n\
|
||||
ldrh r0, [r6, #4] \n\
|
||||
ldrh r1, [r7, #4] \n\
|
||||
mul r0, r3 \n\
|
||||
mul r1, r4 \n\
|
||||
add r2, r0, r2 \n\
|
||||
ldrh r0, [r5, #4] \n\
|
||||
add r2, r1, r2 \n\
|
||||
mov r1, r8 \n\
|
||||
add r2, r0, r2 \n\
|
||||
and r1, r2 \n\
|
||||
lsr r2, r2, #15 \n\
|
||||
strh r1, [r5, #2] \n\
|
||||
\n\
|
||||
ldrh r0, [r6, #6] \n\
|
||||
ldrh r1, [r7, #6] \n\
|
||||
mul r0, r3 \n\
|
||||
mul r1, r4 \n\
|
||||
add r2, r0, r2 \n\
|
||||
ldrh r0, [r5, #6] \n\
|
||||
add r2, r1, r2 \n\
|
||||
mov r1, r8 \n\
|
||||
add r2, r0, r2 \n\
|
||||
and r1, r2 \n\
|
||||
lsr r2, r2, #15 \n\
|
||||
strh r1, [r5, #4] \n\
|
||||
\n\
|
||||
ldrh r0, [r6, #8] \n\
|
||||
ldrh r1, [r7, #8] \n\
|
||||
mul r0, r3 \n\
|
||||
mul r1, r4 \n\
|
||||
add r2, r0, r2 \n\
|
||||
ldrh r0, [r5, #8] \n\
|
||||
add r2, r1, r2 \n\
|
||||
mov r1, r8 \n\
|
||||
add r2, r0, r2 \n\
|
||||
and r1, r2 \n\
|
||||
lsr r2, r2, #15 \n\
|
||||
strh r1, [r5, #6] \n\
|
||||
\n\
|
||||
add r5, r5, #8 \n\
|
||||
add r6, r6, #8 \n\
|
||||
add r7, r7, #8 \n\
|
||||
cmp r5, r9 \n\
|
||||
bne loop%= \n\
|
||||
\n\
|
||||
str r2, %[carry] \n\
|
||||
"
|
||||
: [carry] "=m" (r)
|
||||
: [xu] "m" (xu), [f] "m" (f), [d] "m" (d), [y] "m" (y),
|
||||
[m] "m" (m), [limit] "m" (limit)
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||
} else {
|
||||
r = 0;
|
||||
}
|
||||
v = len4;
|
||||
#else
|
||||
r = 0;
|
||||
for (v = 0; v < len4; v += 4) {
|
||||
uint32_t z;
|
||||
@ -64,6 +156,7 @@ br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y,
|
||||
r = z >> 15;
|
||||
d[v + 3] = z & 0x7FFF;
|
||||
}
|
||||
#endif
|
||||
for (; v < len; v ++) {
|
||||
uint32_t z;
|
||||
|
||||
|
36
src/rsa/rsa_default_pkcs1_sign.c
Normal file
36
src/rsa/rsa_default_pkcs1_sign.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_rsa.h */
|
||||
br_rsa_pkcs1_sign
|
||||
br_rsa_pkcs1_sign_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_rsa_i15_pkcs1_sign;
|
||||
#else
|
||||
return &br_rsa_i31_pkcs1_sign;
|
||||
#endif
|
||||
}
|
36
src/rsa/rsa_default_pkcs1_vrfy.c
Normal file
36
src/rsa/rsa_default_pkcs1_vrfy.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_rsa.h */
|
||||
br_rsa_pkcs1_vrfy
|
||||
br_rsa_pkcs1_vrfy_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_rsa_i15_pkcs1_vrfy;
|
||||
#else
|
||||
return &br_rsa_i31_pkcs1_vrfy;
|
||||
#endif
|
||||
}
|
36
src/rsa/rsa_default_priv.c
Normal file
36
src/rsa/rsa_default_priv.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_rsa.h */
|
||||
br_rsa_private
|
||||
br_rsa_private_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_rsa_i15_private;
|
||||
#else
|
||||
return &br_rsa_i31_private;
|
||||
#endif
|
||||
}
|
36
src/rsa/rsa_default_pub.c
Normal file
36
src/rsa/rsa_default_pub.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_rsa.h */
|
||||
br_rsa_public
|
||||
br_rsa_public_get_default(void)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
return &br_rsa_i15_public;
|
||||
#else
|
||||
return &br_rsa_i31_public;
|
||||
#endif
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
#define U (1 + ((BR_MAX_RSA_FACTOR + 14) / 15))
|
||||
#define U (2 + ((BR_MAX_RSA_FACTOR + 14) / 15))
|
||||
#define TLEN (8 * U)
|
||||
|
||||
/* obsolete
|
||||
@ -54,7 +54,7 @@ br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk)
|
||||
size_t fwlen;
|
||||
uint16_t p0i, q0i;
|
||||
size_t xlen;
|
||||
uint16_t tmp[TLEN];
|
||||
uint16_t tmp[1 + TLEN];
|
||||
long z;
|
||||
uint16_t *mp, *mq, *s1, *s2, *t1, *t2, *t3;
|
||||
uint32_t r;
|
||||
@ -86,6 +86,10 @@ br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk)
|
||||
z -= 15;
|
||||
fwlen ++;
|
||||
}
|
||||
/*
|
||||
* Round up the word length to an even number.
|
||||
*/
|
||||
fwlen += (fwlen & 1);
|
||||
|
||||
/*
|
||||
* We need to fit at least 6 values in the stack buffer.
|
||||
@ -100,34 +104,41 @@ br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk)
|
||||
xlen = (sk->n_bitlen + 7) >> 3;
|
||||
|
||||
/*
|
||||
* Decode q.
|
||||
* Ensure 32-bit alignment for value words.
|
||||
*/
|
||||
mq = tmp;
|
||||
if (((uintptr_t)mq & 2) == 0) {
|
||||
mq ++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode q.
|
||||
*/
|
||||
br_i15_decode(mq, q, qlen);
|
||||
|
||||
/*
|
||||
* Compute s2 = x^dq mod q.
|
||||
*/
|
||||
q0i = br_i15_ninv15(mq[1]);
|
||||
s2 = tmp + fwlen;
|
||||
s2 = mq + fwlen;
|
||||
br_i15_decode_reduce(s2, x, xlen, mq);
|
||||
r = br_i15_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i,
|
||||
tmp + 2 * fwlen, TLEN - 2 * fwlen);
|
||||
mq + 2 * fwlen, TLEN - 2 * fwlen);
|
||||
|
||||
/*
|
||||
* Decode p.
|
||||
*/
|
||||
mp = tmp + 2 * fwlen;
|
||||
mp = mq + 2 * fwlen;
|
||||
br_i15_decode(mp, p, plen);
|
||||
|
||||
/*
|
||||
* Compute s1 = x^dq mod q.
|
||||
*/
|
||||
p0i = br_i15_ninv15(mp[1]);
|
||||
s1 = tmp + 3 * fwlen;
|
||||
s1 = mq + 3 * fwlen;
|
||||
br_i15_decode_reduce(s1, x, xlen, mp);
|
||||
r &= br_i15_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i,
|
||||
tmp + 4 * fwlen, TLEN - 4 * fwlen);
|
||||
mq + 4 * fwlen, TLEN - 4 * fwlen);
|
||||
|
||||
/*
|
||||
* Compute:
|
||||
@ -142,8 +153,8 @@ br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk)
|
||||
* inverse of q modulo p), we also tolerate improperly large
|
||||
* values for this parameter.
|
||||
*/
|
||||
t1 = tmp + 4 * fwlen;
|
||||
t2 = tmp + 5 * fwlen;
|
||||
t1 = mq + 4 * fwlen;
|
||||
t2 = mq + 5 * fwlen;
|
||||
br_i15_reduce(t2, s2, mp);
|
||||
br_i15_add(s1, mp, br_i15_sub(s1, t2, 1));
|
||||
br_i15_to_monty(s1, mp);
|
||||
|
@ -28,7 +28,7 @@
|
||||
* As a strict minimum, we need four buffers that can hold a
|
||||
* modular integer.
|
||||
*/
|
||||
#define TLEN (4 * (1 + ((BR_MAX_RSA_SIZE + 14) / 15)))
|
||||
#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 14) / 15)))
|
||||
|
||||
/* see bearssl_rsa.h */
|
||||
uint32_t
|
||||
@ -37,7 +37,7 @@ br_rsa_i15_public(unsigned char *x, size_t xlen,
|
||||
{
|
||||
const unsigned char *n;
|
||||
size_t nlen;
|
||||
uint16_t tmp[TLEN];
|
||||
uint16_t tmp[1 + TLEN];
|
||||
uint16_t *m, *a, *t;
|
||||
size_t fwlen;
|
||||
long z;
|
||||
@ -63,15 +63,25 @@ br_rsa_i15_public(unsigned char *x, size_t xlen,
|
||||
z -= 15;
|
||||
fwlen ++;
|
||||
}
|
||||
/*
|
||||
* Round up length to an even number.
|
||||
*/
|
||||
fwlen += (fwlen & 1);
|
||||
|
||||
/*
|
||||
* The modulus gets decoded into m[].
|
||||
* The value to exponentiate goes into a[].
|
||||
* The temporaries for modular exponentiations are in t[].
|
||||
*
|
||||
* We want the first value word of each integer to be aligned
|
||||
* on a 32-bit boundary.
|
||||
*/
|
||||
m = tmp;
|
||||
a = tmp + fwlen;
|
||||
t = tmp + 2 * fwlen;
|
||||
if (((uintptr_t)m & 2) == 0) {
|
||||
m ++;
|
||||
}
|
||||
a = m + fwlen;
|
||||
t = m + 2 * fwlen;
|
||||
|
||||
/*
|
||||
* Decode the modulus.
|
||||
|
36
src/ssl/ssl_client_default_rsapub.c
Normal file
36
src/ssl/ssl_client_default_rsapub.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_client_set_default_rsapub(br_ssl_client_context *cc)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
br_ssl_client_set_rsapub(cc, &br_rsa_i15_public);
|
||||
#else
|
||||
br_ssl_client_set_rsapub(cc, &br_rsa_i31_public);
|
||||
#endif
|
||||
}
|
@ -125,13 +125,13 @@ br_ssl_client_init_full(br_ssl_client_context *cc,
|
||||
*/
|
||||
br_ssl_engine_set_suites(&cc->eng, suites,
|
||||
(sizeof suites) / (sizeof suites[0]));
|
||||
br_ssl_client_set_rsapub(cc, &br_rsa_i31_public);
|
||||
br_ssl_engine_set_rsavrfy(&cc->eng, &br_rsa_i31_pkcs1_vrfy);
|
||||
br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_ecdsa(&cc->eng, &br_ecdsa_i31_vrfy_asn1);
|
||||
br_x509_minimal_set_rsa(xc, &br_rsa_i31_pkcs1_vrfy);
|
||||
br_ssl_client_set_default_rsapub(cc);
|
||||
br_ssl_engine_set_default_rsavrfy(&cc->eng);
|
||||
br_ssl_engine_set_default_ecdsa(&cc->eng);
|
||||
br_x509_minimal_set_rsa(xc, br_ssl_engine_get_rsavrfy(&cc->eng));
|
||||
br_x509_minimal_set_ecdsa(xc,
|
||||
&br_ec_all_m15, &br_ecdsa_i31_vrfy_asn1);
|
||||
br_ssl_engine_get_ec(&cc->eng),
|
||||
br_ssl_engine_get_ecdsa(&cc->eng));
|
||||
|
||||
/*
|
||||
* Set supported hash functions, for the SSL engine and for the
|
||||
@ -158,47 +158,11 @@ br_ssl_client_init_full(br_ssl_client_context *cc,
|
||||
br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption. We use the "default" implementations
|
||||
* (fastest among constant-time implementations).
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_cbc(&cc->eng,
|
||||
&br_aes_ct64_cbcenc_vtable,
|
||||
&br_aes_ct64_cbcdec_vtable);
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_cbc(&cc->eng,
|
||||
&br_aes_ct_cbcenc_vtable,
|
||||
&br_aes_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
br_ssl_engine_set_des_cbc(&cc->eng,
|
||||
&br_des_ct_cbcenc_vtable,
|
||||
&br_des_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_chacha20(&cc->eng,
|
||||
&br_chacha20_ct_run);
|
||||
br_ssl_engine_set_poly1305(&cc->eng,
|
||||
&br_poly1305_ctmul_run);
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM).
|
||||
*/
|
||||
br_ssl_engine_set_cbc(&cc->eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_chapol(&cc->eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_default_aes_cbc(&cc->eng);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
br_ssl_engine_set_default_des_cbc(&cc->eng);
|
||||
br_ssl_engine_set_default_chapol(&cc->eng);
|
||||
}
|
||||
|
56
src/ssl/ssl_engine_default_aescbc.c
Normal file
56
src/ssl/ssl_engine_default_aescbc.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc)
|
||||
{
|
||||
#if BR_AES_X86NI
|
||||
const br_block_cbcenc_class *ienc;
|
||||
const br_block_cbcdec_class *idec;
|
||||
#endif
|
||||
|
||||
br_ssl_engine_set_cbc(cc,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
#if BR_AES_X86NI
|
||||
ienc = br_aes_x86ni_cbcenc_get_vtable();
|
||||
idec = br_aes_x86ni_cbcdec_get_vtable();
|
||||
if (ienc != NULL && idec != NULL) {
|
||||
br_ssl_engine_set_aes_cbc(cc, ienc, idec);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_cbc(cc,
|
||||
&br_aes_ct64_cbcenc_vtable,
|
||||
&br_aes_ct64_cbcdec_vtable);
|
||||
#else
|
||||
br_ssl_engine_set_aes_cbc(cc,
|
||||
&br_aes_ct_cbcenc_vtable,
|
||||
&br_aes_ct_cbcdec_vtable);
|
||||
#endif
|
||||
}
|
71
src/ssl/ssl_engine_default_aesgcm.c
Normal file
71
src/ssl/ssl_engine_default_aesgcm.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc)
|
||||
{
|
||||
#if BR_AES_X86NI
|
||||
const br_block_ctr_class *ictr;
|
||||
br_ghash ighash;
|
||||
#endif
|
||||
|
||||
br_ssl_engine_set_gcm(cc,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
#if BR_AES_X86NI
|
||||
ictr = br_aes_x86ni_ctr_get_vtable();
|
||||
if (ictr != NULL) {
|
||||
br_ssl_engine_set_aes_ctr(cc, ictr);
|
||||
} else {
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable);
|
||||
#else
|
||||
br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable);
|
||||
#else
|
||||
br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable);
|
||||
#endif
|
||||
#endif
|
||||
#if BR_AES_X86NI
|
||||
ighash = br_ghash_pclmul_get();
|
||||
if (ighash != 0) {
|
||||
br_ssl_engine_set_ghash(cc, ighash);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if BR_LOMUL
|
||||
br_ssl_engine_set_ghash(cc, &br_ghash_ctmul32);
|
||||
#elif BR_64
|
||||
br_ssl_engine_set_ghash(cc, &br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_ghash(cc, &br_ghash_ctmul);
|
||||
#endif
|
||||
}
|
40
src/ssl/ssl_engine_default_chapol.c
Normal file
40
src/ssl/ssl_engine_default_chapol.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc)
|
||||
{
|
||||
br_ssl_engine_set_chapol(cc,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_chacha20(cc, &br_chacha20_ct_run);
|
||||
#if BR_LOMUL
|
||||
br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul32_run);
|
||||
#else
|
||||
br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul_run);
|
||||
#endif
|
||||
}
|
37
src/ssl/ssl_engine_default_descbc.c
Normal file
37
src/ssl/ssl_engine_default_descbc.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc)
|
||||
{
|
||||
br_ssl_engine_set_cbc(cc,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_des_cbc(cc,
|
||||
&br_des_ct_cbcenc_vtable,
|
||||
&br_des_ct_cbcdec_vtable);
|
||||
}
|
36
src/ssl/ssl_engine_default_ec.c
Normal file
36
src/ssl/ssl_engine_default_ec.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_engine_set_default_ec(br_ssl_engine_context *cc)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
br_ssl_engine_set_ec(cc, &br_ec_all_m15);
|
||||
#else
|
||||
br_ssl_engine_set_ec(cc, &br_ec_all_m31);
|
||||
#endif
|
||||
}
|
38
src/ssl/ssl_engine_default_ecdsa.c
Normal file
38
src/ssl/ssl_engine_default_ecdsa.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
br_ssl_engine_set_ec(cc, &br_ec_all_m15);
|
||||
br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i15_vrfy_asn1);
|
||||
#else
|
||||
br_ssl_engine_set_ec(cc, &br_ec_all_m31);
|
||||
br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i31_vrfy_asn1);
|
||||
#endif
|
||||
}
|
36
src/ssl/ssl_engine_default_rsavrfy.c
Normal file
36
src/ssl/ssl_engine_default_rsavrfy.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
void
|
||||
br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc)
|
||||
{
|
||||
#if BR_LOMUL
|
||||
br_ssl_engine_set_rsavrfy(cc, &br_rsa_i15_pkcs1_vrfy);
|
||||
#else
|
||||
br_ssl_engine_set_rsavrfy(cc, &br_rsa_i31_pkcs1_vrfy);
|
||||
#endif
|
||||
}
|
@ -99,7 +99,7 @@ br_ssl_server_init_full_ec(br_ssl_server_context *cc,
|
||||
*/
|
||||
br_ssl_engine_set_suites(&cc->eng, suites,
|
||||
(sizeof suites) / (sizeof suites[0]));
|
||||
br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_default_ec(&cc->eng);
|
||||
|
||||
/*
|
||||
* Set the "server policy": handler for the certificate chain
|
||||
@ -108,7 +108,13 @@ br_ssl_server_init_full_ec(br_ssl_server_context *cc,
|
||||
br_ssl_server_set_single_ec(cc, chain, chain_len, sk,
|
||||
BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN,
|
||||
cert_issuer_key_type,
|
||||
&br_ec_all_m15, br_ecdsa_i31_sign_asn1);
|
||||
br_ssl_engine_get_ec(&cc->eng),
|
||||
#if BR_LOMUL
|
||||
br_ecdsa_i15_sign_asn1
|
||||
#else
|
||||
br_ecdsa_i31_sign_asn1
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Set supported hash functions.
|
||||
@ -128,47 +134,10 @@ br_ssl_server_init_full_ec(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_cbc(&cc->eng,
|
||||
&br_aes_ct64_cbcenc_vtable,
|
||||
&br_aes_ct64_cbcdec_vtable);
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_cbc(&cc->eng,
|
||||
&br_aes_ct_cbcenc_vtable,
|
||||
&br_aes_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
br_ssl_engine_set_des_cbc(&cc->eng,
|
||||
&br_des_ct_cbcenc_vtable,
|
||||
&br_des_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_chacha20(&cc->eng,
|
||||
&br_chacha20_ct_run);
|
||||
br_ssl_engine_set_poly1305(&cc->eng,
|
||||
&br_poly1305_ctmul_run);
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM).
|
||||
*/
|
||||
br_ssl_engine_set_cbc(&cc->eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_chapol(&cc->eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_default_aes_cbc(&cc->eng);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
br_ssl_engine_set_default_des_cbc(&cc->eng);
|
||||
br_ssl_engine_set_default_chapol(&cc->eng);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ br_ssl_server_init_full_rsa(br_ssl_server_context *cc,
|
||||
*/
|
||||
br_ssl_engine_set_suites(&cc->eng, suites,
|
||||
(sizeof suites) / (sizeof suites[0]));
|
||||
br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_default_ec(&cc->eng);
|
||||
|
||||
/*
|
||||
* Set the "server policy": handler for the certificate chain
|
||||
@ -97,7 +97,12 @@ br_ssl_server_init_full_rsa(br_ssl_server_context *cc,
|
||||
*/
|
||||
br_ssl_server_set_single_rsa(cc, chain, chain_len, sk,
|
||||
BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN,
|
||||
br_rsa_i31_private, br_rsa_i31_pkcs1_sign);
|
||||
#if BR_LOMUL
|
||||
br_rsa_i15_private, br_rsa_i15_pkcs1_sign
|
||||
#else
|
||||
br_rsa_i31_private, br_rsa_i31_pkcs1_sign
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Set supported hash functions.
|
||||
@ -117,47 +122,10 @@ br_ssl_server_init_full_rsa(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_cbc(&cc->eng,
|
||||
&br_aes_ct64_cbcenc_vtable,
|
||||
&br_aes_ct64_cbcdec_vtable);
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_cbc(&cc->eng,
|
||||
&br_aes_ct_cbcenc_vtable,
|
||||
&br_aes_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
br_ssl_engine_set_des_cbc(&cc->eng,
|
||||
&br_des_ct_cbcenc_vtable,
|
||||
&br_des_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_chacha20(&cc->eng,
|
||||
&br_chacha20_ct_run);
|
||||
br_ssl_engine_set_poly1305(&cc->eng,
|
||||
&br_poly1305_ctmul_run);
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM, ChaCha20).
|
||||
*/
|
||||
br_ssl_engine_set_cbc(&cc->eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_chapol(&cc->eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_default_aes_cbc(&cc->eng);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
br_ssl_engine_set_default_des_cbc(&cc->eng);
|
||||
br_ssl_engine_set_default_chapol(&cc->eng);
|
||||
}
|
||||
|
@ -65,18 +65,7 @@ br_ssl_server_init_mine2c(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
br_ssl_engine_set_chacha20(&cc->eng,
|
||||
&br_chacha20_ct_run);
|
||||
br_ssl_engine_set_poly1305(&cc->eng,
|
||||
&br_poly1305_ctmul_run);
|
||||
|
||||
/*
|
||||
* Set the SSL record engines.
|
||||
*/
|
||||
br_ssl_engine_set_chapol(&cc->eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_default_chapol(&cc->eng);
|
||||
}
|
||||
|
@ -65,28 +65,7 @@ br_ssl_server_init_mine2g(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM).
|
||||
*/
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
}
|
||||
|
@ -65,21 +65,7 @@ br_ssl_server_init_minf2c(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
br_ssl_engine_set_chacha20(&cc->eng,
|
||||
&br_chacha20_ct_run);
|
||||
br_ssl_engine_set_poly1305(&cc->eng,
|
||||
&br_poly1305_ctmul_run);
|
||||
|
||||
/*
|
||||
* Set the SSL record engines.
|
||||
*/
|
||||
br_ssl_engine_set_chapol(&cc->eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_default_chapol(&cc->eng);
|
||||
}
|
||||
|
@ -65,28 +65,7 @@ br_ssl_server_init_minf2g(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM).
|
||||
*/
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
}
|
||||
|
@ -64,28 +64,7 @@ br_ssl_server_init_minr2g(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM).
|
||||
*/
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
}
|
||||
|
@ -64,28 +64,7 @@ br_ssl_server_init_minu2g(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM).
|
||||
*/
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
}
|
||||
|
@ -64,28 +64,7 @@ br_ssl_server_init_minv2g(br_ssl_server_context *cc,
|
||||
br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf);
|
||||
|
||||
/*
|
||||
* Symmetric encryption. We use the "constant-time"
|
||||
* implementations, which are the safest.
|
||||
*
|
||||
* On architectures detected as "64-bit", use the 64-bit
|
||||
* versions (aes_ct64, ghash_ctmul64).
|
||||
* Symmetric encryption.
|
||||
*/
|
||||
#if BR_64
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct64_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul64);
|
||||
#else
|
||||
br_ssl_engine_set_aes_ctr(&cc->eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc->eng,
|
||||
&br_ghash_ctmul);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the SSL record engines (CBC, GCM).
|
||||
*/
|
||||
br_ssl_engine_set_gcm(&cc->eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc->eng);
|
||||
}
|
||||
|
263
src/symcipher/aes_x86ni.c
Normal file
263
src/symcipher/aes_x86ni.c
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/*
|
||||
* This code contains the AES key schedule implementation using the
|
||||
* AES-NI opcodes.
|
||||
*/
|
||||
|
||||
#if BR_AES_X86NI
|
||||
|
||||
#if BR_AES_X86NI_GCC
|
||||
#include <wmmintrin.h>
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#if BR_AES_X86NI_MSC
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
/* see inner.h */
|
||||
int
|
||||
br_aes_x86ni_supported(void)
|
||||
{
|
||||
/*
|
||||
* Bit mask for features in ECX:
|
||||
* 19 SSE4.1 (used for _mm_insert_epi32(), for AES-CTR)
|
||||
* 25 AES-NI
|
||||
*/
|
||||
#define MASK 0x02080000
|
||||
|
||||
#if BR_AES_X86NI_GCC
|
||||
unsigned eax, ebx, ecx, edx;
|
||||
|
||||
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
|
||||
return (ecx & MASK) == MASK;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif BR_AES_X86NI_MSC
|
||||
int info[4];
|
||||
|
||||
__cpuid(info, 1);
|
||||
return ((uint32_t)info[2] & MASK) == MASK;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#undef MASK
|
||||
}
|
||||
|
||||
BR_TARGET("sse2,aes")
|
||||
static inline __m128i
|
||||
expand_step128(__m128i k, __m128i k2)
|
||||
{
|
||||
k = _mm_xor_si128(k, _mm_slli_si128(k, 4));
|
||||
k = _mm_xor_si128(k, _mm_slli_si128(k, 4));
|
||||
k = _mm_xor_si128(k, _mm_slli_si128(k, 4));
|
||||
k2 = _mm_shuffle_epi32(k2, 0xFF);
|
||||
return _mm_xor_si128(k, k2);
|
||||
}
|
||||
|
||||
BR_TARGET("sse2,aes")
|
||||
static inline void
|
||||
expand_step192(__m128i *t1, __m128i *t2, __m128i *t3)
|
||||
{
|
||||
__m128i t4;
|
||||
|
||||
*t2 = _mm_shuffle_epi32(*t2, 0x55);
|
||||
t4 = _mm_slli_si128(*t1, 0x4);
|
||||
*t1 = _mm_xor_si128(*t1, t4);
|
||||
t4 = _mm_slli_si128(t4, 0x4);
|
||||
*t1 = _mm_xor_si128(*t1, t4);
|
||||
t4 = _mm_slli_si128(t4, 0x4);
|
||||
*t1 = _mm_xor_si128(*t1, t4);
|
||||
*t1 = _mm_xor_si128(*t1, *t2);
|
||||
*t2 = _mm_shuffle_epi32(*t1, 0xFF);
|
||||
t4 = _mm_slli_si128(*t3, 0x4);
|
||||
*t3 = _mm_xor_si128(*t3, t4);
|
||||
*t3 = _mm_xor_si128(*t3, *t2);
|
||||
}
|
||||
|
||||
BR_TARGET("sse2,aes")
|
||||
static inline void
|
||||
expand_step256_1(__m128i *t1, __m128i *t2)
|
||||
{
|
||||
__m128i t4;
|
||||
|
||||
*t2 = _mm_shuffle_epi32(*t2, 0xFF);
|
||||
t4 = _mm_slli_si128(*t1, 0x4);
|
||||
*t1 = _mm_xor_si128(*t1, t4);
|
||||
t4 = _mm_slli_si128(t4, 0x4);
|
||||
*t1 = _mm_xor_si128(*t1, t4);
|
||||
t4 = _mm_slli_si128(t4, 0x4);
|
||||
*t1 = _mm_xor_si128(*t1, t4);
|
||||
*t1 = _mm_xor_si128(*t1, *t2);
|
||||
}
|
||||
|
||||
BR_TARGET("sse2,aes")
|
||||
static inline void
|
||||
expand_step256_2(__m128i *t1, __m128i *t3)
|
||||
{
|
||||
__m128i t2, t4;
|
||||
|
||||
t4 = _mm_aeskeygenassist_si128(*t1, 0x0);
|
||||
t2 = _mm_shuffle_epi32(t4, 0xAA);
|
||||
t4 = _mm_slli_si128(*t3, 0x4);
|
||||
*t3 = _mm_xor_si128(*t3, t4);
|
||||
t4 = _mm_slli_si128(t4, 0x4);
|
||||
*t3 = _mm_xor_si128(*t3, t4);
|
||||
t4 = _mm_slli_si128(t4, 0x4);
|
||||
*t3 = _mm_xor_si128(*t3, t4);
|
||||
*t3 = _mm_xor_si128(*t3, t2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform key schedule for AES, encryption direction. Subkeys are written
|
||||
* in sk[], and the number of rounds is returned. Key length MUST be 16,
|
||||
* 24 or 32 bytes.
|
||||
*/
|
||||
BR_TARGET("sse2,aes")
|
||||
static unsigned
|
||||
x86ni_keysched(__m128i *sk, const void *key, size_t len)
|
||||
{
|
||||
const unsigned char *kb;
|
||||
|
||||
#define KEXP128(k, i, rcon) do { \
|
||||
k = expand_step128(k, _mm_aeskeygenassist_si128(k, rcon)); \
|
||||
sk[i] = k; \
|
||||
} while (0)
|
||||
|
||||
#define KEXP192(i, rcon1, rcon2) do { \
|
||||
sk[(i) + 0] = t1; \
|
||||
sk[(i) + 1] = t3; \
|
||||
t2 = _mm_aeskeygenassist_si128(t3, rcon1); \
|
||||
expand_step192(&t1, &t2, &t3); \
|
||||
sk[(i) + 1] = _mm_castpd_si128(_mm_shuffle_pd( \
|
||||
_mm_castsi128_pd(sk[(i) + 1]), \
|
||||
_mm_castsi128_pd(t1), 0)); \
|
||||
sk[(i) + 2] = _mm_castpd_si128(_mm_shuffle_pd( \
|
||||
_mm_castsi128_pd(t1), \
|
||||
_mm_castsi128_pd(t3), 1)); \
|
||||
t2 = _mm_aeskeygenassist_si128(t3, rcon2); \
|
||||
expand_step192(&t1, &t2, &t3); \
|
||||
} while (0)
|
||||
|
||||
#define KEXP256(i, rcon) do { \
|
||||
sk[(i) + 0] = t3; \
|
||||
t2 = _mm_aeskeygenassist_si128(t3, rcon); \
|
||||
expand_step256_1(&t1, &t2); \
|
||||
sk[(i) + 1] = t1; \
|
||||
expand_step256_2(&t1, &t3); \
|
||||
} while (0)
|
||||
|
||||
kb = key;
|
||||
switch (len) {
|
||||
__m128i t1, t2, t3;
|
||||
|
||||
case 16:
|
||||
t1 = _mm_loadu_si128((const void *)kb);
|
||||
sk[0] = t1;
|
||||
KEXP128(t1, 1, 0x01);
|
||||
KEXP128(t1, 2, 0x02);
|
||||
KEXP128(t1, 3, 0x04);
|
||||
KEXP128(t1, 4, 0x08);
|
||||
KEXP128(t1, 5, 0x10);
|
||||
KEXP128(t1, 6, 0x20);
|
||||
KEXP128(t1, 7, 0x40);
|
||||
KEXP128(t1, 8, 0x80);
|
||||
KEXP128(t1, 9, 0x1B);
|
||||
KEXP128(t1, 10, 0x36);
|
||||
return 10;
|
||||
|
||||
case 24:
|
||||
t1 = _mm_loadu_si128((const void *)kb);
|
||||
t3 = _mm_loadu_si128((const void *)(kb + 8));
|
||||
t3 = _mm_shuffle_epi32(t3, 0x4E);
|
||||
KEXP192(0, 0x01, 0x02);
|
||||
KEXP192(3, 0x04, 0x08);
|
||||
KEXP192(6, 0x10, 0x20);
|
||||
KEXP192(9, 0x40, 0x80);
|
||||
sk[12] = t1;
|
||||
return 12;
|
||||
|
||||
case 32:
|
||||
t1 = _mm_loadu_si128((const void *)kb);
|
||||
t3 = _mm_loadu_si128((const void *)(kb + 16));
|
||||
sk[0] = t1;
|
||||
KEXP256( 1, 0x01);
|
||||
KEXP256( 3, 0x02);
|
||||
KEXP256( 5, 0x04);
|
||||
KEXP256( 7, 0x08);
|
||||
KEXP256( 9, 0x10);
|
||||
KEXP256(11, 0x20);
|
||||
sk[13] = t3;
|
||||
t2 = _mm_aeskeygenassist_si128(t3, 0x40);
|
||||
expand_step256_1(&t1, &t2);
|
||||
sk[14] = t1;
|
||||
return 14;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef KEXP128
|
||||
#undef KEXP192
|
||||
#undef KEXP256
|
||||
}
|
||||
|
||||
/* see inner.h */
|
||||
BR_TARGET("sse2,aes")
|
||||
unsigned
|
||||
br_aes_x86ni_keysched_enc(unsigned char *skni, const void *key, size_t len)
|
||||
{
|
||||
__m128i sk[15];
|
||||
unsigned num_rounds;
|
||||
|
||||
num_rounds = x86ni_keysched(sk, key, len);
|
||||
memcpy(skni, sk, (num_rounds + 1) << 4);
|
||||
return num_rounds;
|
||||
}
|
||||
|
||||
/* see inner.h */
|
||||
BR_TARGET("sse2,aes")
|
||||
unsigned
|
||||
br_aes_x86ni_keysched_dec(unsigned char *skni, const void *key, size_t len)
|
||||
{
|
||||
__m128i sk[15];
|
||||
unsigned u, num_rounds;
|
||||
|
||||
num_rounds = x86ni_keysched(sk, key, len);
|
||||
_mm_storeu_si128((void *)skni, sk[num_rounds]);
|
||||
for (u = 1; u < num_rounds; u ++) {
|
||||
_mm_storeu_si128((void *)(skni + (u << 4)),
|
||||
_mm_aesimc_si128(sk[num_rounds - u]));
|
||||
}
|
||||
_mm_storeu_si128((void *)(skni + (num_rounds << 4)), sk[0]);
|
||||
return num_rounds;
|
||||
}
|
||||
|
||||
#endif
|
224
src/symcipher/aes_x86ni_cbcdec.c
Normal file
224
src/symcipher/aes_x86ni_cbcdec.c
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
#if BR_AES_X86NI
|
||||
|
||||
#if BR_AES_X86NI_GCC
|
||||
#include <wmmintrin.h>
|
||||
#endif
|
||||
|
||||
#if BR_AES_X86NI_MSC
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
/* see bearssl_block.h */
|
||||
void
|
||||
br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx,
|
||||
const void *key, size_t len)
|
||||
{
|
||||
ctx->vtable = &br_aes_x86ni_cbcdec_vtable;
|
||||
ctx->num_rounds = br_aes_x86ni_keysched_dec(ctx->skey.skni, key, len);
|
||||
}
|
||||
|
||||
/* see bearssl_block.h */
|
||||
BR_TARGET("sse2,aes")
|
||||
void
|
||||
br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx,
|
||||
void *iv, void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned num_rounds;
|
||||
__m128i sk[15], ivx;
|
||||
unsigned u;
|
||||
|
||||
buf = data;
|
||||
ivx = _mm_loadu_si128(iv);
|
||||
num_rounds = ctx->num_rounds;
|
||||
for (u = 0; u <= num_rounds; u ++) {
|
||||
sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4)));
|
||||
}
|
||||
while (len > 0) {
|
||||
__m128i x0, x1, x2, x3, e0, e1, e2, e3;
|
||||
|
||||
x0 = _mm_loadu_si128((void *)(buf + 0));
|
||||
if (len >= 64) {
|
||||
x1 = _mm_loadu_si128((void *)(buf + 16));
|
||||
x2 = _mm_loadu_si128((void *)(buf + 32));
|
||||
x3 = _mm_loadu_si128((void *)(buf + 48));
|
||||
} else {
|
||||
x0 = _mm_loadu_si128((void *)(buf + 0));
|
||||
if (len >= 32) {
|
||||
x1 = _mm_loadu_si128((void *)(buf + 16));
|
||||
if (len >= 48) {
|
||||
x2 = _mm_loadu_si128(
|
||||
(void *)(buf + 32));
|
||||
} else {
|
||||
x2 = x0;
|
||||
}
|
||||
} else {
|
||||
x1 = x0;
|
||||
x2 = x0;
|
||||
}
|
||||
x3 = x0;
|
||||
}
|
||||
e0 = x0;
|
||||
e1 = x1;
|
||||
e2 = x2;
|
||||
e3 = x3;
|
||||
x0 = _mm_xor_si128(x0, sk[0]);
|
||||
x1 = _mm_xor_si128(x1, sk[0]);
|
||||
x2 = _mm_xor_si128(x2, sk[0]);
|
||||
x3 = _mm_xor_si128(x3, sk[0]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[1]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[1]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[1]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[1]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[2]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[2]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[2]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[2]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[3]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[3]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[3]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[3]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[4]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[4]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[4]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[4]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[5]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[5]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[5]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[5]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[6]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[6]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[6]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[6]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[7]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[7]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[7]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[7]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[8]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[8]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[8]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[8]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[9]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[9]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[9]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[9]);
|
||||
if (num_rounds == 10) {
|
||||
x0 = _mm_aesdeclast_si128(x0, sk[10]);
|
||||
x1 = _mm_aesdeclast_si128(x1, sk[10]);
|
||||
x2 = _mm_aesdeclast_si128(x2, sk[10]);
|
||||
x3 = _mm_aesdeclast_si128(x3, sk[10]);
|
||||
} else if (num_rounds == 12) {
|
||||
x0 = _mm_aesdec_si128(x0, sk[10]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[10]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[10]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[10]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[11]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[11]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[11]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[11]);
|
||||
x0 = _mm_aesdeclast_si128(x0, sk[12]);
|
||||
x1 = _mm_aesdeclast_si128(x1, sk[12]);
|
||||
x2 = _mm_aesdeclast_si128(x2, sk[12]);
|
||||
x3 = _mm_aesdeclast_si128(x3, sk[12]);
|
||||
} else {
|
||||
x0 = _mm_aesdec_si128(x0, sk[10]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[10]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[10]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[10]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[11]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[11]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[11]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[11]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[12]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[12]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[12]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[12]);
|
||||
x0 = _mm_aesdec_si128(x0, sk[13]);
|
||||
x1 = _mm_aesdec_si128(x1, sk[13]);
|
||||
x2 = _mm_aesdec_si128(x2, sk[13]);
|
||||
x3 = _mm_aesdec_si128(x3, sk[13]);
|
||||
x0 = _mm_aesdeclast_si128(x0, sk[14]);
|
||||
x1 = _mm_aesdeclast_si128(x1, sk[14]);
|
||||
x2 = _mm_aesdeclast_si128(x2, sk[14]);
|
||||
x3 = _mm_aesdeclast_si128(x3, sk[14]);
|
||||
}
|
||||
x0 = _mm_xor_si128(x0, ivx);
|
||||
x1 = _mm_xor_si128(x1, e0);
|
||||
x2 = _mm_xor_si128(x2, e1);
|
||||
x3 = _mm_xor_si128(x3, e2);
|
||||
ivx = e3;
|
||||
_mm_storeu_si128((void *)(buf + 0), x0);
|
||||
if (len >= 64) {
|
||||
_mm_storeu_si128((void *)(buf + 16), x1);
|
||||
_mm_storeu_si128((void *)(buf + 32), x2);
|
||||
_mm_storeu_si128((void *)(buf + 48), x3);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
} else {
|
||||
if (len >= 32) {
|
||||
_mm_storeu_si128((void *)(buf + 16), x1);
|
||||
if (len >= 48) {
|
||||
_mm_storeu_si128(
|
||||
(void *)(buf + 32), x2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
_mm_storeu_si128(iv, ivx);
|
||||
}
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable = {
|
||||
sizeof(br_aes_x86ni_cbcdec_keys),
|
||||
16,
|
||||
4,
|
||||
(void (*)(const br_block_cbcdec_class **, const void *, size_t))
|
||||
&br_aes_x86ni_cbcdec_init,
|
||||
(void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t))
|
||||
&br_aes_x86ni_cbcdec_run
|
||||
};
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_cbcdec_class *
|
||||
br_aes_x86ni_cbcdec_get_vtable(void)
|
||||
{
|
||||
return br_aes_x86ni_supported() ? &br_aes_x86ni_cbcdec_vtable : NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_cbcdec_class *
|
||||
br_aes_x86ni_cbcdec_get_vtable(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
125
src/symcipher/aes_x86ni_cbcenc.c
Normal file
125
src/symcipher/aes_x86ni_cbcenc.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
#if BR_AES_X86NI
|
||||
|
||||
#if BR_AES_X86NI_GCC
|
||||
#include <wmmintrin.h>
|
||||
#endif
|
||||
|
||||
#if BR_AES_X86NI_MSC
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
/* see bearssl_block.h */
|
||||
void
|
||||
br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx,
|
||||
const void *key, size_t len)
|
||||
{
|
||||
ctx->vtable = &br_aes_x86ni_cbcenc_vtable;
|
||||
ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len);
|
||||
}
|
||||
|
||||
/* see bearssl_block.h */
|
||||
BR_TARGET("sse2,aes")
|
||||
void
|
||||
br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx,
|
||||
void *iv, void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned num_rounds;
|
||||
__m128i sk[15], ivx;
|
||||
unsigned u;
|
||||
|
||||
buf = data;
|
||||
ivx = _mm_loadu_si128(iv);
|
||||
num_rounds = ctx->num_rounds;
|
||||
for (u = 0; u <= num_rounds; u ++) {
|
||||
sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4)));
|
||||
}
|
||||
while (len > 0) {
|
||||
__m128i x;
|
||||
|
||||
x = _mm_xor_si128(_mm_loadu_si128((void *)buf), ivx);
|
||||
x = _mm_xor_si128(x, sk[0]);
|
||||
x = _mm_aesenc_si128(x, sk[1]);
|
||||
x = _mm_aesenc_si128(x, sk[2]);
|
||||
x = _mm_aesenc_si128(x, sk[3]);
|
||||
x = _mm_aesenc_si128(x, sk[4]);
|
||||
x = _mm_aesenc_si128(x, sk[5]);
|
||||
x = _mm_aesenc_si128(x, sk[6]);
|
||||
x = _mm_aesenc_si128(x, sk[7]);
|
||||
x = _mm_aesenc_si128(x, sk[8]);
|
||||
x = _mm_aesenc_si128(x, sk[9]);
|
||||
if (num_rounds == 10) {
|
||||
x = _mm_aesenclast_si128(x, sk[10]);
|
||||
} else if (num_rounds == 12) {
|
||||
x = _mm_aesenc_si128(x, sk[10]);
|
||||
x = _mm_aesenc_si128(x, sk[11]);
|
||||
x = _mm_aesenclast_si128(x, sk[12]);
|
||||
} else {
|
||||
x = _mm_aesenc_si128(x, sk[10]);
|
||||
x = _mm_aesenc_si128(x, sk[11]);
|
||||
x = _mm_aesenc_si128(x, sk[12]);
|
||||
x = _mm_aesenc_si128(x, sk[13]);
|
||||
x = _mm_aesenclast_si128(x, sk[14]);
|
||||
}
|
||||
ivx = x;
|
||||
_mm_storeu_si128((void *)buf, x);
|
||||
buf += 16;
|
||||
len -= 16;
|
||||
}
|
||||
_mm_storeu_si128(iv, ivx);
|
||||
}
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable = {
|
||||
sizeof(br_aes_x86ni_cbcenc_keys),
|
||||
16,
|
||||
4,
|
||||
(void (*)(const br_block_cbcenc_class **, const void *, size_t))
|
||||
&br_aes_x86ni_cbcenc_init,
|
||||
(void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t))
|
||||
&br_aes_x86ni_cbcenc_run
|
||||
};
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_cbcenc_class *
|
||||
br_aes_x86ni_cbcenc_get_vtable(void)
|
||||
{
|
||||
return br_aes_x86ni_supported() ? &br_aes_x86ni_cbcenc_vtable : NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_cbcenc_class *
|
||||
br_aes_x86ni_cbcenc_get_vtable(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
218
src/symcipher/aes_x86ni_ctr.c
Normal file
218
src/symcipher/aes_x86ni_ctr.c
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
#if BR_AES_X86NI
|
||||
|
||||
#if BR_AES_X86NI_GCC
|
||||
#include <smmintrin.h>
|
||||
#include <wmmintrin.h>
|
||||
#define bswap32 __builtin_bswap32
|
||||
#endif
|
||||
|
||||
#if BR_AES_X86NI_MSC
|
||||
#include <stdlib.h>
|
||||
#include <intrin.h>
|
||||
#define bswap32 _byteswap_ulong
|
||||
#endif
|
||||
|
||||
/* see bearssl_block.h */
|
||||
void
|
||||
br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx,
|
||||
const void *key, size_t len)
|
||||
{
|
||||
ctx->vtable = &br_aes_x86ni_ctr_vtable;
|
||||
ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len);
|
||||
}
|
||||
|
||||
/* see bearssl_block.h */
|
||||
BR_TARGET("sse2,sse4.1,aes")
|
||||
uint32_t
|
||||
br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx,
|
||||
const void *iv, uint32_t cc, void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned char ivbuf[16];
|
||||
unsigned num_rounds;
|
||||
__m128i sk[15];
|
||||
__m128i ivx;
|
||||
unsigned u;
|
||||
|
||||
buf = data;
|
||||
memcpy(ivbuf, iv, 12);
|
||||
num_rounds = ctx->num_rounds;
|
||||
for (u = 0; u <= num_rounds; u ++) {
|
||||
sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4)));
|
||||
}
|
||||
ivx = _mm_loadu_si128((void *)ivbuf);
|
||||
while (len > 0) {
|
||||
__m128i x0, x1, x2, x3;
|
||||
|
||||
x0 = _mm_insert_epi32(ivx, bswap32(cc + 0), 3);
|
||||
x1 = _mm_insert_epi32(ivx, bswap32(cc + 1), 3);
|
||||
x2 = _mm_insert_epi32(ivx, bswap32(cc + 2), 3);
|
||||
x3 = _mm_insert_epi32(ivx, bswap32(cc + 3), 3);
|
||||
x0 = _mm_xor_si128(x0, sk[0]);
|
||||
x1 = _mm_xor_si128(x1, sk[0]);
|
||||
x2 = _mm_xor_si128(x2, sk[0]);
|
||||
x3 = _mm_xor_si128(x3, sk[0]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[1]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[1]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[1]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[1]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[2]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[2]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[2]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[2]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[3]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[3]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[3]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[3]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[4]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[4]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[4]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[4]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[5]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[5]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[5]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[5]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[6]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[6]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[6]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[6]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[7]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[7]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[7]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[7]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[8]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[8]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[8]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[8]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[9]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[9]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[9]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[9]);
|
||||
if (num_rounds == 10) {
|
||||
x0 = _mm_aesenclast_si128(x0, sk[10]);
|
||||
x1 = _mm_aesenclast_si128(x1, sk[10]);
|
||||
x2 = _mm_aesenclast_si128(x2, sk[10]);
|
||||
x3 = _mm_aesenclast_si128(x3, sk[10]);
|
||||
} else if (num_rounds == 12) {
|
||||
x0 = _mm_aesenc_si128(x0, sk[10]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[10]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[10]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[10]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[11]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[11]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[11]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[11]);
|
||||
x0 = _mm_aesenclast_si128(x0, sk[12]);
|
||||
x1 = _mm_aesenclast_si128(x1, sk[12]);
|
||||
x2 = _mm_aesenclast_si128(x2, sk[12]);
|
||||
x3 = _mm_aesenclast_si128(x3, sk[12]);
|
||||
} else {
|
||||
x0 = _mm_aesenc_si128(x0, sk[10]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[10]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[10]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[10]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[11]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[11]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[11]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[11]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[12]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[12]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[12]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[12]);
|
||||
x0 = _mm_aesenc_si128(x0, sk[13]);
|
||||
x1 = _mm_aesenc_si128(x1, sk[13]);
|
||||
x2 = _mm_aesenc_si128(x2, sk[13]);
|
||||
x3 = _mm_aesenc_si128(x3, sk[13]);
|
||||
x0 = _mm_aesenclast_si128(x0, sk[14]);
|
||||
x1 = _mm_aesenclast_si128(x1, sk[14]);
|
||||
x2 = _mm_aesenclast_si128(x2, sk[14]);
|
||||
x3 = _mm_aesenclast_si128(x3, sk[14]);
|
||||
}
|
||||
if (len >= 64) {
|
||||
x0 = _mm_xor_si128(x0,
|
||||
_mm_loadu_si128((void *)(buf + 0)));
|
||||
x1 = _mm_xor_si128(x1,
|
||||
_mm_loadu_si128((void *)(buf + 16)));
|
||||
x2 = _mm_xor_si128(x2,
|
||||
_mm_loadu_si128((void *)(buf + 32)));
|
||||
x3 = _mm_xor_si128(x3,
|
||||
_mm_loadu_si128((void *)(buf + 48)));
|
||||
_mm_storeu_si128((void *)(buf + 0), x0);
|
||||
_mm_storeu_si128((void *)(buf + 16), x1);
|
||||
_mm_storeu_si128((void *)(buf + 32), x2);
|
||||
_mm_storeu_si128((void *)(buf + 48), x3);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
cc += 4;
|
||||
} else {
|
||||
unsigned char tmp[64];
|
||||
|
||||
_mm_storeu_si128((void *)(tmp + 0), x0);
|
||||
_mm_storeu_si128((void *)(tmp + 16), x1);
|
||||
_mm_storeu_si128((void *)(tmp + 32), x2);
|
||||
_mm_storeu_si128((void *)(tmp + 48), x3);
|
||||
for (u = 0; u < len; u ++) {
|
||||
buf[u] ^= tmp[u];
|
||||
}
|
||||
cc += (uint32_t)len >> 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_ctr_class br_aes_x86ni_ctr_vtable = {
|
||||
sizeof(br_aes_x86ni_ctr_keys),
|
||||
16,
|
||||
4,
|
||||
(void (*)(const br_block_ctr_class **, const void *, size_t))
|
||||
&br_aes_x86ni_ctr_init,
|
||||
(uint32_t (*)(const br_block_ctr_class *const *,
|
||||
const void *, uint32_t, void *, size_t))
|
||||
&br_aes_x86ni_ctr_run
|
||||
};
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_ctr_class *
|
||||
br_aes_x86ni_ctr_get_vtable(void)
|
||||
{
|
||||
return br_aes_x86ni_supported() ? &br_aes_x86ni_ctr_vtable : NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* see bearssl_block.h */
|
||||
const br_block_ctr_class *
|
||||
br_aes_x86ni_ctr_get_vtable(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
@ -591,7 +591,7 @@ test_HMAC_CT(const br_hash_class *digest_class,
|
||||
|
||||
br_hmac_key_init(&kc, digest_class, key, key_len);
|
||||
|
||||
for (u = 0; u < 130; u ++) {
|
||||
for (u = 0; u < 2; u ++) {
|
||||
for (v = 0; v < 130; v ++) {
|
||||
size_t min_len, max_len;
|
||||
size_t w;
|
||||
@ -3157,7 +3157,6 @@ test_AES_generic(char *name,
|
||||
data_len = hextobin(plain, KAT_AES_CTR[u + 2]);
|
||||
hextobin(cipher, KAT_AES_CTR[u + 3]);
|
||||
vc->init(xc, key, key_len);
|
||||
|
||||
memcpy(buf, plain, data_len);
|
||||
vc->run(xc, iv, 1, buf, data_len);
|
||||
check_equals("KAT CTR AES (1)", buf, cipher, data_len);
|
||||
@ -3271,6 +3270,33 @@ test_AES_ct64(void)
|
||||
1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_AES_x86ni(void)
|
||||
{
|
||||
const br_block_cbcenc_class *x_cbcenc;
|
||||
const br_block_cbcdec_class *x_cbcdec;
|
||||
const br_block_ctr_class *x_ctr;
|
||||
int hcbcenc, hcbcdec, hctr;
|
||||
|
||||
x_cbcenc = br_aes_x86ni_cbcenc_get_vtable();
|
||||
x_cbcdec = br_aes_x86ni_cbcdec_get_vtable();
|
||||
x_ctr = br_aes_x86ni_ctr_get_vtable();
|
||||
hcbcenc = (x_cbcenc != NULL);
|
||||
hcbcdec = (x_cbcdec != NULL);
|
||||
hctr = (x_ctr != NULL);
|
||||
if (hcbcenc != hctr || hcbcdec != hctr) {
|
||||
fprintf(stderr, "AES_x86ni availability mismatch (%d/%d/%d)\n",
|
||||
hcbcenc, hcbcdec, hctr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (hctr) {
|
||||
test_AES_generic("AES_x86ni",
|
||||
x_cbcenc, x_cbcdec, x_ctr, 1, 1);
|
||||
} else {
|
||||
printf("Test AES_x86ni: UNAVAILABLE\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DES known-answer tests. Order: plaintext, key, ciphertext.
|
||||
* (mostly from NIST SP 800-20).
|
||||
@ -4671,6 +4697,19 @@ test_GHASH_ctmul64(void)
|
||||
test_GHASH("GHASH_ctmul64", br_ghash_ctmul64);
|
||||
}
|
||||
|
||||
static void
|
||||
test_GHASH_pclmul(void)
|
||||
{
|
||||
br_ghash gh;
|
||||
|
||||
gh = br_ghash_pclmul_get();
|
||||
if (gh == 0) {
|
||||
printf("Test GHASH_pclmul: UNAVAILABLE\n");
|
||||
} else {
|
||||
test_GHASH("GHASH_pclmul", gh);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_EC_inner(const char *sk, const char *sU,
|
||||
const br_ec_impl *impl, int curve)
|
||||
@ -5559,6 +5598,7 @@ static const struct {
|
||||
STU(AES_small),
|
||||
STU(AES_ct),
|
||||
STU(AES_ct64),
|
||||
STU(AES_x86ni),
|
||||
STU(DES_tab),
|
||||
STU(DES_ct),
|
||||
STU(ChaCha20_ct),
|
||||
@ -5571,6 +5611,7 @@ static const struct {
|
||||
STU(GHASH_ctmul),
|
||||
STU(GHASH_ctmul32),
|
||||
STU(GHASH_ctmul64),
|
||||
STU(GHASH_pclmul),
|
||||
STU(EC_prime_i15),
|
||||
STU(EC_prime_i31),
|
||||
STU(EC_p256_m15),
|
||||
|
@ -88,7 +88,12 @@ test_speed_ ## fname(void) \
|
||||
memset(key, 'T', sizeof key); \
|
||||
memset(buf, 'P', sizeof buf); \
|
||||
memset(iv, 'X', sizeof iv); \
|
||||
vt = &br_ ## cname ## _cbc ## dir ## _vtable; \
|
||||
vt = br_ ## cname ## _cbc ## dir ## _get_vtable(); \
|
||||
if (vt == NULL) { \
|
||||
printf("%-30s UNAVAILABLE\n", #Name); \
|
||||
fflush(stdout); \
|
||||
return; \
|
||||
} \
|
||||
for (i = 0; i < 10; i ++) { \
|
||||
vt->init(&ec.vtable, key, sizeof key); \
|
||||
vt->run(&ec.vtable, iv, buf, sizeof buf); \
|
||||
@ -132,7 +137,12 @@ test_speed_ ## fname(void) \
|
||||
memset(key, 'T', sizeof key); \
|
||||
memset(buf, 'P', sizeof buf); \
|
||||
memset(iv, 'X', sizeof iv); \
|
||||
vt = &br_ ## cname ## _ctr_vtable; \
|
||||
vt = br_ ## cname ## _ctr_get_vtable(); \
|
||||
if (vt == NULL) { \
|
||||
printf("%-30s UNAVAILABLE\n", #Name); \
|
||||
fflush(stdout); \
|
||||
return; \
|
||||
} \
|
||||
for (i = 0; i < 10; i ++) { \
|
||||
vt->init(&ec.vtable, key, sizeof key); \
|
||||
vt->run(&ec.vtable, iv, 1, buf, sizeof buf); \
|
||||
@ -206,6 +216,23 @@ SPEED_HASH(SHA-1, sha1)
|
||||
SPEED_HASH(SHA-256, sha256)
|
||||
SPEED_HASH(SHA-512, sha512)
|
||||
|
||||
/*
|
||||
* There are no vtable selection functions for the portable implementations,
|
||||
* so we define some custom macros.
|
||||
*/
|
||||
#define br_aes_big_cbcenc_get_vtable() (&br_aes_big_cbcenc_vtable)
|
||||
#define br_aes_big_cbcdec_get_vtable() (&br_aes_big_cbcdec_vtable)
|
||||
#define br_aes_big_ctr_get_vtable() (&br_aes_big_ctr_vtable)
|
||||
#define br_aes_small_cbcenc_get_vtable() (&br_aes_small_cbcenc_vtable)
|
||||
#define br_aes_small_cbcdec_get_vtable() (&br_aes_small_cbcdec_vtable)
|
||||
#define br_aes_small_ctr_get_vtable() (&br_aes_small_ctr_vtable)
|
||||
#define br_aes_ct_cbcenc_get_vtable() (&br_aes_ct_cbcenc_vtable)
|
||||
#define br_aes_ct_cbcdec_get_vtable() (&br_aes_ct_cbcdec_vtable)
|
||||
#define br_aes_ct_ctr_get_vtable() (&br_aes_ct_ctr_vtable)
|
||||
#define br_aes_ct64_cbcenc_get_vtable() (&br_aes_ct64_cbcenc_vtable)
|
||||
#define br_aes_ct64_cbcdec_get_vtable() (&br_aes_ct64_cbcdec_vtable)
|
||||
#define br_aes_ct64_ctr_get_vtable() (&br_aes_ct64_ctr_vtable)
|
||||
|
||||
#define SPEED_AES(iname) \
|
||||
SPEED_BLOCKCIPHER_CBC(AES-128 CBC encrypt (iname), aes128_ ## iname ## _cbcenc, aes_ ## iname, 16, enc) \
|
||||
SPEED_BLOCKCIPHER_CBC(AES-128 CBC decrypt (iname), aes128_ ## iname ## _cbcdec, aes_ ## iname, 16, dec) \
|
||||
@ -221,6 +248,12 @@ SPEED_AES(big)
|
||||
SPEED_AES(small)
|
||||
SPEED_AES(ct)
|
||||
SPEED_AES(ct64)
|
||||
SPEED_AES(x86ni)
|
||||
|
||||
#define br_des_tab_cbcenc_get_vtable() (&br_des_tab_cbcenc_vtable)
|
||||
#define br_des_tab_cbcdec_get_vtable() (&br_des_tab_cbcdec_vtable)
|
||||
#define br_des_ct_cbcenc_get_vtable() (&br_des_ct_cbcenc_vtable)
|
||||
#define br_des_ct_cbcdec_get_vtable() (&br_des_ct_cbcdec_vtable)
|
||||
|
||||
#define SPEED_DES(iname) \
|
||||
SPEED_BLOCKCIPHER_CBC(DES CBC encrypt (iname), des_ ## iname ## _cbcenc, des_ ## iname, 8, enc) \
|
||||
@ -287,6 +320,20 @@ test_speed_ghash_ctmul64(void)
|
||||
test_speed_ghash_inner("GHASH (ctmul64)", &br_ghash_ctmul64);
|
||||
}
|
||||
|
||||
static void
|
||||
test_speed_ghash_pclmul(void)
|
||||
{
|
||||
br_ghash gh;
|
||||
|
||||
gh = br_ghash_pclmul_get();
|
||||
if (gh == 0) {
|
||||
printf("%-30s UNAVAILABLE\n", "GHASH (pclmul)");
|
||||
fflush(stdout);
|
||||
} else {
|
||||
test_speed_ghash_inner("GHASH (pclmul)", gh);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
fake_chacha20(const void *key, const void *iv,
|
||||
uint32_t cc, void *data, size_t len)
|
||||
@ -1158,6 +1205,16 @@ static const struct {
|
||||
STU(aes192_ct64_ctr),
|
||||
STU(aes256_ct64_ctr),
|
||||
|
||||
STU(aes128_x86ni_cbcenc),
|
||||
STU(aes128_x86ni_cbcdec),
|
||||
STU(aes192_x86ni_cbcenc),
|
||||
STU(aes192_x86ni_cbcdec),
|
||||
STU(aes256_x86ni_cbcenc),
|
||||
STU(aes256_x86ni_cbcdec),
|
||||
STU(aes128_x86ni_ctr),
|
||||
STU(aes192_x86ni_ctr),
|
||||
STU(aes256_x86ni_ctr),
|
||||
|
||||
STU(des_tab_cbcenc),
|
||||
STU(des_tab_cbcdec),
|
||||
STU(3des_tab_cbcenc),
|
||||
@ -1173,6 +1230,7 @@ static const struct {
|
||||
STU(ghash_ctmul),
|
||||
STU(ghash_ctmul32),
|
||||
STU(ghash_ctmul64),
|
||||
STU(ghash_pclmul),
|
||||
|
||||
STU(poly1305_ctmul),
|
||||
STU(poly1305_ctmul32),
|
||||
|
@ -1531,9 +1531,9 @@ run_test_case(test_case *tc)
|
||||
br_x509_minimal_set_hash(&ctx, id, hash_impls[u].impl);
|
||||
}
|
||||
}
|
||||
br_x509_minimal_set_rsa(&ctx, br_rsa_i31_pkcs1_vrfy);
|
||||
br_x509_minimal_set_rsa(&ctx, br_rsa_pkcs1_vrfy_get_default());
|
||||
br_x509_minimal_set_ecdsa(&ctx,
|
||||
&br_ec_prime_i31, br_ecdsa_i31_vrfy_asn1);
|
||||
br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default());
|
||||
|
||||
/*
|
||||
* Set the validation date.
|
||||
@ -1819,9 +1819,9 @@ test_name_extraction(void)
|
||||
id = hash_impls[u].id;
|
||||
br_x509_minimal_set_hash(&ctx, id, hash_impls[u].impl);
|
||||
}
|
||||
br_x509_minimal_set_rsa(&ctx, br_rsa_i31_pkcs1_vrfy);
|
||||
br_x509_minimal_set_rsa(&ctx, br_rsa_pkcs1_vrfy_get_default());
|
||||
br_x509_minimal_set_ecdsa(&ctx,
|
||||
&br_ec_prime_i31, br_ecdsa_i31_vrfy_asn1);
|
||||
br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default());
|
||||
string_to_time(DEFAULT_TIME, &days, &seconds);
|
||||
br_x509_minimal_set_time(&ctx, days, seconds);
|
||||
|
||||
|
@ -471,6 +471,18 @@ const br_hash_class *get_hash_impl(int id);
|
||||
*/
|
||||
const char *find_error_name(int err, const char **comment);
|
||||
|
||||
/*
|
||||
* Find the symbolic name for an algorithm implementation. Provided
|
||||
* pointer should be a pointer to a vtable or to a function, where
|
||||
* appropriate. If not recognised, then the string "UNKNOWN" is returned.
|
||||
*
|
||||
* If 'long_name' is non-zero, then the returned name recalls the
|
||||
* algorithm type as well; otherwise, only the core implementation name
|
||||
* is returned (e.g. the long name could be 'aes_big_cbcenc' while the
|
||||
* short name is 'big').
|
||||
*/
|
||||
const char *get_algo_name(const void *algo, int long_name);
|
||||
|
||||
/*
|
||||
* Run a SSL engine, with a socket connected to the peer, and using
|
||||
* stdin/stdout to exchange application data.
|
||||
|
@ -341,14 +341,16 @@ static uint32_t
|
||||
cc_do_keyx(const br_ssl_client_certificate_class **pctx,
|
||||
unsigned char *data, size_t *len)
|
||||
{
|
||||
const br_ec_impl *iec;
|
||||
ccert_context *zc;
|
||||
size_t xoff, xlen;
|
||||
uint32_t r;
|
||||
|
||||
zc = (ccert_context *)pctx;
|
||||
r = br_ec_all_m15.mul(data, *len, zc->sk->key.ec.x,
|
||||
iec = br_ec_get_default();
|
||||
r = iec->mul(data, *len, zc->sk->key.ec.x,
|
||||
zc->sk->key.ec.xlen, zc->sk->key.ec.curve);
|
||||
xoff = br_ec_all_m15.xoff(zc->sk->key.ec.curve, &xlen);
|
||||
xoff = iec->xoff(zc->sk->key.ec.curve, &xlen);
|
||||
memmove(data, data + xoff, xlen);
|
||||
*len = xlen;
|
||||
return r;
|
||||
@ -390,8 +392,8 @@ cc_do_sign(const br_ssl_client_certificate_class **pctx,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
x = br_rsa_i31_pkcs1_sign(hash_oid, hv, hv_len,
|
||||
&zc->sk->key.rsa, data);
|
||||
x = br_rsa_pkcs1_sign_get_default()(
|
||||
hash_oid, hv, hv_len, &zc->sk->key.rsa, data);
|
||||
if (!x) {
|
||||
if (zc->verbose) {
|
||||
fprintf(stderr, "ERROR: RSA-sign failure\n");
|
||||
@ -418,8 +420,8 @@ cc_do_sign(const br_ssl_client_certificate_class **pctx,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
sig_len = br_ecdsa_i31_sign_asn1(&br_ec_all_m15,
|
||||
hc, hv, &zc->sk->key.ec, data);
|
||||
sig_len = br_ecdsa_sign_asn1_get_default()(
|
||||
br_ec_get_default(), hc, hv, &zc->sk->key.ec, data);
|
||||
if (sig_len == 0) {
|
||||
if (zc->verbose) {
|
||||
fprintf(stderr, "ERROR: ECDSA-sign failure\n");
|
||||
@ -946,54 +948,29 @@ do_client(int argc, char *argv[])
|
||||
}
|
||||
/* TODO: algorithm implementation selection */
|
||||
if ((req & REQ_AESCBC) != 0) {
|
||||
br_ssl_engine_set_aes_cbc(&cc.eng,
|
||||
&br_aes_ct_cbcenc_vtable,
|
||||
&br_aes_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_cbc(&cc.eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_default_aes_cbc(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_AESGCM) != 0) {
|
||||
br_ssl_engine_set_aes_ctr(&cc.eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc.eng,
|
||||
&br_ghash_ctmul);
|
||||
br_ssl_engine_set_gcm(&cc.eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_CHAPOL) != 0) {
|
||||
br_ssl_engine_set_chacha20(&cc.eng,
|
||||
&br_chacha20_ct_run);
|
||||
br_ssl_engine_set_poly1305(&cc.eng,
|
||||
&br_poly1305_ctmul_run);
|
||||
br_ssl_engine_set_chapol(&cc.eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_default_chapol(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_3DESCBC) != 0) {
|
||||
br_ssl_engine_set_des_cbc(&cc.eng,
|
||||
&br_des_ct_cbcenc_vtable,
|
||||
&br_des_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_cbc(&cc.eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_default_des_cbc(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_RSAKEYX) != 0) {
|
||||
br_ssl_client_set_rsapub(&cc, &br_rsa_i31_public);
|
||||
br_ssl_client_set_default_rsapub(&cc);
|
||||
}
|
||||
if ((req & REQ_ECDHE_RSA) != 0) {
|
||||
br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_rsavrfy(&cc.eng,
|
||||
&br_rsa_i31_pkcs1_vrfy);
|
||||
br_ssl_engine_set_default_ec(&cc.eng);
|
||||
br_ssl_engine_set_default_rsavrfy(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_ECDHE_ECDSA) != 0) {
|
||||
br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_ecdsa(&cc.eng,
|
||||
&br_ecdsa_i31_vrfy_asn1);
|
||||
br_ssl_engine_set_default_ecdsa(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_ECDH) != 0) {
|
||||
br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_default_ec(&cc.eng);
|
||||
}
|
||||
}
|
||||
if (fallback) {
|
||||
@ -1025,9 +1002,9 @@ do_client(int argc, char *argv[])
|
||||
&br_tls12_sha384_prf);
|
||||
}
|
||||
}
|
||||
br_x509_minimal_set_rsa(&xc, &br_rsa_i31_pkcs1_vrfy);
|
||||
br_x509_minimal_set_rsa(&xc, br_rsa_pkcs1_vrfy_get_default());
|
||||
br_x509_minimal_set_ecdsa(&xc,
|
||||
&br_ec_all_m15, &br_ecdsa_i31_vrfy_asn1);
|
||||
br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default());
|
||||
|
||||
/*
|
||||
* If there is no provided trust anchor, then certificate validation
|
||||
|
104
tools/names.c
104
tools/names.c
@ -271,7 +271,7 @@ const cipher_suite cipher_suites[] = {
|
||||
{ NULL, 0, 0, NULL }
|
||||
};
|
||||
|
||||
static struct {
|
||||
static const struct {
|
||||
int id;
|
||||
const char *name;
|
||||
} curves[] = {
|
||||
@ -338,6 +338,108 @@ static struct {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *long_name;
|
||||
const char *short_name;
|
||||
const void *impl;
|
||||
} algo_names[] = {
|
||||
/* Block ciphers */
|
||||
{ "aes_big_cbcenc", "big", &br_aes_big_cbcenc_vtable },
|
||||
{ "aes_big_cbcdec", "big", &br_aes_big_cbcdec_vtable },
|
||||
{ "aes_big_ctr", "big", &br_aes_big_ctr_vtable },
|
||||
{ "aes_small_cbcenc", "small", &br_aes_small_cbcenc_vtable },
|
||||
{ "aes_small_cbcdec", "small", &br_aes_small_cbcdec_vtable },
|
||||
{ "aes_small_ctr", "small", &br_aes_small_ctr_vtable },
|
||||
{ "aes_ct_cbcenc", "ct", &br_aes_ct_cbcenc_vtable },
|
||||
{ "aes_ct_cbcdec", "ct", &br_aes_ct_cbcdec_vtable },
|
||||
{ "aes_ct_ctr", "ct", &br_aes_ct_ctr_vtable },
|
||||
{ "aes_ct64_cbcenc", "ct64", &br_aes_ct64_cbcenc_vtable },
|
||||
{ "aes_ct64_cbcdec", "ct64", &br_aes_ct64_cbcdec_vtable },
|
||||
{ "aes_ct64_ctr", "ct64", &br_aes_ct64_ctr_vtable },
|
||||
|
||||
{ "des_tab_cbcenc", "tab", &br_des_tab_cbcenc_vtable },
|
||||
{ "des_tab_cbcdec", "tab", &br_des_tab_cbcdec_vtable },
|
||||
{ "des_ct_cbcenc", "ct", &br_des_ct_cbcenc_vtable },
|
||||
{ "des_ct_cbcdec", "ct", &br_des_ct_cbcdec_vtable },
|
||||
|
||||
{ "chacha20_ct", "ct", &br_chacha20_ct_run },
|
||||
|
||||
{ "ghash_ctmul", "ctmul", &br_ghash_ctmul },
|
||||
{ "ghash_ctmul32", "ctmul32", &br_ghash_ctmul32 },
|
||||
{ "ghash_ctmul64", "ctmul64", &br_ghash_ctmul64 },
|
||||
|
||||
{ "poly1305_ctmul", "ctmul", &br_poly1305_ctmul_run },
|
||||
{ "poly1305_ctmul32", "ctmul32", &br_poly1305_ctmul32_run },
|
||||
|
||||
{ "ec_all_m15", "all_m15", &br_ec_all_m15 },
|
||||
{ "ec_all_m31", "all_m31", &br_ec_all_m31 },
|
||||
{ "ec_c25519_i15", "c25519_i15", &br_ec_c25519_i15 },
|
||||
{ "ec_c25519_i31", "c25519_i31", &br_ec_c25519_i31 },
|
||||
{ "ec_c25519_m15", "c25519_m15", &br_ec_c25519_m15 },
|
||||
{ "ec_c25519_m31", "c25519_m31", &br_ec_c25519_m31 },
|
||||
{ "ec_p256_m15", "p256_m15", &br_ec_p256_m15 },
|
||||
{ "ec_p256_m31", "p256_m31", &br_ec_p256_m31 },
|
||||
{ "ec_prime_i15", "prime_i15", &br_ec_prime_i15 },
|
||||
{ "ec_prime_i31", "prime_i31", &br_ec_prime_i31 },
|
||||
|
||||
{ "ecdsa_i15_sign_asn1", "i15_asn1", &br_ecdsa_i15_sign_asn1 },
|
||||
{ "ecdsa_i15_sign_raw", "i15_raw", &br_ecdsa_i15_sign_raw },
|
||||
{ "ecdsa_i31_sign_asn1", "i31_asn1", &br_ecdsa_i31_sign_asn1 },
|
||||
{ "ecdsa_i31_sign_raw", "i31_raw", &br_ecdsa_i31_sign_raw },
|
||||
{ "ecdsa_i15_vrfy_asn1", "i15_asn1", &br_ecdsa_i15_vrfy_asn1 },
|
||||
{ "ecdsa_i15_vrfy_raw", "i15_raw", &br_ecdsa_i15_vrfy_raw },
|
||||
{ "ecdsa_i31_vrfy_asn1", "i31_asn1", &br_ecdsa_i31_vrfy_asn1 },
|
||||
{ "ecdsa_i31_vrfy_raw", "i31_raw", &br_ecdsa_i31_vrfy_raw },
|
||||
|
||||
{ "rsa_i15_pkcs1_sign", "i15", &br_rsa_i15_pkcs1_sign },
|
||||
{ "rsa_i31_pkcs1_sign", "i31", &br_rsa_i31_pkcs1_sign },
|
||||
{ "rsa_i32_pkcs1_sign", "i32", &br_rsa_i32_pkcs1_sign },
|
||||
{ "rsa_i15_pkcs1_vrfy", "i15", &br_rsa_i15_pkcs1_vrfy },
|
||||
{ "rsa_i31_pkcs1_vrfy", "i31", &br_rsa_i31_pkcs1_vrfy },
|
||||
{ "rsa_i32_pkcs1_vrfy", "i32", &br_rsa_i32_pkcs1_vrfy },
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *long_name;
|
||||
const char *short_name;
|
||||
const void *(*get)(void);
|
||||
} algo_names_dyn[] = {
|
||||
{ "aes_x86ni_cbcenc", "x86ni",
|
||||
(const void *(*)(void))&br_aes_x86ni_cbcenc_get_vtable },
|
||||
{ "aes_x86ni_cbcdec", "x86ni",
|
||||
(const void *(*)(void))&br_aes_x86ni_cbcdec_get_vtable },
|
||||
{ "aes_x86ni_ctr", "x86ni",
|
||||
(const void *(*)(void))&br_aes_x86ni_ctr_get_vtable },
|
||||
{ "ghash_pclmul", "pclmul",
|
||||
(const void *(*)(void))&br_ghash_pclmul_get },
|
||||
{ 0, 0, 0, }
|
||||
};
|
||||
|
||||
/* see brssl.h */
|
||||
const char *
|
||||
get_algo_name(const void *impl, int long_name)
|
||||
{
|
||||
size_t u;
|
||||
|
||||
for (u = 0; algo_names[u].long_name; u ++) {
|
||||
if (impl == algo_names[u].impl) {
|
||||
return long_name
|
||||
? algo_names[u].long_name
|
||||
: algo_names[u].short_name;
|
||||
}
|
||||
}
|
||||
for (u = 0; algo_names_dyn[u].long_name; u ++) {
|
||||
if (impl == algo_names_dyn[u].get()) {
|
||||
return long_name
|
||||
? algo_names_dyn[u].long_name
|
||||
: algo_names_dyn[u].short_name;
|
||||
}
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
/* see brssl.h */
|
||||
const char *
|
||||
get_curve_name(int id)
|
||||
|
@ -475,14 +475,17 @@ sp_do_keyx(const br_ssl_server_policy_class **pctx,
|
||||
|
||||
pc = (policy_context *)pctx;
|
||||
switch (pc->sk->key_type) {
|
||||
const br_ec_impl *iec;
|
||||
|
||||
case BR_KEYTYPE_RSA:
|
||||
return br_rsa_ssl_decrypt(
|
||||
&br_rsa_i31_private, &pc->sk->key.rsa,
|
||||
data, *len);
|
||||
br_rsa_private_get_default(),
|
||||
&pc->sk->key.rsa, data, *len);
|
||||
case BR_KEYTYPE_EC:
|
||||
r = br_ec_all_m15.mul(data, *len, pc->sk->key.ec.x,
|
||||
iec = br_ec_get_default();
|
||||
r = iec->mul(data, *len, pc->sk->key.ec.x,
|
||||
pc->sk->key.ec.xlen, pc->sk->key.ec.curve);
|
||||
xoff = br_ec_all_m15.xoff(pc->sk->key.ec.curve, &xlen);
|
||||
xoff = iec->xoff(pc->sk->key.ec.curve, &xlen);
|
||||
memmove(data, data + xoff, xlen);
|
||||
*len = xlen;
|
||||
return r;
|
||||
@ -556,8 +559,8 @@ sp_do_sign(const br_ssl_server_policy_class **pctx,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
x = br_rsa_i31_pkcs1_sign(hash_oid, hv, hv_len,
|
||||
&pc->sk->key.rsa, data);
|
||||
x = br_rsa_pkcs1_sign_get_default()(
|
||||
hash_oid, hv, hv_len, &pc->sk->key.rsa, data);
|
||||
if (!x) {
|
||||
if (pc->verbose) {
|
||||
fprintf(stderr, "ERROR: RSA-sign failure\n");
|
||||
@ -584,8 +587,8 @@ sp_do_sign(const br_ssl_server_policy_class **pctx,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
sig_len = br_ecdsa_i31_sign_asn1(&br_ec_all_m15,
|
||||
hc, hv, &pc->sk->key.ec, data);
|
||||
sig_len = br_ecdsa_sign_asn1_get_default()(
|
||||
br_ec_get_default(), hc, hv, &pc->sk->key.ec, data);
|
||||
if (sig_len == 0) {
|
||||
if (pc->verbose) {
|
||||
fprintf(stderr, "ERROR: ECDSA-sign failure\n");
|
||||
@ -956,7 +959,7 @@ do_server(int argc, char *argv[])
|
||||
break;
|
||||
case BR_KEYTYPE_EC:
|
||||
curve = sk->key.ec.curve;
|
||||
supp = br_ec_all_m15.supported_curves;
|
||||
supp = br_ec_get_default()->supported_curves;
|
||||
if (curve > 31 || !((supp >> curve) & 1)) {
|
||||
fprintf(stderr, "ERROR: private key curve (%d)"
|
||||
" is not supported\n", curve);
|
||||
@ -1046,41 +1049,19 @@ do_server(int argc, char *argv[])
|
||||
}
|
||||
/* TODO: algorithm implementation selection */
|
||||
if ((req & REQ_AESCBC) != 0) {
|
||||
br_ssl_engine_set_aes_cbc(&cc.eng,
|
||||
&br_aes_ct_cbcenc_vtable,
|
||||
&br_aes_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_cbc(&cc.eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_default_aes_cbc(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_AESGCM) != 0) {
|
||||
br_ssl_engine_set_aes_ctr(&cc.eng,
|
||||
&br_aes_ct_ctr_vtable);
|
||||
br_ssl_engine_set_ghash(&cc.eng,
|
||||
&br_ghash_ctmul);
|
||||
br_ssl_engine_set_gcm(&cc.eng,
|
||||
&br_sslrec_in_gcm_vtable,
|
||||
&br_sslrec_out_gcm_vtable);
|
||||
br_ssl_engine_set_default_aes_gcm(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_CHAPOL) != 0) {
|
||||
br_ssl_engine_set_chacha20(&cc.eng,
|
||||
&br_chacha20_ct_run);
|
||||
br_ssl_engine_set_poly1305(&cc.eng,
|
||||
&br_poly1305_ctmul_run);
|
||||
br_ssl_engine_set_chapol(&cc.eng,
|
||||
&br_sslrec_in_chapol_vtable,
|
||||
&br_sslrec_out_chapol_vtable);
|
||||
br_ssl_engine_set_default_chapol(&cc.eng);
|
||||
}
|
||||
if ((req & REQ_3DESCBC) != 0) {
|
||||
br_ssl_engine_set_des_cbc(&cc.eng,
|
||||
&br_des_ct_cbcenc_vtable,
|
||||
&br_des_ct_cbcdec_vtable);
|
||||
br_ssl_engine_set_cbc(&cc.eng,
|
||||
&br_sslrec_in_cbc_vtable,
|
||||
&br_sslrec_out_cbc_vtable);
|
||||
br_ssl_engine_set_default_des_cbc(&cc.eng);
|
||||
}
|
||||
if ((req & (REQ_ECDHE_RSA | REQ_ECDHE_ECDSA)) != 0) {
|
||||
br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_default_ec(&cc.eng);
|
||||
}
|
||||
}
|
||||
br_ssl_engine_set_suites(&cc.eng, suite_ids, num_suites);
|
||||
@ -1153,12 +1134,11 @@ do_server(int argc, char *argv[])
|
||||
br_x509_minimal_set_hash(&xc, id, hc);
|
||||
}
|
||||
}
|
||||
br_ssl_engine_set_rsavrfy(&cc.eng, &br_rsa_i31_pkcs1_vrfy);
|
||||
br_ssl_engine_set_ec(&cc.eng, &br_ec_all_m15);
|
||||
br_ssl_engine_set_ecdsa(&cc.eng, &br_ecdsa_i31_vrfy_asn1);
|
||||
br_x509_minimal_set_rsa(&xc, &br_rsa_i31_pkcs1_vrfy);
|
||||
br_ssl_engine_set_default_rsavrfy(&cc.eng);
|
||||
br_ssl_engine_set_default_ecdsa(&cc.eng);
|
||||
br_x509_minimal_set_rsa(&xc, br_rsa_pkcs1_vrfy_get_default());
|
||||
br_x509_minimal_set_ecdsa(&xc,
|
||||
&br_ec_all_m15, &br_ecdsa_i31_vrfy_asn1);
|
||||
br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default());
|
||||
br_ssl_engine_set_x509(&cc.eng, &xc.vtable);
|
||||
br_ssl_server_set_trust_anchor_names_alt(&cc,
|
||||
&VEC_ELT(anchors, 0), VEC_LEN(anchors));
|
||||
|
@ -262,6 +262,57 @@ run_ssl_engine(br_ssl_engine_context *cc, unsigned long fd, unsigned flags)
|
||||
verbose = (flags & RUN_ENGINE_VERBOSE) != 0;
|
||||
trace = (flags & RUN_ENGINE_TRACE) != 0;
|
||||
|
||||
/*
|
||||
* Print algorithm details.
|
||||
*/
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Algorithms:\n");
|
||||
if (cc->iaes_cbcenc != 0) {
|
||||
fprintf(stderr, " AES/CBC (enc): %s\n",
|
||||
get_algo_name(cc->iaes_cbcenc, 0));
|
||||
}
|
||||
if (cc->iaes_cbcdec != 0) {
|
||||
fprintf(stderr, " AES/CBC (dec): %s\n",
|
||||
get_algo_name(cc->iaes_cbcdec, 0));
|
||||
}
|
||||
if (cc->iaes_ctr != 0) {
|
||||
fprintf(stderr, " AES/CTR: %s\n",
|
||||
get_algo_name(cc->iaes_cbcdec, 0));
|
||||
}
|
||||
if (cc->ides_cbcenc != 0) {
|
||||
fprintf(stderr, " DES/CBC (enc): %s\n",
|
||||
get_algo_name(cc->ides_cbcenc, 0));
|
||||
}
|
||||
if (cc->ides_cbcdec != 0) {
|
||||
fprintf(stderr, " DES/CBC (dec): %s\n",
|
||||
get_algo_name(cc->ides_cbcdec, 0));
|
||||
}
|
||||
if (cc->ighash != 0) {
|
||||
fprintf(stderr, " GHASH (GCM): %s\n",
|
||||
get_algo_name(cc->ighash, 0));
|
||||
}
|
||||
if (cc->ichacha != 0) {
|
||||
fprintf(stderr, " ChaCha20: %s\n",
|
||||
get_algo_name(cc->ichacha, 0));
|
||||
}
|
||||
if (cc->ipoly != 0) {
|
||||
fprintf(stderr, " Poly1305: %s\n",
|
||||
get_algo_name(cc->ipoly, 0));
|
||||
}
|
||||
if (cc->iec != 0) {
|
||||
fprintf(stderr, " EC: %s\n",
|
||||
get_algo_name(cc->iec, 0));
|
||||
}
|
||||
if (cc->iecdsa != 0) {
|
||||
fprintf(stderr, " ECDSA: %s\n",
|
||||
get_algo_name(cc->iecdsa, 0));
|
||||
}
|
||||
if (cc->irsavrfy != 0) {
|
||||
fprintf(stderr, " RSA (vrfy): %s\n",
|
||||
get_algo_name(cc->irsavrfy, 0));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
fd_event = WSA_INVALID_EVENT;
|
||||
can_send = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user