Home | History | Annotate | Download | only in Tpm2CommandLib
      1 /** @file
      2   Implement TPM2 Session related command.
      3 
      4 Copyright (c) 2014, Intel Corporation. All rights reserved. <BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <IndustryStandard/UefiTcgPlatform.h>
     16 #include <Library/Tpm2CommandLib.h>
     17 #include <Library/Tpm2DeviceLib.h>
     18 #include <Library/BaseMemoryLib.h>
     19 #include <Library/BaseLib.h>
     20 #include <Library/DebugLib.h>
     21 
     22 #pragma pack(1)
     23 
     24 typedef struct {
     25   TPM2_COMMAND_HEADER       Header;
     26   TPMI_DH_OBJECT            TpmKey;
     27   TPMI_DH_ENTITY            Bind;
     28   TPM2B_NONCE               NonceCaller;
     29   TPM2B_ENCRYPTED_SECRET    Salt;
     30   TPM_SE                    SessionType;
     31   TPMT_SYM_DEF              Symmetric;
     32   TPMI_ALG_HASH             AuthHash;
     33 } TPM2_START_AUTH_SESSION_COMMAND;
     34 
     35 typedef struct {
     36   TPM2_RESPONSE_HEADER      Header;
     37   TPMI_SH_AUTH_SESSION      SessionHandle;
     38   TPM2B_NONCE               NonceTPM;
     39 } TPM2_START_AUTH_SESSION_RESPONSE;
     40 
     41 #pragma pack()
     42 
     43 /**
     44   This command is used to start an authorization session using alternative methods of
     45   establishing the session key (sessionKey) that is used for authorization and encrypting value.
     46 
     47   @param[in]  TpmKey             Handle of a loaded decrypt key used to encrypt salt.
     48   @param[in]  Bind               Entity providing the authValue.
     49   @param[in]  NonceCaller        Initial nonceCaller, sets nonce size for the session.
     50   @param[in]  Salt               Value encrypted according to the type of tpmKey.
     51   @param[in]  SessionType        Indicates the type of the session.
     52   @param[in]  Symmetric          The algorithm and key size for parameter encryption.
     53   @param[in]  AuthHash           Hash algorithm to use for the session.
     54   @param[out] SessionHandle      Handle for the newly created session.
     55   @param[out] NonceTPM           The initial nonce from the TPM, used in the computation of the sessionKey.
     56 
     57   @retval EFI_SUCCESS            Operation completed successfully.
     58   @retval EFI_DEVICE_ERROR       The command was unsuccessful.
     59 **/
     60 EFI_STATUS
     61 EFIAPI
     62 Tpm2StartAuthSession (
     63   IN      TPMI_DH_OBJECT            TpmKey,
     64   IN      TPMI_DH_ENTITY            Bind,
     65   IN      TPM2B_NONCE               *NonceCaller,
     66   IN      TPM2B_ENCRYPTED_SECRET    *Salt,
     67   IN      TPM_SE                    SessionType,
     68   IN      TPMT_SYM_DEF              *Symmetric,
     69   IN      TPMI_ALG_HASH             AuthHash,
     70      OUT  TPMI_SH_AUTH_SESSION      *SessionHandle,
     71      OUT  TPM2B_NONCE               *NonceTPM
     72   )
     73 {
     74   EFI_STATUS                        Status;
     75   TPM2_START_AUTH_SESSION_COMMAND   SendBuffer;
     76   TPM2_START_AUTH_SESSION_RESPONSE  RecvBuffer;
     77   UINT32                            SendBufferSize;
     78   UINT32                            RecvBufferSize;
     79   UINT8                             *Buffer;
     80 
     81   //
     82   // Construct command
     83   //
     84   SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
     85   SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_StartAuthSession);
     86 
     87   SendBuffer.TpmKey = SwapBytes32 (TpmKey);
     88   SendBuffer.Bind = SwapBytes32 (Bind);
     89   Buffer = (UINT8 *)&SendBuffer.NonceCaller;
     90 
     91   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NonceCaller->size));
     92   Buffer += sizeof(UINT16);
     93   CopyMem (Buffer, NonceCaller->buffer, NonceCaller->size);
     94   Buffer += NonceCaller->size;
     95 
     96   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Salt->size));
     97   Buffer += sizeof(UINT16);
     98   CopyMem (Buffer, Salt->secret, Salt->size);
     99   Buffer += Salt->size;
    100 
    101   *(TPM_SE *)Buffer = SessionType;
    102   Buffer++;
    103 
    104   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->algorithm));
    105   Buffer += sizeof(UINT16);
    106   switch (Symmetric->algorithm) {
    107   case TPM_ALG_NULL:
    108     break;
    109   case TPM_ALG_AES:
    110     WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.aes));
    111     Buffer += sizeof(UINT16);
    112     WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.aes));
    113     Buffer += sizeof(UINT16);
    114     break;
    115   case TPM_ALG_SM4:
    116     WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.SM4));
    117     Buffer += sizeof(UINT16);
    118     WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.SM4));
    119     Buffer += sizeof(UINT16);
    120     break;
    121   case TPM_ALG_SYMCIPHER:
    122     WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.sym));
    123     Buffer += sizeof(UINT16);
    124     WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.sym));
    125     Buffer += sizeof(UINT16);
    126     break;
    127   case TPM_ALG_XOR:
    128     WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.xor));
    129     Buffer += sizeof(UINT16);
    130     break;
    131   default:
    132     ASSERT (FALSE);
    133     DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - Symmetric->algorithm - %x\n", Symmetric->algorithm));
    134     return EFI_UNSUPPORTED;
    135   }
    136 
    137   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthHash));
    138   Buffer += sizeof(UINT16);
    139 
    140   SendBufferSize = (UINT32) ((UINTN)Buffer - (UINTN)&SendBuffer);
    141   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
    142 
    143   //
    144   // send Tpm command
    145   //
    146   RecvBufferSize = sizeof (RecvBuffer);
    147   Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
    148   if (EFI_ERROR (Status)) {
    149     return Status;
    150   }
    151 
    152   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
    153     DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - RecvBufferSize Error - %x\n", RecvBufferSize));
    154     return EFI_DEVICE_ERROR;
    155   }
    156   if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
    157     DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
    158     return EFI_DEVICE_ERROR;
    159   }
    160 
    161   //
    162   // Return the response
    163   //
    164   *SessionHandle = SwapBytes32 (RecvBuffer.SessionHandle);
    165   NonceTPM->size = SwapBytes16 (RecvBuffer.NonceTPM.size);
    166   CopyMem (NonceTPM->buffer, &RecvBuffer.NonceTPM.buffer, NonceTPM->size);
    167 
    168   return EFI_SUCCESS;
    169 }
    170