Example #1
0
DH *
DH_new_method(ENGINE *engine)
{
	DH *ret;

	ret = malloc(sizeof(DH));
	if (ret == NULL) {
		DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	ret->meth = DH_get_default_method();
#ifndef OPENSSL_NO_ENGINE
	if (engine) {
		if (!ENGINE_init(engine)) {
			DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
			free(ret);
			return NULL;
		}
		ret->engine = engine;
	} else
		ret->engine = ENGINE_get_default_DH();
	if(ret->engine) {
		ret->meth = ENGINE_get_DH(ret->engine);
		if (!ret->meth) {
			DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
			ENGINE_finish(ret->engine);
			free(ret);
			return NULL;
		}
	}
#endif

	ret->pad = 0;
	ret->version = 0;
	ret->p = NULL;
	ret->g = NULL;
	ret->length = 0;
	ret->pub_key = NULL;
	ret->priv_key = NULL;
	ret->q = NULL;
	ret->j = NULL;
	ret->seed = NULL;
	ret->seedlen = 0;
	ret->counter = NULL;
	ret->method_mont_p=NULL;
	ret->references = 1;
	ret->flags = ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW;
	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
	if (ret->meth->init != NULL && !ret->meth->init(ret)) {
#ifndef OPENSSL_NO_ENGINE
		if (ret->engine)
			ENGINE_finish(ret->engine);
#endif
		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data);
		free(ret);
		ret = NULL;
	}
	return ret;
}
Example #2
0
static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
                              X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
{
    ASN1_OBJECT *aoid;
    int atype;
    void *aval;
    ASN1_INTEGER *public_key = NULL;
    int rv = 0;
    EVP_PKEY *pkpeer = NULL, *pk = NULL;
    DH *dhpeer = NULL;
    const unsigned char *p;
    int plen;

    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
    if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
        goto err;
    /* Only absent parameters allowed in RFC XXXX */
    if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
        goto err;

    pk = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!pk)
        goto err;
    if (pk->type != EVP_PKEY_DHX)
        goto err;
    /* Get parameters from parent key */
    dhpeer = DHparams_dup(pk->pkey.dh);
    /* We have parameters now set public key */
    plen = ASN1_STRING_length(pubkey);
    p = ASN1_STRING_data(pubkey);
    if (!p || !plen)
        goto err;

    if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) {
        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
        goto err;
    }

    /* We have parameters now set public key */
    if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
        goto err;
    }

    pkpeer = EVP_PKEY_new();
    if (!pkpeer)
        goto err;
    EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
    dhpeer = NULL;
    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
        rv = 1;
 err:
    if (public_key)
        ASN1_INTEGER_free(public_key);
    if (pkpeer)
        EVP_PKEY_free(pkpeer);
    if (dhpeer)
        DH_free(dhpeer);
    return rv;
}
Example #3
0
static int dh_cms_decrypt(CMS_RecipientInfo *ri)
{
    EVP_PKEY_CTX *pctx;
    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
    if (!pctx)
        return 0;
    /* See if we need to set peer key */
    if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
        X509_ALGOR *alg;
        ASN1_BIT_STRING *pubkey;
        if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
                                                 NULL, NULL, NULL))
            return 0;
        if (!alg || !pubkey)
            return 0;
        if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
            DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
            return 0;
        }
    }
    /* Set DH derivation parameters and initialise unwrap context */
    if (!dh_cms_set_shared_info(pctx, ri)) {
        DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
        return 0;
    }
    return 1;
}
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
	{
	BN_CTX *ctx=NULL;
	BN_MONT_CTX *mont=NULL;
	BIGNUM *tmp;
	int ret= -1;
        int check_result;

	if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
		{
		DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE);
		goto err;
		}

	ctx = BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	tmp = BN_CTX_get(ctx);
	
	if (dh->priv_key == NULL)
		{
		DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
		goto err;
		}

	if (dh->flags & DH_FLAG_CACHE_MONT_P)
		{
		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
				CRYPTO_LOCK_DH, dh->p, ctx);
		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
			{
			/* XXX */
			BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME);
			}
		if (!mont)
			goto err;
		}

        if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result)
		{
		DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY);
		goto err;
		}

	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
		{
		DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	ret=BN_bn2bin(tmp,key);
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return(ret);
	}
