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 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 * 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 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 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 * 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 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 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 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 * 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 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