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