Example #5
0
static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
	{
	const unsigned char *p, *pm;
	int pklen, pmlen;
	int ptype;
	void *pval;
	ASN1_STRING *pstr;
	X509_ALGOR *palg;
	ASN1_INTEGER *public_key = NULL;

	DH *dh = NULL;

	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
		return 0;
	X509_ALGOR_get0(NULL, &ptype, &pval, palg);

	if (ptype != V_ASN1_SEQUENCE)
		{
		DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
		goto err;
		}

	pstr = pval;	
	pm = pstr->data;
	pmlen = pstr->length;

	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
		{
		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
		goto err;
		}

	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
		{
		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
		goto err;
		}

	/* We have parameters now set public key */
	if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
		{
		DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
		goto err;
		}

	ASN1_INTEGER_free(public_key);
	EVP_PKEY_assign_DH(pkey, dh);
	return 1;

	err:
	if (public_key)
		ASN1_INTEGER_free(public_key);
	if (dh)
		DH_free(dh);
	return 0;

	}
Example #6
0
static int dh_priv_decode (EVP_PKEY * pkey, PKCS8_PRIV_KEY_INFO * p8)
{
    const unsigned char *p, *pm;

    int pklen, pmlen;

    int ptype;

    void *pval;

    ASN1_STRING *pstr;

    X509_ALGOR *palg;

    ASN1_INTEGER *privkey = NULL;

    DH *dh = NULL;

    if (!PKCS8_pkey_get0 (NULL, &p, &pklen, &palg, p8))
        return 0;

    X509_ALGOR_get0 (NULL, &ptype, &pval, palg);

    if (ptype != V_ASN1_SEQUENCE)
        goto decerr;

    if (!(privkey = d2i_ASN1_INTEGER (NULL, &p, pklen)))
        goto decerr;


    pstr = pval;
    pm = pstr->data;
    pmlen = pstr->length;
    if (!(dh = d2i_DHparams (NULL, &pm, pmlen)))
        goto decerr;
    /* We have parameters now set private key */
    if (!(dh->priv_key = ASN1_INTEGER_to_BN (privkey, NULL)))
    {
        DHerr (DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR);
        goto dherr;
    }
    /* Calculate public key */
    if (!DH_generate_key (dh))
        goto dherr;

    EVP_PKEY_assign_DH (pkey, dh);

    ASN1_INTEGER_free (privkey);

    return 1;

  decerr:
    DHerr (DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
  dherr:
    DH_free (dh);
    return 0;
}
Example #7
0
static int dh_priv_encode (PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey)
{
    ASN1_STRING *params = NULL;

    ASN1_INTEGER *prkey = NULL;

    unsigned char *dp = NULL;

    int dplen;

    params = ASN1_STRING_new ();

    if (!params)
    {
        DHerr (DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    params->length = i2d_DHparams (pkey->pkey.dh, &params->data);
    if (params->length <= 0)
    {
        DHerr (DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    params->type = V_ASN1_SEQUENCE;

    /* Get private key into integer */
    prkey = BN_to_ASN1_INTEGER (pkey->pkey.dh->priv_key, NULL);

    if (!prkey)
    {
        DHerr (DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR);
        goto err;
    }

    dplen = i2d_ASN1_INTEGER (prkey, &dp);

    ASN1_INTEGER_free (prkey);

    if (!PKCS8_pkey_set0 (p8, OBJ_nid2obj (NID_dhKeyAgreement), 0, V_ASN1_SEQUENCE, params, dp, dplen))
        goto err;

    return 1;

  err:
    if (dp != NULL)
        OPENSSL_free (dp);
    if (params != NULL)
        ASN1_STRING_free (params);
    if (prkey != NULL)
        ASN1_INTEGER_free (prkey);
    return 0;
}
Example #8
0
static int dh_pub_encode (X509_PUBKEY * pk, const EVP_PKEY * pkey)
{
    DH *dh;

    void *pval = NULL;

    int ptype;

    unsigned char *penc = NULL;

    int penclen;

    ASN1_STRING *str;

    ASN1_INTEGER *pub_key = NULL;

    dh = pkey->pkey.dh;

    str = ASN1_STRING_new ();
    str->length = i2d_DHparams (dh, &str->data);
    if (str->length <= 0)
    {
        DHerr (DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    pval = str;
    ptype = V_ASN1_SEQUENCE;

    pub_key = BN_to_ASN1_INTEGER (dh->pub_key, NULL);
    if (!pub_key)
        goto err;

    penclen = i2d_ASN1_INTEGER (pub_key, &penc);

    ASN1_INTEGER_free (pub_key);

    if (penclen <= 0)
    {
        DHerr (DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (X509_PUBKEY_set0_param (pk, OBJ_nid2obj (EVP_PKEY_DH), ptype, pval, penc, penclen))
        return 1;

  err:
    if (penc)
        OPENSSL_free (penc);
    if (pval)
        ASN1_STRING_free (pval);

    return 0;
}
Example #9
0
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
	{
	int ret;
	DH *dh;
	DH_PKEY_CTX *dctx = ctx->data;
	BIGNUM *dhpub;
	if (!ctx->pkey || !ctx->peerkey)
		{
		DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
		return 0;
		}
	dh = ctx->pkey->pkey.dh;
	dhpub = ctx->peerkey->pkey.dh->pub_key;
	if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE)
		{
		if (key == NULL)
			{
			*keylen = DH_size(dh);
			return 1;
			}
		ret = DH_compute_key(key, dhpub, dh);
		if (ret < 0)
			return ret;
		*keylen = ret;
		return 1;
		}
	else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42)
		{
		unsigned char *Z = NULL;
		size_t Zlen = 0;
		if (!dctx->kdf_outlen || !dctx->kdf_oid)
			return 0;
		if (key == NULL)
			{
			*keylen = dctx->kdf_outlen;
			return 1;
			}
		if (*keylen != dctx->kdf_outlen)
			return 0;
		ret = 0;
		Zlen = DH_size(dh);
		Z = OPENSSL_malloc(Zlen);
		if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
			goto err;
		if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
					dctx->kdf_ukm, dctx->kdf_ukmlen,
					dctx->kdf_md))
			goto err;
		*keylen = dctx->kdf_outlen;
		ret = 1;
		err:
		if (Z)
			{
			OPENSSL_cleanse(Z, Zlen);
			OPENSSL_free(Z);
			}
		return ret;
		}
	return 1;
	}
Example #10
0
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
	{
	BN_CTX *ctx;
	BN_MONT_CTX *mont=NULL;
	BIGNUM *tmp;
	int ret= -1;

	ctx = BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	tmp = BN_CTX_get(ctx);
	
	if (dh->priv_key == NULL)
		{
		DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
		goto err;
		}

	if (dh->flags & DH_FLAG_CACHE_MONT_P)
		{
		mont = BN_MONT_CTX_set_locked(
				(BN_MONT_CTX **)&dh->method_mont_p,
				CRYPTO_LOCK_DH, dh->p, ctx);
		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
			{
			/* XXX */
			BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME);
			}
		if (!mont)
			goto err;
		}

	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
		{
		DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	ret=BN_bn2bin(tmp,key);
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return(ret);
	}
Example #11
0
static int generate_key(DH *dh)
	{
	int ok=0;
	int generate_new_key=0;
	unsigned l;
	BN_CTX *ctx;
	BN_MONT_CTX *mont;
	BIGNUM *pub_key=NULL,*priv_key=NULL;

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

	if (dh->priv_key == NULL)
		{
		priv_key=BN_new();
		if (priv_key == NULL) goto err;
		generate_new_key=1;
		}
	else
		priv_key=dh->priv_key;

	if (dh->pub_key == NULL)
		{
		pub_key=BN_new();
		if (pub_key == NULL) goto err;
		}
	else
		pub_key=dh->pub_key;

	if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
		{
		if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
				dh->p,ctx)) goto err;
		}
	mont=(BN_MONT_CTX *)dh->method_mont_p;

	if (generate_new_key)
		{
		l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
		if (!BN_rand(priv_key, l, 0, 0)) goto err;
		}
	if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, priv_key,dh->p,ctx,mont))
		goto err;
		
	dh->pub_key=pub_key;
	dh->priv_key=priv_key;
	ok=1;
err:
	if (ok != 1)
		DHerr(DH_F_DH_GENERATE_KEY,ERR_R_BN_LIB);

	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
	BN_CTX_free(ctx);
	return(ok);
	}
Example #12
0
int DH_generate_key(DH *dh)
{
#ifdef OPENSSL_FIPS
    if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
        && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) {
        DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD);
        return 0;
    }
