示例#1
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);
        }
示例#2
0
        public static byte[] PssEncode(byte[] m, TpmAlgId hashAlg, int sLen, int emBits)
        {
            var emLen = (int)Math.Ceiling(1.0 * emBits / 8);
            int hLen  = CryptoLib.DigestSize(hashAlg);

            // 1 - Ignore
            // 2
            byte[] mHash = TpmHash.FromData(hashAlg, m);

            // 3
            if (emLen < hLen + sLen + 2)
            {
                if (Tpm2._TssBehavior.Passthrough)
                {
                    return(new byte[0]);
                }
                else
                {
                    throw new Exception("Encoding error");
                }
            }

            // 4
            byte[] salt = Globs.GetRandomBytes(sLen);

            // 5
            byte[] mPrime = Globs.Concatenate(new[] { Globs.ByteArray(8, 0),
                                                      mHash,
                                                      salt });

            // 6
            byte[] h = CryptoLib.HashData(hashAlg, mPrime);

            // 7
            byte[] ps = Globs.GetZeroBytes(emLen - sLen - hLen - 2);

            // 8
            byte[] db = Globs.Concatenate(new[] { ps,
                                                  new byte[] { 0x01 },
                                                  salt });

            // 9
            byte[] dbMask = CryptoLib.MGF(h, emLen - hLen - 1, hashAlg);

            // 10
            byte[] maskedDb = XorEngine.Xor(db, dbMask);

            // 11
            int  numZeroBits = 8 * emLen - emBits;
            byte mask        = GetByteMask(numZeroBits);

            maskedDb[0] &= mask;

            // 12
            byte[] em = Globs.Concatenate(new[] { maskedDb,
                                                  h,
                                                  new byte[] { 0xbc } });
            // 13
            return(em);
        }
示例#3
0
 /// <summary>
 /// Return a new TpmHash set to the hash of the supplied data
 /// </summary>
 /// <param name="hashAlg"></param>
 /// <param name="dataToHash"></param>
 /// <returns></returns>
 public static TpmHash FromData(TpmAlgId hashAlg, byte[] dataToHash)
 {
     if (!CryptoLib.IsHashAlgorithm(hashAlg))
     {
         Globs.Throw <ArgumentException>("TpmHash.FromData: Not a hash algorithm");
     }
     return(new TpmHash(hashAlg, CryptoLib.HashData(hashAlg, dataToHash)));
 }
示例#4
0
 /// <summary>
 /// Return a TpmHash that is the hash of Encoding.Unicode.GetBytes(password)
 /// </summary>
 /// <param name="hashAlg"></param>
 /// <param name="password"></param>
 /// <returns></returns>
 public static TpmHash FromString(TpmAlgId hashAlg, string password)
 {
     if (!CryptoLib.IsHashAlgorithm(hashAlg))
     {
         Globs.Throw <ArgumentException>("TpmHash.FromString: Not a hash algorithm");
     }
     return(new TpmHash(hashAlg, CryptoLib.HashData(hashAlg, Encoding.Unicode.GetBytes(password))));
 }
示例#5
0
        /// <summary>
        /// Make a new TpmHash from the hash of the TPM representation of data
        /// </summary>
        /// <param name="hashAlg"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static TpmHash FromObject(TpmAlgId hashAlg, Object data)
        {
            var newHash = new TpmHash(hashAlg);

            byte[] temp = Marshaller.GetTpmRepresentation(data);
            newHash.HashData = CryptoLib.HashData(hashAlg, temp);
            return(newHash);
        }
