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; }
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); }
void KeyPair::Keygen() { for(;;) { ecc_make_key(publicKey, privateKey); if (publicKey[0] == DAT_BYTE) break; } hasPrivate = true; }
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); }
/* 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); }
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); }
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; } }
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; }
/* { 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; }
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"); }
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)); }
void Generate_New_Key(){ // Copy over previous epoch's data memcpy(&old_point,¤t_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(¤t_point,current_private,entropy); } // Generate new Y value current_y = (uint8_t) ecc_compress_y_coord(¤t_point); }
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, <c->ecdsa)); rc = (rc == CRYPT_OK); #ifdef DYING rpmltcDumpECDSA(__FUNCTION__, ltc); #endif SPEW(!rc, rc, dig); return rc; }
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; }
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); }
/** 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; }
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; } }
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); }
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 }
/** 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; }
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 (¶ms->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; }