Home | History | Annotate | Download | only in IpSecDxe
      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