Main Content

Missing parameters for key generation

Context used for key generation is associated with NULL parameters

Description

This defect occurs when you perform a key generation step with a context object without first associating the object with required parameters.

For instance, you associate a EVP_PKEY_CTX context object with an empty EVP_PKEY object params before key generation :

EVP_PKEY * params = EVP_PKEY_new();
...
EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new(params, NULL);
... 
EVP_PKEY_keygen(ctx, &pkey);

Risk

Without appropriate parameters, the key generation step does not occur. The redundant operation often indicates a coding error.

Fix

Check the placement of the key generation step. If the operation is intended, make sure that the parameters are set before key generation.

Certain algorithms use default parameters. For instance, if you specify the DSA algorithm when creating the EVP_PKEY_CTX object, a default key length of 1024 bits is used:

kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
Specifying the algorithm during context creation is sufficient to avoid this defect. Only if you use the Elliptic Curve (EC) algorithm, you must also specify the curve explicitly before key generation.

However, the default parameters can generate keys that are too weak for encryption. Weak parameters can trigger another defect. To change default parameters, use functions specific to the algorithm. For instance, to set parameters, you can use these functions:

  • Diffie-Hellman (DH): Use EVP_PKEY_CTX_set_dh_paramgen_prime_len and EVP_PKEY_CTX_set_dh_paramgen_generator.

  • Digital Signature Algorithm (DSA): Use EVP_PKEY_CTX_set_dsa_paramgen_bits.

  • RSA: Use EVP_PKEY_CTX_set_rsa_padding, EVP_PKEY_CTX_set_rsa_pss_saltlen, EVP_PKEY_CTX_set_rsa_rsa_keygen_bits, and EVP_PKEY_CTX_set_rsa_keygen_pubexp.

  • Elliptic curve (EC): Use EVP_PKEY_CTX_set_ec_paramgen_curve_nid and EVP_PKEY_CTX_set_ec_param_enc.

Examples

expand all

#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
int func(EVP_PKEY *pkey){
  EVP_PKEY * params = EVP_PKEY_new();
  if (params == NULL) fatal_error();

  EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new(params, NULL);
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_keygen_init(ctx);
  if (ret <= 0) fatal_error();
  return EVP_PKEY_keygen(ctx, &pkey);
}

In this example, the context object ctx is associated with an empty parameter object params. The context object does not have the required parameters for key generation.

Correction — Specify Algorithm During Context Creation

One possible correction is to specify an algorithm, such as RSA, during context creation. For stronger encryption, use 2048 bits for key length instead of the default 1024 bits.

#include <openssl/evp.h>
#include <openssl/rsa.h>

#define fatal_error() exit(-1)

int ret;
int func(EVP_PKEY *pkey){
  EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); 
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_keygen_init(ctx);
  if (ret <= 0) fatal_error();
  
  ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048); 
  if (ret <= 0) fatal_error();
  
  return EVP_PKEY_keygen(ctx, &pkey); 
}

Result Information

Group: Cryptography
Language: C | C++
Default: Off
Command-Line Syntax: CRYPTO_PKEY_NO_PARAMS
Impact: Medium

Version History

Introduced in R2018a