记录开发过程中的问题和功能。毕se代做,小家电开发。 收徒带做企业级项目,帮助毕业生和转行人员顺利找到工作。

LiSun

记录开发过程中的问题和功能。毕se代做,小家电开发。 收徒带做企业级项目,帮助毕业生和转行人员顺利找到工作。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
#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));

在这里插入图片描述

工程下载

posted on 2022-08-13 11:00  嵌入式单片机实验室  阅读(261)  评论(0)    收藏  举报
记录开发过程中的问题和功能。毕se代做,小家电开发。 收徒带做企业级项目,帮助毕业生和转行人员顺利找到工作。