2 Diffie-Hellman Wrapper Implementation over OpenSSL.
4 Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "InternalCryptLib.h"
16 #include <openssl/bn.h>
17 #include <openssl/dh.h>
21 Allocates and Initializes one Diffie-Hellman Context for subsequent use.
23 @return Pointer to the Diffie-Hellman Context that has been initialized.
24 If the allocations fails, DhNew() returns NULL.
34 // Allocates & Initializes DH Context by OpenSSL DH_new()
36 return (VOID
*) DH_new ();
40 Release the specified DH context.
42 If DhContext is NULL, then return FALSE.
44 @param[in] DhContext Pointer to the DH context to be released.
54 // Free OpenSSL DH Context
56 DH_free ((DH
*) DhContext
);
60 Generates DH parameter.
62 Given generator g, and length of prime number p in bits, this function generates p,
63 and sets DH context according to value of g and p.
65 Before this function can be invoked, pseudorandom number generator must be correctly
66 initialized by RandomSeed().
68 If DhContext is NULL, then return FALSE.
69 If Prime is NULL, then return FALSE.
71 @param[in, out] DhContext Pointer to the DH context.
72 @param[in] Generator Value of generator.
73 @param[in] PrimeLength Length in bits of prime to be generated.
74 @param[out] Prime Pointer to the buffer to receive the generated prime number.
76 @retval TRUE DH pamameter generation succeeded.
77 @retval FALSE Value of Generator is not supported.
78 @retval FALSE PRNG fails to generate random prime number with PrimeLength.
84 IN OUT VOID
*DhContext
,
93 // Check input parameters.
95 if (DhContext
== NULL
|| Prime
== NULL
|| PrimeLength
> INT_MAX
) {
99 if (Generator
!= DH_GENERATOR_2
&& Generator
!= DH_GENERATOR_5
) {
103 RetVal
= (BOOLEAN
) DH_generate_parameters_ex (DhContext
, (UINT32
) PrimeLength
, (UINT32
) Generator
, NULL
);
108 BN_bn2bin (((DH
*) DhContext
)->p
, Prime
);
114 Sets generator and prime parameters for DH.
116 Given generator g, and prime number p, this function and sets DH
119 If DhContext is NULL, then return FALSE.
120 If Prime is NULL, then return FALSE.
122 @param[in, out] DhContext Pointer to the DH context.
123 @param[in] Generator Value of generator.
124 @param[in] PrimeLength Length in bits of prime to be generated.
125 @param[in] Prime Pointer to the prime number.
127 @retval TRUE DH pamameter setting succeeded.
128 @retval FALSE Value of Generator is not supported.
129 @retval FALSE Value of Generator is not suitable for the Prime.
130 @retval FALSE Value of Prime is not a prime number.
131 @retval FALSE Value of Prime is not a safe prime number.
137 IN OUT VOID
*DhContext
,
139 IN UINTN PrimeLength
,
140 IN CONST UINT8
*Prime
147 // Check input parameters.
149 if (DhContext
== NULL
|| Prime
== NULL
|| PrimeLength
> INT_MAX
) {
153 if (Generator
!= DH_GENERATOR_2
&& Generator
!= DH_GENERATOR_5
) {
159 Dh
= (DH
*) DhContext
;
171 Bn
= BN_bin2bn (Prime
, (UINT32
) (PrimeLength
/ 8), Dh
->p
);
176 if (BN_set_word (Dh
->g
, (UINT32
) Generator
) == 0) {
200 Generates DH public key.
202 This function generates random secret exponent, and computes the public key, which is
203 returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.
204 If the PublicKey buffer is too small to hold the public key, FALSE is returned and
205 PublicKeySize is set to the required buffer size to obtain the public key.
207 If DhContext is NULL, then return FALSE.
208 If PublicKeySize is NULL, then return FALSE.
209 If PublicKeySize is large enough but PublicKey is NULL, then return FALSE.
211 @param[in, out] DhContext Pointer to the DH context.
212 @param[out] PublicKey Pointer to the buffer to receive generated public key.
213 @param[in, out] PublicKeySize On input, the size of PublicKey buffer in bytes.
214 On output, the size of data returned in PublicKey buffer in bytes.
216 @retval TRUE DH public key generation succeeded.
217 @retval FALSE DH public key generation failed.
218 @retval FALSE PublicKeySize is not large enough.
224 IN OUT VOID
*DhContext
,
225 OUT UINT8
*PublicKey
,
226 IN OUT UINTN
*PublicKeySize
234 // Check input parameters.
236 if (DhContext
== NULL
|| PublicKeySize
== NULL
) {
240 if (PublicKey
== NULL
&& *PublicKeySize
!= 0) {
244 Dh
= (DH
*) DhContext
;
246 RetVal
= (BOOLEAN
) DH_generate_key (DhContext
);
248 Size
= BN_num_bytes (Dh
->pub_key
);
249 if ((Size
> 0) && (*PublicKeySize
< (UINTN
) Size
)) {
250 *PublicKeySize
= Size
;
254 BN_bn2bin (Dh
->pub_key
, PublicKey
);
255 *PublicKeySize
= Size
;
262 Computes exchanged common key.
264 Given peer's public key, this function computes the exchanged common key, based on its own
265 context including value of prime modulus and random secret exponent.
267 If DhContext is NULL, then return FALSE.
268 If PeerPublicKey is NULL, then return FALSE.
269 If KeySize is NULL, then return FALSE.
270 If Key is NULL, then return FALSE.
271 If KeySize is not large enough, then return FALSE.
273 @param[in, out] DhContext Pointer to the DH context.
274 @param[in] PeerPublicKey Pointer to the peer's public key.
275 @param[in] PeerPublicKeySize Size of peer's public key in bytes.
276 @param[out] Key Pointer to the buffer to receive generated key.
277 @param[in, out] KeySize On input, the size of Key buffer in bytes.
278 On output, the size of data returned in Key buffer in bytes.
280 @retval TRUE DH exchanged key generation succeeded.
281 @retval FALSE DH exchanged key generation failed.
282 @retval FALSE KeySize is not large enough.
288 IN OUT VOID
*DhContext
,
289 IN CONST UINT8
*PeerPublicKey
,
290 IN UINTN PeerPublicKeySize
,
292 IN OUT UINTN
*KeySize
299 // Check input parameters.
301 if (DhContext
== NULL
|| PeerPublicKey
== NULL
|| KeySize
== NULL
|| Key
== NULL
) {
305 if (PeerPublicKeySize
> INT_MAX
) {
309 Bn
= BN_bin2bn (PeerPublicKey
, (UINT32
) PeerPublicKeySize
, NULL
);
314 Size
= DH_compute_key (Key
, Bn
, DhContext
);
320 if (*KeySize
< (UINTN
) Size
) {