Example #1
0
/**
 * Use PKCS1.5 for encryption/signing.
 * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
 */
int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
                uint8_t *out_data, int is_signing) {
  int byte_size = ctx->num_octets;
  int num_pads_needed = byte_size - in_len - 3;
  bigint *dat_bi, *encrypt_bi;

  /* note: in_len+11 must be > byte_size */
  out_data[0] = 0; /* ensure encryption block is < modulus */

  if (is_signing) {
    out_data[1] = 1; /* PKCS1.5 signing pads with "0xff"'s */
    memset(&out_data[2], 0xff, num_pads_needed);
  } else /* randomize the encryption padding with non-zero bytes */
  {
    out_data[1] = 2;
    if (get_random_nonzero(&out_data[2], num_pads_needed) < 0) return -1;
  }

  out_data[2 + num_pads_needed] = 0;
  memcpy(&out_data[3 + num_pads_needed], in_data, in_len);

  /* now encrypt it */
  dat_bi = bi_import(ctx->bi_ctx, out_data, byte_size);
  encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) : RSA_public(ctx, dat_bi);
  bi_export(ctx->bi_ctx, encrypt_bi, out_data, byte_size);

  /* save a few bytes of memory */
  bi_clear_cache(ctx->bi_ctx);
  return byte_size;
}
Example #2
0
/**
 * @brief Use PKCS1.5 for decryption/verification.
 * @param ctx [in] The context
 * @param in_data [in] The data to decrypt (must be < modulus size-11)
 * @param out_data [out] The decrypted data.
 * @param out_len [int] The size of the decrypted buffer in bytes
 * @param is_decryption [in] Decryption or verify operation.
 * @return  The number of bytes that were originally encrypted. -1 on error.
 * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
 */
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, 
                            uint8_t *out_data, int out_len, int is_decryption)
{
    const int byte_size = ctx->num_octets;
    int i = 0, size;
    bigint *decrypted_bi, *dat_bi;
    uint8_t *block = (uint8_t *)SSL_MALLOC(byte_size);
    int pad_count = 0;

    if (out_len < byte_size)        /* check output has enough size */
        return -1;
    memset(out_data, 0, out_len); /* initialise */

    /* decrypt */
    dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size);
#ifdef CONFIG_SSL_CERT_VERIFICATION
    decrypted_bi = is_decryption ?  /* decrypt or verify? */
            RSA_private(ctx, dat_bi) : RSA_public(ctx, dat_bi);
#else   /* always a decryption */
    decrypted_bi = RSA_private(ctx, dat_bi);
#endif

    /* convert to a normal block */
    bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);

    if (block[i++] != 0)             /* leading 0? */
        return -1;

#ifdef CONFIG_SSL_CERT_VERIFICATION
    if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
    {
        if (block[i++] != 0x01)     /* BT correct? */
            return -1;

        while (block[i++] == 0xff && i < byte_size)
            pad_count++;
    }
    else                    /* PKCS1.5 encryption padding is random */
#endif
    {
        if (block[i++] != 0x02)     /* BT correct? */
            return -1;

        while (block[i++] && i < byte_size)
            pad_count++;
    }

    /* check separator byte 0x00 - and padding must be 8 or more bytes */
    if (i == byte_size || pad_count < 8) 
        return -1;

    size = byte_size - i;

    /* get only the bit we want */
    if (size > 0)
        memcpy(out_data, &block[i], size);

    SSL_FREE(block);
    return size ? size : -1;
}
Example #3
0
/**************************************************************************
 * RSA tests 
 *
 * Use the results from openssl to verify PKCS1 etc 
 **************************************************************************/
