pseudonym *polypseud_specialize(const polypseud_ctx *ctx, pseudonym *pseud, char *spid, unsigned char *Dp, int Dp_len, unsigned char *Dk, int Dk_len) {
    unsigned int kdf_dp_len;
    unsigned char *kdf_dp_arr = KDF(Dp, Dp_len, (unsigned char *)spid, strlen(spid), &kdf_dp_len);
    if(kdf_dp_arr == NULL)
        return NULL;
    BIGNUM *kdf_dp = BN_bin2bn(kdf_dp_arr, kdf_dp_len, NULL);
    unsigned int kdf_dk_len;
    unsigned char *kdf_dk_arr = KDF(Dk, Dk_len, (unsigned char *)spid, strlen(spid), &kdf_dk_len);
    if(kdf_dk_arr == NULL)
        return NULL;
    BIGNUM *kdf_dk = BN_bin2bn(kdf_dk_arr, kdf_dk_len, NULL);
    BIGNUM *kdf_dk_inv = BN_mod_inverse(NULL, kdf_dk, ctx->q, ctx->bn_ctx);

    EC_POINT_mul(ctx->ec_group, pseud->a, NULL, pseud->a, kdf_dp, ctx->bn_ctx);
    EC_POINT_mul(ctx->ec_group, pseud->b, NULL, pseud->b, kdf_dp, ctx->bn_ctx);

    EC_POINT_mul(ctx->ec_group, pseud->a, NULL, pseud->a, kdf_dk, ctx->bn_ctx);
    EC_POINT_mul(ctx->ec_group, pseud->c, NULL, pseud->c, kdf_dk_inv, ctx->bn_ctx);

    if(polypseud_randomize(ctx, pseud) == NULL)
        return NULL;

    BN_free(kdf_dk_inv);
    BN_free(kdf_dk);
    free(kdf_dk_arr);
    BN_free(kdf_dp);
    free(kdf_dp_arr);

    return pseud;
}
Ejemplo n.º 2
0
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
                     const EC_KEY *eckey,
                     void *(*KDF) (const void *in, size_t inlen, void *out,
                                   size_t *outlen))
{
    unsigned char *sec = NULL;
    size_t seclen;
    if (eckey->meth->compute_key == NULL) {
        ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
        return 0;
    }
    if (outlen > INT_MAX) {
        ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
        return 0;
    }
    if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
        return 0;
    if (KDF != NULL) {
        KDF(sec, seclen, out, &outlen);
    } else {
        if (outlen > seclen)
            outlen = seclen;
        memcpy(out, sec, outlen);
    }
    OPENSSL_clear_free(sec, seclen);
    return outlen;
}
Ejemplo n.º 3
0
int ecdh_compute_key_point(void *out, size_t outlen, const EC_POINT *pub_key,
   EC_KEY *ecdh,
   void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
   {
   BN_CTX *ctx = NULL;
   EC_POINT *tmp=NULL;
   const BIGNUM *priv_key;
   const EC_GROUP* group;
   int ret= -1;
   size_t buflen;
   unsigned char *buf=NULL;

   check((outlen < INT_MAX), "out of memory"); /* sort of, anyway */

   if ((ctx = BN_CTX_new()) == NULL) goto err;
   BN_CTX_start(ctx);

   priv_key = EC_KEY_get0_private_key(ecdh);
   check(priv_key, "No pivate key");

   group = EC_KEY_get0_group(ecdh);
   tmp = EC_POINT_new(group);
   check(tmp, "Out of memory");

   check((EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)),
           "Arithmetic error");

    buflen = EC_POINT_point2oct(group, tmp, EC_KEY_get_conv_form(ecdh), NULL,
            0, ctx);
    check((buflen != 0), "Failed to convert point to hex");

    buf = OPENSSL_malloc(buflen);
    check(buf, "Out of memory");

    check((buflen == EC_POINT_point2oct(group, tmp, EC_KEY_get_conv_form(ecdh),
                    buf, buflen, ctx)), "Failed to convert point to hex");

    if (KDF != 0)
    {
        check((KDF(buf, buflen, out, &outlen) != NULL),
                "Key derivation function failed");
        ret = outlen;
    }
    else
    {
        /* no KDF, just copy as much as we can */
        if (outlen > buflen)
            outlen = buflen;
        memcpy(out, buf, outlen);
        ret = outlen;
    }

err:
    if (tmp) EC_POINT_free(tmp);
    if (ctx) BN_CTX_end(ctx);
    if (ctx) BN_CTX_free(ctx);
    if (buf) OPENSSL_free(buf);
    return(ret);
}
Ejemplo n.º 4
0
/**
 * ECDH key derivation method (replaces ossl_ecdh_compute_key)
 * Implementation for OpenSSL 1.1.0-pre3 and earlier
 *
 * @param  out        derived key
 * @param  outlen     derived key length
 * @param  peer_point public key point
 * @param  ecdh       private key
 * @param  KCF        key derivation function
 * @return the length of the derived key or -1 if an error occurred
 */