示例#6
0
 /// <summary>
 /// Return a new TpmHash that is the hash of random data
 /// </summary>
 /// <param name="hashAlg"></param>
 /// <returns></returns>
 public static TpmHash FromRandom(TpmAlgId hashAlg)
 {
     if (!CryptoLib.IsHashAlgorithm(hashAlg))
     {
         Globs.Throw <ArgumentException>("TpmHash.FromRandom: Not a hash algorithm");
     }
     return(new TpmHash(hashAlg, CryptoLib.HashData(hashAlg, Globs.GetRandomBytes((int)DigestSize(hashAlg)))));
 }
        /// <summary>
        /// Sign using a non-default hash algorithm.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="sigHash"></param>
        /// <returns></returns>
        public ISignatureUnion SignData(byte[] data, TpmAlgId sigHash)
        {
            var rsaParams = PublicParms.parameters as RsaParms;

            if (rsaParams != null)
            {
                TpmAlgId sigScheme = rsaParams.scheme.GetUnionSelector();

                switch (sigScheme)
                {
                case TpmAlgId.Rsassa:
                {
                    if (sigHash == TpmAlgId.Null)
                    {
                        sigHash = (rsaParams.scheme as SigSchemeRsassa).hashAlg;
                    }
                    byte[]  digest    = CryptoLib.HashData(sigHash, data);
                    IBuffer sigBuffer = CryptographicEngine.SignHashedData(Key, CryptographicBuffer.CreateFromByteArray(digest));
                    byte[]  sig;
                    CryptographicBuffer.CopyToByteArray(sigBuffer, out sig);
                    return(new SignatureRsassa(sigHash, sig));
                }

                case TpmAlgId.Rsapss:
                {
                    Globs.Throw <ArgumentException>("SignData(): PSS scheme is not supported");
                    return(null);
                }
                }
                Globs.Throw <ArgumentException>("Unsupported signature scheme");
                return(null);
            }

            var eccParms = PublicParms.parameters as EccParms;

            if (eccParms != null)
            {
                if (eccParms.scheme.GetUnionSelector() != TpmAlgId.Ecdsa)
                {
                    Globs.Throw <ArgumentException>("Unsupported ECC sig scheme");
                    return(null);
                }
                if (sigHash == TpmAlgId.Null)
                {
                    sigHash = (eccParms.scheme as SigSchemeEcdsa).hashAlg;
                }
                byte[]  digest = CryptoLib.HashData(sigHash, data);
                IBuffer buf    = CryptographicEngine.SignHashedData(Key, CryptographicBuffer.CreateFromByteArray(digest));
                byte[]  sig;
                CryptographicBuffer.CopyToByteArray(buf, out sig);
                int len = sig.Length / 2;
                return(new SignatureEcdsa(sigHash, Globs.CopyData(sig, 0, len), Globs.CopyData(sig, len, len)));
            }

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(null);
        } // SignData()
示例#8
0
 /// <summary>
 /// Set the PRNG seed used by the tester. If this routine is not called then the seed is
 /// extracted from the system RNG. Note that there is on RNG shared by all threads using
 /// TPM library services, so non-determinism is to be expected in multi-threaded programs
 /// even when the RNG is seeded.
 /// </summary>
 /// <param name="seed"></param>
 public static void SetRngSeed(string seed)
 {
     lock (RandLock)
     {
         _randSeed = seed == null ? new byte[0] :
                     CryptoLib.HashData(TpmAlgId.Sha256, Encoding.UTF8.GetBytes(seed));
         _randRound = 0;
         _randBuf   = null;
     }
 }
示例#9
0
 /// <summary>
 /// Set the PRNG seed. If this routine is not called then the seed is generated
 /// by the system RNG. Note that there is one RNG shared by all threads using
 /// TPM library services, so non-determinism is to be expected in multi-threaded
 /// programs even when the RNG is seeded.
 /// </summary>
 public void SetRngSeed(string seed)
 {
     lock (this)
     {
         Seed = seed == null ? new byte[0]
                             : CryptoLib.HashData(TpmAlgId.Sha256,
                                                  Encoding.UTF8.GetBytes(seed));
         Round = 0;
         FillRandBuf();
     }
 }
示例#10
0
        TkVerified SignApproval(Tpm2 tpm, byte[] approvedPolicy, byte[] policyRef,
                                TpmHandle hSigKey, ISigSchemeUnion scheme = null)
        {
            byte[]    name, qname;
            TpmPublic pub = tpm.ReadPublic(hSigKey, out name, out qname);

            byte[] dataToSign = Globs.Concatenate(approvedPolicy, policyRef);
            byte[] aHash      = CryptoLib.HashData(pub.nameAlg, dataToSign);

            // Create an authorization certificate for the "approvedPolicy"
            var sig = tpm.Sign(hSigKey, aHash, scheme, new TkHashcheck());

            return(tpm.VerifySignature(hSigKey, aHash, sig));
        }
