예제 #1
0
int
evrb_crypto_keys_compute(void* local_ctx, void* distant_ctx, int caller)
{
	srtp_policy_t* loc_policy;
	srtp_policy_t* dist_policy;
	EVRB_CRYPTO* loc = (EVRB_CRYPTO*)local_ctx;
	EVRB_CRYPTO* dist = (EVRB_CRYPTO*)distant_ctx;
	unsigned char *master_key;
	int	master_key_len;

	if(!local_ctx || !distant_ctx)
		return -1;

	loc_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
	dist_policy = (srtp_policy_t*)malloc(sizeof(srtp_policy_t));
	if(!loc_policy || !dist_policy)
		return -1;

	memcpy(loc_policy, &default_policy, sizeof(srtp_policy_t));
	memcpy(dist_policy, &default_policy, sizeof(srtp_policy_t));
	loc_policy->ssrc.type = ssrc_any_outbound;
	dist_policy->ssrc.type = ssrc_any_inbound;

	if (loc->dh == NULL)
	  return -1;

	master_key = dh_compute_key(loc->dh, dist->key, &master_key_len);

#ifndef NDEBUG
	{
	  int i;
	printf("key1=%s\nkey2=%s\n", loc->key, dist->key);
	printf("master_key(%d)=", master_key_len);
	for (i = 0; i < master_key_len; i++)
	  printf("%02x", master_key[i]);
	printf("\n");
	}
#endif
	loc_policy->key = (uint8_t*)malloc(EVRB_KEY_SIZE);
	dist_policy->key = (uint8_t*)malloc(EVRB_KEY_SIZE);

	// TODO: better key derivation
	/* Simmetric keys */
	if (caller)
	  {
	    memcpy(loc_policy->key, master_key, EVRB_KEY_SIZE);
	    memcpy(dist_policy->key, master_key+EVRB_KEY_SIZE, EVRB_KEY_SIZE);
	  }
	else
	  {
	    memcpy(loc_policy->key, master_key+EVRB_KEY_SIZE, EVRB_KEY_SIZE);
	    memcpy(dist_policy->key, master_key, EVRB_KEY_SIZE);
	  }

	if(srtp_create(&loc->srtp_session, loc_policy))
		return -1;

	if(srtp_create(&dist->srtp_session, dist_policy))
		return -1;

	return 0;
}
예제 #2
0
int
dh_gm_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in,
        BN_CTX *bn_ctx)
{
    int ret = 0;
    BUF_MEM * mem_h = NULL;
    BIGNUM * bn_s = NULL, *bn_h = NULL, *bn_g = NULL;
    DH *static_key = NULL, *ephemeral_key = NULL;

    check(ctx && ctx->static_key && s && ctx->ka_ctx, "Invalid arguments");

    BN_CTX_start(bn_ctx);

    static_key = EVP_PKEY_get1_DH(ctx->static_key);
    if (!static_key)
        goto err;

    /* Convert nonce to BIGNUM */
    bn_s = BN_bin2bn((unsigned char *) s->data, s->length, bn_s);
    if (!bn_s)
        goto err;

    /* complete the DH and convert the result to a BIGNUM */
    mem_h = dh_compute_key(ctx->static_key, in, bn_ctx);
    if (!mem_h)
        goto err;
    bn_h = BN_bin2bn((unsigned char *) mem_h->data, mem_h->length, bn_h);
    if (!bn_h)
        goto err;

    /* Initialize ephemeral parameters with parameters from the static key */
    ephemeral_key = DHparams_dup_with_q(static_key);
    if (!ephemeral_key)
        goto err;

    /* map to new generator */
    bn_g = BN_CTX_get(bn_ctx);
    if (!bn_g ||
        /* bn_g = g^s mod p */
        !BN_mod_exp(bn_g, static_key->g, bn_s, static_key->p, bn_ctx) ||
        /* ephemeral_key->g = bn_g * h mod p = g^s * h mod p */
        !BN_mod_mul(ephemeral_key->g, bn_g, bn_h, static_key->p, bn_ctx))
        goto err;

    /* Copy ephemeral key to context structure */
    if (!EVP_PKEY_set1_DH(ctx->ka_ctx->key, ephemeral_key))
        goto err;

    ret = 1;

err:
    if (mem_h) {
        OPENSSL_cleanse(mem_h->data, mem_h->max);
        BUF_MEM_free(mem_h);
    }
    if (bn_h)
        BN_clear_free(bn_h);
    if (bn_s)
        BN_clear_free(bn_s);
    /* Decrement reference count, keys are still available via PACE_CTX */
    if (static_key)
        DH_free(static_key);
    if (ephemeral_key)
        DH_free(ephemeral_key);
    BN_CTX_end(bn_ctx);

    return ret;
}