Пример #1
0
void DH_compute_key(DH_CTX *dh_ctx)
{
    BI_CTX *bi_ctx = bi_initialize();
    int len = dh_ctx->len;
    bigint *p = bi_import(bi_ctx, dh_ctx->p, len); //p modulus
    bigint *x = bi_import(bi_ctx, dh_ctx->x, len); //private key
    bigint *gy = bi_import(bi_ctx, dh_ctx->gy, len);  //public key(peer)
    bigint *k;                                      //negotiated(session) key

    bi_permanent(x);
    bi_permanent(gy);

    //calculate session key k = gy^x mod p
    bi_set_mod(bi_ctx, p,  BIGINT_M_OFFSET);
    bi_ctx->mod_offset = BIGINT_M_OFFSET;
    k = bi_mod_power(bi_ctx, gy, x);
    bi_permanent(k);

    bi_export(bi_ctx, k, dh_ctx->k, len);

    bi_depermanent(x);
    bi_depermanent(gy);
    bi_depermanent(k);
    bi_free(bi_ctx, x);
    bi_free(bi_ctx, gy);
    bi_free(bi_ctx, k);

    bi_free_mod(bi_ctx, BIGINT_M_OFFSET);
    bi_terminate(bi_ctx);
}
Пример #2
0
void DH_generate_key(DH_CTX *dh_ctx)
{
    BI_CTX *bi_ctx = bi_initialize();
    int len = dh_ctx->len;
    bigint *p = bi_import(bi_ctx, dh_ctx->p, len); //p modulus
    bigint *g = bi_import(bi_ctx, dh_ctx->g, dh_ctx->glen); //generator
    bigint *x, *gx;

    bi_permanent(g);

    //generate private key  X
    get_random_NZ(len, dh_ctx->x);
    x = bi_import(bi_ctx, dh_ctx->x, len);
    bi_permanent(x);

    //calculate public key gx = g^x mod p
    bi_set_mod(bi_ctx, p,  BIGINT_M_OFFSET);
    bi_ctx->mod_offset = BIGINT_M_OFFSET;
    gx = bi_mod_power(bi_ctx, g, x);
    bi_permanent(gx);

    bi_export(bi_ctx, x, dh_ctx->x, len);
    bi_export(bi_ctx, gx, dh_ctx->gx, len);

    bi_depermanent(g);
    bi_depermanent(x);
    bi_depermanent(gx);
    bi_free(bi_ctx, g);
    bi_free(bi_ctx, x);
    bi_free(bi_ctx, gx);

    bi_free_mod(bi_ctx, BIGINT_M_OFFSET);
    bi_terminate(bi_ctx);
}
Пример #3
0
void RSA_pub_key_new(RSA_CTX **ctx, 
        const uint8_t *modulus, int mod_len,
        const uint8_t *pub_exp, int pub_len)
{
    RSA_CTX *rsa_ctx;
    BI_CTX *bi_ctx = bi_initialize();
    *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
    rsa_ctx = *ctx;
    rsa_ctx->bi_ctx = bi_ctx;
    rsa_ctx->num_octets = (mod_len & 0xFFF0);
    rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
    bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
    rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
    bi_permanent(rsa_ctx->e);
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
0
void RSA_pub_key_new(RSA_CTX **ctx, const uint8_t *modulus, int mod_len,
                     const uint8_t *pub_exp, int pub_len) {
  RSA_CTX *rsa_ctx;
  BI_CTX *bi_ctx;

  if (*ctx) /* if we load multiple certs, dump the old one */
    RSA_free(*ctx);

  bi_ctx = bi_initialize();
  *ctx = (RSA_CTX *) calloc(1, sizeof(RSA_CTX));
  rsa_ctx = *ctx;
  rsa_ctx->bi_ctx = bi_ctx;
  rsa_ctx->num_octets = mod_len;
  rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
  bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
  rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
  bi_permanent(rsa_ctx->e);
}
Пример #8
0
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, const uint8_t *p,
                      int p_len, const uint8_t *q, int q_len, const uint8_t *dP,
                      int dP_len, const uint8_t *dQ, int dQ_len,
                      const uint8_t *qInv, int qInv_len) {
  RSA_CTX *rsa_ctx;
  BI_CTX *bi_ctx;
  RSA_pub_key_new(ctx, modulus, mod_len, pub_exp, pub_len);
  rsa_ctx = *ctx;
  bi_ctx = rsa_ctx->bi_ctx;
  rsa_ctx->d = bi_import(bi_ctx, priv_exp, priv_len);
  bi_permanent(rsa_ctx->d);

  rsa_ctx->p = bi_import(bi_ctx, p, p_len);
  rsa_ctx->q = bi_import(bi_ctx, q, q_len);
  rsa_ctx->dP = bi_import(bi_ctx, dP, dP_len);
  rsa_ctx->dQ = bi_import(bi_ctx, dQ, dQ_len);
  rsa_ctx->qInv = bi_import(bi_ctx, qInv, qInv_len);
  bi_permanent(rsa_ctx->dP);
  bi_permanent(rsa_ctx->dQ);
  bi_permanent(rsa_ctx->qInv);
  bi_set_mod(bi_ctx, rsa_ctx->p, BIGINT_P_OFFSET);
  bi_set_mod(bi_ctx, rsa_ctx->q, BIGINT_Q_OFFSET);
}
Пример #9
0
/**
 * Take a signature and decrypt it.
 */
