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