/** 
 | 
 * \file rsa.h 
 | 
 */ 
 | 
#ifndef _RSA_H 
 | 
#define _RSA_H 
 | 
  
 | 
#ifdef __cplusplus 
 | 
extern "C" { 
 | 
#endif 
 | 
  
 | 
#include "bignum.h" 
 | 
  
 | 
#define ERR_RSA_BAD_INPUT_DATA                  0x0300 
 | 
#define ERR_RSA_INVALID_PADDING                 0x0310 
 | 
#define ERR_RSA_KEY_GEN_FAILED                  0x0320 
 | 
#define ERR_RSA_KEY_CHK_FAILED                  0x0330 
 | 
#define ERR_RSA_PUBLIC_FAILED                   0x0340 
 | 
#define ERR_RSA_PRIVATE_FAILED                  0x0350 
 | 
#define ERR_RSA_VERIFY_FAILED                   0x0360 
 | 
  
 | 
/* 
 | 
 * PKCS#1 stuff 
 | 
 */ 
 | 
#define RSA_RAW             0 
 | 
#define RSA_MD2             2 
 | 
#define RSA_MD4             3 
 | 
#define RSA_MD5             4 
 | 
#define RSA_SHA1            5 
 | 
  
 | 
#define RSA_SIGN            0x01 
 | 
#define RSA_CRYPT           0x02 
 | 
  
 | 
/* 
 | 
 * DigestInfo ::= SEQUENCE { 
 | 
 *   digestAlgorithm DigestAlgorithmIdentifier, 
 | 
 *   digest Digest } 
 | 
 * 
 | 
 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 
 | 
 * 
 | 
 * Digest ::= OCTET STRING 
 | 
 */ 
 | 
#define ASN1_HASH_MDX                       \ 
 | 
    "\x30\x20\x30\x0C\x06\x08\x2A\x86\x48"  \ 
 | 
    "\x86\xF7\x0D\x02\x00\x05\x00\x04\x10" 
 | 
  
 | 
#define ASN1_HASH_SHA1                      \ 
 | 
    "\x30\x21\x30\x09\x06\x05\x2B\x0E\x03"  \ 
 | 
    "\x02\x1A\x05\x00\x04\x14" 
 | 
  
 | 
typedef struct 
 | 
{ 
 | 
    int ver;    /*!<  should be 0       */ 
 | 
    int len;    /*!<  size(N) in chars  */ 
 | 
    mpi N;      /*!<  public modulus    */ 
 | 
    mpi E;      /*!<  public exponent   */ 
 | 
    mpi D;      /*!<  private exponent  */ 
 | 
  
 | 
    mpi P;      /*!<  1st prime factor  */ 
 | 
    mpi Q;      /*!<  2nd prime factor  */ 
 | 
    mpi DP;     /*!<  D mod (P - 1)     */ 
 | 
    mpi DQ;     /*!<  D mod (Q - 1)     */ 
 | 
    mpi QP;     /*!<  inverse of Q % P  */ 
 | 
  
 | 
    mpi RN;     /*!<  cached R^2 mod N  */ 
 | 
    mpi RP;     /*!<  cached R^2 mod P  */ 
 | 
    mpi RQ;     /*!<  cached R^2 mod Q  */ 
 | 
} 
 | 
rsa_context; 
 | 
  
 | 
/** 
 | 
 * \brief          Generate an RSA keypair 
 | 
 * 
 | 
 * \param ctx      RSA context to be initialized 
 | 
 * \param nbits    size of the public key in bits 
 | 
 * \param exponent public exponent (e.g., 65537) 
 | 
 * \param rng_f    points to the RNG function 
 | 
 * \param rng_d    points to the RNG data  
 | 
 * 
 | 
 * \return         0 if successful, or an ERR_RSA_XXX error code 
 | 
 */ 
 | 
int rsa_gen_key( rsa_context *ctx, int nbits, int exponent, 
 | 
                 int (*rng_f)(void *), void *rng_d ); 
 | 
  
 | 
/** 
 | 
 * \brief          Perform an RSA public key operation 
 | 
 * 
 | 
 * \return         0 if successful, or an ERR_RSA_XXX error code 
 | 
 * 
 | 
 * \note           This function does not take care of message 
 | 
 *                 padding: both ilen and olen must be equal to 
 | 
 *                 the modulus size (ctx->len). Also, be sure 
 | 
 *                 to set input[0] = 0. 
 | 
 */ 
 | 
int rsa_public( rsa_context   *ctx, 
 | 
                unsigned char *input,  int ilen, 
 | 
                unsigned char *output, int *olen ); 
 | 
  
 | 
/** 
 | 
 * \brief          Perform an RSA private key operation 
 | 
 * 
 | 
 * \return         0 if successful, or an ERR_RSA_XXX error code 
 | 
 * 
 | 
 * \note           This function does not take care of message 
 | 
 *                 padding: both ilen and olen must be equal to 
 | 
 *                 the modulus size (ctx->len). Also, be sure 
 | 
 *                 to set input[0] = 0. 
 | 
 */ 
 | 
int rsa_private( rsa_context   *ctx, 
 | 
                 unsigned char *input,  int ilen, 
 | 
                 unsigned char *output, int *olen ); 
 | 
  
 | 
/** 
 | 
 * \brief          Return 0 if the public key is valid, 
 | 
 *                 or ERR_RSA_KEY_CHECK_FAILED 
 | 
 */ 
 | 
int rsa_check_pubkey( rsa_context *ctx ); 
 | 
  
 | 
/** 
 | 
 * \brief          Return 0 if the private key is valid, 
 | 
 *                 or ERR_RSA_KEY_CHECK_FAILED 
 | 
 */ 
 | 
int rsa_check_privkey( rsa_context *ctx ); 
 | 
  
 | 
/** 
 | 
 * \brief          Add the PKCS#1 v1.5 padding and do a public RSA 
 | 
 * 
 | 
 * \param ctx      RSA context 
 | 
 * \param input    buffer holding the data to be encrypted 
 | 
 * \param ilen     length of the plaintext; cannot be longer 
 | 
 *                 than the modulus, minus 3+8 for padding 
 | 
 * \param output   buffer that will hold the ciphertext 
 | 
 * \param olen     must be the same as the modulus size 
 | 
 *                 (for example, 128 if RSA-1024 is used) 
 | 
 * 
 | 
 * \return         0 if successful, or an ERR_RSA_XXX error code 
 | 
 */ 
 | 
int rsa_pkcs1_encrypt( rsa_context   *ctx, 
 | 
                       unsigned char *input,  int ilen, 
 | 
                       unsigned char *output, int *olen ); 
 | 
  
 | 
/** 
 | 
 * \brief          Do a private RSA, removes the PKCS#1 v1.5 padding 
 | 
 * 
 | 
 * \param ctx      RSA context 
 | 
 * \param input    buffer holding the encrypted data 
 | 
 * \param ilen     must be the same as the modulus size 
 | 
 * \param output   buffer that will hold the plaintext 
 | 
 * \param olen     size of output buffer, will be updated 
 | 
 *                 to contain the length of the plaintext 
 | 
 * 
 | 
 * \return         0 if successful, or an ERR_RSA_XXX error code 
 | 
 */ 
 | 
int rsa_pkcs1_decrypt( rsa_context   *ctx, 
 | 
                       unsigned char *input,  int  ilen, 
 | 
                       unsigned char *output, int *olen ); 
 | 
  
 | 
/** 
 | 
 * \brief          Perform a private RSA to sign a message digest 
 | 
 * 
 | 
 * \param ctx      RSA context 
 | 
 * \param alg_id   RSA_RAW, RSA_MD2/4/5 or RSA_SHA1 
 | 
 * \param hash     buffer holding the message digest 
 | 
 * \param hashlen  message digest length 
 | 
 * \param sig      buffer that will hold the ciphertext 
 | 
 * \param siglen   must be the same as the modulus size 
 | 
 *                 (for example, 128 if RSA-1024 is used) 
 | 
 * 
 | 
 * \return         0 if the signing operation was successful, 
 | 
 *                 or an ERR_RSA_XXX error code 
 | 
 */ 
 | 
int rsa_pkcs1_sign( rsa_context   *ctx,  int alg_id, 
 | 
                    unsigned char *hash, int hashlen, 
 | 
                    unsigned char *sig,  int siglen ); 
 | 
  
 | 
/** 
 | 
 * \brief          Perform a public RSA and check the message digest 
 | 
 * 
 | 
 * \param ctx      points to an RSA public key 
 | 
 * \param alg_id   RSA_RAW, RSA_MD2/4/5 or RSA_SHA1 
 | 
 * \param hash     buffer holding the message digest 
 | 
 * \param hashlen  message digest length 
 | 
 * \param sig      buffer holding the ciphertext 
 | 
 * \param siglen   must be the same as the modulus size 
 | 
 * 
 | 
 * \return         0 if the verify operation was successful, 
 | 
 *                 or an ERR_RSA_XXX error code 
 | 
 */ 
 | 
int rsa_pkcs1_verify( rsa_context   *ctx,  int alg_id, 
 | 
                      unsigned char *hash, int hashlen, 
 | 
                      unsigned char *sig,  int siglen ); 
 | 
  
 | 
/** 
 | 
 * \brief          Free the components of an RSA key 
 | 
 */ 
 | 
void rsa_free( rsa_context *ctx ); 
 | 
  
 | 
/** 
 | 
 * \brief          Checkup routine 
 | 
 * 
 | 
 * \return         0 if successful, or 1 if the test failed 
 | 
 */ 
 | 
int rsa_self_test( void ); 
 | 
  
 | 
#ifdef __cplusplus 
 | 
} 
 | 
#endif 
 | 
  
 | 
#endif 
 |