Example #1
0
 public TpmPolicyTicket(TpmPublic authorizingKey, byte[] policyRef, TpmSt ticketType)
     : base("")
 {
     AuthorizingKey = authorizingKey;
     PolicyRef      = Globs.CopyData(policyRef);
     TicketType     = ticketType;
 }
Example #2
0
        private void LogTestAttributes(TpmSt sessionTag, TpmCc command)
        {
            if (!TestCategorizer.CommandDefined(command))
            {
                return;
            }

            if (sessionTag.Equals(TpmSt.Null))
            {
                TestIsThreadSafe        = false;
                TestWithinMinTpmProfile = false;
                return;
            }

            bool threadSafe = TestCategorizer.GetThreadSafety(command);

            if (!threadSafe)
            {
                TestIsThreadSafe = false;
            }
            if (!TestCategorizer.InProfile0(command))
            {
                TestWithinMinTpmProfile = false;
                return;
            }
            // else is P0 command.  What privileges are needed?
            NecessaryPrivilege priv = TestCategorizer.GetNecessaryPrivileges(command);

            if (priv > MaximumPrivilege)
            {
                MaximumPrivilege = priv;
            }
        }
Example #3
0
 ///<param name = "the_tag">ticket structure tag</param>
 ///<param name = "the_hierarchy">the hierarchy of the object used to produce the ticket</param>
 ///<param name = "the_digest">This shall be the HMAC produced using a proof value of hierarchy.</param>
 public TkAuth(
 TpmSt the_tag,
 TpmHandle the_hierarchy,
 byte[] the_digest
 )
 {
     this.tag = the_tag;
     this.hierarchy = the_hierarchy;
     this.digest = the_digest;
 }
Example #4
0
 public TkAuth()
 {
     tag = new TpmSt();
     hierarchy = new TpmHandle();
     digest = new byte[0];
 }
Example #5
0
 ///<param name = "the_Tag">Command tag (sessions, or no sessions)</param>
 ///<param name = "the_CommandSize">Total command buffer length</param>
 ///<param name = "the_CommandCode">Command code</param>
 public CommandHeader(
 TpmSt the_Tag,
 uint the_CommandSize,
 TpmCc the_CommandCode
 )
 {
     this.Tag = the_Tag;
     this.CommandSize = the_CommandSize;
     this.CommandCode = the_CommandCode;
 }
Example #6
0
 public CommandHeader()
 {
     Tag = new TpmSt();
 }
Example #7
0
        public static void SplitResponse(
            byte[] response,
            uint numHandles,
            out TpmSt tag,
            out uint paramSize,
            out TpmRc responseCode,
            out TpmHandle[] handles,
            out SessionOut[] sessions,
            out byte[] responseParmsNoHandles,
            out byte[] responseParmsWithHandles)
        {
            var m = new Marshaller(response);
            tag = m.Get<TpmSt>();
            paramSize = m.Get<uint>();
            responseCode = m.Get<TpmRc>();
            // If error we only get the header
            if (responseCode != TpmRc.Success)
            {
                handles = new TpmHandle[0];
                sessions = new SessionOut[0];
                responseParmsNoHandles = new byte[0];
                responseParmsWithHandles = new byte[0];
                return;
            }

            handles = new TpmHandle[numHandles];
            for (int j = 0; j < numHandles; j++)
            {
                handles[j] = m.Get<TpmHandle>();
            }
            uint parmsEnd = m.GetValidLength();
            if (tag == TpmSt.Sessions)
            {
                var sessionOffset = m.Get<uint>();
                uint startOfParmsX = m.GetGetPos();
                parmsEnd = startOfParmsX + sessionOffset;
                m.SetGetPos(parmsEnd);
                var sessX = new List<SessionOut>();
                while (m.GetGetPos() < m.GetValidLength())
                {
                    var s = m.Get<SessionOut>();
                    sessX.Add(s);
                }
                sessions = sessX.ToArray();
                m.SetGetPos(startOfParmsX);
            }
            else
            {
                sessions = new SessionOut[0];
            }

            uint startOfParms = m.GetGetPos();
            uint parmsLength = parmsEnd - m.GetGetPos();

            // Get the response buf with no handles
            responseParmsNoHandles = new byte[parmsLength];
            Array.Copy(response, (int)startOfParms, responseParmsNoHandles, 0, (int)parmsLength);

            // Get the response buf with handles
            responseParmsWithHandles = new byte[parmsLength + numHandles * 4];
            Array.Copy(response, 10, responseParmsWithHandles, 0, (int)numHandles * 4);
            Array.Copy(response, (int)startOfParms, responseParmsWithHandles, (int)numHandles * 4, (int)parmsLength);
        }
