// Returns reference to the byte buffer containing unique value of inPub. // Note that in case of ECC keys, the returned buffer references only the // first half of the unique value (i.e. x-coordinate of the ECC point). public static FieldInfo GetUniqueBuffer(TpmPublic pub, out byte[] buf) { var keyType = pub.parameters.GetUnionSelector(); buf = null; switch (keyType) { case TpmAlgId.Rsa: buf = (pub.unique as Tpm2bPublicKeyRsa).buffer; return(pub.unique.GetType().GetField("buffer")); case TpmAlgId.Ecc: buf = (pub.unique as EccPoint).x; return(pub.unique.GetType().GetField("x")); case TpmAlgId.Symcipher: case TpmAlgId.Keyedhash: buf = (pub.unique as Tpm2bDigest).buffer; return(pub.unique.GetType().GetField("buffer")); } Globs.Throw <NotImplementedException>( "GetUniqueBuffer: Unknown TpmPublic type " + keyType); return(null); }
// Returns the ratio of a TPM clock second to one system time second public static double MeasureClockRate(Tpm2 tpm) { const int MaxIter = 20; int NumSamplesPerIter = 5; int N = NumSamplesPerIter, L = 0; double[] tpmTimes = null; double[] sysTimes = null; double[] newTpmTimes = new double[N]; double[] newSysTimes = new double[N]; int iter = 0; double stdDevSys = 0, meanSys = 0, stdDevTpm = 0, meanTpm = 0; int n = 0; double sysTime = 0, tpmTime = 0; do { tpmTimes = newTpmTimes; sysTimes = newSysTimes; TimeInfo tpmStart = null; DateTime sysStart = DateTime.MinValue; for (int i = L; i <= N; i++) { TimeInfo tpmStop = tpm.ReadClock(); DateTime sysStop = DateTime.Now; if (tpmStart != null) { tpmTimes[i - 1] = tpmStop.time - tpmStart.time; sysTimes[i - 1] = (sysStop - sysStart).TotalMilliseconds; } tpmStart = tpmStop; sysStart = sysStop; Thread.Sleep(600); } // Eliminate outliers that may be caused by the current thread having // been preempted at a "wrong" point causing the measured rate distortion. meanSys = meanTpm = stdDevSys = stdDevTpm = sysTime = tpmTime = 0; for (int i = 0; i < N; i++) { meanSys += sysTimes[i]; meanTpm += tpmTimes[i]; } meanSys /= N; meanTpm /= N; for (int i = 0; i < N; i++) { double d = (sysTimes[i] - meanSys); stdDevSys += d * d; d = (tpmTimes[i] - meanTpm); stdDevTpm += d * d; } stdDevSys = Math.Sqrt(stdDevSys / N); stdDevTpm = Math.Sqrt(stdDevTpm / N); bool imprecise = stdDevSys / meanSys > 0.03 || stdDevTpm / meanTpm > 0.03; if (imprecise) { newTpmTimes = new double[N + NumSamplesPerIter]; newSysTimes = new double[N + NumSamplesPerIter]; } n = 0; for (int i = 0; i < N; i++) { if (Math.Abs(sysTimes[i] - meanSys) < 2 * stdDevSys && Math.Abs(tpmTimes[i] - meanTpm) < 2 * stdDevTpm) { sysTime += sysTimes[i]; tpmTime += tpmTimes[i]; if (imprecise) { newSysTimes[n] = sysTimes[i]; newTpmTimes[n] = tpmTimes[i]; } ++n; } //else Console.Write("Dropped[{0}] = {1} ", i, sysTimes[i]); } if (!imprecise && n > 2) { break; } L = n; N = L + NumSamplesPerIter; } while (++iter < MaxIter); if (iter == MaxIter) { Globs.Throw("The system is likely overloaded. Cannot do reliable time measurements."); } //Console.WriteLine("ITER {0}, MEAN {1:F0}->{2:F0}, SD {3:F1}; Good {4}; RATE {5:F2}", // iter+1, meanSys, sysTime / n, stdDevSys, n, tpmTime / sysTime); return(tpmTime / sysTime); } // MeasureClockRate()