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