#endif
    return dh->meth->generate_key(dh);
}
Example #13
0
int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
{
#ifdef OPENSSL_FIPS
    if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD)
        && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) {
        DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD);
        return 0;
    }
#endif
    return dh->meth->compute_key(key, pub_key, dh);
}
Example #14
0
static int dh_param_decode(EVP_PKEY *pkey,
                           const unsigned char **pder, int derlen)
{
    DH *dh;
    if (!(dh = d2i_dhp(pkey, pder, derlen))) {
        DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
        return 0;
    }
    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
    return 1;
}
Example #15
0
static int dh_param_decode(EVP_PKEY *pkey,
					const unsigned char **pder, int derlen)
	{
	DH *dh;
	if (!(dh = d2i_DHparams(NULL, pder, derlen)))
		{
		DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
		return 0;
		}
	EVP_PKEY_assign_DH(pkey, dh);
	return 1;
	}
static int generate_key(DH *dh)
	{
	int ok=0;
	BN_CTX ctx;
	BN_MONT_CTX *mont;
	BIGNUM *pub_key=NULL,*priv_key=NULL;

	BN_CTX_init(&ctx);

	if (dh->priv_key == NULL)
		{
		priv_key=BN_new();
		if (priv_key == NULL) goto err;
		do
			if (!BN_rand_range(priv_key, dh->p)) goto err;
		while (BN_is_zero(priv_key));
		}
	else
		priv_key=dh->priv_key;

	if (dh->pub_key == NULL)
		{
		pub_key=BN_new();
		if (pub_key == NULL) goto err;
		}
	else
		pub_key=dh->pub_key;

	if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
		{
		if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
				dh->p,&ctx)) goto err;
		}
	mont=(BN_MONT_CTX *)dh->method_mont_p;

	if (!dh->meth->bn_mod_exp(dh, pub_key,dh->g,priv_key,dh->p,&ctx,mont))
								goto err;
		
	dh->pub_key=pub_key;
	dh->priv_key=priv_key;
	ok=1;
