internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { TpmCc commandCode = 0; if (TicketType == TpmSt.AuthSecret) { commandCode = TpmCc.PolicySecret; } else if (TicketType == TpmSt.AuthSigned) { commandCode = TpmCc.PolicySigned; } else { Globs.Throw <ArgumentException>("Ticket type is not recognized"); return(new TpmHash(hashAlg)); } if (ObjectName == null) { ObjectName = AuthorizingKey.GetName(); } var m = new Marshaller(); m.Put(commandCode, "ordinal"); m.Put(ObjectName, "name"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes()).Extend(PolicyRef)); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(TpmCc.PolicyNameHash, "commandCod"); m.Put(NameHash, "hashData"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(TpmCc.PolicyLocality, "ordinal"); m.Put(AllowedLocality, "locality"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(TpmCc.PolicyCommandCode, "ordinal"); m.Put(AllowedCommand, "allowedCommand"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(TpmCc.PolicyPCR, "ordinal"); m.Put(Pcrs.GetTpmlPcrSelection(), "selection"); m.Put(Pcrs.GetSelectionHash(hashAlg).HashData, "pcrs"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
/// <summary> /// Implements the first step of the policy digest update (see the PolicyUpdate() /// method), and also used by PolicyAuthorizeNV. /// </summary> internal TpmHash PolicyUpdate1(TpmHash currentHash, TpmCc commandCode, byte[] name) { var m = new Marshaller(); m.Put(commandCode, "commandCode"); m.Put(name, "name"); return(currentHash.Extend(m.GetBytes())); }
/// <summary> /// Create a 10 byte error response that matches TPM error responses. /// </summary> /// <param name="errorCode"></param> /// <returns></returns> private byte[] FormatError(TpmRc errorCode) { var m = new Marshaller(); m.Put(TpmSt.NoSessions, ""); m.Put((uint)10, ""); m.Put(errorCode, ""); return(m.GetBytes()); }
/// <summary> /// This is a formatting helper to help callbacks create a properly formed hash to sign. /// </summary> /// <returns></returns> public static byte[] GetDataStructureToSign(int expirationTime, byte[] nonceTpm, byte[] cpHash, byte[] policyRef) { var dataToSign = new Marshaller(); dataToSign.Put(nonceTpm, ""); dataToSign.Put(expirationTime, ""); dataToSign.Put(cpHash, ""); dataToSign.Put(policyRef, ""); return(dataToSign.GetBytes()); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(TpmCc.PolicyNvWritten, "ordinal"); byte writtenName = IsNvIndexRequiredToHaveBeenWritten ? (byte)1 : (byte)0; m.Put(writtenName, "writtenSet"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
internal override void ToNet(Marshaller m) { if (CryptoLib.DigestSize(HashAlg) != HashData.Length) { if (!Tpm2._TssBehavior.Passthrough) { throw new Exception("Hash data length does not match the algorithm"); } } m.Put(HashAlg, "HashAlg"); m.Put(HashData, "HashData"); }
internal override void ToNet(Marshaller m) { if (Algorithm == TpmAlgId.Xor) { Globs.Throw <NotImplementedException>("SymDefObject.ToNet: XOR is not supported"); } m.Put(Algorithm, "algorithm"); if (Algorithm == TpmAlgId.None || Algorithm == TpmAlgId.Null) { return; } m.Put(KeyBits, "keyBits"); m.Put(Mode, "mode"); }
internal override TpmRc Execute(Tpm2 tpm, AuthSession sess, PolicyTree policy) { byte[] nonceTpm = UseNonceTpm ? Globs.CopyData(sess.NonceTpm) : new byte[0]; TpmHandle sigKey; // If we have both the authorizing signature and the corresponding // signing key handle, we are good to go. if (AuthSig == null) { var dataToSign = new Marshaller(); dataToSign.Put(nonceTpm, ""); // If we have a signing key we can build the challenge here // (else we need to call out) if (SwSigningKey != null) { dataToSign.Put(ExpirationTime, ""); dataToSign.Put(CpHash, ""); dataToSign.Put(PolicyRef, ""); // Just ask the key to sign the challenge AuthSig = SwSigningKey.Sign(dataToSign.GetBytes()); sigKey = tpm.LoadExternal(null, SigningKeyPub, TpmRh.Owner); } else { TpmPublic verifier; AuthSig = AssociatedPolicy.ExecuteSignerCallback(this, nonceTpm, out verifier); sigKey = tpm.LoadExternal(null, verifier, TpmRh.Owner); } } else { sigKey = tpm.LoadExternal(null, SigningKeyPub, TpmRh.Owner); } Timeout = tpm.PolicySigned(sigKey, sess, nonceTpm, CpHash, PolicyRef, ExpirationTime, AuthSig, out Ticket); TpmRc responseCode = tpm._GetLastResponseCode(); tpm.FlushContext(sigKey); if (!KeepAuth) { AuthSig = null; } return(responseCode); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(OperandB, "operandB"); m.Put(Offset, "offset"); m.Put(Operation, "operation"); byte[] args = CryptoLib.HashData(hashAlg, m.GetBytes()); m = new Marshaller(); m.Put(TpmCc.PolicyNV, "ord"); m.Put(args, "args"); m.Put(IndexName, "name"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(OperandB, "operandB"); m.Put(Offset, "offset"); m.Put(Operation, "operation"); byte[] toHash = m.GetBytes(); byte[] args = CryptoLib.HashData(hashAlg, toHash); m = new Marshaller(); m.Put(TpmCc.PolicyCounterTimer, "cc"); m.Put(args, "args"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { var m = new Marshaller(); m.Put(TpmCc.PolicyDuplicationSelect, "ordinal"); if (IncludeObjectNameInPolicyHash) { m.Put(DupObjectName, "objectName"); } m.Put(NewParentName, "newParent"); byte includeName = IncludeObjectNameInPolicyHash ? (byte)1 : (byte)0; m.Put(includeName, "includeObject"); return(GetNextAcePolicyDigest(hashAlg).Extend(m.GetBytes())); }
internal override void ToNet(Marshaller m) { if (Algorithm == TpmAlgId.Xor) { if (!Tpm2._TssBehavior.Passthrough) { throw new Exception("Unsupported symmetric algorithm"); } } m.Put(Algorithm, "algorithm"); if (Algorithm == TpmAlgId.None || Algorithm == TpmAlgId.Null) { return; } m.Put(KeyBits, "keyBits"); m.Put(Mode, "mode"); }
public static byte[] GetTpmRepresentation(params Object[] theObjects) { var m = new Marshaller(); foreach (Object o in theObjects) { m.Put(o, null); } return(m.GetBytes()); }
internal override TpmHash GetPolicyDigest(TpmAlgId hashAlg) { int numBranches = PolicyBranches.Count; if (numBranches < 2 || numBranches > 8) { Globs.Throw("GetPolicyDigest: Must have between 2 and 8 branches in a PolicyOr"); } var m = new Marshaller(); m.Put(TpmHash.ZeroHash(hashAlg).HashData, "zero"); m.Put(TpmCc.PolicyOR, "ordinal"); foreach (PolicyAce branch in PolicyBranches) { TpmHash branchPolicyHash = branch.GetPolicyDigest(hashAlg); m.Put(branchPolicyHash.HashData, "h"); } return(TpmHash.FromData(hashAlg, m.GetBytes())); }
internal override void ToNet(Marshaller m) { m.Put(Algorithm, "algorithm"); switch (Algorithm) { case TpmAlgId.None: case TpmAlgId.Null: return; case TpmAlgId.Xor: m.Put(Mode, "hash"); break; case TpmAlgId.Aes: m.Put(KeyBits, "keyBits"); m.Put(Mode, "mode"); break; default: if (Tpm2._TssBehavior.Passthrough) { m.Put(KeyBits, "keyBits"); m.Put(Mode, "mode"); break; } else { throw new NotImplementedException(); } } }
internal override void ToNet(Marshaller m) { m.Put(Algorithm, "algorithm"); switch (Algorithm) { case TpmAlgId.None: case TpmAlgId.Null: return; case TpmAlgId.Xor: m.Put(Mode, "hash"); break; case TpmAlgId.Aes: case TpmAlgId.Tdes: m.Put(KeyBits, "keyBits"); m.Put(Mode, "mode"); break; default: Globs.Throw <NotImplementedException>("SymDef.ToNet: Unknown algorithm"); m.Put(KeyBits, "keyBits"); m.Put(Mode, "mode"); break; } }
internal static byte[] GetKeyBlob(byte[] x, byte[] y, TpmAlgId alg, bool isEcdh, EccCurve curve) { var m = new Marshaller(); byte[] magic = BitConverter.GetBytes(MagicFromTpmAlgId(alg, isEcdh, curve, true)); m.Put(magic, ""); int keyBits = GetKeyLength(curve); int keySizeBytes = (keyBits + 7) / 8; if (x.Length != keySizeBytes || y.Length != keySizeBytes) { throw new Exception("Badly formed ECC key"); } var size = Globs.ReverseByteOrder(Globs.HostToNet(keySizeBytes)); m.Put(size, "len"); m.Put(x, "x"); m.Put(y, "y"); var res = m.GetBytes(); return(res); }
/// <summary> /// Get the hash of the concatenation of the values in the array order defined by the PcrSelection[] /// returned from GetPcrSelectionArray. /// </summary> /// <param name="hashAlg"></param> /// <returns></returns> public TpmHash GetSelectionHash(TpmAlgId hashAlg) { var m = new Marshaller(); PcrSelection[] selections = GetPcrSelectionArray(); foreach (PcrSelection sel in selections) { uint[] pcrIndices = sel.GetSelectedPcrs(); foreach (uint index in pcrIndices) { PcrValue v = GetSpecificValue(sel.hash, index); m.Put(v.value.HashData, "hash"); } } var valueHash = new TpmHash(hashAlg, CryptoLib.HashData(hashAlg, m.GetBytes())); return(valueHash); }
/// <summary> /// Implements marshaling logic for most of the TPM object types. /// Can be overridden if a custom marshaling logic is required (e.g. when /// marshaling of a field depends on other field's value). /// </summary> /// <param name="m"></param> /// <returns></returns> internal virtual void ToNet(Marshaller m) { var members = GetFieldsToMarshal(); dbg.Indent(); for (int i = 0; i < members.Length; ++i) { var mem = members[i]; object memVal = Globs.GetMember(mem, this); dbg.Trace(i + ": " + mem.Name + " = " + memVal); if (mem.SizeLength > 0) { bool arr = mem.WireType == MarshalType.VariableLengthArray; int len = arr ? (memVal == null ? 0 : ((Array)memVal).Length) : Marshaller.GetTpmRepresentation(memVal).Length; dbg.Trace("Sending " + (arr ? "Array " : "Struct ") + mem.Name + " of size " + len); m.PutSizeTag(len, mem.SizeLength, mem.SizeName); } m.Put(memVal, mem.Name); } dbg.Unindent(); }
/// <summary> // Verify that a TPM quote matches an expect PCR selection, is well formed, // and is properly signed. In acse of failure this overload additionally // returns information about the specific check that failed. /// </summary> /// <param name="pcrDigestAlg"></param> /// <param name="expectedSelectedPcr"></param> /// <param name="expectedPcrValues"></param> /// <param name="nonce"></param> /// <param name="quotedInfo"></param> /// <param name="signature"></param> /// <param name="pointOfFailure"></param> /// <param name="qualifiedNameOfSigner"></param> /// <returns></returns> public bool VerifyQuote(TpmAlgId pcrDigestAlg, PcrSelection[] expectedSelectedPcr, Tpm2bDigest[] expectedPcrValues, byte[] nonce, Attest quotedInfo, ISignatureUnion signature, out QuoteElt pointOfFailure, byte[] qualifiedNameOfSigner = null) { pointOfFailure = QuoteElt.None; if (!(quotedInfo.attested is QuoteInfo)) { pointOfFailure = QuoteElt.Type; return(false); } if (quotedInfo.magic != Generated.Value) { pointOfFailure = QuoteElt.Magic; return(false); } if (!quotedInfo.extraData.IsEqual(nonce)) { pointOfFailure = QuoteElt.ExtraData; return(false); } // Check environment of signer (name) is expected if (qualifiedNameOfSigner != null && !quotedInfo.qualifiedSigner.IsEqual(qualifiedNameOfSigner)) { pointOfFailure = QuoteElt.QualifiedSigner; return(false); } // Now check the quote-specific fields var quoted = (QuoteInfo)quotedInfo.attested; // Check values pcr indices are what we expect if (!Globs.ArraysAreEqual(quoted.pcrSelect, expectedSelectedPcr)) { pointOfFailure = QuoteElt.PcrSelect; return(false); } // Check that values in the indices above are what we expect // ReSharper disable once UnusedVariable var expected = new PcrValueCollection(expectedSelectedPcr, expectedPcrValues); var m = new Marshaller(); foreach (Tpm2bDigest d in expectedPcrValues) { m.Put(d.buffer, ""); } TpmHash expectedPcrHash = TpmHash.FromData(pcrDigestAlg, m.GetBytes()); if (!Globs.ArraysAreEqual(expectedPcrHash, quoted.pcrDigest)) { pointOfFailure = QuoteElt.PcrDigest; return(false); } // And finally check the signature if (!VerifySignatureOverData(quotedInfo.GetTpmRepresentation(), signature)) { pointOfFailure = QuoteElt.Signature; return(false); } return(true); }