/// <summary> /// Returns true if the two ECC points are equal, i.e. if both coordinates /// are pairwise equal. /// </summary> /// <param name="lhs">Left hand side operand</param> /// <param name="rhs">Right hand side operand</param> public static bool operator ==(EccPoint lhs, EccPoint rhs) { return((object)lhs == null ? (object)rhs == null : (object)rhs != null && Globs.ArraysAreEqual(lhs.x, rhs.x) && Globs.ArraysAreEqual(lhs.y, rhs.y)); }
/// <summary> /// De-envelope inner-wrapped duplication blob. /// TODO: Move this to TpmPublic and make it fully general /// </summary> /// <param name="exportedPrivate"></param> /// <param name="encAlg"></param> /// <param name="encKey"></param> /// <param name="nameAlg"></param> /// <param name="name"></param> /// <returns></returns> public static Sensitive SensitiveFromDuplicateBlob(TpmPrivate exportedPrivate, SymDefObject encAlg, byte[] encKey, TpmAlgId nameAlg, byte[] name) { byte[] dupBlob = exportedPrivate.buffer; byte[] sensNoLen; using (SymmCipher c = Create(encAlg, encKey)) { byte[] innerObject = c.Decrypt(dupBlob); byte[] innerIntegrity, sensitive; KDF.Split(innerObject, 16 + CryptoLib.DigestSize(nameAlg) * 8, out innerIntegrity, 8 * (innerObject.Length - CryptoLib.DigestSize(nameAlg) - 2), out sensitive); byte[] expectedInnerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData(nameAlg, sensitive, name)); if (!Globs.ArraysAreEqual(expectedInnerIntegrity, innerIntegrity)) { Globs.Throw("SensitiveFromDuplicateBlob: Bad inner integrity"); } sensNoLen = Marshaller.Tpm2BToBuffer(sensitive); } var sens = Marshaller.FromTpmRepresentation <Sensitive>(sensNoLen); return(sens); }
/// <summary> /// Verify that quotedInfo is properly signed by an associated private key /// holder, and that the quotedInfo.type, .extraData and .magic are correct. /// Also check that the certified name is what the caller expects. The caller /// must check other fields (for instance the qualified name) /// </summary> /// <param name="name"></param> /// <param name="nonce"></param> /// <param name="quotedInfo"></param> /// <param name="expectedName"></param> /// <param name="signature"></param> /// <returns></returns> public bool VerifyCertify(TpmHash name, byte[] nonce, Attest quotedInfo, byte[] expectedName, ISignatureUnion signature) { // Check generic signature stuff if (quotedInfo.type != TpmSt.AttestCertify) { return(false); } if (!Globs.ArraysAreEqual(quotedInfo.extraData, nonce)) { return(false); } if (quotedInfo.magic != Generated.Value) { return(false); } // Check specific certify-signature stuff var certInfo = (CertifyInfo)quotedInfo.attested; if (!Globs.ArraysAreEqual(expectedName, certInfo.name)) { return(false); } // Check the actual signature TpmHash sigHash = TpmHash.FromData(TpmAlgId.Sha1, quotedInfo.GetTpmRepresentation()); bool certifyOk = VerifySignatureOverHash(sigHash, signature); return(certifyOk); }
/// <summary> /// Returns true if the two hashes are equal, i.e. if both hash algorithms and /// digests are the same. When this operator is used to compare a hash object /// with a byte buffer representing digest, the latter is converted to a hash /// object with its hash algorithm set to null, which excludes the algorithms /// from comparison). /// </summary> /// <param name="lhs">Left hand side operand</param> /// <param name="rhs">Right hand side operand</param> /// <returns></returns> public static bool operator ==(TpmHash lhs, TpmHash rhs) { return((object)lhs == null ? (object)rhs == null : (object)rhs != null && (lhs._HashAlg == TpmAlgId.None || rhs._HashAlg == TpmAlgId.None || lhs._HashAlg == rhs._HashAlg) && Globs.ArraysAreEqual(lhs._HashData, rhs._HashData)); }
public override bool Equals(Object obj) { if (obj == null || this.GetType() != obj.GetType()) { return(false); } byte[] b0 = this.GetTpmRepresentation(), b1 = ((TpmStructureBase)obj).GetTpmRepresentation(); return(Globs.ArraysAreEqual(b0, b1)); }
void Init(RSAParameters rsaParams, int numBits) { NumBits = numBits; E = FromBigEndian(rsaParams.Exponent); N = FromBigEndian(rsaParams.Modulus); Debug.Assert(Globs.ArraysAreEqual(ToBigEndian(N.ToByteArray()), rsaParams.Modulus)); if (rsaParams.P != null) { D = FromBigEndian(rsaParams.D); P = FromBigEndian(rsaParams.P); Q = FromBigEndian(rsaParams.Q); InverseQ = FromBigEndian(rsaParams.InverseQ); DP = FromBigEndian(rsaParams.DP); DQ = FromBigEndian(rsaParams.DQ); } }
/// <summary> /// Create an enveloped (encrypted and integrity protected) private area from a provided sensitive. /// </summary> /// <param name="iv"></param> /// <param name="sens"></param> /// <param name="nameHash"></param> /// <param name="publicName"></param> /// <param name="symWrappingAlg"></param> /// <param name="symKey"></param> /// <param name="parentNameAlg"></param> /// <param name="parentSeed"></param> /// <param name="f"></param> /// <returns></returns> public static byte[] CreatePrivateFromSensitive( SymDefObject symWrappingAlg, byte[] symKey, byte[] iv, Sensitive sens, TpmAlgId nameHash, byte[] publicName, TpmAlgId parentNameAlg, byte[] parentSeed, TssObject.Transformer f = null) { // ReSharper disable once InconsistentNaming byte[] tpm2bIv = Marshaller.ToTpm2B(iv); Transform(tpm2bIv, f); byte[] sensitive = sens.GetTpmRepresentation(); Transform(sensitive, f); // ReSharper disable once InconsistentNaming byte[] tpm2bSensitive = Marshaller.ToTpm2B(sensitive); Transform(tpm2bSensitive, f); byte[] encSensitive = SymCipher.Encrypt(symWrappingAlg, symKey, iv, tpm2bSensitive); Transform(encSensitive, f); byte[] decSensitive = SymCipher.Decrypt(symWrappingAlg, symKey, iv, encSensitive); Debug.Assert(f != null || Globs.ArraysAreEqual(decSensitive, tpm2bSensitive)); var hmacKeyBits = CryptoLib.DigestSize(parentNameAlg) * 8; byte[] hmacKey = KDF.KDFa(parentNameAlg, parentSeed, "INTEGRITY", new byte[0], new byte[0], hmacKeyBits); Transform(hmacKey, f); byte[] dataToHmac = Marshaller.GetTpmRepresentation(tpm2bIv, encSensitive, publicName); Transform(dataToHmac, f); byte[] outerHmac = CryptoLib.Hmac(parentNameAlg, hmacKey, dataToHmac); Transform(outerHmac, f); byte[] priv = Marshaller.GetTpmRepresentation(Marshaller.ToTpm2B(outerHmac), tpm2bIv, encSensitive); Transform(priv, f); return(priv); }
public bool PkcsVerify(byte[] m, byte[] s, TpmAlgId hashAlg) { if (s.Length != KeySize) { throw new Exception("Invalid signature"); } int k = KeySize; BigInteger sig = FromBigEndian(s); BigInteger emx = BigInteger.ModPow(sig, E, N); byte[] emDecrypted = ToBigEndian(emx, KeySize); byte[] emPrime = CryptoEncoders.Pkcs15Encode(m, k, hashAlg); if (!Globs.ArraysAreEqual(emPrime, emDecrypted)) { return(false); } return(true); }
/// <summary> /// PSS verify. Note: we expect the caller to do the hash. /// </summary> /// <param name="m"></param> /// <param name="em"></param> /// <param name="sLen"></param> /// <param name="emBits"></param> /// <param name="hashAlg"></param> /// <returns></returns> public static bool PssVerify(byte[] m, byte[] em, int sLen, int emBits, TpmAlgId hashAlg) { var emLen = (int)Math.Ceiling(1.0 * emBits / 8); int hLen = CryptoLib.DigestSize(hashAlg); // 1 - Skip // 2 byte[] mHash = TpmHash.FromData(hashAlg, m); // 3 if (emLen < hLen + sLen + 2) { return(false); } // 4 if (em[em.Length - 1] != 0xbc) { return(false); } // 5 byte[] maskedDB = Globs.CopyData(em, 0, emLen - hLen - 1); byte[] h = Globs.CopyData(em, emLen - hLen - 1, hLen); // 6 int numZeroBits = 8 * emLen - emBits; // First numZero bits is zero in mask byte mask = GetByteMask(numZeroBits); if ((maskedDB[0] & mask) != maskedDB[0]) { return(false); } // 7 byte[] dbMask = CryptoLib.MGF(h, emLen - hLen - 1, hashAlg); // 8 byte[] db = XorEngine.Xor(maskedDB, dbMask); // 9 int numZeroBits2 = 8 * emLen - emBits; byte mask2 = GetByteMask(numZeroBits2); db[0] &= mask2; // 10 for (int j = 0; j < emLen - hLen - sLen - 2; j++) { if (db[j] != 0) { return(false); } } if (db[emLen - hLen - sLen - 1 - 1] != 1) { return(false); } // 11 byte[] salt = Globs.CopyData(db, db.Length - sLen); // 12 byte[] mPrime = Globs.Concatenate(new[] { Globs.ByteArray(8, 0), mHash, salt }); // 13 byte[] hPrime = TpmHash.FromData(hashAlg, mPrime); // 14 bool match = Globs.ArraysAreEqual(h, hPrime); if (match == false) { return(false); } return(true); }
public static bool OaepDecode(byte[] eMx, byte[] encodingParms, TpmAlgId hashAlg, out byte[] decoded) { decoded = new byte[0]; var em = new byte[eMx.Length + 1]; Array.Copy(eMx, 0, em, 1, eMx.Length); int hLen = CryptoLib.DigestSize(hashAlg); int k = em.Length; // a. byte[] lHash = CryptoLib.HashData(hashAlg, encodingParms); // b. byte y = em[0]; byte[] maskedSeed = Globs.CopyData(em, 1, hLen); byte[] maskedDB = Globs.CopyData(em, 1 + hLen); // c. byte[] seedMask = CryptoLib.MGF(maskedDB, hLen, hashAlg); // d. byte[] seed = XorEngine.Xor(maskedSeed, seedMask); // e. byte[] dbMask = CryptoLib.MGF(seed, k - hLen - 1, hashAlg); // f. byte[] db = XorEngine.Xor(maskedDB, dbMask); // g. byte[] lHashPrime = Globs.CopyData(db, 0, hLen); // Look for the zero.. int j; for (j = hLen; j < db.Length; j++) { if (db[j] == 0) { continue; } if (db[j] == 1) { break; } return(false); } if (j == db.Length - 1) { return(false); } byte[] m = Globs.CopyData(db, j + 1); if (y != 0) { return(false); } if (!Globs.ArraysAreEqual(lHash, lHashPrime)) { return(false); } decoded = m; return(true); }
public static bool VerifyHmacSignature(TpmAlgId underlyingHash, byte[] key, byte[] dataToHash, byte[] sig) { byte[] expectedSig = HmacData(underlyingHash, key, dataToHash); return(Globs.ArraysAreEqual(expectedSig, sig)); }
public static bool IsEqual(this Array a1, Array otherArray) { return(Globs.ArraysAreEqual(a1, otherArray)); }
/// <summary> /// Returns true if the two arguments either are both null references or /// contain equal authorization values. /// </summary> /// <param name="lhs">Left hand side operand</param> /// <param name="rhs">Right hand side operand</param> /// <returns></returns> public static bool operator ==(AuthValue lhs, AuthValue rhs) { return((object)lhs == null ? (object)rhs == null : (object)rhs != null && Globs.ArraysAreEqual(lhs.AuthVal, rhs.AuthVal)); }
/// <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); }
public static bool VerifyHmac(TpmAlgId hashAlg, byte[] key, byte[] data, byte[] sig) { return(Globs.ArraysAreEqual(sig, Hmac(hashAlg, key, data))); }
public static bool VerifyHmacSignature(TpmAlgId hashAlg, byte[] key, byte[] dataToSign, byte[] sig) { byte[] digestToSign = HashData(hashAlg, dataToSign); byte[] expectedSig = HmacData(hashAlg, key, digestToSign); return(Globs.ArraysAreEqual(expectedSig, sig)); }