err:
	if (ok != 1)
		DHerr(DH_F_DH_GENERATE_KEY,ERR_R_BN_LIB);

	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
	BN_CTX_free(&ctx);
	return(ok);
	}
Example #17
0
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
	{
	BN_CTX *ctx;
	BN_MONT_CTX *mont;
	BIGNUM *tmp;
	int ret= -1;

	ctx = BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	tmp = BN_CTX_get(ctx);
	
	if (dh->priv_key == NULL)
		{
		DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
		goto err;
		}
	if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
		{
		if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
				dh->p,ctx)) goto err;
		}

	mont=(BN_MONT_CTX *)dh->method_mont_p;
	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
		{
		DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	ret=BN_bn2bin(tmp,key);
err:
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	return(ret);
	}
Example #18
0
int DHparams_print_fp(FILE *fp, const DH *x)
        {
        BIO *b;
        int ret;

        if ((b=BIO_new(BIO_s_file())) == NULL)
		{
		DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
                return(0);
		}
        BIO_set_fp(b,fp,BIO_NOCLOSE);
        ret=DHparams_print(b, x);
        BIO_free(b);
        return(ret);
        }
Example #19
0
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
	{
	int ret;
	if (!ctx->pkey || !ctx->peerkey)
		{
		DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
		return 0;
		}
	ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
							ctx->pkey->pkey.dh);
	if (ret < 0)
		return ret;
	*keylen = ret;
	return 1;
	}
