1 /** @file
2   Common operation of the IKE
3 
4   Copyright (c) 2010 - 2015, 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 "Ike.h"
17 #include "IkeCommon.h"
18 #include "IpSecConfigImpl.h"
19 #include "IpSecDebug.h"
20 
21 //
22 // Initial the SPI
23 //
24 UINT32            mNextSpi  = IKE_SPI_BASE;
25 
26 /**
27   Call Crypto Lib to generate a random value with eight-octet length.
28 
29   @return the 64 byte vaule.
30 
31 **/
32 UINT64
IkeGenerateCookie(VOID)33 IkeGenerateCookie (
34   VOID
35   )
36 {
37   UINT64     Cookie;
38   EFI_STATUS Status;
39 
40   Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)&Cookie, sizeof (UINT64));
41   if (EFI_ERROR (Status)) {
42     return 0;
43   } else {
44     return Cookie;
45   }
46 }
47 
48 /**
49   Generate the random data for Nonce payload.
50 
51   @param[in]  NonceSize      Size of the data in bytes.
52 
53   @return Buffer which contains the random data of the spcified size.
54 
55 **/
56 UINT8 *
IkeGenerateNonce(IN UINTN NonceSize)57 IkeGenerateNonce (
58   IN UINTN              NonceSize
59   )
60 {
61   UINT8                  *Nonce;
62   EFI_STATUS             Status;
63 
64   Nonce = AllocateZeroPool (NonceSize);
65   if (Nonce == NULL) {
66     return NULL;
67   }
68 
69   Status = IpSecCryptoIoGenerateRandomBytes (Nonce, NonceSize);
70   if (EFI_ERROR (Status)) {
71     FreePool (Nonce);
72     return NULL;
73   } else {
74     return Nonce;
75   }
76 }
77 
78 /**
79   Convert the IKE Header from Network order to Host order.
80 
81   @param[in, out]  Header    The pointer of the IKE_HEADER.
82 
83 **/
84 VOID
IkeHdrNetToHost(IN OUT IKE_HEADER * Header)85 IkeHdrNetToHost (
86   IN OUT IKE_HEADER *Header
87   )
88 {
89   Header->InitiatorCookie = NTOHLL (Header->InitiatorCookie);
90   Header->ResponderCookie = NTOHLL (Header->ResponderCookie);
91   Header->MessageId       = NTOHL (Header->MessageId);
92   Header->Length          = NTOHL (Header->Length);
93 }
94 
95 /**
96   Convert the IKE Header from Host order to Network order.
97 
98   @param[in, out] Header     The pointer of the IKE_HEADER.
99 
100 **/
101 VOID
IkeHdrHostToNet(IN OUT IKE_HEADER * Header)102 IkeHdrHostToNet (
103   IN OUT IKE_HEADER *Header
104   )
105 {
106   Header->InitiatorCookie = HTONLL (Header->InitiatorCookie);
107   Header->ResponderCookie = HTONLL (Header->ResponderCookie);
108   Header->MessageId       = HTONL (Header->MessageId);
109   Header->Length          = HTONL (Header->Length);
110 }
111 
112 /**
113   Allocate a buffer of IKE_PAYLOAD and set its Signature.
114 
115   @return A buffer of IKE_PAYLOAD.
116 
117 **/
118 IKE_PAYLOAD *
IkePayloadAlloc(VOID)119 IkePayloadAlloc (
120   VOID
121   )
122 {
123   IKE_PAYLOAD *IkePayload;
124 
125   IkePayload            = (IKE_PAYLOAD *) AllocateZeroPool (sizeof (IKE_PAYLOAD));
126   if (IkePayload == NULL) {
127     return NULL;
128   }
129 
130   IkePayload->Signature = IKE_PAYLOAD_SIGNATURE;
131 
132   return IkePayload;
133 }
134 
135 /**
136   Free a specified IKE_PAYLOAD buffer.
137 
138   @param[in]  IkePayload   Pointer of IKE_PAYLOAD to be freed.
139 
140 **/
141 VOID
IkePayloadFree(IN IKE_PAYLOAD * IkePayload)142 IkePayloadFree (
143   IN IKE_PAYLOAD *IkePayload
144   )
145 {
146   if (IkePayload == NULL) {
147     return;
148   }
149   //
150   // If this IkePayload is not referred by others, free it.
151   //
152   if (!IkePayload->IsPayloadBufExt && (IkePayload->PayloadBuf != NULL)) {
153     FreePool (IkePayload->PayloadBuf);
154   }
155 
156   FreePool (IkePayload);
157 }
158 
159 /**
160   Generate an new SPI.
161 
162   @return a SPI in 4 bytes.
163 
164 **/
165 UINT32
IkeGenerateSpi(VOID)166 IkeGenerateSpi (
167   VOID
168   )
169 {
170   //
171   // TODO: should generate SPI randomly to avoid security issue
172   //
173   return mNextSpi++;
174 }
175 
176 /**
177   Generate a random data for IV
178 
179   @param[in]  IvBuffer  The pointer of the IV buffer.
180   @param[in]  IvSize    The IV size.
181 
182   @retval     EFI_SUCCESS  Create a random data for IV.
183   @retval     otherwise    Failed.
184 
185 **/
186 EFI_STATUS
IkeGenerateIv(IN UINT8 * IvBuffer,IN UINTN IvSize)187 IkeGenerateIv (
188   IN UINT8                           *IvBuffer,
189   IN UINTN                           IvSize
190   )
191 {
192   return IpSecCryptoIoGenerateRandomBytes (IvBuffer, IvSize);
193 }
194 
195 
196 /**
197   Find SPD entry by a specified SPD selector.
198 
199   @param[in] SpdSel       Point to SPD Selector to be searched for.
200 
201   @retval Point to SPD Entry if the SPD entry found.
202   @retval NULL if not found.
203 
204 **/
205 IPSEC_SPD_ENTRY *
IkeSearchSpdEntry(IN EFI_IPSEC_SPD_SELECTOR * SpdSel)206 IkeSearchSpdEntry (
207   IN EFI_IPSEC_SPD_SELECTOR             *SpdSel
208   )
209 {
210   IPSEC_SPD_ENTRY *SpdEntry;
211   LIST_ENTRY      *SpdList;
212   LIST_ENTRY      *Entry;
213 
214   SpdList = &mConfigData[IPsecConfigDataTypeSpd];
215 
216   NET_LIST_FOR_EACH (Entry, SpdList) {
217     SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
218 
219     //
220     // Find the required SPD entry
221     //
222     if (CompareSpdSelector (
223           (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
224           (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
225           )) {
226       return SpdEntry;
227     }
228 
229   }
230 
231   return NULL;
232 }
233 
234 /**
235   Get the IKE Version from the IKE_SA_SESSION.
236 
237   @param[in]  Session  Pointer of the IKE_SA_SESSION.
238 
239 **/
240 UINT8
IkeGetVersionFromSession(IN UINT8 * Session)241 IkeGetVersionFromSession (
242   IN UINT8    *Session
243   )
244 {
245   if (*(UINT32 *) Session == IKEV2_SA_SESSION_SIGNATURE) {
246     return ((IKEV2_SA_SESSION *) Session)->SessionCommon.IkeVer;
247   } else {
248     //
249     // Add IKEv1 support here.
250     //
251     return 0;
252   }
253 }
254 
255