static int pkcs11_ec_ckey(void *out, size_t outlen,
		const EC_POINT *peer_point, const EC_KEY *ecdh,
		void *(*KDF)(const void *, size_t, void *, size_t *))
{
	PKCS11_KEY *key;
	CK_ECDH1_DERIVE_PARAMS *parms;
	unsigned char *buf = NULL;
	size_t buflen;
	int rv;

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
	key = (PKCS11_KEY *)EC_KEY_get_ex_data(ecdh, ec_ex_index);
#else
	key = (PKCS11_KEY *)ECDSA_get_ex_data((EC_KEY *)ecdh, ec_ex_index);
#endif
	if (key == NULL) /* The private key is not handled by PKCS#11 */
		return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh, KDF);
	/* TODO: Add an atfork check */

	/* both peer and ecdh use same group parameters */
	parms = pkcs11_ecdh_params_alloc(EC_KEY_get0_group(ecdh), peer_point);
	if (parms == NULL)
		return -1;
	rv = pkcs11_ecdh_derive(&buf, &buflen, CKM_ECDH1_DERIVE, parms, NULL, key);
	pkcs11_ecdh_params_free(parms);
	if (rv < 0)
		return -1;

	if (KDF) {
		if (KDF(buf, buflen, out, &outlen) == NULL) {
			OPENSSL_free(buf);
			return -1;
		}
	} else {
		if (outlen > buflen)
			outlen = buflen;
		memcpy(out, buf, outlen);
	}
	OPENSSL_free(buf);
	return outlen;
}
Ejemplo n.º 5
0
void
kdf_calc_ptk(struct ether_addr *auth_ea, struct ether_addr *sta_ea,
                       uint8 *anonce, uint8* snonce, uint8 *pmk, uint pmk_len,
                       uint8 *ptk, uint ptk_len)
{
	uchar data[128], prf_buff[PRF_OUTBUF_LEN];
	char prefix[] = "Pairwise key expansion";
	uint data_len = 0;

	/* Create the the data portion:
	 * the lesser of the EAs, followed by the greater of the EAs,
	 * followed by the lesser of the the nonces, followed by the
	 * greater of the nonces.
	 */
	bcopy(wpa_array_cmp(MIN_ARRAY, (uint8 *)auth_ea, (uint8 *)sta_ea,
	                    ETHER_ADDR_LEN),
	      (char *)&data[data_len], ETHER_ADDR_LEN);
	data_len += ETHER_ADDR_LEN;
	bcopy(wpa_array_cmp(MAX_ARRAY, (uint8 *)auth_ea, (uint8 *)sta_ea,
	                    ETHER_ADDR_LEN),
	      (char *)&data[data_len], ETHER_ADDR_LEN);
	data_len += ETHER_ADDR_LEN;
	bcopy(wpa_array_cmp(MIN_ARRAY, snonce, anonce,
	                    EAPOL_WPA_KEY_NONCE_LEN),
	      (char *)&data[data_len], EAPOL_WPA_KEY_NONCE_LEN);
	data_len += EAPOL_WPA_KEY_NONCE_LEN;
	bcopy(wpa_array_cmp(MAX_ARRAY, snonce, anonce,
	                    EAPOL_WPA_KEY_NONCE_LEN),
	      (char *)&data[data_len], EAPOL_WPA_KEY_NONCE_LEN);
	data_len += EAPOL_WPA_KEY_NONCE_LEN;

	/* generate the PTK */
	ASSERT(strlen(prefix) + data_len + 1 <= PRF_MAX_I_D_LEN);
	KDF(pmk, (int)pmk_len, (uchar *)prefix, strlen(prefix), data, data_len,
	     prf_buff, (int)ptk_len);
	bcopy(prf_buff, (char*)ptk, ptk_len);
}
Ejemplo n.º 6
0
/**
 * ECDH key derivation method (replaces ossl_ecdh_compute_key)
 * Implementation for OpenSSL 1.1.0-pre3 and earlier
 *
 * @param  out        derived key
 * @param  outlen     derived key length
 * @param  peer_point public key point
 * @param  ecdh       private key
 * @param  KCF        key derivation function
 * @return the length of the derived key or -1 if an error occurred
 */