static bigint *ICACHE_FLASH_ATTR sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
        bigint *modulus, bigint *pub_exp)
{
    int i, size;
    bigint *decrypted_bi, *dat_bi;
    bigint *bir = NULL;
    uint8_t *block = (uint8_t *)os_malloc(sig_len);

    /* decrypt */
    dat_bi = bi_import(ctx, sig, sig_len);
    ctx->mod_offset = BIGINT_M_OFFSET;

    /* convert to a normal block */
    decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);

    bi_export(ctx, decrypted_bi, block, sig_len);
    ctx->mod_offset = BIGINT_M_OFFSET;

    i = 10; /* start at the first possible non-padded byte */
    while (block[i++] && i < sig_len);
    size = sig_len - i;

    /* get only the bit we want */
    if (size > 0)
    {
        int len;
        const uint8_t *sig_ptr = get_signature(&block[i], &len);

        if (sig_ptr)
        {
            bir = bi_import(ctx, sig_ptr, len);
        }
    }

    /* save a few bytes of memory */
    bi_clear_cache(ctx);

    os_free(block);
    return bir;
}
Пример #10
0
/**
 * Take a signature and decrypt it.
**/
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
        bigint *modulus, bigint *pub_exp)
{
    uint8_t *block;
    int i, size;
    bigint *decrypted_bi, *dat_bi;
    bigint *bir = NULL;

    block = (uint8_t *)malloc(sig_len);

    /* decrypt */
    dat_bi = bi_import(ctx, sig, sig_len);
    ctx->mod_offset = BIGINT_M_OFFSET;

    /* convert to a normal block */
    decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);

    bi_export(ctx, decrypted_bi, block, sig_len);
    ctx->mod_offset = BIGINT_M_OFFSET;

    i = 10; /* start at the first possible non-padded byte */
    while (block[i++] && i < sig_len);
    size = sig_len - i;

    /* get only the bit we want */
    if (size > 0)
    {
        int len;
        const uint8_t *sig_ptr = x509_get_signature(&block[i], &len);

        if (sig_ptr)
        {
            bir = bi_import(ctx, sig_ptr, len);
        }
    }

    free(block);
    return bir;
}
Пример #11
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;
}
Пример #12
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;
}
Пример #13
0
/**
 * Construct a new x509 object.
 * @return 0 if ok. < 0 if there was a problem.
 */
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
{
    int begin_tbs, end_tbs;
    int ret = X509_NOT_OK, offset = 0, cert_size = 0;
    X509_CTX *x509_ctx;
    BI_CTX *bi_ctx;

    *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
    x509_ctx = *ctx;

    /* get the certificate size */
    asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE);

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    begin_tbs = offset;         /* start of the tbs */
    end_tbs = begin_tbs;        /* work out the end of the tbs */
    asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    if (cert[offset] == ASN1_EXPLICIT_TAG)   /* optional version */
    {
        if (asn1_version(cert, &offset, x509_ctx))
            goto end_cert;
    }

    if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */
            asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    /* make sure the signature is ok */
    if (asn1_signature_type(cert, &offset, x509_ctx))
    {
        ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
        goto end_cert;
    }

    if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) ||
            asn1_validity(cert, &offset, x509_ctx) ||
            asn1_name(cert, &offset, x509_ctx->cert_dn) ||
            asn1_public_key(cert, &offset, x509_ctx))
    {
        goto end_cert;
    }

    bi_ctx = x509_ctx->rsa_ctx->bi_ctx;

    x509_ctx->fingerprint = malloc(SHA1_SIZE);
    SHA1_CTX sha_fp_ctx;
    SHA1_Init(&sha_fp_ctx);
    SHA1_Update(&sha_fp_ctx, &cert[0], cert_size);
    SHA1_Final(x509_ctx->fingerprint, &sha_fp_ctx);

