Ejemplo n.º 1
0
/*
 * Processing FOR KE values.
 */
void
unpack_KE(struct state *st
	  , struct pluto_crypto_req *r
	  , chunk_t *g)
{
    struct pcr_kenonce *kn = &r->pcr_d.kn;

    if (!st->st_sec_in_use)
    {
	st->st_sec_in_use = TRUE;
	freeanychunk(*g);	/* happens in odd error cases */

	clonetochunk(*g, wire_chunk_ptr(kn, &(kn->gi))
		     , kn->gi.len, "saved gi value");
#ifdef HAVE_LIBNSS
	DBG(DBG_CRYPT, DBG_log("saving DH priv (local secret) and pub key into state struc"));
	clonetochunk(st->st_sec_chunk
		     , wire_chunk_ptr(kn, &(kn->secret))
		     , kn->secret.len, "pointer to DH private key (secret)");

	clonetochunk(st->pubk
		     , wire_chunk_ptr(kn, &(kn->pubk))
		     , kn->pubk.len, "pointer to DH public key");
#else
	n_to_mpz(&st->st_sec
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , kn->secret.len);
	clonetochunk(st->st_sec_chunk
		     , wire_chunk_ptr(kn, &(kn->secret))
		     , kn->secret.len, "long term secret");
#endif
    }
}
Ejemplo n.º 2
0
void calc_nonce(struct pluto_crypto_req *r)
{
  struct pcr_kenonce *kn = &r->pcr_d.kn;

  pluto_crypto_allocchunk(&kn->thespace, &kn->n, DEFAULT_NONCE_SIZE);
  get_rnd_bytes(wire_chunk_ptr(kn, &(kn->n)), DEFAULT_NONCE_SIZE);

  DBG(DBG_CRYPT,
      DBG_dump("Generated nonce:\n"
	       , wire_chunk_ptr(kn, &(kn->n))
	       , DEFAULT_NONCE_SIZE));
}
Ejemplo n.º 3
0
void unpack_nonce(chunk_t *n, struct pluto_crypto_req *r)
{
	struct pcr_kenonce *kn = &r->pcr_d.kn;

	freeanychunk(*n);
	clonetochunk(*n, wire_chunk_ptr(kn, &(kn->n)),
		     DEFAULT_NONCE_SIZE, "initiator nonce");
}
Ejemplo n.º 4
0
void finish_dh_secret(struct state *st,
		      struct pluto_crypto_req *r)
{
    struct pcr_skeyid_r *dhr = &r->pcr_d.dhr;

    clonetochunk(st->st_shared,   wire_chunk_ptr(dhr, &(dhr->shared))
		 , dhr->shared.len,   "calculated shared secret");
}
Ejemplo n.º 5
0
void finish_dh_secretiv(struct state *st,
			struct pluto_crypto_req *r)
{
    struct pcr_skeyid_r *dhr = &r->pcr_d.dhr;

    clonetochunk(st->st_shared,   wire_chunk_ptr(dhr, &(dhr->shared))
		 , dhr->shared.len,   "calculated shared secret");
    clonetochunk(st->st_skeyid,   wire_chunk_ptr(dhr, &(dhr->skeyid))
		 , dhr->skeyid.len,   "calculated skeyid secret");
    clonetochunk(st->st_skeyid_d, wire_chunk_ptr(dhr, &(dhr->skeyid_d))
		 , dhr->skeyid_d.len, "calculated skeyid_d secret");
    clonetochunk(st->st_skeyid_a, wire_chunk_ptr(dhr, &(dhr->skeyid_a))
		 , dhr->skeyid_a.len, "calculated skeyid_a secret");
    clonetochunk(st->st_skeyid_e, wire_chunk_ptr(dhr, &(dhr->skeyid_e))
		 , dhr->skeyid_e.len, "calculated skeyid_a secret");
    clonetochunk(st->st_enc_key, wire_chunk_ptr(dhr, &(dhr->enc_key))
		 , dhr->enc_key.len, "calculated key for phase 1");