Example #8
0
        /// <summary>
        /// Handles TPM response value.
        /// Converts the error code into a human-readable form, invokes callbacks and
        /// encapsulates error info into a .Net exception.
        /// </summary>
        /// <param name="responseTag"></param>
        /// <param name="responseParamSize"></param>
        /// <param name="resultCode"></param>
        /// <param name="inParms"></param>
        /// <returns></returns>
        // ReSharper disable once UnusedParameter.Local
        private bool ProcessError(TpmSt responseTag, uint responseParamSize,
                                  TpmRc resultCode, TpmStructureBase inParms)
        {
            string errorString;

            AssertExpectedResponsesValid();

            // Process TPM success case (both expected success, and unexpected success)
            if (resultCode == TpmRc.Success)
            {
                LastError = TpmRc.Success;
                if (IsSuccessExpected())
                {
                    return true;
                }
                // Else we have unexpectedly succeeded

                // If TolerateErrors is set, then no error indication is provided apart
                // from setting LastReponseCode (the caller must query to find that
                // the error does not match).
                if (TolerateErrors)
                {
                    return false;
                }
                // If there is an installed error handler invoke it.
                if (TheErrorHandler != null)
                {
                    TheErrorHandler(resultCode, ExpectedResponses);
                    return false;
                }
                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                if (ExpectedResponses.Length == 1)
                {
                    errorString = string.Format("Error {0} was expected but command {1} succeeded",
                                                ExpectedResponses[0],
                                                CurrentCommand);
                }
                else
                {
                    errorString = string.Format("Errors {{{0}}} were expected but command {1} succeeded",
                                                string.Join(", ", ExpectedResponses),
                                                CurrentCommand);
                }

                _ClearCommandContext();
                throw new TssException(errorString);
            }
            // Else we have an error
            if (responseTag != TpmSt.NoSessions)
            {
                throw new Exception("Ill-formed responseTag (not NoSessions)");
            }
            if (responseParamSize != 10)
            {
                throw new Exception("Ill-formed reponseParamSize (not 10)");
            }

            // There are two encodings for errors - format 0 and format 1.
            var resultCodeValue = (uint)resultCode;
            bool formatOneErrorType = TpmErrorHelpers.IsFmt1(resultCode);

            // Extract the actual error number
            LastError = TpmErrorHelpers.ErrorNumber(resultCode);

            string errorEntity = "Unknown";
            uint errorEntityIndex = 0;
            string errorParmName = "Unknown";
            if (formatOneErrorType)
            {
                errorEntityIndex = (resultCodeValue & 0xF00U) >> 8;
                if ((resultCodeValue & 0x40) != 0)
                {
                    errorEntity = "Parameter";
                    errorParmName = GetParmName(inParms.GetType(), errorEntityIndex);
                }
                else
                {
                    if (errorEntityIndex >= 8)
                    {
                        errorEntityIndex -= 8;
                        errorEntity = "Session";
                    }
                    else
                    {
                        errorEntity = "Handle";
                    }
                }
            }
            string errorDetails = FormatString("\r\n" +
                                               "Details: \n" +
                                               "[Code=TpmRc.{0}],"+
                                               "[RawCode=0x{1:X},{1}]\n" +
                                               "[ErrorEntity={2}], [ParmNum={3}]\n" +
                                               "[ParmName={4}]",
                                               new Object[] {
                                                   LastError.ToString(), 
                                                   resultCodeValue,
                                                   errorEntity,
                                                   errorEntityIndex,
                                                   errorParmName
                                               });
            // We have found out all we can about the error.  Now process it according to the tpm context

            // AllowErrors() specifies that errors should be handled silently
            if ((OuterCommand == TpmCc.None && IsErrorAllowed(LastError)) ||
                (OuterCommand != TpmCc.None && LastError == TpmRc.Canceled))
            {
                return false;
            }

            if (OuterCommand != TpmCc.None || ExpectedResponses == null)
            {
                errorString = string.Format("Error {{{0}}} was returned for command {1}.",
                                            LastError, CurrentCommand);
            }
            else
            {
                errorString = string.Format("Error {{{0}}} was returned instead of {{{1}}} for command {2}.",
                                            LastError,
                                            string.Join(", ", ExpectedResponses),
                                            CurrentCommand);
            }

            if (AreErrorsExpected())
            {
                // We have a mismatched error. If a warning handler is installed, call it.
                if (TheWarningHandler != null)
                {
                    TheWarningHandler(errorString);
                    _ClearCommandContext();
                    return false;
                }
            }

            // Otherwise propagate the unexpected error as an exception
            _ClearCommandContext();
            errorString += errorDetails;
            throw new TpmException(resultCode, errorString);
        }