Example #20
0
static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
    DH *dh = NULL;
    if (ctx->pkey == NULL) {
        DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
        return 0;
    }
    dh = DH_new();
    if (!dh)
        return 0;
    EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
    /* Note: if error return, pkey is freed by parent routine */
    if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
        return 0;
    return DH_generate_key(pkey->pkey.dh);
}
Example #21
0
File: dh_gen.c Project: 002301/node
int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
	{
#ifdef OPENSSL_FIPS
	if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD)
			&& !(ret->flags & DH_FLAG_NON_FIPS_ALLOW))
		{
		DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD);
		return 0;
		}
#endif
	if(ret->meth->generate_params)
		return ret->meth->generate_params(ret, prime_len, generator, cb);
#ifdef OPENSSL_FIPS
	if (FIPS_mode())
		return FIPS_dh_generate_parameters_ex(ret, prime_len,
							generator, cb);
#endif
	return dh_builtin_genparams(ret, prime_len, generator, cb);
	}
Example #22
0
int DHparams_print(BIO *bp, const DH *x)
	{
	unsigned char *m=NULL;
	int reason=ERR_R_BUF_LIB,ret=0;
	size_t buf_len=0, i;

	if (x->p)
		buf_len = (size_t)BN_num_bytes(x->p);
	else
		{
		reason = ERR_R_PASSED_NULL_PARAMETER;
		goto err;
		}
	if (x->g)
		if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
			buf_len = i;
	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
	if (m == NULL)
		{
		reason=ERR_R_MALLOC_FAILURE;
		goto err;
		}

	if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
		BN_num_bits(x->p)) <= 0)
		goto err;
	if (!print(bp,"prime:",x->p,m,4)) goto err;
	if (!print(bp,"generator:",x->g,m,4)) goto err;
	if (x->length != 0)
		{
		if (BIO_printf(bp,"    recommended-private-length: %d bits\n",
			(int)x->length) <= 0) goto err;
		}
	ret=1;
	if (0)
		{
err:
		DHerr(DH_F_DHPARAMS_PRINT,reason);
		}
	if (m != NULL) OPENSSL_free(m);
	return(ret);
	}
DH *DH_new_method(DH_METHOD *meth)
	{
	DH *ret;
	ret=(DH *)Malloc(sizeof(DH));

	if (ret == NULL)
		{
		DHerr(DH_F_DH_NEW,ERR_R_MALLOC_FAILURE);
		return(NULL);
		}
	if(meth) ret->meth = meth;
	else ret->meth = DH_get_default_method();
	ret->pad=0;
	ret->version=0;
	ret->p=NULL;
	ret->g=NULL;
	ret->length=0;
	ret->pub_key=NULL;
	ret->priv_key=NULL;
	ret->q=NULL;
	ret->j=NULL;
	ret->seed = NULL;
	ret->seedlen = 0;
	ret->counter = NULL;
	ret->method_mont_p=NULL;
	ret->references = 1;
	ret->flags=ret->meth->flags;
	CRYPTO_new_ex_data(dh_meth,ret,&ret->ex_data);
	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
		{
		CRYPTO_free_ex_data(dh_meth,ret,&ret->ex_data);
		Free(ret);
		ret=NULL;
		}
	return(ret);
	}
