@ -13,18 +13,27 @@
*/
# include "internal/deprecated.h"
# include "e_os.h" /* strcasecmp */
# include <openssl/core_numbers.h>
# include <openssl/core_names.h>
# include <openssl/bn.h>
# include <openssl/params.h>
# include "prov/implementations.h"
# include <openssl/err.h>
# include "prov/providercommon.h"
# include "prov/implementations.h"
# include "prov/provider_ctx.h"
# include "crypto/dsa.h"
# include "openssl/param_build.h"
# include "internal/sizes.h"
# include "internal/nelem.h"
# include "internal/param_build_set.h"
static OSSL_OP_keymgmt_new_fn dsa_newdata ;
static OSSL_OP_keymgmt_free_fn dsa_freedata ;
static OSSL_OP_keymgmt_gen_init_fn dsa_gen_init ;
static OSSL_OP_keymgmt_gen_set_template_fn dsa_gen_set_template ;
static OSSL_OP_keymgmt_gen_set_params_fn dsa_gen_set_params ;
static OSSL_OP_keymgmt_gen_settable_params_fn dsa_gen_settable_params ;
static OSSL_OP_keymgmt_gen_fn dsa_gen ;
static OSSL_OP_keymgmt_gen_cleanup_fn dsa_gen_cleanup ;
static OSSL_OP_keymgmt_get_params_fn dsa_get_params ;
static OSSL_OP_keymgmt_gettable_params_fn dsa_gettable_params ;
static OSSL_OP_keymgmt_has_fn dsa_has ;
@ -36,45 +45,63 @@ static OSSL_OP_keymgmt_export_fn dsa_export;
static OSSL_OP_keymgmt_export_types_fn dsa_export_types ;
# define DSA_DEFAULT_MD "SHA256"
# define DSA_POSSIBLE_SELECTIONS \
# define DSA_POSSIBLE_SELECTIONS \
( OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS )
static int domparams_to_params ( DSA * dsa , OSSL_PARAM_BLD * tmpl )
{
const BIGNUM * dsa_p = NULL , * dsa_q = NULL , * dsa_g = NULL ;
struct dsa_gen_ctx {
OPENSSL_CTX * libctx ;
FFC_PARAMS * ffc_params ;
int selection ;
/* All these parameters are used for parameter generation only */
size_t pbits ;
size_t qbits ;
EVP_MD * md ;
unsigned char * seed ; /* optional FIPS186-4 param for testing */
size_t seedlen ;
int gindex ; /* optional FIPS186-4 generator index (ignored if -1) */
int gen_type ; /* DSA_PARAMGEN_TYPE_FIPS_186_2 or DSA_PARAMGEN_TYPE_FIPS_186_4 */
int pcounter ;
int hindex ;
OSSL_CALLBACK * cb ;
void * cbarg ;
} ;
typedef struct dh_name2id_st {
const char * name ;
int id ;
} DSA_GENTYPE_NAME2ID ;
if ( dsa = = NULL )
return 0 ;
static const DSA_GENTYPE_NAME2ID dsatype2id [ ] =
{
{ " default " , DSA_PARAMGEN_TYPE_FIPS_186_4 } ,
{ " fips186_4 " , DSA_PARAMGEN_TYPE_FIPS_186_4 } ,
{ " fips186_2 " , DSA_PARAMGEN_TYPE_FIPS_186_2 } ,
} ;
DSA_get0_pqg ( dsa , & dsa_p , & dsa_q , & dsa_g ) ;
if ( dsa_p ! = NULL
& & ! OSSL_PARAM_BLD_push_BN ( tmpl , OSSL_PKEY_PARAM_FFC_P , dsa_p ) )
return 0 ;
if ( dsa_q ! = NULL
& & ! OSSL_PARAM_BLD_push_BN ( tmpl , OSSL_PKEY_PARAM_FFC_Q , dsa_q ) )
return 0 ;
if ( dsa_g ! = NULL
& & ! OSSL_PARAM_BLD_push_BN ( tmpl , OSSL_PKEY_PARAM_FFC_G , dsa_g ) )
return 0 ;
static int dsa_gen_type_name2id ( const char * name )
{
size_t i ;
return 1 ;
for ( i = 0 ; i < OSSL_NELEM ( dsatype2id ) ; + + i ) {
if ( strcasecmp ( dsatype2id [ i ] . name , name ) = = 0 )
return dsatype2id [ i ] . id ;
}
return - 1 ;
}
static int key_to_params ( DSA * dsa , OSSL_PARAM_BLD * tmpl )
static int dsa_key_todata( DSA * dsa , OSSL_PARAM_BLD * bld , OSSL_PARAM params [ ] )
{
const BIGNUM * priv _key = NULL , * pub _key = NULL ;
const BIGNUM * priv = NULL , * pub = NULL ;
if ( dsa = = NULL )
return 0 ;
if ( ! domparams_to_params ( dsa , tmpl ) )
return 0 ;
DSA_get0_key ( dsa , & pub _key , & priv _key ) ;
if ( priv _key ! = NULL
& & ! OSSL_PARAM_BLD_push_BN( tmpl , OSSL_PKEY_PARAM_PRIV_KEY , priv _key ) )
DSA_get0_key ( dsa , & pub , & priv ) ;
if ( priv ! = NULL
& & ! ossl_param_build_set_bn( bld , params , OSSL_PKEY_PARAM_PRIV_KEY , priv ) )
return 0 ;
if ( pub _key ! = NULL
& & ! OSSL_PARAM_BLD_push_BN( tmpl , OSSL_PKEY_PARAM_PUB_KEY , pub _key ) )
if ( pub ! = NULL
& & ! ossl_param_build_set_bn( bld , params , OSSL_PKEY_PARAM_PUB_KEY , pub ) )
return 0 ;
return 1 ;
@ -133,16 +160,16 @@ static int dsa_match(const void *keydata1, const void *keydata2, int selection)
static int dsa_import ( void * keydata , int selection , const OSSL_PARAM params [ ] )
{
DSA * dsa = keydata ;
int ok = 0 ;
int ok = 1 ;
if ( dsa = = NULL )
return 0 ;
if ( ( selection & DSA_POSSIBLE_SELECTIONS ) ! = 0 )
ok = 1 ;
if ( ( selection & DSA_POSSIBLE_SELECTIONS ) = = 0 )
return 0 ;
if ( ( selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ) ! = 0 )
ok = ok & & ffc_fromdata( dsa_get0_params ( dsa ) , params ) ;
ok = ok & & dsa_ ffc_params_ fromdata( dsa , params ) ;
if ( ( selection & OSSL_KEYMGMT_SELECT_KEYPAIR ) ! = 0 )
ok = ok & & dsa_key_fromdata ( dsa , params ) ;
@ -158,12 +185,12 @@ static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
int ok = 1 ;
if ( dsa = = NULL )
goto err ; ;
goto err ;
if ( ( selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ) ! = 0 )
ok = ok & & domparams_to_params( dsa , tmpl ) ;
ok = ok & & ffc_params_todata( dsa_get0_params ( dsa ) , tmpl , NULL ) ;
if ( ( selection & OSSL_KEYMGMT_SELECT_KEYPAIR ) ! = 0 )
ok = ok & & key_to_params( dsa , tmpl ) ;
ok = ok & & dsa_key_todata( dsa , tmpl , NULL ) ;
if ( ! ok
| | ( params = OSSL_PARAM_BLD_to_param ( tmpl ) ) = = NULL )
@ -178,10 +205,16 @@ err:
/* IMEXPORT = IMPORT + EXPORT */
# define DSA_IMEXPORTABLE_PARAMETERS \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_FFC_P , NULL , 0 ) , \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_FFC_Q , NULL , 0 ) , \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_FFC_G , NULL , 0 )
# define DSA_IMEXPORTABLE_PARAMETERS \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_FFC_P , NULL , 0 ) , \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_FFC_Q , NULL , 0 ) , \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_FFC_G , NULL , 0 ) , \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_FFC_COFACTOR , NULL , 0 ) , \
OSSL_PARAM_int ( OSSL_PKEY_PARAM_FFC_GINDEX , NULL ) , \
OSSL_PARAM_int ( OSSL_PKEY_PARAM_FFC_PCOUNTER , NULL ) , \
OSSL_PARAM_int ( OSSL_PKEY_PARAM_FFC_H , NULL ) , \
OSSL_PARAM_utf8_string ( OSSL_PKEY_PARAM_FFC_GROUP , NULL , 0 ) , \
OSSL_PARAM_octet_string ( OSSL_PKEY_PARAM_FFC_SEED , NULL , 0 )
# define DSA_IMEXPORTABLE_PUBLIC_KEY \
OSSL_PARAM_BN ( OSSL_PKEY_PARAM_PUB_KEY , NULL , 0 )
# define DSA_IMEXPORTABLE_PRIVATE_KEY \
@ -246,7 +279,8 @@ static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[])
if ( ( p = OSSL_PARAM_locate ( params , OSSL_PKEY_PARAM_DEFAULT_DIGEST ) ) ! = NULL
& & ! OSSL_PARAM_set_utf8_string ( p , DSA_DEFAULT_MD ) )
return 0 ;
return 1 ;
return ffc_params_todata ( dsa_get0_params ( dsa ) , NULL , params )
& & dsa_key_todata ( dsa , NULL , params ) ;
}
static const OSSL_PARAM dsa_params [ ] = {
@ -254,6 +288,9 @@ static const OSSL_PARAM dsa_params[] = {
OSSL_PARAM_int ( OSSL_PKEY_PARAM_SECURITY_BITS , NULL ) ,
OSSL_PARAM_int ( OSSL_PKEY_PARAM_MAX_SIZE , NULL ) ,
OSSL_PARAM_utf8_string ( OSSL_PKEY_PARAM_DEFAULT_DIGEST , NULL , 0 ) ,
DSA_IMEXPORTABLE_PARAMETERS ,
DSA_IMEXPORTABLE_PUBLIC_KEY ,
DSA_IMEXPORTABLE_PRIVATE_KEY ,
OSSL_PARAM_END
} ;
@ -311,8 +348,224 @@ static int dsa_validate(void *keydata, int selection)
return ok ;
}
static void * dsa_gen_init ( void * provctx , int selection )
{
OPENSSL_CTX * libctx = PROV_LIBRARY_CONTEXT_OF ( provctx ) ;
struct dsa_gen_ctx * gctx = NULL ;
if ( ( selection & DSA_POSSIBLE_SELECTIONS ) = = 0 )
return NULL ;
if ( ( gctx = OPENSSL_zalloc ( sizeof ( * gctx ) ) ) ! = NULL ) {
gctx - > selection = selection ;