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