1 /** @file 2 IKE Packet related operation. 3 4 Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR> 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php. 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "IpSecDebug.h" 17 #include "Ikev2/Utility.h" 18 19 /** 20 Allocate a buffer for the IKE_PACKET and intitalize its Header and payloadlist. 21 22 @return The pointer of the IKE_PACKET. 23 24 **/ 25 IKE_PACKET * 26 IkePacketAlloc ( 27 VOID 28 ) 29 { 30 IKE_PACKET *IkePacket; 31 32 IkePacket = (IKE_PACKET *) AllocateZeroPool (sizeof (IKE_PACKET)); 33 if (IkePacket == NULL) { 34 return NULL; 35 } 36 37 IkePacket->RefCount = 1; 38 InitializeListHead (&IkePacket->PayloadList); 39 40 IkePacket->Header = (IKE_HEADER *) AllocateZeroPool (sizeof (IKE_HEADER)); 41 if (IkePacket->Header == NULL) { 42 FreePool (IkePacket); 43 return NULL; 44 } 45 return IkePacket; 46 } 47 48 /** 49 Free the IkePacket by the specified IKE_PACKET pointer. 50 51 @param[in] IkePacket The pointer of the IKE_PACKET to be freed. 52 53 **/ 54 VOID 55 IkePacketFree ( 56 IN IKE_PACKET *IkePacket 57 ) 58 { 59 LIST_ENTRY *Entry; 60 IKE_PAYLOAD *IkePayload; 61 62 if (IkePacket == NULL) { 63 return; 64 } 65 // 66 // Check if the Packet is referred by others. 67 // 68 if (--IkePacket->RefCount == 0) { 69 // 70 // Free IkePacket header 71 // 72 if (!IkePacket->IsHdrExt && IkePacket->Header != NULL) { 73 FreePool (IkePacket->Header); 74 } 75 // 76 // Free the PayloadsBuff 77 // 78 if (!IkePacket->IsPayloadsBufExt && IkePacket->PayloadsBuf != NULL) { 79 FreePool (IkePacket->PayloadsBuf); 80 } 81 // 82 // Iterate payloadlist and free all payloads 83 // 84 for (Entry = (IkePacket)->PayloadList.ForwardLink; Entry != &(IkePacket)->PayloadList;) { 85 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry); 86 Entry = Entry->ForwardLink; 87 88 IkePayloadFree (IkePayload); 89 } 90 91 FreePool (IkePacket); 92 } 93 } 94 95 /** 96 Callback funtion of NetbufFromExt() 97 98 @param[in] Arg The data passed from the NetBufFromExe(). 99 100 **/ 101 VOID 102 EFIAPI 103 IkePacketNetbufFree ( 104 IN VOID *Arg 105 ) 106 { 107 // 108 // TODO: add something if need. 109 // 110 } 111 112 /** 113 Copy the NetBuf into a IKE_PACKET sturcture. 114 115 Create a IKE_PACKET and fill the received IKE header into the header of IKE_PACKET 116 and copy the recieved packet without IKE HEADER to the PayloadBuf of IKE_PACKET. 117 118 @param[in] Netbuf The pointer of the Netbuf which contains the whole received 119 IKE packet. 120 121 @return The pointer of the IKE_PACKET which contains the received packet. 122 123 **/ 124 IKE_PACKET * 125 IkePacketFromNetbuf ( 126 IN NET_BUF *Netbuf 127 ) 128 { 129 IKE_PACKET *IkePacket; 130 131 IkePacket = NULL; 132 if (Netbuf->TotalSize < sizeof (IKE_HEADER)) { 133 goto Error; 134 } 135 136 IkePacket = IkePacketAlloc (); 137 if (IkePacket == NULL) { 138 return NULL; 139 } 140 // 141 // Copy the IKE header from Netbuf to IkePacket->Hdr 142 // 143 NetbufCopy (Netbuf, 0, sizeof (IKE_HEADER), (UINT8 *) IkePacket->Header); 144 // 145 // Net order to host order 146 // 147 IkeHdrNetToHost (IkePacket->Header); 148 if (IkePacket->Header->Length < Netbuf->TotalSize) { 149 goto Error; 150 } 151 152 IkePacket->PayloadTotalSize = IkePacket->Header->Length - sizeof (IKE_HEADER); 153 IkePacket->PayloadsBuf = (UINT8 *) AllocateZeroPool (IkePacket->PayloadTotalSize); 154 155 if (IkePacket->PayloadsBuf == NULL) { 156 goto Error; 157 } 158 // 159 // Copy the IKE packet without the header into the IkePacket->PayloadsBuf. 160 // 161 NetbufCopy (Netbuf, sizeof (IKE_HEADER), (UINT32) IkePacket->PayloadTotalSize, IkePacket->PayloadsBuf); 162 return IkePacket; 163 164 Error: 165 if (IkePacket != NULL) { 166 IkePacketFree (IkePacket); 167 } 168 169 return NULL; 170 } 171 172 /** 173 Convert the format from IKE_PACKET to NetBuf. 174 175 @param[in] SessionCommon Pointer of related IKE_COMMON_SESSION 176 @param[in] IkePacket Pointer of IKE_PACKET to be copy to NetBuf 177 @param[in] IkeType The IKE type to pointer the packet is for which IKE 178 phase. Now it supports IKE_SA_TYPE, IKE_CHILDSA_TYPE, 179 IKE_INFO_TYPE. 180 181 @return a pointer of Netbuff which contains the IKE_PACKE in network order. 182 183 **/ 184 NET_BUF * 185 IkeNetbufFromPacket ( 186 IN UINT8 *SessionCommon, 187 IN IKE_PACKET *IkePacket, 188 IN UINTN IkeType 189 ) 190 { 191 NET_BUF *Netbuf; 192 NET_FRAGMENT *Fragments; 193 UINTN Index; 194 UINTN NumPayloads; 195 LIST_ENTRY *PacketEntry; 196 LIST_ENTRY *Entry; 197 IKE_PAYLOAD *IkePayload; 198 EFI_STATUS RetStatus; 199 200 RetStatus = EFI_SUCCESS; 201 202 if (!IkePacket->IsEncoded) { 203 IkePacket->IsEncoded = TRUE; 204 // 205 // Convert Host order to Network order for IKE_PACKET header and payloads 206 // Encryption payloads if needed 207 // 208 if (((IKEV2_SESSION_COMMON *) SessionCommon)->IkeVer == 2) { 209 RetStatus = Ikev2EncodePacket ((IKEV2_SESSION_COMMON *) SessionCommon, IkePacket, IkeType); 210 if (EFI_ERROR (RetStatus)) { 211 return NULL; 212 } 213 214 } else { 215 // 216 // If IKEv1 support, check it here. 217 // 218 return NULL; 219 } 220 } 221 222 NumPayloads = 0; 223 // 224 // Get the number of the payloads 225 // 226 NET_LIST_FOR_EACH (PacketEntry, &(IkePacket)->PayloadList) { 227 228 NumPayloads++; 229 } 230 // 231 // Allocate the Framgents according to the numbers of the IkePayload 232 // 233 Fragments = (NET_FRAGMENT *) AllocateZeroPool ((1 + NumPayloads) * sizeof (NET_FRAGMENT)); 234 if (Fragments == NULL) { 235 return NULL; 236 } 237 238 Fragments[0].Bulk = (UINT8 *) IkePacket->Header; 239 Fragments[0].Len = sizeof (IKE_HEADER); 240 Index = 0; 241 242 // 243 // Set payloads to the Framgments. 244 // 245 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) { 246 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry); 247 248 Fragments[Index + 1].Bulk = IkePayload->PayloadBuf; 249 Fragments[Index + 1].Len = (UINT32) IkePayload->PayloadSize; 250 Index++; 251 } 252 253 Netbuf = NetbufFromExt ( 254 Fragments, 255 (UINT32) (NumPayloads + 1), 256 0, 257 0, 258 IkePacketNetbufFree, 259 NULL 260 ); 261 262 FreePool (Fragments); 263 return Netbuf; 264 } 265 266