Esempio n. 1
0
 /// <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));
 }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
0
 /// <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));
 }
Esempio n. 5
0
 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));
 }
Esempio n. 6
0
 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);
     }
 }
Esempio n. 7
0
        /// <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);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        /// <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);
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
 public static bool VerifyHmacSignature(TpmAlgId underlyingHash, byte[] key, byte[] dataToHash, byte[] sig)
 {
     byte[] expectedSig = HmacData(underlyingHash, key, dataToHash);
     return(Globs.ArraysAreEqual(expectedSig, sig));
 }
Esempio n. 12
0
 public static bool IsEqual(this Array a1, Array otherArray)
 {
     return(Globs.ArraysAreEqual(a1, otherArray));
 }
Esempio n. 13
0
 /// <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));
 }
Esempio n. 14
0
        /// <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);
        }
Esempio n. 15
0
 public static bool VerifyHmac(TpmAlgId hashAlg, byte[] key, byte[] data, byte[] sig)
 {
     return(Globs.ArraysAreEqual(sig, Hmac(hashAlg, key, data)));
 }
Esempio n. 16
0
 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));
 }