예제 #1
0
        public static byte[] GetPcrProperty(Tpm2 tpm, PtPcr prop)
        {
            ICapabilitiesUnion caps;

            tpm.GetCapability(Cap.PcrProperties, (uint)prop, 1, out caps);
            TaggedPcrSelect[] props = (caps as TaggedPcrPropertyArray).pcrProperty;
            if (props.Length == 0)
            {
                return(new byte[0]);
            }
            if (props.Length != 1)
            {
                Globs.Throw("Unexpected return from GetCapability");
            }
            return(props[0].pcrSelect);
        }
예제 #2
0
        virtual internal void ToStringInternal(TpmStructPrinter p)
        {
            bool enabled = dbg.Enabled;

            dbg.Enabled = false;
            var members = GetFieldsToMarshal();

            dbg.Enabled = enabled;
            foreach (var mem in members)
            {
                MemberInfo memInfo = mem;
                object     memVal  = Globs.GetMember(memInfo, this);
                Type       memType = Globs.GetMemberType(memInfo);
                p.Print(memInfo.Name, Globs.ToCSharpStyle(memType.Name), memVal);
            }
        }
예제 #3
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);
     }
 }
예제 #4
0
        internal static int GetKeyLength(EccCurve curve)
        {
            switch (curve)
            {
            case EccCurve.TpmEccNistP256:
                return(256);

            case EccCurve.TpmEccNistP384:
                return(384);

            case EccCurve.TpmEccNistP521:
                return(521);
            }
            Globs.Throw <ArgumentException>("GetKeyLength(): Invalid ECC curve");
            return(-1);
        }
예제 #5
0
        public byte[] OaepEncrypt(byte[] data, TpmAlgId hashAlg, byte[] encodingParms)
        {
            int encLen = NumBits / 8;

            byte[]     zeroTermEncoding = GetLabel(encodingParms);
            byte[]     encoded          = CryptoEncoders.OaepEncode(data, zeroTermEncoding, hashAlg, encLen);
            BigInteger message          = FromBigEndian(encoded);
            BigInteger cipher           = BigInteger.ModPow(message, E, N);

            byte[] encMessageBigEnd = ToBigEndian(cipher, KeySize);
            if (encMessageBigEnd.Length < encLen)
            {
                encMessageBigEnd = Globs.AddZeroToBeginning(encMessageBigEnd, encLen - encMessageBigEnd.Length);
            }
            return(encMessageBigEnd);
        }
예제 #6
0
        private byte[] GetTpmAuth(TBS_AUTH_TYPE authType)
        {
#if false
            return(new byte[0]);
#else
            if (TbsHandle == UIntPtr.Zero)
            {
                throw new Exception("TBS context not created.");
            }

            //Console.WriteLine("GetTpmAuth: Retrieving auth value {0}", authType);
            var  resultBuf               = new byte[256];
            uint resultByteCount         = (uint)resultBuf.Length;
            TbsWrapper.TBS_RESULT result = TbsWrapper.NativeMethods.
                                           Tbsi_Get_OwnerAuth(TbsHandle,
                                                              (uint)authType,
                                                              resultBuf,
                                                              ref resultByteCount);
            if (result != TbsWrapper.TBS_RESULT.SUCCESS)
            {
#if !__NETCOREAPP2__ && false
                Console.WriteLine($"Trying to read LockoutAuth from the registry...");
                try
                {
                    string lockoutAuthBase64 = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TPM\WMI\Admin", "LockoutHash", null);
                    if (lockoutAuthBase64 != null)
                    {
                        resultBuf = Convert.FromBase64String(lockoutAuthBase64);
                        Console.WriteLine($"LockoutAuth: {lockoutAuthBase64} | len {resultBuf.Length} bytes | {Globs.HexFromByteArray(resultBuf)}");
                        return(resultBuf);
                    }
                }
                catch (Exception e) {
                    Console.WriteLine($"Exception: {e}");
                }
#endif
#if !WINDOWS_UWP
                Console.WriteLine("GetTpmAuth({0}): Windows TBS returned 0x{1:X} {2}", authType, result,
                                  result == TbsWrapper.TBS_RESULT.OWNERAUTH_NOT_FOUND ? " (OWNERAUTH_NOT_FOUND)" :
                                  result == TbsWrapper.TBS_RESULT.BAD_PARAMETER ? " (BAD_PARAMETER)" : "");
#endif
                return(new byte[0]);
            }

            return(Globs.CopyData(resultBuf, 0, (int)resultByteCount));
#endif
        }
