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