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