示例#11
0
 /// <summary>
 /// Calculate the qualified name of an object presumed loaded under the provided ancestral chain
 /// in a given hierarchy.
 /// </summary>
 /// <param name="hierarchyHandle"></param>
 /// <param name="children"></param>
 /// <returns></returns>
 public static byte[] GetQualifiedName(TpmHandle hierarchyHandle, TpmPublic[] children)
 {
     byte[] runningName = Marshaller.GetTpmRepresentation(hierarchyHandle);
     foreach (TpmPublic pub in children)
     {
         byte[] thisName = pub.GetName();
         runningName = Globs.Concatenate
                       (
             Marshaller.GetTpmRepresentation(pub.nameAlg),
             CryptoLib.HashData(pub.nameAlg, new[] { runningName, thisName })
                       );
     }
     return(runningName);
 }
示例#12
0
        /// <summary>
        /// Creates a *software* key.  The key will be random (not created from
        /// a seed).  The key can be used as the root of a software hierarchy that
        /// can be translated into a duplication blob ready for import into a TPM.
        /// Depending on the type of key, the software root key can be a parent for
        /// other root keys that can comprise a migration group.  The caller should
        /// specify necessary key parameters in Public.
        ///
        /// Parameter keyData is used only with symmetric or HMAC keys. If non-null
        /// on entry, it contains the key bytes supplied by the caller, otherwise the
        /// key will be randomly generated. For asymmetric keys keyData must be null.
        ///
        /// Parameter authVal specifies the authorization value associated with the key.
        /// If it is null, then an random value will be used.
        /// </summary>
        /// <param name="pub"></param>
        /// <param name="authVal"></param>
        /// <param name="keyData"></param>
        /// <returns></returns>
        public static TssObject Create(TpmPublic pub,
                                       AuthValue authVal = null,
                                       byte[] keyData    = null)
        {
            var newKey = new TssObject();

            // Create a new key from the supplied parameters
            IPublicIdUnion publicId;
            var            sensData = CreateSensitiveComposite(pub, ref keyData, out publicId);

            var nameSize = CryptoLib.DigestSize(pub.nameAlg);

            // Create the associated seed value
            byte[] seed = Globs.GetRandomBytes(nameSize);

            // Fill in the fields for the symmetric private-part of the asymmetric key
            var sens = new Sensitive(authVal ?? AuthValue.FromRandom(nameSize),
                                     seed, sensData);

            newKey.Sensitive = sens;
            newKey.Private   = new TpmPrivate(sens.GetTpm2BRepresentation());

            // fill in the public data
            newKey.Public = pub.Copy();

            if (pub.type == TpmAlgId.Keyedhash || pub.type == TpmAlgId.Symcipher)
            {
                byte[] unique = null;
                if (pub.objectAttributes.HasFlag(ObjectAttr.Restricted | ObjectAttr.Decrypt))
                {
                    unique = CryptoLib.Hmac(pub.nameAlg, seed, keyData);
                }
                else
                {
                    unique = CryptoLib.HashData(pub.nameAlg, seed, keyData);
                }
                newKey.Public.unique = pub.type == TpmAlgId.Keyedhash
                                     ? new Tpm2bDigestKeyedhash(unique) as IPublicIdUnion
                                     : new Tpm2bDigestSymcipher(unique);
            }
            else
            {
                newKey.Public.unique = publicId;
            }

            // And return the new key
            return(newKey);
        }
示例#13
0
        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()));
        }
示例#14
0
        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()));
        }
示例#15
0
        /// <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);
        }
示例#16
0
        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");
            }
            byte[] polVal = CryptoLib.HashData(hashAlg, m.GetBytes());
            return(new TpmHash(hashAlg, polVal));
        }
示例#17
0
 /// <summary>
 /// Replace the hash value with the hash of the concatenation of the current value and the TPM representation
 /// of objectToExtend
 /// </summary>
 /// <param name="objectToExtend"></param>
 /// <returns></returns>
 public TpmHash Extend(Object objectToExtend)
 {
     byte[] temp = Marshaller.GetTpmRepresentation(objectToExtend);
     HashData = CryptoLib.HashData(HashAlg, HashData, temp);
     return(this);
 }
