Beispiel #1
1
int main()
{

    uint8_t a_pub[ECC_BYTES+1];
    uint8_t a_pri[ECC_BYTES];

    uint8_t b_pub[ECC_BYTES+1];
    uint8_t b_pri[ECC_BYTES];

    uint8_t a_secret[ECC_BYTES];
    uint8_t b_secret[ECC_BYTES];

    uint8_t p_signature[ECC_BYTES*2];

    uint8_t a_hash[SHA256_BLOCK_SIZE];
    uint8_t b_hash[SHA256_BLOCK_SIZE];

    SHA256_CTX ctx;

    int errid = 0;
    int i=0;

    /* print ECC_CURVE parameter */
    print_parameter(ECC_CURVE);

    /* make key */
    errid = ecc_make_key(a_pub,a_pri);
    if(errid != 1){
        printf("[ecc_make _key] error!!!");
        return -1;
    }
    printf("A key pair generation completed...\n");


    errid = ecc_make_key(b_pub,b_pri);
    if(errid != 1){
        printf("[ecc_make _key] error!!!");
        return -1;
    }
    printf("B key pair generation completed...\n");

    /* compute shared secret */
    errid = ecdh_shared_secret(b_pub,a_pri,a_secret);
    if(errid != 1){
        printf("[ecdh_sharedS_secret]error!!!");
        return -1;
    }
    printf("A shared_secret generation completed...\n");

    errid = ecdh_shared_secret(a_pub,b_pri,b_secret);
    if(errid != 1){
        printf("[ecdh_sharedS_secret]error!!!");
        return -1;
    }
    printf("B shared_secret generation completed...\n");

    hash_sha256(a_secret,a_hash);
    if(errid != 1){
        printf("[hash_sha256]error!!!");
        return -1;
    }
    printf("A shared_secret hash completed...\n");

    hash_sha256(b_secret,b_hash);
    if(errid != 1){
        printf("[hash_sha256]error!!!");
        return -1;
    }
    printf("B shared_secret hash completed...\n");


    /* sign */
    errid = ecdsa_sign(a_pri,a_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_sign]error!!!");
        return -1;
    }

    /* verify */
    errid = ecdsa_verify(a_pub,a_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_verify]error!!!");
        return -1;
    }else{
        printf("success \n");
    }

    errid = ecdsa_sign(b_pri,b_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_sign]error!!!");
        return -1;
    }

    /* verify */
    errid = ecdsa_verify(b_pub,b_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_verify]error!!!");
        return -1;
    }else{
        printf("success \n");
    }

    return 0;
}
Beispiel #2
0
void bench_eccKeyAgree(void)
{
    ecc_key genKey, genKey2;
    double start, total, each, milliEach;
    int    i;
    const int agreeTimes = 5;
    byte   shared[1024];
    byte   sig[1024];
    byte   digest[32];
    word32 x;

    ecc_make_key(&rng, 32, &genKey);
    ecc_make_key(&rng, 32, &genKey2);

    /* 256 bit */
    start = current_time();

    for(i = 0; i < agreeTimes; i++) {
        x = sizeof(shared);
        ecc_shared_secret(&genKey, &genKey2, shared, &x);
    }

    total = current_time() - start;
    each  = total / agreeTimes;  /* per second  */
    milliEach = each * 1000;   /* millisconds */
    printf("EC-DHE   key agreement   %6.2f milliseconds, avg over %d"
           " iterations\n", milliEach, agreeTimes);

    /* make dummy digest */
    for (i = 0; i < (int)sizeof(digest); i++)
        digest[i] = i;


    start = current_time();

    for(i = 0; i < agreeTimes; i++) {
        x = sizeof(sig);
        ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &genKey);
    }

    total = current_time() - start;
    each  = total / agreeTimes;  /* per second  */
    milliEach = each * 1000;   /* millisconds */
    printf("EC-DSA   sign time       %6.2f milliseconds, avg over %d"
           " iterations\n", milliEach, agreeTimes);

    ecc_free(&genKey2);
    ecc_free(&genKey);
}
Beispiel #3
0
void KeyPair::Keygen() {
	for(;;) {
		ecc_make_key(publicKey, privateKey);
		if (publicKey[0] == DAT_BYTE) break;
	}
	hasPrivate = true;
}
Beispiel #4
0
void bench_eccKeyGen(void)
{
    ecc_key genKey;
    double start, total, each, milliEach;
    int    i, ret;
  
    ret = InitRng(&rng);
    if (ret < 0) {
        printf("InitRNG failed\n");
        return;
    }
    /* 256 bit */ 
    start = current_time(1);

    for(i = 0; i < genTimes; i++) {
        ecc_make_key(&rng, 32, &genKey);
        ecc_free(&genKey);
    }

    total = current_time(0) - start;
    each  = total / genTimes;  /* per second  */
    milliEach = each * 1000;   /* millisconds */
    printf("\n");
    printf("ECC  256 key generation  %6.3f milliseconds, avg over %d"
           " iterations\n", milliEach, genTimes);
}
Beispiel #5
0
/* ECC DHE Make key */
int CRYPT_ECC_DHE_KeyMake(CRYPT_ECC_CTX* ecc, CRYPT_RNG_CTX* rng, int keySz)
{
    if (ecc == NULL || rng == NULL)
        return BAD_FUNC_ARG;

    return ecc_make_key((RNG*)rng, keySz, (ecc_key*)ecc->holder);
}
Beispiel #6
0
C4Err ECC_Generate(ECC_ContextRef  ctx, size_t keysize )
{
    C4Err   err = kC4Err_NoErr;
    
    validateECCContext(ctx);
    
    if(keysize == 414)
    {
        ctx->isBLCurve = true;
        err = ecc_bl_make_key(NULL, find_prng("sprng"),  (int) keysize/8, &ctx->key);CKERR;
        
    }
    else
    {
        ctx->isBLCurve = false;
        err = ecc_make_key(NULL, find_prng("sprng"),   (int)keysize/8, &ctx->key);CKERR;
    }
    
    ctx->isInited = true;
    
done:
    
    return (err);
    
}
Beispiel #7
0
static void make_pk(struct test_data *data)
{
	if (!ecc_make_key(data->local_pk, data->local_sk)) {
		tester_print("Failed to general local ECDH keypair");
		tester_setup_failed();
		return;
	}
}
Beispiel #8
0
int TestPK(prng_state * PRNG)
{
    int     err = CRYPT_OK;
    int     i;
    
    ecc_key     eccKey;
    uint8_t        PT[PTsize];
    uint8_t        CT[256];
    uint8_t        DT[PTsize];
    unsigned long   z,w;
    
 
    uint8_t        PrivKey[256];
    uint8_t        PubKey[256];
   
 //   uint8_t             tempBuf[256];
 //   unsigned long       tempLen;

    
    printf("\nTesting PK\n");
   
    // fill PT
    for(i = 0; i< PTsize; i++) PT[i]= i;
      
    DO( ecc_make_key(PRNG, find_prng ("yarrow"),  384/8, &eccKey));
  
    z = sizeof(PubKey);
     DO( ecc_export(PubKey, &z, PK_PUBLIC, &eccKey));
    printf("\tPub Key (%ld bytes)\n", z);
    dumpHex(PubKey,  z, 8);
     
    z = sizeof(PrivKey);
   DO( ecc_export(PrivKey, &z, PK_PRIVATE, &eccKey));
    printf("\n\tPriv Key (%ld bytes)\n", z);
    dumpHex(PrivKey,  z, 8);
     
    z = 384; 
    DO( ecc_encrypt_key(PT, PTsize, CT, &z, 
                        PRNG, 
                        find_prng("yarrow"), 
                        find_hash("sha256"),
                        &eccKey));
 
    printf("\n\tEncrypted message (%ld bytes)\n", z);
    dumpHex(CT,  z, 0);
    
    DO( ecc_decrypt_key(CT, z, DT, &w, &eccKey));
      
    /* check against know-answer */
    DO(compareResults( DT, PT, PTsize , kResultFormat_Byte, "ECC Decrypt"));
    printf("\n\tDecrypted OK\n");
    dumpHex(DT,  w, 0);
 
      ecc_free(&eccKey);
    
    return err;
    
}
Beispiel #9
0
/* { generateKeys start } */
int generateKeys(prng_state* prng){
	ecc_key key;
	int err;
	if ((err = ecc_make_key(prng,find_prng("fortuna"),24,&key))!= CRYPT_OK) {
		printf("Error setting up , %s\n", error_to_string(err));
		exit(EXIT_FAILURE);
	}
	saveKeyToFile(&key, "private.key", PK_PRIVATE);
	saveKeyToFile(&key, "public.key", PK_PUBLIC);
	return 0;
}
Beispiel #10
0
static void test_multi(void)
{
	uint8_t public1[64], public2[64];
	uint8_t private1[32], private2[32];
	uint8_t shared1[32], shared2[32];
	int i;

	printf("Testing %u random private key pairs\n", PAIR_COUNT);

	for (i = 0; i < PAIR_COUNT; i++) {
		printf(".");
		fflush(stdout);

		ecc_make_key(public1, private1);
		ecc_make_key(public2, private2);

		ecdh_shared_secret(public1, private2, shared1);
		ecdh_shared_secret(public2, private1, shared2);

		if (memcmp(shared1, shared2, sizeof(shared1)) != 0) {
			printf("Shared secrets are not identical!\n");
			printf("Shared secret 1 = ");
			vli_print(shared1, sizeof(shared1));
			printf("\n");
			printf("Shared secret 2 = ");
			vli_print(shared2, sizeof(shared2));
			printf("\n");
			printf("Private key 1 = ");
			vli_print(private1, sizeof(private1));
			printf("\n");
			printf("Private key 2 = ");
			vli_print(private2, sizeof(private2));
			printf("\n");
			g_assert_not_reached();
		}
	}

	printf("\n");
}
Beispiel #11
0
static void cmd_le_read_local_pk256(struct bt_le *hci,
						const void *data, uint8_t size)
{
	struct bt_hci_evt_le_read_local_pk256_complete evt;

	cmd_status(hci, BT_HCI_ERR_SUCCESS, BT_HCI_CMD_LE_READ_LOCAL_PK256);

	evt.status = BT_HCI_ERR_SUCCESS;
	ecc_make_key(evt.local_pk256, hci->le_local_sk256);

	if (hci->le_event_mask[0] & 0x80)
		le_meta_event(hci, BT_HCI_EVT_LE_READ_LOCAL_PK256_COMPLETE,
							&evt, sizeof(evt));
}
Beispiel #12
0
void Generate_New_Key(){
    
    // Copy over previous epoch's data
    memcpy(&old_point,&current_point,sizeof(EccPoint));
    memcpy(old_private,current_private,N_DATA_SYMBOLS * sizeof(uint32_t));
    old_y = current_y;

    // Generate new epoch's puclig and private keys
    uint32_t entropy[N_DATA_SYMBOLS];
    int rc = 0;
    while(!rc) {
        Fill_Random_Bytes((uint8_t *) &entropy,N_DATA_SYMBOLS * sizeof(uint32_t));
        rc = ecc_make_key(&current_point,current_private,entropy);
    }

    // Generate new Y value
    current_y = (uint8_t) ecc_compress_y_coord(&current_point);
}
Beispiel #13
0
static
int rpmltcGenerateECDSA(pgpDig dig)
	/*@*/
{
    rpmltc ltc = dig->impl;
    int rc;

if (ltc->nbits == 0) ltc->nbits = 256;	/* XXX FIXME */

    rc = rpmltcErr(ltc, "ecc_make_key",
		ecc_make_key(&yarrow_prng, find_prng ("yarrow"),
			ltc->nbits/8, &ltc->ecdsa));
    rc = (rc == CRYPT_OK);

#ifdef	DYING
rpmltcDumpECDSA(__FUNCTION__, ltc);
#endif

SPEW(!rc, rc, dig);
    return rc;
}
Beispiel #14
0
int main(int argc, char **argv)
{
    unsigned l_num = 1;
    unsigned i, j;
    
    if(argc > 1)
    {
        l_num = strtoul(argv[1], NULL, 10);
    }
    
    randfd = open("/dev/urandom", O_RDONLY);
    if(randfd == -1)
    {
        printf("No access to urandom\n");
        return -1;
    }
    
    uint32_t l_private[NUM_ECC_DIGITS];
    EccPoint l_public;
    
    for(i=0; i<l_num; ++i)
    {
        getRandomBytes((char *)l_private, NUM_ECC_DIGITS * sizeof(uint32_t));
        ecc_make_key(&l_public, l_private, l_private);
        
        printf("uint32_t private_%u[NUM_ECC_DIGITS] = {", i);
        vli_print(l_private);
        printf("};\n");

        printf("EccPoint public_%u = {\n", i);
        printf("    {");
        vli_print(l_public.x);
        printf("},\n");
        printf("    {");
        vli_print(l_public.y);
        printf("}};\n\n");
    }
    
    return 0;
}
Beispiel #15
0
void bench_eccKeyGen(void)
{
    ecc_key genKey;
    double start, total, each, milliEach;
    int    i;
    const int genTimes = 5;
  
    /* 256 bit */ 
    start = current_time(1);

    for(i = 0; i < genTimes; i++) {
        ecc_make_key(&rng, 32, &genKey);
        ecc_free(&genKey);
    }

    total = current_time(0) - start;
    each  = total / genTimes;  /* per second  */
    milliEach = each * 1000;   /* millisconds */
    printf("\n");
    printf("ECC  256 key generation  %6.2f milliseconds, avg over %d" 
           " iterations\n", milliEach, genTimes);
}
Beispiel #16
0
/** Generates and returns a new (privkey, pubkey) ECDH key pair.
 * Keys are represented as Lua strings, the private one under a libtomcrypt
 * proprietary format, the public one under X9.63 format. */
