Exemple #1
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