示例#18
0
        /// <summary>
        /// EME-OAEP PKCS1.2, section 9.1.1.1.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="encodingParameters"></param>
        /// <param name="hashAlg"></param>
        /// <param name="modulusNumBytes"></param>
        /// <returns></returns>
        public static byte[] OaepEncode(byte[] message, byte[] encodingParameters, TpmAlgId hashAlg, int modulusNumBytes)
        {
            int encodedMessageLength = modulusNumBytes - 1;
            int messageLength        = message.Length;
            int hashLength           = CryptoLib.DigestSize(hashAlg);

            // 1 (Step numbers from RSA labs spec.)
            // Ignore the ParametersLength limitation

            // 2
            if (messageLength > encodedMessageLength - 2 * hashLength - 1)
            {
                if (Tpm2._TssBehavior.Passthrough)
                {
                    return(new byte[0]);
                }
                else
                {
                    throw new ArgumentException("input message too long");
                }
            }
            int psLen = encodedMessageLength - messageLength - 2 * hashLength - 1;
            var ps    = new byte[psLen];

            // 3 (Not needed.)
            for (int j = 0; j < psLen; j++)
            {
                ps[j] = 0;
            }

            // 4
            byte[] pHash = CryptoLib.HashData(hashAlg, encodingParameters);

            // 5
            var db  = new byte[hashLength + psLen + 1 + messageLength];
            var one = new byte[1];

            one[0] = 1;
            pHash.CopyTo(db, 0);
            ps.CopyTo(db, pHash.Length);
            one.CopyTo(db, pHash.Length + ps.Length);
            message.CopyTo(db, pHash.Length + ps.Length + 1);

            // 6
            byte[] seed = Globs.GetRandomBytes(hashLength);

            // 7
            byte[] dbMask = CryptoLib.MGF(seed, encodedMessageLength - hashLength, hashAlg);

            // 8
            byte[] maskedDb = XorEngine.Xor(db, dbMask);

            // 9
            byte[] seedMask = CryptoLib.MGF(maskedDb, hashLength, hashAlg);

            // 10
            byte[] maskedSeed = XorEngine.Xor(seed, seedMask);

            //11
            var encodedMessage = new byte[maskedSeed.Length + maskedDb.Length];

            maskedSeed.CopyTo(encodedMessage, 0);
            maskedDb.CopyTo(encodedMessage, maskedSeed.Length);

            // 12
            return(encodedMessage);
        }
示例#19
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);
        }
示例#20
0
        /// <summary>
        /// Sign using a non-default hash algorithm.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="sigHash"></param>
        /// <returns></returns>
        public ISignatureUnion SignData(byte[] data, TpmAlgId sigHash)
        {
#if TSS_USE_BCRYPT
            Debug.Assert(Key != UIntPtr.Zero);
#endif
            var rsaParams = PublicParms.parameters as RsaParms;
            if (rsaParams != null)
            {
#if !TSS_USE_BCRYPT
                Debug.Assert(RsaProvider != null);
#endif
                TpmAlgId sigScheme = rsaParams.scheme.GetUnionSelector();

                switch (sigScheme)
                {
                case TpmAlgId.Rsassa:
                {
                    if (sigHash == TpmAlgId.Null)
                    {
                        sigHash = (rsaParams.scheme as SigSchemeRsassa).hashAlg;
                    }
                    byte[] digest = CryptoLib.HashData(sigHash, data);
#if TSS_USE_BCRYPT
                    byte[] sig = Key.SignHash(digest, BcryptScheme.Rsassa, sigHash);
#else
                    byte[] sig = RsaProvider.SignData(data, CryptoLib.GetHashName(sigHash));
#endif
                    return(new SignatureRsassa(sigHash, sig));
                }

                case TpmAlgId.Rsapss:
                {
#if true
                    Globs.Throw <ArgumentException>("SignData(): PSS scheme is not supported");
                    return(null);
#else
                    if (sigHash == TpmAlgId.Null)
                    {
                        sigHash = (rsaParams.scheme as SigSchemeRsapss).hashAlg;
                    }
#if TSS_USE_BCRYPT
                    byte[] sig = BCryptInterface.SignHash(KeyHandle, digest, sigHash, false);
#else
                    var    rr  = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize);
                    byte[] sig = rr.PssSign(digest, sigHash);
#endif
                    return(new SignatureRsapss(sigHash, sig));
#endif // false
                }
                }
                Globs.Throw <ArgumentException>("Unsupported signature scheme");
                return(null);
            }

            var eccParms = PublicParms.parameters as EccParms;
            if (eccParms != null)
            {
                if (eccParms.scheme.GetUnionSelector() != TpmAlgId.Ecdsa)
                {
                    Globs.Throw <ArgumentException>("Unsupported ECC sig scheme");
                    return(null);
                }
                if (sigHash == TpmAlgId.Null)
                {
                    sigHash = (eccParms.scheme as SigSchemeEcdsa).hashAlg;
                }
                byte[] digest = CryptoLib.HashData(sigHash, data);
#if TSS_USE_BCRYPT
                //throw new NotImplementedException("ECC signing with BCrypt is not implemented");
                byte[] sig = Key.SignHash(digest, BcryptScheme.Ecdsa, sigHash);
                int    len = sig.Length / 2;
                return(new SignatureEcdsa(sigHash, Globs.CopyData(sig, 0, len), Globs.CopyData(sig, len, len)));
#elif !__MonoCS__
                Debug.Assert(EcdsaProvider != null);
                EcdsaProvider.HashAlgorithm = GetCngAlgorithm(sigHash);
                byte[] sig = EcdsaProvider.SignData(data);

                int fragLen = sig.Length / 2;
                var r       = Globs.CopyData(sig, 0, fragLen);
                var s       = Globs.CopyData(sig, fragLen, fragLen);
                return(new SignatureEcdsa(sigHash, r, s));
#endif // !TSS_USE_BCRYPT && !__MonoCS__
            }

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(null);
        } // SignData()