예제 #7
0
파일: TpmKey.cs 프로젝트: jimsdog/TSS.MSR
        /// <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;

            // 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);
        }
예제 #8
0
        public static byte[] HmacData(TpmAlgId hashAlgId, byte[] key, byte[] dataToHash)
        {
#if TSS_USE_BCRYPT
            string algName = Native.BCryptHashAlgName(hashAlgId);
            if (string.IsNullOrEmpty(algName))
            {
                Globs.Throw <ArgumentException>("HmacData(): Unsupported hash algorithm " + hashAlgId);
                return(null);
            }

            var alg    = new BCryptAlgorithm(algName, Native.BCRYPT_ALG_HANDLE_HMAC);
            var digest = alg.HmacData(key, dataToHash);
            alg.Close();
            return(digest);
#else
            switch (hashAlgId)
            {
            case TpmAlgId.Sha1:
                using (var h = new HMACSHA1(key))
                {
                    return(h.ComputeHash(dataToHash));
                }

            case TpmAlgId.Sha256:
                using (var h2 = new HMACSHA256(key))
                {
                    return(h2.ComputeHash(dataToHash));
                }

            case TpmAlgId.Sha384:
                using (var h3 = new HMACSHA384(key))
                {
                    return(h3.ComputeHash(dataToHash));
                }

            case TpmAlgId.Sha512:
                using (var h4 = new HMACSHA512(key))
                {
                    return(h4.ComputeHash(dataToHash));
                }

            default:
                Globs.Throw <ArgumentException>("HmacData(): Unsupported hash algorithm " + hashAlgId);
                return(null);
            }
#endif // !TSS_USE_BCRYPT
        }
예제 #9
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);
        }
예제 #10
0
        /// <summary>
        /// Calculate and return the auth-hmac (or plaintext auth if it is a policy session with PlaintextAuth set)
        /// based on the current session parms.
        /// </summary>
        /// <param name="parmHash"></param>
        /// <param name="direction"></param>
        /// <param name="nonceDec"></param>
        /// <param name="nonceEnc"></param>
        /// <returns></returns>
        internal byte[] GetAuthHmac(byte[] parmHash, Direction direction, byte[] nonceDec = null, byte[] nonceEnc = null)
        {
            // special case.  If this is a policy session and the session includes PolicyPassword the
            // TPM expects and assumes that the HMAC field will have the plaintext entity field as in
            // a PWAP session (the related PolicyAuthValue demands an HMAC as usual)
            if (PlaintextAuth)
            {
                return(Handle.Auth ?? AuthHandle.Auth);
            }

            byte[] nonceNewer, nonceOlder;
            if (direction == Direction.Command)
            {
                nonceNewer = NonceCaller;
                nonceOlder = NonceTpm;
            }
            else
            {
                nonceNewer = NonceTpm;
                nonceOlder = NonceCaller;
            }
            byte[] sessionAttrs = Marshaller.GetTpmRepresentation(Attrs);

            byte[] auth = Handle.Auth;
            if (AuthHandle != null && Handle != TpmRh.TpmRsPw && auth == null &&
                ((SessionType != TpmSe.Policy && BindObject != AuthHandle) ||
                 (SessionType == TpmSe.Policy && SessIncludesAuth)))
            {
                auth = Globs.TrimTrailingZeros(AuthHandle.Auth);
            }
            byte[] hmacKey   = Globs.Concatenate(SessionKey, auth);
            byte[] bufToHmac = Globs.Concatenate(new[] { parmHash, nonceNewer, nonceOlder,
                                                         nonceDec, nonceEnc, sessionAttrs });

            byte[] hmac = CryptoLib.Hmac(AuthHash, hmacKey, bufToHmac);
#if false
            Console.WriteLine(Globs.FormatBytesCompact("hmacKey: ", hmacKey));
            Console.WriteLine(Globs.FormatBytesCompact("nonceNewer: ", nonceNewer));
            Console.WriteLine(Globs.FormatBytesCompact("nonceOlder: ", nonceOlder));
            Console.WriteLine(Globs.FormatBytesCompact("nonceDec: ", nonceDec));
            Console.WriteLine(Globs.FormatBytesCompact("nonceEnc: ", nonceEnc));
            Console.WriteLine(Globs.FormatBytesCompact("attrs: ", sessionAttrs));
            Console.WriteLine(Globs.FormatBytesCompact("HMAC: ", hmac));
#endif
            return(hmac);
        }