#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
    /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
    if (x509_ctx->sig_type == SIG_TYPE_MD5)
    {
        MD5_CTX md5_ctx;
        uint8_t md5_dgst[MD5_SIZE];
        MD5_Init(&md5_ctx);
        MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        MD5_Final(md5_dgst, &md5_ctx);
        x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
    }
    else if (x509_ctx->sig_type == SIG_TYPE_SHA1)
    {
        SHA1_CTX sha_ctx;
        uint8_t sha_dgst[SHA1_SIZE];
        SHA1_Init(&sha_ctx);
        SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        SHA1_Final(sha_dgst, &sha_ctx);
        x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
    }
    else if (x509_ctx->sig_type == SIG_TYPE_MD2)
    {
        MD2_CTX md2_ctx;
        uint8_t md2_dgst[MD2_SIZE];
        MD2_Init(&md2_ctx);
        MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        MD2_Final(md2_dgst, &md2_ctx);
        x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE);
    }

    if (cert[offset] == ASN1_V3_DATA)
    {
        int suboffset;

        ++offset;
        get_asn1_length(cert, &offset);

        if ((suboffset = asn1_find_subjectaltname(cert, offset)) > 0)
        {
            if (asn1_next_obj(cert, &suboffset, ASN1_OCTET_STRING) > 0)
            {
                int altlen;

                if ((altlen = asn1_next_obj(cert,
                                            &suboffset, ASN1_SEQUENCE)) > 0)
                {
                    int endalt = suboffset + altlen;
                    int totalnames = 0;

                    while (suboffset < endalt)
                    {
                        int type = cert[suboffset++];
                        int dnslen = get_asn1_length(cert, &suboffset);

                        if (type == ASN1_CONTEXT_DNSNAME)
                        {
                            x509_ctx->subject_alt_dnsnames = (char**)
                                                             realloc(x509_ctx->subject_alt_dnsnames,
                                                                     (totalnames + 2) * sizeof(char*));
                            x509_ctx->subject_alt_dnsnames[totalnames] =
                                (char*)malloc(dnslen + 1);
                            x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
                            memcpy(x509_ctx->subject_alt_dnsnames[totalnames],
                                   cert + suboffset, dnslen);
                            x509_ctx->subject_alt_dnsnames[
                                totalnames][dnslen] = 0;
                            ++totalnames;
                        }

                        suboffset += dnslen;
                    }
                }
            }
        }
    }

    offset = end_tbs;   /* skip the rest of v3 data */
    if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) ||
            asn1_signature(cert, &offset, x509_ctx))
        goto end_cert;
#endif
    ret = X509_OK;
