/** Construct cross-certification for the master identity key with * the ntor onion key. Store the sign of the corresponding ed25519 public key * in *<b>sign_out</b>. */ tor_cert_t * make_ntor_onion_key_crosscert(const curve25519_keypair_t *onion_key, const ed25519_public_key_t *master_id_key, time_t now, time_t lifetime, int *sign_out) { tor_cert_t *cert = NULL; ed25519_keypair_t ed_onion_key; if (ed25519_keypair_from_curve25519_keypair(&ed_onion_key, sign_out, onion_key) < 0) goto end; cert = tor_cert_create(&ed_onion_key, CERT_TYPE_ONION_ID, master_id_key, now, lifetime, 0); end: memwipe(&ed_onion_key, 0, sizeof(ed_onion_key)); return cert; }
static void test_crypto_ed25519_fuzz_donna(void *arg) { const unsigned iters = 1024; uint8_t msg[1024]; unsigned i; (void)arg; tt_uint_op(iters, OP_EQ, sizeof(msg)); crypto_rand((char*) msg, sizeof(msg)); /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to * generate keys/sign per iteration. */ for (i = 0; i < iters; ++i) { const int use_donna = i & 1; uint8_t blinding[32]; curve25519_keypair_t ckp; ed25519_keypair_t kp, kp_blind, kp_curve25519; ed25519_public_key_t pk, pk_blind, pk_curve25519; ed25519_signature_t sig, sig_blind; int bit = 0; crypto_rand((char*) blinding, sizeof(blinding)); /* Impl. A: * 1. Generate a keypair. * 2. Blinded the keypair. * 3. Sign a message (unblinded). * 4. Sign a message (blinded). * 5. Generate a curve25519 keypair, and convert it to Ed25519. */ ed25519_set_impl_params(use_donna); tt_int_op(0, OP_EQ, ed25519_keypair_generate(&kp, i&1)); tt_int_op(0, OP_EQ, ed25519_keypair_blind(&kp_blind, &kp, blinding)); tt_int_op(0, OP_EQ, ed25519_sign(&sig, msg, i, &kp)); tt_int_op(0, OP_EQ, ed25519_sign(&sig_blind, msg, i, &kp_blind)); tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ckp, i&1)); tt_int_op(0, OP_EQ, ed25519_keypair_from_curve25519_keypair( &kp_curve25519, &bit, &ckp)); /* Impl. B: * 1. Validate the public key by rederiving it. * 2. Validate the blinded public key by rederiving it. * 3. Validate the unblinded signature (and test a invalid signature). * 4. Validate the blinded signature. * 5. Validate the public key (from Curve25519) by rederiving it. */ ed25519_set_impl_params(!use_donna); tt_int_op(0, OP_EQ, ed25519_public_key_generate(&pk, &kp.seckey)); tt_mem_op(pk.pubkey, OP_EQ, kp.pubkey.pubkey, 32); tt_int_op(0, OP_EQ, ed25519_public_blind(&pk_blind, &kp.pubkey, blinding)); tt_mem_op(pk_blind.pubkey, OP_EQ, kp_blind.pubkey.pubkey, 32); tt_int_op(0, OP_EQ, ed25519_checksig(&sig, msg, i, &pk)); sig.sig[0] ^= 15; tt_int_op(-1, OP_EQ, ed25519_checksig(&sig, msg, sizeof(msg), &pk)); tt_int_op(0, OP_EQ, ed25519_checksig(&sig_blind, msg, i, &pk_blind)); tt_int_op(0, OP_EQ, ed25519_public_key_from_curve25519_public_key( &pk_curve25519, &ckp.pubkey, bit)); tt_mem_op(pk_curve25519.pubkey, OP_EQ, kp_curve25519.pubkey.pubkey, 32); } done: ; }
hs_desc_intro_point_t * hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now, const char *addr, int legacy) { int ret; ed25519_keypair_t auth_kp; hs_desc_intro_point_t *intro_point = NULL; hs_desc_intro_point_t *ip = hs_desc_intro_point_new(); /* For a usable intro point we need at least two link specifiers: One legacy * keyid and one ipv4 */ { tor_addr_t a; tor_addr_make_unspec(&a); link_specifier_t *ls_legacy = link_specifier_new(); link_specifier_t *ls_ip = link_specifier_new(); link_specifier_set_ls_type(ls_legacy, LS_LEGACY_ID); memset(link_specifier_getarray_un_legacy_id(ls_legacy), 'C', link_specifier_getlen_un_legacy_id(ls_legacy)); int family = tor_addr_parse(&a, addr); switch (family) { case AF_INET: link_specifier_set_ls_type(ls_ip, LS_IPV4); link_specifier_set_un_ipv4_addr(ls_ip, tor_addr_to_ipv4h(&a)); link_specifier_set_un_ipv4_port(ls_ip, 9001); break; case AF_INET6: link_specifier_set_ls_type(ls_ip, LS_IPV6); memcpy(link_specifier_getarray_un_ipv6_addr(ls_ip), tor_addr_to_in6_addr8(&a), link_specifier_getlen_un_ipv6_addr(ls_ip)); link_specifier_set_un_ipv6_port(ls_ip, 9001); break; default: /* Stop the test, not supposed to have an error. * Compare with -1 to show the actual family. */ tt_int_op(family, OP_EQ, -1); } smartlist_add(ip->link_specifiers, ls_legacy); smartlist_add(ip->link_specifiers, ls_ip); } ret = ed25519_keypair_generate(&auth_kp, 0); tt_int_op(ret, ==, 0); ip->auth_key_cert = tor_cert_create(signing_kp, CERT_TYPE_AUTH_HS_IP_KEY, &auth_kp.pubkey, now, HS_DESC_CERT_LIFETIME, CERT_FLAG_INCLUDE_SIGNING_KEY); tt_assert(ip->auth_key_cert); if (legacy) { ip->legacy.key = crypto_pk_new(); tt_assert(ip->legacy.key); ret = crypto_pk_generate_key(ip->legacy.key); tt_int_op(ret, ==, 0); ssize_t cert_len = tor_make_rsa_ed25519_crosscert( &signing_kp->pubkey, ip->legacy.key, now + HS_DESC_CERT_LIFETIME, &ip->legacy.cert.encoded); tt_assert(ip->legacy.cert.encoded); tt_u64_op(cert_len, OP_GT, 0); ip->legacy.cert.len = cert_len; } /* Encryption key. */ { int signbit; curve25519_keypair_t curve25519_kp; ed25519_keypair_t ed25519_kp; tor_cert_t *cross_cert; ret = curve25519_keypair_generate(&curve25519_kp, 0); tt_int_op(ret, ==, 0); ed25519_keypair_from_curve25519_keypair(&ed25519_kp, &signbit, &curve25519_kp); cross_cert = tor_cert_create(signing_kp, CERT_TYPE_CROSS_HS_IP_KEYS, &ed25519_kp.pubkey, time(NULL), HS_DESC_CERT_LIFETIME, CERT_FLAG_INCLUDE_SIGNING_KEY); tt_assert(cross_cert); ip->enc_key_cert = cross_cert; } intro_point = ip; done: if (intro_point == NULL) tor_free(ip); return intro_point; }