static int RSA_test(void)
{
    int res = 1;
    const char *plaintext = /* 128 byte hex number */
        "1234567890abbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee2"
        "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeee2\012";
    uint8_t enc_data[128], dec_data[128];
    RSA_CTX *rsa_ctx = NULL;
    BI_CTX *bi_ctx;
    bigint *plaintext_bi;
    bigint *enc_data_bi, *dec_data_bi;
    uint8_t enc_data2[128], dec_data2[128];
    int len; 
    uint8_t *buf;
	
    /* extract the private key elements */
    len = get_file("./axTLS.key_1024", &buf);
    if (asn1_get_private_key(buf, len, &rsa_ctx) < 0)
    {
        goto end;
    }

    free(buf);
    
	dump_frame("original data",(char *)plaintext, strlen(plaintext));
	
    bi_ctx = rsa_ctx->bi_ctx;
    plaintext_bi = bi_import(bi_ctx, 
            (const uint8_t *)plaintext, strlen(plaintext));
    /* basic rsa encrypt */
    enc_data_bi = RSA_public(rsa_ctx, plaintext_bi);
    bi_export(bi_ctx, bi_copy(enc_data_bi), enc_data, sizeof(enc_data));
	dump_frame("encrypt data",(char *)enc_data, sizeof(enc_data));
    /* basic rsa decrypt */
    dec_data_bi = RSA_private(rsa_ctx, enc_data_bi);
    bi_export(bi_ctx, dec_data_bi, dec_data, sizeof(dec_data));
	dump_frame("decrypt data",(char *)dec_data, sizeof(dec_data));
    if (memcmp(dec_data, plaintext, strlen(plaintext)))
    {
        printf("Error: DECRYPT #1 failed\n");
        goto end;
    }

    RSA_encrypt(rsa_ctx, (const uint8_t *)"abc", 3, enc_data2, 0);
    RSA_decrypt(rsa_ctx, enc_data2, dec_data2, 1);
    if (memcmp("abc", dec_data2, 3))
    {
        printf("Error: ENCRYPT/DECRYPT #2 failed\n");
        goto end;
    }

    RSA_free(rsa_ctx);
    res = 0;
    printf("All RSA tests passed\n");

end:
    return res;
}
Example #4
0
/**
 * @brief Use PKCS1.5 for decryption/verification.
 * @param ctx [in] The context
 * @param in_data [in] The data to encrypt (must be < modulus size-11)
 * @param out_data [out] The encrypted data.
 * @param is_decryption [in] Decryption or verify operation.
 * @return  The number of bytes that were originally encrypted. -1 on error.
 * @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
 */
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, 
                            uint8_t *out_data, int is_decryption)
{
    int byte_size = ctx->num_octets;
    uint8_t *block;
    int i, size;
    bigint *decrypted_bi,*dat_bi;

    memset(out_data, 0, byte_size); /* initialise */

    /* decrypt */
    dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size);
#ifdef CONFIG_SSL_CERT_VERIFICATION
    decrypted_bi = is_decryption ?  /* decrypt or verify? */
        RSA_private(ctx, dat_bi): RSA_public(ctx, dat_bi);
#else   /* always a decryption */
    decrypted_bi = RSA_private(ctx, dat_bi);
#endif
    /* convert to a normal block */
    block = (uint8_t *)malloc(byte_size);
    bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);
        int o=0;
        for(o;o<byte_size;o++){
        printf("block[%d]:0x%02x   ",o,block[o]);
        }
        printf("\n");
    i = 10; /* start at the first possible non-padded byte */

#ifdef CONFIG_SSL_CERT_VERIFICATION
    if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
    {
        while (block[i++] == 0xff && i < byte_size);

        if (block[i-2] != 0xff)
            i = byte_size;     /*ensure size is 0 */   
    }
    else                    /* PKCS1.5 encryption padding is random */
#endif
    {
        while (block[i++] && i < byte_size);
    }
    size = byte_size - i;

    /* get only the bit we want */
    if (size > 0)
        memcpy(out_data, &block[i], size);
    
    free(block);
        printf("size:%d\n",size);
    return size ? size : -1;
}
Example #5
0
/**
 * Use PKCS1.5 for encryption/signing.
 * see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
 */
