]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/Ikev2/Sa.c
SecurityPkg: Delete Auth Variable driver
[mirror_edk2.git] / NetworkPkg / IpSecDxe / Ikev2 / Sa.c
CommitLineData
9166f840 1/** @file\r
2 The operations for IKEv2 SA.\r
3\r
bfd4204b 4 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
9166f840 5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Utility.h"\r
17#include "IpSecDebug.h"\r
18#include "IkeService.h"\r
19#include "Ikev2.h"\r
20\r
21/**\r
22 Generates the DH Key.\r
23\r
24 This generates the DH local public key and store it in the IKEv2 SA Session's GxBuffer.\r
25 \r
26 @param[in] IkeSaSession Pointer to related IKE SA Session.\r
27\r
28 @retval EFI_SUCCESS The operation succeeded.\r
29 @retval Others The operation failed.\r
30\r
31**/\r
32EFI_STATUS\r
33Ikev2GenerateSaDhPublicKey (\r
34 IN IKEV2_SA_SESSION *IkeSaSession\r
35 );\r
36\r
37/**\r
38 Generates the IKEv2 SA key for the furthure IKEv2 exchange.\r
39\r
40 @param[in] IkeSaSession Pointer to IKEv2 SA Session.\r
41 @param[in] KePayload Pointer to Key payload used to generate the Key.\r
42\r
43 @retval EFI_UNSUPPORTED If the Algorithm Id is not supported.\r
44 @retval EFI_SUCCESS The operation succeeded.\r
45\r
46**/\r
47EFI_STATUS\r
48Ikev2GenerateSaKeys (\r
49 IN IKEV2_SA_SESSION *IkeSaSession,\r
50 IN IKE_PAYLOAD *KePayload\r
51 );\r
52\r
53/**\r
54 Generates the Keys for the furthure IPsec Protocol.\r
55\r
56 @param[in] ChildSaSession Pointer to IKE Child SA Session.\r
57 @param[in] KePayload Pointer to Key payload used to generate the Key.\r
58\r
59 @retval EFI_UNSUPPORTED If one or more Algorithm Id is unsupported.\r
60 @retval EFI_SUCCESS The operation succeeded.\r
61\r
62**/\r
63EFI_STATUS\r
64Ikev2GenerateChildSaKeys (\r
65 IN IKEV2_CHILD_SA_SESSION *ChildSaSession,\r
66 IN IKE_PAYLOAD *KePayload\r
67 );\r
68\r
69/**\r
70 Gernerates IKEv2 packet for IKE_SA_INIT exchange.\r
71\r
72 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.\r
73 @param[in] Context Context Data passed by caller.\r
74\r
75 @retval EFI_SUCCESS The IKEv2 packet generation succeeded.\r
76 @retval Others The IKEv2 packet generation failed.\r
77\r
78**/\r
79IKE_PACKET *\r
80Ikev2InitPskGenerator (\r
81 IN UINT8 *SaSession,\r
82 IN VOID *Context\r
83 )\r
84{\r
85 IKE_PACKET *IkePacket;\r
86 IKEV2_SA_SESSION *IkeSaSession;\r
87 IKE_PAYLOAD *SaPayload;\r
88 IKE_PAYLOAD *KePayload;\r
89 IKE_PAYLOAD *NoncePayload;\r
90 IKE_PAYLOAD *NotifyPayload;\r
91 EFI_STATUS Status;\r
92\r
93 SaPayload = NULL;\r
94 KePayload = NULL;\r
95 NoncePayload = NULL;\r
96 NotifyPayload = NULL;\r
97\r
98 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;\r
99\r
100 //\r
101 // 1. Allocate IKE packet\r
102 //\r
103 IkePacket = IkePacketAlloc ();\r
104 ASSERT (IkePacket != NULL);\r
105\r
106 //\r
107 // 1.a Fill the IkePacket->Hdr\r
108 //\r
109 IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_INIT;\r
110 IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;\r
111 IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;\r
112 IkePacket->Header->Version = (UINT8) (2 << 4);\r
113 IkePacket->Header->MessageId = 0;\r
114\r
115 if (IkeSaSession->SessionCommon.IsInitiator) {\r
116 IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;\r
117 } else {\r
118 IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;\r
119 }\r
120\r
121 //\r
122 // If the NCookie is not NULL, this IKE_SA_INIT packet is resent by the NCookie\r
123 // and the NCookie payload should be the first payload in this packet.\r
124 //\r
125 if (IkeSaSession->NCookie != NULL) {\r
126 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_NOTIFY;\r
127 NotifyPayload = Ikev2GenerateNotifyPayload (\r
128 IPSEC_PROTO_ISAKMP,\r
129 IKEV2_PAYLOAD_TYPE_SA,\r
130 0,\r
131 IKEV2_NOTIFICATION_COOKIE,\r
132 NULL,\r
133 IkeSaSession->NCookie,\r
134 IkeSaSession->NCookieSize\r
135 );\r
136 } else {\r
137 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_SA;\r
138 }\r
139\r
140 //\r
141 // 2. Generate SA Payload according to the SaData & SaParams\r
142 //\r
143 SaPayload = Ikev2GenerateSaPayload (\r
144 IkeSaSession->SaData,\r
145 IKEV2_PAYLOAD_TYPE_KE,\r
146 IkeSessionTypeIkeSa\r
147 );\r
148\r
149 //\r
150 // 3. Generate DH public key.\r
151 // The DhPrivate Key has been generated in Ikev2InitPskParser, if the\r
152 // IkeSaSession is responder. If resending IKE_SA_INIT with Cookie Notify\r
153 // No need to recompute the Public key.\r
154 //\r
155 if ((IkeSaSession->SessionCommon.IsInitiator) && (IkeSaSession->NCookie == NULL)) { \r
156 Status = Ikev2GenerateSaDhPublicKey (IkeSaSession);\r
157 if (EFI_ERROR (Status)) {\r
158 goto CheckError;\r
159 }\r
160 }\r
161\r
162 //\r
163 // 4. Generate KE Payload according to SaParams->DhGroup\r
164 //\r
165 KePayload = Ikev2GenerateKePayload (\r
166 IkeSaSession, \r
167 IKEV2_PAYLOAD_TYPE_NONCE\r
168 );\r
169\r
170 //\r
171 // 5. Generate Nonce Payload\r
172 // If resending IKE_SA_INIT with Cookie Notify paylaod, no need to regenerate\r
173 // the Nonce Payload.\r
174 //\r
175 if ((IkeSaSession->SessionCommon.IsInitiator) && (IkeSaSession->NCookie == NULL)) {\r
176 IkeSaSession->NiBlkSize = IKE_NONCE_SIZE;\r
177 IkeSaSession->NiBlock = IkeGenerateNonce (IKE_NONCE_SIZE);\r
178 ASSERT (IkeSaSession->NiBlock != NULL);\r
179 }\r
180\r
181 if (IkeSaSession->SessionCommon.IsInitiator) {\r
182 NoncePayload = Ikev2GenerateNoncePayload (\r
183 IkeSaSession->NiBlock,\r
184 IkeSaSession->NiBlkSize,\r
185 IKEV2_PAYLOAD_TYPE_NONE\r
186 );\r
187 } else {\r
188 //\r
189 // The Nonce Payload has been created in Ikev2PskParser if the IkeSaSession is\r
190 // responder.\r
191 //\r
192 NoncePayload = Ikev2GenerateNoncePayload (\r
193 IkeSaSession->NrBlock,\r
194 IkeSaSession->NrBlkSize,\r
195 IKEV2_PAYLOAD_TYPE_NONE\r
196 );\r
197 }\r
198\r
199 if (NotifyPayload != NULL) {\r
200 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload);\r
201 }\r
202 if (SaPayload != NULL) {\r
203 IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload);\r
204 }\r
205 if (KePayload != NULL) {\r
206 IKE_PACKET_APPEND_PAYLOAD (IkePacket, KePayload);\r
207 }\r
208 if (NoncePayload != NULL) {\r
209 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NoncePayload);\r
210 }\r
211\r
212 return IkePacket;\r
213\r
214CheckError:\r
215 if (IkePacket != NULL) {\r
216 IkePacketFree (IkePacket);\r
217 }\r
218 if (SaPayload != NULL) {\r
219 IkePayloadFree (SaPayload);\r
220 }\r
221 return NULL; \r
222}\r
223\r
224/**\r
225 Parses the IKEv2 packet for IKE_SA_INIT exchange.\r
226\r
227 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.\r
228 @param[in] IkePacket The received IKE packet to be parsed.\r
229\r
230 @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is\r
231 saved for furthure communication.\r
232 @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA proposal is unacceptable.\r
233\r
234**/\r
235EFI_STATUS\r
236Ikev2InitPskParser (\r
237 IN UINT8 *SaSession,\r
238 IN IKE_PACKET *IkePacket\r
239 ) \r
240{\r
241 IKEV2_SA_SESSION *IkeSaSession;\r
242 IKE_PAYLOAD *SaPayload;\r
243 IKE_PAYLOAD *KeyPayload;\r
244 IKE_PAYLOAD *IkePayload;\r
245 IKE_PAYLOAD *NoncePayload;\r
246 IKE_PAYLOAD *NotifyPayload;\r
247 UINT8 *NonceBuffer;\r
248 UINTN NonceSize;\r
249 LIST_ENTRY *Entry;\r
250 EFI_STATUS Status;\r
251\r
252 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;\r
253 KeyPayload = NULL;\r
254 SaPayload = NULL;\r
255 NoncePayload = NULL;\r
256 IkePayload = NULL;\r
257 NotifyPayload = NULL;\r
258\r
259 //\r
260 // Iterate payloads to find the SaPayload and KeyPayload.\r
261 //\r
262 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {\r
263 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
264 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) {\r
265 SaPayload = IkePayload;\r
266 }\r
267 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_KE) {\r
268 KeyPayload = IkePayload;\r
269 }\r
270 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_NONCE) {\r
271 NoncePayload = IkePayload;\r
272 }\r
273 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_NOTIFY) {\r
274 NotifyPayload = IkePayload;\r
275 }\r
276 }\r
277\r
278 //\r
279 // According to RFC 4306 - 2.6. If the responder responds with the COOKIE Notify\r
280 // payload with the cookie data, initiator MUST retry the IKE_SA_INIT with a\r
281 // Notify payload of type COOKIE containing the responder suppplied cookie data\r
282 // as first payload and all other payloads unchanged.\r
283 //\r
284 if (IkeSaSession->SessionCommon.IsInitiator) {\r
285 if (NotifyPayload != NULL) {\r
286 Status = Ikev2ParserNotifyCookiePayload (NotifyPayload, IkeSaSession);\r
287 return Status;\r
288 }\r
289 }\r
290\r
291 if ((KeyPayload == NULL) || (SaPayload == NULL) || (NoncePayload == NULL)) {\r
292 return EFI_INVALID_PARAMETER;\r
293 }\r
294\r
295 //\r
296 // Store NoncePayload for SKEYID computing.\r
297 //\r
298 NonceSize = NoncePayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER);\r
299 NonceBuffer = (UINT8 *) AllocatePool (NonceSize);\r
300 ASSERT (NonceBuffer != NULL);\r
301 CopyMem (\r
302 NonceBuffer,\r
303 NoncePayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),\r
304 NonceSize\r
305 );\r
306\r
307 //\r
308 // Check if IkePacket Header matches the state\r
309 //\r
310 if (IkeSaSession->SessionCommon.IsInitiator) {\r
311 //\r
312 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND\r
313 //\r
314 if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) {\r
315 Status = EFI_INVALID_PARAMETER;\r
316 goto CheckError;\r
317 }\r
318\r
319 //\r
320 // 2. Parse the SA Payload and Key Payload to find out the cryptographic\r
321 // suite and fill in the Sa paramse into CommonSession->SaParams\r
322 //\r
323 if (!Ikev2SaParseSaPayload (IkeSaSession, SaPayload, IkePacket->Header->Flags)) {\r
324 Status = EFI_INVALID_PARAMETER;\r
325 goto CheckError;\r
326 }\r
327\r
328 //\r
329 // 3. If Initiator, the NoncePayload is Nr_b.\r
330 //\r
331 IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateAuth);\r
332 IkeSaSession->NrBlock = NonceBuffer;\r
333 IkeSaSession->NrBlkSize = NonceSize;\r
334 IkeSaSession->SessionCommon.State = IkeStateAuth;\r
335 IkeSaSession->ResponderCookie = IkePacket->Header->ResponderCookie;\r
336\r
337 //\r
338 // 4. Change the state of IkeSaSession\r
339 //\r
340 IkeSaSession->SessionCommon.State = IkeStateAuth;\r
341 } else {\r
342 //\r
343 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT\r
344 //\r
345 if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) {\r
346 Status = EFI_INVALID_PARAMETER;\r
347 goto CheckError;\r
348 }\r
349\r
350 //\r
351 // 2. Parse the SA payload and find out the perfered one\r
352 // and fill in the SA parameters into CommonSession->SaParams and SaData into\r
353 // IkeSaSession for the responder SA payload generation.\r
354 //\r
355 if (!Ikev2SaParseSaPayload (IkeSaSession, SaPayload, IkePacket->Header->Flags)) {\r
356 Status = EFI_INVALID_PARAMETER;\r
357 goto CheckError;\r
358 }\r
359\r
360 //\r
361 // 3. Generat Dh Y parivate Key\r
362 //\r
363 Status = Ikev2GenerateSaDhPublicKey (IkeSaSession);\r
364 if (EFI_ERROR (Status)) {\r
365 goto CheckError;\r
366 }\r
367\r
368 //\r
369 // 4. If Responder, the NoncePayload is Ni_b and go to generate Nr_b.\r
370 //\r
371 IkeSaSession->NiBlock = NonceBuffer;\r
372 IkeSaSession->NiBlkSize = NonceSize;\r
373\r
374 //\r
375 // 5. Generate Nr_b\r
376 //\r
377 IkeSaSession->NrBlock = IkeGenerateNonce (IKE_NONCE_SIZE);\r
378 ASSERT_EFI_ERROR (IkeSaSession->NrBlock != NULL);\r
379 IkeSaSession->NrBlkSize = IKE_NONCE_SIZE;\r
380\r
381 //\r
382 // 6. Save the Cookies\r
383 //\r
384 IkeSaSession->InitiatorCookie = IkePacket->Header->InitiatorCookie;\r
385 IkeSaSession->ResponderCookie = IkeGenerateCookie ();\r
386 }\r
387\r
388 if (IkeSaSession->SessionCommon.PreferDhGroup != ((IKEV2_KEY_EXCHANGE *)KeyPayload->PayloadBuf)->DhGroup) {\r
389 Status = EFI_INVALID_PARAMETER;\r
390 goto CheckError;\r
391 }\r
392 //\r
393 // Call Ikev2GenerateSaKeys to create SKEYID, SKEYID_d, SKEYID_a, SKEYID_e.\r
394 //\r
395 Status = Ikev2GenerateSaKeys (IkeSaSession, KeyPayload);\r
396 if (EFI_ERROR(Status)) {\r
397 goto CheckError;\r
398 }\r
399 return EFI_SUCCESS;\r
400\r
401CheckError:\r
402 if (NonceBuffer != NULL) {\r
403 FreePool (NonceBuffer);\r
404 }\r
405 \r
406 return Status;\r
407}\r
408\r
409/**\r
410 Generates the IKEv2 packet for IKE_AUTH exchange.\r
411\r
412 @param[in] SaSession Pointer to IKEV2_SA_SESSION.\r
413 @param[in] Context Context data passed by caller.\r
414\r
415 @retval Pointer to IKE Packet to be sent out.\r
416\r
417**/\r
418IKE_PACKET *\r
419Ikev2AuthPskGenerator (\r
420 IN UINT8 *SaSession,\r
421 IN VOID *Context\r
422 )\r
423{\r
424 IKE_PACKET *IkePacket;\r
425 IKEV2_SA_SESSION *IkeSaSession;\r
426 IKE_PAYLOAD *IdPayload;\r
427 IKE_PAYLOAD *AuthPayload;\r
428 IKE_PAYLOAD *SaPayload;\r
429 IKE_PAYLOAD *TsiPayload;\r
430 IKE_PAYLOAD *TsrPayload;\r
431 IKE_PAYLOAD *NotifyPayload;\r
432 IKE_PAYLOAD *CpPayload;\r
433 IKEV2_CHILD_SA_SESSION *ChildSaSession;\r
434 \r
435\r
436 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;\r
437 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));\r
438\r
439 CpPayload = NULL;\r
440 NotifyPayload = NULL;\r
441 \r
442 //\r
443 // 1. Allocate IKE Packet\r
444 //\r
445 IkePacket= IkePacketAlloc ();\r
446 ASSERT (IkePacket != NULL);\r
447\r
448 //\r
449 // 1.a Fill the IkePacket Header.\r
450 //\r
451 IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_AUTH;\r
452 IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;\r
453 IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;\r
454 IkePacket->Header->Version = (UINT8)(2 << 4);\r
455 if (ChildSaSession->SessionCommon.IsInitiator) {\r
456 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_INIT;\r
457 } else {\r
458 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_RSP;\r
459 }\r
460\r
461 //\r
462 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should \r
463 // be always number 0 and 1;\r
464 //\r
465 IkePacket->Header->MessageId = 1;\r
466\r
467 if (IkeSaSession->SessionCommon.IsInitiator) {\r
468 IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;\r
469 } else {\r
470 IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;\r
471 }\r
472\r
473 //\r
474 // 2. Generate ID Payload according to IP version and address.\r
475 //\r
476 IdPayload = Ikev2GenerateIdPayload (\r
477 &IkeSaSession->SessionCommon,\r
478 IKEV2_PAYLOAD_TYPE_AUTH\r
479 );\r
480\r
481 //\r
482 // 3. Generate Auth Payload\r
483 // If it is tunnel mode, should create the configuration payload after the\r
484 // Auth payload.\r
485 //\r
486 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {\r
487\r
488 AuthPayload = Ikev2PskGenerateAuthPayload (\r
489 ChildSaSession->IkeSaSession,\r
490 IdPayload,\r
491 IKEV2_PAYLOAD_TYPE_SA,\r
492 FALSE\r
493 );\r
494 } else {\r
495 AuthPayload = Ikev2PskGenerateAuthPayload (\r
496 ChildSaSession->IkeSaSession,\r
497 IdPayload,\r
498 IKEV2_PAYLOAD_TYPE_CP,\r
499 FALSE\r
500 );\r
501 if (IkeSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) {\r
502 CpPayload = Ikev2GenerateCpPayload (\r
503 ChildSaSession->IkeSaSession,\r
504 IKEV2_PAYLOAD_TYPE_SA,\r
505 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS\r
506 );\r
507 } else {\r
508 CpPayload = Ikev2GenerateCpPayload (\r
509 ChildSaSession->IkeSaSession,\r
510 IKEV2_PAYLOAD_TYPE_SA,\r
511 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS\r
512 );\r
513 }\r
514 }\r
515\r
516 //\r
517 // 4. Generate SA Payload according to the SA Data in ChildSaSession\r
518 //\r
519 SaPayload = Ikev2GenerateSaPayload (\r
520 ChildSaSession->SaData,\r
521 IKEV2_PAYLOAD_TYPE_TS_INIT,\r
522 IkeSessionTypeChildSa\r
523 );\r
524\r
525 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {\r
526 //\r
527 // Generate Tsi and Tsr.\r
528 //\r
529 TsiPayload = Ikev2GenerateTsPayload (\r
530 ChildSaSession,\r
531 IKEV2_PAYLOAD_TYPE_TS_RSP,\r
532 FALSE\r
533 );\r
534\r
535 TsrPayload = Ikev2GenerateTsPayload (\r
536 ChildSaSession,\r
537 IKEV2_PAYLOAD_TYPE_NOTIFY,\r
538 FALSE\r
539 );\r
540\r
541 //\r
542 // Generate Notify Payload. If transport mode, there should have Notify\r
543 // payload with TRANSPORT_MODE notification.\r
544 //\r
545 NotifyPayload = Ikev2GenerateNotifyPayload (\r
546 0,\r
547 IKEV2_PAYLOAD_TYPE_NONE,\r
548 0,\r
549 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE,\r
550 NULL,\r
551 NULL,\r
552 0\r
553 );\r
554 } else {\r
555 //\r
556 // Generate Tsr for Tunnel mode.\r
557 //\r
558 TsiPayload = Ikev2GenerateTsPayload (\r
559 ChildSaSession,\r
560 IKEV2_PAYLOAD_TYPE_TS_RSP,\r
561 TRUE\r
562 );\r
563 TsrPayload = Ikev2GenerateTsPayload (\r
564 ChildSaSession,\r
565 IKEV2_PAYLOAD_TYPE_NONE,\r
566 FALSE\r
567 );\r
568 }\r
569\r
570 IKE_PACKET_APPEND_PAYLOAD (IkePacket, IdPayload);\r
571 IKE_PACKET_APPEND_PAYLOAD (IkePacket, AuthPayload);\r
572 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {\r
573 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CpPayload);\r
574 }\r
575 IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload);\r
576 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsiPayload);\r
577 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsrPayload);\r
578 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {\r
579 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload);\r
580 }\r
581\r
582 return IkePacket;\r
583}\r
584\r
585/**\r
586 Parses IKE_AUTH packet.\r
587\r
588 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.\r
589 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.\r
590\r
591 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA \r
592 proposal is unacceptable.\r
593 @retval EFI_SUCCESS The IKE packet is acceptable and the\r
594 relative data is saved for furthure communication.\r
595\r
596**/\r
597EFI_STATUS \r
598Ikev2AuthPskParser (\r
599 IN UINT8 *SaSession,\r
600 IN IKE_PACKET *IkePacket\r
601 )\r
602{\r
603 IKEV2_CHILD_SA_SESSION *ChildSaSession;\r
604 IKEV2_SA_SESSION *IkeSaSession;\r
605 IKE_PAYLOAD *IkePayload;\r
606 IKE_PAYLOAD *SaPayload;\r
607 IKE_PAYLOAD *IdiPayload;\r
608 IKE_PAYLOAD *IdrPayload;\r
609 IKE_PAYLOAD *AuthPayload;\r
610 IKE_PAYLOAD *TsiPayload;\r
611 IKE_PAYLOAD *TsrPayload;\r
612 IKE_PAYLOAD *VerifiedAuthPayload;\r
613 LIST_ENTRY *Entry;\r
614 EFI_STATUS Status;\r
615\r
616 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;\r
617 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));\r
618\r
619 SaPayload = NULL;\r
620 IdiPayload = NULL;\r
621 IdrPayload = NULL;\r
622 AuthPayload = NULL;\r
623 TsiPayload = NULL;\r
624 TsrPayload = NULL;\r
625\r
626 //\r
627 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.\r
628 //\r
629 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {\r
630 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
631\r
632 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_INIT) {\r
633 IdiPayload = IkePayload;\r
634 }\r
635 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_RSP) {\r
636 IdrPayload = IkePayload;\r
637 }\r
638 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) {\r
639 SaPayload = IkePayload;\r
640 }\r
641 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_AUTH) {\r
642 AuthPayload = IkePayload;\r
643 }\r
644 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_INIT) {\r
645 TsiPayload = IkePayload;\r
646 }\r
647 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_RSP) {\r
648 TsrPayload = IkePayload;\r
649 }\r
650 }\r
651\r
652 if ((SaPayload == NULL) || (AuthPayload == NULL) || (TsiPayload == NULL) || (TsrPayload == NULL)) {\r
653 return EFI_INVALID_PARAMETER;\r
654 }\r
655 if ((IdiPayload == NULL) && (IdrPayload == NULL)) {\r
656 return EFI_INVALID_PARAMETER;\r
657 }\r
658\r
659 //\r
660 // Check IkePacket Header is match the state\r
661 //\r
662 if (IkeSaSession->SessionCommon.IsInitiator) {\r
663 \r
664 //\r
665 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND\r
666 //\r
667 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) ||\r
668 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)\r
669 ) {\r
670 return EFI_INVALID_PARAMETER;\r
671 }\r
672\r
673 } else {\r
674 //\r
675 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT\r
676 //\r
677 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) ||\r
678 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)\r
679 ) {\r
680 return EFI_INVALID_PARAMETER;\r
681 }\r
682\r
683 //\r
684 // 2. Parse the SA payload and Key Payload and find out the perferable one\r
685 // and fill in the Sa paramse into CommonSession->SaParams and SaData into\r
686 // IkeSaSession for the responder SA payload generation.\r
687 //\r
688 }\r
689\r
690 //\r
691 // Verify the Auth Payload.\r
692 //\r
693 VerifiedAuthPayload = Ikev2PskGenerateAuthPayload (\r
694 IkeSaSession,\r
695 IkeSaSession->SessionCommon.IsInitiator ? IdrPayload : IdiPayload,\r
696 IKEV2_PAYLOAD_TYPE_SA,\r
697 TRUE\r
698 );\r
699 if ((VerifiedAuthPayload != NULL) &&\r
700 (0 != CompareMem (\r
701 VerifiedAuthPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),\r
702 AuthPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),\r
703 VerifiedAuthPayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER)\r
704 ))) {\r
705 return EFI_INVALID_PARAMETER;\r
706 };\r
707\r
708 //\r
709 // 3. Parse the SA Payload to find out the cryptographic suite\r
710 // and fill in the Sa paramse into CommonSession->SaParams. If no acceptable\r
711 // porposal found, return EFI_INVALID_PARAMETER.\r
712 //\r
713 if (!Ikev2ChildSaParseSaPayload (ChildSaSession, SaPayload, IkePacket->Header->Flags)) {\r
714 return EFI_INVALID_PARAMETER;\r
715 }\r
716\r
717 //\r
718 // 4. Parse TSi, TSr payloads.\r
719 //\r
720 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId !=\r
721 ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId) &&\r
722 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) &&\r
723 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0)\r
724 ) {\r
725 return EFI_INVALID_PARAMETER;\r
726 }\r
727\r
728 if (!IkeSaSession->SessionCommon.IsInitiator) {\r
729 //\r
730 //TODO:check the Port range. Only support any port and one certain port here.\r
731 //\r
732 ChildSaSession->ProtoId = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId;\r
733 ChildSaSession->LocalPort = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;\r
734 ChildSaSession->RemotePort = ((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;\r
735 //\r
736 // Association a SPD with this SA.\r
737 //\r
738 Status = Ikev2ChildSaAssociateSpdEntry (ChildSaSession);\r
739 if (EFI_ERROR (Status)) {\r
740 return EFI_INVALID_PARAMETER;\r
741 }\r
742 //\r
743 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.\r
744 //\r
745 if (ChildSaSession->IkeSaSession->Spd == NULL) {\r
746 ChildSaSession->IkeSaSession->Spd = ChildSaSession->Spd;\r
747 Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession);\r
748 }\r
749 } else {\r
750 //\r
751 //TODO:check the Port range.\r
752 //\r
753 if ((((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&\r
754 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->RemotePort)\r
755 ) {\r
756 return EFI_INVALID_PARAMETER;\r
757 } \r
758 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&\r
759 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->LocalPort)\r
760 ) {\r
761 return EFI_INVALID_PARAMETER;\r
762 }\r
763 //\r
764 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.\r
765 //\r
766 if (ChildSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {\r
767 if (!ChildSaSession->IkeSaSession->SessionCommon.IsInitiator) {\r
768 //\r
769 // If it is tunnel mode, the UEFI part must be the initiator.\r
770 //\r
771 return EFI_INVALID_PARAMETER;\r
772 }\r
773 //\r
774 // Get the Virtual IP address from the Tsi traffic selector. \r
775 // TODO: check the CFG reply payload\r
776 //\r
777 CopyMem (\r
778 &ChildSaSession->SpdSelector->LocalAddress[0].Address,\r
779 TsiPayload->PayloadBuf + sizeof (IKEV2_TS) + sizeof (TRAFFIC_SELECTOR),\r
780 (ChildSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) ?\r
781 sizeof (EFI_IPv4_ADDRESS) : sizeof (EFI_IPv6_ADDRESS)\r
782 );\r
783 } \r
784 }\r
785\r
786 //\r
787 // 5. Generate keymats for IPsec protocol.\r
788 //\r
789 Ikev2GenerateChildSaKeys (ChildSaSession, NULL);\r
790 if (IkeSaSession->SessionCommon.IsInitiator) {\r
791 //\r
792 // 6. Change the state of IkeSaSession\r
793 //\r
794 IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateIkeSaEstablished);\r
795 IkeSaSession->SessionCommon.State = IkeStateIkeSaEstablished;\r
796 }\r
797 \r
798 return EFI_SUCCESS;\r
799}\r
800\r
801/**\r
802 Gernerates IKEv2 packet for IKE_SA_INIT exchange.\r
803\r
804 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.\r
805 @param[in] Context Context Data passed by caller.\r
806\r
807 @retval EFI_SUCCESS The IKE packet generation succeeded.\r
808 @retval Others The IKE packet generation failed.\r
809\r
810**/\r
811IKE_PACKET*\r
812Ikev2InitCertGenerator (\r
813 IN UINT8 *SaSession,\r
814 IN VOID *Context\r
815 ) \r
816{\r
817 IKE_PACKET *IkePacket;\r
818 IKE_PAYLOAD *CertReqPayload;\r
819 LIST_ENTRY *Node;\r
820 IKE_PAYLOAD *NoncePayload;\r
821\r
bfd4204b 822 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {\r
9166f840 823 return NULL;\r
824 }\r
825\r
826 //\r
827 // The first two messages exchange is same between PSK and Cert.\r
828 //\r
829 IkePacket = Ikev2InitPskGenerator (SaSession, Context);\r
830\r
831 if ((IkePacket != NULL) && (!((IKEV2_SA_SESSION *)SaSession)->SessionCommon.IsInitiator)) {\r
832 //\r
833 // Add the Certification Request Payload\r
834 //\r
835 CertReqPayload = Ikev2GenerateCertificatePayload (\r
836 (IKEV2_SA_SESSION *)SaSession,\r
837 IKEV2_PAYLOAD_TYPE_NONE,\r
bfd4204b 838 (UINT8*)PcdGetPtr(PcdIpsecUefiCaFile),\r
839 PcdGet32(PcdIpsecUefiCaFileSize),\r
9166f840 840 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT,\r
841 TRUE\r
842 );\r
843 //\r
844 // Change Nonce Payload Next payload type.\r
845 //\r
846 IKE_PACKET_END_PAYLOAD (IkePacket, Node);\r
847 NoncePayload = IKE_PAYLOAD_BY_PACKET (Node);\r
848 ((IKEV2_NONCE *)NoncePayload->PayloadBuf)->Header.NextPayload = IKEV2_PAYLOAD_TYPE_CERTREQ;\r
849\r
850 //\r
851 // Add Certification Request Payload\r
852 //\r
853 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertReqPayload);\r
854 }\r
855\r
856 return IkePacket;\r
857}\r
858\r
859/**\r
860 Parses the IKEv2 packet for IKE_SA_INIT exchange.\r
861\r
862 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.\r
863 @param[in] IkePacket The received IKEv2 packet to be parsed.\r
864\r
865 @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is\r
866 saved for furthure communication.\r
867 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA proposal is unacceptable. \r
868 @retval EFI_UNSUPPORTED The certificate authentication is not supported.\r
869\r
870**/\r
871EFI_STATUS\r
872Ikev2InitCertParser (\r
873 IN UINT8 *SaSession,\r
874 IN IKE_PACKET *IkePacket\r
875 )\r
876{\r
bfd4204b 877 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {\r
9166f840 878 return EFI_UNSUPPORTED;\r
879 } \r
880 \r
881 //\r
882 // The first two messages exchange is same between PSK and Cert.\r
883 // Todo: Parse Certificate Request from responder Initial Exchange. \r
884 //\r
885 return Ikev2InitPskParser (SaSession, IkePacket);\r
886}\r
887\r
888/**\r
889 Generates the IKEv2 packet for IKE_AUTH exchange.\r
890\r
891 @param[in] SaSession Pointer to IKEV2_SA_SESSION.\r
892 @param[in] Context Context data passed by caller.\r
893\r
894 @retval Pointer to IKEv2 Packet to be sent out.\r
895\r
896**/\r
897IKE_PACKET *\r
898Ikev2AuthCertGenerator (\r
899 IN UINT8 *SaSession,\r
900 IN VOID *Context\r
901 )\r
902{\r
903 IKE_PACKET *IkePacket;\r
904 IKEV2_SA_SESSION *IkeSaSession;\r
905 IKE_PAYLOAD *IdPayload;\r
906 IKE_PAYLOAD *AuthPayload;\r
907 IKE_PAYLOAD *SaPayload;\r
908 IKE_PAYLOAD *TsiPayload;\r
909 IKE_PAYLOAD *TsrPayload;\r
910 IKE_PAYLOAD *NotifyPayload;\r
911 IKE_PAYLOAD *CpPayload;\r
912 IKE_PAYLOAD *CertPayload;\r
913 IKE_PAYLOAD *CertReqPayload;\r
914 IKEV2_CHILD_SA_SESSION *ChildSaSession;\r
915\r
bfd4204b 916 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {\r
9166f840 917 return NULL;\r
918 }\r
919\r
920 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;\r
921 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));\r
922\r
923 CpPayload = NULL;\r
924 NotifyPayload = NULL;\r
925 CertPayload = NULL;\r
926 CertReqPayload = NULL;\r
927\r
928 //\r
929 // 1. Allocate IKE Packet\r
930 //\r
931 IkePacket= IkePacketAlloc ();\r
932 ASSERT (IkePacket != NULL);\r
933\r
934 //\r
935 // 1.a Fill the IkePacket Header.\r
936 //\r
937 IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_AUTH;\r
938 IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;\r
939 IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;\r
940 IkePacket->Header->Version = (UINT8)(2 << 4);\r
941 if (ChildSaSession->SessionCommon.IsInitiator) {\r
942 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_INIT;\r
943 } else {\r
944 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_RSP;\r
945 }\r
946\r
947 //\r
948 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should\r
949 // be always number 0 and 1;\r
950 //\r
951 IkePacket->Header->MessageId = 1;\r
952\r
953 if (IkeSaSession->SessionCommon.IsInitiator) {\r
954 IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;\r
955 } else {\r
956 IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;\r
957 }\r
958\r
959 //\r
960 // 2. Generate ID Payload according to IP version and address.\r
961 //\r
962 IdPayload = Ikev2GenerateCertIdPayload (\r
963 &IkeSaSession->SessionCommon,\r
964 IKEV2_PAYLOAD_TYPE_CERT,\r
bfd4204b 965 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate),\r
966 PcdGet32 (PcdIpsecUefiCertificateSize)\r
9166f840 967 );\r
968\r
969 //\r
970 // 3. Generate Certificate Payload\r
971 //\r
972 CertPayload = Ikev2GenerateCertificatePayload (\r
973 IkeSaSession,\r
974 (UINT8)(IkeSaSession->SessionCommon.IsInitiator ? IKEV2_PAYLOAD_TYPE_CERTREQ : IKEV2_PAYLOAD_TYPE_AUTH),\r
bfd4204b 975 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate),\r
976 PcdGet32 (PcdIpsecUefiCertificateSize),\r
9166f840 977 IKEV2_CERT_ENCODEING_X509_CERT_SIGN,\r
978 FALSE\r
979 );\r
980 if (IkeSaSession->SessionCommon.IsInitiator) {\r
981 CertReqPayload = Ikev2GenerateCertificatePayload (\r
982 IkeSaSession,\r
983 IKEV2_PAYLOAD_TYPE_AUTH,\r
bfd4204b 984 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate),\r
985 PcdGet32 (PcdIpsecUefiCertificateSize),\r
9166f840 986 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT,\r
987 TRUE\r
988 );\r
989 }\r
990\r
991 //\r
992 // 4. Generate Auth Payload\r
993 // If it is tunnel mode, should create the configuration payload after the\r
994 // Auth payload.\r
995 //\r
996 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {\r
997 AuthPayload = Ikev2CertGenerateAuthPayload (\r
998 ChildSaSession->IkeSaSession,\r
999 IdPayload,\r
1000 IKEV2_PAYLOAD_TYPE_SA,\r
1001 FALSE,\r
bfd4204b 1002 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificateKey),\r
1003 PcdGet32 (PcdIpsecUefiCertificateKeySize),\r
9166f840 1004 ChildSaSession->IkeSaSession->Pad->Data->AuthData,\r
1005 ChildSaSession->IkeSaSession->Pad->Data->AuthDataSize\r
1006 );\r
1007 } else {\r
1008 AuthPayload = Ikev2CertGenerateAuthPayload (\r
1009 ChildSaSession->IkeSaSession,\r
1010 IdPayload,\r
1011 IKEV2_PAYLOAD_TYPE_CP,\r
1012 FALSE,\r
bfd4204b 1013 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificateKey),\r
1014 PcdGet32 (PcdIpsecUefiCertificateKeySize),\r
9166f840 1015 ChildSaSession->IkeSaSession->Pad->Data->AuthData,\r
1016 ChildSaSession->IkeSaSession->Pad->Data->AuthDataSize\r
1017 );\r
1018 if (IkeSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) {\r
1019 CpPayload = Ikev2GenerateCpPayload (\r
1020 ChildSaSession->IkeSaSession,\r
1021 IKEV2_PAYLOAD_TYPE_SA,\r
1022 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS\r
1023 );\r
1024 } else {\r
1025 CpPayload = Ikev2GenerateCpPayload (\r
1026 ChildSaSession->IkeSaSession,\r
1027 IKEV2_PAYLOAD_TYPE_SA,\r
1028 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS\r
1029 );\r
1030 }\r
1031 }\r
1032\r
1033 //\r
1034 // 5. Generate SA Payload according to the Sa Data in ChildSaSession\r
1035 //\r
1036 SaPayload = Ikev2GenerateSaPayload (\r
1037 ChildSaSession->SaData,\r
1038 IKEV2_PAYLOAD_TYPE_TS_INIT,\r
1039 IkeSessionTypeChildSa\r
1040 );\r
1041\r
1042 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {\r
1043 //\r
1044 // Generate Tsi and Tsr.\r
1045 //\r
1046 TsiPayload = Ikev2GenerateTsPayload (\r
1047 ChildSaSession,\r
1048 IKEV2_PAYLOAD_TYPE_TS_RSP,\r
1049 FALSE\r
1050 );\r
1051\r
1052 TsrPayload = Ikev2GenerateTsPayload (\r
1053 ChildSaSession,\r
1054 IKEV2_PAYLOAD_TYPE_NOTIFY,\r
1055 FALSE\r
1056 );\r
1057\r
1058 //\r
1059 // Generate Notify Payload. If transport mode, there should have Notify \r
1060 // payload with TRANSPORT_MODE notification.\r
1061 //\r
1062 NotifyPayload = Ikev2GenerateNotifyPayload (\r
1063 0,\r
1064 IKEV2_PAYLOAD_TYPE_NONE,\r
1065 0,\r
1066 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE,\r
1067 NULL,\r
1068 NULL,\r
1069 0\r
1070 );\r
1071 } else {\r
1072 //\r
1073 // Generate Tsr for Tunnel mode.\r
1074 //\r
1075 TsiPayload = Ikev2GenerateTsPayload (\r
1076 ChildSaSession,\r
1077 IKEV2_PAYLOAD_TYPE_TS_RSP,\r
1078 TRUE\r
1079 );\r
1080 TsrPayload = Ikev2GenerateTsPayload (\r
1081 ChildSaSession,\r
1082 IKEV2_PAYLOAD_TYPE_NONE,\r
1083 FALSE\r
1084 );\r
1085 }\r
1086\r
1087 IKE_PACKET_APPEND_PAYLOAD (IkePacket, IdPayload);\r
1088 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertPayload);\r
1089 if (IkeSaSession->SessionCommon.IsInitiator) {\r
1090 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertReqPayload);\r
1091 }\r
1092 IKE_PACKET_APPEND_PAYLOAD (IkePacket, AuthPayload);\r
1093 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {\r
1094 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CpPayload);\r
1095 }\r
1096 IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload);\r
1097 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsiPayload);\r
1098 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsrPayload);\r
1099 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {\r
1100 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload);\r
1101 }\r
1102\r
1103 return IkePacket;\r
1104}\r
1105\r
1106/**\r
1107 Parses IKE_AUTH packet.\r
1108\r
1109 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.\r
1110 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.\r
1111\r
1112 @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA\r
1113 proposal is unacceptable.\r
1114 @retval EFI_SUCCESS The IKE packet is acceptable and the\r
1115 relative data is saved for furthure communication.\r
1116 @retval EFI_UNSUPPORTED The certificate authentication is not supported.\r
1117\r
1118**/\r
1119EFI_STATUS\r
1120Ikev2AuthCertParser (\r
1121 IN UINT8 *SaSession,\r
1122 IN IKE_PACKET *IkePacket\r
1123 )\r
1124{\r
1125 IKEV2_CHILD_SA_SESSION *ChildSaSession;\r
1126 IKEV2_SA_SESSION *IkeSaSession;\r
1127 IKE_PAYLOAD *IkePayload;\r
1128 IKE_PAYLOAD *SaPayload;\r
1129 IKE_PAYLOAD *IdiPayload;\r
1130 IKE_PAYLOAD *IdrPayload;\r
1131 IKE_PAYLOAD *AuthPayload;\r
1132 IKE_PAYLOAD *TsiPayload;\r
1133 IKE_PAYLOAD *TsrPayload;\r
1134 IKE_PAYLOAD *CertPayload;\r
1135 IKE_PAYLOAD *CertReqPayload;\r
1136 IKE_PAYLOAD *VerifiedAuthPayload;\r
1137 LIST_ENTRY *Entry;\r
1138 EFI_STATUS Status;\r
1139\r
bfd4204b 1140 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {\r
9166f840 1141 return EFI_UNSUPPORTED;\r
1142 }\r
1143\r
1144 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;\r
1145 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));\r
1146\r
1147 SaPayload = NULL;\r
1148 IdiPayload = NULL;\r
1149 IdrPayload = NULL;\r
1150 AuthPayload = NULL;\r
1151 TsiPayload = NULL;\r
1152 TsrPayload = NULL;\r
1153 CertPayload = NULL;\r
1154 CertReqPayload = NULL;\r
1155 VerifiedAuthPayload = NULL;\r
1156 Status = EFI_INVALID_PARAMETER;\r
1157\r
1158 //\r
1159 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.\r
1160 //\r
1161 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {\r
1162 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
1163\r
1164 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_INIT) {\r
1165 IdiPayload = IkePayload;\r
1166 }\r
1167 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_RSP) {\r
1168 IdrPayload = IkePayload;\r
1169 }\r
1170\r
1171 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) {\r
1172 SaPayload = IkePayload;\r
1173 }\r
1174 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_AUTH) {\r
1175 AuthPayload = IkePayload;\r
1176 }\r
1177 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_INIT) {\r
1178 TsiPayload = IkePayload;\r
1179 }\r
1180 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_RSP) {\r
1181 TsrPayload = IkePayload;\r
1182 }\r
1183 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_CERT) {\r
1184 CertPayload = IkePayload;\r
1185 }\r
1186 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_CERTREQ) {\r
1187 CertReqPayload = IkePayload;\r
1188 }\r
1189 }\r
1190\r
1191 if ((SaPayload == NULL) || (AuthPayload == NULL) || (TsiPayload == NULL) || \r
1192 (TsrPayload == NULL) || (CertPayload == NULL)) {\r
1193 goto Exit;\r
1194 }\r
1195 if ((IdiPayload == NULL) && (IdrPayload == NULL)) {\r
1196 goto Exit;\r
1197 }\r
1198\r
1199 //\r
1200 // Check IkePacket Header is match the state\r
1201 //\r
1202 if (IkeSaSession->SessionCommon.IsInitiator) {\r
1203 \r
1204 //\r
1205 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND\r
1206 //\r
1207 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) ||\r
1208 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)) {\r
1209 goto Exit;\r
1210 }\r
1211 } else {\r
1212 //\r
1213 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT\r
1214 //\r
1215 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) ||\r
1216 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)) {\r
1217 goto Exit;\r
1218 }\r
1219 }\r
1220\r
1221 //\r
1222 // Verify the Auth Payload.\r
1223 //\r
1224 VerifiedAuthPayload = Ikev2CertGenerateAuthPayload (\r
1225 IkeSaSession,\r
1226 IkeSaSession->SessionCommon.IsInitiator ? IdrPayload:IdiPayload,\r
1227 IKEV2_PAYLOAD_TYPE_SA,\r
1228 TRUE,\r
1229 NULL,\r
1230 0,\r
1231 NULL,\r
1232 0\r
1233 );\r
1234\r
1235 if ((VerifiedAuthPayload != NULL) &&\r
1236 (!IpSecCryptoIoVerifySignDataByCertificate (\r
1237 CertPayload->PayloadBuf + sizeof (IKEV2_CERT),\r
1238 CertPayload->PayloadSize - sizeof (IKEV2_CERT),\r
bfd4204b 1239 (UINT8 *)PcdGetPtr (PcdIpsecUefiCaFile),\r
1240 PcdGet32 (PcdIpsecUefiCaFileSize),\r
9166f840 1241 VerifiedAuthPayload->PayloadBuf + sizeof (IKEV2_AUTH),\r
1242 VerifiedAuthPayload->PayloadSize - sizeof (IKEV2_AUTH),\r
1243 AuthPayload->PayloadBuf + sizeof (IKEV2_AUTH),\r
1244 AuthPayload->PayloadSize - sizeof (IKEV2_AUTH)\r
1245 ))) {\r
1246 goto Exit;\r
1247 }\r
1248\r
1249 //\r
1250 // 3. Parse the SA Payload to find out the cryptographic suite\r
1251 // and fill in the SA paramse into CommonSession->SaParams. If no acceptable\r
1252 // porposal found, return EFI_INVALID_PARAMETER.\r
1253 //\r
1254 if (!Ikev2ChildSaParseSaPayload (ChildSaSession, SaPayload, IkePacket->Header->Flags)) {\r
1255 goto Exit;\r
1256 }\r
1257\r
1258 //\r
1259 // 4. Parse TSi, TSr payloads.\r
1260 //\r
1261 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId !=\r
1262 ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId) &&\r
1263 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) &&\r
1264 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0)\r
1265 ) {\r
1266 goto Exit;\r
1267 }\r
1268\r
1269 if (!IkeSaSession->SessionCommon.IsInitiator) {\r
1270 //\r
1271 //Todo:check the Port range. Only support any port and one certain port here.\r
1272 //\r
1273 ChildSaSession->ProtoId = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId;\r
1274 ChildSaSession->LocalPort = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;\r
1275 ChildSaSession->RemotePort = ((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;\r
1276 //\r
1277 // Association a SPD with this SA.\r
1278 //\r
1279 if (EFI_ERROR (Ikev2ChildSaAssociateSpdEntry (ChildSaSession))) {\r
1280 goto Exit;\r
1281 }\r
1282 //\r
1283 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.\r
1284 //\r
1285 if (ChildSaSession->IkeSaSession->Spd == NULL) {\r
1286 ChildSaSession->IkeSaSession->Spd = ChildSaSession->Spd;\r
1287 Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession);\r
1288 }\r
1289 } else {\r
1290 //\r
1291 // Todo:check the Port range.\r
1292 //\r
1293 if ((((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&\r
1294 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->RemotePort)\r
1295 ) {\r
1296 goto Exit;\r
1297 } \r
1298 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&\r
1299 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->LocalPort)\r
1300 ) {\r
1301 goto Exit;\r
1302 }\r
1303 //\r
1304 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.\r
1305 //\r
1306 if (ChildSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {\r
1307 if (!ChildSaSession->IkeSaSession->SessionCommon.IsInitiator) {\r
1308 //\r
1309 // If it is tunnel mode, the UEFI part must be the initiator.\r
1310 //\r
1311 goto Exit;\r
1312 }\r
1313 //\r
1314 // Get the Virtual IP address from the Tsi traffic selector. \r
1315 // TODO: check the CFG reply payload\r
1316 //\r
1317 CopyMem (\r
1318 &ChildSaSession->SpdSelector->LocalAddress[0].Address,\r
1319 TsiPayload->PayloadBuf + sizeof (IKEV2_TS) + sizeof (TRAFFIC_SELECTOR),\r
1320 (ChildSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) ?\r
1321 sizeof (EFI_IPv4_ADDRESS) : sizeof (EFI_IPv6_ADDRESS)\r
1322 );\r
1323 }\r
1324 }\r
1325 \r
1326 //\r
1327 // 5. Generat keymats for IPsec protocol.\r
1328 //\r
1329 Ikev2GenerateChildSaKeys (ChildSaSession, NULL);\r
1330 if (IkeSaSession->SessionCommon.IsInitiator) {\r
1331 //\r
1332 // 6. Change the state of IkeSaSession\r
1333 //\r
1334 IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateIkeSaEstablished);\r
1335 IkeSaSession->SessionCommon.State = IkeStateIkeSaEstablished;\r
1336 }\r
1337\r
1338 Status = EFI_SUCCESS;\r
1339\r
1340Exit:\r
1341 if (VerifiedAuthPayload != NULL) {\r
1342 IkePayloadFree (VerifiedAuthPayload);\r
1343 }\r
1344 return Status;\r
1345}\r
1346\r
1347/**\r
1348 Generates the DH Public Key.\r
1349\r
1350 This generates the DH local public key and store it in the IKE SA Session's GxBuffer.\r
1351\r
1352 @param[in] IkeSaSession Pointer to related IKE SA Session.\r
1353\r
1354 @retval EFI_SUCCESS The operation succeeded.\r
1355 @retval Others The operation failed.\r
1356\r
1357**/\r
1358EFI_STATUS\r
1359Ikev2GenerateSaDhPublicKey (\r
1360 IN IKEV2_SA_SESSION *IkeSaSession\r
1361 )\r
1362{\r
1363 EFI_STATUS Status;\r
1364 IKEV2_SESSION_KEYS *IkeKeys;\r
1365\r
1366 IkeSaSession->IkeKeys = AllocateZeroPool (sizeof (IKEV2_SESSION_KEYS));\r
1367 ASSERT (IkeSaSession->IkeKeys != NULL);\r
1368 IkeKeys = IkeSaSession->IkeKeys;\r
1369 IkeKeys->DhBuffer = AllocateZeroPool (sizeof (IKEV2_DH_BUFFER));\r
1370 ASSERT (IkeKeys->DhBuffer != NULL);\r
1371\r
1372 //\r
1373 // Init DH with the certain DH Group Description.\r
1374 //\r
1375 IkeKeys->DhBuffer->GxSize = OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Size >> 3;\r
1376 IkeKeys->DhBuffer->GxBuffer = AllocateZeroPool (IkeKeys->DhBuffer->GxSize);\r
1377 ASSERT (IkeKeys->DhBuffer->GxBuffer != NULL);\r
1378\r
1379 //\r
1380 // Get X PublicKey\r
1381 //\r
1382 Status = IpSecCryptoIoDhGetPublicKey (\r
1383 &IkeKeys->DhBuffer->DhContext,\r
1384 OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].GroupGenerator,\r
1385 OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Size,\r
1386 OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Modulus,\r
1387 IkeKeys->DhBuffer->GxBuffer,\r
1388 &IkeKeys->DhBuffer->GxSize\r
1389 );\r
1390 if (EFI_ERROR (Status)) {\r
1391 DEBUG ((DEBUG_ERROR, "Error CPLKeyManGetKeyParam X public key error Status = %r\n", Status));\r
1392 return Status;\r
1393 }\r
1394\r
1395 IPSEC_DUMP_BUF ("DH Public Key (g^x) Dump", IkeKeys->DhBuffer->GxBuffer, IkeKeys->DhBuffer->GxSize);\r
1396\r
1397 return EFI_SUCCESS;\r
1398}\r
1399\r
1400/**\r
1401 Computes the DH Shared/Exchange Key.\r
1402\r
1403 Given peer's public key, this function computes the exchanged common key and\r
1404 stores it in the IKEv2 SA Session's GxyBuffer.\r
1405\r
1406 @param[in] DhBuffer Pointer to buffer of peer's puliic key.\r
1407 @param[in] KePayload Pointer to received key payload.\r
1408 \r
1409 @retval EFI_SUCCESS The operation succeeded.\r
1410 @retval Otherwise The operation failed.\r
1411\r
1412**/\r
1413EFI_STATUS\r
1414Ikev2GenerateSaDhComputeKey (\r
1415 IN IKEV2_DH_BUFFER *DhBuffer,\r
1416 IN IKE_PAYLOAD *KePayload\r
1417 )\r
1418{\r
1419 EFI_STATUS Status;\r
1420 IKEV2_KEY_EXCHANGE *Ke;\r
1421 UINT8 *PubKey;\r
1422 UINTN PubKeySize;\r
1423\r
1424 Ke = (IKEV2_KEY_EXCHANGE *) KePayload->PayloadBuf;\r
1425 PubKey = (UINT8 *) (Ke + 1);\r
1426 PubKeySize = KePayload->PayloadSize - sizeof (IKEV2_KEY_EXCHANGE);\r
1427 DhBuffer->GxySize = DhBuffer->GxSize;\r
1428 DhBuffer->GxyBuffer = AllocateZeroPool (DhBuffer->GxySize);\r
1429 ASSERT (DhBuffer->GxyBuffer != NULL);\r
1430\r
1431 //\r
1432 // Get GxyBuf\r
1433 //\r
1434 Status = IpSecCryptoIoDhComputeKey (\r
1435 DhBuffer->DhContext,\r
1436 PubKey,\r
1437 PubKeySize,\r
1438 DhBuffer->GxyBuffer,\r
1439 &DhBuffer->GxySize\r
1440 );\r
1441 if (EFI_ERROR (Status)) {\r
1442 DEBUG ((DEBUG_ERROR, "Error CPLKeyManGetKeyParam Y session key error Status = %r\n", Status));\r
1443 return Status;\r
1444 }\r
1445\r
1446 //\r
1447 // Create GxyBuf.\r
1448 //\r
1449 DhBuffer->GySize = PubKeySize;\r
1450 DhBuffer->GyBuffer = AllocateZeroPool (DhBuffer->GySize);\r
1451 ASSERT (DhBuffer->GyBuffer != NULL);\r
1452 CopyMem (DhBuffer->GyBuffer, PubKey, DhBuffer->GySize);\r
1453\r
1454 IPSEC_DUMP_BUF ("DH Public Key (g^y) Dump", DhBuffer->GyBuffer, DhBuffer->GySize);\r
1455 IPSEC_DUMP_BUF ("DH Shared Key (g^xy) Dump", DhBuffer->GxyBuffer, DhBuffer->GxySize);\r
1456\r
1457 return EFI_SUCCESS;\r
1458}\r
1459\r
1460/**\r
1461 Generates the IKE SKEYSEED and seven other secrets. SK_d, SK_ai, SK_ar, SK_ei, SK_er,\r
1462 SK_pi, SK_pr are keys for the furthure IKE exchange.\r
1463\r
1464 @param[in] IkeSaSession Pointer to IKE SA Session.\r
1465 @param[in] KePayload Pointer to Key payload used to generate the Key.\r
1466\r
1467 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.\r
1468 @retval EFI_OUT_OF_RESOURCES If there is no enough resource to be allocated to\r
1469 meet the requirement.\r
1470 @retval EFI_SUCCESS The operation succeeded.\r
1471\r
1472**/\r
1473EFI_STATUS\r
1474Ikev2GenerateSaKeys (\r
1475 IN IKEV2_SA_SESSION *IkeSaSession,\r
1476 IN IKE_PAYLOAD *KePayload\r
1477 )\r
1478{\r
1479 EFI_STATUS Status;\r
1480 IKEV2_SA_PARAMS *SaParams;\r
1481 IPSEC_PAD_ENTRY *Pad;\r
1482 PRF_DATA_FRAGMENT Fragments[4];\r
1483 UINT64 InitiatorCookieNet;\r
1484 UINT64 ResponderCookieNet;\r
1485 UINT8 *KeyBuffer;\r
1486 UINTN KeyBufferSize;\r
1487 UINTN AuthAlgKeyLen;\r
1488 UINTN EncryptAlgKeyLen;\r
1489 UINTN IntegrityAlgKeyLen;\r
1490 UINTN PrfAlgKeyLen;\r
1491 UINT8 *OutputKey;\r
1492 UINTN OutputKeyLength;\r
1493 UINT8 *Digest;\r
1494 UINTN DigestSize;\r
1495\r
1496 Digest = NULL;\r
1497 OutputKey = NULL;\r
1498 KeyBuffer = NULL;\r
02a758cb 1499 Status = EFI_SUCCESS;\r
9166f840 1500\r
1501 //\r
1502 // Generate Gxy\r
1503 //\r
1504 Ikev2GenerateSaDhComputeKey (IkeSaSession->IkeKeys->DhBuffer, KePayload);\r
1505\r
1506 Pad = IkeSaSession->Pad;\r
1507\r
1508 //\r
1509 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.\r
1510 //\r
1511 SaParams = IkeSaSession->SessionCommon.SaParams;\r
1512 AuthAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf);\r
1513 EncryptAlgKeyLen = IpSecGetEncryptKeyLength ((UINT8)SaParams->EncAlgId);\r
1514 IntegrityAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->IntegAlgId);\r
1515 PrfAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf);\r
1516\r
1517 //\r
1518 // If one or more algorithm is not support, return EFI_UNSUPPORTED.\r
1519 //\r
1520 if (AuthAlgKeyLen == 0 || \r
1521 EncryptAlgKeyLen == 0 ||\r
1522 IntegrityAlgKeyLen == 0 ||\r
1523 PrfAlgKeyLen == 0\r
1524 ) {\r
1525 Status = EFI_UNSUPPORTED;\r
1526 goto Exit;\r
1527 }\r
1528\r
1529 //\r
1530 // Compute SKEYSEED = prf(Ni | Nr, g^ir)\r
1531 //\r
1532 KeyBufferSize = IkeSaSession->NiBlkSize + IkeSaSession->NrBlkSize;\r
1533 KeyBuffer = AllocateZeroPool (KeyBufferSize);\r
1534 ASSERT (KeyBuffer != NULL);\r
1535\r
1536 CopyMem (KeyBuffer, IkeSaSession->NiBlock, IkeSaSession->NiBlkSize);\r
1537 CopyMem (KeyBuffer + IkeSaSession->NiBlkSize, IkeSaSession->NrBlock, IkeSaSession->NrBlkSize);\r
1538\r
1539 Fragments[0].Data = IkeSaSession->IkeKeys->DhBuffer->GxyBuffer;\r
1540 Fragments[0].DataSize = IkeSaSession->IkeKeys->DhBuffer->GxySize;\r
1541\r
1542 DigestSize = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf);\r
1543 Digest = AllocateZeroPool (DigestSize);\r
1544\r
1545 if (Digest == NULL) {\r
1546 Status = EFI_OUT_OF_RESOURCES;\r
1547 goto Exit;\r
1548 }\r
1549\r
1550 IpSecCryptoIoHmac (\r
1551 (UINT8)SaParams->Prf,\r
1552 KeyBuffer,\r
1553 KeyBufferSize,\r
1554 (HASH_DATA_FRAGMENT *) Fragments,\r
1555 1,\r
1556 Digest,\r
1557 DigestSize\r
1558 );\r
1559\r
1560 //\r
1561 // {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } = prf+\r
1562 // (SKEYSEED, Ni | Nr | SPIi | SPIr )\r
1563 //\r
1564 Fragments[0].Data = IkeSaSession->NiBlock;\r
1565 Fragments[0].DataSize = IkeSaSession->NiBlkSize;\r
1566 Fragments[1].Data = IkeSaSession->NrBlock;\r
1567 Fragments[1].DataSize = IkeSaSession->NrBlkSize;\r
1568 InitiatorCookieNet = HTONLL (IkeSaSession->InitiatorCookie);\r
1569 ResponderCookieNet = HTONLL (IkeSaSession->ResponderCookie);\r
1570 Fragments[2].Data = (UINT8 *)(&InitiatorCookieNet);\r
1571 Fragments[2].DataSize = sizeof (IkeSaSession->InitiatorCookie);\r
1572 Fragments[3].Data = (UINT8 *)(&ResponderCookieNet);\r
1573 Fragments[3].DataSize = sizeof (IkeSaSession->ResponderCookie);\r
1574\r
1575 IPSEC_DUMP_BUF (">>> NiBlock", IkeSaSession->NiBlock, IkeSaSession->NiBlkSize);\r
1576 IPSEC_DUMP_BUF (">>> NrBlock", IkeSaSession->NrBlock, IkeSaSession->NrBlkSize);\r
1577 IPSEC_DUMP_BUF (">>> InitiatorCookie", (UINT8 *)&IkeSaSession->InitiatorCookie, sizeof(UINT64));\r
1578 IPSEC_DUMP_BUF (">>> ResponderCookie", (UINT8 *)&IkeSaSession->ResponderCookie, sizeof(UINT64));\r
1579 \r
1580 OutputKeyLength = PrfAlgKeyLen + \r
1581 2 * EncryptAlgKeyLen +\r
1582 2 * AuthAlgKeyLen +\r
1583 2 * IntegrityAlgKeyLen;\r
1584 OutputKey = AllocateZeroPool (OutputKeyLength);\r
02a758cb 1585 if (OutputKey == NULL) {\r
1586 Status = EFI_OUT_OF_RESOURCES;\r
1587 goto Exit;\r
1588 }\r
9166f840 1589\r
1590 //\r
1591 // Generate Seven Keymates.\r
1592 //\r
1593 Status = Ikev2SaGenerateKey (\r
1594 (UINT8)SaParams->Prf,\r
1595 Digest,\r
1596 DigestSize,\r
1597 OutputKey,\r
1598 OutputKeyLength,\r
1599 Fragments,\r
1600 4\r
1601 );\r
1602 if (EFI_ERROR(Status)) {\r
1603 goto Exit;\r
1604 }\r
1605\r
1606 //\r
1607 // Save the seven keys into KeySession.\r
1608 // First, SK_d\r
1609 //\r
1610 IkeSaSession->IkeKeys->SkdKey = AllocateZeroPool (PrfAlgKeyLen);\r
02a758cb 1611 if (IkeSaSession->IkeKeys->SkdKey == NULL) {\r
1612 Status = EFI_OUT_OF_RESOURCES;\r
1613 goto Exit;\r
1614 }\r
9166f840 1615 IkeSaSession->IkeKeys->SkdKeySize = PrfAlgKeyLen;\r
1616 CopyMem (IkeSaSession->IkeKeys->SkdKey, OutputKey, PrfAlgKeyLen);\r
1617\r
1618 IPSEC_DUMP_BUF (">>> SK_D Key", IkeSaSession->IkeKeys->SkdKey, PrfAlgKeyLen);\r
1619\r
1620 //\r
1621 // Second, Sk_ai\r
1622 //\r
1623 IkeSaSession->IkeKeys->SkAiKey = AllocateZeroPool (IntegrityAlgKeyLen);\r
02a758cb 1624 if (IkeSaSession->IkeKeys->SkAiKey == NULL) {\r
1625 Status = EFI_OUT_OF_RESOURCES;\r
1626 goto Exit;\r
1627 }\r
9166f840 1628 IkeSaSession->IkeKeys->SkAiKeySize = IntegrityAlgKeyLen;\r
1629 CopyMem (IkeSaSession->IkeKeys->SkAiKey, OutputKey + PrfAlgKeyLen, IntegrityAlgKeyLen);\r
1630 \r
1631 IPSEC_DUMP_BUF (">>> SK_Ai Key", IkeSaSession->IkeKeys->SkAiKey, IkeSaSession->IkeKeys->SkAiKeySize);\r
1632\r
1633 //\r
1634 // Third, Sk_ar\r
1635 //\r
1636 IkeSaSession->IkeKeys->SkArKey = AllocateZeroPool (IntegrityAlgKeyLen);\r
02a758cb 1637 if (IkeSaSession->IkeKeys->SkArKey == NULL) {\r
1638 Status = EFI_OUT_OF_RESOURCES;\r
1639 goto Exit;\r
1640 }\r
9166f840 1641 IkeSaSession->IkeKeys->SkArKeySize = IntegrityAlgKeyLen;\r
1642 CopyMem (\r
1643 IkeSaSession->IkeKeys->SkArKey,\r
1644 OutputKey + PrfAlgKeyLen + IntegrityAlgKeyLen,\r
1645 IntegrityAlgKeyLen\r
1646 );\r
1647 \r
1648 IPSEC_DUMP_BUF (">>> SK_Ar Key", IkeSaSession->IkeKeys->SkArKey, IkeSaSession->IkeKeys->SkArKeySize);\r
1649\r
1650 //\r
1651 // Fourth, Sk_ei\r
1652 //\r
1653 IkeSaSession->IkeKeys->SkEiKey = AllocateZeroPool (EncryptAlgKeyLen);\r
02a758cb 1654 if (IkeSaSession->IkeKeys->SkEiKey == NULL) {\r
1655 Status = EFI_OUT_OF_RESOURCES;\r
1656 goto Exit;\r
1657 }\r
9166f840 1658 IkeSaSession->IkeKeys->SkEiKeySize = EncryptAlgKeyLen;\r
1659 \r
1660 CopyMem (\r
1661 IkeSaSession->IkeKeys->SkEiKey,\r
1662 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen,\r
1663 EncryptAlgKeyLen\r
1664 );\r
1665 IPSEC_DUMP_BUF (\r
1666 ">>> SK_Ei Key", \r
1667 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen,\r
1668 EncryptAlgKeyLen\r
1669 );\r
1670\r
1671 //\r
1672 // Fifth, Sk_er\r
1673 //\r
1674 IkeSaSession->IkeKeys->SkErKey = AllocateZeroPool (EncryptAlgKeyLen);\r
02a758cb 1675 if (IkeSaSession->IkeKeys->SkErKey == NULL) {\r
1676 Status = EFI_OUT_OF_RESOURCES;\r
1677 goto Exit;\r
1678 }\r
9166f840 1679 IkeSaSession->IkeKeys->SkErKeySize = EncryptAlgKeyLen;\r
1680\r
1681 CopyMem (\r
1682 IkeSaSession->IkeKeys->SkErKey,\r
1683 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + EncryptAlgKeyLen,\r
1684 EncryptAlgKeyLen\r
1685 );\r
1686 IPSEC_DUMP_BUF (\r
1687 ">>> SK_Er Key",\r
1688 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + EncryptAlgKeyLen,\r
1689 EncryptAlgKeyLen\r
1690 );\r
1691\r
1692 //\r
1693 // Sixth, Sk_pi\r
1694 //\r
1695 IkeSaSession->IkeKeys->SkPiKey = AllocateZeroPool (AuthAlgKeyLen);\r
02a758cb 1696 if (IkeSaSession->IkeKeys->SkPiKey == NULL) {\r
1697 Status = EFI_OUT_OF_RESOURCES;\r
1698 goto Exit;\r
1699 }\r
9166f840 1700 IkeSaSession->IkeKeys->SkPiKeySize = AuthAlgKeyLen;\r
1701\r
1702 CopyMem (\r
1703 IkeSaSession->IkeKeys->SkPiKey,\r
1704 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen,\r
1705 AuthAlgKeyLen\r
1706 );\r
1707 IPSEC_DUMP_BUF (\r
1708 ">>> SK_Pi Key",\r
1709 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen,\r
1710 AuthAlgKeyLen\r
1711 );\r
1712\r
1713 //\r
1714 // Seventh, Sk_pr\r
1715 //\r
1716 IkeSaSession->IkeKeys->SkPrKey = AllocateZeroPool (AuthAlgKeyLen);\r
02a758cb 1717 if (IkeSaSession->IkeKeys->SkPrKey == NULL) {\r
1718 Status = EFI_OUT_OF_RESOURCES;\r
1719 goto Exit;\r
1720 }\r
9166f840 1721 IkeSaSession->IkeKeys->SkPrKeySize = AuthAlgKeyLen;\r
1722\r
1723 CopyMem (\r
1724 IkeSaSession->IkeKeys->SkPrKey,\r
1725 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen + AuthAlgKeyLen,\r
1726 AuthAlgKeyLen\r
1727 ); \r
1728 IPSEC_DUMP_BUF (\r
1729 ">>> SK_Pr Key",\r
1730 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen + AuthAlgKeyLen,\r
1731 AuthAlgKeyLen\r
1732 );\r
1733\r
1734\r
1735Exit:\r
1736 if (Digest != NULL) {\r
1737 FreePool (Digest);\r
1738 }\r
1739 if (KeyBuffer != NULL) {\r
1740 FreePool (KeyBuffer);\r
1741 }\r
1742 if (OutputKey != NULL) {\r
1743 FreePool (OutputKey);\r
1744 }\r
02a758cb 1745\r
1746 if (EFI_ERROR(Status)) {\r
1747 if (IkeSaSession->IkeKeys->SkdKey != NULL) {\r
1748 FreePool (IkeSaSession->IkeKeys->SkdKey);\r
1749 }\r
1750 if (IkeSaSession->IkeKeys->SkAiKey != NULL) {\r
1751 FreePool (IkeSaSession->IkeKeys->SkAiKey);\r
1752 }\r
1753 if (IkeSaSession->IkeKeys->SkArKey != NULL) {\r
1754 FreePool (IkeSaSession->IkeKeys->SkArKey);\r
1755 }\r
1756 if (IkeSaSession->IkeKeys->SkEiKey != NULL) {\r
1757 FreePool (IkeSaSession->IkeKeys->SkEiKey);\r
1758 }\r
1759 if (IkeSaSession->IkeKeys->SkErKey != NULL) {\r
1760 FreePool (IkeSaSession->IkeKeys->SkErKey);\r
1761 }\r
1762 if (IkeSaSession->IkeKeys->SkPiKey != NULL) {\r
1763 FreePool (IkeSaSession->IkeKeys->SkPiKey);\r
1764 }\r
1765 if (IkeSaSession->IkeKeys->SkPrKey != NULL) {\r
1766 FreePool (IkeSaSession->IkeKeys->SkPrKey);\r
1767 }\r
1768 }\r
1769\r
9166f840 1770 \r
1771 return Status;\r
1772}\r
1773\r
1774/**\r
1775 Generates the Keys for the furthure IPsec Protocol.\r
1776\r
1777 @param[in] ChildSaSession Pointer to IKE Child SA Session.\r
1778 @param[in] KePayload Pointer to Key payload used to generate the Key.\r
1779\r
1780 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.\r
1781 @retval EFI_SUCCESS The operation succeeded.\r
1782\r
1783**/\r
1784EFI_STATUS\r
1785Ikev2GenerateChildSaKeys (\r
1786 IN IKEV2_CHILD_SA_SESSION *ChildSaSession,\r
1787 IN IKE_PAYLOAD *KePayload\r
1788 )\r
1789{\r
1790 EFI_STATUS Status;\r
1791 IKEV2_SA_PARAMS *SaParams;\r
1792 PRF_DATA_FRAGMENT Fragments[3];\r
1793 UINTN EncryptAlgKeyLen;\r
1794 UINTN IntegrityAlgKeyLen;\r
1795 UINT8* OutputKey;\r
1796 UINTN OutputKeyLength;\r
1797\r
02a758cb 1798 Status = EFI_SUCCESS;\r
1799 OutputKey = NULL;\r
1800 \r
9166f840 1801 if (KePayload != NULL) {\r
1802 //\r
1803 // Generate Gxy \r
1804 //\r
1805 Ikev2GenerateSaDhComputeKey (ChildSaSession->DhBuffer, KePayload);\r
1806 Fragments[0].Data = ChildSaSession->DhBuffer->GxyBuffer;\r
1807 Fragments[0].DataSize = ChildSaSession->DhBuffer->GxySize;\r
1808 }\r
1809\r
1810 Fragments[1].Data = ChildSaSession->NiBlock;\r
1811 Fragments[1].DataSize = ChildSaSession->NiBlkSize;\r
1812 Fragments[2].Data = ChildSaSession->NrBlock;\r
1813 Fragments[2].DataSize = ChildSaSession->NrBlkSize;\r
1814\r
1815 //\r
1816 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.\r
1817 //\r
1818 SaParams = ChildSaSession->SessionCommon.SaParams;\r
1819 EncryptAlgKeyLen = IpSecGetEncryptKeyLength ((UINT8)SaParams->EncAlgId);\r
1820 IntegrityAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->IntegAlgId);\r
1821 OutputKeyLength = 2 * EncryptAlgKeyLen + 2 * IntegrityAlgKeyLen;\r
1822\r
1823 if ((EncryptAlgKeyLen == 0) || (IntegrityAlgKeyLen == 0)) {\r
02a758cb 1824 Status = EFI_UNSUPPORTED;\r
1825 goto Exit;\r
9166f840 1826 }\r
1827\r
1828 //\r
1829 // \r
1830 // If KePayload is not NULL, calculate KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr ),\r
1831 // otherwise, KEYMAT = prf+(SK_d, Ni | Nr )\r
1832 //\r
1833 OutputKey = AllocateZeroPool (OutputKeyLength);\r
02a758cb 1834 if (OutputKey == NULL) {\r
1835 Status = EFI_OUT_OF_RESOURCES;\r
1836 goto Exit;\r
1837 }\r
9166f840 1838\r
1839 //\r
1840 // Derive Key from the SkdKey Buffer.\r
1841 //\r
1842 Status = Ikev2SaGenerateKey (\r
1843 (UINT8)ChildSaSession->IkeSaSession->SessionCommon.SaParams->Prf,\r
1844 ChildSaSession->IkeSaSession->IkeKeys->SkdKey,\r
1845 ChildSaSession->IkeSaSession->IkeKeys->SkdKeySize,\r
1846 OutputKey,\r
1847 OutputKeyLength,\r
1848 KePayload == NULL ? &Fragments[1] : Fragments,\r
1849 KePayload == NULL ? 2 : 3\r
1850 );\r
1851\r
1852 if (EFI_ERROR (Status)) {\r
02a758cb 1853 goto Exit; \r
9166f840 1854 }\r
1855 \r
1856 //\r
1857 // Copy KEYMATE (SK_ENCRYPT_i | SK_ENCRYPT_r | SK_INTEG_i | SK_INTEG_r) to\r
1858 // ChildKeyMates.\r
1859 // \r
1860 if (!ChildSaSession->SessionCommon.IsInitiator) {\r
1861\r
1862 // \r
1863 // Initiator Encryption Key\r
1864 //\r
1865 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;\r
1866 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;\r
1867 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);\r
02a758cb 1868 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey == NULL) {\r
1869 Status = EFI_OUT_OF_RESOURCES;\r
1870 goto Exit;\r
1871 }\r
9166f840 1872\r
1873 CopyMem (\r
1874 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey,\r
1875 OutputKey,\r
1876 EncryptAlgKeyLen\r
1877 );\r
1878\r
1879 //\r
1880 // Initiator Authentication Key\r
1881 //\r
1882 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;\r
1883 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;\r
1884 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);\r
02a758cb 1885 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey == NULL) {\r
1886 Status = EFI_OUT_OF_RESOURCES;\r
1887 goto Exit;\r
1888 } \r
1889 \r
9166f840 1890 CopyMem (\r
1891 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey,\r
1892 OutputKey + EncryptAlgKeyLen,\r
1893 IntegrityAlgKeyLen\r
1894 );\r
1895\r
1896 //\r
1897 // Responder Encrypt Key\r
1898 //\r
1899 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;\r
1900 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;\r
1901 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);\r
02a758cb 1902 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey == NULL) {\r
1903 Status = EFI_OUT_OF_RESOURCES;\r
1904 goto Exit;\r
1905 } \r
1906 \r
9166f840 1907 CopyMem (\r
1908 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey,\r
1909 OutputKey + EncryptAlgKeyLen + IntegrityAlgKeyLen,\r
1910 EncryptAlgKeyLen\r
1911 );\r
1912\r
1913 //\r
1914 // Responder Authentication Key\r
1915 //\r
1916 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;\r
1917 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;\r
1918 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);\r
02a758cb 1919 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey == NULL) {\r
1920 Status = EFI_OUT_OF_RESOURCES;\r
1921 goto Exit;\r
1922 } \r
9166f840 1923 \r
1924 CopyMem (\r
1925 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey,\r
1926 OutputKey + 2 * EncryptAlgKeyLen + IntegrityAlgKeyLen,\r
1927 IntegrityAlgKeyLen\r
1928 );\r
1929 } else {\r
1930 //\r
1931 // Initiator Encryption Key\r
1932 //\r
1933 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;\r
1934 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;\r
1935 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);\r
02a758cb 1936 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey == NULL) {\r
1937 Status = EFI_OUT_OF_RESOURCES;\r
1938 goto Exit;\r
1939 } \r
1940 \r
9166f840 1941 CopyMem (\r
1942 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey,\r
1943 OutputKey,\r
1944 EncryptAlgKeyLen\r
1945 );\r
1946\r
1947 //\r
1948 // Initiator Authentication Key\r
1949 //\r
1950 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;\r
1951 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;\r
1952 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);\r
02a758cb 1953 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey == NULL) {\r
1954 Status = EFI_OUT_OF_RESOURCES;\r
1955 goto Exit;\r
1956 } \r
1957 \r
9166f840 1958 CopyMem (\r
1959 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey,\r
1960 OutputKey + EncryptAlgKeyLen,\r
1961 IntegrityAlgKeyLen\r
1962 );\r
1963\r
1964 //\r
1965 // Responder Encryption Key\r
1966 //\r
1967 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;\r
1968 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;\r
1969 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);\r
02a758cb 1970 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey == NULL) {\r
1971 Status = EFI_OUT_OF_RESOURCES;\r
1972 goto Exit;\r
1973 } \r
1974 \r
9166f840 1975 CopyMem (\r
1976 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey,\r
1977 OutputKey + EncryptAlgKeyLen + IntegrityAlgKeyLen,\r
1978 EncryptAlgKeyLen\r
1979 );\r
1980\r
1981 //\r
1982 // Responder Authentication Key\r
1983 //\r
1984 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;\r
1985 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;\r
1986 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);\r
02a758cb 1987 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey == NULL) {\r
1988 Status = EFI_OUT_OF_RESOURCES;\r
1989 goto Exit;\r
1990 } \r
1991 \r
9166f840 1992 CopyMem (\r
1993 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey,\r
1994 OutputKey + 2 * EncryptAlgKeyLen + IntegrityAlgKeyLen,\r
1995 IntegrityAlgKeyLen\r
1996 );\r
1997 }\r
1998\r
1999 IPSEC_DUMP_BUF (\r
2000 " >>> Local Encryption Key",\r
2001 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey,\r
2002 EncryptAlgKeyLen\r
2003 );\r
2004 IPSEC_DUMP_BUF (\r
2005 " >>> Remote Encryption Key",\r
2006 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey,\r
2007 EncryptAlgKeyLen\r
2008 );\r
2009 IPSEC_DUMP_BUF (\r
2010 " >>> Local Authentication Key",\r
2011 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey,\r
2012 IntegrityAlgKeyLen\r
2013 );\r
2014 IPSEC_DUMP_BUF (\r
2015 " >>> Remote Authentication Key",\r
2016 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey,\r
2017 IntegrityAlgKeyLen\r
2018 );\r
2019\r
02a758cb 2020\r
2021\r
2022Exit:\r
2023 if (EFI_ERROR (Status)) {\r
2024 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey != NULL) {\r
2025 FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey);\r
2026 }\r
2027 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey != NULL) {\r
2028 FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey);\r
2029 }\r
2030 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey != NULL) {\r
2031 FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey);\r
2032 }\r
2033 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey != NULL) {\r
2034 FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey);\r
2035 }\r
2036 }\r
2037\r
2038 if (OutputKey != NULL) {\r
2039 FreePool (OutputKey);\r
2040 }\r
9166f840 2041 \r
2042 return EFI_SUCCESS;\r
2043}\r
2044\r
2045GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Initial[][2] = {\r
2046 { //PSK\r
2047 { // IKEV2_INIT\r
2048 Ikev2InitPskParser,\r
2049 Ikev2InitPskGenerator\r
2050 },\r
2051 { //IKEV2_AUTH\r
2052 Ikev2AuthPskParser,\r
2053 Ikev2AuthPskGenerator\r
2054 }\r
2055 },\r
2056 { // CERT\r
2057 { // IKEV2_INIT\r
2058 Ikev2InitCertParser,\r
2059 Ikev2InitCertGenerator\r
2060 },\r
2061 { // IKEV2_AUTH\r
2062 Ikev2AuthCertParser,\r
2063 Ikev2AuthCertGenerator\r
2064 },\r
2065 },\r
2066};\r