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