]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/IpSecDxe/IkeCommon.c
NetworkPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeCommon.c
1 /** @file
2 Common operation of the IKE
3
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "Ike.h"
11 #include "IkeCommon.h"
12 #include "IpSecConfigImpl.h"
13 #include "IpSecDebug.h"
14
15 /**
16 Check whether the new generated Spi has existed.
17
18 @param[in] IkeSaSession Pointer to the Child SA Session.
19 @param[in] SpiValue SPI Value.
20
21 @retval TRUE This SpiValue has existed in the Child SA Session
22 @retval FALSE This SpiValue doesn't exist in the Child SA Session.
23
24 **/
25 BOOLEAN
26 IkeSpiValueExisted (
27 IN IKEV2_SA_SESSION *IkeSaSession,
28 IN UINT32 SpiValue
29 )
30 {
31 LIST_ENTRY *Entry;
32 LIST_ENTRY *Next;
33 IKEV2_CHILD_SA_SESSION *SaSession;
34
35 Entry = NULL;
36 Next = NULL;
37 SaSession = NULL;
38
39 //
40 // Check whether the SPI value has existed in ChildSaEstablishSessionList.
41 //
42 NET_LIST_FOR_EACH_SAFE (Entry, Next, &IkeSaSession->ChildSaEstablishSessionList) {
43 SaSession= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);
44 if (SaSession->LocalPeerSpi == SpiValue) {
45 return TRUE;
46 }
47 }
48
49 //
50 // Check whether the SPI value has existed in ChildSaSessionList.
51 //
52 NET_LIST_FOR_EACH_SAFE (Entry, Next, &IkeSaSession->ChildSaSessionList) {
53 SaSession= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);
54 if (SaSession->LocalPeerSpi == SpiValue) {
55 return TRUE;
56 }
57 }
58
59 return FALSE;
60 }
61
62 /**
63 Call Crypto Lib to generate a random value with eight-octet length.
64
65 @return the 64 byte vaule.
66
67 **/
68 UINT64
69 IkeGenerateCookie (
70 VOID
71 )
72 {
73 UINT64 Cookie;
74 EFI_STATUS Status;
75
76 Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)&Cookie, sizeof (UINT64));
77 if (EFI_ERROR (Status)) {
78 return 0;
79 } else {
80 return Cookie;
81 }
82 }
83
84 /**
85 Generate the random data for Nonce payload.
86
87 @param[in] NonceSize Size of the data in bytes.
88
89 @return Buffer which contains the random data of the spcified size.
90
91 **/
92 UINT8 *
93 IkeGenerateNonce (
94 IN UINTN NonceSize
95 )
96 {
97 UINT8 *Nonce;
98 EFI_STATUS Status;
99
100 Nonce = AllocateZeroPool (NonceSize);
101 if (Nonce == NULL) {
102 return NULL;
103 }
104
105 Status = IpSecCryptoIoGenerateRandomBytes (Nonce, NonceSize);
106 if (EFI_ERROR (Status)) {
107 FreePool (Nonce);
108 return NULL;
109 } else {
110 return Nonce;
111 }
112 }
113
114 /**
115 Convert the IKE Header from Network order to Host order.
116
117 @param[in, out] Header The pointer of the IKE_HEADER.
118
119 **/
120 VOID
121 IkeHdrNetToHost (
122 IN OUT IKE_HEADER *Header
123 )
124 {
125 Header->InitiatorCookie = NTOHLL (Header->InitiatorCookie);
126 Header->ResponderCookie = NTOHLL (Header->ResponderCookie);
127 Header->MessageId = NTOHL (Header->MessageId);
128 Header->Length = NTOHL (Header->Length);
129 }
130
131 /**
132 Convert the IKE Header from Host order to Network order.
133
134 @param[in, out] Header The pointer of the IKE_HEADER.
135
136 **/
137 VOID
138 IkeHdrHostToNet (
139 IN OUT IKE_HEADER *Header
140 )
141 {
142 Header->InitiatorCookie = HTONLL (Header->InitiatorCookie);
143 Header->ResponderCookie = HTONLL (Header->ResponderCookie);
144 Header->MessageId = HTONL (Header->MessageId);
145 Header->Length = HTONL (Header->Length);
146 }
147
148 /**
149 Allocate a buffer of IKE_PAYLOAD and set its Signature.
150
151 @return A buffer of IKE_PAYLOAD.
152
153 **/
154 IKE_PAYLOAD *
155 IkePayloadAlloc (
156 VOID
157 )
158 {
159 IKE_PAYLOAD *IkePayload;
160
161 IkePayload = (IKE_PAYLOAD *) AllocateZeroPool (sizeof (IKE_PAYLOAD));
162 if (IkePayload == NULL) {
163 return NULL;
164 }
165
166 IkePayload->Signature = IKE_PAYLOAD_SIGNATURE;
167
168 return IkePayload;
169 }
170
171 /**
172 Free a specified IKE_PAYLOAD buffer.
173
174 @param[in] IkePayload Pointer of IKE_PAYLOAD to be freed.
175
176 **/
177 VOID
178 IkePayloadFree (
179 IN IKE_PAYLOAD *IkePayload
180 )
181 {
182 if (IkePayload == NULL) {
183 return;
184 }
185 //
186 // If this IkePayload is not referred by others, free it.
187 //
188 if (!IkePayload->IsPayloadBufExt && (IkePayload->PayloadBuf != NULL)) {
189 FreePool (IkePayload->PayloadBuf);
190 }
191
192 FreePool (IkePayload);
193 }
194
195 /**
196 Generate an new SPI.
197
198 @param[in] IkeSaSession Pointer to IKEV2_SA_SESSION related to this Child SA
199 Session.
200 @param[in, out] SpiValue Pointer to the new generated SPI value.
201
202 @retval EFI_SUCCESS The operation performs successfully.
203 @retval Otherwise The operation is failed.
204
205 **/
206 EFI_STATUS
207 IkeGenerateSpi (
208 IN IKEV2_SA_SESSION *IkeSaSession,
209 IN OUT UINT32 *SpiValue
210 )
211 {
212 EFI_STATUS Status;
213
214 Status = EFI_SUCCESS;
215
216 while (TRUE) {
217 //
218 // Generate SPI randomly
219 //
220 Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)SpiValue, sizeof (UINT32));
221 if (EFI_ERROR (Status)) {
222 break;
223 }
224
225 //
226 // The set of SPI values in the range 1 through 255 are reserved by the
227 // Internet Assigned Numbers Authority (IANA) for future use; a reserved
228 // SPI value will not normally be assigned by IANA unless the use of the
229 // assigned SPI value is specified in an RFC.
230 //
231 if (*SpiValue < IKE_SPI_BASE) {
232 *SpiValue += IKE_SPI_BASE;
233 }
234
235 //
236 // Check whether the new generated SPI has existed.
237 //
238 if (!IkeSpiValueExisted (IkeSaSession, *SpiValue)) {
239 break;
240 }
241 }
242
243 return Status;
244 }
245
246 /**
247 Generate a random data for IV
248
249 @param[in] IvBuffer The pointer of the IV buffer.
250 @param[in] IvSize The IV size.
251
252 @retval EFI_SUCCESS Create a random data for IV.
253 @retval otherwise Failed.
254
255 **/
256 EFI_STATUS
257 IkeGenerateIv (
258 IN UINT8 *IvBuffer,
259 IN UINTN IvSize
260 )
261 {
262 return IpSecCryptoIoGenerateRandomBytes (IvBuffer, IvSize);
263 }
264
265
266 /**
267 Find SPD entry by a specified SPD selector.
268
269 @param[in] SpdSel Point to SPD Selector to be searched for.
270
271 @retval Point to SPD Entry if the SPD entry found.
272 @retval NULL if not found.
273
274 **/
275 IPSEC_SPD_ENTRY *
276 IkeSearchSpdEntry (
277 IN EFI_IPSEC_SPD_SELECTOR *SpdSel
278 )
279 {
280 IPSEC_SPD_ENTRY *SpdEntry;
281 LIST_ENTRY *SpdList;
282 LIST_ENTRY *Entry;
283
284 SpdList = &mConfigData[IPsecConfigDataTypeSpd];
285
286 NET_LIST_FOR_EACH (Entry, SpdList) {
287 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
288
289 //
290 // Find the required SPD entry
291 //
292 if (CompareSpdSelector (
293 (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
294 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
295 )) {
296 return SpdEntry;
297 }
298
299 }
300
301 return NULL;
302 }
303
304 /**
305 Get the IKE Version from the IKE_SA_SESSION.
306
307 @param[in] Session Pointer of the IKE_SA_SESSION.
308
309 **/
310 UINT8
311 IkeGetVersionFromSession (
312 IN UINT8 *Session
313 )
314 {
315 if (*(UINT32 *) Session == IKEV2_SA_SESSION_SIGNATURE) {
316 return ((IKEV2_SA_SESSION *) Session)->SessionCommon.IkeVer;
317 } else {
318 //
319 // Add IKEv1 support here.
320 //
321 return 0;
322 }
323 }
324