예제 #11
0
        public static byte[] HashData(TpmAlgId algId, byte[] dataToHash)
        {
            if (dataToHash == null)
            {
                dataToHash = new byte[0];
            }

#if TSS_USE_BCRYPT
            string algName = Native.BCryptHashAlgName(algId);
            if (string.IsNullOrEmpty(algName))
            {
                Globs.Throw <ArgumentException>("HashData(): Unsupported hash algorithm " + algId);
                return(null);
            }

            var alg    = new BCryptAlgorithm(algName);
            var digest = alg.HashData(dataToHash);
            alg.Close();
            return(digest);
#else
            HashAlgorithm hashAlg = null;
            switch (algId)
            {
            case TpmAlgId.Sha1:
                hashAlg = new SHA1Managed();
                break;

            case TpmAlgId.Sha256:
                hashAlg = new SHA256Managed();
                break;

            case TpmAlgId.Sha384:
                hashAlg = new SHA384Managed();
                break;

            case TpmAlgId.Sha512:
                hashAlg = new SHA512Managed();
                break;

            default:
                Globs.Throw <ArgumentException>("AlgId is not a supported hash algorithm");
                return(null);
            }
            return(hashAlg.ComputeHash(dataToHash));
#endif
        }
예제 #12
0
        public static byte[] TrimTrailingZeros(byte[] buf)
        {
            if (buf == null || buf.Length == 0)
            {
                return(buf);
            }

            int i = buf.Length;

            while (buf[i - 1] == 0 && --i > 0)
            {
                continue;
            }

            Debug.Assert(i >= 0);
            return(Globs.CopyData(buf, 0, i));
        }
예제 #13
0
        public byte[] OaepEncrypt(byte[] data, TpmAlgId hashAlg, byte[] encodingParms)
        {
            if (data.Length == 0)
            {
                Globs.Throw <ArgumentException>("OaepEncrypt: Empty data buffer");
                return(new byte[0]);
            }
            int encLen = NumBits / 8;

            byte[]     zeroTermEncoding = GetLabel(encodingParms);
            byte[]     encoded          = CryptoEncoders.OaepEncode(data, zeroTermEncoding, hashAlg, encLen);
            BigInteger message          = FromBigEndian(encoded);
            BigInteger cipher           = BigInteger.ModPow(message, E, N);

            byte[] encMessageBigEnd = ToBigEndian(cipher, KeySize);
            return(encMessageBigEnd);
        }
예제 #14
0
        internal async Task <Tpm2CreatePrimaryResponse> CreatePrimaryRsaAsyncInternal(
            int keyLen,
            byte[] useAuth,
            byte[] policyAuth,
            PcrSelection[] pcrSel)
        {
            ObjectAttr attr = ObjectAttr.Restricted | ObjectAttr.Decrypt
                              | ObjectAttr.FixedParent | ObjectAttr.FixedTPM
                              | ObjectAttr.SensitiveDataOrigin;

            var theUseAuth = new byte[0];

            if (useAuth != null)
            {
                theUseAuth = useAuth;
                attr      |= ObjectAttr.UserWithAuth;
            }
            var thePolicyAuth = new byte[0];

            if (policyAuth != null)
            {
                thePolicyAuth = policyAuth;
                attr         |= ObjectAttr.AdminWithPolicy;
            }
            var theSelection = new PcrSelection[0];

            if (pcrSel != null)
            {
                theSelection = pcrSel;
            }

            var sensCreate = new SensitiveCreate(theUseAuth, new byte[0]);
            var parms      = new TpmPublic(H.NameHash,
                                           attr,
                                           thePolicyAuth,
                                           new RsaParms(new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb),
                                                        new NullAsymScheme(),
                                                        (ushort)keyLen,
                                                        0),
                                           new Tpm2bPublicKeyRsa());

            byte[] outsideInfo = Globs.GetRandomBytes(8);
            return(await H.Tpm.CreatePrimaryAsync(TpmRh.Owner, sensCreate,
                                                  parms, outsideInfo, theSelection));
        }
예제 #15
0
 private void DebugStateSave()
 {
     if (Globs.GetRandomDouble() < StateSaveProbability)
     {
         bool   s3           = NumStateSaves % 4 < 2;
         bool   doPowerCycle = (NumStateSaves % 2 == 0);
         string message      = s3 ? "{S3}" : "{S4}";
         if (!doPowerCycle)
         {
             message = "{S3-abort}";
         }
         Console.ForegroundColor = ConsoleColor.Magenta;
         Console.Error.Write(message);
         Console.ResetColor();
         StateSaveAndReload(s3, (NumStateSaves % 2 == 0));
         NumStateSaves++;
     }
 }
