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