static int lnew( lua_State *L) {
    prng_state prng;
    int prng_initialized = 0;
    ecc_key key;

    int idx = find_prng("fortuna");
    if( -1 == idx) goto failure;
    if( CRYPT_OK != rng_make_prng( ENTROPY, idx, & prng, NULL)) goto failure;
    prng_initialized=1;

    /* Generate the 512 bits ECC key in privkey. */
    if( CRYPT_OK != ecc_make_key( & prng, idx, 64, & key)) goto failure;

    /* Buffer will hold both the private and public key transiently,
     * until each of them is transformed into a Lua string. */
    unsigned char buff [BUFF_SIZE];
    unsigned long buff_len = BUFF_SIZE;

    /* Push the string representation of privkey (tomcrypt's proprietary format). */
    if( CRYPT_OK != ecc_export( buff, & buff_len, PK_PRIVATE, & key)) goto failure;
    lua_pushlstring( L, (const char*) buff, buff_len);

    /* Push the string representation of pubkey (ANSI X9.63 format, which only
     * supports public keys. This is the format expected by the server). */
    if( CRYPT_OK != ecc_ansi_x963_export( & key, buff, & buff_len)) goto failure;
    lua_pushlstring( L, (const char *) buff, buff_len);

    fortuna_done( & prng);
    return 2;

    failure:
    /* TODO: release resources */
    if( prng_initialized) fortuna_done( & prng);
    lua_pushnil( L);
    lua_pushstring( L, "error");
    return 2;
}
Beispiel #17
0
static void test_le_generate_dhkey(const void *test_data)
{
	struct user_data *user = tester_get_data();
	struct bt_hci_cmd_le_generate_dhkey cmd;
	struct le_keys *keys = (void *)test_data;

	ecc_make_key(cmd.remote_pk256, keys->remote_sk);

	/* Unregister handler for META event */
	bt_hci_unregister(user->hci_ut, 1);

	bt_hci_register(user->hci_ut, BT_HCI_EVT_LE_META_EVENT,
				test_le_generate_dhkey_complete, keys,
				NULL);

	if (!bt_hci_send(user->hci_ut, BT_HCI_CMD_LE_GENERATE_DHKEY, &cmd,
				sizeof(cmd), test_le_generate_dhkey_status,
				NULL, NULL)) {
		tester_warn("Failed to send HCI LE Encrypt command");
		tester_test_failed();
		return;
	}

}
Beispiel #18
0
void bench_eccKeyAgree(void)
{
    ecc_key genKey, genKey2;
    double start, total, each, milliEach;
    int    i, ret;
    byte   shared[1024];
    byte   sig[1024];
    byte   digest[32];
    word32 x = 0;
 
    ecc_init(&genKey);
    ecc_init(&genKey2);

    ret = InitRng(&rng);
    if (ret < 0) {
        printf("InitRNG failed\n");
        return;
    }

    ret = ecc_make_key(&rng, 32, &genKey);
    if (ret != 0) {
        printf("ecc_make_key failed\n");
        return;
    }
    ret = ecc_make_key(&rng, 32, &genKey2);
    if (ret != 0) {
        printf("ecc_make_key failed\n");
        return;
    }

    /* 256 bit */ 
    start = current_time(1);

    for(i = 0; i < agreeTimes; i++) {
        x = sizeof(shared);
        ret = ecc_shared_secret(&genKey, &genKey2, shared, &x);
        if (ret != 0) {
            printf("ecc_shared_secret failed\n");
            return; 
        }
    }

    total = current_time(0) - start;
    each  = total / agreeTimes;  /* per second  */
    milliEach = each * 1000;   /* millisconds */
    printf("EC-DHE   key agreement   %6.3f milliseconds, avg over %d"
           " iterations\n", milliEach, agreeTimes);

    /* make dummy digest */
    for (i = 0; i < (int)sizeof(digest); i++)
        digest[i] = (byte)i;


    start = current_time(1);

    for(i = 0; i < agreeTimes; i++) {
        x = sizeof(sig);
        ret = ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &genKey);
        if (ret != 0) {
            printf("ecc_sign_hash failed\n");
            return; 
        }
    }

    total = current_time(0) - start;
    each  = total / agreeTimes;  /* per second  */
    milliEach = each * 1000;   /* millisconds */
    printf("EC-DSA   sign   time     %6.3f milliseconds, avg over %d"
           " iterations\n", milliEach, agreeTimes);

    start = current_time(1);

    for(i = 0; i < agreeTimes; i++) {
        int verify = 0;
        ret = ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &genKey);
        if (ret != 0) {
            printf("ecc_verify_hash failed\n");
            return; 
        }
    }

    total = current_time(0) - start;
    each  = total / agreeTimes;  /* per second  */
    milliEach = each * 1000;     /* millisconds */
    printf("EC-DSA   verify time     %6.3f milliseconds, avg over %d"
           " iterations\n", milliEach, agreeTimes);

    ecc_free(&genKey2);
    ecc_free(&genKey);
}
Beispiel #19
0
int ecc_tests (void)
{
  unsigned char buf[4][4096];
  unsigned long x, y, z, s;
  int           stat, stat2;
  ecc_key usera, userb, pubKey, privKey;
	
  DO(ecc_test ());
  DO(ecc_test ());
  DO(ecc_test ());
  DO(ecc_test ());
  DO(ecc_test ());

  for (s = 0; s < (sizeof(sizes)/sizeof(sizes[0])); s++) {
     /* make up two keys */
     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));
     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb));

     /* make the shared secret */
     x = sizeof(buf[0]);
     DO(ecc_shared_secret (&usera, &userb, buf[0], &x));

     y = sizeof(buf[1]);
     DO(ecc_shared_secret (&userb, &usera, buf[1], &y));

     if (y != x) {
       fprintf(stderr, "ecc Shared keys are not same size.");
       return 1;
     }

     if (memcmp (buf[0], buf[1], x)) {
       fprintf(stderr, "ecc Shared keys not same contents.");
       return 1;
     }

     /* now export userb */
     y = sizeof(buf[0]);
     DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
     ecc_free (&userb);

     /* import and make the shared secret again */
     DO(ecc_import (buf[1], y, &userb));

     z = sizeof(buf[0]);
     DO(ecc_shared_secret (&usera, &userb, buf[2], &z));

     if (z != x) {
       fprintf(stderr, "failed.  Size don't match?");
       return 1;
     }
     if (memcmp (buf[0], buf[2], x)) {
       fprintf(stderr, "Failed.  Contents didn't match.");
       return 1;
     }

     /* export with ANSI X9.63 */
     y = sizeof(buf[1]);
     DO(ecc_ansi_x963_export(&userb, buf[1], &y));
     ecc_free (&userb);

     /* now import the ANSI key */
     DO(ecc_ansi_x963_import(buf[1], y, &userb));

     /* shared secret */
     z = sizeof(buf[0]);
     DO(ecc_shared_secret (&usera, &userb, buf[2], &z));

     if (z != x) {
       fprintf(stderr, "failed.  Size don't match?");
       return 1;
     }
     if (memcmp (buf[0], buf[2], x)) {
       fprintf(stderr, "Failed.  Contents didn't match.");
       return 1;
     }

     ecc_free (&usera);
     ecc_free (&userb);

     /* test encrypt_key */
     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));

     /* export key */
     x = sizeof(buf[0]);
     DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera));
     DO(ecc_import(buf[0], x, &pubKey));
     x = sizeof(buf[0]);
     DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera));
     DO(ecc_import(buf[0], x, &privKey));

     for (x = 0; x < 32; x++) {
        buf[0][x] = x;
     }
     y = sizeof (buf[1]);
     DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey));
     zeromem (buf[0], sizeof (buf[0]));
     x = sizeof (buf[0]);
     DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey));
     if (x != 32) {
       fprintf(stderr, "Failed (length)");
       return 1;
     }
     for (x = 0; x < 32; x++) {
        if (buf[0][x] != x) {
           fprintf(stderr, "Failed (contents)");
           return 1;
        }
     }
     /* test sign_hash */
     for (x = 0; x < 16; x++) {
        buf[0][x] = x;
     }
     x = sizeof (buf[1]);
     DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey));
     DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey));
     buf[0][0] ^= 1;
     DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey));
     if (!(stat == 1 && stat2 == 0)) { 
        fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2);
        return 1;
     }
     ecc_free (&usera); 
     ecc_free (&pubKey);
     ecc_free (&privKey);
  }
