0

I am trying to use wincrypt to generate the private key using P and G values. I get ERROR_INVALID_PARAMETER I am not sure what is wrong in my code. It is the same implementation as in example code given in microsoft website. https://msdn.microsoft.com/en-us/library/aa381969(VS.85).aspx#exchanging_diffie-hellman_keys

int err, gen_fld_sz, fld_sz, salt_len;
const char *generator = ""; // generator as string
const char *prime     = ""; // prime as string
 BYTE* g_rgbPrime = new BYTE[fld_sz+1];
 memcpy(g_rgbPrime, prime, fld_sz+1);  // Prime conta
  BYTE* g_rgbGenerator = new BYTE[gen_fld_sz+1];
  memcpy(g_rgbGenerator, generator, gen_fld_sz+1);
  BYTE* g_rgbData = new BYTE[key_len+1];
  memcpy(g_rgbData, str_server_pub_key, key_len);

  BOOL fReturn;
  HCRYPTPROV hProvParty1 = NULL;
  HCRYPTPROV hProvParty2 = NULL;
  DATA_BLOB P;
  DATA_BLOB G;
  DATA_BLOB S;
  HCRYPTKEY hPrivateKey1 = NULL;
  HCRYPTKEY hPrivateKey2 = NULL;
  PBYTE pbKeyBlob1 = NULL;
  PBYTE pbKeyBlob2 = NULL;
  HCRYPTKEY hSessionKey1 = NULL;
  HCRYPTKEY hSessionKey2 = NULL;
  PBYTE pbData = NULL;

  /************************
  Construct data BLOBs for the prime and generator. The P and G
  values, represented by the g_rgbPrime and g_rgbGenerator arrays
  respectively, are shared values that have been agreed to by both
  parties.
  ************************/
  P.cbData = fld_sz+1;
  P.pbData = (BYTE*)(g_rgbPrime);

  G.cbData = gen_fld_sz+1;
  G.pbData = (BYTE*)(g_rgbGenerator);
  // Acquire a provider handle for party 1.
  fReturn = CryptAcquireContext(
    &hProvParty1,
    NULL,
    MS_ENH_DSS_DH_PROV,
    PROV_DSS_DH,
    CRYPT_VERIFYCONTEXT);
  if (!fReturn)
  {
    log_error("error in setting CryptAcquireContext " << GetLastError());
    goto ErrorExit;
  }


  // Set the prime for party 1's private key.
  fReturn = CryptSetKeyParam(
    hPrivateKey1,
    KP_P,
    (PBYTE)&P,
    0);
  if (!fReturn)
  {
    log_error("error in setting CryptSetKeyParam " << GetLastError());
    goto ErrorExit;
  }

I am getting error in last CryptSetKeyParam. Please advice.

Thanks in advance.

Prakash N
  • 1,020
  • 1
  • 8
  • 20

1 Answers1

0

Well, just following the example you linked, there were some steps more than you do. For example, between CryptAcquireContext and CryptSetKeyParam, he calls CryptGenKey, that is giving a temporary value to hPrivateKey1.

// Create an ephemeral private key for party 1.
fReturn = CryptGenKey(
    hProvParty1, 
    CALG_DH_EPHEM, 
    DHKEYSIZE << 16 | CRYPT_EXPORTABLE | CRYPT_PREGEN,
    &hPrivateKey1);
if(!fReturn)
{
    goto ErrorExit;
}

In your code, you are calling CryptGenKey with hPrivateKey1=NULL;

Federico
  • 743
  • 9
  • 22