Example #24
0
static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
{
    int rv = 0;

    X509_ALGOR *alg, *kekalg = NULL;
    ASN1_OCTET_STRING *ukm;
    const unsigned char *p;
    unsigned char *dukm = NULL;
    size_t dukmlen = 0;
    int keylen, plen;
    const EVP_CIPHER *kekcipher;
    EVP_CIPHER_CTX *kekctx;

    if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
        goto err;

    /*
     * For DH we only have one OID permissible. If ever any more get defined
     * we will need something cleverer.
     */
    if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
        DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
        goto err;
    }

    if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
        goto err;

    if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
        goto err;

    if (alg->parameter->type != V_ASN1_SEQUENCE)
        goto err;

    p = alg->parameter->value.sequence->data;
    plen = alg->parameter->value.sequence->length;
    kekalg = d2i_X509_ALGOR(NULL, &p, plen);
    if (!kekalg)
        goto err;
    kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
    if (!kekctx)
        goto err;
    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
    if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
        goto err;
    if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
        goto err;
    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
        goto err;

    keylen = EVP_CIPHER_CTX_key_length(kekctx);
    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
        goto err;
    /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
                                     OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
        <= 0)
        goto err;

    if (ukm) {
        dukmlen = ASN1_STRING_length(ukm);
        dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
        if (!dukm)
            goto err;
    }

    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
        goto err;
    dukm = NULL;

    rv = 1;
 err:
    if (kekalg)
        X509_ALGOR_free(kekalg);
    if (dukm)
        OPENSSL_free(dukm);
    return rv;
}
Example #25
0
static int do_dh_print(BIO *bp, const DH *x, int indent,
                       ASN1_PCTX *ctx, int ptype)
{
    unsigned char *m = NULL;
    int reason = ERR_R_BUF_LIB, ret = 0;
    size_t buf_len = 0;

    const char *ktype = NULL;

    BIGNUM *priv_key, *pub_key;

    if (ptype == 2)
        priv_key = x->priv_key;
    else
        priv_key = NULL;

    if (ptype > 0)
        pub_key = x->pub_key;
    else
        pub_key = NULL;

    update_buflen(x->p, &buf_len);

    if (buf_len == 0) {
        reason = ERR_R_PASSED_NULL_PARAMETER;
        goto err;
    }

    update_buflen(x->g, &buf_len);
    update_buflen(x->q, &buf_len);
    update_buflen(x->j, &buf_len);
    update_buflen(x->counter, &buf_len);
    update_buflen(pub_key, &buf_len);
    update_buflen(priv_key, &buf_len);

    if (ptype == 2)
        ktype = "DH Private-Key";
    else if (ptype == 1)
        ktype = "DH Public-Key";
    else
        ktype = "DH Parameters";

    m = OPENSSL_malloc(buf_len + 10);
    if (m == NULL) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
    }

    BIO_indent(bp, indent, 128);
    if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
        goto err;
    indent += 4;

    if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent))
        goto err;
    if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent))
        goto err;

    if (!ASN1_bn_print(bp, "prime:", x->p, m, indent))
        goto err;
    if (!ASN1_bn_print(bp, "generator:", x->g, m, indent))
        goto err;
    if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, m, indent))
        goto err;
    if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, m, indent))
        goto err;
    if (x->seed) {
        int i;
        BIO_indent(bp, indent, 128);
        BIO_puts(bp, "seed:");
        for (i = 0; i < x->seedlen; i++) {
            if ((i % 15) == 0) {
                if (BIO_puts(bp, "\n") <= 0
                    || !BIO_indent(bp, indent + 4, 128))
                    goto err;
            }
            if (BIO_printf(bp, "%02x%s", x->seed[i],
                           ((i + 1) == x->seedlen) ? "" : ":") <= 0)
                goto err;
        }
        if (BIO_write(bp, "\n", 1) <= 0)
            return (0);
    }
    if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, m, indent))
        goto err;
    if (x->length != 0) {
        BIO_indent(bp, indent, 128);
        if (BIO_printf(bp, "recommended-private-length: %d bits\n",
                       (int)x->length) <= 0)
            goto err;
    }

    ret = 1;
    if (0) {
 err:
        DHerr(DH_F_DO_DH_PRINT, reason);
    }
    if (m != NULL)
        OPENSSL_free(m);
    return (ret);
}
Example #26
0
DH *DH_generate_parameters(int prime_len, int generator,
	     void (*callback)(int,int,void *), void *cb_arg)
	{
	BIGNUM *p=NULL,*t1,*t2;
	DH *ret=NULL;
	int g,ok= -1;
	BN_CTX *ctx=NULL;

	ret=DH_new();
	if (ret == NULL) goto err;
	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	t1 = BN_CTX_get(ctx);
	t2 = BN_CTX_get(ctx);
	if (t1 == NULL || t2 == NULL) goto err;
	
	if (generator == DH_GENERATOR_2)
		{
		BN_set_word(t1,24);
		BN_set_word(t2,11);
		g=2;
		}
#ifdef undef  /* does not work for safe primes */
	else if (generator == DH_GENERATOR_3)
		{
		BN_set_word(t1,12);
		BN_set_word(t2,5);
		g=3;
		}
#endif
	else if (generator == DH_GENERATOR_5)
		{
		BN_set_word(t1,10);
		BN_set_word(t2,3);
		/* BN_set_word(t3,7); just have to miss
		 * out on these ones :-( */
		g=5;
		}
	else
		g=generator;
	
	p=BN_generate_prime(NULL,prime_len,1,t1,t2,callback,cb_arg);
	if (p == NULL) goto err;
	if (callback != NULL) callback(3,0,cb_arg);
	ret->p=p;
	ret->g=BN_new();
	if (!BN_set_word(ret->g,g)) goto err;
	ok=1;
err:
	if (ok == -1)
		{
		DHerr(DH_F_DH_GENERATE_PARAMETERS,ERR_R_BN_LIB);
		ok=0;
		}

	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (!ok && (ret != NULL))
		{
		DH_free(ret);
		ret=NULL;
		}
	return(ret);
	}