예제 #16
0
 /// <summary>
 /// This command is used to cause conditional gating of a policy based on the contents of an NV Index.
 /// </summary>
 public TpmPolicyNV(
     TpmHandle authorizationHandle,
     byte[] nvAccessAuth,
     TpmHandle nvIndex,
     byte[] indexName,
     byte[] operandB,
     ushort offset,
     Eo operation,
     string branchName = "") : base(branchName)
 {
     AuthorizationHandle = authorizationHandle;
     NvAccessAuth        = Globs.CopyData(nvAccessAuth);
     NvIndex             = nvIndex;
     OperandB            = Globs.CopyData(operandB);
     Offset    = offset;
     Operation = operation;
     IndexName = Globs.CopyData(indexName);
 }
예제 #17
0
        /// <summary>
        /// Create a new asymmetric key based on the parameters in keyParms. The resulting key data is returned in structures
        /// suitable for incorporation in a TPMT_PUBLIC and TPMS_SENSITIVE
        /// </summary>
        /// <param name="keyParms"></param>
        /// <param name="publicParms"></param>
        /// <returns></returns>
        internal static ISensitiveCompositeUnion CreateSensitiveComposite(TpmPublic keyParms, out IPublicIdUnion publicParms)
        {
            TpmAlgId keyAlgId = keyParms.type;
            ISensitiveCompositeUnion newSens;

            // Create the asymmetric key
            if (keyAlgId != TpmAlgId.Rsa)
            {
                Globs.Throw <ArgumentException>("Algorithm not supported");
            }

            var newKeyPair = new RawRsa((keyParms.parameters as RsaParms).keyBits);

            // Put the key bits into the required structure envelopes
            newSens     = new Tpm2bPrivateKeyRsa(newKeyPair.Private);
            publicParms = new Tpm2bPublicKeyRsa(newKeyPair.Public);
            return(newSens);
        }
예제 #18
0
        internal static void KeyInfoFromPublicBlob(byte[] blob, out byte[] x, out byte[] y)
        {
            x = null;
            y = null;
            var  m       = new Marshaller(blob);
            uint magic   = BitConverter.ToUInt32(m.GetNBytes(4), 0);
            bool magicOk = AlgInfo.Any(xx => xx.Magic == magic);

            if (!magicOk)
            {
                Globs.Throw <ArgumentException>("KeyInfoFromPublicBlob: Public key blob magic not recognized");
            }

            uint cbKey = BitConverter.ToUInt32(m.GetNBytes(4), 0);

            x = m.GetNBytes((int)cbKey);
            y = m.GetNBytes((int)cbKey);
        }
예제 #19
0
        /// <summary>
        /// Create a new random software key (public and private) matching the parameters in keyParams.
        /// </summary>
        /// <param name="keyParams"></param>
        /// <returns></returns>
        public AsymCryptoSystem(TpmPublic keyParams)
        {
            TpmAlgId keyAlgId = keyParams.type;

            PublicParms = keyParams.Copy();

            switch (keyAlgId)
            {
            case TpmAlgId.Rsa:
            {
                var rsaParams = keyParams.parameters as RsaParms;
                AsymmetricKeyAlgorithmProvider RsaProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaOaepSha256);
                Key = RsaProvider.CreateKeyPair(rsaParams.keyBits);
                IBuffer keyBlobBuffer = Key.ExportPublicKey(CryptographicPublicKeyBlobType.BCryptPublicKey);
                byte[]  blob;
                CryptographicBuffer.CopyToByteArray(keyBlobBuffer, out blob);
                var m       = new Marshaller(blob, DataRepresentation.LittleEndian);
                var header  = m.Get <BCryptRsaKeyBlob>();
                var modulus = m.GetArray <byte>((int)header.cbModulus);
                var pubId   = new Tpm2bPublicKeyRsa(modulus);
                PublicParms.unique = pubId;
                break;
            }

            case TpmAlgId.Ecc:
            {
                var eccParms = keyParams.parameters as EccParms;
                var alg      = RawEccKey.GetEccAlg(keyParams);
                if (alg == null)
                {
                    Globs.Throw <ArgumentException>("Unknown ECC curve");
                    return;
                }
                AsymmetricKeyAlgorithmProvider EccProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(alg);
                Key = EccProvider.CreateKeyPair((uint)RawEccKey.GetKeyLength(eccParms.curveID));
                break;
            }

            default:
                Globs.Throw <ArgumentException>("Algorithm not supported");
                break;
            }
        }