示例#21
0
 public override int GetHashCode()
 {
     byte[] objectData = GetTpmRepresentation();
     return(BitConverter.ToInt32(objectData.Length <= sizeof(int) ? objectData : CryptoLib.HashData(TpmAlgId.Sha1, objectData), 0));
 }
示例#22
0
        /// <summary>
        /// Verifies the signature over data or a digest.
        /// The data will be hashed internall by the method using hash algorithm from
        /// the signing scheme digest computed from the specified data buffer.
        /// The signing scheme is retrieved from the signature. The verification key
        /// shall have either compatible or null scheme.
        /// </summary>
        /// <param name="data">Byte buffer containing either digest or data to check against the signature</param>
        /// <param name="dataIsDigest">Specifies the type of 'data' parameter contents</param>
        /// <param name="signature">The signature</param>
        /// <returns>True if the verification succeeds.</returns>
        private bool VerifySignature(byte[] data, bool dataIsDigest, ISignatureUnion sig)
        {
#if TSS_USE_BCRYPT
            Debug.Assert(Key != UIntPtr.Zero);
#endif
            TpmAlgId sigScheme = sig.GetUnionSelector();
            TpmAlgId sigHash   = CryptoLib.SchemeHash(sig);

            var rsaParams = PublicParms.parameters as RsaParms;
            if (rsaParams != null)
            {
#if !TSS_USE_BCRYPT
                Debug.Assert(RsaProvider != null);
#endif
                var      s         = sig as SignatureRsa;
                TpmAlgId keyScheme = rsaParams.scheme.GetUnionSelector();

                if (keyScheme != TpmAlgId.Null && keyScheme != sigScheme)
                {
                    Globs.Throw <ArgumentException>("Key scheme and signature scheme do not match");
                    return(false);
                }

                byte[] digest = dataIsDigest ? data : CryptoLib.HashData(sigHash, data);

                if (sigScheme == TpmAlgId.Rsassa)
                {
#if TSS_USE_BCRYPT
                    return(Key.VerifySignature(digest, s.sig, sigHash, true));
#else
                    return(RsaProvider.VerifyHash(digest, CryptoLib.GetHashName(sigHash), s.sig));
#endif
                }
                if (sigScheme == TpmAlgId.Rsapss)
                {
#if true
                    Globs.Throw <ArgumentException>("VerifySignature(): PSS scheme is not supported");
                    return(false);
#else
#if TSS_USE_BCRYPT
                    return(BCryptInterface.VerifySignature(KeyHandle, digest, sig.sig, sigHash, false));
#else
                    var rr = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize);
                    return(rr.PssVerify(digest, sig.sig, sigHash));
#endif
#endif // false
                }
                Globs.Throw <ArgumentException>("VerifySignature(): Unrecognized scheme");
                return(false);
            }

            var eccParams = PublicParms.parameters as EccParms;
            if (eccParams != null)
            {
                if (eccParams.scheme.GetUnionSelector() != TpmAlgId.Ecdsa)
                {
                    Globs.Throw <ArgumentException>("Unsupported ECC sig scheme");
                    return(false);
                }
                TpmAlgId keyScheme = eccParams.scheme.GetUnionSelector();

                if (keyScheme != TpmAlgId.Null && keyScheme != sigScheme)
                {
                    Globs.Throw <ArgumentException>("Key scheme and signature scheme do not match");
                    return(false);
                }

                var    s       = sig as SignatureEcdsa;
                byte[] digest  = dataIsDigest ? data : CryptoLib.HashData(sigHash, data);
                byte[] sigBlob = Globs.Concatenate(s.signatureR, s.signatureS);
#if TSS_USE_BCRYPT
                return(Key.VerifySignature(digest, sigBlob));
#elif !__MonoCS__
                Debug.Assert(EcdsaProvider != null);
                EcdsaProvider.HashAlgorithm = GetCngAlgorithm(sigHash);
                return(EcdsaProvider.VerifyHash(digest, sigBlob));
#endif // !TSS_USE_BCRYPT && !__MonoCS__
            }

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(false);
        } // VerifySignature()
