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