#ifdef LTC_ECC_SHAMIR
  return ecc_test_shamir();
#else
  return 0;
#endif
}
Beispiel #20
0
/**
  Sign a message digest
  @param in        The message digest to sign
  @param inlen     The length of the digest
  @param out       [out] The destination for the signature
  @param outlen    [in/out] The max size and resulting size of the signature
  @param prng      An active PRNG state
  @param wprng     The index of the PRNG you wish to use
  @param key       A private ECC key
  @return CRYPT_OK if successful
*/
int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
                        unsigned char *out, unsigned long *outlen, 
                        prng_state *prng, int wprng, ecc_key *key)
{
   ecc_key       pubkey;
   void          *r, *s, *e, *p;
   int           err;

   LTC_ARGCHK(in     != NULL);
   LTC_ARGCHK(out    != NULL);
   LTC_ARGCHK(outlen != NULL);
   LTC_ARGCHK(key    != NULL);

   /* is this a private key? */
   if (key->type != PK_PRIVATE) {
      return CRYPT_PK_NOT_PRIVATE;
   }
   
   /* is the IDX valid ?  */
   if (ltc_ecc_is_valid_idx(key->idx) != 1) {
      return CRYPT_PK_INVALID_TYPE;
   }
   
   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
      return err;
   }

   /* get the hash and load it as a bignum into 'e' */
   /* init the bignums */
   if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { 
      ecc_free(&pubkey);
      goto LBL_ERR;
   }
   if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 16)) != CRYPT_OK)        { goto error; }
   if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK)          { goto error; }

   /* make up a key and export the public copy */
   for (;;) {
      if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
         return err;
      }

      /* find r = x1 mod n */
      if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK)                 { goto error; }

      if (mp_iszero(r)) {
         ecc_free(&pubkey);
      } else { 
        /* find s = (e + xr)/k */
        if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK)            { goto error; } /* k = 1/k */
        if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK)                  { goto error; } /* s = xr */
        if ((err = mp_add(e, s, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */
        if ((err = mp_mod(s, p, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */
        if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK)                { goto error; } /* s = (e + xr)/k */

        if (mp_iszero(s)) {
           ecc_free(&pubkey);
        } else {
           break;
        }
      }
   }

   /* store as SEQUENCE { r, s -- integer } */
   err = der_encode_sequence_multi(out, outlen,
                             LTC_ASN1_INTEGER, 1UL, r,
                             LTC_ASN1_INTEGER, 1UL, s,
                             LTC_ASN1_EOL, 0UL, NULL);
   goto LBL_ERR;
error:
LBL_ERR:
   mp_clear_multi(r, s, p, e, NULL);
   ecc_free(&pubkey);

   return err;   
}
Beispiel #21
0
Datei: pk.c Projekt: intgr/gnutls
static int
wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo,
                                unsigned int level /*bits */ ,
                                gnutls_pk_params_st * params)
{
  int ret;
  unsigned int i, q_bits;

  memset(params, 0, sizeof(*params));

  switch (algo)
    {

    case GNUTLS_PK_DSA:
      {
        struct dsa_public_key pub;
        struct dsa_private_key priv;

        dsa_public_key_init (&pub);
        dsa_private_key_init (&priv);

        /* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
         * but we do NIST DSA here */
        if (level <= 1024)
          q_bits = 160;
        else
          q_bits = 256;

        ret =
          dsa_generate_keypair (&pub, &priv, NULL,
                                rnd_func, NULL, NULL, level, q_bits);
        if (ret != 1)
          {
            gnutls_assert ();
            ret = GNUTLS_E_INTERNAL_ERROR;
            goto dsa_fail;
          }

        params->params_nr = 0;
        for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like (&pub.p);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto dsa_fail;
              }
            params->params_nr++;
          }

        ret = 0;
        _gnutls_mpi_set (params->params[0], pub.p);
        _gnutls_mpi_set (params->params[1], pub.q);
        _gnutls_mpi_set (params->params[2], pub.g);
        _gnutls_mpi_set (params->params[3], pub.y);
        _gnutls_mpi_set (params->params[4], priv.x);

dsa_fail:
        dsa_private_key_clear (&priv);
        dsa_public_key_clear (&pub);

        if (ret < 0)
          goto fail;

        break;
      }
    case GNUTLS_PK_RSA:
      {
        struct rsa_public_key pub;
        struct rsa_private_key priv;

        rsa_public_key_init (&pub);
        rsa_private_key_init (&priv);

        _gnutls_mpi_set_ui (&pub.e, 65537);

        ret =
          rsa_generate_keypair (&pub, &priv, NULL,
                                rnd_func, NULL, NULL, level, 0);
        if (ret != 1)
          {
            gnutls_assert ();
            ret = GNUTLS_E_INTERNAL_ERROR;
            goto rsa_fail;
          }

        params->params_nr = 0;
        for (i = 0; i < RSA_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like (&pub.n);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto rsa_fail;
              }
            params->params_nr++;

          }
          
        ret = 0;

        _gnutls_mpi_set (params->params[0], pub.n);
        _gnutls_mpi_set (params->params[1], pub.e);
        _gnutls_mpi_set (params->params[2], priv.d);
        _gnutls_mpi_set (params->params[3], priv.p);
        _gnutls_mpi_set (params->params[4], priv.q);
        _gnutls_mpi_set (params->params[5], priv.c);
        _gnutls_mpi_set (params->params[6], priv.a);
        _gnutls_mpi_set (params->params[7], priv.b);

rsa_fail:
        rsa_private_key_clear (&priv);
        rsa_public_key_clear (&pub);

        if (ret < 0)
          goto fail;

        break;
      }
    case GNUTLS_PK_EC:
      {
        ecc_key key;
        ecc_set_type tls_ecc_set;
        const gnutls_ecc_curve_entry_st *st;

        st = _gnutls_ecc_curve_get_params(level);
        if (st == NULL)
          return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
        
        tls_ecc_set.size = st->size;
        tls_ecc_set.prime = st->prime;
        tls_ecc_set.order = st->order;
        tls_ecc_set.Gx = st->Gx;
        tls_ecc_set.Gy = st->Gy;
        tls_ecc_set.A = st->A;
        tls_ecc_set.B = st->B;

        ret = ecc_make_key(NULL, rnd_func, &key, &tls_ecc_set, st->id);
        if (ret != 0)
          return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

        params->params_nr = 0;
        for (i = 0; i < ECC_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like(&key.prime);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto ecc_fail;
              }
            params->params_nr++;
          }
        params->flags = level;

        mpz_set(TOMPZ(params->params[ECC_PRIME]), key.prime);
        mpz_set(TOMPZ(params->params[ECC_ORDER]), key.order);
        mpz_set(TOMPZ(params->params[ECC_A]), key.A);
        mpz_set(TOMPZ(params->params[ECC_B]), key.B);
        mpz_set(TOMPZ(params->params[ECC_GX]), key.Gx);
        mpz_set(TOMPZ(params->params[ECC_GY]), key.Gy);
        mpz_set(TOMPZ(params->params[ECC_X]), key.pubkey.x);
        mpz_set(TOMPZ(params->params[ECC_Y]), key.pubkey.y);
        mpz_set(TOMPZ(params->params[ECC_K]), key.k);
        