Example #9
0
 public TpmPolicyTicket(TpmPublic authorizingKey, byte[] policyRef, TpmSt ticketType) : base("")
 {
     AuthorizingKey = authorizingKey;
     PolicyRef = Globs.CopyData(policyRef);
     TicketType = ticketType;
 }
Example #10
0
        // This is installed as the raw command callback handler on the underlying TPM.
        // It is used to generate low-level test statistics (number of commands executed,
        // etc.), dumps of the conversation with the TPM and to keep a record of all
        // command sequences seen that contain types that we haven't seen before.
        // In the case of a multi-context TPM this will be called on different threads,
        // but locking should be handled safely by MainTestLogger.
        void ICommandCallbacks.PostCallback(byte[] inBuf, byte[] outBuf)
        {
            TimeSpan cmdExecutionTime = DateTime.Now - CurCmdStartTime;

            if (inBuf.Length < 10)
            {
                return;
            }
            Marshaller m           = new Marshaller(inBuf);
            TpmSt      sessionTag  = m.Get <TpmSt>();
            uint       parmSize    = m.Get <UInt32>();
            TpmCc      commandCode = m.Get <TpmCc>();

            if (commandCode == TpmCc.Clear)
            {
                ClearWasExecuted = true;
            }

            Marshaller mOut              = new Marshaller(outBuf);
            TpmSt      responseTag       = mOut.Get <TpmSt>();
            uint       responseParamSize = mOut.Get <uint>();
            TpmRc      responseCode      = mOut.Get <TpmRc>();

            if (ValidateTestAttributes)
            {
                // ValidateTestAttributes should not be set for a stress run
                LogTestAttributes(sessionTag, commandCode);
                try
                {
                    if (responseCode == TpmRc.Success)
                    {
                        ValidateHandleUsage(commandCode, inBuf);
                    }
                }
                catch (Exception)
                {
                    // Invalid command buffer can mess this up
                }
            }

            if (sessionTag.Equals(TpmSt.Null))
            {
                return;
            }

            // There are two encoding for errors - formats 0 and 1. Decode the error type
            uint resultCodeValue    = (uint)responseCode;
            bool formatOneErrorType = ((resultCodeValue & 0x80) != 0);
            uint resultCodeMask     = formatOneErrorType ? 0xBFU : 0x97FU;

            TpmRc maskedError = (TpmRc)((uint)responseCode & resultCodeMask);

            lock (this)
            {
                // log the command info to the test logger so that it can collect stats
                LogCommandExecution(commandCode, maskedError, cmdExecutionTime);
            }

#if false
            // Keep a copy of successfully executed commands that contain types we have
            // not seen so far. This is for tests that need good-command candidate strings,
            // like TestCommandDispatcherCoverage.
            // Code 0x80280400 is returned by TBS when the command is blocked by Windows.
            if (maskedError == TpmRc.Success && !Tpm2.IsTbsError(resultCodeValue))
            {
                // look at all types in command string.  If we have a new type we keep it
                CrackedCommand cc   = CommandProcessor.CrackCommand(inBuf);
                CommandInfo    info = CommandInformation.Info.First(x =>
                                                                    x.CommandCode == cc.Header.CommandCode);
                byte[] inStructBytes = Globs.Concatenate(
                    Globs.GetZeroBytes((int)info.HandleCountIn * 4),
                    cc.CommandParms);
                Marshaller mx = new Marshaller(inStructBytes);

                TpmStructureBase bb = (TpmStructureBase)mx.Get(info.InStructType, "");

                // If a new type is contained, save this command for testing in
                // TestDispatcherCoverage.
                if (HasNewTypes(bb))
                {
                    ExecutedCommandInfo.Add(inBuf);
                }
            }
            else
#else
            if (maskedError != TpmRc.Success)
#endif
            {
                // If a command failed, we can get here only if the corresponding
                // expected error assertion was specified.
                ++NumAsserts;
            }
            ReportProgress();

            // output TPM IO to a text file for later processing
            if (Logger.LogTpmIo)
            {
                while (TpmIoWriter == null)
                {
                    try
                    {
                        string ioLogPath;
                        if (Logger.LogPath != null)
                        {
                            ioLogPath = System.IO.Path.Combine(Logger.LogPath, "tpm_io.txt");
                        }
                        else
                        {
                            string fileName;
                            lock (this)
                            {
                                fileName = "tpm_io-" + DateTime.Now.ToString("yyyy-MMM-dd-HH");
                                if (PrevLogName == fileName)
                                {
                                    fileName += "(" + ++PrevLogInstance + ")";
                                }
                                else
                                {
                                    PrevLogName     = fileName;
                                    PrevLogInstance = 1;
                                }
                            }
                            fileName += ".txt";

#if TSS_MIN_API
                            ioLogPath = fileName;
#else
                            string docsPath = Environment.GetFolderPath(
                                Environment.SpecialFolder.MyDocuments);
                            ioLogPath = System.IO.Path.Combine(docsPath, fileName);
#endif
                        }

                        TpmIoWriter = new StreamWriter(new FileStream(ioLogPath,
                                                                      FileMode.Create));
                        Logger.WriteToLog("Dumping TPM I/O to " + ioLogPath);
                    }
                    catch (Exception e)
                    {
                        string message = "Failed to open the tpm_io.txt file for writing.\n" +
                                         "Error: " + e.Message;
                        Logger.WriteErrorToLog(message);
                    }
                }

                // get the test source code line that initiated the command
                string caller = "unknown";
#if !TSS_NO_STACK
                StackTrace   trace      = new StackTrace(true);
                StackFrame[] frames     = trace.GetFrames();
                int          frameCount = frames.Length;
                StackFrame   f          = null;
                // start at 1 to not count the currently executing function
                for (int j = 1; j < frameCount; j++)
                {
                    f = frames[j];
                    if (f.GetMethod().DeclaringType.Assembly == Logger.TestAssembly)
                    {
                        caller = f.GetFileName() + ":" + f.GetFileLineNumber();
                        break;
                    }
                }
#endif
                string commandCodeString = Enum.GetName(typeof(TpmCc), commandCode);
                string inString          = "{MALFORMED COMMAND BUFFER}";
                string outString         = "{MALFORMED RESPONSE BUFFER}";

                try { inString = CommandProcessor.ParseCommand(inBuf); }
                catch (Exception) { }
                try { outString = CommandProcessor.ParseResponse(commandCodeString, outBuf); }
                catch (Exception) { }

                lock (this)
                {
                    TpmIoWriter.WriteLine(commandCode);
                    TpmIoWriter.WriteLine(caller);

                    TpmIoWriter.WriteLine(">>>> Raw input");
                    TpmIoWriter.WriteLine(Globs.HexFromByteArray(inBuf));
                    TpmIoWriter.WriteLine(">>>> Raw output");
                    TpmIoWriter.WriteLine(Globs.HexFromByteArray(outBuf));

                    TpmIoWriter.WriteLine(">>>> Parsed input");
                    TpmIoWriter.WriteLine(inString);
                    TpmIoWriter.WriteLine(">>>> Parsed output");
                    TpmIoWriter.WriteLine(outString);

                    TpmIoWriter.WriteLine("-----------------------------------------");
                    TpmIoWriter.Flush();
                }
            }

            if (ChainedCallbacks != null)
            {
                ChainedCallbacks.PostCallback(inBuf, outBuf);
            }
        } // ICommandCallbacks.PostCallback
Example #11
0
 public TkAuth()
 {
     tag = new TpmSt();
     hierarchy = new TpmHandle();
     digest = null;
 }
Example #12
0
 public CommandHeader()
 {
     Tag = new TpmSt();
     CommandSize = 0;
     CommandCode = new TpmCc();
 }