]>
Commit | Line | Data |
---|---|---|
a3bcde70 | 1 | /** @file\r |
9166f840 | 2 | Common interfaces to call Security library.\r |
a3bcde70 | 3 | \r |
f75a7f56 | 4 | Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r |
a3bcde70 | 5 | \r |
ecf98fbc | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
a3bcde70 HT |
7 | \r |
8 | **/\r | |
9 | \r | |
10 | #include "IpSecCryptIo.h"\r | |
11 | //\r | |
9166f840 | 12 | // The informations for the supported Encrypt/Decrpt Alogrithm.\r |
a3bcde70 | 13 | //\r |
9166f840 | 14 | GLOBAL_REMOVE_IF_UNREFERENCED ENCRYPT_ALGORITHM mIpsecEncryptAlgorithmList[IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE] = {\r |
68d3f2fb | 15 | {IKE_EALG_NULL, 0, 0, 1, NULL, NULL, NULL, NULL},\r |
f75a7f56 | 16 | {IKE_EALG_NONE, 0, 0, 1, NULL, NULL, NULL, NULL},\r |
9166f840 | 17 | {IKE_EALG_3DESCBC, 24, 8, 8, TdesGetContextSize, TdesInit, TdesCbcEncrypt, TdesCbcDecrypt},\r |
18 | {IKE_EALG_AESCBC, 16, 16, 16, AesGetContextSize, AesInit, AesCbcEncrypt, AesCbcDecrypt}\r | |
a3bcde70 | 19 | };\r |
9166f840 | 20 | \r |
21 | //\r | |
22 | // The informations for the supported Authentication algorithm\r | |
23 | //\r | |
24 | GLOBAL_REMOVE_IF_UNREFERENCED AUTH_ALGORITHM mIpsecAuthAlgorithmList[IPSEC_AUTH_ALGORITHM_LIST_SIZE] = {\r | |
25 | {IKE_AALG_NONE, 0, 0, 0, NULL, NULL, NULL, NULL},\r | |
26 | {IKE_AALG_NULL, 0, 0, 0, NULL, NULL, NULL, NULL},\r | |
27 | {IKE_AALG_SHA1HMAC, 20, 12, 64, HmacSha1GetContextSize, HmacSha1Init, HmacSha1Update, HmacSha1Final}\r | |
28 | };\r | |
29 | \r | |
a3bcde70 | 30 | //\r |
9166f840 | 31 | // The information for the supported Hash aglorithm\r |
a3bcde70 | 32 | //\r |
9166f840 | 33 | GLOBAL_REMOVE_IF_UNREFERENCED HASH_ALGORITHM mIpsecHashAlgorithmList[IPSEC_HASH_ALGORITHM_LIST_SIZE] = {\r |
68d3f2fb | 34 | {IKE_AALG_NONE, 0, 0, 0, NULL, NULL, NULL, NULL},\r |
35 | {IKE_AALG_NULL, 0, 0, 0, NULL, NULL, NULL, NULL},\r | |
9166f840 | 36 | {IKE_AALG_SHA1HMAC, 20, 12, 64, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final}\r |
a3bcde70 HT |
37 | };\r |
38 | \r | |
9166f840 | 39 | BOOLEAN mInitialRandomSeed = FALSE;\r |
a3bcde70 HT |
40 | \r |
41 | /**\r | |
d1c85a17 | 42 | Get the block size of specified encryption algorithm.\r |
a3bcde70 | 43 | \r |
9166f840 | 44 | @param[in] AlgorithmId The encryption algorithm ID.\r |
a3bcde70 HT |
45 | \r |
46 | @return The value of block size.\r | |
47 | \r | |
48 | **/\r | |
49 | UINTN\r | |
50 | IpSecGetEncryptBlockSize (\r | |
51 | IN UINT8 AlgorithmId\r | |
52 | )\r | |
53 | {\r | |
54 | UINT8 Index;\r | |
55 | \r | |
56 | for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {\r | |
57 | if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {\r | |
a3bcde70 HT |
58 | return mIpsecEncryptAlgorithmList[Index].BlockSize;\r |
59 | }\r | |
60 | }\r | |
61 | \r | |
62 | return (UINTN) -1;\r | |
63 | }\r | |
64 | \r | |
65 | /**\r | |
d1c85a17 | 66 | Get the key length of the specified encryption algorithm.\r |
9166f840 | 67 | \r |
68 | @param[in] AlgorithmId The encryption algorithm ID.\r | |
69 | \r | |
70 | @return The value of key length.\r | |
71 | \r | |
72 | **/\r | |
73 | UINTN\r | |
74 | IpSecGetEncryptKeyLength (\r | |
75 | IN UINT8 AlgorithmId\r | |
76 | )\r | |
77 | {\r | |
78 | UINT8 Index;\r | |
79 | \r | |
80 | for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {\r | |
81 | if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {\r | |
82 | return mIpsecEncryptAlgorithmList[Index].KeyLength;\r | |
83 | }\r | |
84 | }\r | |
85 | \r | |
86 | return (UINTN) -1;\r | |
87 | }\r | |
88 | \r | |
89 | /**\r | |
d1c85a17 | 90 | Get the IV size of the specified encryption algorithm.\r |
a3bcde70 | 91 | \r |
9166f840 | 92 | @param[in] AlgorithmId The encryption algorithm ID.\r |
a3bcde70 HT |
93 | \r |
94 | @return The value of IV size.\r | |
95 | \r | |
96 | **/\r | |
97 | UINTN\r | |
98 | IpSecGetEncryptIvLength (\r | |
99 | IN UINT8 AlgorithmId\r | |
100 | )\r | |
101 | {\r | |
102 | UINT8 Index;\r | |
103 | \r | |
104 | for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {\r | |
105 | if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {\r | |
a3bcde70 HT |
106 | return mIpsecEncryptAlgorithmList[Index].IvLength;\r |
107 | }\r | |
108 | }\r | |
109 | \r | |
110 | return (UINTN) -1;\r | |
111 | }\r | |
112 | \r | |
113 | /**\r | |
9166f840 | 114 | Get the HMAC digest length by the specified Algorithm ID.\r |
115 | \r | |
116 | @param[in] AlgorithmId The specified Alogrithm ID.\r | |
117 | \r | |
118 | @return The digest length of the specified Authentication Algorithm ID.\r | |
119 | \r | |
120 | **/\r | |
121 | UINTN\r | |
122 | IpSecGetHmacDigestLength (\r | |
123 | IN UINT8 AlgorithmId\r | |
124 | )\r | |
125 | {\r | |
126 | UINT8 Index;\r | |
127 | \r | |
128 | for (Index = 0; Index < IPSEC_AUTH_ALGORITHM_LIST_SIZE; Index++) {\r | |
129 | if (mIpsecAuthAlgorithmList[Index].AlgorithmId == AlgorithmId) {\r | |
130 | //\r | |
131 | // Return the Digest Length of the Algorithm.\r | |
132 | //\r | |
133 | return mIpsecAuthAlgorithmList[Index].DigestLength;\r | |
134 | }\r | |
135 | }\r | |
136 | \r | |
137 | return 0;\r | |
138 | }\r | |
139 | \r | |
140 | /**\r | |
d1c85a17 | 141 | Get the ICV size of the specified Authenticaion algorithm.\r |
a3bcde70 | 142 | \r |
9166f840 | 143 | @param[in] AlgorithmId The Authentication algorithm ID.\r |
a3bcde70 HT |
144 | \r |
145 | @return The value of ICV size.\r | |
146 | \r | |
147 | **/\r | |
148 | UINTN\r | |
149 | IpSecGetIcvLength (\r | |
9166f840 | 150 | IN UINT8 AlgorithmId\r |
a3bcde70 HT |
151 | )\r |
152 | {\r | |
153 | UINT8 Index;\r | |
9166f840 | 154 | \r |
a3bcde70 | 155 | for (Index = 0; Index < IPSEC_AUTH_ALGORITHM_LIST_SIZE; Index++) {\r |
9166f840 | 156 | if (AlgorithmId == mIpsecAuthAlgorithmList[Index].AlgorithmId) {\r |
a3bcde70 HT |
157 | return mIpsecAuthAlgorithmList[Index].IcvLength;\r |
158 | }\r | |
159 | }\r | |
9166f840 | 160 | \r |
a3bcde70 HT |
161 | return (UINTN) -1;\r |
162 | }\r | |
163 | \r | |
164 | /**\r | |
165 | Generate a random data for IV. If the IvSize is zero, not needed to create\r | |
166 | IV and return EFI_SUCCESS.\r | |
167 | \r | |
168 | @param[in] IvBuffer The pointer of the IV buffer.\r | |
9166f840 | 169 | @param[in] IvSize The IV size in bytes.\r |
a3bcde70 HT |
170 | \r |
171 | @retval EFI_SUCCESS Create a random data for IV.\r | |
172 | \r | |
173 | **/\r | |
174 | EFI_STATUS\r | |
175 | IpSecGenerateIv (\r | |
176 | IN UINT8 *IvBuffer,\r | |
177 | IN UINTN IvSize\r | |
178 | )\r | |
179 | {\r | |
180 | if (IvSize != 0) {\r | |
9166f840 | 181 | return IpSecCryptoIoGenerateRandomBytes (IvBuffer, IvSize);\r |
182 | }\r | |
f75a7f56 | 183 | \r |
9166f840 | 184 | return EFI_SUCCESS;\r |
185 | }\r | |
186 | \r | |
187 | /**\r | |
d1c85a17 | 188 | Get index of the specified encryption algorithm from the mIpsecEncryptAlgorithmList.\r |
9166f840 | 189 | \r |
190 | @param[in] AlgorithmId The encryption algorithm ID.\r | |
191 | \r | |
192 | @return the index.\r | |
f75a7f56 | 193 | \r |
9166f840 | 194 | **/\r |
195 | UINTN\r | |
196 | IpSecGetIndexFromEncList (\r | |
197 | IN UINT8 AlgorithmId\r | |
198 | )\r | |
199 | {\r | |
200 | UINT8 Index;\r | |
f75a7f56 | 201 | \r |
9166f840 | 202 | for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {\r |
203 | if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {\r | |
204 | return Index;\r | |
205 | }\r | |
206 | }\r | |
f75a7f56 | 207 | \r |
9166f840 | 208 | return (UINTN) -1;\r |
209 | }\r | |
210 | \r | |
211 | /**\r | |
d1c85a17 | 212 | Get index of the specified encryption algorithm from the mIpsecAuthAlgorithmList.\r |
9166f840 | 213 | \r |
214 | @param[in] AlgorithmId The encryption algorithm ID.\r | |
215 | \r | |
216 | @return the index.\r | |
f75a7f56 | 217 | \r |
9166f840 | 218 | **/\r |
219 | UINTN\r | |
220 | IpSecGetIndexFromAuthList (\r | |
221 | IN UINT8 AlgorithmId\r | |
222 | )\r | |
223 | {\r | |
224 | UINT8 Index;\r | |
f75a7f56 | 225 | \r |
9166f840 | 226 | for (Index = 0; Index < IPSEC_AUTH_ALGORITHM_LIST_SIZE; Index++) {\r |
227 | if (AlgorithmId == mIpsecAuthAlgorithmList[Index].AlgorithmId) {\r | |
228 | //\r | |
229 | // The BlockSize is same with IvSize.\r | |
230 | //\r | |
231 | return Index;\r | |
232 | }\r | |
233 | }\r | |
f75a7f56 | 234 | \r |
9166f840 | 235 | return (UINTN) -1;\r |
236 | }\r | |
237 | \r | |
238 | /**\r | |
239 | Encrypt the buffer.\r | |
240 | \r | |
241 | This function calls relevant encryption interface from CryptoLib according to\r | |
d1c85a17 | 242 | the input algorithm ID. The InData should be multiple of block size. This function\r |
9166f840 | 243 | doesn't perform the padding. If it has the Ivec data, the length of it should be\r |
244 | same with the block size. The block size is different from the different algorithm.\r | |
245 | \r | |
d1c85a17 | 246 | @param[in] AlgorithmId The Algorithm identification defined in RFC.\r |
9166f840 | 247 | @param[in] Key Pointer to the buffer containing encrypting key.\r |
76389e18 | 248 | @param[in] KeyBits The length of the key in bits.\r |
d1c85a17 | 249 | @param[in] Ivec Point to the buffer containing the Initialization\r |
9166f840 | 250 | Vector (IV) data.\r |
251 | @param[in] InData Point to the buffer containing the data to be\r | |
252 | encrypted.\r | |
253 | @param[in] InDataLength The length of InData in Bytes.\r | |
254 | @param[out] OutData Point to the buffer that receives the encryption\r | |
255 | output.\r | |
256 | \r | |
257 | @retval EFI_UNSUPPORTED The input Algorithm is not supported.\r | |
258 | @retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.\r | |
259 | @retval EFI_SUCCESS The operation completed successfully.\r | |
260 | \r | |
261 | **/\r | |
262 | EFI_STATUS\r | |
263 | IpSecCryptoIoEncrypt (\r | |
264 | IN CONST UINT8 AlgorithmId,\r | |
265 | IN CONST UINT8 *Key,\r | |
266 | IN CONST UINTN KeyBits,\r | |
267 | IN CONST UINT8 *Ivec, OPTIONAL\r | |
268 | IN UINT8 *InData,\r | |
269 | IN UINTN InDataLength,\r | |
270 | OUT UINT8 *OutData\r | |
271 | )\r | |
f75a7f56 | 272 | {\r |
9166f840 | 273 | UINTN Index;\r |
274 | UINTN ContextSize;\r | |
275 | UINT8 *Context;\r | |
276 | EFI_STATUS Status;\r | |
f75a7f56 | 277 | \r |
9166f840 | 278 | Status = EFI_UNSUPPORTED;\r |
f75a7f56 | 279 | \r |
9166f840 | 280 | switch (AlgorithmId) {\r |
281 | \r | |
282 | case IKE_EALG_NULL:\r | |
283 | case IKE_EALG_NONE:\r | |
284 | CopyMem (OutData, InData, InDataLength);\r | |
285 | return EFI_SUCCESS;\r | |
286 | \r | |
287 | case IKE_EALG_3DESCBC:\r | |
288 | case IKE_EALG_AESCBC:\r | |
289 | Index = IpSecGetIndexFromEncList (AlgorithmId);\r | |
290 | if (Index == -1) {\r | |
291 | return Status;\r | |
292 | }\r | |
293 | //\r | |
294 | // Get Context Size\r | |
295 | //\r | |
296 | ContextSize = mIpsecEncryptAlgorithmList[Index].CipherGetContextSize ();\r | |
297 | Context = AllocateZeroPool (ContextSize);\r | |
298 | \r | |
299 | if (Context == NULL) {\r | |
300 | return EFI_OUT_OF_RESOURCES;\r | |
301 | }\r | |
a3bcde70 | 302 | //\r |
9166f840 | 303 | // Initiate Context\r |
a3bcde70 | 304 | //\r |
9166f840 | 305 | if (mIpsecEncryptAlgorithmList[Index].CipherInitiate (Context, Key, KeyBits)) {\r |
306 | if (mIpsecEncryptAlgorithmList[Index].CipherEncrypt (Context, InData, InDataLength, Ivec, OutData)) {\r | |
307 | Status = EFI_SUCCESS;\r | |
308 | }\r | |
309 | }\r | |
310 | break;\r | |
311 | \r | |
312 | default:\r | |
313 | return Status;\r | |
314 | \r | |
315 | }\r | |
316 | \r | |
317 | if (Context != NULL) {\r | |
318 | FreePool (Context);\r | |
319 | }\r | |
f75a7f56 | 320 | \r |
9166f840 | 321 | return Status;\r |
322 | }\r | |
323 | \r | |
324 | /**\r | |
325 | Decrypts the buffer.\r | |
326 | \r | |
327 | This function calls relevant Decryption interface from CryptoLib according to\r | |
d1c85a17 | 328 | the input algorithm ID. The InData should be multiple of block size. This function\r |
9166f840 | 329 | doesn't perform the padding. If it has the Ivec data, the length of it should be\r |
330 | same with the block size. The block size is different from the different algorithm.\r | |
331 | \r | |
d1c85a17 | 332 | @param[in] AlgorithmId The Algorithm identification defined in RFC.\r |
9166f840 | 333 | @param[in] Key Pointer to the buffer containing encrypting key.\r |
76389e18 | 334 | @param[in] KeyBits The length of the key in bits.\r |
d1c85a17 | 335 | @param[in] Ivec Point to the buffer containing the Initialization\r |
9166f840 | 336 | Vector (IV) data.\r |
337 | @param[in] InData Point to the buffer containing the data to be\r | |
76389e18 | 338 | decrypted.\r |
9166f840 | 339 | @param[in] InDataLength The length of InData in Bytes.\r |
340 | @param[out] OutData Pointer to the buffer that receives the decryption\r | |
341 | output.\r | |
342 | \r | |
343 | @retval EFI_UNSUPPORTED The input Algorithm is not supported.\r | |
344 | @retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.\r | |
345 | @retval EFI_SUCCESS The operation completed successfully.\r | |
346 | \r | |
347 | **/\r | |
348 | EFI_STATUS\r | |
349 | IpSecCryptoIoDecrypt (\r | |
350 | IN CONST UINT8 AlgorithmId,\r | |
351 | IN CONST UINT8 *Key,\r | |
352 | IN CONST UINTN KeyBits,\r | |
353 | IN CONST UINT8 *Ivec, OPTIONAL\r | |
354 | IN UINT8 *InData,\r | |
355 | IN UINTN InDataLength,\r | |
356 | OUT UINT8 *OutData\r | |
357 | )\r | |
f75a7f56 | 358 | {\r |
9166f840 | 359 | UINTN Index;\r |
360 | UINTN ContextSize;\r | |
361 | UINT8 *Context;\r | |
362 | EFI_STATUS Status;\r | |
363 | \r | |
364 | Status = EFI_UNSUPPORTED;\r | |
365 | \r | |
366 | switch (AlgorithmId) {\r | |
367 | \r | |
368 | case IKE_EALG_NULL:\r | |
369 | case IKE_EALG_NONE:\r | |
370 | CopyMem (OutData, InData, InDataLength);\r | |
a3bcde70 | 371 | return EFI_SUCCESS;\r |
9166f840 | 372 | \r |
373 | case IKE_EALG_3DESCBC:\r | |
374 | case IKE_EALG_AESCBC:\r | |
375 | Index = IpSecGetIndexFromEncList(AlgorithmId);\r | |
376 | if (Index == -1) {\r | |
377 | return Status;\r | |
378 | }\r | |
379 | \r | |
380 | //\r | |
381 | // Get Context Size\r | |
382 | //\r | |
383 | ContextSize = mIpsecEncryptAlgorithmList[Index].CipherGetContextSize();\r | |
384 | Context = AllocateZeroPool (ContextSize);\r | |
385 | if (Context == NULL) {\r | |
386 | return EFI_OUT_OF_RESOURCES;\r | |
387 | }\r | |
388 | \r | |
389 | //\r | |
390 | // Initiate Context\r | |
391 | //\r | |
392 | if (mIpsecEncryptAlgorithmList[Index].CipherInitiate (Context, Key, KeyBits)) {\r | |
393 | if (mIpsecEncryptAlgorithmList[Index].CipherDecrypt (Context, InData, InDataLength, Ivec, OutData)) {\r | |
f75a7f56 | 394 | Status = EFI_SUCCESS;\r |
9166f840 | 395 | }\r |
396 | }\r | |
397 | break;\r | |
398 | \r | |
399 | default:\r | |
400 | return Status;\r | |
401 | }\r | |
402 | \r | |
403 | if (Context != NULL) {\r | |
404 | FreePool (Context);\r | |
a3bcde70 | 405 | }\r |
9166f840 | 406 | \r |
407 | return Status;\r | |
408 | }\r | |
409 | \r | |
410 | /**\r | |
411 | Digests the Payload with key and store the result into the OutData.\r | |
412 | \r | |
413 | This function calls relevant Hmac interface from CryptoLib according to\r | |
d1c85a17 | 414 | the input algorithm ID. It computes all datas from InDataFragment and output\r |
9166f840 | 415 | the result into the OutData buffer. If the OutDataSize is larger than the related\r |
d1c85a17 | 416 | HMAC algorithm output size, return EFI_INVALID_PARAMETER.\r |
f75a7f56 | 417 | \r |
9166f840 | 418 | @param[in] AlgorithmId The authentication Identification.\r |
419 | @param[in] Key Pointer of the authentication key.\r | |
420 | @param[in] KeyLength The length of the Key in bytes.\r | |
421 | @param[in] InDataFragment The list contains all data to be authenticated.\r | |
422 | @param[in] FragmentCount The size of the InDataFragment.\r | |
423 | @param[out] OutData For in, the buffer to receive the output data.\r | |
424 | For out, the buffer contains the authenticated data.\r | |
425 | @param[in] OutDataSize The size of the buffer of OutData.\r | |
426 | \r | |
427 | @retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.\r | |
428 | @retval EFI_INVALID_PARAMETER The OutData buffer size is larger than algorithm digest size.\r | |
429 | @retval EFI_SUCCESS Authenticate the payload successfully.\r | |
430 | @retval otherwise Authentication of the payload fails.\r | |
431 | \r | |
432 | **/\r | |
433 | EFI_STATUS\r | |
434 | IpSecCryptoIoHmac (\r | |
435 | IN CONST UINT8 AlgorithmId,\r | |
436 | IN CONST UINT8 *Key,\r | |
437 | IN UINTN KeyLength,\r | |
438 | IN HASH_DATA_FRAGMENT *InDataFragment,\r | |
439 | IN UINTN FragmentCount,\r | |
440 | OUT UINT8 *OutData,\r | |
441 | IN UINTN OutDataSize\r | |
442 | )\r | |
443 | {\r | |
444 | UINTN ContextSize;\r | |
445 | UINTN Index;\r | |
446 | UINT8 FragmentIndex;\r | |
447 | UINT8 *HashContext;\r | |
448 | EFI_STATUS Status;\r | |
449 | UINT8 *OutHashData;\r | |
450 | UINTN OutHashSize;\r | |
451 | \r | |
452 | Status = EFI_UNSUPPORTED;\r | |
453 | OutHashData = NULL;\r | |
454 | \r | |
455 | OutHashSize = IpSecGetHmacDigestLength (AlgorithmId);\r | |
456 | //\r | |
457 | // If the expected hash data size is larger than the related Hash algorithm\r | |
458 | // output length, return EFI_INVALID_PARAMETER.\r | |
459 | //\r | |
460 | if (OutDataSize > OutHashSize) {\r | |
461 | return EFI_INVALID_PARAMETER;\r | |
462 | }\r | |
463 | OutHashData = AllocatePool (OutHashSize);\r | |
464 | \r | |
465 | if (OutHashData == NULL) {\r | |
466 | return EFI_OUT_OF_RESOURCES;\r | |
467 | }\r | |
468 | \r | |
469 | switch (AlgorithmId) {\r | |
470 | \r | |
471 | case IKE_AALG_NONE :\r | |
472 | case IKE_AALG_NULL :\r | |
473 | return EFI_SUCCESS;\r | |
474 | \r | |
475 | case IKE_AALG_SHA1HMAC:\r | |
476 | Index = IpSecGetIndexFromAuthList (AlgorithmId);\r | |
477 | if (Index == -1) {\r | |
478 | return Status;\r | |
479 | }\r | |
480 | \r | |
481 | //\r | |
482 | // Get Context Size\r | |
483 | //\r | |
484 | ContextSize = mIpsecAuthAlgorithmList[Index].HmacGetContextSize();\r | |
485 | HashContext = AllocateZeroPool (ContextSize);\r | |
486 | \r | |
487 | if (HashContext == NULL) {\r | |
488 | Status = EFI_OUT_OF_RESOURCES;\r | |
489 | goto Exit;\r | |
490 | }\r | |
491 | \r | |
492 | //\r | |
493 | // Initiate HMAC context and hash the input data.\r | |
494 | //\r | |
495 | if (mIpsecAuthAlgorithmList[Index].HmacInitiate(HashContext, Key, KeyLength)) {\r | |
496 | for (FragmentIndex = 0; FragmentIndex < FragmentCount; FragmentIndex++) {\r | |
497 | if (!mIpsecAuthAlgorithmList[Index].HmacUpdate (\r | |
498 | HashContext,\r | |
499 | InDataFragment[FragmentIndex].Data,\r | |
500 | InDataFragment[FragmentIndex].DataSize\r | |
501 | )\r | |
502 | ) {\r | |
503 | goto Exit;\r | |
504 | }\r | |
505 | }\r | |
506 | if (mIpsecAuthAlgorithmList[Index].HmacFinal (HashContext, OutHashData)) {\r | |
507 | //\r | |
508 | // In some cases, like the Icv computing, the Icv size might be less than\r | |
509 | // the key length size, so copy the part of hash data to the OutData.\r | |
510 | //\r | |
511 | CopyMem (OutData, OutHashData, OutDataSize);\r | |
512 | Status = EFI_SUCCESS;\r | |
513 | }\r | |
514 | \r | |
515 | goto Exit;\r | |
f75a7f56 LG |
516 | }\r |
517 | \r | |
9166f840 | 518 | default:\r |
519 | return Status;\r | |
520 | }\r | |
521 | \r | |
522 | Exit:\r | |
523 | if (HashContext != NULL) {\r | |
524 | FreePool (HashContext);\r | |
525 | }\r | |
526 | if (OutHashData != NULL) {\r | |
527 | FreePool (OutHashData);\r | |
528 | }\r | |
529 | \r | |
530 | return Status;\r | |
531 | }\r | |
532 | \r | |
533 | /**\r | |
534 | Digests the Payload and store the result into the OutData.\r | |
535 | \r | |
536 | This function calls relevant Hash interface from CryptoLib according to\r | |
d1c85a17 | 537 | the input algorithm ID. It computes all datas from InDataFragment and output\r |
9166f840 | 538 | the result into the OutData buffer. If the OutDataSize is larger than the related\r |
d1c85a17 | 539 | Hash algorithm output size, return EFI_INVALID_PARAMETER.\r |
9166f840 | 540 | \r |
541 | @param[in] AlgorithmId The authentication Identification.\r | |
542 | @param[in] InDataFragment A list contains all data to be authenticated.\r | |
543 | @param[in] FragmentCount The size of the InDataFragment.\r | |
544 | @param[out] OutData For in, the buffer to receive the output data.\r | |
545 | For out, the buffer contains the authenticated data.\r | |
546 | @param[in] OutDataSize The size of the buffer of OutData.\r | |
547 | \r | |
548 | @retval EFI_UNSUPPORTED If the AuthAlg is not in the support list.\r | |
549 | @retval EFI_SUCCESS Authenticated the payload successfully.\r | |
550 | @retval EFI_INVALID_PARAMETER If the OutDataSize is larger than the related Hash\r | |
551 | algorithm could handle.\r | |
552 | @retval otherwise Authentication of the payload failed.\r | |
553 | \r | |
554 | **/\r | |
555 | EFI_STATUS\r | |
556 | IpSecCryptoIoHash (\r | |
557 | IN CONST UINT8 AlgorithmId,\r | |
558 | IN HASH_DATA_FRAGMENT *InDataFragment,\r | |
559 | IN UINTN FragmentCount,\r | |
560 | OUT UINT8 *OutData,\r | |
561 | IN UINTN OutDataSize\r | |
562 | )\r | |
563 | {\r | |
564 | UINTN ContextSize;\r | |
565 | UINTN Index;\r | |
566 | UINT8 FragmentIndex;\r | |
567 | UINT8 *HashContext;\r | |
568 | EFI_STATUS Status;\r | |
569 | UINT8 *OutHashData;\r | |
570 | UINTN OutHashSize;\r | |
571 | \r | |
572 | Status = EFI_UNSUPPORTED;\r | |
573 | OutHashData = NULL;\r | |
f75a7f56 | 574 | \r |
9166f840 | 575 | OutHashSize = IpSecGetHmacDigestLength (AlgorithmId);\r |
576 | //\r | |
577 | // If the expected hash data size is larger than the related Hash algorithm\r | |
f75a7f56 | 578 | // output length, return EFI_INVALID_PARAMETER.\r |
9166f840 | 579 | //\r |
580 | if (OutDataSize > OutHashSize) {\r | |
581 | return EFI_INVALID_PARAMETER;\r | |
582 | }\r | |
583 | OutHashData = AllocatePool (OutHashSize);\r | |
584 | if (OutHashData == NULL) {\r | |
585 | return EFI_OUT_OF_RESOURCES;\r | |
586 | }\r | |
f75a7f56 | 587 | \r |
9166f840 | 588 | switch (AlgorithmId) {\r |
589 | \r | |
590 | case IKE_AALG_NONE:\r | |
591 | case IKE_AALG_NULL:\r | |
592 | return EFI_SUCCESS;\r | |
593 | \r | |
594 | case IKE_AALG_SHA1HMAC:\r | |
595 | Index = IpSecGetIndexFromAuthList (AlgorithmId);\r | |
596 | if (Index == -1) {\r | |
597 | return Status;\r | |
598 | }\r | |
599 | //\r | |
600 | // Get Context Size\r | |
601 | //\r | |
602 | ContextSize = mIpsecHashAlgorithmList[Index].HashGetContextSize();\r | |
603 | HashContext = AllocateZeroPool (ContextSize);\r | |
604 | if (HashContext == NULL) {\r | |
605 | Status = EFI_OUT_OF_RESOURCES;\r | |
606 | goto Exit;\r | |
607 | }\r | |
f75a7f56 | 608 | \r |
9166f840 | 609 | //\r |
610 | // Initiate Hash context and hash the input data.\r | |
611 | //\r | |
612 | if (mIpsecHashAlgorithmList[Index].HashInitiate(HashContext)) {\r | |
613 | for (FragmentIndex = 0; FragmentIndex < FragmentCount; FragmentIndex++) {\r | |
614 | if (!mIpsecHashAlgorithmList[Index].HashUpdate (\r | |
615 | HashContext,\r | |
616 | InDataFragment[FragmentIndex].Data,\r | |
617 | InDataFragment[FragmentIndex].DataSize\r | |
618 | )\r | |
619 | ) {\r | |
620 | goto Exit;\r | |
621 | }\r | |
622 | }\r | |
623 | if (mIpsecHashAlgorithmList[Index].HashFinal (HashContext, OutHashData)) {\r | |
624 | //\r | |
625 | // In some cases, like the Icv computing, the Icv size might be less than\r | |
626 | // the key length size, so copy the part of hash data to the OutData.\r | |
627 | //\r | |
f75a7f56 | 628 | CopyMem (OutData, OutHashData, OutDataSize);\r |
9166f840 | 629 | Status = EFI_SUCCESS;\r |
630 | }\r | |
f75a7f56 LG |
631 | \r |
632 | goto Exit;\r | |
633 | }\r | |
634 | \r | |
9166f840 | 635 | default:\r |
636 | return Status;\r | |
637 | }\r | |
638 | \r | |
639 | Exit:\r | |
640 | if (HashContext != NULL) {\r | |
641 | FreePool (HashContext);\r | |
642 | }\r | |
643 | if (OutHashData != NULL) {\r | |
644 | FreePool (OutHashData);\r | |
645 | }\r | |
646 | \r | |
647 | return Status;\r | |
648 | }\r | |
649 | \r | |
650 | /**\r | |
651 | Generates the Diffie-Hellman public key.\r | |
652 | \r | |
653 | This function first initiate a DHContext, then call the DhSetParameter() to set\r | |
d1c85a17 | 654 | the prime and primelength, at end call the DhGenerateKey() to generates random\r |
9166f840 | 655 | secret exponent, and computes the public key. The output returned via parameter\r |
656 | PublicKey and PublicKeySize. DH context is updated accordingly. If the PublicKey\r | |
657 | buffer is too small to hold the public key, EFI_INVALID_PARAMETER is returned\r | |
658 | and PublicKeySize is set to the required buffer size to obtain the public key.\r | |
659 | \r | |
660 | @param[in, out] DhContext Pointer to the DH context.\r | |
d1c85a17 | 661 | @param[in] Generator Value of generator.\r |
9166f840 | 662 | @param[in] PrimeLength Length in bits of prime to be generated.\r |
663 | @param[in] Prime Pointer to the buffer to receive the generated\r | |
664 | prime number.\r | |
665 | @param[out] PublicKey Pointer to the buffer to receive generated public key.\r | |
666 | @param[in, out] PublicKeySize For in, the size of PublicKey buffer in bytes.\r | |
667 | For out, the size of data returned in PublicKey\r | |
668 | buffer in bytes.\r | |
669 | \r | |
d1c85a17 | 670 | @retval EFI_SUCCESS The operation performs successfully.\r |
9166f840 | 671 | @retval Otherwise The operation is failed.\r |
672 | \r | |
673 | **/\r | |
674 | EFI_STATUS\r | |
675 | IpSecCryptoIoDhGetPublicKey (\r | |
676 | IN OUT UINT8 **DhContext,\r | |
677 | IN UINTN Generator,\r | |
678 | IN UINTN PrimeLength,\r | |
679 | IN CONST UINT8 *Prime,\r | |
680 | OUT UINT8 *PublicKey,\r | |
681 | IN OUT UINTN *PublicKeySize\r | |
f75a7f56 | 682 | )\r |
9166f840 | 683 | {\r |
684 | EFI_STATUS Status;\r | |
f75a7f56 | 685 | \r |
9166f840 | 686 | *DhContext = DhNew ();\r |
687 | ASSERT (*DhContext != NULL);\r | |
688 | if (!DhSetParameter (*DhContext, Generator, PrimeLength, Prime)) {\r | |
689 | Status = EFI_INVALID_PARAMETER;\r | |
690 | goto Exit;\r | |
691 | }\r | |
692 | \r | |
693 | if (!DhGenerateKey (*DhContext, PublicKey, PublicKeySize)) {\r | |
694 | Status = EFI_INVALID_PARAMETER;\r | |
695 | goto Exit;\r | |
696 | }\r | |
697 | return EFI_SUCCESS;\r | |
698 | \r | |
699 | Exit:\r | |
700 | if (*DhContext != NULL) {\r | |
701 | DhFree (*DhContext);\r | |
702 | DhContext = NULL;\r | |
703 | }\r | |
f75a7f56 | 704 | \r |
9166f840 | 705 | return Status;\r |
706 | }\r | |
707 | \r | |
708 | /**\r | |
709 | Generates exchanged common key.\r | |
710 | \r | |
711 | Given peer's public key, this function computes the exchanged common key, based\r | |
712 | on its own context including value of prime modulus and random secret exponent.\r | |
713 | \r | |
714 | @param[in, out] DhContext Pointer to the DH context.\r | |
715 | @param[in] PeerPublicKey Pointer to the peer's Public Key.\r | |
716 | @param[in] PeerPublicKeySize Size of peer's public key in bytes.\r | |
717 | @param[out] Key Pointer to the buffer to receive generated key.\r | |
718 | @param[in, out] KeySize For in, the size of Key buffer in bytes.\r | |
719 | For out, the size of data returned in Key\r | |
720 | buffer in bytes.\r | |
721 | \r | |
d1c85a17 | 722 | @retval EFI_SUCCESS The operation performs successfully.\r |
9166f840 | 723 | @retval Otherwise The operation is failed.\r |
724 | \r | |
725 | **/\r | |
726 | EFI_STATUS\r | |
727 | IpSecCryptoIoDhComputeKey (\r | |
f75a7f56 | 728 | IN OUT UINT8 *DhContext,\r |
9166f840 | 729 | IN CONST UINT8 *PeerPublicKey,\r |
730 | IN UINTN PeerPublicKeySize,\r | |
731 | OUT UINT8 *Key,\r | |
732 | IN OUT UINTN *KeySize\r | |
733 | )\r | |
734 | {\r | |
735 | if (!DhComputeKey (DhContext, PeerPublicKey, PeerPublicKeySize, Key, KeySize)) {\r | |
736 | return EFI_INVALID_PARAMETER;\r | |
737 | }\r | |
738 | \r | |
739 | return EFI_SUCCESS;\r | |
740 | }\r | |
741 | \r | |
742 | /**\r | |
743 | Releases the DH context. If DhContext is NULL, return EFI_INVALID_PARAMETER.\r | |
744 | \r | |
745 | @param[in, out] DhContext Pointer to the DH context to be freed.\r | |
746 | \r | |
d1c85a17 | 747 | @retval EFI_SUCCESS The operation performs successfully.\r |
9166f840 | 748 | @retval EFI_INVALID_PARAMETER The DhContext is NULL.\r |
f75a7f56 | 749 | \r |
9166f840 | 750 | **/\r |
751 | EFI_STATUS\r | |
752 | IpSecCryptoIoFreeDh (\r | |
753 | IN OUT UINT8 **DhContext\r | |
754 | )\r | |
f75a7f56 | 755 | {\r |
9166f840 | 756 | if (*DhContext == NULL) {\r |
757 | return EFI_INVALID_PARAMETER;\r | |
758 | }\r | |
759 | \r | |
760 | DhFree (*DhContext);\r | |
a3bcde70 HT |
761 | return EFI_SUCCESS;\r |
762 | }\r | |
9166f840 | 763 | \r |
764 | /**\r | |
765 | Generates random numbers of specified size.\r | |
766 | \r | |
767 | If the Random Generator wasn't initiated, initiate it first, then call RandomBytes.\r | |
768 | \r | |
769 | @param[out] OutBuffer Pointer to buffer to receive random value.\r | |
d1c85a17 | 770 | @param[in] Bytes Size of random bytes to generate.\r |
9166f840 | 771 | \r |
d1c85a17 | 772 | @retval EFI_SUCCESS The operation performs successfully.\r |
9166f840 | 773 | @retval Otherwise The operation is failed.\r |
774 | \r | |
775 | **/\r | |
776 | EFI_STATUS\r | |
777 | IpSecCryptoIoGenerateRandomBytes (\r | |
778 | OUT UINT8* OutBuffer,\r | |
779 | IN UINTN Bytes\r | |
780 | )\r | |
781 | {\r | |
782 | if (!mInitialRandomSeed) {\r | |
783 | RandomSeed (NULL, 0);\r | |
784 | mInitialRandomSeed = TRUE;\r | |
785 | }\r | |
786 | if (RandomBytes (OutBuffer, Bytes)) {\r | |
787 | return EFI_SUCCESS;\r | |
788 | } else {\r | |
789 | return EFI_INVALID_PARAMETER;\r | |
790 | }\r | |
791 | }\r | |
792 | \r | |
793 | /**\r | |
794 | Authenticate data with the certificate.\r | |
795 | \r | |
796 | @param[in] InData Pointer to the Data to be signed.\r | |
797 | @param[in] InDataSize InData size in bytes.\r | |
798 | @param[in] PrivateKey Pointer to the private key.\r | |
799 | @param[in] PrivateKeySize The size of Private Key in bytes.\r | |
800 | @param[in] KeyPassWord Pointer to the password for retrieving private key.\r | |
801 | @param[in] KeyPwdSize The size of Key Password in bytes.\r | |
802 | @param[out] OutData The pointer to the signed data.\r | |
803 | @param[in, out] OutDataSize Pointer to contain the size of out data.\r | |
f75a7f56 | 804 | \r |
9166f840 | 805 | **/\r |
806 | VOID\r | |
807 | IpSecCryptoIoAuthDataWithCertificate (\r | |
808 | IN UINT8 *InData,\r | |
809 | IN UINTN InDataSize,\r | |
810 | IN UINT8 *PrivateKey,\r | |
811 | IN UINTN PrivateKeySize,\r | |
812 | IN UINT8 *KeyPassWord,\r | |
813 | IN UINTN KeyPwdSize,\r | |
814 | OUT UINT8 **OutData,\r | |
815 | IN OUT UINTN *OutDataSize\r | |
816 | )\r | |
817 | {\r | |
818 | UINT8 *RsaContext;\r | |
819 | UINT8 *Signature;\r | |
820 | UINTN SigSize;\r | |
f75a7f56 | 821 | \r |
9166f840 | 822 | SigSize = 0;\r |
94866d40 ED |
823 | RsaContext = NULL;\r |
824 | \r | |
9166f840 | 825 | //\r |
826 | // Retrieve RSA Private Key from password-protected PEM data\r | |
827 | //\r | |
828 | RsaGetPrivateKeyFromPem (\r | |
829 | (CONST UINT8 *)PrivateKey,\r | |
830 | PrivateKeySize,\r | |
831 | (CONST CHAR8 *)KeyPassWord,\r | |
832 | (VOID **) &RsaContext\r | |
833 | );\r | |
834 | if (RsaContext == NULL) {\r | |
835 | return;\r | |
836 | }\r | |
837 | \r | |
838 | //\r | |
839 | // Sign data\r | |
840 | //\r | |
f75a7f56 | 841 | Signature = NULL;\r |
9166f840 | 842 | if (!RsaPkcs1Sign (RsaContext, InData, InDataSize, Signature, &SigSize)) {\r |
843 | Signature = AllocateZeroPool (SigSize);\r | |
844 | } else {\r | |
845 | return;\r | |
f75a7f56 | 846 | }\r |
9166f840 | 847 | \r |
848 | RsaPkcs1Sign (RsaContext, InData, InDataSize, Signature, &SigSize);\r | |
849 | \r | |
850 | *OutData = Signature;\r | |
851 | *OutDataSize = SigSize;\r | |
852 | \r | |
853 | if (RsaContext != NULL) {\r | |
854 | RsaFree (RsaContext);\r | |
855 | }\r | |
856 | }\r | |
857 | \r | |
858 | /**\r | |
859 | Verify the singed data with the public key which is contained in a certificate.\r | |
860 | \r | |
861 | @param[in] InCert Pointer to the Certificate which contains the\r | |
862 | public key.\r | |
76389e18 | 863 | @param[in] CertLen The size of Certificate in bytes.\r |
9166f840 | 864 | @param[in] InCa Pointer to the CA certificate\r |
865 | @param[in] CaLen The size of CA certificate in bytes.\r | |
d1c85a17 | 866 | @param[in] InData Pointer to octet message hash to be checked.\r |
9166f840 | 867 | @param[in] InDataSize Size of the message hash in bytes.\r |
d1c85a17 | 868 | @param[in] Singnature The pointer to the RSA PKCS1-V1_5 signature to be verified.\r |
9166f840 | 869 | @param[in] SigSize Size of signature in bytes.\r |
870 | \r | |
871 | @retval TRUE Valid signature encoded in PKCS1-v1_5.\r | |
872 | @retval FALSE Invalid signature or invalid RSA context.\r | |
f75a7f56 | 873 | \r |
9166f840 | 874 | **/\r |
875 | BOOLEAN\r | |
876 | IpSecCryptoIoVerifySignDataByCertificate (\r | |
877 | IN UINT8 *InCert,\r | |
878 | IN UINTN CertLen,\r | |
879 | IN UINT8 *InCa,\r | |
880 | IN UINTN CaLen,\r | |
881 | IN UINT8 *InData,\r | |
882 | IN UINTN InDataSize,\r | |
883 | IN UINT8 *Singnature,\r | |
884 | IN UINTN SigSize\r | |
885 | )\r | |
886 | {\r | |
887 | UINT8 *RsaContext;\r | |
888 | BOOLEAN Status;\r | |
889 | \r | |
890 | //\r | |
891 | // Create the RSA Context\r | |
892 | //\r | |
893 | RsaContext = RsaNew ();\r | |
894 | if (RsaContext == NULL) {\r | |
895 | return FALSE;\r | |
896 | }\r | |
897 | \r | |
898 | //\r | |
899 | // Verify the validity of X509 Certificate\r | |
900 | //\r | |
901 | if (!X509VerifyCert (InCert, CertLen, InCa, CaLen)) {\r | |
902 | return FALSE;\r | |
903 | }\r | |
904 | \r | |
905 | //\r | |
906 | // Retrieve the RSA public Key from Certificate\r | |
907 | //\r | |
908 | RsaGetPublicKeyFromX509 ((CONST UINT8 *)InCert, CertLen, (VOID **)&RsaContext);\r | |
f75a7f56 | 909 | \r |
9166f840 | 910 | //\r |
911 | // Verify data\r | |
912 | //\r | |
913 | Status = RsaPkcs1Verify (RsaContext, InData, InDataSize, Singnature, SigSize);\r | |
914 | \r | |
915 | if (RsaContext != NULL) {\r | |
916 | RsaFree (RsaContext);\r | |
917 | }\r | |
918 | \r | |
919 | return Status;\r | |
920 | }\r | |
921 | \r | |
922 | /**\r | |
923 | Retrieves the RSA Public Key from one X509 certificate (DER format only).\r | |
924 | \r | |
925 | @param[in] InCert Pointer to the certificate.\r | |
926 | @param[in] CertLen The size of the certificate in bytes.\r | |
927 | @param[out] PublicKey Pointer to the retrieved public key.\r | |
928 | @param[out] PublicKeyLen Size of Public Key in bytes.\r | |
929 | \r | |
930 | @retval EFI_SUCCESS Successfully get the public Key.\r | |
931 | @retval EFI_INVALID_PARAMETER The certificate is malformed.\r | |
932 | \r | |
933 | **/\r | |
934 | EFI_STATUS\r | |
935 | IpSecCryptoIoGetPublicKeyFromCert (\r | |
936 | IN UINT8 *InCert,\r | |
937 | IN UINTN CertLen,\r | |
938 | OUT UINT8 **PublicKey,\r | |
939 | OUT UINTN *PublicKeyLen\r | |
940 | )\r | |
941 | {\r | |
942 | UINT8 *RsaContext;\r | |
943 | EFI_STATUS Status;\r | |
944 | \r | |
945 | Status = EFI_SUCCESS;\r | |
946 | \r | |
947 | //\r | |
948 | // Create the RSA Context\r | |
949 | //\r | |
950 | RsaContext = RsaNew ();\r | |
951 | \r | |
952 | //\r | |
953 | // Retrieve the RSA public key from CA Certificate\r | |
954 | //\r | |
955 | if (!RsaGetPublicKeyFromX509 ((CONST UINT8 *)InCert, CertLen, (VOID **) &RsaContext)) {\r | |
956 | Status = EFI_INVALID_PARAMETER;\r | |
957 | goto EXIT;\r | |
958 | }\r | |
959 | \r | |
960 | *PublicKeyLen = 0;\r | |
f75a7f56 | 961 | \r |
9166f840 | 962 | RsaGetKey (RsaContext, RsaKeyN, NULL, PublicKeyLen);\r |
f75a7f56 | 963 | \r |
9166f840 | 964 | *PublicKey = AllocateZeroPool (*PublicKeyLen);\r |
6b16c9e7 JW |
965 | if (*PublicKey == NULL) {\r |
966 | Status = EFI_OUT_OF_RESOURCES;\r | |
967 | goto EXIT;\r | |
968 | }\r | |
9166f840 | 969 | \r |
970 | if (!RsaGetKey (RsaContext, RsaKeyN, *PublicKey, PublicKeyLen)) {\r | |
971 | Status = EFI_INVALID_PARAMETER;\r | |
972 | }\r | |
973 | \r | |
974 | EXIT:\r | |
975 | if (RsaContext != NULL) {\r | |
976 | RsaFree (RsaContext);\r | |
977 | }\r | |
978 | \r | |
979 | return Status;\r | |
980 | }\r | |
981 | \r | |
982 | /**\r | |
983 | Retrieves the subject name from one X509 certificate (DER format only).\r | |
984 | \r | |
985 | @param[in] InCert Pointer to the X509 certificate.\r | |
986 | @param[in] CertSize The size of the X509 certificate in bytes.\r | |
987 | @param[out] CertSubject Pointer to the retrieved certificate subject.\r | |
988 | @param[out] SubjectSize The size of Certificate Subject in bytes.\r | |
f75a7f56 | 989 | \r |
9166f840 | 990 | @retval EFI_SUCCESS Retrieved the certificate subject successfully.\r |
991 | @retval EFI_INVALID_PARAMETER The certificate is malformed.\r | |
f75a7f56 | 992 | \r |
9166f840 | 993 | **/\r |
994 | EFI_STATUS\r | |
995 | IpSecCryptoIoGetSubjectFromCert (\r | |
996 | IN UINT8 *InCert,\r | |
997 | IN UINTN CertSize,\r | |
998 | OUT UINT8 **CertSubject,\r | |
999 | OUT UINTN *SubjectSize\r | |
1000 | )\r | |
1001 | {\r | |
1002 | EFI_STATUS Status;\r | |
1003 | \r | |
1004 | Status = EFI_SUCCESS;\r | |
1005 | \r | |
1006 | *SubjectSize = 0;\r | |
1007 | X509GetSubjectName (InCert, CertSize, *CertSubject, SubjectSize);\r | |
1008 | \r | |
1009 | *CertSubject = AllocateZeroPool (*SubjectSize);\r | |
1010 | if (!X509GetSubjectName (InCert, CertSize, *CertSubject, SubjectSize)) {\r | |
1011 | Status = EFI_INVALID_PARAMETER;\r | |
1012 | }\r | |
1013 | \r | |
1014 | return Status;\r | |
1015 | }\r |