예제 #20
0
        /// <summary>
        /// Calculates and returns the policy-hashes of the attached branches.
        /// </summary>
        /// <param name="hashAlg"></param>
        /// <returns></returns>
        public Tpm2bDigest[] GetPolicyHashArray(TpmAlgId hashAlg)
        {
            int numBranches = PolicyBranches.Count;

            if (numBranches < 2 || numBranches > 8)
            {
                Globs.Throw("GetPolicyHashArray: Must have between 2 and 8 branches in a PolicyOr");
            }

            int i           = 0;
            var childHashes = new Tpm2bDigest[numBranches];

            foreach (PolicyAce branch in PolicyBranches)
            {
                childHashes[i++] = branch.GetPolicyDigest(hashAlg);
            }

            return(childHashes);
        }
예제 #21
0
        /// <summary>
        /// Extract and return the SymDefObject that describes the associated symmetric algorithm that is used for key protection
        /// in storage keys.
        /// </summary>
        /// <param name="keyParms"></param>
        /// <returns></returns>
        internal static SymDefObject GetSymDef(TpmPublic keyParms)
        {
            TpmAlgId keyAlgId = keyParms.type;

            switch (keyAlgId)
            {
            case TpmAlgId.Rsa:
                var rsaParms = (RsaParms)keyParms.parameters;
                return(rsaParms.symmetric);

            case TpmAlgId.Ecc:
                var eccParms = (EccParms)keyParms.parameters;
                return(eccParms.symmetric);

            default:
                Globs.Throw("Unsupported algorithm");
                return(new SymDefObject());
            }
        }
예제 #22
0
파일: CryptoSymm.cs 프로젝트: rgl/TSS.MSR
        /// <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 SensitiveFromDupBlob(TpmPrivate exportedPrivate,
                                                     SymDefObject encAlg, byte[] encKey,
                                                     TpmAlgId nameAlg, byte[] name)
        {
            byte[] dupBlob   = exportedPrivate.buffer;
            byte[] sensNoLen = null;
            using (SymCipher c = Create(encAlg, encKey))
            {
                byte[] innerObject = null;
                if (c == null)
                {
                    if (encAlg.Algorithm != TpmAlgId.Null)
                    {
                        return(null);
                    }
                    else
                    {
                        return(Marshaller.FromTpmRepresentation <Sensitive>(Marshaller.Tpm2BToBuffer(dupBlob)));
                    }
                }
                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("SensitiveFromDupBlob: Bad inner integrity");
                }

                sensNoLen = Marshaller.Tpm2BToBuffer(sensitive);
            }
            var sens = Marshaller.FromTpmRepresentation <Sensitive>(sensNoLen);

            return(sens);
        }
예제 #23
0
        /// <summary>
        /// Assuming a ushort-prepended array, return the payload (if properly formed).
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        static public byte[] Tpm2BToBuffer(byte[] x)
        {
            var m   = new Marshaller(x);
            var len = m.Get <ushort>();

            if (len != x.Length - 2)
            {
                Globs.Throw <ArgumentException>("Tpm2BToBuffer: Ill formed TPM2B");
                if (x.Length < 2)
                {
                    return(new byte[0]);
                }
                len = (ushort)(x.Length - 2);
            }
            var ret = new byte[len];

            Array.Copy(x, 2, ret, 0, len);
            return(ret);
        }
예제 #24
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);
        }
예제 #25
0
 private Object FromNetValueType(Type tp)
 {
     byte[] data = Buffer.Extract(Globs.SizeOf(tp));
     if (data == null)
     {
         return(null);
     }
     if (Repr == DataRepresentation.Tpm)
     {
         return(Globs.NetToHostValue(tp, data));
     }
     if (Repr == DataRepresentation.LittleEndian)
     {
         return(Globs.FromBytes(tp, data));
     }
     // Unsupported type
     Debug.Assert(false);
     return(null);
 }
