Added AES+GHASH implementation using AES-NI opcodes; also ARM-Thumb assembly for...
authorThomas Pornin <pornin@bolet.org>
Sun, 29 Jan 2017 20:46:33 +0000 (21:46 +0100)
committerThomas Pornin <pornin@bolet.org>
Sun, 29 Jan 2017 20:46:33 +0000 (21:46 +0100)
58 files changed:
conf/Unix.mk
conf/Unix32.mk [new file with mode: 0644]
conf/UnixClang.mk [new file with mode: 0644]
conf/samd20.mk
inc/bearssl_block.h
inc/bearssl_ec.h
inc/bearssl_hash.h
inc/bearssl_rsa.h
inc/bearssl_ssl.h
mk/Rules.mk
mk/mkrules.sh
samples/custom_profile.c
src/config.h
src/ec/ec_default.c [new file with mode: 0644]
src/ec/ecdsa_default_sign_asn1.c [new file with mode: 0644]
src/ec/ecdsa_default_sign_raw.c [new file with mode: 0644]
src/ec/ecdsa_default_vrfy_asn1.c [new file with mode: 0644]
src/ec/ecdsa_default_vrfy_raw.c [new file with mode: 0644]
src/hash/ghash_pclmul.c [new file with mode: 0644]
src/inner.h
src/int/i15_modpow2.c
src/int/i15_montmul.c
src/rsa/rsa_default_pkcs1_sign.c [new file with mode: 0644]
src/rsa/rsa_default_pkcs1_vrfy.c [new file with mode: 0644]
src/rsa/rsa_default_priv.c [new file with mode: 0644]
src/rsa/rsa_default_pub.c [new file with mode: 0644]
src/rsa/rsa_i15_priv.c
src/rsa/rsa_i15_pub.c
src/ssl/ssl_client_default_rsapub.c [new file with mode: 0644]
src/ssl/ssl_client_full.c
src/ssl/ssl_engine_default_aescbc.c [new file with mode: 0644]
src/ssl/ssl_engine_default_aesgcm.c [new file with mode: 0644]
src/ssl/ssl_engine_default_chapol.c [new file with mode: 0644]
src/ssl/ssl_engine_default_descbc.c [new file with mode: 0644]
src/ssl/ssl_engine_default_ec.c [new file with mode: 0644]
src/ssl/ssl_engine_default_ecdsa.c [new file with mode: 0644]
src/ssl/ssl_engine_default_rsavrfy.c [new file with mode: 0644]
src/ssl/ssl_server_full_ec.c
src/ssl/ssl_server_full_rsa.c
src/ssl/ssl_server_mine2c.c
src/ssl/ssl_server_mine2g.c
src/ssl/ssl_server_minf2c.c
src/ssl/ssl_server_minf2g.c
src/ssl/ssl_server_minr2g.c
src/ssl/ssl_server_minu2g.c
src/ssl/ssl_server_minv2g.c
src/symcipher/aes_x86ni.c [new file with mode: 0644]
src/symcipher/aes_x86ni_cbcdec.c [new file with mode: 0644]
src/symcipher/aes_x86ni_cbcenc.c [new file with mode: 0644]
src/symcipher/aes_x86ni_ctr.c [new file with mode: 0644]
test/test_crypto.c
test/test_speed.c
test/test_x509.c
tools/brssl.h
tools/client.c
tools/names.c
tools/server.c
tools/sslio.c

index a9b6450..7764748 100644 (file)
@@ -53,7 +53,7 @@ LDDLLOUT = -o
 
 # Static linker.
 LD = gcc
-LDFLAGS =
+LDFLAGS = 
 LDOUT = -o 
 
 # C# compiler; we assume usage of Mono.
diff --git a/conf/Unix32.mk b/conf/Unix32.mk
new file mode 100644 (file)
index 0000000..0d3bed8
--- /dev/null
@@ -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
diff --git a/conf/UnixClang.mk b/conf/UnixClang.mk
new file mode 100644 (file)
index 0000000..331f4a8
--- /dev/null
@@ -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
index acb6272..5b3d500 100644 (file)
@@ -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
 
