Added RSA key generation code (i15, i31, i62).

This commit is contained in:
Thomas Pornin 2018-07-31 23:00:26 +02:00
parent a0054ad821
commit 491a45337d
15 changed files with 2865 additions and 13 deletions

View file

@ -84,7 +84,7 @@ extern "C" {
* random masking, but "true" constant-time code.
*
* - They support only private keys with two prime factors. RSA private
* key with three or more prime factors are nominally supported, but
* keys with three or more prime factors are nominally supported, but
* rarely used; they may offer faster operations, at the expense of
* more code and potentially a reduction in security if there are
* "too many" prime factors.
@ -92,7 +92,7 @@ extern "C" {
* - The public exponent may have arbitrary length. Of course, it is
* a good idea to keep public exponents small, so that public key
* operations are fast; but, contrary to some widely deployed
* implementations, BearSSL has no problem with public exponent
* implementations, BearSSL has no problem with public exponents
* longer than 32 bits.
*
* - The two prime factors of the modulus need not have the same length
@ -170,7 +170,7 @@ typedef struct {
/**
* \brief RSA private key.
*
* The structure references the primvate factors, reduced private
* The structure references the private factors, reduced private
* exponents, and CRT coefficient. It also contains the bit length of
* the modulus. The big integers use unsigned big-endian representation;
* extra leading bytes of value 0 are allowed. However, the modulus bit
@ -1032,6 +1032,158 @@ uint32_t br_rsa_i62_oaep_decrypt(
const br_hash_class *dig, const void *label, size_t label_len,
const br_rsa_private_key *sk, void *data, size_t *len);
/**
* \brief Get buffer size to hold RSA private key elements.
*
* This macro returns the length (in bytes) of the buffer needed to
* receive the elements of a RSA private key, as generated by one of
* the `br_rsa_*_keygen()` functions. If the provided size is a constant
* expression, then the whole macro evaluates to a constant expression.
*
* \param size target key size (modulus size, in bits)
* \return the length of the private key buffer, in bytes.
*/
#define BR_RSA_KBUF_PRIV_SIZE(size) (5 * (((size) + 15) >> 4))
/**
* \brief Get buffer size to hold RSA public key elements.
*
* This macro returns the length (in bytes) of the buffer needed to
* receive the elements of a RSA public key, as generated by one of
* the `br_rsa_*_keygen()` functions. If the provided size is a constant
* expression, then the whole macro evaluates to a constant expression.
*
* \param size target key size (modulus size, in bits)
* \return the length of the public key buffer, in bytes.
*/
#define BR_RSA_KBUF_PUB_SIZE(size) (4 + (((size) + 7) >> 3))
/**
* \brief Type for RSA key pair generator implementation.
*
* This function generates a new RSA key pair whose modulus has bit
* length `size` bits. The private key elements are written in the
* `kbuf_priv` buffer, and pointer values and length fields to these
* elements are populated in the provided private key structure `sk`.
* Similarly, the public key elements are written in `kbuf_pub`, with
* pointers and lengths set in `pk`.
*
* If `sk` is `NULL`, then `kbuf_pub` may be `NULL`, and only the
* private key is set.
*
* If `pubexp` is not zero, then its value will be used as public
* exponent. Valid RSA public exponent values are odd integers
* greater than 1. If `pubexp` is zero, then the public exponent will
* have value 3.
*
* The provided PRNG (`rng_ctx`) must have already been initialized
* and seeded.
*
* Returned value is 1 on success, 0 on error. An error is reported
* if the requested range is outside of the supported key sizes, or
* if an invalid non-zero public exponent value is provided. Supported
* range starts at 512 bits, and up to an implementation-defined
* maximum (by default 4096 bits). Note that key sizes up to 768 bits
* have been broken in practice, and sizes lower than 2048 bits are
* usually considered to be weak and should not be used.
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
typedef uint32_t (*br_rsa_keygen)(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, unsigned char *kbuf_priv,
br_rsa_public_key *pk, unsigned char *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief RSA key pair generation with the "i15" engine.
*
* \see br_rsa_keygen
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
uint32_t br_rsa_i15_keygen(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, unsigned char *kbuf_priv,
br_rsa_public_key *pk, unsigned char *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief RSA key pair generation with the "i31" engine.
*
* \see br_rsa_keygen
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
uint32_t br_rsa_i31_keygen(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, unsigned char *kbuf_priv,
br_rsa_public_key *pk, unsigned char *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief RSA key pair generation with the "i62" engine.
*
* This function is defined only on architecture that offer a 64x64->128
* opcode. Use `br_rsa_i62_keygen_get()` to dynamically obtain a pointer
* to that function.
*
* \see br_rsa_keygen
*
* \param rng_ctx source PRNG context (already initialized)
* \param sk RSA private key structure (destination)
* \param kbuf_priv buffer for private key elements
* \param pk RSA public key structure (destination), or `NULL`
* \param kbuf_pub buffer for public key elements, or `NULL`
* \param size target RSA modulus size (in bits)
* \param pubexp public exponent to use, or zero
* \return 1 on success, 0 on error (invalid parameters)
*/
uint32_t br_rsa_i62_keygen(
const br_prng_class **rng_ctx,
br_rsa_private_key *sk, unsigned char *kbuf_priv,
br_rsa_public_key *pk, unsigned char *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
* \brief Get the RSA "i62" implementation (key pair generation),
* if available.
*
* \return the implementation, or 0.
*/
br_rsa_keygen br_rsa_i62_keygen_get(void);
/**
* \brief Get "default" RSA implementation (key pair generation).
*
* This returns the preferred implementation of RSA (key pair generation)
* on the current system.
*
* \return the default implementation.
*/
br_rsa_keygen br_rsa_keygen_get_default(void);
#ifdef __cplusplus
}
#endif