Example #1
0
        /// <summary>
        /// First determine whether parm enc/decryption is in effect for this command. If not 
        /// return an unmodified buffer.  If so then do the parm encryption.
        /// </summary>
        /// <param name="parms"></param>
        /// <param name="commandInfo"></param>
        /// <param name="offset"></param>
        /// <param name="inOrOut"></param>
        /// <returns></returns>
        private byte[] DoParmEncryption(byte[] parms, CommandInfo commandInfo, int offset, Direction inOrOut)
        {
            if (OuterCommand != TpmCc.None)
                return parms;

            AuthSession     encSess = null;
            ParmCryptInfo   encFlag2, encFlag4;

            if (inOrOut == Direction.Command)
            {
                encSess = DecSession;
                encFlag2 = ParmCryptInfo.EncIn2;
                encFlag4 = ParmCryptInfo.EncIn4;
            }
            else
            {
                encSess = EncSession;
                encFlag2 = ParmCryptInfo.DecOut2;
                encFlag4 = ParmCryptInfo.DecOut4;
            }

            // See if encryption/decryption is needed in whatever direction we are currently going ...
            if (encSess == null)
            {
                return parms;
            }
            if ((commandInfo.TheParmCryptInfo & (encFlag2 | encFlag4)) == 0)
            {
                if (!_Behavior.Passthrough)
                {
                    throw new Exception(string.Format("Command {0} cannot use {1} session",
                                                      commandInfo.CommandCode,
                                                      inOrOut == Direction.Command ? "decryption" : "encryption"));
                }
                return parms;
            }

            // ... and get the length of the size counter prepending the XCrypted parameter.
            int countSize = commandInfo.TheParmCryptInfo.HasFlag(encFlag2) ? 2 : 4;

            // Now get the encrypted data (first parm) pos and length ...
            // We are interpreting the byte-stream starting at startPos as a length (2 or 4 byte)
            // prepended buffer
            byte[] lenX = Globs.CopyData(parms, offset, countSize);
            uint len = Globs.NetToHostVar(lenX);
            byte[] firstParm = Globs.CopyData(parms, offset + countSize, (int)len);
            byte[] encFirstParm = encSess.ParmEncrypt(firstParm, inOrOut);

            for (int j = 0; j < len; j++)
            {
                parms[offset + countSize + j] = encFirstParm[j];
            }
            return parms;
        } // DoParmEncryption()
Example #2
0
 /// <summary>
 /// Updates TBS context database for commands that either fill or empty slots.
 /// </summary>
 /// <param name="caller"></param>
 /// <param name="command"></param>
 /// <param name="responseHandles"></param>
 /// <param name="inputObjects"></param>
 private void ProcessUpdatedTpmState(TbsContext caller, CommandInfo command, TpmHandle[] responseHandles, ObjectContext[] inputObjects)
 {
     switch (command.CommandCode)
     {
         // Commands that fill a slot (apart from contextLoad, which is more complex)
         case TpmCc.Load:
         case TpmCc.LoadExternal:
         case TpmCc.CreatePrimary:
         case TpmCc.HmacStart:
         case TpmCc.HashSequenceStart:
         case TpmCc.StartAuthSession:
             var t = new TpmHandle(responseHandles[0].handle);
             // ReSharper disable once UnusedVariable
             ObjectContext context2 = ContextManager.CreateObjectContext(caller, t);
             break;
         case TpmCc.ContextLoad:
         case TpmCc.ContextSave:
             throw new Exception("ProcessUpdatedTpmState: Should not be here");
         case TpmCc.FlushContext:
         case TpmCc.SequenceComplete:
             ContextManager.Remove(inputObjects[0]);
             break;
         case TpmCc.EventSequenceComplete:
             ContextManager.Remove(inputObjects[1]);
             break;
     }
 }