    passert(dhr->new_iv.len <= MAX_DIGEST_LEN);
    passert(dhr->new_iv.len > 0);
    memcpy(st->st_new_iv, wire_chunk_ptr(dhr, &(dhr->new_iv)),dhr->new_iv.len);
    st->st_new_iv_len = dhr->new_iv.len;

    st->hidden_variables.st_skeyid_calculated = TRUE;
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
0
/*
 * Processing FOR KE values.
 */
void
unpack_KE(struct state *st
	  , struct pluto_crypto_req *r
	  , chunk_t *g)
{
    struct pcr_kenonce *kn = &r->pcr_d.kn;

    if (!st->st_sec_in_use)
    {
	st->st_sec_in_use = TRUE;
	freeanychunk(*g);	/* happens in odd error cases */
	
	clonetochunk(*g, wire_chunk_ptr(kn, &(kn->gi))
		     , kn->gi.len, "saved gi value");

	n_to_mpz(&st->st_sec
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , kn->secret.len);
	clonetochunk(st->st_sec_chunk
		     , wire_chunk_ptr(kn, &(kn->secret))
		     , kn->secret.len, "long term secret");
    }
}
Ejemplo n.º 8
0
/*******************************************************************************
函数名称: calc_ke
功能描述: 当模长度是1024时,可以使用硬件来加速模幂运算
输入参数: 
输出参数: 无
返 回 值: 无
--------------------------------------------------------------------------------
最近一次修改记录 :
修改作者: 李	志
修改目的: 性能优化
修改日期: 2011-1-15
*******************************************************************************/
void calc_ke(struct pluto_crypto_req *r)
{
    s32 ret = -1; 
    const struct oakley_group_desc *group;
    chunk_t gi;
    
    struct pcr_kenonce *kn = &r->pcr_d.kn;

    group = lookup_group(kn->oakley_group);
    pluto_crypto_allocchunk(&kn->thespace, &kn->secret, LOCALSECRETSIZE);
    
    get_rnd_bytes(wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

	if(OAKLEY_GROUP_MODP1024 == kn->oakley_group && (!g_ipsec_device_is_dpx))
	{
		/*由于硬件只支持1024和512位的模运算,而ipsec最低使用768位的模运算,故只有1024位时才可以使用硬件计算*/
		chunk_t secret_chunk;

        IPSEC_DEBUG(DBG_CRYPT, IPSEC_dbg("hardware calc_ke mod exp, group:%d\n", kn->oakley_group););
Ejemplo n.º 9
0
void finish_dh_v2(struct state *st,
		  struct pluto_crypto_req *r)
{
    struct pcr_skeycalc_v2 *dhv2 = &r->pcr_d.dhv2;

    clonetochunk(st->st_shared,   wire_chunk_ptr(dhv2, &(dhv2->shared))
		 , dhv2->shared.len,   "calculated shared secret");
    clonetochunk(st->st_skey_d,   wire_chunk_ptr(dhv2, &(dhv2->skeyid_d))
		 , dhv2->skeyid_d.len,   "calculated skeyid secret");
    clonetochunk(st->st_skey_ai, wire_chunk_ptr(dhv2, &(dhv2->skeyid_ai))
		 , dhv2->skeyid_ai.len, "calculated skeyid_ai secret");
    clonetochunk(st->st_skey_ar, wire_chunk_ptr(dhv2, &(dhv2->skeyid_ar))
		 , dhv2->skeyid_ar.len, "calculated skeyid_ar secret");
    clonetochunk(st->st_skey_pi, wire_chunk_ptr(dhv2, &(dhv2->skeyid_pi))
		 , dhv2->skeyid_pi.len, "calculated skeyid_pi secret");
    clonetochunk(st->st_skey_pr, wire_chunk_ptr(dhv2, &(dhv2->skeyid_pr))
		 , dhv2->skeyid_pr.len, "calculated skeyid_pr secret");
    clonetochunk(st->st_skey_ei, wire_chunk_ptr(dhv2, &(dhv2->skeyid_ei))
		 , dhv2->skeyid_ei.len, "calculated skeyid_ei secret");
    clonetochunk(st->st_skey_er, wire_chunk_ptr(dhv2, &(dhv2->skeyid_er))
		 , dhv2->skeyid_er.len, "calculated skeyid_er secret");

    st->hidden_variables.st_skeyid_calculated = TRUE;
}
Ejemplo n.º 10
0
    chunk_t gi;
    
    struct pcr_kenonce *kn = &r->pcr_d.kn;

    group = lookup_group(kn->oakley_group);
    pluto_crypto_allocchunk(&kn->thespace, &kn->secret, LOCALSECRETSIZE);
    
    get_rnd_bytes(wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

	if(OAKLEY_GROUP_MODP1024 == kn->oakley_group && (!g_ipsec_device_is_dpx))
	{
		/*由于硬件只支持1024和512位的模运算,而ipsec最低使用768位的模运算,故只有1024位时才可以使用硬件计算*/
		chunk_t secret_chunk;

        IPSEC_DEBUG(DBG_CRYPT, IPSEC_dbg("hardware calc_ke mod exp, group:%d\n", kn->oakley_group););
		secret_chunk.ptr = wire_chunk_ptr(kn, &(kn->secret));
		secret_chunk.len = LOCALSECRETSIZE;
		
        ret = ipsec_child_rsa_proc(&gi, &g_ipsec_groupgenerator, &secret_chunk, &g_ipsec_groupmod_1024, &g_ipsec_const_1024);
            
	}
    /*使用硬件处理失败,或模位数为768,1536,2048等其他位数的仍然使用GMP库来进行软件计算*/    

    if(ret < 0)
    {
        MP_INT mp_g;
        MP_INT secret;
        
        IPSEC_DEBUG(DBG_CRYPT,IPSEC_dbg("using software mpz_pown to calc_ke mod exp...\n"););

        n_to_mpz(&secret, wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);
Ejemplo n.º 11
0
void calc_ke(struct pluto_crypto_req *r)
{
    chunk_t  prime;
    chunk_t  base;
    SECKEYDHParams      dhp;
    PK11SlotInfo *slot = NULL;
    SECKEYPrivateKey *privk;
    SECKEYPublicKey   *pubk;
    struct pcr_kenonce *kn = &r->pcr_d.kn;
    const struct oakley_group_desc *group;

    group = lookup_group(kn->oakley_group);


    base  = mpz_to_n2(group->generator);
    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);
}
Ejemplo n.º 12
0
/*
 * invoke helper to do DH work.
 */
stf_status start_dh_secretiv(struct pluto_crypto_req_cont *cn
			     , struct state *st
			     , enum crypto_importance importance
			     , enum phase1_role init       /* TRUE=g_init,FALSE=g_r */
			     , u_int16_t oakley_group2)
{
    struct pluto_crypto_req r;
    struct pcr_skeyid_q *dhq;
    const chunk_t *pss = get_preshared_secret(st->st_connection);
    err_t e;
    bool toomuch = FALSE;

    pcr_init(&r, pcr_compute_dh_iv, importance);

    dhq = &r.pcr_d.dhq;

    passert(st->st_sec_in_use);

    /* convert appropriate data to dhq */
    dhq->auth = st->st_oakley.auth;
    dhq->prf_hash = st->st_oakley.prf_hash;
    dhq->oakley_group = oakley_group2;
    dhq->init = init;
    dhq->keysize = st->st_oakley.enckeylen/BITS_PER_BYTE;

    passert(r.pcr_d.dhq.oakley_group != 0);
    DBG(DBG_CONTROL | DBG_CRYPT,
       DBG_log("parent1 type: %d group: %d len: %d\n", r.pcr_type,
	    r.pcr_d.dhq.oakley_group, (int)r.pcr_len));

    if(pss) {
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->pss, *pss);
    }
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->ni,  st->st_ni);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->nr,  st->st_nr);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gi,  st->st_gi);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gr,  st->st_gr);
    pluto_crypto_copychunk(&dhq->thespace, dhq->space
			   , &dhq->secret, st->st_sec_chunk);

#ifdef HAVE_LIBNSS
    /*copying required encryption algo*/
    /*dhq->encrypt_algo = st->st_oakley.encrypt;*/
    dhq->encrypter = st->st_oakley.encrypter;
    DBG(DBG_CRYPT, DBG_log("Copying DH pub key pointer to be sent to a thread helper"));
    pluto_crypto_copychunk(&dhq->thespace, dhq->space , &dhq->pubk, st->pubk);
#endif

