summaryrefslogtreecommitdiff
path: root/NetworkPkg/IpSecDxe/Ikev2/Sa.c
diff options
context:
space:
mode:
Diffstat (limited to 'NetworkPkg/IpSecDxe/Ikev2/Sa.c')
-rw-r--r--NetworkPkg/IpSecDxe/Ikev2/Sa.c2262
1 files changed, 0 insertions, 2262 deletions
diff --git a/NetworkPkg/IpSecDxe/Ikev2/Sa.c b/NetworkPkg/IpSecDxe/Ikev2/Sa.c
deleted file mode 100644
index 4cbfac33b1..0000000000
--- a/NetworkPkg/IpSecDxe/Ikev2/Sa.c
+++ /dev/null
@@ -1,2262 +0,0 @@
-/** @file
- The operations for IKEv2 SA.
-
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
- Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php.
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "Utility.h"
-#include "IpSecDebug.h"
-#include "IkeService.h"
-#include "Ikev2.h"
-
-/**
- Generates the DH Key.
-
- This generates the DH local public key and store it in the IKEv2 SA Session's GxBuffer.
-
- @param[in] IkeSaSession Pointer to related IKE SA Session.
-
- @retval EFI_SUCCESS The operation succeeded.
- @retval Others The operation failed.
-
-**/
-EFI_STATUS
-Ikev2GenerateSaDhPublicKey (
- IN IKEV2_SA_SESSION *IkeSaSession
- );
-
-/**
- Generates the IKEv2 SA key for the furthure IKEv2 exchange.
-
- @param[in] IkeSaSession Pointer to IKEv2 SA Session.
- @param[in] KePayload Pointer to Key payload used to generate the Key.
-
- @retval EFI_UNSUPPORTED If the Algorithm Id is not supported.
- @retval EFI_SUCCESS The operation succeeded.
-
-**/
-EFI_STATUS
-Ikev2GenerateSaKeys (
- IN IKEV2_SA_SESSION *IkeSaSession,
- IN IKE_PAYLOAD *KePayload
- );
-
-/**
- Generates the Keys for the furthure IPsec Protocol.
-
- @param[in] ChildSaSession Pointer to IKE Child SA Session.
- @param[in] KePayload Pointer to Key payload used to generate the Key.
-
- @retval EFI_UNSUPPORTED If one or more Algorithm Id is unsupported.
- @retval EFI_SUCCESS The operation succeeded.
-
-**/
-EFI_STATUS
-Ikev2GenerateChildSaKeys (
- IN IKEV2_CHILD_SA_SESSION *ChildSaSession,
- IN IKE_PAYLOAD *KePayload
- );
-
-/**
- Gernerates IKEv2 packet for IKE_SA_INIT exchange.
-
- @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
- @param[in] Context Context Data passed by caller.
-
- @retval EFI_SUCCESS The IKEv2 packet generation succeeded.
- @retval Others The IKEv2 packet generation failed.
-
-**/
-IKE_PACKET *
-Ikev2InitPskGenerator (
- IN UINT8 *SaSession,
- IN VOID *Context
- )
-{
- IKE_PACKET *IkePacket;
- IKEV2_SA_SESSION *IkeSaSession;
- IKE_PAYLOAD *SaPayload;
- IKE_PAYLOAD *KePayload;
- IKE_PAYLOAD *NoncePayload;
- IKE_PAYLOAD *NotifyPayload;
- EFI_STATUS Status;
-
- SaPayload = NULL;
- KePayload = NULL;
- NoncePayload = NULL;
- NotifyPayload = NULL;
-
- IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
-
- //
- // 1. Allocate IKE packet
- //
- IkePacket = IkePacketAlloc ();
- if (IkePacket == NULL) {
- goto CheckError;
- }
-
- //
- // 1.a Fill the IkePacket->Hdr
- //
- IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_INIT;
- IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;
- IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;
- IkePacket->Header->Version = (UINT8) (2 << 4);
- IkePacket->Header->MessageId = 0;
-
- if (IkeSaSession->SessionCommon.IsInitiator) {
- IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;
- } else {
- IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
- }
-
- //
- // If the NCookie is not NULL, this IKE_SA_INIT packet is resent by the NCookie
- // and the NCookie payload should be the first payload in this packet.
- //
- if (IkeSaSession->NCookie != NULL) {
- IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_NOTIFY;
- NotifyPayload = Ikev2GenerateNotifyPayload (
- IPSEC_PROTO_ISAKMP,
- IKEV2_PAYLOAD_TYPE_SA,
- 0,
- IKEV2_NOTIFICATION_COOKIE,
- NULL,
- IkeSaSession->NCookie,
- IkeSaSession->NCookieSize
- );
- } else {
- IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_SA;
- }
-
- //
- // 2. Generate SA Payload according to the SaData & SaParams
- //
- SaPayload = Ikev2GenerateSaPayload (
- IkeSaSession->SaData,
- IKEV2_PAYLOAD_TYPE_KE,
- IkeSessionTypeIkeSa
- );
-
- //
- // 3. Generate DH public key.
- // The DhPrivate Key has been generated in Ikev2InitPskParser, if the
- // IkeSaSession is responder. If resending IKE_SA_INIT with Cookie Notify
- // No need to recompute the Public key.
- //
- if ((IkeSaSession->SessionCommon.IsInitiator) && (IkeSaSession->NCookie == NULL)) {
- Status = Ikev2GenerateSaDhPublicKey (IkeSaSession);
- if (EFI_ERROR (Status)) {
- goto CheckError;
- }
- }
-
- //
- // 4. Generate KE Payload according to SaParams->DhGroup
- //
- KePayload = Ikev2GenerateKePayload (
- IkeSaSession,
- IKEV2_PAYLOAD_TYPE_NONCE
- );
-
- //
- // 5. Generate Nonce Payload
- // If resending IKE_SA_INIT with Cookie Notify paylaod, no need to regenerate
- // the Nonce Payload.
- //
- if ((IkeSaSession->SessionCommon.IsInitiator) && (IkeSaSession->NCookie == NULL)) {
- IkeSaSession->NiBlkSize = IKE_NONCE_SIZE;
- IkeSaSession->NiBlock = IkeGenerateNonce (IKE_NONCE_SIZE);
- if (IkeSaSession->NiBlock == NULL) {
- goto CheckError;
- }
- }
-
- if (IkeSaSession->SessionCommon.IsInitiator) {
- NoncePayload = Ikev2GenerateNoncePayload (
- IkeSaSession->NiBlock,
- IkeSaSession->NiBlkSize,
- IKEV2_PAYLOAD_TYPE_NONE
- );
- } else {
- //
- // The Nonce Payload has been created in Ikev2PskParser if the IkeSaSession is
- // responder.
- //
- NoncePayload = Ikev2GenerateNoncePayload (
- IkeSaSession->NrBlock,
- IkeSaSession->NrBlkSize,
- IKEV2_PAYLOAD_TYPE_NONE
- );
- }
-
- if (NotifyPayload != NULL) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload);
- }
- if (SaPayload != NULL) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload);
- }
- if (KePayload != NULL) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, KePayload);
- }
- if (NoncePayload != NULL) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, NoncePayload);
- }
-
- return IkePacket;
-
-CheckError:
- if (IkePacket != NULL) {
- IkePacketFree (IkePacket);
- }
- if (SaPayload != NULL) {
- IkePayloadFree (SaPayload);
- }
- return NULL;
-}
-
-/**
- Parses the IKEv2 packet for IKE_SA_INIT exchange.
-
- @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
- @param[in] IkePacket The received IKE packet to be parsed.
-
- @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is
- saved for furthure communication.
- @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA proposal is unacceptable.
-
-**/
-EFI_STATUS
-Ikev2InitPskParser (
- IN UINT8 *SaSession,
- IN IKE_PACKET *IkePacket
- )
-{
- IKEV2_SA_SESSION *IkeSaSession;
- IKE_PAYLOAD *SaPayload;
- IKE_PAYLOAD *KeyPayload;
- IKE_PAYLOAD *IkePayload;
- IKE_PAYLOAD *NoncePayload;
- IKE_PAYLOAD *NotifyPayload;
- UINT8 *NonceBuffer;
- UINTN NonceSize;
- LIST_ENTRY *Entry;
- EFI_STATUS Status;
-
- IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
- KeyPayload = NULL;
- SaPayload = NULL;
- NoncePayload = NULL;
- IkePayload = NULL;
- NotifyPayload = NULL;
-
- //
- // Iterate payloads to find the SaPayload and KeyPayload.
- //
- NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {
- IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) {
- SaPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_KE) {
- KeyPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_NONCE) {
- NoncePayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_NOTIFY) {
- NotifyPayload = IkePayload;
- }
- }
-
- //
- // According to RFC 4306 - 2.6. If the responder responds with the COOKIE Notify
- // payload with the cookie data, initiator MUST retry the IKE_SA_INIT with a
- // Notify payload of type COOKIE containing the responder suppplied cookie data
- // as first payload and all other payloads unchanged.
- //
- if (IkeSaSession->SessionCommon.IsInitiator) {
- if (NotifyPayload != NULL) {
- Status = Ikev2ParserNotifyCookiePayload (NotifyPayload, IkeSaSession);
- return Status;
- }
- }
-
- if ((KeyPayload == NULL) || (SaPayload == NULL) || (NoncePayload == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Store NoncePayload for SKEYID computing.
- //
- NonceSize = NoncePayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER);
- NonceBuffer = (UINT8 *) AllocatePool (NonceSize);
- if (NonceBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto CheckError;
- }
-
- CopyMem (
- NonceBuffer,
- NoncePayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),
- NonceSize
- );
-
- //
- // Check if IkePacket Header matches the state
- //
- if (IkeSaSession->SessionCommon.IsInitiator) {
- //
- // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
- //
- if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) {
- Status = EFI_INVALID_PARAMETER;
- goto CheckError;
- }
-
- //
- // 2. Parse the SA Payload and Key Payload to find out the cryptographic
- // suite and fill in the Sa paramse into CommonSession->SaParams
- //
- if (!Ikev2SaParseSaPayload (IkeSaSession, SaPayload, IkePacket->Header->Flags)) {
- Status = EFI_INVALID_PARAMETER;
- goto CheckError;
- }
-
- //
- // 3. If Initiator, the NoncePayload is Nr_b.
- //
- IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateAuth);
- IkeSaSession->NrBlock = NonceBuffer;
- IkeSaSession->NrBlkSize = NonceSize;
- IkeSaSession->SessionCommon.State = IkeStateAuth;
- IkeSaSession->ResponderCookie = IkePacket->Header->ResponderCookie;
-
- //
- // 4. Change the state of IkeSaSession
- //
- IkeSaSession->SessionCommon.State = IkeStateAuth;
- } else {
- //
- // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
- //
- if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) {
- Status = EFI_INVALID_PARAMETER;
- goto CheckError;
- }
-
- //
- // 2. Parse the SA payload and find out the perfered one
- // and fill in the SA parameters into CommonSession->SaParams and SaData into
- // IkeSaSession for the responder SA payload generation.
- //
- if (!Ikev2SaParseSaPayload (IkeSaSession, SaPayload, IkePacket->Header->Flags)) {
- Status = EFI_INVALID_PARAMETER;
- goto CheckError;
- }
-
- //
- // 3. Generat Dh Y parivate Key
- //
- Status = Ikev2GenerateSaDhPublicKey (IkeSaSession);
- if (EFI_ERROR (Status)) {
- goto CheckError;
- }
-
- //
- // 4. If Responder, the NoncePayload is Ni_b and go to generate Nr_b.
- //
- IkeSaSession->NiBlock = NonceBuffer;
- IkeSaSession->NiBlkSize = NonceSize;
-
- //
- // 5. Generate Nr_b
- //
- IkeSaSession->NrBlock = IkeGenerateNonce (IKE_NONCE_SIZE);
- ASSERT (IkeSaSession->NrBlock != NULL);
- IkeSaSession->NrBlkSize = IKE_NONCE_SIZE;
-
- //
- // 6. Save the Cookies
- //
- IkeSaSession->InitiatorCookie = IkePacket->Header->InitiatorCookie;
- IkeSaSession->ResponderCookie = IkeGenerateCookie ();
- }
-
- if (IkeSaSession->SessionCommon.PreferDhGroup != ((IKEV2_KEY_EXCHANGE *)KeyPayload->PayloadBuf)->DhGroup) {
- Status = EFI_INVALID_PARAMETER;
- goto CheckError;
- }
- //
- // Call Ikev2GenerateSaKeys to create SKEYID, SKEYID_d, SKEYID_a, SKEYID_e.
- //
- Status = Ikev2GenerateSaKeys (IkeSaSession, KeyPayload);
- if (EFI_ERROR(Status)) {
- goto CheckError;
- }
- return EFI_SUCCESS;
-
-CheckError:
- if (NonceBuffer != NULL) {
- FreePool (NonceBuffer);
- }
-
- return Status;
-}
-
-/**
- Generates the IKEv2 packet for IKE_AUTH exchange.
-
- @param[in] SaSession Pointer to IKEV2_SA_SESSION.
- @param[in] Context Context data passed by caller.
-
- @retval Pointer to IKE Packet to be sent out.
-
-**/
-IKE_PACKET *
-Ikev2AuthPskGenerator (
- IN UINT8 *SaSession,
- IN VOID *Context
- )
-{
- IKE_PACKET *IkePacket;
- IKEV2_SA_SESSION *IkeSaSession;
- IKE_PAYLOAD *IdPayload;
- IKE_PAYLOAD *AuthPayload;
- IKE_PAYLOAD *SaPayload;
- IKE_PAYLOAD *TsiPayload;
- IKE_PAYLOAD *TsrPayload;
- IKE_PAYLOAD *NotifyPayload;
- IKE_PAYLOAD *CpPayload;
- IKEV2_CHILD_SA_SESSION *ChildSaSession;
-
-
- IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
- ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));
-
- IkePacket = NULL;
- IdPayload = NULL;
- AuthPayload = NULL;
- SaPayload = NULL;
- TsiPayload = NULL;
- TsrPayload = NULL;
- NotifyPayload = NULL;
- CpPayload = NULL;
- NotifyPayload = NULL;
-
- //
- // 1. Allocate IKE Packet
- //
- IkePacket= IkePacketAlloc ();
- if (IkePacket == NULL) {
- return NULL;
- }
-
- //
- // 1.a Fill the IkePacket Header.
- //
- IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_AUTH;
- IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;
- IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;
- IkePacket->Header->Version = (UINT8)(2 << 4);
- if (ChildSaSession->SessionCommon.IsInitiator) {
- IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_INIT;
- } else {
- IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_RSP;
- }
-
- //
- // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
- // be always number 0 and 1;
- //
- IkePacket->Header->MessageId = 1;
-
- if (IkeSaSession->SessionCommon.IsInitiator) {
- IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;
- } else {
- IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
- }
-
- //
- // 2. Generate ID Payload according to IP version and address.
- //
- IdPayload = Ikev2GenerateIdPayload (
- &IkeSaSession->SessionCommon,
- IKEV2_PAYLOAD_TYPE_AUTH
- );
- if (IdPayload == NULL) {
- goto CheckError;
- }
-
- //
- // 3. Generate Auth Payload
- // If it is tunnel mode, should create the configuration payload after the
- // Auth payload.
- //
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {
-
- AuthPayload = Ikev2PskGenerateAuthPayload (
- ChildSaSession->IkeSaSession,
- IdPayload,
- IKEV2_PAYLOAD_TYPE_SA,
- FALSE
- );
- } else {
- AuthPayload = Ikev2PskGenerateAuthPayload (
- ChildSaSession->IkeSaSession,
- IdPayload,
- IKEV2_PAYLOAD_TYPE_CP,
- FALSE
- );
- if (IkeSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) {
- CpPayload = Ikev2GenerateCpPayload (
- ChildSaSession->IkeSaSession,
- IKEV2_PAYLOAD_TYPE_SA,
- IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS
- );
- } else {
- CpPayload = Ikev2GenerateCpPayload (
- ChildSaSession->IkeSaSession,
- IKEV2_PAYLOAD_TYPE_SA,
- IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
- );
- }
-
- if (CpPayload == NULL) {
- goto CheckError;
- }
- }
-
- if (AuthPayload == NULL) {
- goto CheckError;
- }
-
- //
- // 4. Generate SA Payload according to the SA Data in ChildSaSession
- //
- SaPayload = Ikev2GenerateSaPayload (
- ChildSaSession->SaData,
- IKEV2_PAYLOAD_TYPE_TS_INIT,
- IkeSessionTypeChildSa
- );
- if (SaPayload == NULL) {
- goto CheckError;
- }
-
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {
- //
- // Generate Tsi and Tsr.
- //
- TsiPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_TS_RSP,
- FALSE
- );
-
- TsrPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_NOTIFY,
- FALSE
- );
-
- //
- // Generate Notify Payload. If transport mode, there should have Notify
- // payload with TRANSPORT_MODE notification.
- //
- NotifyPayload = Ikev2GenerateNotifyPayload (
- 0,
- IKEV2_PAYLOAD_TYPE_NONE,
- 0,
- IKEV2_NOTIFICATION_USE_TRANSPORT_MODE,
- NULL,
- NULL,
- 0
- );
- if (NotifyPayload == NULL) {
- goto CheckError;
- }
- } else {
- //
- // Generate Tsr for Tunnel mode.
- //
- TsiPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_TS_RSP,
- TRUE
- );
- TsrPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_NONE,
- FALSE
- );
- }
-
- if (TsiPayload == NULL || TsrPayload == NULL) {
- goto CheckError;
- }
-
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, IdPayload);
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, AuthPayload);
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, CpPayload);
- }
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload);
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsiPayload);
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsrPayload);
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload);
- }
-
- return IkePacket;
-
-CheckError:
- if (IkePacket != NULL) {
- IkePacketFree (IkePacket);
- }
-
- if (IdPayload != NULL) {
- IkePayloadFree (IdPayload);
- }
-
- if (AuthPayload != NULL) {
- IkePayloadFree (AuthPayload);
- }
-
- if (CpPayload != NULL) {
- IkePayloadFree (CpPayload);
- }
-
- if (SaPayload != NULL) {
- IkePayloadFree (SaPayload);
- }
-
- if (TsiPayload != NULL) {
- IkePayloadFree (TsiPayload);
- }
-
- if (TsrPayload != NULL) {
- IkePayloadFree (TsrPayload);
- }
-
- if (NotifyPayload != NULL) {
- IkePayloadFree (NotifyPayload);
- }
-
- return NULL;
-}
-
-/**
- Parses IKE_AUTH packet.
-
- @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.
- @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.
-
- @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA
- proposal is unacceptable.
- @retval EFI_SUCCESS The IKE packet is acceptable and the
- relative data is saved for furthure communication.
-
-**/
-EFI_STATUS
-Ikev2AuthPskParser (
- IN UINT8 *SaSession,
- IN IKE_PACKET *IkePacket
- )
-{
- IKEV2_CHILD_SA_SESSION *ChildSaSession;
- IKEV2_SA_SESSION *IkeSaSession;
- IKE_PAYLOAD *IkePayload;
- IKE_PAYLOAD *SaPayload;
- IKE_PAYLOAD *IdiPayload;
- IKE_PAYLOAD *IdrPayload;
- IKE_PAYLOAD *AuthPayload;
- IKE_PAYLOAD *TsiPayload;
- IKE_PAYLOAD *TsrPayload;
- IKE_PAYLOAD *VerifiedAuthPayload;
- LIST_ENTRY *Entry;
- EFI_STATUS Status;
-
- IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
- ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));
-
- SaPayload = NULL;
- IdiPayload = NULL;
- IdrPayload = NULL;
- AuthPayload = NULL;
- TsiPayload = NULL;
- TsrPayload = NULL;
-
- //
- // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
- //
- NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {
- IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);
-
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_INIT) {
- IdiPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_RSP) {
- IdrPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) {
- SaPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_AUTH) {
- AuthPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_INIT) {
- TsiPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_RSP) {
- TsrPayload = IkePayload;
- }
- }
-
- if ((SaPayload == NULL) || (AuthPayload == NULL) || (TsiPayload == NULL) || (TsrPayload == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- if ((IdiPayload == NULL) && (IdrPayload == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check IkePacket Header is match the state
- //
- if (IkeSaSession->SessionCommon.IsInitiator) {
-
- //
- // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
- //
- if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) ||
- (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)
- ) {
- return EFI_INVALID_PARAMETER;
- }
-
- } else {
- //
- // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
- //
- if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) ||
- (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)
- ) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // 2. Parse the SA payload and Key Payload and find out the perferable one
- // and fill in the Sa paramse into CommonSession->SaParams and SaData into
- // IkeSaSession for the responder SA payload generation.
- //
- }
-
- //
- // Verify the Auth Payload.
- //
- VerifiedAuthPayload = Ikev2PskGenerateAuthPayload (
- IkeSaSession,
- IkeSaSession->SessionCommon.IsInitiator ? IdrPayload : IdiPayload,
- IKEV2_PAYLOAD_TYPE_SA,
- TRUE
- );
- if ((VerifiedAuthPayload != NULL) &&
- (0 != CompareMem (
- VerifiedAuthPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),
- AuthPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER),
- VerifiedAuthPayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER)
- ))) {
- return EFI_INVALID_PARAMETER;
- };
-
- //
- // 3. Parse the SA Payload to find out the cryptographic suite
- // and fill in the Sa paramse into CommonSession->SaParams. If no acceptable
- // porposal found, return EFI_INVALID_PARAMETER.
- //
- if (!Ikev2ChildSaParseSaPayload (ChildSaSession, SaPayload, IkePacket->Header->Flags)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // 4. Parse TSi, TSr payloads.
- //
- if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId !=
- ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId) &&
- (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) &&
- (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0)
- ) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (!IkeSaSession->SessionCommon.IsInitiator) {
- //
- //TODO:check the Port range. Only support any port and one certain port here.
- //
- ChildSaSession->ProtoId = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId;
- ChildSaSession->LocalPort = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;
- ChildSaSession->RemotePort = ((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;
- //
- // Association a SPD with this SA.
- //
- Status = Ikev2ChildSaAssociateSpdEntry (ChildSaSession);
- if (EFI_ERROR (Status)) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
- //
- if (ChildSaSession->IkeSaSession->Spd == NULL) {
- ChildSaSession->IkeSaSession->Spd = ChildSaSession->Spd;
- Status = Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- } else {
- //
- //TODO:check the Port range.
- //
- if ((((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&
- (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->RemotePort)
- ) {
- return EFI_INVALID_PARAMETER;
- }
- if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&
- (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->LocalPort)
- ) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
- //
- if (ChildSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {
- if (!ChildSaSession->IkeSaSession->SessionCommon.IsInitiator) {
- //
- // If it is tunnel mode, the UEFI part must be the initiator.
- //
- return EFI_INVALID_PARAMETER;
- }
- //
- // Get the Virtual IP address from the Tsi traffic selector.
- // TODO: check the CFG reply payload
- //
- CopyMem (
- &ChildSaSession->SpdSelector->LocalAddress[0].Address,
- TsiPayload->PayloadBuf + sizeof (IKEV2_TS) + sizeof (TRAFFIC_SELECTOR),
- (ChildSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) ?
- sizeof (EFI_IPv4_ADDRESS) : sizeof (EFI_IPv6_ADDRESS)
- );
- }
- }
-
- //
- // 5. Generate keymats for IPsec protocol.
- //
- Status = Ikev2GenerateChildSaKeys (ChildSaSession, NULL);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (IkeSaSession->SessionCommon.IsInitiator) {
- //
- // 6. Change the state of IkeSaSession
- //
- IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateIkeSaEstablished);
- IkeSaSession->SessionCommon.State = IkeStateIkeSaEstablished;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Gernerates IKEv2 packet for IKE_SA_INIT exchange.
-
- @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
- @param[in] Context Context Data passed by caller.
-
- @retval EFI_SUCCESS The IKE packet generation succeeded.
- @retval Others The IKE packet generation failed.
-
-**/
-IKE_PACKET*
-Ikev2InitCertGenerator (
- IN UINT8 *SaSession,
- IN VOID *Context
- )
-{
- IKE_PACKET *IkePacket;
- IKE_PAYLOAD *CertReqPayload;
- LIST_ENTRY *Node;
- IKE_PAYLOAD *NoncePayload;
-
- if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {
- return NULL;
- }
-
- //
- // The first two messages exchange is same between PSK and Cert.
- //
- IkePacket = Ikev2InitPskGenerator (SaSession, Context);
-
- if ((IkePacket != NULL) && (!((IKEV2_SA_SESSION *)SaSession)->SessionCommon.IsInitiator)) {
- //
- // Add the Certification Request Payload
- //
- CertReqPayload = Ikev2GenerateCertificatePayload (
- (IKEV2_SA_SESSION *)SaSession,
- IKEV2_PAYLOAD_TYPE_NONE,
- (UINT8*)PcdGetPtr(PcdIpsecUefiCaFile),
- PcdGet32(PcdIpsecUefiCaFileSize),
- IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT,
- TRUE
- );
- //
- // Change Nonce Payload Next payload type.
- //
- IKE_PACKET_END_PAYLOAD (IkePacket, Node);
- NoncePayload = IKE_PAYLOAD_BY_PACKET (Node);
- ((IKEV2_NONCE *)NoncePayload->PayloadBuf)->Header.NextPayload = IKEV2_PAYLOAD_TYPE_CERTREQ;
-
- //
- // Add Certification Request Payload
- //
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertReqPayload);
- }
-
- return IkePacket;
-}
-
-/**
- Parses the IKEv2 packet for IKE_SA_INIT exchange.
-
- @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
- @param[in] IkePacket The received IKEv2 packet to be parsed.
-
- @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is
- saved for furthure communication.
- @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA proposal is unacceptable.
- @retval EFI_UNSUPPORTED The certificate authentication is not supported.
-
-**/
-EFI_STATUS
-Ikev2InitCertParser (
- IN UINT8 *SaSession,
- IN IKE_PACKET *IkePacket
- )
-{
- if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // The first two messages exchange is same between PSK and Cert.
- // Todo: Parse Certificate Request from responder Initial Exchange.
- //
- return Ikev2InitPskParser (SaSession, IkePacket);
-}
-
-/**
- Generates the IKEv2 packet for IKE_AUTH exchange.
-
- @param[in] SaSession Pointer to IKEV2_SA_SESSION.
- @param[in] Context Context data passed by caller.
-
- @retval Pointer to IKEv2 Packet to be sent out.
-
-**/
-IKE_PACKET *
-Ikev2AuthCertGenerator (
- IN UINT8 *SaSession,
- IN VOID *Context
- )
-{
- IKE_PACKET *IkePacket;
- IKEV2_SA_SESSION *IkeSaSession;
- IKE_PAYLOAD *IdPayload;
- IKE_PAYLOAD *AuthPayload;
- IKE_PAYLOAD *SaPayload;
- IKE_PAYLOAD *TsiPayload;
- IKE_PAYLOAD *TsrPayload;
- IKE_PAYLOAD *NotifyPayload;
- IKE_PAYLOAD *CpPayload;
- IKE_PAYLOAD *CertPayload;
- IKE_PAYLOAD *CertReqPayload;
- IKEV2_CHILD_SA_SESSION *ChildSaSession;
-
- if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {
- return NULL;
- }
-
- IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
- ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));
-
- IkePacket = NULL;
- IdPayload = NULL;
- AuthPayload = NULL;
- CpPayload = NULL;
- SaPayload = NULL;
- TsiPayload = NULL;
- TsrPayload = NULL;
- NotifyPayload = NULL;
- CertPayload = NULL;
- CertReqPayload = NULL;
-
- //
- // 1. Allocate IKE Packet
- //
- IkePacket= IkePacketAlloc ();
- if (IkePacket == NULL) {
- return NULL;
- }
-
- //
- // 1.a Fill the IkePacket Header.
- //
- IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_AUTH;
- IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;
- IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;
- IkePacket->Header->Version = (UINT8)(2 << 4);
- if (ChildSaSession->SessionCommon.IsInitiator) {
- IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_INIT;
- } else {
- IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_RSP;
- }
-
- //
- // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
- // be always number 0 and 1;
- //
- IkePacket->Header->MessageId = 1;
-
- if (IkeSaSession->SessionCommon.IsInitiator) {
- IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;
- } else {
- IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
- }
-
- //
- // 2. Generate ID Payload according to IP version and address.
- //
- IdPayload = Ikev2GenerateCertIdPayload (
- &IkeSaSession->SessionCommon,
- IKEV2_PAYLOAD_TYPE_CERT,
- (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate),
- PcdGet32 (PcdIpsecUefiCertificateSize)
- );
- if (IdPayload == NULL) {
- goto CheckError;
- }
-
- //
- // 3. Generate Certificate Payload
- //
- CertPayload = Ikev2GenerateCertificatePayload (
- IkeSaSession,
- (UINT8)(IkeSaSession->SessionCommon.IsInitiator ? IKEV2_PAYLOAD_TYPE_CERTREQ : IKEV2_PAYLOAD_TYPE_AUTH),
- (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate),
- PcdGet32 (PcdIpsecUefiCertificateSize),
- IKEV2_CERT_ENCODEING_X509_CERT_SIGN,
- FALSE
- );
- if (CertPayload == NULL) {
- goto CheckError;
- }
-
- if (IkeSaSession->SessionCommon.IsInitiator) {
- CertReqPayload = Ikev2GenerateCertificatePayload (
- IkeSaSession,
- IKEV2_PAYLOAD_TYPE_AUTH,
- (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate),
- PcdGet32 (PcdIpsecUefiCertificateSize),
- IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT,
- TRUE
- );
- if (CertReqPayload == NULL) {
- goto CheckError;
- }
- }
-
- //
- // 4. Generate Auth Payload
- // If it is tunnel mode, should create the configuration payload after the
- // Auth payload.
- //
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {
- AuthPayload = Ikev2CertGenerateAuthPayload (
- ChildSaSession->IkeSaSession,
- IdPayload,
- IKEV2_PAYLOAD_TYPE_SA,
- FALSE,
- (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificateKey),
- PcdGet32 (PcdIpsecUefiCertificateKeySize),
- ChildSaSession->IkeSaSession->Pad->Data->AuthData,
- ChildSaSession->IkeSaSession->Pad->Data->AuthDataSize
- );
- } else {
- AuthPayload = Ikev2CertGenerateAuthPayload (
- ChildSaSession->IkeSaSession,
- IdPayload,
- IKEV2_PAYLOAD_TYPE_CP,
- FALSE,
- (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificateKey),
- PcdGet32 (PcdIpsecUefiCertificateKeySize),
- ChildSaSession->IkeSaSession->Pad->Data->AuthData,
- ChildSaSession->IkeSaSession->Pad->Data->AuthDataSize
- );
- if (IkeSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) {
- CpPayload = Ikev2GenerateCpPayload (
- ChildSaSession->IkeSaSession,
- IKEV2_PAYLOAD_TYPE_SA,
- IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS
- );
- } else {
- CpPayload = Ikev2GenerateCpPayload (
- ChildSaSession->IkeSaSession,
- IKEV2_PAYLOAD_TYPE_SA,
- IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
- );
- }
-
- if (CpPayload == NULL) {
- goto CheckError;
- }
- }
-
- if (AuthPayload == NULL) {
- goto CheckError;
- }
-
- //
- // 5. Generate SA Payload according to the Sa Data in ChildSaSession
- //
- SaPayload = Ikev2GenerateSaPayload (
- ChildSaSession->SaData,
- IKEV2_PAYLOAD_TYPE_TS_INIT,
- IkeSessionTypeChildSa
- );
- if (SaPayload == NULL) {
- goto CheckError;
- }
-
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {
- //
- // Generate Tsi and Tsr.
- //
- TsiPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_TS_RSP,
- FALSE
- );
-
- TsrPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_NOTIFY,
- FALSE
- );
-
- //
- // Generate Notify Payload. If transport mode, there should have Notify
- // payload with TRANSPORT_MODE notification.
- //
- NotifyPayload = Ikev2GenerateNotifyPayload (
- 0,
- IKEV2_PAYLOAD_TYPE_NONE,
- 0,
- IKEV2_NOTIFICATION_USE_TRANSPORT_MODE,
- NULL,
- NULL,
- 0
- );
- if (NotifyPayload == NULL) {
- goto CheckError;
- }
- } else {
- //
- // Generate Tsr for Tunnel mode.
- //
- TsiPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_TS_RSP,
- TRUE
- );
- TsrPayload = Ikev2GenerateTsPayload (
- ChildSaSession,
- IKEV2_PAYLOAD_TYPE_NONE,
- FALSE
- );
- }
-
- if (TsiPayload == NULL || TsrPayload == NULL) {
- goto CheckError;
- }
-
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, IdPayload);
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertPayload);
- if (IkeSaSession->SessionCommon.IsInitiator) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertReqPayload);
- }
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, AuthPayload);
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, CpPayload);
- }
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload);
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsiPayload);
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsrPayload);
- if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) {
- IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload);
- }
-
- return IkePacket;
-
-CheckError:
- if (IkePacket != NULL) {
- IkePacketFree (IkePacket);
- }
-
- if (IdPayload != NULL) {
- IkePayloadFree (IdPayload);
- }
-
- if (CertPayload != NULL) {
- IkePayloadFree (CertPayload);
- }
-
- if (CertReqPayload != NULL) {
- IkePayloadFree (CertReqPayload);
- }
-
- if (AuthPayload != NULL) {
- IkePayloadFree (AuthPayload);
- }
-
- if (CpPayload != NULL) {
- IkePayloadFree (CpPayload);
- }
-
- if (SaPayload != NULL) {
- IkePayloadFree (SaPayload);
- }
-
- if (TsiPayload != NULL) {
- IkePayloadFree (TsiPayload);
- }
-
- if (TsrPayload != NULL) {
- IkePayloadFree (TsrPayload);
- }
-
- if (NotifyPayload != NULL) {
- IkePayloadFree (NotifyPayload);
- }
-
- return NULL;
-}
-
-/**
- Parses IKE_AUTH packet.
-
- @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.
- @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.
-
- @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA
- proposal is unacceptable.
- @retval EFI_SUCCESS The IKE packet is acceptable and the
- relative data is saved for furthure communication.
- @retval EFI_UNSUPPORTED The certificate authentication is not supported.
-
-**/
-EFI_STATUS
-Ikev2AuthCertParser (
- IN UINT8 *SaSession,
- IN IKE_PACKET *IkePacket
- )
-{
- IKEV2_CHILD_SA_SESSION *ChildSaSession;
- IKEV2_SA_SESSION *IkeSaSession;
- IKE_PAYLOAD *IkePayload;
- IKE_PAYLOAD *SaPayload;
- IKE_PAYLOAD *IdiPayload;
- IKE_PAYLOAD *IdrPayload;
- IKE_PAYLOAD *AuthPayload;
- IKE_PAYLOAD *TsiPayload;
- IKE_PAYLOAD *TsrPayload;
- IKE_PAYLOAD *CertPayload;
- IKE_PAYLOAD *VerifiedAuthPayload;
- LIST_ENTRY *Entry;
- EFI_STATUS Status;
-
- if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) {
- return EFI_UNSUPPORTED;
- }
-
- IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
- ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList));
-
- SaPayload = NULL;
- IdiPayload = NULL;
- IdrPayload = NULL;
- AuthPayload = NULL;
- TsiPayload = NULL;
- TsrPayload = NULL;
- CertPayload = NULL;
- VerifiedAuthPayload = NULL;
- Status = EFI_INVALID_PARAMETER;
-
- //
- // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
- //
- NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {
- IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);
-
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_INIT) {
- IdiPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_RSP) {
- IdrPayload = IkePayload;
- }
-
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) {
- SaPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_AUTH) {
- AuthPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_INIT) {
- TsiPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_RSP) {
- TsrPayload = IkePayload;
- }
- if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_CERT) {
- CertPayload = IkePayload;
- }
- }
-
- if ((SaPayload == NULL) || (AuthPayload == NULL) || (TsiPayload == NULL) ||
- (TsrPayload == NULL) || (CertPayload == NULL)) {
- goto Exit;
- }
- if ((IdiPayload == NULL) && (IdrPayload == NULL)) {
- goto Exit;
- }
-
- //
- // Check IkePacket Header is match the state
- //
- if (IkeSaSession->SessionCommon.IsInitiator) {
-
- //
- // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
- //
- if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) ||
- (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)) {
- goto Exit;
- }
- } else {
- //
- // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
- //
- if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) ||
- (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)) {
- goto Exit;
- }
- }
-
- //
- // Verify the Auth Payload.
- //
- VerifiedAuthPayload = Ikev2CertGenerateAuthPayload (
- IkeSaSession,
- IkeSaSession->SessionCommon.IsInitiator ? IdrPayload:IdiPayload,
- IKEV2_PAYLOAD_TYPE_SA,
- TRUE,
- NULL,
- 0,
- NULL,
- 0
- );
-
- if ((VerifiedAuthPayload != NULL) &&
- (!IpSecCryptoIoVerifySignDataByCertificate (
- CertPayload->PayloadBuf + sizeof (IKEV2_CERT),
- CertPayload->PayloadSize - sizeof (IKEV2_CERT),
- (UINT8 *)PcdGetPtr (PcdIpsecUefiCaFile),
- PcdGet32 (PcdIpsecUefiCaFileSize),
- VerifiedAuthPayload->PayloadBuf + sizeof (IKEV2_AUTH),
- VerifiedAuthPayload->PayloadSize - sizeof (IKEV2_AUTH),
- AuthPayload->PayloadBuf + sizeof (IKEV2_AUTH),
- AuthPayload->PayloadSize - sizeof (IKEV2_AUTH)
- ))) {
- goto Exit;
- }
-
- //
- // 3. Parse the SA Payload to find out the cryptographic suite
- // and fill in the SA paramse into CommonSession->SaParams. If no acceptable
- // porposal found, return EFI_INVALID_PARAMETER.
- //
- if (!Ikev2ChildSaParseSaPayload (ChildSaSession, SaPayload, IkePacket->Header->Flags)) {
- goto Exit;
- }
-
- //
- // 4. Parse TSi, TSr payloads.
- //
- if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId !=
- ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId) &&
- (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) &&
- (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0)
- ) {
- goto Exit;
- }
-
- if (!IkeSaSession->SessionCommon.IsInitiator) {
- //
- //Todo:check the Port range. Only support any port and one certain port here.
- //
- ChildSaSession->ProtoId = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId;
- ChildSaSession->LocalPort = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;
- ChildSaSession->RemotePort = ((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort;
- //
- // Association a SPD with this SA.
- //
- if (EFI_ERROR (Ikev2ChildSaAssociateSpdEntry (ChildSaSession))) {
- goto Exit;
- }
- //
- // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
- //
- if (ChildSaSession->IkeSaSession->Spd == NULL) {
- ChildSaSession->IkeSaSession->Spd = ChildSaSession->Spd;
- Status = Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
- }
- } else {
- //
- // Todo:check the Port range.
- //
- if ((((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&
- (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->RemotePort)
- ) {
- goto Exit;
- }
- if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) &&
- (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->LocalPort)
- ) {
- goto Exit;
- }
- //
- // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
- //
- if (ChildSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {
- if (!ChildSaSession->IkeSaSession->SessionCommon.IsInitiator) {
- //
- // If it is tunnel mode, the UEFI part must be the initiator.
- //
- goto Exit;
- }
- //
- // Get the Virtual IP address from the Tsi traffic selector.
- // TODO: check the CFG reply payload
- //
- CopyMem (
- &ChildSaSession->SpdSelector->LocalAddress[0].Address,
- TsiPayload->PayloadBuf + sizeof (IKEV2_TS) + sizeof (TRAFFIC_SELECTOR),
- (ChildSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) ?
- sizeof (EFI_IPv4_ADDRESS) : sizeof (EFI_IPv6_ADDRESS)
- );
- }
- }
-
- //
- // 5. Generat keymats for IPsec protocol.
- //
- Status = Ikev2GenerateChildSaKeys (ChildSaSession, NULL);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- if (IkeSaSession->SessionCommon.IsInitiator) {
- //
- // 6. Change the state of IkeSaSession
- //
- IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateIkeSaEstablished);
- IkeSaSession->SessionCommon.State = IkeStateIkeSaEstablished;
- }
-
- Status = EFI_SUCCESS;
-
-Exit:
- if (VerifiedAuthPayload != NULL) {
- IkePayloadFree (VerifiedAuthPayload);
- }
- return Status;
-}
-
-/**
- Generates the DH Public Key.
-
- This generates the DH local public key and store it in the IKE SA Session's GxBuffer.
-
- @param[in] IkeSaSession Pointer to related IKE SA Session.
-
- @retval EFI_SUCCESS The operation succeeded.
- @retval Others The operation failed.
-
-**/
-EFI_STATUS
-Ikev2GenerateSaDhPublicKey (
- IN IKEV2_SA_SESSION *IkeSaSession
- )
-{
- EFI_STATUS Status;
- IKEV2_SESSION_KEYS *IkeKeys;
-
- IkeSaSession->IkeKeys = AllocateZeroPool (sizeof (IKEV2_SESSION_KEYS));
- if (IkeSaSession->IkeKeys == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- IkeKeys = IkeSaSession->IkeKeys;
- IkeKeys->DhBuffer = AllocateZeroPool (sizeof (IKEV2_DH_BUFFER));
- if (IkeKeys->DhBuffer == NULL) {
- FreePool (IkeSaSession->IkeKeys);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Init DH with the certain DH Group Description.
- //
- IkeKeys->DhBuffer->GxSize = OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Size >> 3;
- IkeKeys->DhBuffer->GxBuffer = AllocateZeroPool (IkeKeys->DhBuffer->GxSize);
- if (IkeKeys->DhBuffer->GxBuffer == NULL) {
- FreePool (IkeKeys->DhBuffer);
- FreePool (IkeSaSession->IkeKeys);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Get X PublicKey
- //
- Status = IpSecCryptoIoDhGetPublicKey (
- &IkeKeys->DhBuffer->DhContext,
- OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].GroupGenerator,
- OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Size,
- OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Modulus,
- IkeKeys->DhBuffer->GxBuffer,
- &IkeKeys->DhBuffer->GxSize
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Error CPLKeyManGetKeyParam X public key error Status = %r\n", Status));
-
- FreePool (IkeKeys->DhBuffer->GxBuffer);
-
- FreePool (IkeKeys->DhBuffer);
-
- FreePool (IkeSaSession->IkeKeys);
-
- return Status;
- }
-
- IPSEC_DUMP_BUF ("DH Public Key (g^x) Dump", IkeKeys->DhBuffer->GxBuffer, IkeKeys->DhBuffer->GxSize);
-
- return EFI_SUCCESS;
-}
-
-/**
- Computes the DH Shared/Exchange Key.
-
- Given peer's public key, this function computes the exchanged common key and
- stores it in the IKEv2 SA Session's GxyBuffer.
-
- @param[in] DhBuffer Pointer to buffer of peer's puliic key.
- @param[in] KePayload Pointer to received key payload.
-
- @retval EFI_SUCCESS The operation succeeded.
- @retval Otherwise The operation failed.
-
-**/
-EFI_STATUS
-Ikev2GenerateSaDhComputeKey (
- IN IKEV2_DH_BUFFER *DhBuffer,
- IN IKE_PAYLOAD *KePayload
- )
-{
- EFI_STATUS Status;
- IKEV2_KEY_EXCHANGE *Ke;
- UINT8 *PubKey;
- UINTN PubKeySize;
-
- Ke = (IKEV2_KEY_EXCHANGE *) KePayload->PayloadBuf;
- PubKey = (UINT8 *) (Ke + 1);
- PubKeySize = KePayload->PayloadSize - sizeof (IKEV2_KEY_EXCHANGE);
- DhBuffer->GxySize = DhBuffer->GxSize;
- DhBuffer->GxyBuffer = AllocateZeroPool (DhBuffer->GxySize);
- if (DhBuffer->GxyBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Get GxyBuf
- //
- Status = IpSecCryptoIoDhComputeKey (
- DhBuffer->DhContext,
- PubKey,
- PubKeySize,
- DhBuffer->GxyBuffer,
- &DhBuffer->GxySize
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Error CPLKeyManGetKeyParam Y session key error Status = %r\n", Status));
-
- FreePool (DhBuffer->GxyBuffer);
-
- return Status;
- }
-
- //
- // Create GxyBuf.
- //
- DhBuffer->GySize = PubKeySize;
- DhBuffer->GyBuffer = AllocateZeroPool (DhBuffer->GySize);
- if (DhBuffer->GyBuffer == NULL) {
- FreePool (DhBuffer->GxyBuffer);
-
- return Status;
- }
-
- CopyMem (DhBuffer->GyBuffer, PubKey, DhBuffer->GySize);
-
- IPSEC_DUMP_BUF ("DH Public Key (g^y) Dump", DhBuffer->GyBuffer, DhBuffer->GySize);
- IPSEC_DUMP_BUF ("DH Shared Key (g^xy) Dump", DhBuffer->GxyBuffer, DhBuffer->GxySize);
-
- return EFI_SUCCESS;
-}
-
-/**
- Generates the IKE SKEYSEED and seven other secrets. SK_d, SK_ai, SK_ar, SK_ei, SK_er,
- SK_pi, SK_pr are keys for the furthure IKE exchange.
-
- @param[in] IkeSaSession Pointer to IKE SA Session.
- @param[in] KePayload Pointer to Key payload used to generate the Key.
-
- @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.
- @retval EFI_OUT_OF_RESOURCES If there is no enough resource to be allocated to
- meet the requirement.
- @retval EFI_SUCCESS The operation succeeded.
-
-**/
-EFI_STATUS
-Ikev2GenerateSaKeys (
- IN IKEV2_SA_SESSION *IkeSaSession,
- IN IKE_PAYLOAD *KePayload
- )
-{
- EFI_STATUS Status;
- IKEV2_SA_PARAMS *SaParams;
- PRF_DATA_FRAGMENT Fragments[4];
- UINT64 InitiatorCookieNet;
- UINT64 ResponderCookieNet;
- UINT8 *KeyBuffer;
- UINTN KeyBufferSize;
- UINTN AuthAlgKeyLen;
- UINTN EncryptAlgKeyLen;
- UINTN IntegrityAlgKeyLen;
- UINTN PrfAlgKeyLen;
- UINT8 *OutputKey;
- UINTN OutputKeyLength;
- UINT8 *Digest;
- UINTN DigestSize;
-
- Digest = NULL;
- OutputKey = NULL;
- KeyBuffer = NULL;
- Status = EFI_SUCCESS;
-
- //
- // Generate Gxy
- //
- Status = Ikev2GenerateSaDhComputeKey (IkeSaSession->IkeKeys->DhBuffer, KePayload);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- //
- // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
- //
- SaParams = IkeSaSession->SessionCommon.SaParams;
- AuthAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf);
- EncryptAlgKeyLen = IpSecGetEncryptKeyLength ((UINT8)SaParams->EncAlgId);
- IntegrityAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->IntegAlgId);
- PrfAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf);
-
- //
- // If one or more algorithm is not support, return EFI_UNSUPPORTED.
- //
- if (AuthAlgKeyLen == 0 ||
- EncryptAlgKeyLen == 0 ||
- IntegrityAlgKeyLen == 0 ||
- PrfAlgKeyLen == 0
- ) {
- Status = EFI_UNSUPPORTED;
- goto Exit;
- }
-
- //
- // Compute SKEYSEED = prf(Ni | Nr, g^ir)
- //
- KeyBufferSize = IkeSaSession->NiBlkSize + IkeSaSession->NrBlkSize;
- KeyBuffer = AllocateZeroPool (KeyBufferSize);
- if (KeyBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (KeyBuffer, IkeSaSession->NiBlock, IkeSaSession->NiBlkSize);
- CopyMem (KeyBuffer + IkeSaSession->NiBlkSize, IkeSaSession->NrBlock, IkeSaSession->NrBlkSize);
-
- Fragments[0].Data = IkeSaSession->IkeKeys->DhBuffer->GxyBuffer;
- Fragments[0].DataSize = IkeSaSession->IkeKeys->DhBuffer->GxySize;
-
- DigestSize = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf);
- Digest = AllocateZeroPool (DigestSize);
-
- if (Digest == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- IpSecCryptoIoHmac (
- (UINT8)SaParams->Prf,
- KeyBuffer,
- KeyBufferSize,
- (HASH_DATA_FRAGMENT *) Fragments,
- 1,
- Digest,
- DigestSize
- );
-
- //
- // {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } = prf+
- // (SKEYSEED, Ni | Nr | SPIi | SPIr )
- //
- Fragments[0].Data = IkeSaSession->NiBlock;
- Fragments[0].DataSize = IkeSaSession->NiBlkSize;
- Fragments[1].Data = IkeSaSession->NrBlock;
- Fragments[1].DataSize = IkeSaSession->NrBlkSize;
- InitiatorCookieNet = HTONLL (IkeSaSession->InitiatorCookie);
- ResponderCookieNet = HTONLL (IkeSaSession->ResponderCookie);
- Fragments[2].Data = (UINT8 *)(&InitiatorCookieNet);
- Fragments[2].DataSize = sizeof (IkeSaSession->InitiatorCookie);
- Fragments[3].Data = (UINT8 *)(&ResponderCookieNet);
- Fragments[3].DataSize = sizeof (IkeSaSession->ResponderCookie);
-
- IPSEC_DUMP_BUF (">>> NiBlock", IkeSaSession->NiBlock, IkeSaSession->NiBlkSize);
- IPSEC_DUMP_BUF (">>> NrBlock", IkeSaSession->NrBlock, IkeSaSession->NrBlkSize);
- IPSEC_DUMP_BUF (">>> InitiatorCookie", (UINT8 *)&IkeSaSession->InitiatorCookie, sizeof(UINT64));
- IPSEC_DUMP_BUF (">>> ResponderCookie", (UINT8 *)&IkeSaSession->ResponderCookie, sizeof(UINT64));
-
- OutputKeyLength = PrfAlgKeyLen +
- 2 * EncryptAlgKeyLen +
- 2 * AuthAlgKeyLen +
- 2 * IntegrityAlgKeyLen;
- OutputKey = AllocateZeroPool (OutputKeyLength);
- if (OutputKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Generate Seven Keymates.
- //
- Status = Ikev2SaGenerateKey (
- (UINT8)SaParams->Prf,
- Digest,
- DigestSize,
- OutputKey,
- OutputKeyLength,
- Fragments,
- 4
- );
- if (EFI_ERROR(Status)) {
- goto Exit;
- }
-
- //
- // Save the seven keys into KeySession.
- // First, SK_d
- //
- IkeSaSession->IkeKeys->SkdKey = AllocateZeroPool (PrfAlgKeyLen);
- if (IkeSaSession->IkeKeys->SkdKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- IkeSaSession->IkeKeys->SkdKeySize = PrfAlgKeyLen;
- CopyMem (IkeSaSession->IkeKeys->SkdKey, OutputKey, PrfAlgKeyLen);
-
- IPSEC_DUMP_BUF (">>> SK_D Key", IkeSaSession->IkeKeys->SkdKey, PrfAlgKeyLen);
-
- //
- // Second, Sk_ai
- //
- IkeSaSession->IkeKeys->SkAiKey = AllocateZeroPool (IntegrityAlgKeyLen);
- if (IkeSaSession->IkeKeys->SkAiKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- IkeSaSession->IkeKeys->SkAiKeySize = IntegrityAlgKeyLen;
- CopyMem (IkeSaSession->IkeKeys->SkAiKey, OutputKey + PrfAlgKeyLen, IntegrityAlgKeyLen);
-
- IPSEC_DUMP_BUF (">>> SK_Ai Key", IkeSaSession->IkeKeys->SkAiKey, IkeSaSession->IkeKeys->SkAiKeySize);
-
- //
- // Third, Sk_ar
- //
- IkeSaSession->IkeKeys->SkArKey = AllocateZeroPool (IntegrityAlgKeyLen);
- if (IkeSaSession->IkeKeys->SkArKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- IkeSaSession->IkeKeys->SkArKeySize = IntegrityAlgKeyLen;
- CopyMem (
- IkeSaSession->IkeKeys->SkArKey,
- OutputKey + PrfAlgKeyLen + IntegrityAlgKeyLen,
- IntegrityAlgKeyLen
- );
-
- IPSEC_DUMP_BUF (">>> SK_Ar Key", IkeSaSession->IkeKeys->SkArKey, IkeSaSession->IkeKeys->SkArKeySize);
-
- //
- // Fourth, Sk_ei
- //
- IkeSaSession->IkeKeys->SkEiKey = AllocateZeroPool (EncryptAlgKeyLen);
- if (IkeSaSession->IkeKeys->SkEiKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- IkeSaSession->IkeKeys->SkEiKeySize = EncryptAlgKeyLen;
-
- CopyMem (
- IkeSaSession->IkeKeys->SkEiKey,
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen,
- EncryptAlgKeyLen
- );
- IPSEC_DUMP_BUF (
- ">>> SK_Ei Key",
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen,
- EncryptAlgKeyLen
- );
-
- //
- // Fifth, Sk_er
- //
- IkeSaSession->IkeKeys->SkErKey = AllocateZeroPool (EncryptAlgKeyLen);
- if (IkeSaSession->IkeKeys->SkErKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- IkeSaSession->IkeKeys->SkErKeySize = EncryptAlgKeyLen;
-
- CopyMem (
- IkeSaSession->IkeKeys->SkErKey,
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + EncryptAlgKeyLen,
- EncryptAlgKeyLen
- );
- IPSEC_DUMP_BUF (
- ">>> SK_Er Key",
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + EncryptAlgKeyLen,
- EncryptAlgKeyLen
- );
-
- //
- // Sixth, Sk_pi
- //
- IkeSaSession->IkeKeys->SkPiKey = AllocateZeroPool (AuthAlgKeyLen);
- if (IkeSaSession->IkeKeys->SkPiKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- IkeSaSession->IkeKeys->SkPiKeySize = AuthAlgKeyLen;
-
- CopyMem (
- IkeSaSession->IkeKeys->SkPiKey,
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen,
- AuthAlgKeyLen
- );
- IPSEC_DUMP_BUF (
- ">>> SK_Pi Key",
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen,
- AuthAlgKeyLen
- );
-
- //
- // Seventh, Sk_pr
- //
- IkeSaSession->IkeKeys->SkPrKey = AllocateZeroPool (AuthAlgKeyLen);
- if (IkeSaSession->IkeKeys->SkPrKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- IkeSaSession->IkeKeys->SkPrKeySize = AuthAlgKeyLen;
-
- CopyMem (
- IkeSaSession->IkeKeys->SkPrKey,
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen + AuthAlgKeyLen,
- AuthAlgKeyLen
- );
- IPSEC_DUMP_BUF (
- ">>> SK_Pr Key",
- OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen + AuthAlgKeyLen,
- AuthAlgKeyLen
- );
-
-
-Exit:
- if (Digest != NULL) {
- FreePool (Digest);
- }
- if (KeyBuffer != NULL) {
- FreePool (KeyBuffer);
- }
- if (OutputKey != NULL) {
- FreePool (OutputKey);
- }
-
- if (EFI_ERROR(Status)) {
- if (IkeSaSession->IkeKeys->SkdKey != NULL) {
- FreePool (IkeSaSession->IkeKeys->SkdKey);
- }
- if (IkeSaSession->IkeKeys->SkAiKey != NULL) {
- FreePool (IkeSaSession->IkeKeys->SkAiKey);
- }
- if (IkeSaSession->IkeKeys->SkArKey != NULL) {
- FreePool (IkeSaSession->IkeKeys->SkArKey);
- }
- if (IkeSaSession->IkeKeys->SkEiKey != NULL) {
- FreePool (IkeSaSession->IkeKeys->SkEiKey);
- }
- if (IkeSaSession->IkeKeys->SkErKey != NULL) {
- FreePool (IkeSaSession->IkeKeys->SkErKey);
- }
- if (IkeSaSession->IkeKeys->SkPiKey != NULL) {
- FreePool (IkeSaSession->IkeKeys->SkPiKey);
- }
- if (IkeSaSession->IkeKeys->SkPrKey != NULL) {
- FreePool (IkeSaSession->IkeKeys->SkPrKey);
- }
- }
-
-
- return Status;
-}
-
-/**
- Generates the Keys for the furthure IPsec Protocol.
-
- @param[in] ChildSaSession Pointer to IKE Child SA Session.
- @param[in] KePayload Pointer to Key payload used to generate the Key.
-
- @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.
- @retval EFI_SUCCESS The operation succeeded.
-
-**/
-EFI_STATUS
-Ikev2GenerateChildSaKeys (
- IN IKEV2_CHILD_SA_SESSION *ChildSaSession,
- IN IKE_PAYLOAD *KePayload
- )
-{
- EFI_STATUS Status;
- IKEV2_SA_PARAMS *SaParams;
- PRF_DATA_FRAGMENT Fragments[3];
- UINTN EncryptAlgKeyLen;
- UINTN IntegrityAlgKeyLen;
- UINT8* OutputKey;
- UINTN OutputKeyLength;
-
- Status = EFI_SUCCESS;
- OutputKey = NULL;
-
- if (KePayload != NULL) {
- //
- // Generate Gxy
- //
- Status = Ikev2GenerateSaDhComputeKey (ChildSaSession->DhBuffer, KePayload);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- Fragments[0].Data = ChildSaSession->DhBuffer->GxyBuffer;
- Fragments[0].DataSize = ChildSaSession->DhBuffer->GxySize;
- }
-
- Fragments[1].Data = ChildSaSession->NiBlock;
- Fragments[1].DataSize = ChildSaSession->NiBlkSize;
- Fragments[2].Data = ChildSaSession->NrBlock;
- Fragments[2].DataSize = ChildSaSession->NrBlkSize;
-
- //
- // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
- //
- SaParams = ChildSaSession->SessionCommon.SaParams;
- EncryptAlgKeyLen = IpSecGetEncryptKeyLength ((UINT8)SaParams->EncAlgId);
- IntegrityAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->IntegAlgId);
- OutputKeyLength = 2 * EncryptAlgKeyLen + 2 * IntegrityAlgKeyLen;
-
- if ((EncryptAlgKeyLen == 0) || (IntegrityAlgKeyLen == 0)) {
- Status = EFI_UNSUPPORTED;
- goto Exit;
- }
-
- //
- //
- // If KePayload is not NULL, calculate KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr ),
- // otherwise, KEYMAT = prf+(SK_d, Ni | Nr )
- //
- OutputKey = AllocateZeroPool (OutputKeyLength);
- if (OutputKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Derive Key from the SkdKey Buffer.
- //
- Status = Ikev2SaGenerateKey (
- (UINT8)ChildSaSession->IkeSaSession->SessionCommon.SaParams->Prf,
- ChildSaSession->IkeSaSession->IkeKeys->SkdKey,
- ChildSaSession->IkeSaSession->IkeKeys->SkdKeySize,
- OutputKey,
- OutputKeyLength,
- KePayload == NULL ? &Fragments[1] : Fragments,
- KePayload == NULL ? 2 : 3
- );
-
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- //
- // Copy KEYMATE (SK_ENCRYPT_i | SK_ENCRYPT_r | SK_INTEG_i | SK_INTEG_r) to
- // ChildKeyMates.
- //
- if (!ChildSaSession->SessionCommon.IsInitiator) {
-
- //
- // Initiator Encryption Key
- //
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);
- if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey,
- OutputKey,
- EncryptAlgKeyLen
- );
-
- //
- // Initiator Authentication Key
- //
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);
- if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey,
- OutputKey + EncryptAlgKeyLen,
- IntegrityAlgKeyLen
- );
-
- //
- // Responder Encrypt Key
- //
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);
- if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey,
- OutputKey + EncryptAlgKeyLen + IntegrityAlgKeyLen,
- EncryptAlgKeyLen
- );
-
- //
- // Responder Authentication Key
- //
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);
- if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey,
- OutputKey + 2 * EncryptAlgKeyLen + IntegrityAlgKeyLen,
- IntegrityAlgKeyLen
- );
- } else {
- //
- // Initiator Encryption Key
- //
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);
- if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey,
- OutputKey,
- EncryptAlgKeyLen
- );
-
- //
- // Initiator Authentication Key
- //
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);
- if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey,
- OutputKey + EncryptAlgKeyLen,
- IntegrityAlgKeyLen
- );
-
- //
- // Responder Encryption Key
- //
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen);
- if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey,
- OutputKey + EncryptAlgKeyLen + IntegrityAlgKeyLen,
- EncryptAlgKeyLen
- );
-
- //
- // Responder Authentication Key
- //
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen;
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen);
- if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey,
- OutputKey + 2 * EncryptAlgKeyLen + IntegrityAlgKeyLen,
- IntegrityAlgKeyLen
- );
- }
-
- IPSEC_DUMP_BUF (
- " >>> Local Encryption Key",
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey,
- EncryptAlgKeyLen
- );
- IPSEC_DUMP_BUF (
- " >>> Remote Encryption Key",
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey,
- EncryptAlgKeyLen
- );
- IPSEC_DUMP_BUF (
- " >>> Local Authentication Key",
- ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey,
- IntegrityAlgKeyLen
- );
- IPSEC_DUMP_BUF (
- " >>> Remote Authentication Key",
- ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey,
- IntegrityAlgKeyLen
- );
-
-
-
-Exit:
- if (EFI_ERROR (Status)) {
- if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey != NULL) {
- FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey);
- }
- if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey != NULL) {
- FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey);
- }
- if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey != NULL) {
- FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey);
- }
- if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey != NULL) {
- FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey);
- }
- }
-
- if (OutputKey != NULL) {
- FreePool (OutputKey);
- }
-
- return EFI_SUCCESS;
-}
-
-GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Initial[][2] = {
- { //PSK
- { // IKEV2_INIT
- Ikev2InitPskParser,
- Ikev2InitPskGenerator
- },
- { //IKEV2_AUTH
- Ikev2AuthPskParser,
- Ikev2AuthPskGenerator
- }
- },
- { // CERT
- { // IKEV2_INIT
- Ikev2InitCertParser,
- Ikev2InitCertGenerator
- },
- { // IKEV2_AUTH
- Ikev2AuthCertParser,
- Ikev2AuthCertGenerator
- },
- },
-};