Added support code for RSA and EC key encoding (including reconstruction of all public and private key elements from the private key structure), with raw and PKCS#8 formats, both in DER and PEM.

This commit is contained in:
Thomas Pornin 2018-08-06 00:02:36 +02:00
parent cfbc702d3d
commit d8fa415fca
32 changed files with 3528 additions and 105 deletions

View file

@ -28,6 +28,8 @@
#include <stddef.h>
#include <stdint.h>
#include "bearssl_rand.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -1068,7 +1070,7 @@ uint32_t br_rsa_i62_oaep_decrypt(
* 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
* If `pk` 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
@ -1098,8 +1100,8 @@ uint32_t br_rsa_i62_oaep_decrypt(
*/
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,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
@ -1118,8 +1120,8 @@ typedef uint32_t (*br_rsa_keygen)(
*/
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,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
@ -1138,8 +1140,8 @@ uint32_t br_rsa_i15_keygen(
*/
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,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
@ -1162,8 +1164,8 @@ uint32_t br_rsa_i31_keygen(
*/
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,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp);
/**
@ -1184,6 +1186,176 @@ br_rsa_keygen br_rsa_i62_keygen_get(void);
*/
br_rsa_keygen br_rsa_keygen_get_default(void);
/**
* \brief Type for a modulus computing function.
*
* Such a function computes the public modulus from the private key. The
* encoded modulus (unsigned big-endian) is written on `n`, and the size
* (in bytes) is returned. If `n` is `NULL`, then the size is returned but
* the modulus itself is not computed.
*
* If the key size exceeds an internal limit, 0 is returned.
*
* \param n destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the modulus length (in bytes), or 0.
*/
typedef size_t (*br_rsa_compute_modulus)(void *n, const br_rsa_private_key *sk);
/**
* \brief Recompute RSA modulus ("i15" engine).
*
* \see br_rsa_compute_modulus
*
* \param n destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the modulus length (in bytes), or 0.
*/
size_t br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk);
/**
* \brief Recompute RSA modulus ("i31" engine).
*
* \see br_rsa_compute_modulus
*
* \param n destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the modulus length (in bytes), or 0.
*/
size_t br_rsa_i31_compute_modulus(void *n, const br_rsa_private_key *sk);
/**
* \brief Get "default" RSA implementation (recompute modulus).
*
* This returns the preferred implementation of RSA (recompute modulus)
* on the current system.
*
* \return the default implementation.
*/
br_rsa_compute_modulus br_rsa_compute_modulus_get_default(void);
/**
* \brief Type for a public exponent computing function.
*
* Such a function recomputes the public exponent from the private key.
* 0 is returned if any of the following occurs:
*
* - Either `p` or `q` is not equal to 3 modulo 4.
*
* - The public exponent does not fit on 32 bits.
*
* - An internal limit is exceeded.
*
* - The private key is invalid in some way.
*
* For all private keys produced by the key generator functions
* (`br_rsa_keygen` type), this function succeeds and returns the true
* public exponent. The public exponent is always an odd integer greater
* than 1.
*
* \return the public exponent, or 0.
*/
typedef uint32_t (*br_rsa_compute_pubexp)(const br_rsa_private_key *sk);
/**
* \brief Recompute RSA public exponent ("i15" engine).
*
* \see br_rsa_compute_pubexp
*
* \return the public exponent, or 0.
*/
uint32_t br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk);
/**
* \brief Recompute RSA public exponent ("i31" engine).
*
* \see br_rsa_compute_pubexp
*
* \return the public exponent, or 0.
*/
uint32_t br_rsa_i31_compute_pubexp(const br_rsa_private_key *sk);
/**
* \brief Get "default" RSA implementation (recompute public exponent).
*
* This returns the preferred implementation of RSA (recompute public
* exponent) on the current system.
*
* \return the default implementation.
*/
br_rsa_compute_pubexp br_rsa_compute_pubexp_get_default(void);
/**
* \brief Type for a private exponent computing function.
*
* An RSA private key (`br_rsa_private_key`) contains two reduced
* private exponents, which are sufficient to perform private key
* operations. However, standard encoding formats for RSA private keys
* require also a copy of the complete private exponent (non-reduced),
* which this function recomputes.
*
* This function suceeds if all the following conditions hold:
*
* - Both private factors `p` and `q` are equal to 3 modulo 4.
*
* - The provided public exponent `pubexp` is correct, and, in particular,
* is odd, relatively prime to `p-1` and `q-1`, and greater than 1.
*
* - No internal storage limit is exceeded.
*
* For all private keys produced by the key generator functions
* (`br_rsa_keygen` type), this function succeeds. Note that the API
* restricts the public exponent to a maximum size of 32 bits.
*
* The encoded private exponent is written in `d` (unsigned big-endian
* convention), and the length (in bytes) is returned. If `d` is `NULL`,
* then the exponent is not written anywhere, but the length is still
* returned. On error, 0 is returned.
*
* Not all error conditions are detected when `d` is `NULL`; therefore, the
* returned value shall be checked also when actually producing the value.
*
* \param d destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the private exponent length (in bytes), or 0.
*/
typedef size_t (*br_rsa_compute_privexp)(void *d,
const br_rsa_private_key *sk, uint32_t pubexp);
/**
* \brief Recompute RSA private exponent ("i15" engine).
*
* \see br_rsa_compute_privexp
*
* \param d destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the private exponent length (in bytes), or 0.
*/
size_t br_rsa_i15_compute_privexp(void *d,
const br_rsa_private_key *sk, uint32_t pubexp);
/**
* \brief Recompute RSA private exponent ("i31" engine).
*
* \see br_rsa_compute_privexp
*
* \param d destination buffer (or `NULL`).
* \param sk RSA private key.
* \return the private exponent length (in bytes), or 0.
*/
size_t br_rsa_i31_compute_privexp(void *d,
const br_rsa_private_key *sk, uint32_t pubexp);
/**
* \brief Get "default" RSA implementation (recompute private exponent).
*
* This returns the preferred implementation of RSA (recompute private
* exponent) on the current system.
*
* \return the default implementation.
*/
br_rsa_compute_privexp br_rsa_compute_privexp_get_default(void);
#ifdef __cplusplus
}
#endif