Main Content

Missing peer key

Context used for shared secret derivation is associated with NULL peer key or not associated with a peer key at all

Description

This defect occurs when you use a context object for shared secret derivation but you have not previously associated the object with a non-NULL peer key.

For instance, you initialize the context object, and then use the object for shared secret derivation without an intermediate step where the object is associated with a peer key:

EVP_PKEY_derive_init(ctx);
/* Missing step for associating peer key with context */
ret = EVP_PKEY_derive(ctx, out_buf, &out_len);

The counterpart checker Missing private key checks for a private key in shared secret derivation.

Risk

Without a peer key, the shared secret derivation step does not occur. The redundant operation often indicates a coding error.

Fix

Check the placement of the shared secret derivation step. If the operation is intended, make sure that you have completed these steps prior to the operation:

  • Generate a non-NULL peer key.

    For instance:

    EVP_PKEY* peerkey = NULL;
    EVP_PKEY_keygen(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), &peerkey);

  • Associate a non-NULL context object with the peer key.

    For instance:

    EVP_PKEY_derive_set_peer(ctx,peerkey);
    

Examples

expand all

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

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf;
size_t out_len;

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

  EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); 
  if (ctx == NULL) fatal_error();
  ret = EVP_PKEY_derive_init(ctx);
  if (ret <= 0) fatal_error();
  return EVP_PKEY_derive(ctx, out_buf, &out_len); 
}

In this example, the context object ctx is associated with a private key but not a peer key. The EVP_PKEY_derive function uses this context object for shared secret derivation.

Correction — Set Peer Key in Context

One possible correction is to use the function EVP_PKEY_derive_set_peer and associate a peer key with the context object. Make sure that the peer key is non-NULL.

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

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf;
size_t out_len;

int func(EVP_PKEY *pkey,  EVP_PKEY* peerkey){
  if (pkey == NULL) fatal_error(); 
  if (peerkey == NULL) fatal_error(); 
  
  EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); 
  if (ctx == NULL) fatal_error();
  ret = EVP_PKEY_derive_init(ctx);
  if (ret <= 0) fatal_error();
  ret = EVP_PKEY_derive_set_peer(ctx,peerkey); 
  if (ret <= 0) fatal_error();
  return EVP_PKEY_derive(ctx, out_buf, &out_len); 
}

Result Information

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

Version History

Introduced in R2018a