> On Thu, Mar 14, 2013, Leon Brits wrote:
>
> > Hi List,
> >
> > I just want to verify: Elliptic curve functions are not encapsulated by
> the
> > EVP functions - correct? If so, what is the
> > EVP_PKEY_CTX_set_ec_paramgen_curve_nid function then used for? If NOT
> so,
> > then please help with an example since I could only find the normal
> > EC_{KEY,GROUP}* type of example code?
> >
> > I am required to perform ECDSA and was hoping I could use EVP which is
> now
> > working for DSA and RSA (sans the padding problem).
> >
>
As Steve has said, yes you can use ECDSA using EVP. The
EVP_PKEY_CTX_set_ec_paramgen_curve_nid is used during parameter generation.
Here is some sample code that uses it. Once you have an EVP_PKEY set up
with a type of EVP_PKEY_EC, then the code to do signatures should be pretty
much identical for DSA and ECDSA. This code generates a new key but you can
equally set it directly using EVP_PKEY_set1_EC_KEY. See the man page for
further details:
http://www.openssl.org/docs/crypto/EVP_PKEY_set1_RSA.html
EVP_PKEY *generate_key(int type)
{
EVP_PKEY_CTX *pctx = NULL, *kctx = NULL;
EVP_PKEY *params = NULL, *key = NULL;
/* Check whether we need to generate parameters first */
if(type == EVP_PKEY_EC || type == EVP_PKEY_DSA || type == EVP_PKEY_DH)
{
/* Create the context for generating the parameters */
if(!(pctx = EVP_PKEY_CTX_new_id(type, NULL))) goto err;
if(!EVP_PKEY_paramgen_init(pctx)) goto err;
/* Set the paramgen parameters according to the type */
switch(type)
{
case EVP_PKEY_EC:
if(!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
NID_X9_62_prime256v1)) goto err;
break;
case EVP_PKEY_DSA:
if(!EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, 2048)) goto
err;
break;
case EVP_PKEY_DH:
if(!EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, 2048)) goto
err;
}
/* Generate parameters */
if (!EVP_PKEY_paramgen(pctx, ¶ms)) goto err;
/* Create context for the key generation */
if(!(kctx = EVP_PKEY_CTX_new(params, NULL))) goto err;
}
else
{
/* Create context for the key generation */
if(!(kctx = EVP_PKEY_CTX_new_id(type, NULL))) goto err;
}
/* Set the keygen parameters according to the type */
if(type == EVP_PKEY_RSA)
{
if(!EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, 2048)) goto err;
}
/* Generate the key */
if(!EVP_PKEY_keygen_init(kctx)) goto err;
if(type == EVP_PKEY_CMAC)
{
if (EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_CIPHER,
0, (void *)EVP_aes_256_ecb()) <= 0)
goto err;
if (EVP_PKEY_CTX_ctrl(kctx, -1, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_SET_MAC_KEY,
/*key length*/32, "01234567890123456789012345678901") <= 0)
goto err;
}
if (!EVP_PKEY_keygen(kctx, &key)) goto err;
goto end;
err:
ERR_print_errors_fp(stderr);
end:
if(pctx) EVP_PKEY_CTX_free(pctx);
if(params) EVP_PKEY_free(params);
if(kctx) EVP_PKEY_CTX_free(kctx);
return key;
}
Regards
Matt