    pluto_crypto_allocchunk(&dhq->thespace, &dhq->icookie, COOKIE_SIZE);
    memcpy(wire_chunk_ptr(dhq, &dhq->icookie)
	   , st->st_icookie, COOKIE_SIZE);

    pluto_crypto_allocchunk(&dhq->thespace, &dhq->rcookie, COOKIE_SIZE);
    memcpy(wire_chunk_ptr(dhq, &dhq->rcookie)
	   , st->st_rcookie, COOKIE_SIZE);

    passert(dhq->oakley_group != 0);
    e = send_crypto_helper_request(&r, cn, &toomuch);

    if(e != NULL) {
	loglog(RC_LOG_SERIOUS, "can not start crypto helper: %s", e);
	if(toomuch) {
	    return STF_TOOMUCHCRYPTO;
	} else {
	    return STF_FAIL;
	}
    } else if(!toomuch) {
	st->st_calculating = TRUE;
	delete_event(st);
	event_schedule(EVENT_CRYPTO_FAILED, EVENT_CRYPTO_FAILED_DELAY, st);
	return STF_SUSPEND;
    } else {
	/* we must have run the continuation directly, so
	 * complete_state_transition already got called.
	 */
	return STF_INLINE;
    }
}
Ejemplo n.º 13
0
/*
 * invoke helper to do DH work.
 */