end_cert:
    if (len)
    {
        *len = cert_size;
    }

    if (ret)
    {
#ifdef CONFIG_SSL_FULL_MODE
        printf("Error: Invalid X509 ASN.1 file (%s)\n",
               x509_display_error(ret));
#endif
        x509_free(x509_ctx);
        *ctx = NULL;
    }

    return ret;
}
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
}
Пример #15
0
/**
 * Construct a new x509 object.
 * @return 0 if ok. < 0 if there was a problem.
 */
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
{
    int begin_tbs, end_tbs, begin_spki, end_spki;
    int ret = X509_NOT_OK, offset = 0, cert_size = 0;
    int version = 0;
    X509_CTX *x509_ctx;
#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
    BI_CTX *bi_ctx;
#endif

    *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
    x509_ctx = *ctx;

    /* get the certificate size */
    asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE); 

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    begin_tbs = offset;         /* start of the tbs */
    end_tbs = begin_tbs;        /* work out the end of the tbs */
    asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    /* optional version */
    if (cert[offset] == ASN1_EXPLICIT_TAG && 
            asn1_version(cert, &offset, &version) == X509_NOT_OK)
        goto end_cert;

    if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */ 
            asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    /* make sure the signature is ok */
    if (asn1_signature_type(cert, &offset, x509_ctx))
    {
        ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
        goto end_cert;
    }

    if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) || 
            asn1_validity(cert, &offset, x509_ctx) ||
            asn1_name(cert, &offset, x509_ctx->cert_dn))
    {
        goto end_cert;
    }
    begin_spki = offset;
    if (asn1_public_key(cert, &offset, x509_ctx))
        goto end_cert;
    end_spki = offset;

    x509_ctx->fingerprint = malloc(SHA1_SIZE);
    SHA1_CTX sha_fp_ctx;
    SHA1_Init(&sha_fp_ctx);
    SHA1_Update(&sha_fp_ctx, &cert[0], cert_size);
    SHA1_Final(x509_ctx->fingerprint, &sha_fp_ctx);

    x509_ctx->spki_sha256 = malloc(SHA256_SIZE);
    SHA256_CTX spki_hash_ctx;
    SHA256_Init(&spki_hash_ctx);
    SHA256_Update(&spki_hash_ctx, &cert[begin_spki], end_spki-begin_spki);
    SHA256_Final(x509_ctx->spki_sha256, &spki_hash_ctx);

#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
    bi_ctx = x509_ctx->rsa_ctx->bi_ctx;

    /* use the appropriate signature algorithm */
    switch (x509_ctx->sig_type)
    {
        case SIG_TYPE_MD5:
        {
            MD5_CTX md5_ctx;
            uint8_t md5_dgst[MD5_SIZE];
            MD5_Init(&md5_ctx);
            MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            MD5_Final(md5_dgst, &md5_ctx);
            x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
        }
            break;

        case SIG_TYPE_SHA1:
        {
            SHA1_CTX sha_ctx;
            uint8_t sha_dgst[SHA1_SIZE];
            SHA1_Init(&sha_ctx);
            SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA1_Final(sha_dgst, &sha_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
        }
            break;

        case SIG_TYPE_SHA256:
        {
            SHA256_CTX sha256_ctx;
            uint8_t sha256_dgst[SHA256_SIZE];
            SHA256_Init(&sha256_ctx);
            SHA256_Update(&sha256_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA256_Final(sha256_dgst, &sha256_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha256_dgst, SHA256_SIZE);
        }
            break;

        case SIG_TYPE_SHA384:
        {
            SHA384_CTX sha384_ctx;
            uint8_t sha384_dgst[SHA384_SIZE];
            SHA384_Init(&sha384_ctx);
            SHA384_Update(&sha384_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA384_Final(sha384_dgst, &sha384_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha384_dgst, SHA384_SIZE);
        }
            break;

        case SIG_TYPE_SHA512:
        {
            SHA512_CTX sha512_ctx;
            uint8_t sha512_dgst[SHA512_SIZE];
            SHA512_Init(&sha512_ctx);
            SHA512_Update(&sha512_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA512_Final(sha512_dgst, &sha512_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha512_dgst, SHA512_SIZE);
        }
            break;
    }

    if (version == 2 && asn1_next_obj(cert, &offset, ASN1_V3_DATA) > 0)
    {
        x509_v3_subject_alt_name(cert, offset, x509_ctx);
        x509_v3_basic_constraints(cert, offset, x509_ctx);
        x509_v3_key_usage(cert, offset, x509_ctx);
    }

    offset = end_tbs;   /* skip the rest of v3 data */
    if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) || 
            asn1_signature(cert, &offset, x509_ctx))
        goto end_cert;

    /* Saves a few bytes of memory */
    bi_clear_cache(bi_ctx);
#endif
    ret = X509_OK;
end_cert:
    if (len)
    {
        *len = cert_size;
    }

    if (ret)
    {
#ifdef CONFIG_SSL_FULL_MODE
        char buff[64];
        printf("Error: Invalid X509 ASN.1 file (%s)\n",
                        x509_display_error(ret, buff));
#endif
        x509_free(x509_ctx);
        *ctx = NULL;
    }

    return ret;
}