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