ecc_fail:
        ecc_free(&key);
        
        if (ret < 0)
          goto fail;

        break;
      }
    default:
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  return 0;

fail:

  for (i = 0; i < params->params_nr; i++)
    {
      _gnutls_mpi_release (&params->params[i]);
    }
  params->params_nr = 0;

  return ret;
}
/**
  Encrypt a symmetric key with ECC 
  @param in         The symmetric key you want to encrypt
  @param inlen      The length of the key to encrypt (octets)
  @param out        [out] The destination for the ciphertext
  @param outlen     [in/out] The max size and resulting size of the ciphertext
  @param prng       An active PRNG state
  @param wprng      The index of the PRNG you wish to use 
  @param hash       The index of the hash you want to use 
  @param key        The ECC key you want to encrypt to
  @return CRYPT_OK if successful
*/
int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen,
                          unsigned char *out,  unsigned long *outlen, 
                          prng_state *prng, int wprng, int hash, 
                          ecc_key *key)
{
    unsigned char *pub_expt, *ecc_shared, *skey;
    ecc_key        pubkey;
    unsigned long  x, y, pubkeysize;
    int            err;

    LTC_ARGCHK(in      != NULL);
    LTC_ARGCHK(out     != NULL);
    LTC_ARGCHK(outlen  != NULL);
    LTC_ARGCHK(key     != NULL);

    /* check that wprng/cipher/hash are not invalid */
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
       return err;
    }

    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
       return err;
    }

    if (inlen > hash_descriptor[hash].hashsize) {
       return CRYPT_INVALID_HASH;
    }

    /* make a random key and export the public copy */
    if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
       return err;
    }

    pub_expt   = XMALLOC(ECC_BUF_SIZE);
    ecc_shared = XMALLOC(ECC_BUF_SIZE);
    skey       = XMALLOC(MAXBLOCKSIZE);
    if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
       if (pub_expt != NULL) {
          XFREE(pub_expt);
       }
       if (ecc_shared != NULL) {
          XFREE(ecc_shared);
       }
       if (skey != NULL) {
          XFREE(skey);
       }
       ecc_free(&pubkey);
       return CRYPT_MEM;
    }

    pubkeysize = ECC_BUF_SIZE;
    if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
       ecc_free(&pubkey);
       goto LBL_ERR;
    }
    
    /* make random key */
    x        = ECC_BUF_SIZE;
    if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
       ecc_free(&pubkey);
       goto LBL_ERR;
    }
    ecc_free(&pubkey);
    y = MAXBLOCKSIZE;
    if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
       goto LBL_ERR;
    }
    
    /* Encrypt key */
    for (x = 0; x < inlen; x++) {
      skey[x] ^= in[x];
    }

    err = der_encode_sequence_multi(out, outlen,
                                    LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID,
                                    LTC_ASN1_OCTET_STRING,       pubkeysize,                     pub_expt,
                                    LTC_ASN1_OCTET_STRING,       inlen,                          skey,
                                    LTC_ASN1_EOL,                0UL,                            NULL);

LBL_ERR:
#ifdef LTC_CLEAN_STACK
    /* clean up */
    zeromem(pub_expt,   ECC_BUF_SIZE);
    zeromem(ecc_shared, ECC_BUF_SIZE);
    zeromem(skey,       MAXBLOCKSIZE);
#endif

    XFREE(skey);
    XFREE(ecc_shared);
    XFREE(pub_expt);

    return err;
}