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