Example #27
0
static int generate_key(DH *dh)
{
    int ok = 0;
    int generate_new_key = 0;
    unsigned l;
    BN_CTX *ctx;
    BN_MONT_CTX *mont = NULL;
    BIGNUM *pub_key = NULL, *priv_key = NULL;

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

    if (dh->priv_key == NULL) {
        priv_key = BN_new();
        if (priv_key == NULL)
            goto err;
        generate_new_key = 1;
    } else
        priv_key = dh->priv_key;

    if (dh->pub_key == NULL) {
        pub_key = BN_new();
        if (pub_key == NULL)
            goto err;
    } else
        pub_key = dh->pub_key;

    if (dh->flags & DH_FLAG_CACHE_MONT_P) {
        mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
                                      CRYPTO_LOCK_DH, dh->p, ctx);
        if (!mont)
            goto err;
    }

    if (generate_new_key) {
        if (dh->q) {
            do {
                if (!BN_rand_range(priv_key, dh->q))
                    goto err;
            }
            while (BN_is_zero(priv_key) || BN_is_one(priv_key));
        } else {
            /* secret exponent length */
            l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
            if (!BN_rand(priv_key, l, 0, 0))
                goto err;
        }
    }

    {
        BIGNUM local_prk;
        BIGNUM *prk;

        if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) {
            BN_init(&local_prk);
            prk = &local_prk;
            BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
        } else
            prk = priv_key;

        if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont))
            goto err;
    }

    dh->pub_key = pub_key;
    dh->priv_key = priv_key;
    ok = 1;
 err:
    if (ok != 1)
        DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);

    if ((pub_key != NULL) && (dh->pub_key == NULL))
        BN_free(pub_key);
    if ((priv_key != NULL) && (dh->priv_key == NULL))
        BN_free(priv_key);
    BN_CTX_free(ctx);
    return (ok);
}
Example #28
0
/* Actually there is no reason to insist that 'generator' be a generator.
 * It's just as OK (and in some sense better) to use a generator of the
 * order-q subgroup.
 */
static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
	{
	BIGNUM *t1,*t2;
	int g,ok= -1;
	BN_CTX *ctx=NULL;

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	t1 = BN_CTX_get(ctx);
	t2 = BN_CTX_get(ctx);
	if (t1 == NULL || t2 == NULL) goto err;

	/* Make sure 'ret' has the necessary elements */
	if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
	if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
	
	if (generator <= 1)
		{
		DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
		goto err;
		}
	if (generator == DH_GENERATOR_2)
		{
		if (!BN_set_word(t1,24)) goto err;
		if (!BN_set_word(t2,11)) goto err;
		g=2;
		}
#if 0 /* does not work for safe primes */
	else if (generator == DH_GENERATOR_3)
		{
		if (!BN_set_word(t1,12)) goto err;
		if (!BN_set_word(t2,5)) goto err;
		g=3;
		}
#endif
	else if (generator == DH_GENERATOR_5)
		{
		if (!BN_set_word(t1,10)) goto err;
		if (!BN_set_word(t2,3)) goto err;
		/* BN_set_word(t3,7); just have to miss
		 * out on these ones :-( */
		g=5;
		}
	else
		{
		/* in the general case, don't worry if 'generator' is a
		 * generator or not: since we are using safe primes,
		 * it will generate either an order-q or an order-2q group,
		 * which both is OK */
		if (!BN_set_word(t1,2)) goto err;
		if (!BN_set_word(t2,1)) goto err;
		g=generator;
		}
	
	if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
	if(!BN_GENCB_call(cb, 3, 0)) goto err;
	if (!BN_set_word(ret->g,g)) goto err;
	ok=1;
err:
	if (ok == -1)
		{
		DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
		ok=0;
		}

	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return ok;
	}
