Skip to content

Commit bbf834f

Browse files
committed
Migrate OSSLDH to OpenSSL 3.0+
1 parent 4f296fa commit bbf834f

File tree

6 files changed

+587
-100
lines changed

6 files changed

+587
-100
lines changed

src/lib/crypto/OSSLDH.cpp

Lines changed: 195 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,13 @@
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

Comments
 (0)