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//
24UINT32            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**/
32UINT64
33IkeGenerateCookie (
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**/
56UINT8 *
57IkeGenerateNonce (
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**/
84VOID
85IkeHdrNetToHost (
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**/
101VOID
102IkeHdrHostToNet (
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**/
118IKE_PAYLOAD *
119IkePayloadAlloc (
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**/
141VOID
142IkePayloadFree (
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**/
165UINT32
166IkeGenerateSpi (
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**/
186EFI_STATUS
187IkeGenerateIv (
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**/
205IPSEC_SPD_ENTRY *
206IkeSearchSpdEntry (
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**/
240UINT8
241IkeGetVersionFromSession (
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