rsa.c File Reference

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include "crypto.h"

Go to the source code of this file.

Functions

void RSA_priv_key_new (RSA_CTX **ctx, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len, const uint8_t *priv_exp, int priv_len)
 Implements the RSA public encryption algorithm.
void RSA_pub_key_new (RSA_CTX **ctx, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
void RSA_free (RSA_CTX *rsa_ctx)
 Free up any RSA context resources.
int RSA_decrypt (const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data, int is_decryption)
 Use PKCS1.5 for decryption/verification.
bigintRSA_private (const RSA_CTX *c, bigint *bi_msg)
 Performs m = c^d mod n.
bigintRSA_public (const RSA_CTX *c, bigint *bi_msg)
 Performs c = m^e mod n.
int RSA_encrypt (const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, uint8_t *out_data, int is_signing)
 Use PKCS1.5 for encryption/signing.


Function Documentation

void RSA_priv_key_new ( RSA_CTX **  ctx,
const uint8_t modulus,
int  mod_len,
const uint8_t pub_exp,
int  pub_len,
const uint8_t priv_exp,
int  priv_len 
)

Implements the RSA public encryption algorithm.

Uses the bigint library to perform its calculations.

Definition at line 34 of file rsa.c.

References RSA_CTX::bi_ctx, bi_import(), bi_permanent(), bi_set_mod(), RSA_CTX::d, and RSA_pub_key_new().

00046 {
00047     RSA_CTX *rsa_ctx;
00048     BI_CTX *bi_ctx;
00049     RSA_pub_key_new(ctx, modulus, mod_len, pub_exp, pub_len);
00050     rsa_ctx = *ctx;
00051     bi_ctx = rsa_ctx->bi_ctx;
00052     rsa_ctx->d = bi_import(bi_ctx, priv_exp, priv_len);
00053     bi_permanent(rsa_ctx->d);
00054 
00055 #ifdef CONFIG_BIGINT_CRT
00056     rsa_ctx->p = bi_import(bi_ctx, p, p_len);
00057     rsa_ctx->q = bi_import(bi_ctx, q, q_len);
00058     rsa_ctx->dP = bi_import(bi_ctx, dP, dP_len);
00059     rsa_ctx->dQ = bi_import(bi_ctx, dQ, dQ_len);
00060     rsa_ctx->qInv = bi_import(bi_ctx, qInv, qInv_len);
00061     bi_permanent(rsa_ctx->dP);
00062     bi_permanent(rsa_ctx->dQ);
00063     bi_permanent(rsa_ctx->qInv);
00064     bi_set_mod(bi_ctx, rsa_ctx->p, BIGINT_P_OFFSET);
00065     bi_set_mod(bi_ctx, rsa_ctx->q, BIGINT_Q_OFFSET);
00066 #endif
00067 }

void RSA_pub_key_new ( RSA_CTX **  ctx,
const uint8_t modulus,
int  mod_len,
const uint8_t pub_exp,
int  pub_len 
)

Definition at line 69 of file rsa.c.

References RSA_CTX::bi_ctx, bi_import(), bi_initialize(), bi_permanent(), bi_set_mod(), BIGINT_M_OFFSET, calloc(), RSA_CTX::e, RSA_CTX::m, and RSA_CTX::num_octets.

Referenced by RSA_priv_key_new(), and tls_send_client_key_exchange().

00072 {
00073     RSA_CTX *rsa_ctx;
00074     BI_CTX *bi_ctx = bi_initialize();
00075     *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
00076     rsa_ctx = *ctx;
00077     rsa_ctx->bi_ctx = bi_ctx;
00078     rsa_ctx->num_octets = (mod_len & 0xFFF0);
00079     rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
00080     bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
00081     rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
00082     bi_permanent(rsa_ctx->e);
00083 }

void RSA_free ( RSA_CTX rsa_ctx  ) 

Free up any RSA context resources.

Definition at line 88 of file rsa.c.

References RSA_CTX::bi_ctx, bi_depermanent(), bi_free(), bi_free_mod(), bi_terminate(), BIGINT_M_OFFSET, RSA_CTX::d, RSA_CTX::e, free(), and NULL.

Referenced by tls_send_client_key_exchange().

00089 {
00090     BI_CTX *bi_ctx;
00091     if (rsa_ctx == NULL)                /* deal with ptrs that are null */
00092         return;
00093 
00094     bi_ctx = rsa_ctx->bi_ctx;
00095 
00096     bi_depermanent(rsa_ctx->e);
00097     bi_free(bi_ctx, rsa_ctx->e);
00098     bi_free_mod(rsa_ctx->bi_ctx, BIGINT_M_OFFSET);
00099 
00100     if (rsa_ctx->d)
00101     {
00102         bi_depermanent(rsa_ctx->d);
00103         bi_free(bi_ctx, rsa_ctx->d);
00104 #ifdef CONFIG_BIGINT_CRT
00105         bi_depermanent(rsa_ctx->dP);
00106         bi_depermanent(rsa_ctx->dQ);
00107         bi_depermanent(rsa_ctx->qInv);
00108         bi_free(bi_ctx, rsa_ctx->dP);
00109         bi_free(bi_ctx, rsa_ctx->dQ);
00110         bi_free(bi_ctx, rsa_ctx->qInv);
00111         bi_free_mod(rsa_ctx->bi_ctx, BIGINT_P_OFFSET);
00112         bi_free_mod(rsa_ctx->bi_ctx, BIGINT_Q_OFFSET);
00113 #endif
00114     }
00115 
00116     bi_terminate(bi_ctx);
00117     free(rsa_ctx);
00118 }

int RSA_decrypt ( const RSA_CTX ctx,
const uint8_t in_data,
uint8_t out_data,
int  is_decryption 
)

Use PKCS1.5 for decryption/verification.

Parameters:
ctx [in] The context
in_data [in] The data to encrypt (must be < modulus size-11)
out_data [out] The encrypted data.
is_decryption [in] Decryption or verify operation.
Returns:
The number of bytes that were originally encrypted. -1 on error.
See also:
http://www.rsasecurity.com/rsalabs/node.asp?id=2125

Definition at line 129 of file rsa.c.

References RSA_CTX::bi_ctx, bi_export(), bi_import(), free(), malloc(), memcpy, memset(), RSA_CTX::num_octets, RSA_private(), RSA_public(), and size.

00131 {
00132     int byte_size = ctx->num_octets;
00133     uint8_t *block;
00134     int i, size;
00135     bigint *decrypted_bi, *dat_bi;
00136 
00137     memset(out_data, 0, byte_size); /* initialise */
00138 
00139     /* decrypt */
00140     dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size);
00141 #ifdef CONFIG_SSL_CERT_VERIFICATION
00142     decrypted_bi = is_decryption ?  /* decrypt or verify? */
00143             RSA_private(ctx, dat_bi) : RSA_public(ctx, dat_bi);
00144 #else   /* always a decryption */
00145     decrypted_bi = RSA_private(ctx, dat_bi);
00146 #endif
00147 
00148     /* convert to a normal block */
00149     block = (uint8_t *)malloc(byte_size);
00150     bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);
00151 
00152     i = 10; /* start at the first possible non-padded byte */
00153 
00154 #ifdef CONFIG_SSL_CERT_VERIFICATION
00155     if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
00156     {
00157         while (block[i++] == 0xff && i < byte_size);
00158 
00159         if (block[i-2] != 0xff)
00160             i = byte_size;     /*ensure size is 0 */   
00161     }
00162     else                    /* PKCS1.5 encryption padding is random */
00163 #endif
00164     {
00165         while (block[i++] && i < byte_size);
00166     }
00167     size = byte_size - i;
00168 
00169     /* get only the bit we want */
00170     if (size > 0)
00171         memcpy(out_data, &block[i], size);
00172     
00173     free(block);
00174     return size ? size : -1;
00175 }