index 6641e6c..c6f20f5 100644 (file)
  * | 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        |
  *
  * 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;
 
 /*
index 5022530..3de86b4 100644 (file)
@@ -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
index e58a54f..524ac01 100644 (file)
@@ -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
index b9362a3..9e5b418 100644 (file)
@@ -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.
  *
index cf1d2db..fee7b3c 100644 (file)
@@ -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
  */
 
 /**
index 97d55d6..9e2ba07 100644 (file)
@@ -1,6 +1,6 @@
 # Automatically generated rules. Use 'mkrules.sh' to modify/regenerate.
 
-OBJ = $(OBJDIR)$Pccopy$O $(OBJDIR)$Pdec16be$O $(OBJDIR)$Pdec16le$O $(OBJDIR)$Pdec32be$O $(OBJDIR)$Pdec32le$O $(OBJDIR)$Pdec64be$O $(OBJDIR)$Pdec64le$O $(OBJDIR)$Penc16be$O $(OBJDIR)$Penc16le$O $(OBJDIR)$Penc32be$O $(OBJDIR)$Penc32le$O $(OBJDIR)$Penc64be$O $(OBJDIR)$Penc64le$O $(OBJDIR)$Ppemdec$O $(OBJDIR)$Pec_all_m15$O $(OBJDIR)$Pec_all_m31$O $(OBJDIR)$Pec_c25519_i15$O $(OBJDIR)$Pec_c25519_i31$O $(OBJDIR)$Pec_c25519_m15$O $(OBJDIR)$Pec_c25519_m31$O $(OBJDIR)$Pec_curve25519$O $(OBJDIR)$Pec_p256_m15$O $(OBJDIR)$Pec_p256_m31$O $(OBJDIR)$Pec_prime_i15$O $(OBJDIR)$Pec_prime_i31$O $(OBJDIR)$Pec_secp256r1$O $(OBJDIR)$Pec_secp384r1$O $(OBJDIR)$Pec_secp521r1$O $(OBJDIR)$Pecdsa_atr$O $(OBJDIR)$Pecdsa_i15_bits$O $(OBJDIR)$Pecdsa_i15_sign_asn1$O $(OBJDIR)$Pecdsa_i15_sign_raw$O $(OBJDIR)$Pecdsa_i15_vrfy_asn1$O $(OBJDIR)$Pecdsa_i15_vrfy_raw$O $(OBJDIR)$Pecdsa_i31_bits$O $(OBJDIR)$Pecdsa_i31_sign_asn1$O $(OBJDIR)$Pecdsa_i31_sign_raw$O $(OBJDIR)$Pecdsa_i31_vrfy_asn1$O $(OBJDIR)$Pecdsa_i31_vrfy_raw$O $(OBJDIR)$Pecdsa_rta$O $(OBJDIR)$Pdig_oid$O $(OBJDIR)$Pdig_size$O $(OBJDIR)$Pghash_ctmul$O $(OBJDIR)$Pghash_ctmul32$O $(OBJDIR)$Pghash_ctmul64$O $(OBJDIR)$Pmd5$O $(OBJDIR)$Pmd5sha1$O $(OBJDIR)$Pmultihash$O $(OBJDIR)$Psha1$O $(OBJDIR)$Psha2big$O $(OBJDIR)$Psha2small$O $(OBJDIR)$Pi15_add$O $(OBJDIR)$Pi15_bitlen$O $(OBJDIR)$Pi15_decmod$O $(OBJDIR)$Pi15_decode$O $(OBJDIR)$Pi15_decred$O $(OBJDIR)$Pi15_encode$O $(OBJDIR)$Pi15_fmont$O $(OBJDIR)$Pi15_iszero$O $(OBJDIR)$Pi15_modpow$O $(OBJDIR)$Pi15_modpow2$O $(OBJDIR)$Pi15_montmul$O $(OBJDIR)$Pi15_mulacc$O $(OBJDIR)$Pi15_muladd$O $(OBJDIR)$Pi15_ninv15$O $(OBJDIR)$Pi15_reduce$O $(OBJDIR)$Pi15_rshift$O $(OBJDIR)$Pi15_sub$O $(OBJDIR)$Pi15_tmont$O $(OBJDIR)$Pi31_add$O $(OBJDIR)$Pi31_bitlen$O $(OBJDIR)$Pi31_decmod$O $(OBJDIR)$Pi31_decode$O $(OBJDIR)$Pi31_decred$O $(OBJDIR)$Pi31_encode$O $(OBJDIR)$Pi31_fmont$O $(OBJDIR)$Pi31_iszero$O $(OBJDIR)$Pi31_modpow$O $(OBJDIR)$Pi31_montmul$O $(OBJDIR)$Pi31_mulacc$O $(OBJDIR)$Pi31_muladd$O $(OBJDIR)$Pi31_ninv31$O $(OBJDIR)$Pi31_reduce$O $(OBJDIR)$Pi31_rshift$O $(OBJDIR)$Pi31_sub$O $(OBJDIR)$Pi31_tmont$O $(OBJDIR)$Pi32_add$O $(OBJDIR)$Pi32_bitlen$O $(OBJDIR)$Pi32_decmod$O $(OBJDIR)$Pi32_decode$O $(OBJDIR)$Pi32_decred$O $(OBJDIR)$Pi32_div32$O $(OBJDIR)$Pi32_encode$O $(OBJDIR)$Pi32_fmont$O $(OBJDIR)$Pi32_iszero$O $(OBJDIR)$Pi32_modpow$O $(OBJDIR)$Pi32_montmul$O $(OBJDIR)$Pi32_mulacc$O $(OBJDIR)$Pi32_muladd$O $(OBJDIR)$Pi32_ninv32$O $(OBJDIR)$Pi32_reduce$O $(OBJDIR)$Pi32_sub$O $(OBJDIR)$Pi32_tmont$O $(OBJDIR)$Phmac$O $(OBJDIR)$Phmac_ct$O $(OBJDIR)$Phmac_drbg$O $(OBJDIR)$Prsa_i15_pkcs1_sign$O $(OBJDIR)$Prsa_i15_pkcs1_vrfy$O $(OBJDIR)$Prsa_i15_priv$O $(OBJDIR)$Prsa_i15_pub$O $(OBJDIR)$Prsa_i31_pkcs1_sign$O $(OBJDIR)$Prsa_i31_pkcs1_vrfy$O $(OBJDIR)$Prsa_i31_priv$O $(OBJDIR)$Prsa_i31_pub$O $(OBJDIR)$Prsa_i32_pkcs1_sign$O $(OBJDIR)$Prsa_i32_pkcs1_vrfy$O $(OBJDIR)$Prsa_i32_priv$O $(OBJDIR)$Prsa_i32_pub$O $(OBJDIR)$Prsa_pkcs1_sig_pad$O $(OBJDIR)$Prsa_pkcs1_sig_unpad$O $(OBJDIR)$Prsa_ssl_decrypt$O $(OBJDIR)$Pprf$O $(OBJDIR)$Pprf_md5sha1$O $(OBJDIR)$Pprf_sha256$O $(OBJDIR)$Pprf_sha384$O $(OBJDIR)$Pssl_ccert_single_ec$O $(OBJDIR)$Pssl_ccert_single_rsa$O $(OBJDIR)$Pssl_client$O $(OBJDIR)$Pssl_client_full$O $(OBJDIR)$Pssl_engine$O $(OBJDIR)$Pssl_hashes$O $(OBJDIR)$Pssl_hs_client$O $(OBJDIR)$Pssl_hs_server$O $(OBJDIR)$Pssl_io$O $(OBJDIR)$Pssl_lru$O $(OBJDIR)$Pssl_rec_cbc$O $(OBJDIR)$Pssl_rec_chapol$O $(OBJDIR)$Pssl_rec_gcm$O $(OBJDIR)$Pssl_scert_single_ec$O $(OBJDIR)$Pssl_scert_single_rsa$O $(OBJDIR)$Pssl_server$O $(OBJDIR)$Pssl_server_full_ec$O $(OBJDIR)$Pssl_server_full_rsa$O $(OBJDIR)$Pssl_server_mine2c$O $(OBJDIR)$Pssl_server_mine2g$O $(OBJDIR)$Pssl_server_minf2c$O $(OBJDIR)$Pssl_server_minf2g$O $(OBJDIR)$Pssl_server_minr2g$O $(OBJDIR)$Pssl_server_minu2g$O $(OBJDIR)$Pssl_server_minv2g$O $(OBJDIR)$Paes_big_cbcdec$O $(OBJDIR)$Paes_big_cbcenc$O $(OBJDIR)$Paes_big_ctr$O $(OBJDIR)$Paes_big_dec$O $(OBJDIR)$Paes_big_enc$O $(OBJDIR)$Paes_common$O $(OBJDIR)$Paes_ct$O $(OBJDIR)$Paes_ct64$O $(OBJDIR)$Paes_ct64_cbcdec$O $(OBJDIR)$Paes_ct64_cbcenc$O $(OBJDIR)$Paes_ct64_ctr$O $(OBJDIR)$Paes_ct64_dec$O $(OBJDIR)$Paes_ct64_enc$O $(OBJDIR)$Paes_ct_cbcdec$O $(OBJDIR)$Paes_ct_cbcenc$O $(OBJDIR)$Paes_ct_ctr$O $(OBJDIR)$Paes_ct_dec$O $(OBJDIR)$Paes_ct_enc$O $(OBJDIR)$Paes_small_cbcdec$O $(OBJDIR)$Paes_small_cbcenc$O $(OBJDIR)$Paes_small_ctr$O $(OBJDIR)$Paes_small_dec$O $(OBJDIR)$Paes_small_enc$O $(OBJDIR)$Pchacha20_ct$O $(OBJDIR)$Pdes_ct$O $(OBJDIR)$Pdes_ct_cbcdec$O $(OBJDIR)$Pdes_ct_cbcenc$O $(OBJDIR)$Pdes_support$O $(OBJDIR)$Pdes_tab$O $(OBJDIR)$Pdes_tab_cbcdec$O $(OBJDIR)$Pdes_tab_cbcenc$O $(OBJDIR)$Ppoly1305_ctmul$O $(OBJDIR)$Ppoly1305_ctmul32$O $(OBJDIR)$Ppoly1305_i15$O $(OBJDIR)$Pskey_decoder$O $(OBJDIR)$Px509_decoder$O $(OBJDIR)$Px509_knownkey$O $(OBJDIR)$Px509_minimal$O $(OBJDIR)$Px509_minimal_full$O
+OBJ = $(OBJDIR)$Pccopy$O $(OBJDIR)$Pdec16be$O $(OBJDIR)$Pdec16le$O $(OBJDIR)$Pdec32be$O $(OBJDIR)$Pdec32le$O $(OBJDIR)$Pdec64be$O $(OBJDIR)$Pdec64le$O $(OBJDIR)$Penc16be$O $(OBJDIR)$Penc16le$O $(OBJDIR)$Penc32be$O $(OBJDIR)$Penc32le$O $(OBJDIR)$Penc64be$O $(OBJDIR)$Penc64le$O $(OBJDIR)$Ppemdec$O $(OBJDIR)$Pec_all_m15$O $(OBJDIR)$Pec_all_m31$O $(OBJDIR)$Pec_c25519_i15$O $(OBJDIR)$Pec_c25519_i31$O $(OBJDIR)$Pec_c25519_m15$O $(OBJDIR)$Pec_c25519_m31$O $(OBJDIR)$Pec_curve25519$O $(OBJDIR)$Pec_default$O $(OBJDIR)$Pec_p256_m15$O $(OBJDIR)$Pec_p256_m31$O $(OBJDIR)$Pec_prime_i15$O $(OBJDIR)$Pec_prime_i31$O $(OBJDIR)$Pec_secp256r1$O $(OBJDIR)$Pec_secp384r1$O $(OBJDIR)$Pec_secp521r1$O $(OBJDIR)$Pecdsa_atr$O $(OBJDIR)$Pecdsa_default_sign_asn1$O $(OBJDIR)$Pecdsa_default_sign_raw$O $(OBJDIR)$Pecdsa_default_vrfy_asn1$O $(OBJDIR)$Pecdsa_default_vrfy_raw$O $(OBJDIR)$Pecdsa_i15_bits$O $(OBJDIR)$Pecdsa_i15_sign_asn1$O $(OBJDIR)$Pecdsa_i15_sign_raw$O $(OBJDIR)$Pecdsa_i15_vrfy_asn1$O $(OBJDIR)$Pecdsa_i15_vrfy_raw$O $(OBJDIR)$Pecdsa_i31_bits$O $(OBJDIR)$Pecdsa_i31_sign_asn1$O $(OBJDIR)$Pecdsa_i31_sign_raw$O $(OBJDIR)$Pecdsa_i31_vrfy_asn1$O $(OBJDIR)$Pecdsa_i31_vrfy_raw$O $(OBJDIR)$Pecdsa_rta$O $(OBJDIR)$Pdig_oid$O $(OBJDIR)$Pdig_size$O $(OBJDIR)$Pghash_ctmul$O $(OBJDIR)$Pghash_ctmul32$O $(OBJDIR)$Pghash_ctmul64$O $(OBJDIR)$Pghash_pclmul$O $(OBJDIR)$Pmd5$O $(OBJDIR)$Pmd5sha1$O $(OBJDIR)$Pmultihash$O $(OBJDIR)$Psha1$O $(OBJDIR)$Psha2big$O $(OBJDIR)$Psha2small$O $(OBJDIR)$Pi15_add$O $(OBJDIR)$Pi15_bitlen$O $(OBJDIR)$Pi15_decmod$O $(OBJDIR)$Pi15_decode$O $(OBJDIR)$Pi15_decred$O $(OBJDIR)$Pi15_encode$O $(OBJDIR)$Pi15_fmont$O $(OBJDIR)$Pi15_iszero$O $(OBJDIR)$Pi15_modpow$O $(OBJDIR)$Pi15_modpow2$O $(OBJDIR)$Pi15_montmul$O $(OBJDIR)$Pi15_mulacc$O $(OBJDIR)$Pi15_muladd$O $(OBJDIR)$Pi15_ninv15$O $(OBJDIR)$Pi15_reduce$O $(OBJDIR)$Pi15_rshift$O $(OBJDIR)$Pi15_sub$O $(OBJDIR)$Pi15_tmont$O $(OBJDIR)$Pi31_add$O $(OBJDIR)$Pi31_bitlen$O $(OBJDIR)$Pi31_decmod$O $(OBJDIR)$Pi31_decode$O $(OBJDIR)$Pi31_decred$O $(OBJDIR)$Pi31_encode$O $(OBJDIR)$Pi31_fmont$O $(OBJDIR)$Pi31_iszero$O $(OBJDIR)$Pi31_modpow$O $(OBJDIR)$Pi31_montmul$O $(OBJDIR)$Pi31_mulacc$O $(OBJDIR)$Pi31_muladd$O $(OBJDIR)$Pi31_ninv31$O $(OBJDIR)$Pi31_reduce$O $(OBJDIR)$Pi31_rshift$O $(OBJDIR)$Pi31_sub$O $(OBJDIR)$Pi31_tmont$O $(OBJDIR)$Pi32_add$O $(OBJDIR)$Pi32_bitlen$O $(OBJDIR)$Pi32_decmod$O $(OBJDIR)$Pi32_decode$O $(OBJDIR)$Pi32_decred$O $(OBJDIR)$Pi32_div32$O $(OBJDIR)$Pi32_encode$O $(OBJDIR)$Pi32_fmont$O $(OBJDIR)$Pi32_iszero$O $(OBJDIR)$Pi32_modpow$O $(OBJDIR)$Pi32_montmul$O $(OBJDIR)$Pi32_mulacc$O $(OBJDIR)$Pi32_muladd$O $(OBJDIR)$Pi32_ninv32$O $(OBJDIR)$Pi32_reduce$O $(OBJDIR)$Pi32_sub$O $(OBJDIR)$Pi32_tmont$O $(OBJDIR)$Phmac$O $(OBJDIR)$Phmac_ct$O $(OBJDIR)$Phmac_drbg$O $(OBJDIR)$Prsa_default_pkcs1_sign$O $(OBJDIR)$Prsa_default_pkcs1_vrfy$O $(OBJDIR)$Prsa_default_priv$O $(OBJDIR)$Prsa_default_pub$O $(OBJDIR)$Prsa_i15_pkcs1_sign$O $(OBJDIR)$Prsa_i15_pkcs1_vrfy$O $(OBJDIR)$Prsa_i15_priv$O $(OBJDIR)$Prsa_i15_pub$O $(OBJDIR)$Prsa_i31_pkcs1_sign$O $(OBJDIR)$Prsa_i31_pkcs1_vrfy$O $(OBJDIR)$Prsa_i31_priv$O $(OBJDIR)$Prsa_i31_pub$O $(OBJDIR)$Prsa_i32_pkcs1_sign$O $(OBJDIR)$Prsa_i32_pkcs1_vrfy$O $(OBJDIR)$Prsa_i32_priv$O $(OBJDIR)$Prsa_i32_pub$O $(OBJDIR)$Prsa_pkcs1_sig_pad$O $(OBJDIR)$Prsa_pkcs1_sig_unpad$O $(OBJDIR)$Prsa_ssl_decrypt$O $(OBJDIR)$Pprf$O $(OBJDIR)$Pprf_md5sha1$O $(OBJDIR)$Pprf_sha256$O $(OBJDIR)$Pprf_sha384$O $(OBJDIR)$Pssl_ccert_single_ec$O $(OBJDIR)$Pssl_ccert_single_rsa$O $(OBJDIR)$Pssl_client$O $(OBJDIR)$Pssl_client_default_rsapub$O $(OBJDIR)$Pssl_client_full$O $(OBJDIR)$Pssl_engine$O $(OBJDIR)$Pssl_engine_default_aescbc$O $(OBJDIR)$Pssl_engine_default_aesgcm$O $(OBJDIR)$Pssl_engine_default_chapol$O $(OBJDIR)$Pssl_engine_default_descbc$O $(OBJDIR)$Pssl_engine_default_ec$O $(OBJDIR)$Pssl_engine_default_ecdsa$O $(OBJDIR)$Pssl_engine_default_rsavrfy$O $(OBJDIR)$Pssl_hashes$O $(OBJDIR)$Pssl_hs_client$O $(OBJDIR)$Pssl_hs_server$O $(OBJDIR)$Pssl_io$O $(OBJDIR)$Pssl_lru$O $(OBJDIR)$Pssl_rec_cbc$O $(OBJDIR)$Pssl_rec_chapol$O $(OBJDIR)$Pssl_rec_gcm$O $(OBJDIR)$Pssl_scert_single_ec$O $(OBJDIR)$Pssl_scert_single_rsa$O $(OBJDIR)$Pssl_server$O $(OBJDIR)$Pssl_server_full_ec$O $(OBJDIR)$Pssl_server_full_rsa$O $(OBJDIR)$Pssl_server_mine2c$O $(OBJDIR)$Pssl_server_mine2g$O $(OBJDIR)$Pssl_server_minf2c$O $(OBJDIR)$Pssl_server_minf2g$O $(OBJDIR)$Pssl_server_minr2g$O $(OBJDIR)$Pssl_server_minu2g$O $(OBJDIR)$Pssl_server_minv2g$O $(OBJDIR)$Paes_big_cbcdec$O $(OBJDIR)$Paes_big_cbcenc$O $(OBJDIR)$Paes_big_ctr$O $(OBJDIR)$Paes_big_dec$O $(OBJDIR)$Paes_big_enc$O $(OBJDIR)$Paes_common$O $(OBJDIR)$Paes_ct$O $(OBJDIR)$Paes_ct64$O $(OBJDIR)$Paes_ct64_cbcdec$O $(OBJDIR)$Paes_ct64_cbcenc$O $(OBJDIR)$Paes_ct64_ctr$O $(OBJDIR)$Paes_ct64_dec$O $(OBJDIR)$Paes_ct64_enc$O $(OBJDIR)$Paes_ct_cbcdec$O $(OBJDIR)$Paes_ct_cbcenc$O $(OBJDIR)$Paes_ct_ctr$O $(OBJDIR)$Paes_ct_dec$O $(OBJDIR)$Paes_ct_enc$O $(OBJDIR)$Paes_small_cbcdec$O $(OBJDIR)$Paes_small_cbcenc$O $(OBJDIR)$Paes_small_ctr$O $(OBJDIR)$Paes_small_dec$O $(OBJDIR)$Paes_small_enc$O $(OBJDIR)$Paes_x86ni$O $(OBJDIR)$Paes_x86ni_cbcdec$O $(OBJDIR)$Paes_x86ni_cbcenc$O $(OBJDIR)$Paes_x86ni_ctr$O $(OBJDIR)$Pchacha20_ct$O $(OBJDIR)$Pdes_ct$O $(OBJDIR)$Pdes_ct_cbcdec$O $(OBJDIR)$Pdes_ct_cbcenc$O $(OBJDIR)$Pdes_support$O $(OBJDIR)$Pdes_tab$O $(OBJDIR)$Pdes_tab_cbcdec$O $(OBJDIR)$Pdes_tab_cbcenc$O $(OBJDIR)$Ppoly1305_ctmul$O $(OBJDIR)$Ppoly1305_ctmul32$O $(OBJDIR)$Ppoly1305_i15$O $(OBJDIR)$Pskey_decoder$O $(OBJDIR)$Px509_decoder$O $(OBJDIR)$Px509_knownkey$O $(OBJDIR)$Px509_minimal$O $(OBJDIR)$Px509_minimal_full$O
 OBJBRSSL = $(OBJDIR)$Pbrssl$O $(OBJDIR)$Pcerts$O $(OBJDIR)$Pchain$O $(OBJDIR)$Pclient$O $(OBJDIR)$Perrors$O $(OBJDIR)$Pfiles$O $(OBJDIR)$Pkeys$O $(OBJDIR)$Pnames$O $(OBJDIR)$Pserver$O $(OBJDIR)$Pskey$O $(OBJDIR)$Psslio$O $(OBJDIR)$Pta$O $(OBJDIR)$Pvector$O $(OBJDIR)$Pverify$O $(OBJDIR)$Pxmem$O
 OBJTESTCRYPTO = $(OBJDIR)$Ptest_crypto$O
 OBJTESTSPEED = $(OBJDIR)$Ptest_speed$O
@@ -122,6 +122,9 @@ $(OBJDIR)$Pec_c25519_m31$O: src$Pec$Pec_c25519_m31.c $(HEADERSPRIV)
 $(OBJDIR)$Pec_curve25519$O: src$Pec$Pec_curve25519.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pec_curve25519$O src$Pec$Pec_curve25519.c
 
+$(OBJDIR)$Pec_default$O: src$Pec$Pec_default.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pec_default$O src$Pec$Pec_default.c
+
 $(OBJDIR)$Pec_p256_m15$O: src$Pec$Pec_p256_m15.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pec_p256_m15$O src$Pec$Pec_p256_m15.c
 
@@ -146,6 +149,18 @@ $(OBJDIR)$Pec_secp521r1$O: src$Pec$Pec_secp521r1.c $(HEADERSPRIV)
 $(OBJDIR)$Pecdsa_atr$O: src$Pec$Pecdsa_atr.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pecdsa_atr$O src$Pec$Pecdsa_atr.c
 
+$(OBJDIR)$Pecdsa_default_sign_asn1$O: src$Pec$Pecdsa_default_sign_asn1.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pecdsa_default_sign_asn1$O src$Pec$Pecdsa_default_sign_asn1.c
+
+$(OBJDIR)$Pecdsa_default_sign_raw$O: src$Pec$Pecdsa_default_sign_raw.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pecdsa_default_sign_raw$O src$Pec$Pecdsa_default_sign_raw.c
+
+$(OBJDIR)$Pecdsa_default_vrfy_asn1$O: src$Pec$Pecdsa_default_vrfy_asn1.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pecdsa_default_vrfy_asn1$O src$Pec$Pecdsa_default_vrfy_asn1.c
+
+$(OBJDIR)$Pecdsa_default_vrfy_raw$O: src$Pec$Pecdsa_default_vrfy_raw.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pecdsa_default_vrfy_raw$O src$Pec$Pecdsa_default_vrfy_raw.c
+
 $(OBJDIR)$Pecdsa_i15_bits$O: src$Pec$Pecdsa_i15_bits.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pecdsa_i15_bits$O src$Pec$Pecdsa_i15_bits.c
 
@@ -194,6 +209,9 @@ $(OBJDIR)$Pghash_ctmul32$O: src$Phash$Pghash_ctmul32.c $(HEADERSPRIV)
 $(OBJDIR)$Pghash_ctmul64$O: src$Phash$Pghash_ctmul64.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pghash_ctmul64$O src$Phash$Pghash_ctmul64.c
 
+$(OBJDIR)$Pghash_pclmul$O: src$Phash$Pghash_pclmul.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pghash_pclmul$O src$Phash$Pghash_pclmul.c
+
 $(OBJDIR)$Pmd5$O: src$Phash$Pmd5.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pmd5$O src$Phash$Pmd5.c
 
@@ -377,6 +395,18 @@ $(OBJDIR)$Phmac_ct$O: src$Pmac$Phmac_ct.c $(HEADERSPRIV)
 $(OBJDIR)$Phmac_drbg$O: src$Prand$Phmac_drbg.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Phmac_drbg$O src$Prand$Phmac_drbg.c
 
+$(OBJDIR)$Prsa_default_pkcs1_sign$O: src$Prsa$Prsa_default_pkcs1_sign.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Prsa_default_pkcs1_sign$O src$Prsa$Prsa_default_pkcs1_sign.c
+
+$(OBJDIR)$Prsa_default_pkcs1_vrfy$O: src$Prsa$Prsa_default_pkcs1_vrfy.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Prsa_default_pkcs1_vrfy$O src$Prsa$Prsa_default_pkcs1_vrfy.c
+
+$(OBJDIR)$Prsa_default_priv$O: src$Prsa$Prsa_default_priv.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Prsa_default_priv$O src$Prsa$Prsa_default_priv.c
+
+$(OBJDIR)$Prsa_default_pub$O: src$Prsa$Prsa_default_pub.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Prsa_default_pub$O src$Prsa$Prsa_default_pub.c
+
 $(OBJDIR)$Prsa_i15_pkcs1_sign$O: src$Prsa$Prsa_i15_pkcs1_sign.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Prsa_i15_pkcs1_sign$O src$Prsa$Prsa_i15_pkcs1_sign.c
 
@@ -443,12 +473,36 @@ $(OBJDIR)$Pssl_ccert_single_rsa$O: src$Pssl$Pssl_ccert_single_rsa.c $(HEADERSPRI
 $(OBJDIR)$Pssl_client$O: src$Pssl$Pssl_client.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_client$O src$Pssl$Pssl_client.c
 
+$(OBJDIR)$Pssl_client_default_rsapub$O: src$Pssl$Pssl_client_default_rsapub.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_client_default_rsapub$O src$Pssl$Pssl_client_default_rsapub.c
+
 $(OBJDIR)$Pssl_client_full$O: src$Pssl$Pssl_client_full.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_client_full$O src$Pssl$Pssl_client_full.c
 
 $(OBJDIR)$Pssl_engine$O: src$Pssl$Pssl_engine.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine$O src$Pssl$Pssl_engine.c
 
+$(OBJDIR)$Pssl_engine_default_aescbc$O: src$Pssl$Pssl_engine_default_aescbc.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine_default_aescbc$O src$Pssl$Pssl_engine_default_aescbc.c
+
+$(OBJDIR)$Pssl_engine_default_aesgcm$O: src$Pssl$Pssl_engine_default_aesgcm.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine_default_aesgcm$O src$Pssl$Pssl_engine_default_aesgcm.c
+
+$(OBJDIR)$Pssl_engine_default_chapol$O: src$Pssl$Pssl_engine_default_chapol.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine_default_chapol$O src$Pssl$Pssl_engine_default_chapol.c
+
+$(OBJDIR)$Pssl_engine_default_descbc$O: src$Pssl$Pssl_engine_default_descbc.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine_default_descbc$O src$Pssl$Pssl_engine_default_descbc.c
+
+$(OBJDIR)$Pssl_engine_default_ec$O: src$Pssl$Pssl_engine_default_ec.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine_default_ec$O src$Pssl$Pssl_engine_default_ec.c
+
+$(OBJDIR)$Pssl_engine_default_ecdsa$O: src$Pssl$Pssl_engine_default_ecdsa.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine_default_ecdsa$O src$Pssl$Pssl_engine_default_ecdsa.c
+
+$(OBJDIR)$Pssl_engine_default_rsavrfy$O: src$Pssl$Pssl_engine_default_rsavrfy.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_engine_default_rsavrfy$O src$Pssl$Pssl_engine_default_rsavrfy.c
+
 $(OBJDIR)$Pssl_hashes$O: src$Pssl$Pssl_hashes.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pssl_hashes$O src$Pssl$Pssl_hashes.c
 
@@ -578,6 +632,18 @@ $(OBJDIR)$Paes_small_dec$O: src$Psymcipher$Paes_small_dec.c $(HEADERSPRIV)
 $(OBJDIR)$Paes_small_enc$O: src$Psymcipher$Paes_small_enc.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Paes_small_enc$O src$Psymcipher$Paes_small_enc.c
 
+$(OBJDIR)$Paes_x86ni$O: src$Psymcipher$Paes_x86ni.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Paes_x86ni$O src$Psymcipher$Paes_x86ni.c
+
+$(OBJDIR)$Paes_x86ni_cbcdec$O: src$Psymcipher$Paes_x86ni_cbcdec.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Paes_x86ni_cbcdec$O src$Psymcipher$Paes_x86ni_cbcdec.c
+
+$(OBJDIR)$Paes_x86ni_cbcenc$O: src$Psymcipher$Paes_x86ni_cbcenc.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Paes_x86ni_cbcenc$O src$Psymcipher$Paes_x86ni_cbcenc.c
+
+$(OBJDIR)$Paes_x86ni_ctr$O: src$Psymcipher$Paes_x86ni_ctr.c $(HEADERSPRIV)
+       $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Paes_x86ni_ctr$O src$Psymcipher$Paes_x86ni_ctr.c
+
 $(OBJDIR)$Pchacha20_ct$O: src$Psymcipher$Pchacha20_ct.c $(HEADERSPRIV)
        $(CC) $(CFLAGS) $(INCFLAGS) $(CCOUT)$(OBJDIR)$Pchacha20_ct$O src$Psymcipher$Pchacha20_ct.c
 
index 8e2132b..4c9d2cd 100755 (executable)
@@ -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 \
index e88d948..7191958 100644 (file)
@@ -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 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.
         *
-        * The RSA code comes in two variants, called "i31" and "i32".
-        * Right now, the "i31" is somewhat faster.
+        *  - 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),
index 5de3a5a..9eadaf4 100644 (file)
 #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
 #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
diff --git a/src/ec/ec_default.c b/src/ec/ec_default.c
new file mode 100644 (file)
index 0000000..7bb6e0c
--- /dev/null
@@ -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
+}
diff --git a/src/ec/ecdsa_default_sign_asn1.c b/src/ec/ecdsa_default_sign_asn1.c
new file mode 100644 (file)
index 0000000..afbf8ac
--- /dev/null
@@ -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
+}
diff --git a/src/ec/ecdsa_default_sign_raw.c b/src/ec/ecdsa_default_sign_raw.c
new file mode 100644 (file)
index 0000000..287c970
--- /dev/null
@@ -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
+}
diff --git a/src/ec/ecdsa_default_vrfy_asn1.c b/src/ec/ecdsa_default_vrfy_asn1.c
new file mode 100644 (file)
index 0000000..fe0996e
--- /dev/null
@@ -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
+}
diff --git a/src/ec/ecdsa_default_vrfy_raw.c b/src/ec/ecdsa_default_vrfy_raw.c
new file mode 100644 (file)
index 0000000..e564a10
--- /dev/null
@@ -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
+}
diff --git a/src/hash/ghash_pclmul.c b/src/hash/ghash_pclmul.c
new file mode 100644 (file)
index 0000000..c709889
--- /dev/null
@@ -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
index 2bb8192..472dc2e 100644 (file)
 #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.
index dce9941..37073a4 100644 (file)
@@ -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);
 
        /*
index 8da938f..e98bc32 100644 (file)
@@ -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;
 
diff --git a/src/rsa/rsa_default_pkcs1_sign.c b/src/rsa/rsa_default_pkcs1_sign.c
new file mode 100644 (file)
index 0000000..4e8d4ec
--- /dev/null
@@ -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
+}
diff --git a/src/rsa/rsa_default_pkcs1_vrfy.c b/src/rsa/rsa_default_pkcs1_vrfy.c
new file mode 100644 (file)
index 0000000..c5d81d6
--- /dev/null
@@ -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
+}
diff --git a/src/rsa/rsa_default_priv.c b/src/rsa/rsa_default_priv.c
new file mode 100644 (file)
index 0000000..04e3381
--- /dev/null
@@ -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
+}
diff --git a/src/rsa/rsa_default_pub.c b/src/rsa/rsa_default_pub.c
new file mode 100644 (file)
index 0000000..1dbfb62
--- /dev/null
@@ -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
+}
index 8dc839a..e692da4 100644 (file)
@@ -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);
index 09f558a..9eab5e8 100644 (file)
@@ -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.
diff --git a/src/ssl/ssl_client_default_rsapub.c b/src/ssl/ssl_client_default_rsapub.c
new file mode 100644 (file)
index 0000000..733151d
--- /dev/null
@@ -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
+}
index cd49a93..9c61d23 100644 (file)
@@ -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).
-        */
-#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).
+        * Symmetric encryption. We use the "default" implementations
+        * (fastest among constant-time implementations).
         */