示例#23
0
 int IEqualityComparer <byte[]> .GetHashCode(byte[] obj)
 {
     return(BitConverter.ToInt32(CryptoLib.HashData(TpmAlgId.Sha1, obj as byte[]), 0));
 }
示例#24
0
文件: TpmKey.cs 项目: jimsdog/TSS.MSR
 /// <summary>
 /// The TPM always signs hash-sized data. This version of the VerifySignature
 /// performs the necessary hashing operation over arbitrarily-length data and
 /// verifies that the hash is properly signed.
 /// </summary>
 /// <param name="data"></param>
 /// <param name="sig"></param>
 /// <returns></returns>
 public bool VerifySignatureOverData(byte[] data, ISignatureUnion sig)
 {
     byte[] digest = CryptoLib.HashData(CryptoLib.SchemeHash(sig), data);
     return(VerifySignatureOverHash(digest, sig));
 }
示例#25
0
文件: TpmKey.cs 项目: jimsdog/TSS.MSR
        /// <summary>
        /// Creates a duplication blob for the current key that can be Imported as a child
        /// of newParent. Three forms are possible. GetPlaintextDuplicationBlob() allows
        /// plaintext-import. This function enables duplication with and without an
        /// inner wrapper (depending on whether innerWrapper is null)
        /// </summary>
        /// <param name="newParent"></param>
        /// <param name="innerWrapper"></param>
        /// <param name="encSecret"></param>
        /// <returns></returns>
        public TpmPrivate GetDuplicationBlob(
            TpmPublic pubNewParent,
            SymCipher innerWrapper,
            out byte[] encSecret)
        {
            byte[] encSensitive;
            if (innerWrapper == null)
            {
                // No inner wrapper
                encSensitive = Marshaller.ToTpm2B(Sensitive.GetTpmRepresentation());
                Transform(encSensitive);
            }
            else
            {
                byte[] sens   = Marshaller.ToTpm2B(Sensitive.GetTpmRepresentation());
                byte[] toHash = Globs.Concatenate(sens, GetName());
                Transform(toHash);
                byte[] innerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData(
                                                               Public.nameAlg, toHash));
                byte[] innerData = Globs.Concatenate(innerIntegrity, sens);
                Transform(innerData);
                encSensitive = innerWrapper.Encrypt(innerData);
                Transform(encSensitive);
            }

            byte[]       seed;
            SymDefObject symDef = GetSymDef(pubNewParent).Copy();

            // TPM duplication procedures always use CFB mode
            symDef.Mode = TpmAlgId.Cfb;

            using (var swNewParent = AsymCryptoSystem.CreateFrom(pubNewParent))
            {
                switch (pubNewParent.type)
                {
                case TpmAlgId.Rsa:
                    // The seed should be the same size as the scheme hash
                    LastSeed =
                        seed = Globs.GetRandomBytes(
                            CryptoLib.DigestSize(swNewParent.OaepHash));
                    encSecret = swNewParent.EncryptOaep(seed, DuplicateEncodingParms);
                    break;

                case TpmAlgId.Ecc:
                    EccPoint pubEphem;
                    seed = swNewParent.EcdhGetKeyExchangeKey(DuplicateEncodingParms,
                                                             pubNewParent.nameAlg,
                                                             out pubEphem);
                    encSecret = Marshaller.GetTpmRepresentation(pubEphem);
                    break;

                default:
                    Globs.Throw <NotImplementedException>(
                        "GetDuplicationBlob: Unsupported algorithm");
                    encSecret = new byte[0];
                    return(new TpmPrivate());
                }
            }
            Transform(seed);
            Transform(encSecret);

            byte[] symKey = KDF.KDFa(pubNewParent.nameAlg, seed, "STORAGE",
                                     Public.GetName(), new byte[0], symDef.KeyBits);
            Transform(symKey);

            byte[] dupSensitive;
            using (SymCipher enc2 = SymCipher.Create(symDef, symKey))
            {
                if (enc2 == null)
                {
                    return(null);
                }

                dupSensitive = enc2.Encrypt(encSensitive);
            }
            Transform(dupSensitive);

            var npNameNumBits = CryptoLib.DigestSize(pubNewParent.nameAlg) * 8;

            byte[] hmacKey = KDF.KDFa(pubNewParent.nameAlg, seed, "INTEGRITY",
                                      new byte[0], new byte[0], npNameNumBits);

            byte[] outerDataToHmac = Globs.Concatenate(dupSensitive, Public.GetName());
            Transform(outerDataToHmac);

            byte[] outerHmac = Marshaller.ToTpm2B(CryptoLib.Hmac(pubNewParent.nameAlg,
                                                                 hmacKey, outerDataToHmac));
            Transform(outerHmac);

            byte[] dupBlob = Globs.Concatenate(outerHmac, dupSensitive);
            Transform(dupBlob);

            return(new TpmPrivate(dupBlob));
        }