bigint* RSA_private ( const RSA_CTX c,
bigint bi_msg 
)

Performs m = c^d mod n.

Definition at line 180 of file rsa.c.

References RSA_CTX::bi_ctx, bi_mod_power(), BIGINT_M_OFFSET, RSA_CTX::d, and BI_CTX::mod_offset.

Referenced by RSA_decrypt(), and RSA_encrypt().

00181 {
00182 #ifdef CONFIG_BIGINT_CRT
00183     return bi_crt(c, bi_msg);
00184 #else
00185     BI_CTX *ctx = c->bi_ctx;
00186     ctx->mod_offset = BIGINT_M_OFFSET;
00187     return bi_mod_power(ctx, bi_msg, c->d);
00188 #endif
00189 }

bigint* RSA_public ( const RSA_CTX c,
bigint bi_msg 
)

Performs c = m^e mod n.

Definition at line 245 of file rsa.c.

References RSA_CTX::bi_ctx, bi_mod_power(), BIGINT_M_OFFSET, RSA_CTX::e, and BI_CTX::mod_offset.

Referenced by RSA_decrypt(), and RSA_encrypt().

00246 {
00247     c->bi_ctx->mod_offset = BIGINT_M_OFFSET;
00248     return bi_mod_power(c->bi_ctx, bi_msg, c->e);
00249 }

int RSA_encrypt ( const RSA_CTX ctx,
const uint8_t in_data,
uint16_t  in_len,
uint8_t out_data,
int  is_signing 
)

Use PKCS1.5 for encryption/signing.

see http://www.rsasecurity.com/rsalabs/node.asp?id=2125

Definition at line 255 of file rsa.c.

References RSA_CTX::bi_ctx, bi_export(), bi_import(), get_random_NZ(), memcpy, memset(), RSA_CTX::num_octets, RSA_private(), and RSA_public().

Referenced by tls_send_client_key_exchange().

00257 {
00258     int byte_size = ctx->num_octets;
00259     int num_pads_needed = byte_size-in_len-3;
00260     bigint *dat_bi, *encrypt_bi;
00261 
00262     /* note: in_len+11 must be > byte_size */
00263     out_data[0] = 0;     /* ensure encryption block is < modulus */
00264 
00265     if (is_signing)
00266     {
00267         out_data[1] = 1;        /* PKCS1.5 signing pads with "0xff"'s */
00268         memset(&out_data[2], 0xff, num_pads_needed);
00269     }
00270     else /* randomize the encryption padding with non-zero bytes */   
00271     {
00272         out_data[1] = 2;
00273         get_random_NZ(num_pads_needed, &out_data[2]);
00274     }
00275 
00276     out_data[2+num_pads_needed] = 0;
00277     memcpy(&out_data[3+num_pads_needed], in_data, in_len);
00278 
00279     /* now encrypt it */
00280     dat_bi = bi_import(ctx->bi_ctx, out_data, byte_size);
00281     encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) : 
00282         RSA_public(ctx, dat_bi);
00283     bi_export(ctx->bi_ctx, encrypt_bi, out_data, byte_size);
00284     return byte_size;
00285 }


Generated on Tue Apr 6 20:01:15 2010 for gPXE by  doxygen 1.5.7.1