]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c
CryptoPkg: Apply uncrustify changes
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptDh.c
1 /** @file
2 Diffie-Hellman Wrapper Implementation over OpenSSL.
3
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "InternalCryptLib.h"
10 #include <openssl/bn.h>
11 #include <openssl/dh.h>
12
13 /**
14 Allocates and Initializes one Diffie-Hellman Context for subsequent use.
15
16 @return Pointer to the Diffie-Hellman Context that has been initialized.
17 If the allocations fails, DhNew() returns NULL.
18
19 **/
20 VOID *
21 EFIAPI
22 DhNew (
23 VOID
24 )
25 {
26 //
27 // Allocates & Initializes DH Context by OpenSSL DH_new()
28 //
29 return (VOID *)DH_new ();
30 }
31
32 /**
33 Release the specified DH context.
34
35 If DhContext is NULL, then return FALSE.
36
37 @param[in] DhContext Pointer to the DH context to be released.
38
39 **/
40 VOID
41 EFIAPI
42 DhFree (
43 IN VOID *DhContext
44 )
45 {
46 //
47 // Free OpenSSL DH Context
48 //
49 DH_free ((DH *)DhContext);
50 }
51
52 /**
53 Generates DH parameter.
54
55 Given generator g, and length of prime number p in bits, this function generates p,
56 and sets DH context according to value of g and p.
57
58 Before this function can be invoked, pseudorandom number generator must be correctly
59 initialized by RandomSeed().
60
61 If DhContext is NULL, then return FALSE.
62 If Prime is NULL, then return FALSE.
63
64 @param[in, out] DhContext Pointer to the DH context.
65 @param[in] Generator Value of generator.
66 @param[in] PrimeLength Length in bits of prime to be generated.
67 @param[out] Prime Pointer to the buffer to receive the generated prime number.
68
69 @retval TRUE DH parameter generation succeeded.
70 @retval FALSE Value of Generator is not supported.
71 @retval FALSE PRNG fails to generate random prime number with PrimeLength.
72
73 **/
74 BOOLEAN
75 EFIAPI
76 DhGenerateParameter (
77 IN OUT VOID *DhContext,
78 IN UINTN Generator,
79 IN UINTN PrimeLength,
80 OUT UINT8 *Prime
81 )
82 {
83 BOOLEAN RetVal;
84 BIGNUM *BnP;
85
86 //
87 // Check input parameters.
88 //
89 if ((DhContext == NULL) || (Prime == NULL) || (PrimeLength > INT_MAX)) {
90 return FALSE;
91 }
92
93 if ((Generator != DH_GENERATOR_2) && (Generator != DH_GENERATOR_5)) {
94 return FALSE;
95 }
96
97 RetVal = (BOOLEAN)DH_generate_parameters_ex (DhContext, (UINT32)PrimeLength, (UINT32)Generator, NULL);
98 if (!RetVal) {
99 return FALSE;
100 }
101
102 DH_get0_pqg (DhContext, (const BIGNUM **)&BnP, NULL, NULL);
103 BN_bn2bin (BnP, Prime);
104
105 return TRUE;
106 }
107
108 /**
109 Sets generator and prime parameters for DH.
110
111 Given generator g, and prime number p, this function and sets DH
112 context accordingly.
113
114 If DhContext is NULL, then return FALSE.
115 If Prime is NULL, then return FALSE.
116
117 @param[in, out] DhContext Pointer to the DH context.
118 @param[in] Generator Value of generator.
119 @param[in] PrimeLength Length in bits of prime to be generated.
120 @param[in] Prime Pointer to the prime number.
121
122 @retval TRUE DH parameter setting succeeded.
123 @retval FALSE Value of Generator is not supported.
124 @retval FALSE Value of Generator is not suitable for the Prime.
125 @retval FALSE Value of Prime is not a prime number.
126 @retval FALSE Value of Prime is not a safe prime number.
127
128 **/
129 BOOLEAN
130 EFIAPI
131 DhSetParameter (
132 IN OUT VOID *DhContext,
133 IN UINTN Generator,
134 IN UINTN PrimeLength,
135 IN CONST UINT8 *Prime
136 )
137 {
138 DH *Dh;
139 BIGNUM *BnP;
140 BIGNUM *BnG;
141
142 //
143 // Check input parameters.
144 //
145 if ((DhContext == NULL) || (Prime == NULL) || (PrimeLength > INT_MAX)) {
146 return FALSE;
147 }
148
149 if ((Generator != DH_GENERATOR_2) && (Generator != DH_GENERATOR_5)) {
150 return FALSE;
151 }
152
153 //
154 // Set the generator and prime parameters for DH object.
155 //
156 Dh = (DH *)DhContext;
157 BnP = BN_bin2bn ((const unsigned char *)Prime, (int)(PrimeLength / 8), NULL);
158 BnG = BN_bin2bn ((const unsigned char *)&Generator, 1, NULL);
159 if ((BnP == NULL) || (BnG == NULL) || !DH_set0_pqg (Dh, BnP, NULL, BnG)) {
160 goto Error;
161 }
162
163 return TRUE;
164
165 Error:
166 BN_free (BnP);
167 BN_free (BnG);
168
169 return FALSE;
170 }
171
172 /**
173 Generates DH public key.
174
175 This function generates random secret exponent, and computes the public key, which is
176 returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.
177 If the PublicKey buffer is too small to hold the public key, FALSE is returned and
178 PublicKeySize is set to the required buffer size to obtain the public key.
179
180 If DhContext is NULL, then return FALSE.
181 If PublicKeySize is NULL, then return FALSE.
182 If PublicKeySize is large enough but PublicKey is NULL, then return FALSE.
183
184 @param[in, out] DhContext Pointer to the DH context.
185 @param[out] PublicKey Pointer to the buffer to receive generated public key.
186 @param[in, out] PublicKeySize On input, the size of PublicKey buffer in bytes.
187 On output, the size of data returned in PublicKey buffer in bytes.
188
189 @retval TRUE DH public key generation succeeded.
190 @retval FALSE DH public key generation failed.
191 @retval FALSE PublicKeySize is not large enough.
192
193 **/
194 BOOLEAN
195 EFIAPI
196 DhGenerateKey (
197 IN OUT VOID *DhContext,
198 OUT UINT8 *PublicKey,
199 IN OUT UINTN *PublicKeySize
200 )
201 {
202 BOOLEAN RetVal;
203 DH *Dh;
204 BIGNUM *DhPubKey;
205 INTN Size;
206
207 //
208 // Check input parameters.
209 //
210 if ((DhContext == NULL) || (PublicKeySize == NULL)) {
211 return FALSE;
212 }
213
214 if ((PublicKey == NULL) && (*PublicKeySize != 0)) {
215 return FALSE;
216 }
217
218 Dh = (DH *)DhContext;
219
220 RetVal = (BOOLEAN)DH_generate_key (DhContext);
221 if (RetVal) {
222 DH_get0_key (Dh, (const BIGNUM **)&DhPubKey, NULL);
223 Size = BN_num_bytes (DhPubKey);
224 if ((Size > 0) && (*PublicKeySize < (UINTN)Size)) {
225 *PublicKeySize = Size;
226 return FALSE;
227 }
228
229 if (PublicKey != NULL) {
230 BN_bn2bin (DhPubKey, PublicKey);
231 }
232
233 *PublicKeySize = Size;
234 }
235
236 return RetVal;
237 }
238
239 /**
240 Computes exchanged common key.
241
242 Given peer's public key, this function computes the exchanged common key, based on its own
243 context including value of prime modulus and random secret exponent.
244
245 If DhContext is NULL, then return FALSE.
246 If PeerPublicKey is NULL, then return FALSE.
247 If KeySize is NULL, then return FALSE.
248 If Key is NULL, then return FALSE.
249 If KeySize is not large enough, then return FALSE.
250
251 @param[in, out] DhContext Pointer to the DH context.
252 @param[in] PeerPublicKey Pointer to the peer's public key.
253 @param[in] PeerPublicKeySize Size of peer's public key in bytes.
254 @param[out] Key Pointer to the buffer to receive generated key.
255 @param[in, out] KeySize On input, the size of Key buffer in bytes.
256 On output, the size of data returned in Key buffer in bytes.
257
258 @retval TRUE DH exchanged key generation succeeded.
259 @retval FALSE DH exchanged key generation failed.
260 @retval FALSE KeySize is not large enough.
261
262 **/
263 BOOLEAN
264 EFIAPI
265 DhComputeKey (
266 IN OUT VOID *DhContext,
267 IN CONST UINT8 *PeerPublicKey,
268 IN UINTN PeerPublicKeySize,
269 OUT UINT8 *Key,
270 IN OUT UINTN *KeySize
271 )
272 {
273 BIGNUM *Bn;
274 INTN Size;
275
276 //
277 // Check input parameters.
278 //
279 if ((DhContext == NULL) || (PeerPublicKey == NULL) || (KeySize == NULL) || (Key == NULL)) {
280 return FALSE;
281 }
282
283 if (PeerPublicKeySize > INT_MAX) {
284 return FALSE;
285 }
286
287 Bn = BN_bin2bn (PeerPublicKey, (UINT32)PeerPublicKeySize, NULL);
288 if (Bn == NULL) {
289 return FALSE;
290 }
291
292 Size = DH_compute_key (Key, Bn, DhContext);
293 if (Size < 0) {
294 BN_free (Bn);
295 return FALSE;
296 }
297
298 if (*KeySize < (UINTN)Size) {
299 *KeySize = Size;
300 BN_free (Bn);
301 return FALSE;
302 }
303
304 *KeySize = Size;
305 BN_free (Bn);
306 return TRUE;
307 }