示例#26
0
 /// <summary>
 /// Replace the hash value with the hash of the concatenation of the current hash value and DataToExtend
 /// </summary>
 /// <param name="dataToExtend"></param>
 /// <returns></returns>
 public TpmHash Event(byte[] dataToExtend)
 {
     HashData = CryptoLib.HashData(HashAlg, HashData, CryptoLib.HashData(HashAlg, dataToExtend));
     return(this);
 }
示例#27
0
        /// <summary>
        /// Creates a duplication blob for the current key that can be Imported as a child
        /// of newParent. Three forms are possible. GetPlaintextDuplicationBlob() allows
        /// plaintext-import. This function enables duplication with and without an
        /// inner wrapper (depending on whether innerWrapper is null)
        /// </summary>
        /// <param name="newParent"></param>
        /// <param name="innerWrapper"></param>
        /// <param name="encryptedWrappingKey"></param>
        /// <returns></returns>
        public TpmPrivate GetDuplicationBlob(
            TpmPublic newParent,
            SymmCipher innerWrapper,
            out byte[] encryptedWrappingKey)
        {
            byte[] encSensitive;
            if (innerWrapper == null)
            {
                // No inner wrapper
                encSensitive = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation());
            }
            else
            {
                byte[] sens           = Marshaller.ToTpm2B(sensitivePart.GetTpmRepresentation());
                byte[] toHash         = Globs.Concatenate(sens, GetName());
                byte[] innerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData(publicPart.nameAlg, toHash));
                byte[] innerData      = Globs.Concatenate(innerIntegrity, sens);
                encSensitive = innerWrapper.Encrypt(innerData);
            }

            byte[]       seed, encSecret;
            SymDefObject symDef = GetSymDef(newParent);

            using (AsymCryptoSystem newParentPubKey = AsymCryptoSystem.CreateFrom(newParent))
            {
                switch (newParent.type)
                {
                case TpmAlgId.Rsa:
                    // The seed should be the same size as the symmKey
                    seed      = Globs.GetRandomBytes((symDef.KeyBits + 7) / 8);
                    encSecret = newParentPubKey.EncryptOaep(seed, DuplicateEncodingParms);
                    break;

                case TpmAlgId.Ecc:
                    EccPoint pubEphem;
                    seed = newParentPubKey.EcdhGetKeyExchangeKey(DuplicateEncodingParms,
                                                                 newParent.nameAlg,
                                                                 out pubEphem);
                    encSecret = Marshaller.GetTpmRepresentation(pubEphem);
                    break;

                default:
                    Globs.Throw <NotImplementedException>("GetDuplicationBlob: Unsupported algorithm");
                    encryptedWrappingKey = new byte[0];
                    return(new TpmPrivate());
                }
            }

            encryptedWrappingKey = encSecret;

            byte[] symKey = KDF.KDFa(newParent.nameAlg, seed, "STORAGE", publicPart.GetName(), new byte[0], symDef.KeyBits);

            byte[] dupSensitive;
            using (SymmCipher enc2 = SymmCipher.Create(symDef, symKey))
            {
                dupSensitive = enc2.Encrypt(encSensitive);
            }

            var npNameNumBits = CryptoLib.DigestSize(newParent.nameAlg) * 8;

            byte[] hmacKey = KDF.KDFa(newParent.nameAlg, seed, "INTEGRITY", new byte[0], new byte[0], npNameNumBits);

            byte[] outerDataToHmac = Globs.Concatenate(dupSensitive, publicPart.GetName());

            byte[] outerHmac = Marshaller.ToTpm2B(CryptoLib.HmacData(newParent.nameAlg, hmacKey, outerDataToHmac));

            byte[] dupBlob = Globs.Concatenate(outerHmac, dupSensitive);

            return(new TpmPrivate(dupBlob));
        }
        private bool VerifySignature(byte[] data, bool dataIsDigest, ISignatureUnion signature, TpmAlgId sigHash)
        {
            var rsaParams = PublicParms.parameters as RsaParms;

            if (rsaParams != null)
            {
                var      sig       = signature as SignatureRsa;
                TpmAlgId sigScheme = sig.GetUnionSelector();
                TpmAlgId keyScheme = rsaParams.scheme.GetUnionSelector();

                if (keyScheme != TpmAlgId.Null && keyScheme != sigScheme)
                {
                    Globs.Throw <ArgumentException>("Key scheme and signature scheme do not match");
                    return(false);
                }
                if (sigHash == TpmAlgId.Null)
                {
                    sigHash = (rsaParams.scheme as SchemeHash).hashAlg;
                }
                if (sigHash != sig.hash)
                {
                    Globs.Throw <ArgumentException>("Key scheme hash and signature scheme hash do not match");
                    return(false);
                }

                byte[] digest = dataIsDigest ? data : CryptoLib.HashData(sigHash, data);

                if (sigScheme == TpmAlgId.Rsassa)
                {
                    return(CryptographicEngine.VerifySignatureWithHashInput(Key, CryptographicBuffer.CreateFromByteArray(digest), CryptographicBuffer.CreateFromByteArray(sig.sig)));
                }
                if (sigScheme == TpmAlgId.Rsapss)
                {
                    Globs.Throw <ArgumentException>("VerifySignature(): PSS scheme is not supported");
                    return(false);
                }
                Globs.Throw <ArgumentException>("VerifySignature(): Unrecognized scheme");
                return(false);
            }

            var eccParms = PublicParms.parameters as EccParms;

            if (eccParms != null)
            {
                if (eccParms.scheme.GetUnionSelector() != TpmAlgId.Ecdsa)
                {
                    Globs.Throw <ArgumentException>("Unsupported ECC sig scheme");
                    return(false);
                }
                if (sigHash == TpmAlgId.Null)
                {
                    sigHash = (eccParms.scheme as SigSchemeEcdsa).hashAlg;
                }

                byte[] digest  = dataIsDigest ? data : CryptoLib.HashData(sigHash, data);
                var    sig     = signature as SignatureEcdsa;
                byte[] sigBlob = Globs.Concatenate(sig.signatureR, sig.signatureS);
                return(CryptographicEngine.VerifySignatureWithHashInput(Key, CryptographicBuffer.CreateFromByteArray(digest), CryptographicBuffer.CreateFromByteArray(sigBlob)));
            }

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(false);
        } // VerifySignature()