stf_status start_dh_v2(struct pluto_crypto_req_cont *cn,
		       struct state *st,
		       enum crypto_importance importance,
		       enum phase1_role init,        /* TRUE=g_init,FALSE=g_r */
		       u_int16_t oakley_group2)
{
	struct pluto_crypto_req r;
	struct pcr_skeyid_q *dhq;
	err_t e;
	bool toomuch = FALSE;

	pcr_init(&r, pcr_compute_dh_v2, importance);

	dhq = &r.pcr_d.dhq;

	passert(st->st_sec_in_use);

	DBG(DBG_CONTROLMORE,
	    DBG_log("calculating skeyseed using prf=%s integ=%s cipherkey=%s",
		    enum_name(&ikev2_trans_type_prf_names,   st->st_oakley.prf_hash),
		    enum_name(&ikev2_trans_type_integ_names,
			      st->st_oakley.integ_hash),
		    enum_name(&ikev2_trans_type_encr_names,
			      st->st_oakley.encrypt)));

	/* convert appropriate data to dhq */
	dhq->auth = st->st_oakley.auth;
	dhq->prf_hash   = st->st_oakley.prf_hash;
	dhq->integ_hash = st->st_oakley.integ_hash;
	dhq->oakley_group = oakley_group2;
	dhq->init = init;
	dhq->keysize = st->st_oakley.enckeylen / BITS_PER_BYTE;

	passert(r.pcr_d.dhq.oakley_group != 0);

	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->ni,
			       st->st_ni);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->nr,
			       st->st_nr);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gi,
			       st->st_gi);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space, &dhq->gr,
			       st->st_gr);
	pluto_crypto_copychunk(&dhq->thespace, dhq->space,
			       &dhq->secret, st->st_sec_chunk);

	/*copying required encryption algo*/
	/*dhq->encrypt_algo = st->st_oakley.encrypter->common.algo_v2id;*/
	dhq->encrypter = st->st_oakley.encrypter;
	DBG(DBG_CRYPT,
	    DBG_log("Copying DH pub key pointer to be sent to a thread helper"));
	pluto_crypto_copychunk(&dhq->thespace, dhq->space,
			       &dhq->pubk, st->pubk);

	pluto_crypto_allocchunk(&dhq->thespace, &dhq->icookie, COOKIE_SIZE);
	memcpy(wire_chunk_ptr(dhq, &dhq->icookie),
	       st->st_icookie, COOKIE_SIZE);

	pluto_crypto_allocchunk(&dhq->thespace, &dhq->rcookie, COOKIE_SIZE);
	memcpy(wire_chunk_ptr(dhq, &dhq->rcookie),
	       st->st_rcookie, COOKIE_SIZE);

	passert(dhq->oakley_group != 0);
	e = send_crypto_helper_request(&r, cn, &toomuch);

	if (e != NULL) {
		loglog(RC_LOG_SERIOUS, "can not start crypto helper: %s", e);
		if (toomuch)
			return STF_TOOMUCHCRYPTO;
		else
			return STF_FAIL;
	} else if (!toomuch) {
		st->st_calculating = TRUE;
		delete_event(st);
		event_schedule(EVENT_CRYPTO_FAILED, EVENT_CRYPTO_FAILED_DELAY,
			       st);
		return STF_SUSPEND;
	} else {
		/* we must have run the continuation directly, so
		 * complete_state_transition already got called.
		 */
		return STF_INLINE;
	}
}
Ejemplo n.º 14
0
int main(int argc, char *argv[])
{
	struct pluto_crypto_req r;
	struct pcr_skeyid_r *skr = &r.pcr_d.dhr;
	struct pcr_skeyid_q *skq = &r.pcr_d.dhq;

	progname = argv[0];
	
	/* initialize list of moduli */
	init_crypto();

	skq->thespace.start = 0;
	skq->thespace.len   = sizeof(skq->space);
	skq->auth     = tc2_auth;
	skq->prf_hash = tc2_hash;
	skq->oakley_group = tc2_oakleygroup;
	skq->init = tc2_init;
	skq->keysize = tc2_encrypter->keydeflen/BITS_PER_BYTE;

#define copydatlen(field, data, len) do { \
		chunk_t tchunk;           \
		setchunk(tchunk, data, len); \
		pluto_crypto_copychunk(&skq->thespace, skq->space \
				       , &skq->field, tchunk); }   \
		while(0)

	copydatlen(ni, tc2_ni, tc2_ni_len);
	copydatlen(nr, tc2_nr, tc2_nr_len);
	copydatlen(gi, tc2_gi, tc2_gi_len);
	copydatlen(gr, tc2_gr, tc2_gr_len);
	copydatlen(secret, tc2_secret, tc2_secret_len);
	copydatlen(icookie, tc2_icookie, tc2_icookie_len);
	copydatlen(rcookie, tc2_rcookie, tc2_rcookie_len);

#define dumpdat(field) \
	libreswan_DBG_dump(#field,	\
			  wire_chunk_ptr(skq, &skq->field), \
			  skq->field.len);

	dumpdat(icookie);
	dumpdat(rcookie);
	dumpdat(ni);
	dumpdat(nr);
	dumpdat(gi);
	dumpdat(gr);
	dumpdat(secret);

	fflush(stdout);
	fflush(stderr);
	
	calc_dh_iv(&r);

	printf("\noutput:\n");
	

	{
		void *shared = wire_chunk_ptr(skr, &skr->shared);

		libreswan_DBG_dump("shared", shared, skr->shared.len);
	}

	exit(4);
}