예제 #26
0
        // Returns the PcrSelection[] for the current PcrValueCollection
        public PcrSelection[] GetPcrSelectionArray()
        {
            // find all referenced algorithms
            var referencedAlgs = new List <TpmAlgId>();

            foreach (PcrValue v in Values)
            {
                // todo reference or value contains?
                if (!referencedAlgs.Contains(v.value.HashAlg))
                {
                    referencedAlgs.Add(v.value.HashAlg);
                }
            }
            var selection = new PcrSelection[referencedAlgs.Count];
            int count     = 0;

            foreach (TpmAlgId algId in referencedAlgs)
            {
                selection[count++] = new PcrSelection(algId, new uint[0]);
            }
            uint bankNum = 0;

            foreach (TpmAlgId algId in referencedAlgs)
            {
                foreach (PcrValue val in Values)
                {
                    if (val.value.HashAlg != algId)
                    {
                        continue;
                    }
                    // Do we already have a PcrValue with the same {alg, pcrNum?}
                    if (selection[bankNum].IsPcrSelected(val.index))
                    {
                        Globs.Throw("PcrValueCollection.GetPcrSelectionArray: PCR is referenced more than once");
                    }
                    // Else select it
                    selection[bankNum].SelectPcr(val.index);
                }
                bankNum++;
            }
            return(selection);
        }
예제 #27
0
        public override void Connect()
        {
            TbsWrapper.TBS_CONTEXT_PARAMS contextParams;

            UIntPtr tbsContext = UIntPtr.Zero;

            contextParams.Version = TbsWrapper.TBS_CONTEXT_VERSION.TWO;
            contextParams.Flags   = TbsWrapper.TBS_CONTEXT_CREATE_FLAGS.IncludeTpm20;
            TbsWrapper.TBS_RESULT result = TbsWrapper.NativeMethods
                                           .Tbsi_Context_Create(ref contextParams, ref tbsContext);
            Debug.WriteLine(Globs.GetResourceString("TbsHandle:") + tbsContext.ToUInt32());

            if (result != TbsWrapper.TBS_RESULT.SUCCESS)
            {
                throw new Exception("Failed to create TBS context: Error {" + result + "}");
            }

            TbsHandle      = tbsContext;
            OriginalHandle = tbsContext;
        }
예제 #28
0
        // ReSharper disable once InconsistentNaming
        public static byte[] KDFa(TpmAlgId hmacHash, byte[] hmacKey, string label, byte[] contextU, byte[] contextV, uint numBitsRequired)
        {
            int  bitsPerLoop = CryptoLib.DigestSize(hmacHash) * 8;
            long numLoops    = (numBitsRequired + bitsPerLoop - 1) / bitsPerLoop;
            var  kdfStream   = new byte[numLoops * bitsPerLoop / 8];

            for (int j = 0; j < numLoops; j++)
            {
                byte[] toHmac = Globs.Concatenate(new[] {
                    Globs.HostToNet(j + 1),
                    Encoding.UTF8.GetBytes(label), Globs.HostToNet((byte)0),
                    contextU,
                    contextV,
                    Globs.HostToNet(numBitsRequired)
                });
                byte[] fragment = CryptoLib.HmacData(hmacHash, hmacKey, toHmac);
                Array.Copy(fragment, 0, kdfStream, j * bitsPerLoop / 8, fragment.Length);
            }
            return(Globs.ShiftRight(kdfStream, (int)(bitsPerLoop * numLoops - numBitsRequired)));
        }
예제 #29
0
        /// <summary>
        /// Calculate the session-key from the nonces and salt/bound values (if present)
        /// </summary>
        public void CalcSessionKey()
        {
            if (Salt == SaltNeeded)
            {
                Globs.Throw("Unencrypted salt value must be provided for the session" +
                            Handle.handle.ToString("X8"));
            }

            // Compute Handle.Auth in accordance with Part 1, 19.6.8.
            if (Salt == null && BindObject == TpmRh.Null)
            {
                SessionKey = new byte[0];
                return;
            }

            byte[] auth    = Globs.TrimTrailingZeros(BindObject.Auth);
            byte[] hmacKey = Globs.Concatenate(auth, Salt);
            SessionKey = KDF.KDFa(AuthHash, hmacKey, "ATH", NonceTpm, NonceCaller,
                                  TpmHash.DigestSize(AuthHash) * 8);
        }
예제 #30
0
        private static byte[] ShiftRightInternal(byte[] x, int numBits)
        {
            if (numBits > 7)
            {
                Globs.Throw <ArgumentException>("ShiftRightInternal: Can only shift up to 7 bits");
                numBits = 0;
            }
            int numCarryBits = 8 - numBits;
            var y            = new byte[x.Length];

            for (int j = x.Length - 1; j >= 0; j--)
            {
                y[j] = (byte)(x[j] >> numBits);
                if (j != 0)
                {
                    y[j] |= (byte)(x[j - 1] << numCarryBits);
                }
            }
            return(y);
        }