int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, 
        uint8_t *out_data, int is_signing)
{
    int byte_size = ctx->num_octets;printf("byte_size:%d\n",byte_size);
    int num_pads_needed = byte_size-in_len-3;printf("num_pads_needed:%d\n",num_pads_needed);
    bigint *dat_bi, *encrypt_bi;

    /* note: in_len+11 must be > byte_size */
    out_data[0] = 0;     /* ensure encryption block is < modulus */
    if (is_signing)
    {
        out_data[1] = 1;        /* PKCS1.5 signing pads with "0xff"'s */
        memset(&out_data[2], 0xff, num_pads_needed);
    }
    else /* randomize the encryption padding with non-zero bytes */   
    {    
        out_data[1] = 2;
        get_random_NZ(num_pads_needed, &out_data[2]);
    }
    out_data[2+num_pads_needed] = 0;

    memcpy(&out_data[3+num_pads_needed], in_data, in_len);

    /* now encrypt it */
    dat_bi = bi_import(ctx->bi_ctx, out_data, byte_size);
           bi_print("pre_dispose_data",dat_bi);
    encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) : 
        RSA_public(ctx, dat_bi);
        
    bi_export(ctx->bi_ctx, encrypt_bi, out_data, byte_size);
        int i=0;
        printf("encrypted message in uint8_t:");
        for (i;i<byte_size;i++)
                printf("0x%02x ",out_data[i]);
        printf("\n\n");
        
    return byte_size;
}
int main(int argc, char *argv[])
{
#ifdef CONFIG_SSL_CERT_VERIFICATION
    RSA_CTX *rsa_ctx = NULL;
    BI_CTX *ctx;
    bigint *bi_data, *bi_res;
    float diff;
    int res = 1;
    struct timeval tv_old, tv_new;
    const char *plaintext;
    uint8_t compare[MAX_KEY_BYTE_SIZE];
    int i, max_biggie = 10;    /* really crank performance */
    int len; 
    uint8_t *buf;

    /**
     * 512 bit key
     */
    plaintext = /* 64 byte number */
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";

    len = get_file("../ssl/test/axTLS.key_512", &buf);
    asn1_get_private_key(buf, len, &rsa_ctx);
    ctx = rsa_ctx->bi_ctx;
    bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
    bi_res = RSA_public(rsa_ctx, bi_data);
    bi_data = bi_res;   /* reuse again */

    gettimeofday(&tv_old, NULL);
    for (i = 0; i < max_biggie; i++)
    {
        bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
        if (i < max_biggie-1)
        {
            bi_free(ctx, bi_res);
        }
    }

    gettimeofday(&tv_new, NULL);
    bi_free(ctx, bi_data);

    diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
                (tv_new.tv_usec-tv_old.tv_usec)/1000;
    printf("512 bit decrypt time: %.2fms\n", diff/max_biggie);
    TTY_FLUSH();
    bi_export(ctx, bi_res, compare, 64);
    RSA_free(rsa_ctx);
    free(buf);
    if (memcmp(plaintext, compare, 64) != 0)
        goto end;

    /**
     * 1024 bit key
     */
    plaintext = /* 128 byte number */
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";

    len = get_file("../ssl/test/axTLS.key_1024", &buf);
    rsa_ctx = NULL;
    asn1_get_private_key(buf, len, &rsa_ctx);
    ctx = rsa_ctx->bi_ctx;
    bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
    bi_res = RSA_public(rsa_ctx, bi_data);
    bi_data = bi_res;   /* reuse again */

    gettimeofday(&tv_old, NULL);
    for (i = 0; i < max_biggie; i++)
    {
        bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
        if (i < max_biggie-1)
        {
            bi_free(ctx, bi_res);
        }
    }

    gettimeofday(&tv_new, NULL);
    bi_free(ctx, bi_data);

    diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
                (tv_new.tv_usec-tv_old.tv_usec)/1000;
    printf("1024 bit decrypt time: %.2fms\n", diff/max_biggie);
    TTY_FLUSH();
    bi_export(ctx, bi_res, compare, 128);
    RSA_free(rsa_ctx);
    free(buf);
    if (memcmp(plaintext, compare, 128) != 0)
        goto end;

    /**
     * 2048 bit key
     */
    plaintext = /* 256 byte number */
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";

    len = get_file("../ssl/test/axTLS.key_2048", &buf);
    rsa_ctx = NULL;
    asn1_get_private_key(buf, len, &rsa_ctx);
    ctx = rsa_ctx->bi_ctx;
    bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
    bi_res = RSA_public(rsa_ctx, bi_data);
    bi_data = bi_res;   /* reuse again */

    gettimeofday(&tv_old, NULL);
    for (i = 0; i < max_biggie; i++)
    {
        bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
        if (i < max_biggie-1)
        {
            bi_free(ctx, bi_res);
        }
    }
    gettimeofday(&tv_new, NULL);
    bi_free(ctx, bi_data);

    diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
                (tv_new.tv_usec-tv_old.tv_usec)/1000;
    printf("2048 bit decrypt time: %.2fms\n", diff/max_biggie);
    TTY_FLUSH();
    bi_export(ctx, bi_res, compare, 256);
    RSA_free(rsa_ctx);
    free(buf);
    if (memcmp(plaintext, compare, 256) != 0)
        goto end;

    /**
     * 4096 bit key
     */
    plaintext = /* 512 byte number */
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^"
        "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*^";

    len = get_file("../ssl/test/axTLS.key_4096", &buf);
    rsa_ctx = NULL;
    asn1_get_private_key(buf, len, &rsa_ctx);
    ctx = rsa_ctx->bi_ctx;
    bi_data = bi_import(ctx, (uint8_t *)plaintext, strlen(plaintext));
    gettimeofday(&tv_old, NULL);
    bi_res = RSA_public(rsa_ctx, bi_data);
    gettimeofday(&tv_new, NULL);
    diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
                (tv_new.tv_usec-tv_old.tv_usec)/1000;
    printf("4096 bit encrypt time: %.2fms\n", diff);
    TTY_FLUSH();
    bi_data = bi_res;   /* reuse again */

    gettimeofday(&tv_old, NULL);
    for (i = 0; i < max_biggie; i++)
    {
        bi_res = RSA_private(rsa_ctx, bi_copy(bi_data));
        if (i < max_biggie-1)
        {
            bi_free(ctx, bi_res);
        }
    }

    gettimeofday(&tv_new, NULL);
    bi_free(ctx, bi_data);

    diff = (tv_new.tv_sec-tv_old.tv_sec)*1000 +
                (tv_new.tv_usec-tv_old.tv_usec)/1000;
    printf("4096 bit decrypt time: %.2fms\n", diff/max_biggie);
    TTY_FLUSH();
    bi_export(ctx, bi_res, compare, 512);
    RSA_free(rsa_ctx);
    free(buf);
    if (memcmp(plaintext, compare, 512) != 0)
        goto end;

    /* done */
    printf("Bigint performance testing complete\n");
    res = 0;

end:
    return res;
#else
    return 0;
#endif
}