static int pkcs11_ec_ckey(void *out, size_t outlen,
		const EC_POINT *peer_point, const EC_KEY *ecdh,
		void *(*KDF)(const void *, size_t, void *, size_t *))
{
	PKCS11_KEY *key;
	CK_ECDH1_DERIVE_PARAMS *parms;
	unsigned char *buf = NULL;
	size_t buflen;
	int rv;

	key = pkcs11_get_ex_data_ec(ecdh);
	if (check_key_fork(key) < 0)
		return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh, KDF);

	/* both peer and ecdh use same group parameters */
	parms = pkcs11_ecdh_params_alloc(EC_KEY_get0_group(ecdh), peer_point);
	if (parms == NULL)
		return -1;
	rv = pkcs11_ecdh_derive(&buf, &buflen, CKM_ECDH1_DERIVE, parms, NULL, key);
	pkcs11_ecdh_params_free(parms);
	if (rv < 0)
		return -1;

	if (KDF) {
		if (KDF(buf, buflen, out, &outlen) == NULL) {
			OPENSSL_free(buf);
			return -1;
		}
	} else {
		if (outlen > buflen)
			outlen = buflen;
		memcpy(out, buf, outlen);
	}
	OPENSSL_free(buf);
	return outlen;
}
Ejemplo n.º 7
0
/* This implementation is based on the following primitives in the IEEE 1363 standard:
 *  - ECKAS-DH1
 *  - ECSVDP-DH
 * Finally an optional KDF is applied.
 */
static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
	EC_KEY *ecdh,
	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
	{
	BN_CTX *ctx;
	EC_POINT *tmp=NULL;
	BIGNUM *x=NULL, *y=NULL;
	const BIGNUM *priv_key;
	const EC_GROUP* group;
	int ret= -1;
	size_t buflen, len;
	unsigned char *buf=NULL;

	if (outlen > INT_MAX)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
		return -1;
		}

	if ((ctx = BN_CTX_new()) == NULL) goto err;
	BN_CTX_start(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	
	priv_key = EC_KEY_get0_private_key(ecdh);
	if (priv_key == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
		goto err;
		}

	group = EC_KEY_get0_group(ecdh);
	if ((tmp=EC_POINT_new(group)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) 
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
		goto err;
		}
		
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
		{
		if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#ifndef OPENSSL_NO_EC2M
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#endif

	buflen = (EC_GROUP_get_degree(group) + 7)/8;
	len = BN_num_bytes(x);
	if (len > buflen)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
		goto err;
		}
	if ((buf = malloc(buflen)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	
	memset(buf, 0, buflen - len);
	if (len != (size_t)BN_bn2bin(x, buf + buflen - len))
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	if (KDF != 0)
		{
		if (KDF(buf, buflen, out, &outlen) == NULL)
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_KDF_FAILED);
			goto err;
			}
		ret = outlen;
		}
	else
		{
		/* no KDF, just copy as much as we can */
		if (outlen > buflen)
			outlen = buflen;
		memcpy(out, buf, outlen);
		ret = outlen;
		}
	
err:
	EC_POINT_free(tmp);
	if (ctx)
		BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	free(buf);
	return(ret);
	}
