3939#include " OSSLDHKeyPair.h"
4040#include " OSSLUtil.h"
4141#include < algorithm>
42+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
4243#include < openssl/dh.h>
44+ #else
45+ #include < openssl/core_names.h>
46+ #include < openssl/param_build.h>
47+ #include < openssl/provider.h>
48+ #endif
4349#include < openssl/pem.h>
4450#include < openssl/err.h>
4551
@@ -126,18 +132,21 @@ bool OSSLDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters
126132
127133 DHParameters* params = (DHParameters*) parameters;
128134
135+ BIGNUM* bn_p = OSSL::byteString2bn (params->getP ());
136+ BIGNUM* bn_g = OSSL::byteString2bn (params->getG ());
137+
138+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
129139 // Generate the key-pair
130140 DH* dh = DH_new ();
131141 if (dh == NULL )
132142 {
133143 ERROR_MSG (" Failed to instantiate OpenSSL DH object" );
144+ BN_free (bn_p);
145+ BN_free (bn_g);
134146
135147 return false ;
136148 }
137149
138- BIGNUM* bn_p = OSSL::byteString2bn (params->getP ());
139- BIGNUM* bn_g = OSSL::byteString2bn (params->getG ());
140-
141150 if (!DH_set0_pqg (dh, bn_p, NULL , bn_g))
142151 {
143152 ERROR_MSG (" DH set pqg failed (0x%08X)" , ERR_get_error ());
@@ -169,6 +178,77 @@ bool OSSLDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters
169178
170179 return false ;
171180 }
181+ #else
182+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (EVP_PKEY_DH, NULL );
183+ if (!ctx)
184+ {
185+ ERROR_MSG (" Failed to create EVP_PKEY_CTX" );
186+ BN_free (bn_p);
187+ BN_free (bn_g);
188+ return false ;
189+ }
190+
191+ OSSL_PARAM_BLD* bld = OSSL_PARAM_BLD_new ();
192+ if (!bld)
193+ {
194+ ERROR_MSG (" Failed to create OSSL_PARAM_BLD" );
195+ BN_free (bn_p);
196+ BN_free (bn_g);
197+ EVP_PKEY_CTX_free (ctx);
198+ return false ;
199+ }
200+
201+ OSSL_PARAM_BLD_push_BN (bld, OSSL_PKEY_PARAM_FFC_P, bn_p);
202+ OSSL_PARAM_BLD_push_BN (bld, OSSL_PKEY_PARAM_FFC_G, bn_g);
203+ if (params->getXBitLength () > 0 )
204+ {
205+ OSSL_PARAM_BLD_push_uint (bld, OSSL_PKEY_PARAM_DH_PRIV_LEN, params->getXBitLength ());
206+ }
207+
208+ OSSL_PARAM* params_built = OSSL_PARAM_BLD_to_param (bld);
209+ if (!params_built)
210+ {
211+ ERROR_MSG (" Failed to build OSSL_PARAM" );
212+ BN_free (bn_p);
213+ BN_free (bn_g);
214+ OSSL_PARAM_BLD_free (bld);
215+ EVP_PKEY_CTX_free (ctx);
216+ return false ;
217+ }
218+
219+ EVP_PKEY* dh = NULL ;
220+ if (EVP_PKEY_fromdata_init (ctx) <= 0 || EVP_PKEY_fromdata (ctx, &dh, EVP_PKEY_KEYPAIR, params_built) <= 0 )
221+ {
222+ ERROR_MSG (" EVP_PKEY_fromdata failed" );
223+ BN_free (bn_p);
224+ BN_free (bn_g);
225+ OSSL_PARAM_free (params_built);
226+ OSSL_PARAM_BLD_free (bld);
227+ EVP_PKEY_CTX_free (ctx);
228+ EVP_PKEY_free (dh);
229+ return false ;
230+ }
231+
232+ EVP_PKEY_CTX_free (ctx);
233+ ctx = EVP_PKEY_CTX_new (dh, NULL );
234+ if (EVP_PKEY_keygen_init (ctx) <= 0 || EVP_PKEY_keygen (ctx, &dh) <= 0 ) {
235+ ERROR_MSG (" DH key generation failed" );
236+ BN_free (bn_p);
237+ BN_free (bn_g);
238+ OSSL_PARAM_free (params_built);
239+ OSSL_PARAM_BLD_free (bld);
240+ EVP_PKEY_CTX_free (ctx);
241+ EVP_PKEY_free (dh);
242+ return false ;
243+ }
244+
245+ BN_free (bn_p);
246+ BN_free (bn_g);
247+ OSSL_PARAM_free (params_built);
248+ OSSL_PARAM_BLD_free (bld);
249+ EVP_PKEY_CTX_free (ctx);
250+
251+ #endif
172252
173253 // Create an asymmetric key-pair object to return
174254 OSSLDHKeyPair* kp = new OSSLDHKeyPair ();
@@ -179,7 +259,11 @@ bool OSSLDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters
179259 *ppKeyPair = kp;
180260
181261 // Release the key
262+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
182263 DH_free (dh);
264+ #else
265+ EVP_PKEY_free (dh);
266+ #endif
183267
184268 return true ;
185269}
@@ -194,6 +278,7 @@ bool OSSLDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, Priv
194278 return false ;
195279 }
196280
281+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
197282 // Get keys
198283 DH *pub = ((OSSLDHPublicKey *)publicKey)->getOSSLKey ();
199284 DH *priv = ((OSSLDHPrivateKey *)privateKey)->getOSSLKey ();
@@ -228,6 +313,58 @@ bool OSSLDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, Priv
228313
229314 // We compensate that OpenSSL removes leading zeros
230315 memcpy (&secret[0 ] + size - keySize, &derivedSecret[0 ], keySize);
316+ #else
317+ // Get keys
318+ EVP_PKEY *pub = ((OSSLDHPublicKey *)publicKey)->getOSSLKey ();
319+ EVP_PKEY *priv = ((OSSLDHPrivateKey *)privateKey)->getOSSLKey ();
320+ if (pub == NULL || priv == NULL )
321+ {
322+ ERROR_MSG (" Failed to get OpenSSL DH keys" );
323+ return false ;
324+ }
325+
326+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (priv, NULL );
327+ if (!ctx)
328+ {
329+ ERROR_MSG (" Failed to create EVP_PKEY_CTX" );
330+ return false ;
331+ }
332+
333+ if (EVP_PKEY_derive_init (ctx) <= 0 )
334+ {
335+ ERROR_MSG (" EVP_PKEY_derive_init failed" );
336+ EVP_PKEY_CTX_free (ctx);
337+ return false ;
338+ }
339+
340+ if (EVP_PKEY_derive_set_peer (ctx, pub) <= 0 )
341+ {
342+ ERROR_MSG (" EVP_PKEY_derive_set_peer failed" );
343+ EVP_PKEY_CTX_free (ctx);
344+ return false ;
345+ }
346+
347+ // Determine buffer length
348+ size_t secretLen = 0 ;
349+ if (EVP_PKEY_derive (ctx, NULL , &secretLen) <= 0 )
350+ {
351+ ERROR_MSG (" EVP_PKEY_derive size query failed" );
352+ EVP_PKEY_CTX_free (ctx);
353+ return false ;
354+ }
355+
356+ ByteString secret;
357+ secret.wipe (secretLen);
358+
359+ if (EVP_PKEY_derive (ctx, &secret[0 ], &secretLen) <= 0 )
360+ {
361+ ERROR_MSG (" EVP_PKEY_derive failed" );
362+ EVP_PKEY_CTX_free (ctx);
363+ return false ;
364+ }
365+
366+ EVP_PKEY_CTX_free (ctx);
367+ #endif
231368
232369 *ppSymmetricKey = new SymmetricKey (secret.size () * 8 );
233370 if (*ppSymmetricKey == NULL )
@@ -273,6 +410,7 @@ bool OSSLDH::generateParameters(AsymmetricParameters** ppParams, void* parameter
273410 return false ;
274411 }
275412
413+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
276414 DH* dh = DH_new ();
277415 if (dh == NULL )
278416 {
@@ -290,19 +428,69 @@ bool OSSLDH::generateParameters(AsymmetricParameters** ppParams, void* parameter
290428 return false ;
291429 }
292430
293- // Store the DH parameters
294- DHParameters* params = new DHParameters ();
295-
296431 const BIGNUM* bn_p = NULL ;
297432 const BIGNUM* bn_g = NULL ;
298-
299433 DH_get0_pqg (dh, &bn_p, NULL , &bn_g);
434+ #else
435+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (EVP_PKEY_DH, NULL );
436+ if (!ctx)
437+ {
438+ ERROR_MSG (" Failed to create EVP_PKEY_CTX" );
439+ return false ;
440+ }
441+
442+ if (EVP_PKEY_paramgen_init (ctx) <= 0 )
443+ {
444+ ERROR_MSG (" EVP_PKEY_paramgen_init failed" );
445+ EVP_PKEY_CTX_free (ctx);
446+ return false ;
447+ }
448+
449+ if (EVP_PKEY_CTX_set_dh_paramgen_prime_len (ctx, bitLen) <= 0 )
450+ {
451+ ERROR_MSG (" EVP_PKEY_CTX_set_dh_paramgen_prime_len failed" );
452+ EVP_PKEY_CTX_free (ctx);
453+ return false ;
454+ }
455+
456+ if (EVP_PKEY_CTX_set_dh_paramgen_generator (ctx, 2 ) <= 0 )
457+ {
458+ ERROR_MSG (" EVP_PKEY_CTX_set_dh_paramgen_generator failed" );
459+ EVP_PKEY_CTX_free (ctx);
460+ return false ;
461+ }
462+
463+ EVP_PKEY* dh_params = NULL ;
464+ if (EVP_PKEY_paramgen (ctx, &dh_params) <= 0 )
465+ {
466+ ERROR_MSG (" Failed to generate DH parameters" );
467+ EVP_PKEY_CTX_free (ctx);
468+ return false ;
469+ }
470+
471+ EVP_PKEY_CTX_free (ctx);
472+
473+ BIGNUM* bn_p = NULL ;
474+ BIGNUM* bn_g = NULL ;
475+
476+ EVP_PKEY_get_bn_param (dh_params, OSSL_PKEY_PARAM_FFC_P, &bn_p);
477+ EVP_PKEY_get_bn_param (dh_params, OSSL_PKEY_PARAM_FFC_G, &bn_g);
478+ #endif
479+
480+ // Store the DH parameters
481+ DHParameters* params = new DHParameters ();
300482 ByteString p = OSSL::bn2ByteString (bn_p); params->setP (p);
301483 ByteString g = OSSL::bn2ByteString (bn_g); params->setG (g);
302484
303485 *ppParams = params;
304486
487+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
305488 DH_free (dh);
489+ #else
490+ EVP_PKEY_free (dh_params);
491+ BN_free (bn_p);
492+ BN_free (bn_g);
493+ #endif
306494
307495 return true ;
308496}
0 commit comments