Example #29
0
static int do_dh_print(BIO *bp, const DH *x, int indent,
						ASN1_PCTX *ctx, int ptype)
	{
	unsigned char *m=NULL;
	int reason=ERR_R_BUF_LIB,ret=0;
	size_t buf_len=0;

	const char *ktype = NULL;

	BIGNUM *priv_key, *pub_key;

	if (ptype == 2)
		priv_key = x->priv_key;
	else
		priv_key = NULL;

	if (ptype > 0)
		pub_key = x->pub_key;
	else
		pub_key = NULL;

	update_buflen(x->p, &buf_len);

	if (buf_len == 0)
		{
		reason = ERR_R_PASSED_NULL_PARAMETER;
		goto err;
		}

	update_buflen(x->g, &buf_len);
	update_buflen(pub_key, &buf_len);
	update_buflen(priv_key, &buf_len);

	if (ptype == 2)
		ktype = "PKCS#3 DH Private-Key";
	else if (ptype == 1)
		ktype = "PKCS#3 DH Public-Key";
	else
		ktype = "PKCS#3 DH Parameters";

	m= OPENSSL_malloc(buf_len+10);
	if (m == NULL)
		{
		reason=ERR_R_MALLOC_FAILURE;
		goto err;
		}

	BIO_indent(bp, indent, 128);
	if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
		goto err;
	indent += 4;

	if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
	if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;

	if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
	if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
	if (x->length != 0)
		{
		BIO_indent(bp, indent, 128);
		if (BIO_printf(bp,"recommended-private-length: %d bits\n",
			(int)x->length) <= 0) goto err;
		}


	ret=1;
	if (0)
		{
err:
		DHerr(DH_F_DO_DH_PRINT,reason);
		}
	if (m != NULL) OPENSSL_free(m);
	return(ret);
	}
Example #30
0
static int generate_key(DH *dh)
	{
	int ok=0;
	int generate_new_key=0;
	unsigned l;
	BN_CTX *ctx;
	BN_MONT_CTX *mont=NULL;
	BIGNUM *pub_key=NULL,*priv_key=NULL;

	if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
		{
		DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
		return 0;
		}

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

	if (dh->priv_key == NULL)
		{
		priv_key=BN_new();
		if (priv_key == NULL) goto err;
		generate_new_key=1;
		}
	else
		priv_key=dh->priv_key;

	if (dh->pub_key == NULL)
		{
		pub_key=BN_new();
		if (pub_key == NULL) goto err;
		}
	else
		pub_key=dh->pub_key;

	if (dh->flags & DH_FLAG_CACHE_MONT_P)
		{
		mont = BN_MONT_CTX_set_locked(
				(BN_MONT_CTX **)&dh->method_mont_p,
				CRYPTO_LOCK_DH, dh->p, ctx);
		if (!mont)
			goto err;
		}

	if (generate_new_key)
		{
		l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
		if (!BN_rand(priv_key, l, 0, 0)) goto err;
		}

	{
		BIGNUM local_prk;
		BIGNUM *prk;

		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
			{
			BN_init(&local_prk);
			prk = &local_prk;
			BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
			}
		else
			prk = priv_key;

		if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont))
			goto err;
	}
		
	dh->pub_key=pub_key;
	dh->priv_key=priv_key;
	ok=1;
err:
	if (ok != 1)
		DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB);

	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
	BN_CTX_free(ctx);
	return(ok);
	}