Ejemplo n.º 8
0
static int compute_key(void *out, size_t outlen,
	const EC_POINT *pub_key, EC_KEY *ecdh,
	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
{
	const EC_GROUP* group;
	int ret;

	group = EC_KEY_get0_group(ecdh);

	// only use our solution if the curve name is SECT163K1
	if (EC_GROUP_get_curve_name(group) == NID_sect163k1) {
		const BIGNUM* rkey;
		BN_CTX *ctx;
		BIGNUM* x, *y;
		mm256_point_t p, q;
		mm_256 mkey;
		int r;

		ctx = BN_CTX_new();
		BN_CTX_start(ctx);

		x = BN_CTX_get(ctx);
		y = BN_CTX_get(ctx);

		rkey = EC_KEY_get0_private_key(ecdh);
		memset(&mkey, 0, sizeof(mkey));
		memcpy(&mkey, rkey->d, sizeof(rkey->d[0]) * rkey->top);
		ec2m_import_key(&mkey);

		r = EC_POINT_get_affine_coordinates_GF2m(group, pub_key, x, y, ctx);
		memset(&p, 0, sizeof(p));
		memcpy(&p.x, x->d, sizeof(x->d[0]) * x->top);
		memcpy(&p.y, y->d, sizeof(y->d[0]) * y->top);
		p.z.iv[0] = 1;

		r = ec2m_private_operation(&p, &q);
		if (r < 0) {
			fprintf(stderr, "invalid result: %d\n", r);
		}

		int xlen = (163 + 7) / 8; 
		if (KDF != 0)
		{
			if (KDF(&q.x, xlen, out, &outlen) == NULL)
			{
				return -1;
			}
			ret = outlen;
		}
		else
		{
			/* no KDF, just copy as much as we can */
			if (outlen > xlen)
				outlen = xlen;
			memcpy(out, &q.x, outlen);
			ret = outlen;
		}

		BN_CTX_end(ctx);
		BN_CTX_free(ctx);

	} else {
		// use the default method
		const ECDH_METHOD* meth = ECDH_OpenSSL();
		return meth->compute_key(out, outlen, pub_key, ecdh, KDF);
	}

	return ret;
}
Ejemplo n.º 9
0
/* Our version of the ossl_ecdh_compute_key replaced in the EC_KEY_METHOD */
static int pkcs11_ec_ckey(void *out,
		size_t outlen,
		const EC_POINT *ecpointpeer,
		const EC_KEY *ecdh,
		void *(*KDF) (const void *in,
			size_t inlen,
			void *out,
			size_t *outlen))
{
	int ret = -1;
	size_t buflen;
	unsigned char *buf = NULL;
	size_t peerbuflen;
	unsigned char *peerbuf = NULL;
	const EC_GROUP *ecgroup = NULL;
	const EC_POINT *ecpoint = NULL;
	CK_ECDH1_DERIVE_PARAMS ecdh_parms;
	PKCS11_KEY * key = NULL;

	key = (PKCS11_KEY *) EC_KEY_get_ex_data(ecdh, ec_key_ex_index);

	if (key == NULL) {
	    ret -1;
	    goto err;
	}

	/* both peer and ecdh use same group parameters */
	ecgroup = EC_KEY_get0_group(ecdh);
	buflen = (EC_GROUP_get_degree(ecgroup) + 7) / 8;

	peerbuflen = 2*buflen + 1;
	peerbuf = OPENSSL_malloc(peerbuflen);
	if (peerbuf == NULL) {
		ret = -1;
		goto err;
	}

	ecdh_parms.kdf = CKD_NULL;
	ecdh_parms.ulSharedDataLen = 0;
	ecdh_parms.pSharedData = NULL;
	ecdh_parms.ulPublicDataLen = peerbuflen;
	ret = EC_POINT_point2oct(ecgroup,
			ecpointpeer,
			POINT_CONVERSION_UNCOMPRESSED,
			peerbuf, peerbuflen,NULL);
	ecdh_parms.ulPublicDataLen = peerbuflen;
	ecdh_parms.pPublicData = peerbuf;


	ret = pkcs11_ecdh_derive_internal(&buf, &buflen, CKM_ECDH1_DERIVE,
		(const void *)&ecdh_parms, NULL, key);

	if (KDF != 0) {
		if (KDF(buf, buflen, out, &outlen) == NULL) {
			ret -1;
			goto err;
		}
		ret = outlen;
	} else {
		if (outlen > buflen)
		    outlen = buflen;
		memcpy(out, buf, outlen);
		ret = outlen;
	}
err:
	OPENSSL_free(buf);
	return (ret);
}
Ejemplo n.º 10
0
VOID PMF_DerivePTK(
	IN PRTMP_ADAPTER pAd, 
	IN UCHAR *PMK,
	IN UCHAR *ANonce,
	IN UCHAR *AA,
	IN UCHAR *SNonce,
	IN UCHAR *SA,
	OUT UCHAR *output,
	IN UINT	len)
{	
	UCHAR concatenation[76];
	UINT CurrPos = 0;
	UCHAR temp[32];
	UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', 
			'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};

	/* initiate the concatenation input */
	NdisZeroMemory(temp, sizeof(temp));
	NdisZeroMemory(concatenation, 76);

	/* Get smaller address */
	if (RTMPCompareMemory(SA, AA, 6) == 1)
		NdisMoveMemory(concatenation, AA, 6);
	else
		NdisMoveMemory(concatenation, SA, 6);
	CurrPos += 6;

	/* Get larger address */
	if (RTMPCompareMemory(SA, AA, 6) == 1)
		NdisMoveMemory(&concatenation[CurrPos], SA, 6);
	else
		NdisMoveMemory(&concatenation[CurrPos], AA, 6);
		
	/* store the larger mac address for backward compatible of 
	   ralink proprietary STA-key issue */
	NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);		
	CurrPos += 6;

	/* Get smaller Nonce */
	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
		NdisMoveMemory(&concatenation[CurrPos], temp, 32);
	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
	else
		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
	CurrPos += 32;

	/* Get larger Nonce */
	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
		NdisMoveMemory(&concatenation[CurrPos], temp, 32);
	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
	else
		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
	CurrPos += 32;

	hex_dump("[PMF]PMK", PMK, LEN_PMK);
	hex_dump("[PMF]concatenation=", concatenation, 76);

	/* Calculate a key material through FT-KDF */
	KDF(PMK, LEN_PMK, Prefix, 22, concatenation, 76, output, len);	
}