#include <string.h>
#include "rsa2048.h"
#include "bignum.h"
#include "keys.h"
#define PADDING_SIZE 11
#define KEY_M_BITS 2048
static unsigned char pkcs_block[RSA_MAX_MODULUS_LEN] = {0};
static int status;
static rsa_pk_t pk = {0};
static rsa_sk_t sk = {0};
static void rsa_load_key(rsa_pk_t *public_key, rsa_sk_t *private_key)
{
// copy keys.h message about public key and private key to the flash RAM
public_key->bits = KEY_M_BITS;
memcpy(&public_key->modulus [RSA_MAX_MODULUS_LEN-sizeof(key_m) ], key_m, sizeof(key_m ));
memcpy(&public_key->exponent [RSA_MAX_MODULUS_LEN-sizeof(key_e) ], key_e, sizeof(key_e ));
private_key->bits = KEY_M_BITS;
memcpy(&private_key->modulus [RSA_MAX_MODULUS_LEN-sizeof(key_m) ], key_m, sizeof(key_m ));
memcpy(&private_key->public_exponet [RSA_MAX_MODULUS_LEN-sizeof(key_e) ], key_e, sizeof(key_e ));
memcpy(&private_key->exponent [RSA_MAX_MODULUS_LEN-sizeof(key_ex)], key_ex, sizeof(key_ex));
memcpy(&private_key->prime1 [RSA_MAX_PRIME_LEN - sizeof(key_p1)], key_p1, sizeof(key_p1));
memcpy(&private_key->prime2 [RSA_MAX_PRIME_LEN - sizeof(key_p2)], key_p2, sizeof(key_p2));
memcpy(&private_key->prime_exponent1[RSA_MAX_PRIME_LEN - sizeof(key_e1)], key_e1, sizeof(key_e1));
memcpy(&private_key->prime_exponent2[RSA_MAX_PRIME_LEN - sizeof(key_e2)], key_e2, sizeof(key_e2));
memcpy(&private_key->coefficient [RSA_MAX_PRIME_LEN - sizeof(key_c) ], key_c, sizeof(key_c ));
}
static void generate_rand(unsigned char *block, unsigned int block_len)
{
unsigned int i;
for (i = 0; i < block_len; i++)
{
block[i] = i;
}
}
static int public_block_operation(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_pk_t *pk)
{
unsigned int edigits = 0, ndigits = 0;
static unsigned int c[BN_MAX_DIGITS] = {0}, e[BN_MAX_DIGITS] = {0};
static unsigned int m[BN_MAX_DIGITS] = {0}, n[BN_MAX_DIGITS] = {0};
bn_decode(m, BN_MAX_DIGITS, in, in_len);
bn_decode(n, BN_MAX_DIGITS, pk->modulus, RSA_MAX_MODULUS_LEN);
bn_decode(e, BN_MAX_DIGITS, pk->exponent, RSA_MAX_MODULUS_LEN);
ndigits = bn_digits(n, BN_MAX_DIGITS);
edigits = bn_digits(e, BN_MAX_DIGITS);
if (bn_cmp(m, n, ndigits) >= 0)
{
return ERR_WRONG_DATA;
}
bn_mod_exp(c, m, e, edigits, n, ndigits);
*out_len = (pk->bits) >> 3;
bn_encode(out, *out_len, c, ndigits);
// Clear potentially sensitive information
memset((unsigned char *)c, 0, sizeof(c));
memset((unsigned char *)m, 0, sizeof(m));
return 0;
}
static int private_block_operation(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_sk_t *sk)
{
unsigned int cdigits = 0, ndigits = 0, pdigits = 0;
static unsigned int c[BN_MAX_DIGITS] = {0}, cp[BN_MAX_DIGITS] = {0}, cq[BN_MAX_DIGITS] = {0};
static unsigned int dp[BN_MAX_DIGITS] = {0}, dq[BN_MAX_DIGITS] = {0};
static unsigned int mp[BN_MAX_DIGITS] = {0}, mq[BN_MAX_DIGITS] = {0};
static unsigned int n[BN_MAX_DIGITS] = {0}, t[BN_MAX_DIGITS] = {0};
static unsigned int p[BN_MAX_DIGITS] = {0}, q[BN_MAX_DIGITS] = {0}, q_inv[BN_MAX_DIGITS] = {0};
bn_decode(c, BN_MAX_DIGITS, in, in_len);
bn_decode(n, BN_MAX_DIGITS, sk->modulus, RSA_MAX_MODULUS_LEN);
bn_decode(p, BN_MAX_DIGITS, sk->prime1, RSA_MAX_PRIME_LEN);
bn_decode(q, BN_MAX_DIGITS, sk->prime2, RSA_MAX_PRIME_LEN);
bn_decode(dp, BN_MAX_DIGITS, sk->prime_exponent1, RSA_MAX_PRIME_LEN);
bn_decode(dq, BN_MAX_DIGITS, sk->prime_exponent2, RSA_MAX_PRIME_LEN);
bn_decode(q_inv, BN_MAX_DIGITS, sk->coefficient, RSA_MAX_PRIME_LEN);
cdigits = bn_digits(c, BN_MAX_DIGITS);
ndigits = bn_digits(n, BN_MAX_DIGITS);
pdigits = bn_digits(p, BN_MAX_DIGITS);
if (bn_cmp(c, n, ndigits) >= 0)
return ERR_WRONG_DATA;
bn_mod(cp, c, cdigits, p, pdigits);
bn_mod(cq, c, cdigits, q, pdigits);
bn_mod_exp(mp, cp, dp, pdigits, p, pdigits);
bn_assign_zero(mq, ndigits);
bn_mod_exp(mq, cq, dq, pdigits, q, pdigits);
if (bn_cmp(mp, mq, pdigits) >= 0)
{
bn_sub(t, mp, mq, pdigits);
}
else
{
bn_sub(t, mq, mp, pdigits);
bn_sub(t, p, t, pdigits);
}
bn_mod_mul(t, t, q_inv, p, pdigits);
bn_mul(t, t, q, pdigits);
bn_add(t, t, mq, ndigits);
*out_len = (sk->bits) >> 3;
bn_encode(out, *out_len, t, ndigits);
// Clear potentially sensitive information
memset((unsigned char *)c, 0, sizeof(c));
memset((unsigned char *)cp, 0, sizeof(cp));
memset((unsigned char *)cq, 0, sizeof(cq));
memset((unsigned char *)dp, 0, sizeof(dp));
memset((unsigned char *)dq, 0, sizeof(dq));
memset((unsigned char *)mp, 0, sizeof(mp));
memset((unsigned char *)mq, 0, sizeof(mq));
memset((unsigned char *)p, 0, sizeof(p));
memset((unsigned char *)q, 0, sizeof(q));
memset((unsigned char *)q_inv, 0, sizeof(q_inv));
memset((unsigned char *)t, 0, sizeof(t));
return 0;
}
int rsa_public_encrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_pk_t *pk)
{
unsigned char byte;
unsigned int i, modulus_len;
modulus_len = (pk->bits) >> 3;
if (in_len + PADDING_SIZE > modulus_len)
{
return ERR_WRONG_LEN;
}
pkcs_block[0] = 0;
pkcs_block[1] = 2;
for (i = 2; i < modulus_len - in_len - 1; i++)
{
do
{
generate_rand(&byte, 1);
} while (byte == 0);
pkcs_block[i] = byte;
}
pkcs_block[i++] = 0;
memcpy((unsigned char *)&pkcs_block[i], (unsigned char *)in, in_len);
status = public_block_operation(out, out_len, pkcs_block, modulus_len, pk);
// Clear potentially sensitive information
byte = 0;
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));
return status;
}
int rsa_public_decrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_pk_t *pk)
{
unsigned int i, modulus_len, pkcs_block_len;
modulus_len = (pk->bits) >> 3;
if (in_len > modulus_len)
return ERR_WRONG_LEN;
status = public_block_operation(pkcs_block, &pkcs_block_len, in, in_len, pk);
if (status != 0)
return status;
if (pkcs_block_len != modulus_len)
return ERR_WRONG_LEN;
if ((pkcs_block[0] != 0) || (pkcs_block[1] != 1))
return ERR_WRONG_DATA;
for (i = 2; i < modulus_len - 1; i++)
{
if (pkcs_block[i] != 0xFF)
break;
}
if (pkcs_block[i++] != 0)
return ERR_WRONG_DATA;
*out_len = modulus_len - i;
if (*out_len + PADDING_SIZE > modulus_len)
return ERR_WRONG_DATA;
memcpy((unsigned char *)out, (unsigned char *)&pkcs_block[i], *out_len);
// Clear potentially sensitive information
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));
return status;
}
int rsa_private_encrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_sk_t *sk)
{
static unsigned char pkcs_block[RSA_MAX_MODULUS_LEN];
unsigned int i, modulus_len;
// Clear potentially sensitive information
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));
modulus_len = (sk->bits) >> 3;
if (in_len + PADDING_SIZE > modulus_len)
return ERR_WRONG_LEN;
pkcs_block[0] = 0;
pkcs_block[1] = 1;
for (i = 2; i < modulus_len - in_len - 1; i++)
{
pkcs_block[i] = 0xFF;
}
pkcs_block[i++] = 0;
memcpy((unsigned char *)&pkcs_block[i], (unsigned char *)in, in_len);
status = private_block_operation(out, out_len, pkcs_block, modulus_len, sk);
return status;
}
int rsa_private_decrypt(unsigned char *out, unsigned int *out_len,
unsigned char *in, unsigned int in_len, rsa_sk_t *sk)
{
unsigned int i, modulus_len = 0, pkcs_block_len = 0;
modulus_len = (sk->bits) >> 3;
if (in_len > modulus_len)
return ERR_WRONG_LEN;
status = private_block_operation(pkcs_block, &pkcs_block_len, in, in_len, sk);
if (status != 0)
return status;
if (pkcs_block_len != modulus_len)
return ERR_WRONG_LEN;
if ((pkcs_block[0] != 0) || (pkcs_block[1] != 2))
return ERR_WRONG_DATA;
for (i = 2; i < modulus_len - 1; i++)
{
if (pkcs_block[i] == 0)
break;
}
i++;
if (i >= modulus_len)
return ERR_WRONG_DATA;
*out_len = modulus_len - i;
if (*out_len + PADDING_SIZE > modulus_len)
return ERR_WRONG_DATA;
memcpy((unsigned char *)out, (unsigned char *)&pkcs_block[i], *out_len);
// Clear potentially sensitive information
memset((unsigned char *)pkcs_block, 0, sizeof(pkcs_block));
return status;
}
int rsa_decrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len)
{
rsa_load_key(&pk, &sk);
status = rsa_public_decrypt(out, out_len, in, in_len, &pk);
return status;
}
int rsa_encrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len)
{
rsa_load_key(&pk, &sk);
status = rsa_private_encrypt(out, out_len, in, in_len, &sk);
return status;
}
#ifndef __RSA_2048_H__
#define __RSA_2048_H__
// RSA key lengths
#define RSA_MAX_MODULUS_BITS 2048
#define RSA_MAX_MODULUS_LEN ((RSA_MAX_MODULUS_BITS) >> 3)
#define RSA_MAX_PRIME_BITS ((RSA_MAX_MODULUS_BITS) >> 1)
#define RSA_MAX_PRIME_LEN ((RSA_MAX_PRIME_BITS) >> 3)
// Error codes
#define ERR_WRONG_DATA 0x1001
#define ERR_WRONG_LEN 0x1002
typedef struct
{
unsigned int bits;
unsigned char modulus[RSA_MAX_MODULUS_LEN];
unsigned char exponent[RSA_MAX_MODULUS_LEN];
} rsa_pk_t;
typedef struct
{
unsigned int bits;
unsigned char modulus[RSA_MAX_MODULUS_LEN];
unsigned char public_exponet[RSA_MAX_MODULUS_LEN];
unsigned char exponent[RSA_MAX_MODULUS_LEN];
unsigned char prime1[RSA_MAX_PRIME_LEN];
unsigned char prime2[RSA_MAX_PRIME_LEN];
unsigned char prime_exponent1[RSA_MAX_PRIME_LEN];
unsigned char prime_exponent2[RSA_MAX_PRIME_LEN];
unsigned char coefficient[RSA_MAX_PRIME_LEN];
} rsa_sk_t;
int rsa_decrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len);
int rsa_encrypt(unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len);
#endif
#ifndef __KEY_RAS_H__
#define __KEY_RAS_H__
const static unsigned char key_m[] = {
0x82, 0x2A, 0xB8, 0xBD, 0x20, 0x9D, 0x30, 0x1F, 0xD9, 0x9A, 0x69, 0x75, 0xC4, 0xA9, 0x4D, 0x1B,
0x67, 0x80, 0x35, 0x85, 0x06, 0xE8, 0xF0, 0xE8, 0x88, 0xA4, 0xB8, 0xBF, 0xE7, 0xA3, 0x58, 0x80,
0x6F, 0xF9, 0x2D, 0xF7, 0x21, 0xF1, 0x7D, 0xB2, 0xDA, 0xE4, 0xE6, 0x02, 0xD2, 0x3C, 0x3B, 0xF6,
0x96, 0x30, 0xC2, 0x15, 0x35, 0x56, 0x3A, 0xC0, 0x69, 0x80, 0x47, 0xAF, 0xC3, 0x35, 0xC9, 0x61,
0x1A, 0x39, 0x3A, 0x7B, 0xBA, 0xE5, 0x47, 0x70, 0xB8, 0x15, 0x9E, 0xF3, 0xFF, 0x8F, 0xAB, 0x59,
0x34, 0xC1, 0x16, 0x0D, 0x1F, 0x66, 0x8D, 0x9C, 0xE6, 0x5F, 0x4A, 0x93, 0x93, 0x66, 0xDF, 0x64,
0x79, 0x72, 0xFB, 0x24, 0x47, 0x82, 0xE3, 0x83, 0xCB, 0x0D, 0xC8, 0xE8, 0x25, 0x96, 0x0C, 0x4B,
0x9C, 0xCB, 0xA0, 0x6F, 0x8C, 0x10, 0xEF, 0x0A, 0xE4, 0x76, 0x15, 0x84, 0xC2, 0xBE, 0x10, 0x37,
0x15, 0xA5, 0x88, 0x4F, 0xC3, 0x2F, 0xD6, 0x69, 0xF9, 0x6C, 0xBD, 0xEB, 0xB7, 0x87, 0x79, 0xC5,
0xB1, 0x00, 0xD8, 0x30, 0x5C, 0xAA, 0x24, 0xB8, 0x18, 0x23, 0x04, 0x1C, 0x8E, 0xFA, 0x94, 0xA2,
0x35, 0x99, 0xDE, 0x7F, 0xC7, 0xB9, 0xBC, 0x1E, 0xE5, 0x01, 0x27, 0xE7, 0x38, 0x75, 0x8B, 0x4B,
0x13, 0x13, 0x83, 0x93, 0xF3, 0x2C, 0xCB, 0xA9, 0x07, 0x45, 0xAB, 0x8D, 0x33, 0x78, 0xE2, 0xC7,
0x89, 0x53, 0x15, 0x9A, 0x40, 0x42, 0x8D, 0xBD, 0x37, 0xCC, 0x79, 0x0C, 0xBC, 0x53, 0x2A, 0x4F,
0xBA, 0xD3, 0xE1, 0xA2, 0x4F, 0x20, 0xAE, 0x2B, 0xD4, 0xF1, 0xF6, 0x94, 0xE9, 0xB9, 0xC3, 0xF7,
0x21, 0xDB, 0xC7, 0x79, 0xFD, 0xB6, 0x7E, 0xD0, 0x0C, 0xF4, 0x9E, 0x3C, 0x56, 0x15, 0x2E, 0xEF,
0x0A, 0x43, 0xDE, 0xD6, 0xD8, 0x6A, 0x4B, 0x78, 0x34, 0x34, 0xEA, 0x3C, 0xAD, 0xAF, 0xC6, 0x61};
const static unsigned char key_e[] = {
0x01, 0x00, 0x01};
const static unsigned char key_ex[] = {
0x70, 0x76, 0x56, 0xDC, 0xD9, 0x03, 0xD6, 0x63, 0x7E, 0x4F, 0xC2, 0x14, 0x45, 0x50, 0xFD, 0x54,
0xD3, 0x0C, 0xDB, 0xB0, 0xCE, 0xB2, 0x8E, 0x0A, 0x6A, 0x9C, 0xDF, 0x1E, 0xB7, 0x14, 0xD3, 0x4F,
0x4C, 0xEF, 0x5E, 0x7E, 0x6A, 0x2E, 0x4A, 0xAB, 0x30, 0x22, 0x9A, 0x74, 0x0F, 0x8E, 0x89, 0x44,
0x58, 0xA9, 0x51, 0xD6, 0x9F, 0x19, 0x9C, 0x73, 0x47, 0xF3, 0xD4, 0x7C, 0x10, 0x4E, 0x35, 0x6A,
0x97, 0x0C, 0xA0, 0xF1, 0xEC, 0x1D, 0x52, 0xA7, 0x19, 0xF5, 0x5C, 0x3B, 0x76, 0x2F, 0x7C, 0x1C,
0xFB, 0xCE, 0x63, 0xAD, 0xFC, 0xD6, 0x4F, 0x3E, 0x23, 0x70, 0x6B, 0x6F, 0xAB, 0xE8, 0x32, 0xD4,
0x8D, 0x76, 0x01, 0x74, 0x6B, 0xF0, 0xB3, 0x7F, 0xD7, 0xFD, 0x55, 0xFA, 0xF5, 0x16, 0x7A, 0x13,
0x0E, 0x2A, 0x84, 0xB8, 0x3B, 0xAD, 0x19, 0xCB, 0x30, 0x6E, 0xB1, 0xD2, 0xDD, 0xAA, 0xF7, 0x38,
0x4E, 0x68, 0x8D, 0xAC, 0xAD, 0x34, 0x8F, 0xC2, 0x62, 0xD4, 0x52, 0x4A, 0xB0, 0xAC, 0x06, 0x78,
0xF6, 0x27, 0x13, 0x97, 0xB7, 0xDE, 0xED, 0xFD, 0x2D, 0xB3, 0x62, 0xF0, 0xF6, 0xCA, 0x0C, 0xC8,
0x57, 0x8D, 0x41, 0xBA, 0x76, 0xEE, 0x51, 0x61, 0x94, 0xF2, 0x32, 0xB7, 0x4B, 0xB3, 0x03, 0xF6,
0xFD, 0x38, 0x81, 0xC2, 0x6B, 0x2F, 0x9A, 0x38, 0xB4, 0x20, 0x78, 0xD5, 0x8B, 0xEA, 0xAE, 0x52,
0x08, 0xFA, 0x92, 0xD1, 0x24, 0x84, 0x59, 0x91, 0x28, 0x37, 0x80, 0xCF, 0x73, 0x8A, 0x46, 0x18,
0xD2, 0xB8, 0x04, 0x96, 0x09, 0xE4, 0xD8, 0x54, 0xE8, 0x8C, 0xD7, 0x9A, 0x8F, 0x83, 0x2A, 0xB9,
0xA4, 0x11, 0x0F, 0xD9, 0x99, 0x83, 0x9D, 0xBF, 0x2A, 0x17, 0x0F, 0xEB, 0x87, 0xEB, 0x2A, 0xC5,
0x9C, 0x89, 0x34, 0x84, 0x24, 0xD3, 0x00, 0xAE, 0xE1, 0x4E, 0x47, 0x68, 0x1F, 0x47, 0x01, 0xD1};
const static unsigned char key_p1[] = {
0xE0, 0x5D, 0x3B, 0xE3, 0xE9, 0xF9, 0xBB, 0xD8, 0xA3, 0x5C, 0x18, 0x2E, 0x33, 0x89, 0xFF, 0x03,
0xC7, 0xFC, 0x03, 0x42, 0xE7, 0xDD, 0xDD, 0x39, 0xCE, 0xE0, 0xD5, 0x1D, 0xFF, 0x75, 0xFE, 0x12,
0xA1, 0x4A, 0xF9, 0x37, 0xDF, 0x6B, 0x80, 0xAE, 0xB5, 0x6E, 0x27, 0x50, 0x1F, 0xE5, 0x73, 0xE5,
0xD2, 0xBF, 0xC7, 0x8F, 0x93, 0x4B, 0x61, 0x67, 0xFA, 0xCF, 0x87, 0x75, 0xEB, 0xF5, 0x0C, 0x7D,
0x70, 0x74, 0xFF, 0xF5, 0xB9, 0x9D, 0x48, 0x4F, 0xE7, 0x18, 0x9A, 0x10, 0x80, 0x6F, 0x68, 0x1D,
0x02, 0x37, 0xB8, 0x51, 0xD2, 0xFA, 0xD5, 0xEF, 0x73, 0x9B, 0xF7, 0x98, 0x8F, 0x86, 0x59, 0x55,
0x5E, 0xC6, 0x96, 0x29, 0xB7, 0x3C, 0xD3, 0x4E, 0x1F, 0x8C, 0x80, 0x99, 0xDA, 0x37, 0xBB, 0x54,
0x17, 0x25, 0x2B, 0x35, 0x25, 0x62, 0xF7, 0x24, 0x4A, 0x41, 0xDD, 0xAA, 0x89, 0xE3, 0xD3, 0xB5};
const static unsigned char key_p2[] = {
0x94, 0x85, 0x4A, 0xEF, 0xF3, 0xB3, 0x17, 0x31, 0xF8, 0x24, 0xF5, 0xD7, 0x53, 0xAE, 0xE3, 0x57,
0x1F, 0x70, 0x86, 0xB7, 0xAA, 0x8F, 0x71, 0x8D, 0x8A, 0xB7, 0xA9, 0x89, 0xBD, 0x86, 0x5F, 0x13,
0x65, 0x5A, 0x81, 0x2F, 0x2E, 0xD3, 0xC2, 0x02, 0x98, 0xBE, 0xEA, 0xE6, 0x6E, 0x4E, 0x00, 0xC5,
0x91, 0x90, 0xA6, 0xF9, 0xE0, 0x70, 0x54, 0xA7, 0xBF, 0xC5, 0xF5, 0x0B, 0x41, 0x18, 0x0D, 0x5F,
0x25, 0x6B, 0x81, 0xA6, 0x35, 0xF9, 0x0A, 0xF8, 0x94, 0xA3, 0x7F, 0xF9, 0x53, 0x45, 0x0A, 0x99,
0x5D, 0x7D, 0xE9, 0xE4, 0x47, 0x4F, 0x55, 0x85, 0xA4, 0x23, 0x02, 0xB3, 0x46, 0xDB, 0x2D, 0x31,
0xF2, 0x45, 0x6B, 0x7F, 0x5E, 0xC9, 0xF7, 0xF4, 0xD1, 0xAF, 0xC6, 0x90, 0x67, 0x92, 0x30, 0x91,
0x23, 0x2F, 0x55, 0xAE, 0x53, 0x47, 0x8A, 0x6D, 0x9C, 0xAD, 0x94, 0x26, 0x12, 0x9A, 0x2B, 0x7D};
const static unsigned char key_e1[] = {
0xB5, 0x29, 0xD3, 0x50, 0x26, 0xFF, 0x25, 0xB4, 0xB9, 0xC3, 0x85, 0x2A, 0xD9, 0x26, 0xD6, 0x29,
0x81, 0x73, 0x76, 0x56, 0xB1, 0xCE, 0xAD, 0xF1, 0x1D, 0xA0, 0xE1, 0xB4, 0xC5, 0x2F, 0xCB, 0x25,
0xD3, 0xE3, 0x2B, 0xF4, 0xF7, 0x8C, 0x60, 0x6D, 0xB1, 0xC5, 0xEE, 0x2C, 0x7E, 0x74, 0xD1, 0xEE,
0x83, 0x0B, 0xA3, 0xE1, 0xC4, 0xB7, 0x9B, 0x41, 0x50, 0x7D, 0xFE, 0x0D, 0x33, 0xA7, 0xBC, 0x9C,
0x15, 0x10, 0x04, 0x15, 0xAF, 0xF8, 0xD6, 0x08, 0xDE, 0xBB, 0x38, 0xBB, 0x96, 0x59, 0x5E, 0xA1,
0xFD, 0xC6, 0x6C, 0x28, 0x75, 0xC9, 0x60, 0xB1, 0x66, 0x92, 0x4B, 0x8C, 0x7E, 0x67, 0xA6, 0xFE,
0x8D, 0xF6, 0xA0, 0x0D, 0xB3, 0x0D, 0x84, 0x39, 0x92, 0xB3, 0xEA, 0xAB, 0x50, 0x4E, 0xAC, 0x0E,
0x2C, 0x5A, 0x30, 0xD7, 0x4B, 0x06, 0xEC, 0x33, 0xFB, 0x59, 0xCF, 0xD9, 0x02, 0x5A, 0x59, 0xF9};
const static unsigned char key_e2[] = {
0x01, 0x41, 0xFB, 0xB7, 0x7A, 0x7D, 0xDA, 0xC5, 0x6E, 0x8F, 0x89, 0x91, 0x70, 0x40, 0xFB, 0xE5,
0xE1, 0xFB, 0x46, 0xF8, 0xC9, 0x35, 0xFB, 0xC5, 0x32, 0x16, 0x8A, 0x16, 0x03, 0x87, 0xDE, 0xC8,
0x40, 0x44, 0x7A, 0xF1, 0x96, 0x58, 0xEE, 0xBC, 0xAC, 0xE4, 0x79, 0x02, 0xC8, 0x8E, 0x5A, 0x8D,
0x51, 0xC5, 0x42, 0xD4, 0xBC, 0xE4, 0xD6, 0xA2, 0xB1, 0x0A, 0x11, 0x20, 0x2E, 0x45, 0xF0, 0xDF,
0x0C, 0x67, 0x13, 0xAA, 0xFF, 0xAC, 0x03, 0x3E, 0xC5, 0xAB, 0x78, 0xCA, 0xF8, 0xBC, 0x8D, 0xF1,
0x6C, 0x8C, 0x43, 0x6D, 0xCE, 0x78, 0xCA, 0x85, 0x9E, 0x35, 0x39, 0xB1, 0xA0, 0xF8, 0xFC, 0x31,
0xFF, 0x16, 0x3D, 0x69, 0xCF, 0xB8, 0xB0, 0x23, 0xDF, 0x9E, 0xB8, 0x74, 0xC2, 0x9B, 0xC7, 0x53,
0x83, 0x53, 0xC4, 0x4A, 0xFC, 0xA3, 0x8F, 0x75, 0x8C, 0x2D, 0x20, 0x23, 0x0E, 0x67, 0x45, 0xD5};
const static unsigned char key_c[] = {
0x45, 0x10, 0xB7, 0x07, 0x38, 0x22, 0x5C, 0xC8, 0xC1, 0x53, 0x23, 0x9A, 0x8A, 0xA9, 0x29, 0x8F,
0x68, 0xB5, 0x76, 0xBF, 0x86, 0x2C, 0x02, 0xA9, 0xEF, 0x6F, 0xF5, 0x61, 0x2D, 0xE2, 0x16, 0x31,
0x66, 0x41, 0xC9, 0xD8, 0x14, 0x19, 0xA0, 0x5B, 0xC0, 0x57, 0x7F, 0x22, 0x16, 0xA0, 0x29, 0x8C,
0x3C, 0x1F, 0xB9, 0x31, 0x1B, 0xDA, 0xFD, 0x5F, 0xF8, 0x22, 0x87, 0xF1, 0x9E, 0x8D, 0xAE, 0x3D,
0xC7, 0x99, 0x9F, 0xD4, 0x39, 0x58, 0x40, 0x33, 0xFC, 0x6A, 0x50, 0xF1, 0xA1, 0x69, 0xF4, 0x02,
0x2C, 0x7D, 0x5E, 0xDA, 0xA8, 0x37, 0x29, 0x91, 0x72, 0x72, 0x10, 0x7D, 0xA5, 0xFB, 0xF3, 0x2D,
0x00, 0xBF, 0xDD, 0x76, 0x6C, 0xD2, 0x1B, 0x8D, 0x75, 0x4A, 0x57, 0x8E, 0x13, 0x51, 0xB1, 0xFD,
0xDD, 0xFA, 0xE5, 0xF2, 0xF5, 0xA4, 0xDD, 0x53, 0xD6, 0x2B, 0xD3, 0x3F, 0xB5, 0xBD, 0xA4, 0x48};
#endif
/*****************************************************************************
* @file bignum.c
* @author jianqiang.xue
* @version v1.0.0
* **************************************************************************/
#include <string.h>
#include "bignum.h"
#define BN_MAX_DIGIT 0xFFFFFFFF
#define BN_DIGIT_BITS 32 // For unsigned int
#define DIGIT_2MSB(x) (unsigned int)(((x) >> (BN_DIGIT_BITS - 2)) & 0x03)
#define BN_ASSIGN_DIGIT(a, b, digits) \
{ \
bn_assign_zero(a, digits); \
a[0] = b; \
}
static unsigned int bn_sub_digit_mul(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int *d, unsigned int digits)
{
static unsigned long long result;
unsigned int borrow, rh, rl;
unsigned int i;
result = 0;
if (c == 0)
return 0;
borrow = 0;
for (i = 0; i < digits; i++)
{
result = (unsigned long long)c * d[i];
rl = result & BN_MAX_DIGIT;
rh = (result >> BN_DIGIT_BITS) & BN_MAX_DIGIT;
if ((a[i] = b[i] - borrow) > (BN_MAX_DIGIT - borrow))
{
borrow = 1;
}
else
{
borrow = 0;
}
if ((a[i] -= rl) > (BN_MAX_DIGIT - rl))
{
borrow++;
}
borrow += rh;
}
return borrow;
}
static unsigned int bn_digit_bits(unsigned int a)
{
unsigned int i;
for (i = 0; i < BN_DIGIT_BITS; i++)
{
if (a == 0)
break;
a >>= 1;
}
return i;
}
static unsigned int bn_add_digit_mul(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int *d, unsigned int digits)
{
static unsigned long long result;
unsigned int carry, rh, rl;
unsigned int i;
result = 0;
if (c == 0)
return 0;
carry = 0;
for (i = 0; i < digits; i++)
{
result = (unsigned long long)c * d[i];
rl = result & BN_MAX_DIGIT;
rh = (result >> BN_DIGIT_BITS) & BN_MAX_DIGIT;
if ((a[i] = b[i] + carry) < carry)
{
carry = 1;
}
else
{
carry = 0;
}
if ((a[i] += rl) < rl)
{
carry ++;
}
carry += rh;
}
return carry;
}
void bn_decode(unsigned int *bn, unsigned int digits, unsigned char *hexarr,
unsigned int size)
{
unsigned int t;
int j;
unsigned int i, u;
for (i = 0, j = size - 1; i < digits && j >= 0; i++)
{
t = 0;
for (u = 0; j >= 0 && u < BN_DIGIT_BITS; j--, u += 8)
{
t |= ((unsigned int)hexarr[j]) << u;
}
bn[i] = t;
}
for (; i < digits; i++)
{
bn[i] = 0;
}
}
void bn_encode(unsigned char *hexarr, unsigned int size, unsigned int *bn,
unsigned int digits)
{
unsigned int t;
int j;
unsigned int i, u;
for (i = 0, j = size - 1; i < digits && j >= 0; i++)
{
t = bn[i];
for (u = 0; j >= 0 && u < BN_DIGIT_BITS; j--, u += 8)
{
hexarr[j] = (unsigned char)(t >> u);
}
}
for (; j >= 0; j--)
{
hexarr[j] = 0;
}
}
// a = b
static void bn_assign(unsigned int *a, unsigned int *b, unsigned int digits)
{
unsigned int i;
for (i = 0; i < digits; i++)
{
a[i] = b[i];
}
}
// a = 0
void bn_assign_zero(unsigned int *a, unsigned int digits)
{
unsigned int i;
for (i = 0; i < digits; i++)
{
a[i] = 0;
}
}
unsigned int bn_add(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int digits)
{
unsigned int ai, carry;
unsigned int i;
carry = 0;
for (i = 0; i < digits; i++)
{
if ((ai = b[i] + carry) < carry)
{
ai = c[i];
}
else if ((ai += c[i]) < c[i])
{
carry = 1;
}
else
{
carry = 0;
}
a[i] = ai;
}
return carry;
}
unsigned int bn_sub(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int digits)
{
unsigned int ai, borrow;
unsigned int i;
borrow = 0;
for (i = 0; i < digits; i++)
{
if ((ai = b[i] - borrow) > (BN_MAX_DIGIT - borrow))
{
ai = BN_MAX_DIGIT - c[i];
}
else if ((ai -= c[i]) > (BN_MAX_DIGIT - c[i]))
{
borrow = 1;
}
else
{
borrow = 0;
}
a[i] = ai;
}
return borrow;
}
void bn_mul(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits)
{
static unsigned int t[2 * BN_MAX_DIGITS] = {0};
unsigned int bdigits = 0, cdigits = 0, i = 0;
// Clear potentially sensitive information
memset((unsigned char *)t, 0, sizeof(t));
bn_assign_zero(t, (2 * digits));
bdigits = bn_digits(b, digits);
cdigits = bn_digits(c, digits);
for (i = 0; i < bdigits; i++)
{
t[i + cdigits] += bn_add_digit_mul(&t[i], &t[i], b[i], c, cdigits);
}
bn_assign(a, t, 2 * digits);
}
// a = b << c (a = b * 2^c)
static unsigned int bn_shift_l(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int digits)
{
unsigned int bi, carry;
unsigned int i, t;
if (c >= BN_DIGIT_BITS)
return 0;
t = BN_DIGIT_BITS - c;
carry = 0;
for (i = 0; i < digits; i++)
{
bi = b[i];
a[i] = (bi << c) | carry;
carry = c ? (bi >> t) : 0;
}
return carry;
}
// a = b >> c (a = b / 2^c)
static unsigned int bn_shift_r(unsigned int *a, unsigned int *b, unsigned int c,
unsigned int digits)
{
unsigned int bi, carry;
int i;
unsigned int t;
if (c >= BN_DIGIT_BITS)
return 0;
t = BN_DIGIT_BITS - c;
carry = 0;
i = digits - 1;
for (; i >= 0; i--)
{
bi = b[i];
a[i] = (bi >> c) | carry;
carry = c ? (bi << t) : 0;
}
return carry;
}
// a = b / c, d = b % c
static void bn_div(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int cdigits, unsigned int *d, unsigned int ddigits)
{
static unsigned long long tmp;;
static unsigned int cc[2 * BN_MAX_DIGITS + 1] = {0}, dd[BN_MAX_DIGITS] = {0};
int i;
unsigned int ai, t, dddigits, shift;
tmp = 0;
// Clear potentially sensitive information
memset((unsigned char *)cc, 0, sizeof(cc));
memset((unsigned char *)dd, 0, sizeof(dd));
dddigits = bn_digits(d, ddigits);
if (dddigits == 0)
return;
shift = BN_DIGIT_BITS - bn_digit_bits(d[dddigits - 1]);
bn_assign_zero(cc, dddigits);
cc[cdigits] = bn_shift_l(cc, c, shift, cdigits);
bn_shift_l(dd, d, shift, dddigits);
t = dd[dddigits - 1];
bn_assign_zero(a, cdigits);
i = cdigits - dddigits;
for (; i >= 0; i--)
{
if (t == BN_MAX_DIGIT)
{
ai = cc[i + dddigits];
}
else
{
tmp = cc[i + dddigits - 1];
tmp += (unsigned long long)cc[i + dddigits] << BN_DIGIT_BITS;
ai = tmp / (t + 1);
}
cc[i + dddigits] -= bn_sub_digit_mul(&cc[i], &cc[i], ai, dd, dddigits);
while (cc[i + dddigits] || (bn_cmp(&cc[i], dd, dddigits) >= 0))
{
ai++;
cc[i + dddigits] -= bn_sub(&cc[i], &cc[i], dd, dddigits);
}
a[i] = ai;
}
bn_assign_zero(b, ddigits);
bn_shift_r(b, cc, shift, dddigits);
}
// a = b mod c
void bn_mod(unsigned int *a, unsigned int *b, unsigned int bdigits,
unsigned int *c, unsigned int cdigits)
{
static unsigned int t[2 * BN_MAX_DIGITS] = {0};
// Clear potentially sensitive information
memset((unsigned char *)t, 0, sizeof(t));
bn_div(t, a, b, bdigits, c, cdigits);
}
void bn_mod_mul(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int *d, unsigned int digits)
{
static unsigned int t[2 * BN_MAX_DIGITS]={0};
// Clear potentially sensitive information
memset((unsigned char *)t, 0, sizeof(t));
bn_mul(t, b, c, digits);
bn_mod(a, t, (2 * digits), d, digits);
}
void bn_mod_exp(unsigned int *a, unsigned int *b, unsigned int *c,
unsigned int cdigits, unsigned int *d, unsigned int ddigits)
{
static unsigned int bpower[3][BN_MAX_DIGITS] = {0}, t[BN_MAX_DIGITS] = {0};
int i;
unsigned int ci = 0, ci_bits = 0, j, s;
// Clear potentially sensitive information
memset((unsigned char *)bpower, 0, sizeof(bpower));
memset((unsigned char *)t, 0, sizeof(t));
bn_assign(bpower[0], b, ddigits);
bn_mod_mul(bpower[1], bpower[0], b, d, ddigits);
bn_mod_mul(bpower[2], bpower[1], b, d, ddigits);
BN_ASSIGN_DIGIT(t, 1, ddigits);
cdigits = bn_digits(c, cdigits);
i = cdigits - 1;
for (; i >= 0; i--)
{
ci = c[i];
ci_bits = BN_DIGIT_BITS;
if (i == (int)(cdigits - 1))
{
while (!DIGIT_2MSB(ci))
{
ci <<= 2;
ci_bits -= 2;
}
}
for (j = 0; j < ci_bits; j += 2)
{
bn_mod_mul(t, t, t, d, ddigits);
bn_mod_mul(t, t, t, d, ddigits);
if ((s = DIGIT_2MSB(ci)) != 0)
{
bn_mod_mul(t, t, bpower[s - 1], d, ddigits);
}
ci <<= 2;
}
}
bn_assign(a, t, ddigits);
}
int bn_cmp(unsigned int *a, unsigned int *b, unsigned int digits)
{
int i;
for (i = digits - 1; i >= 0; i--)
{
if (a[i] > b[i])
return 1;
if (a[i] < b[i])
return -1;
}
return 0;
}
unsigned int bn_digits(unsigned int *a, unsigned int digits)
{
int i;
for (i = digits - 1; i >= 0; i--)
{
if (a[i])
break;
}
return (i + 1);
}
/*****************************************************************************
* @file bignum.h
* @author jianqiang.xue
* @version v1.0.0
****************************************************************************/
#ifndef __BIGNUM_H__
#define __BIGNUM_H__
#define BN_MAX_DIGITS 65 // RSA_MAX_MODULUS_LEN + 1
void bn_decode(unsigned int *bn, unsigned int digits, unsigned char *hexarr, unsigned int size);
void bn_encode(unsigned char *hexarr, unsigned int size, unsigned int *bn, unsigned int digits);
// a = 0
void bn_assign_zero(unsigned int *a, unsigned int digits);
// a = b + c, return carry
unsigned int bn_add(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits);
// a = b - c, return borrow
unsigned int bn_sub(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits);
// a = b * c
void bn_mul(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int digits);
// a = b mod c
void bn_mod(unsigned int *a, unsigned int *b, unsigned int bdigits, unsigned int *c, unsigned int cdigits);
// a = b * c mod d
void bn_mod_mul(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d, unsigned int digits);
// a = b ^ c mod d
void bn_mod_exp(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int cdigits, unsigned int *d, unsigned int ddigits);
// returns sign of a - b
int bn_cmp(unsigned int *a, unsigned int *b, unsigned int digits);
// returns significant length of a in digits
unsigned int bn_digits(unsigned int *a, unsigned int digits);
#endif // __BIGNUM_H__
使用例子伪代码 main.c
#include <stdio.h>
#include <string.h>
#include "rsa2048.h"
unsigned char ciphertext[256];
unsigned char plaintext[50]; // 根据明文实际长度定义
unsigned int plaintext_len = 0; // 得到解密后的明文长度
int ciphertext_len = 0; //密文长度
int ret = 0;
strcpy((char *)plaintext, "xjqlisun9527");
ret = rsa_encrypt(plaintext, strlen((char *)plaintext), ciphertext, (unsigned int *)&ciphertext_len);
printf("私钥加密后(%d):\n明文=%s, p_len=%ld, \n密文=%s, c_len=%d\n", ret, plaintext, strlen((char *)plaintext),
ciphertext, ciphertext_len);
memset(plaintext, 0, 50);
plaintext_len = 0;
ret = rsa_decrypt(ciphertext, 256, plaintext, &plaintext_len);
printf("公钥解密后(%d):\n明文=%s, p_len=%d, \n密文=%s, c_len=%ld\n", ret, plaintext, plaintext_len,
ciphertext, strlen((char *)ciphertext));

浙公网安备 33010602011771号