New "i15" implementation of big integers (faster, and constant-time, on ARM Cortex M0/M0+); imported into EC, ECDSA, RSA.

This commit is contained in:
Thomas Pornin 2017-01-04 19:21:09 +01:00
parent 6dd8c51ba7
commit 28e4e120b8
29 changed files with 2993 additions and 326 deletions

View file

@ -369,6 +369,15 @@ typedef struct {
*/
extern const br_ec_impl br_ec_prime_i31;
/**
* \brief EC implementation "i15".
*
* This implementation internally uses generic code for modular integers,
* with a representation as sequences of 15-bit words. It supports secp256r1,
* secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521).
*/
extern const br_ec_impl br_ec_prime_i15;
/**
* \brief EC implementation "i15" for P-256.
*
@ -533,4 +542,70 @@ uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature generator, "i15" implementation, "asn1" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i15_sign_asn1(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature generator, "i15" implementation, "raw" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i15_sign_raw(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature verifier, "i15" implementation, "asn1" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature verifier, "i15" implementation, "raw" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
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);
#endif

View file

@ -121,7 +121,7 @@
*
* ## Implementations
*
* Two RSA implementations are included:
* Three RSA implementations are included:
*
* - The **i32** implementation internally represents big integers
* as arrays of 32-bit integers. It is perfunctory and portable,
@ -132,6 +132,12 @@
* faster than the i32 implementation (the reduced integer size makes
* carry propagation easier) for a similar code footprint, but uses
* very slightly larger stack buffers (about 4% bigger).
*
* - The **i15** implementation uses 16-bit integers, each containing
* 15 bits worth of integer data. Multiplication results fit on
* 32 bits, so this won't use the "widening" multiplication routine
* on ARM Cortex M0/M0+, for much better performance and constant-time
* execution.
*/
/**
@ -445,6 +451,70 @@ uint32_t br_rsa_i31_pkcs1_sign(const unsigned char *hash_oid,
const unsigned char *hash, size_t hash_len,
const br_rsa_private_key *sk, unsigned char *x);
/*
* RSA "i15" engine. Integers are represented as 15-bit integers, so
* the code uses only 32-bit multiplication (no 64-bit result), which
* is vastly faster (and constant-time) on the ARM Cortex M0/M0+.
*/
/**
* \brief RSA public key engine "i15".
*
* \see br_rsa_public
*
* \param x operand to exponentiate.
* \param xlen length of the operand (in bytes).
* \param pk RSA public key.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i15_public(unsigned char *x, size_t xlen,
const br_rsa_public_key *pk);
/**
* \brief RSA signature verification engine "i15".
*
* \see br_rsa_pkcs1_vrfy
*
* \param x signature buffer.
* \param xlen signature length (in bytes).
* \param hash_oid encoded hash algorithm OID (or `NULL`).
* \param hash_len expected hash value length (in bytes).
* \param pk RSA public key.
* \param hash_out output buffer for the hash value.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen,
const unsigned char *hash_oid, size_t hash_len,
const br_rsa_public_key *pk, unsigned char *hash_out);
/**
* \brief RSA private key engine "i15".
*
* \see br_rsa_private
*
* \param x operand to exponentiate.
* \param sk RSA private key.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i15_private(unsigned char *x,
const br_rsa_private_key *sk);
/**
* \brief RSA signature generation engine "i15".
*
* \see br_rsa_pkcs1_sign
*
* \param hash_oid encoded hash algorithm OID (or `NULL`).
* \param hash hash value.
* \param hash_len hash value length (in bytes).
* \param sk RSA private key.
* \param x output buffer for the hash value.
* \return 1 on success, 0 on error.
*/
uint32_t br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid,
const unsigned char *hash, size_t hash_len,
const br_rsa_private_key *sk, unsigned char *x);
/**
* \brief RSA decryption helper, for SSL/TLS.
*