-       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);
 }
diff --git a/src/ssl/ssl_engine_default_aescbc.c b/src/ssl/ssl_engine_default_aescbc.c
new file mode 100644 (file)
index 0000000..556d6eb
--- /dev/null
@@ -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
+}
diff --git a/src/ssl/ssl_engine_default_aesgcm.c b/src/ssl/ssl_engine_default_aesgcm.c
new file mode 100644 (file)
index 0000000..9968342
--- /dev/null
@@ -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
+}
diff --git a/src/ssl/ssl_engine_default_chapol.c b/src/ssl/ssl_engine_default_chapol.c
new file mode 100644 (file)
index 0000000..5f089b1
--- /dev/null
@@ -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
+}
diff --git a/src/ssl/ssl_engine_default_descbc.c b/src/ssl/ssl_engine_default_descbc.c
new file mode 100644 (file)
index 0000000..0253cb2
--- /dev/null
@@ -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);
+}
diff --git a/src/ssl/ssl_engine_default_ec.c b/src/ssl/ssl_engine_default_ec.c
new file mode 100644 (file)
index 0000000..0213ae6
--- /dev/null
@@ -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
+}
diff --git a/src/ssl/ssl_engine_default_ecdsa.c b/src/ssl/ssl_engine_default_ecdsa.c
new file mode 100644 (file)
index 0000000..1304002
--- /dev/null
@@ -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
+}
diff --git a/src/ssl/ssl_engine_default_rsavrfy.c b/src/ssl/ssl_engine_default_rsavrfy.c
new file mode 100644 (file)
index 0000000..f05cc49
--- /dev/null
@@ -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
+}
index dbe215d..e6765f5 100644 (file)
@@ -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).
-        */
-#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).
+        * Symmetric encryption.
         */