Example #3
0
        private void PrepareRequestSessions(CommandInfo commandInfo, TpmHandle[] inHandles)
        {
            if (OuterCommand != TpmCc.None)
            {
                // Nested commands must not use sessions
                return;
            }

            Debug.Assert(commandInfo.AuthHandleCountIn <= inHandles.Length);

            // Does the command require authorization and not all sessions are provided?
            if (!_Behavior.Strict && commandInfo.AuthHandleCountIn > Sessions.Length)
            {
                // Allocate missing sessions
                if (Sessions.Length == 0)
                {
                    Sessions = new SessionBase[commandInfo.AuthHandleCountIn];
                }
                else
                {
                    SessionBase[] explicitSessions = Sessions;
                    Sessions = new SessionBase[commandInfo.AuthHandleCountIn];
                    explicitSessions.CopyTo(Sessions, 0);
                }
            }

            if (Sessions.Length == 0)
            {
                return;
            }

            for (int i = 0; i < Sessions.Length; ++i)
            {
                SessionBase s = Sessions[i];

                // Is authorization for this handle explicitly suppressed?
                if (s == SessionBase.None)
                    continue;

                TpmHandle authHandle = null;
                if (i < commandInfo.AuthHandleCountIn)
                {
                    authHandle = inHandles[i];
                    switch (authHandle.handle)
                    {
                    case (uint)TpmRh.Owner:
                        authHandle.Auth = OwnerAuth;
                        break;
                    case (uint)TpmRh.Endorsement:
                        authHandle.Auth = EndorsementAuth;
                        break;
                    case (uint)TpmRh.Platform:
                        authHandle.Auth = PlatformAuth;
                        break;
                    case (uint)TpmRh.Lockout:
                        authHandle.Auth = LockoutAuth;
                        break;
                    default:
                        if (authHandle.GetType() == Ht.Pcr && PcrHandles != null)
                        {
                            int pcrId = (int)authHandle.GetOffset();
                            Debug.Assert(pcrId < PcrHandles.Length);
                            if (PcrHandles[pcrId] != null)
                            {
                                authHandle.Auth = PcrHandles[pcrId].Auth;
                            }
                        }
                        break;
                    }
                }

                if (SessionBase.IsPlaceholder(s))
                {
                    // Create missing session
                    if (s == SessionBase.Hmac ||
                        s == SessionBase.Default && _GetUnderlyingDevice().NeedsHMAC)
                    {
                        s = Sessions[i] = CancelSafeStartAuthSession(TpmSe.Hmac, TpmAlgId.Sha256);
                        // Stash away session object to flush it from TPM after the command completion
                        TempSessions.Add(Sessions[i]);
                    }
                    else
                    {
                        s = Sessions[i] = new Pwap(authHandle.Auth);
                    }
                }
                if (s.Handle != TpmRh.TpmRsPw && !_InitializeSession(s as AuthSession))
                {
                    // There are no session parameters associated with the session
                    // handle (e.g., when the session was created by other Tpm2 object).
                    throw new Exception("Wrong session handle");
                }
                s.AuthHandle = authHandle;
            }

            foreach (TpmHandle h in inHandles)
            {
                if (h.Name == null)
                {
                    byte[] name = null;
                    // Use try-catch to intercept possible TpmRc.Handle error.
                    try
                    {
                        switch (h.GetType())
                        {
                            case Ht.Transient:
                            case Ht.Persistent:
                            {
                                byte[] qualName = null;
                                ReadPublic(h, out name, out qualName);
                                break;
                            }
                            case Ht.NvIndex:
                            {
                                NvPublic pub = NvReadPublic(h, out name);
                                if (!pub.attributes.HasFlag(NvAttr.Written) ||
                                    (pub.attributes & (NvAttr.ClearStclear | NvAttr.Orderly)) != 0)
                                {
                                    TempNames.Add(h);
                                }
                                break;
                            }
                        }
                    }
                    catch (TpmException)
                    {
                        // Failed to read public part of the object. Leave its name empty.
                    }
                    h.Name = name;
                }
            }

            // Roll the nonces.
            RollNonces();

            // Determine if parameter encryption/decryption is necessary.
            PrepareParmEncryptionSessions();
        }