Exemplo n.º 1
0
/** Compute DH shared secret from our local secret and the peer's public value.
 * We make the leap that the length should be that of the group
 * (see quoted passage at start of ACCEPT_KE).
 */
static void
calc_dh_shared(chunk_t *shared, const chunk_t g
	       , const MP_INT *sec
	       , const struct oakley_group_desc *group)
{
    MP_INT mp_g, mp_shared;
    struct timeval tv0, tv1;
    unsigned long tv_diff;

    gettimeofday(&tv0, NULL);
    n_to_mpz(&mp_g, g.ptr, g.len);
    mpz_init(&mp_shared);
    mpz_powm(&mp_shared, &mp_g, sec, group->modulus);
    mpz_clear(&mp_g);

    *shared = mpz_to_n(&mp_shared, group->bytes);
    mpz_clear(&mp_shared);

    gettimeofday(&tv1, NULL);
    tv_diff=(tv1.tv_sec  - tv0.tv_sec) * 1000000 + (tv1.tv_usec - tv0.tv_usec);
    DBG(DBG_CRYPT, 
    	DBG_log("calc_dh_shared(): time elapsed (%s): %ld usec"
		, enum_show(&oakley_group_names, group->group)
		, tv_diff);
       );
Exemplo n.º 2
0
void calc_ke(struct pluto_crypto_req *r)
{
    MP_INT mp_g;
    MP_INT secret;
    chunk_t gi;
    struct pcr_kenonce *kn = &r->pcr_d.kn;
    const struct oakley_group_desc *group;

    group = lookup_group(kn->oakley_group);

    pluto_crypto_allocchunk(&kn->thespace
			    , &kn->secret
			    , LOCALSECRETSIZE);

    get_rnd_bytes(wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    n_to_mpz(&secret, wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    mpz_init(&mp_g);

    oswcrypto.mod_exp(&mp_g, group->generator, &secret, group->modulus);

    gi = mpz_to_n(&mp_g, group->bytes);

    pluto_crypto_allocchunk(&kn->thespace, &kn->gi, gi.len);

    {
	char *gip = wire_chunk_ptr(kn, &(kn->gi));

	memcpy(gip, gi.ptr, gi.len);
    }

    DBG(DBG_CRYPT,
	DBG_dump("Local DH secret:\n"
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , LOCALSECRETSIZE);
	DBG_dump_chunk("Public DH value sent:\n", gi));

    /* clean up after ourselves */
    mpz_clear(&mp_g);
    mpz_clear(&secret);
    freeanychunk(gi);
}
Exemplo n.º 3
0
chunk_t mpz_to_n2(const MP_INT *mp)
{
	int bytes = (mpz_sizeinbase(mp, 2)+7)/8;

	return mpz_to_n(mp, bytes);
}
Exemplo n.º 4
0
err_t
try_RSA_signature_v2(const u_char hash_val[MAX_DIGEST_LEN]
		     , size_t hash_len
		     , const pb_stream *sig_pbs, struct pubkey *kr
		     , struct state *st)
{
    const u_char *sig_val = sig_pbs->cur;
    size_t sig_len = pbs_left(sig_pbs);
    u_char s[RSA_MAX_OCTETS];	/* for decrypted sig_val */
    u_char *sig;
    unsigned int padlen;
    const struct RSA_public_key *k = &kr->u.rsa;

    if (k == NULL)
	return "1""no key available";	/* failure: no key to use */

    /* decrypt the signature -- reversing RSA_sign_hash */
    if (sig_len != k->k)
    {
        DBG_log("sig_len: %u != k->k: %u"
                , (unsigned int)sig_len, (unsigned int)k->k);
	return "1""SIG length does not match public key length";
    }

    /* actual exponentiation; see PKCS#1 v2.0 5.1 */
    {
	chunk_t temp_s;
	MP_INT c;

	n_to_mpz(&c, sig_val, sig_len);
	oswcrypto.mod_exp(&c, &c, &k->e, &k->n);

	temp_s = mpz_to_n(&c, sig_len);	/* back to octets */
	memcpy(s, temp_s.ptr, sig_len);
	pfree(temp_s.ptr);
	mpz_clear(&c);
    }

    /* check signature contents */
    /* verify padding */
    padlen = sig_len - 3 - (hash_len+der_digestinfo_len);
    /* now check padding */
    sig = s;

    DBG(DBG_CRYPT,
	DBG_dump("v2rsa decrypted SIG1:", sig, sig_len));

    if(sig[0]    != 0x00
       || sig[1] != 0x01
       || sig[padlen+2] != 0x00) {
	return "2""SIG padding does not check out";
    }

    /* skip padding */
    sig += padlen+3;

    /* 2 verify that the has was done with SHA1 */
    if(memcmp(der_digestinfo, sig, der_digestinfo_len)!=0) {
	return "SIG not performed with SHA1";
    }

    sig += der_digestinfo_len;

    DBG(DBG_CRYPT,
	DBG_dump("v2rsa decrypted SIG:", hash_val, hash_len);
	DBG_dump("v2rsa computed hash:", sig, hash_len);
    );
Exemplo n.º 5
0
void calc_ke(struct pluto_crypto_req *r)
{
#ifndef HAVE_LIBNSS
    MP_INT mp_g;
    MP_INT secret;
    chunk_t gi;
#else
    chunk_t  prime;
    chunk_t  base;
    SECKEYDHParams      dhp;
    PK11SlotInfo *slot = NULL;
    SECKEYPrivateKey *privk;
    SECKEYPublicKey   *pubk;
#endif
    struct pcr_kenonce *kn = &r->pcr_d.kn;
    const struct oakley_group_desc *group;

    group = lookup_group(kn->oakley_group);

#ifndef HAVE_LIBNSS
    pluto_crypto_allocchunk(&kn->thespace
			    , &kn->secret
			    , LOCALSECRETSIZE);

    get_rnd_bytes(wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    n_to_mpz(&secret, wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    mpz_init(&mp_g);

#ifdef USE_MODP_RFC5114
    oswcrypto.mod_exp(&mp_g, group->generator, &secret, group->modulus);
#else
    oswcrypto.mod_exp(&mp_g, &groupgenerator, &secret, group->modulus);
#endif

    gi = mpz_to_n(&mp_g, group->bytes);

    pluto_crypto_allocchunk(&kn->thespace, &kn->gi, gi.len);

    {
	char *gip = wire_chunk_ptr(kn, &(kn->gi));

	memcpy(gip, gi.ptr, gi.len);
    }

    DBG(DBG_CRYPT,
	DBG_dump("Local DH secret:\n"
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , LOCALSECRETSIZE);
	DBG_dump_chunk("Public DH value sent:\n", gi));

    /* clean up after ourselves */
    mpz_clear(&mp_g);
    mpz_clear(&secret);
    freeanychunk(gi);
#else

#ifdef USE_MODP_RFC5114
    base  = mpz_to_n2(group->generator);
#else
    base  = mpz_to_n2(&groupgenerator);
#endif
    prime = mpz_to_n2(group->modulus);

    DBG(DBG_CRYPT,DBG_dump_chunk("NSS: Value of Prime:\n", prime));
    DBG(DBG_CRYPT,DBG_dump_chunk("NSS: Value of base:\n", base));

    dhp.prime.data=prime.ptr;
    dhp.prime.len=prime.len;
    dhp.base.data=base.ptr;
    dhp.base.len=base.len;

    slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,osw_return_nss_password_file_info());
    if(!slot) {
	loglog(RC_LOG_SERIOUS, "NSS: slot for DH key gen is NULL");
    }
    PR_ASSERT(slot!=NULL);

    while(1) {
	privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, &dhp, &pubk, PR_FALSE, PR_TRUE, osw_return_nss_password_file_info());
	if(!privk) {
	   loglog(RC_LOG_SERIOUS, "NSS: DH private key creation failed (err %d)", PR_GetError());
	}
	PR_ASSERT(privk!=NULL);

	if( group-> bytes == pubk->u.dh.publicValue.len ) {
	   DBG(DBG_CRYPT, DBG_log("NSS: generated dh priv and pub keys: %d\n", pubk->u.dh.publicValue.len));
	   break;
	} else {
	   DBG(DBG_CRYPT, DBG_log("NSS: generating dh priv and pub keys"));
	   if (privk) SECKEY_DestroyPrivateKey(privk);
	   if (pubk)  SECKEY_DestroyPublicKey(pubk);
	   }
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->secret, sizeof(SECKEYPrivateKey*));
    {
	char *gip = wire_chunk_ptr(kn, &(kn->secret));
	memcpy(gip, &privk, sizeof(SECKEYPrivateKey *));
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->gi, pubk->u.dh.publicValue.len);
    {
	char *gip = wire_chunk_ptr(kn, &(kn->gi));
	memcpy(gip, pubk->u.dh.publicValue.data, pubk->u.dh.publicValue.len);
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->pubk, sizeof(SECKEYPublicKey*));
    {
	char *gip = wire_chunk_ptr(kn, &(kn->pubk));
	memcpy(gip, &pubk, sizeof(SECKEYPublicKey*));
    }

    DBG(DBG_CRYPT,
       DBG_dump("NSS: Local DH secret:\n"
                , wire_chunk_ptr(kn, &(kn->secret))
                , sizeof(SECKEYPrivateKey*));
       DBG_dump("NSS: Public DH value sent(computed in NSS):\n", wire_chunk_ptr(kn, &(kn->gi)),pubk->u.dh.publicValue.len));

    DBG(DBG_CRYPT,
        DBG_dump("NSS: Local DH public value (pointer):\n"
                 , wire_chunk_ptr(kn, &(kn->pubk))
                 , sizeof(SECKEYPublicKey*)));

    /* clean up after ourselves */
    if (slot) {
	PK11_FreeSlot(slot);
    }
    /* if (privk){SECKEY_DestroyPrivateKey(privk);} */
    /* if (pubk){SECKEY_DestroyPublicKey(pubk);} */
    freeanychunk(prime);
    freeanychunk(base);
#endif
}