1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
/** @file
The definitions related to IPsec protocol implementation.
Copyright (c) 2009 - 2018, 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.
**/
#ifndef _IP_SEC_IMPL_H_
#define _IP_SEC_IMPL_H_
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/NetLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Protocol/IpSec.h>
#include <Protocol/IpSecConfig.h>
#include <Protocol/Dpc.h>
#include <Protocol/ComponentName.h>
#include <Protocol/ComponentName2.h>
typedef struct _IPSEC_PRIVATE_DATA IPSEC_PRIVATE_DATA;
typedef struct _IPSEC_SPD_ENTRY IPSEC_SPD_ENTRY;
typedef struct _IPSEC_PAD_ENTRY IPSEC_PAD_ENTRY;
typedef struct _IPSEC_SPD_DATA IPSEC_SPD_DATA;
#define IPSEC_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I', 'P', 'S', 'E')
#define IPSEC_PRIVATE_DATA_FROM_IPSEC(a) CR (a, IPSEC_PRIVATE_DATA, IpSec, IPSEC_PRIVATE_DATA_SIGNATURE)
#define IPSEC_PRIVATE_DATA_FROM_UDP4LIST(a) CR (a, IPSEC_PRIVATE_DATA, Udp4List, IPSEC_PRIVATE_DATA_SIGNATURE)
#define IPSEC_PRIVATE_DATA_FROM_UDP6LIST(a) CR (a, IPSEC_PRIVATE_DATA, Udp6List, IPSEC_PRIVATE_DATA_SIGNATURE)
#define IPSEC_UDP_SERVICE_FROM_LIST(a) BASE_CR (a, IKE_UDP_SERVICE, List)
#define IPSEC_SPD_ENTRY_FROM_LIST(a) BASE_CR (a, IPSEC_SPD_ENTRY, List)
#define IPSEC_SAD_ENTRY_FROM_LIST(a) BASE_CR (a, IPSEC_SAD_ENTRY, List)
#define IPSEC_PAD_ENTRY_FROM_LIST(a) BASE_CR (a, IPSEC_PAD_ENTRY, List)
#define IPSEC_SAD_ENTRY_FROM_SPD(a) BASE_CR (a, IPSEC_SAD_ENTRY, BySpd)
#define IPSEC_STATUS_DISABLED 0
#define IPSEC_STATUS_ENABLED 1
#define IPSEC_ESP_PROTOCOL 50
#define IPSEC_AH_PROTOCOL 51
#define IPSEC_DEFAULT_VARIABLE_SIZE 0x100
//
// Internal Structure Definition
//
#pragma pack(1)
typedef struct _EFI_AH_HEADER {
UINT8 NextHeader;
UINT8 PayloadLen;
UINT16 Reserved;
UINT32 Spi;
UINT32 SequenceNumber;
} EFI_AH_HEADER;
typedef struct _EFI_ESP_HEADER {
UINT32 Spi;
UINT32 SequenceNumber;
} EFI_ESP_HEADER;
typedef struct _EFI_ESP_TAIL {
UINT8 PaddingLength;
UINT8 NextHeader;
} EFI_ESP_TAIL;
#pragma pack()
struct _IPSEC_SPD_DATA {
CHAR16 Name[100];
UINT32 PackageFlag;
EFI_IPSEC_TRAFFIC_DIR TrafficDirection;
EFI_IPSEC_ACTION Action;
EFI_IPSEC_PROCESS_POLICY *ProcessingPolicy;
LIST_ENTRY Sas;
};
struct _IPSEC_SPD_ENTRY {
EFI_IPSEC_SPD_SELECTOR *Selector;
IPSEC_SPD_DATA *Data;
LIST_ENTRY List;
};
typedef struct _IPSEC_SAD_DATA {
EFI_IPSEC_MODE Mode;
UINT64 SequenceNumber;
UINT8 AntiReplayWindowSize;
UINT64 AntiReplayBitmap[4]; // bitmap for received packet
EFI_IPSEC_ALGO_INFO AlgoInfo;
EFI_IPSEC_SA_LIFETIME SaLifetime;
UINT32 PathMTU;
IPSEC_SPD_ENTRY *SpdEntry;
EFI_IPSEC_SPD_SELECTOR *SpdSelector;
BOOLEAN ESNEnabled; // Extended (64-bit) SN enabled
BOOLEAN ManualSet;
EFI_IP_ADDRESS TunnelDestAddress;
EFI_IP_ADDRESS TunnelSourceAddress;
} IPSEC_SAD_DATA;
typedef struct _IPSEC_SAD_ENTRY {
EFI_IPSEC_SA_ID *Id;
IPSEC_SAD_DATA *Data;
LIST_ENTRY List;
LIST_ENTRY BySpd; // Linked on IPSEC_SPD_DATA.Sas
} IPSEC_SAD_ENTRY;
struct _IPSEC_PAD_ENTRY {
EFI_IPSEC_PAD_ID *Id;
EFI_IPSEC_PAD_DATA *Data;
LIST_ENTRY List;
};
typedef struct _IPSEC_RECYCLE_CONTEXT {
EFI_IPSEC_FRAGMENT_DATA *FragmentTable;
UINT8 *PayloadBuffer;
} IPSEC_RECYCLE_CONTEXT;
//
// Struct used to store the Hash and its data.
//
typedef struct {
UINTN DataSize;
UINT8 *Data;
} HASH_DATA_FRAGMENT;
struct _IPSEC_PRIVATE_DATA {
UINT32 Signature;
EFI_HANDLE Handle; // Virtual handle to install private prtocol
EFI_HANDLE ImageHandle;
EFI_IPSEC2_PROTOCOL IpSec;
EFI_IPSEC_CONFIG_PROTOCOL IpSecConfig;
BOOLEAN SetBySelf;
LIST_ENTRY Udp4List;
UINTN Udp4Num;
LIST_ENTRY Udp6List;
UINTN Udp6Num;
LIST_ENTRY Ikev1SessionList;
LIST_ENTRY Ikev1EstablishedList;
LIST_ENTRY Ikev2SessionList;
LIST_ENTRY Ikev2EstablishedList;
BOOLEAN IsIPsecDisabling;
};
/**
This function processes the inbound traffic with IPsec.
It checks the received packet security property, trims the ESP/AH header, and then
returns without an IPsec protected IP Header and FragmentTable.
@param[in] IpVersion The version of IP.
@param[in, out] IpHead Points to IP header containing the ESP/AH header
to be trimed on input, and without ESP/AH header
on return.
@param[in, out] LastHead The Last Header in IP header on return.
@param[in, out] OptionsBuffer Pointer to the options buffer.
@param[in, out] OptionsLength Length of the options buffer.
@param[in, out] FragmentTable Pointer to a list of fragments in form of IPsec
protected on input, and without IPsec protected
on return.
@param[in, out] FragmentCount The number of fragments.
@param[out] SpdEntry Pointer to contain the address of SPD entry on return.
@param[out] RecycleEvent The event for recycling of resources.
@retval EFI_SUCCESS The operation was successful.
@retval EFI_UNSUPPORTED The IPSEC protocol is not supported.
**/
EFI_STATUS
IpSecProtectInboundPacket (
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
IN OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer,
IN OUT UINT32 *OptionsLength,
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
OUT EFI_IPSEC_SPD_SELECTOR **SpdEntry,
OUT EFI_EVENT *RecycleEvent
);
/**
This fucntion processes the output traffic with IPsec.
It protected the sending packet by encrypting it payload and inserting ESP/AH header
in the orginal IP header, then return the IpHeader and IPsec protected Fragmentable.
@param[in] IpVersion The version of IP.
@param[in, out] IpHead Point to IP header containing the orginal IP header
to be processed on input, and inserted ESP/AH header
on return.
@param[in, out] LastHead The Last Header in IP header.
@param[in, out] OptionsBuffer Pointer to the options buffer.
@param[in, out] OptionsLength Length of the options buffer.
@param[in, out] FragmentTable Pointer to a list of fragments to be protected by
IPsec on input, and with IPsec protected
on return.
@param[in, out] FragmentCount Number of fragments.
@param[in] SadEntry Related SAD entry.
@param[out] RecycleEvent Event for recycling of resources.
@retval EFI_SUCCESS The operation is successful.
@retval EFI_UNSUPPORTED If the IPSEC protocol is not supported.
**/
EFI_STATUS
IpSecProtectOutboundPacket (
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
IN OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer,
IN OUT UINT32 *OptionsLength,
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
IN IPSEC_SAD_ENTRY *SadEntry,
OUT EFI_EVENT *RecycleEvent
);
/**
Check if the IP Address in the address range of AddressInfos specified.
@param[in] IpVersion The IP version.
@param[in] IpAddr Points to EFI_IP_ADDRESS to be check.
@param[in] AddressInfo A list of EFI_IP_ADDRESS_INFO that is used to check
the IP Address is matched.
@param[in] AddressCount The total numbers of the AddressInfo.
@retval TRUE If the Specified IP Address is in the range of the AddressInfos specified.
@retval FALSE If the Specified IP Address is not in the range of the AddressInfos specified.
**/
BOOLEAN
IpSecMatchIpAddress (
IN UINT8 IpVersion,
IN EFI_IP_ADDRESS *IpAddr,
IN EFI_IP_ADDRESS_INFO *AddressInfo,
IN UINT32 AddressCount
);
/**
Find a PAD entry according to remote IP address.
@param[in] IpVersion The version of IP.
@param[in] IpAddr Point to remote IP address.
@return The pointer of related PAD entry.
**/
IPSEC_PAD_ENTRY *
IpSecLookupPadEntry (
IN UINT8 IpVersion,
IN EFI_IP_ADDRESS *IpAddr
);
/**
Check if the specified IP packet can be serviced by this SPD entry.
@param[in] SpdEntry Point to SPD entry.
@param[in] IpVersion Version of IP.
@param[in] IpHead Point to IP header.
@param[in] IpPayload Point to IP payload.
@param[in] Protocol The Last protocol of IP packet.
@param[in] IsOutbound Traffic direction.
@param[out] Action The support action of SPD entry.
@retval EFI_SUCCESS Find the related SPD.
@retval EFI_NOT_FOUND Not find the related SPD entry;
**/
EFI_STATUS
IpSecLookupSpdEntry (
IN IPSEC_SPD_ENTRY *SpdEntry,
IN UINT8 IpVersion,
IN VOID *IpHead,
IN UINT8 *IpPayload,
IN UINT8 Protocol,
IN BOOLEAN IsOutbound,
OUT EFI_IPSEC_ACTION *Action
);
/**
Look up if there is existing SAD entry for specified IP packet sending.
This function is called by the IPsecProcess when there is some IP packet needed to
send out. This function checks if there is an existing SAD entry that can be serviced
to this IP packet sending. If no existing SAD entry could be used, this
function will invoke an IPsec Key Exchange Negotiation.
@param[in] Private Points to private data.
@param[in] NicHandle Points to a NIC handle.
@param[in] IpVersion The version of IP.
@param[in] IpHead The IP Header of packet to be sent out.
@param[in] IpPayload The IP Payload to be sent out.
@param[in] OldLastHead The Last protocol of the IP packet.
@param[in] SpdEntry Points to a related SPD entry.
@param[out] SadEntry Contains the Point of a related SAD entry.
@retval EFI_DEVICE_ERROR One of following conditions is TRUE:
- If don't find related UDP service.
- Sequence Number is used up.
- Extension Sequence Number is used up.
@retval EFI_NOT_READY No existing SAD entry could be used.
@retval EFI_SUCCESS Find the related SAD entry.
**/
EFI_STATUS
IpSecLookupSadEntry (
IN IPSEC_PRIVATE_DATA *Private,
IN EFI_HANDLE NicHandle,
IN UINT8 IpVersion,
IN VOID *IpHead,
IN UINT8 *IpPayload,
IN UINT8 OldLastHead,
IN IPSEC_SPD_ENTRY *SpdEntry,
OUT IPSEC_SAD_ENTRY **SadEntry
);
/**
Find the SAD through whole SAD list.
@param[in] Spi The SPI used to search the SAD entry.
@param[in] DestAddress The destination used to search the SAD entry.
@param[in] IpVersion The IP version. Ip4 or Ip6.
@return The pointer to a certain SAD entry.
**/
IPSEC_SAD_ENTRY *
IpSecLookupSadBySpi (
IN UINT32 Spi,
IN EFI_IP_ADDRESS *DestAddress,
IN UINT8 IpVersion
)
;
/**
Handles IPsec packet processing for inbound and outbound IP packets.
The EFI_IPSEC_PROCESS process routine handles each inbound or outbound packet.
The behavior is that it can perform one of the following actions:
bypass the packet, discard the packet, or protect the packet.
@param[in] This Pointer to the EFI_IPSEC2_PROTOCOL instance.
@param[in] NicHandle Instance of the network interface.
@param[in] IpVersion IPV4 or IPV6.
@param[in, out] IpHead Pointer to the IP Header.
@param[in, out] LastHead The protocol of the next layer to be processed by IPsec.
@param[in, out] OptionsBuffer Pointer to the options buffer.
@param[in, out] OptionsLength Length of the options buffer.
@param[in, out] FragmentTable Pointer to a list of fragments.
@param[in, out] FragmentCount Number of fragments.
@param[in] TrafficDirection Traffic direction.
@param[out] RecycleSignal Event for recycling of resources.
@retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.
@retval EFI_SUCCESS The packet was protected.
@retval EFI_ACCESS_DENIED The packet was discarded.
**/
EFI_STATUS
EFIAPI
IpSecProcess (
IN EFI_IPSEC2_PROTOCOL *This,
IN EFI_HANDLE NicHandle,
IN UINT8 IpVersion,
IN OUT VOID *IpHead,
IN OUT UINT8 *LastHead,
IN OUT VOID **OptionsBuffer,
IN OUT UINT32 *OptionsLength,
IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
IN OUT UINT32 *FragmentCount,
IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection,
OUT EFI_EVENT *RecycleSignal
);
extern EFI_DPC_PROTOCOL *mDpc;
extern EFI_IPSEC2_PROTOCOL mIpSecInstance;
extern EFI_COMPONENT_NAME2_PROTOCOL gIpSecComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gIpSecComponentName;
#endif
|