-       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);
 }
index ffec9be..cbb60f9 100644 (file)
@@ -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).
-        */
-#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).
+        * Symmetric encryption.
         */
-       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);
 }
index 7c53e29..bf61b56 100644 (file)
@@ -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);
 }
index f5a1e7d..80fa5b1 100644 (file)
@@ -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);
 }
index 7ded293..3f44236 100644 (file)
@@ -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);
 }
index 94f9dfb..8613de1 100644 (file)
@@ -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);
 }
index 05ad891..83c238b 100644 (file)
@@ -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);
 }
index cbf1fe4..6721384 100644 (file)
@@ -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);
 }
index 714a399..194e654 100644 (file)
@@ -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);
 }
diff --git a/src/symcipher/aes_x86ni.c b/src/symcipher/aes_x86ni.c
new file mode 100644 (file)
index 0000000..dcc3952
--- /dev/null
@@ -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
diff --git a/src/symcipher/aes_x86ni_cbcdec.c b/src/symcipher/aes_x86ni_cbcdec.c
new file mode 100644 (file)
index 0000000..6f75348
--- /dev/null
@@ -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
diff --git a/src/symcipher/aes_x86ni_cbcenc.c b/src/symcipher/aes_x86ni_cbcenc.c
new file mode 100644 (file)
index 0000000..f1c473e
--- /dev/null
@@ -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
diff --git a/src/symcipher/aes_x86ni_ctr.c b/src/symcipher/aes_x86ni_ctr.c
new file mode 100644 (file)
index 0000000..a476843
--- /dev/null
@@ -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
index 53a5f13..ca7234d 100644 (file)
@@ -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),
index 0d440ff..d7dfaad 100644 (file)
@@ -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),
index 6f75feb..2c61cf5 100644 (file)
@@ -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);
 
index 8c84b04..f2957e6 100644 (file)
@@ -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.
index 37b8877..fad18e0 100644 (file)
@@ -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
index 438f41a..753a736 100644 (file)
@@ -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)
index fbc7786..363028f 100644 (file)
@@ -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));
index 9941090..8d58ee9 100644 (file)
@@ -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;