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