Exemple #1
0
 internal override void ToHost(Marshaller m)
 {
     Algorithm = (TpmAlgId)m.Get(typeof(TpmAlgId), "algorithm");
     if (Algorithm == TpmAlgId.None || Algorithm == TpmAlgId.Null)
     {
         return;
     }
     KeyBits = (ushort)m.Get(typeof(ushort), "keyBits");
     Mode    = (TpmAlgId)m.Get(typeof(TpmAlgId), "mode");
 }
Exemple #2
0
        /// <summary>
        /// Instantiates the object using a TPM generated key pair
        /// </summary>
        /// <param name="pub"></param>
        /// <param name="priv"></param>
        public RawRsa(TpmPublic pub, TpmPrivate priv)
        {
            var m        = new Marshaller(priv.buffer);
            var privSize = m.Get <UInt16>();

            // Assert that the private key blob is in plain text
            Debug.Assert(priv.buffer.Length == privSize + 2);
            var sens = m.Get <Sensitive>();

            Init(pub, sens.sensitive as Tpm2bPrivateKeyRsa);
        }
Exemple #3
0
        private TpmRc GetResultCode(byte[] responseBuf)
        {
            var mOut = new Marshaller(responseBuf);
            // ReSharper disable once UnusedVariable
            var responseTag = mOut.Get <TpmSt>();
            // ReSharper disable once UnusedVariable
            var responseParamSize = mOut.Get <uint>();
            var resultCode        = mOut.Get <TpmRc>();

            return(resultCode);
        }
Exemple #4
0
        public Sensitive GetSensitive()
        {
            TpmPublic  fromCspPublic;
            TpmPrivate fromCspPrivate = Csp.CspToTpm(ExportCspBlob(), out fromCspPublic);
            var        m        = new Marshaller(fromCspPrivate.buffer);
            ushort     privSize = m.Get <UInt16>();

            if (fromCspPrivate.buffer.Length != privSize + 2)
            {
                Globs.Throw("Invalid key blob");
            }
            return(m.Get <Sensitive>());
        }
Exemple #5
0
        public static T FromTpmRepresentation <T>(byte[] b)
        {
            var    m   = new Marshaller(b);
            Object obj = m.Get <T>();

            return((T)obj);
        }
Exemple #6
0
        internal override void ToHost(Marshaller m)
        {
            Algorithm = m.Get <TpmAlgId>();
            switch (Algorithm)
            {
            case TpmAlgId.None:
            case TpmAlgId.Null:
                return;

            case TpmAlgId.Xor:
                KeyBits = 0;
                Mode    = m.Get <TpmAlgId>();
                break;

            case TpmAlgId.Aes:
                KeyBits = m.Get <ushort>();
                Mode    = m.Get <TpmAlgId>();
                break;

            default:
                throw new NotImplementedException();
            }
        }
Exemple #7
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)
            {
                throw new Exception("Ill formed TPM2B");
            }
            var ret = new byte[len];

            Array.Copy(x, 2, ret, 0, len);
            return(ret);
        }
Exemple #8
0
        internal override void ToHost(Marshaller m)
        {
            Algorithm = m.Get <TpmAlgId>();
            switch (Algorithm)
            {
            case TpmAlgId.None:
            case TpmAlgId.Null:
                return;

            case TpmAlgId.Xor:
                KeyBits = 0;
                Mode    = m.Get <TpmAlgId>();
                break;

            case TpmAlgId.Aes:
                KeyBits = m.Get <ushort>();
                Mode    = m.Get <TpmAlgId>();
                break;

            default:
                Globs.Throw <NotImplementedException>("SymDef.ToHost: Unknown algorithm");
                break;
            }
        }
Exemple #9
0
        internal override void ToHost(Marshaller m)
        {
            var id = (TpmAlgId)m.Get(typeof(TpmAlgId), "HashAlg");

            if (id == TpmAlgId.Null)
            {
                _HashAlg = id;
                HashData = new byte[0];
                return;
            }
            _HashAlg = id;
            int hashLength = CryptoLib.DigestSize(id);

            HashData = m.GetArray <byte>(hashLength, "HashData");
        }
        /// <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;
            }
        }
        public RawRsa(CryptographicKey key)
        {
            IBuffer buf = key.Export(CryptographicPrivateKeyBlobType.BCryptPrivateKey);

            byte[] blob;
            CryptographicBuffer.CopyToByteArray(buf, out blob);

            var m      = new Marshaller(blob, DataRepresentation.LittleEndian);
            var header = m.Get <BCryptRsaKeyBlob>();

            E        = FromBigEndian(m.GetArray <byte>((int)header.cbPublicExp));
            N        = FromBigEndian(m.GetArray <byte>((int)header.cbModulus));
            P        = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            Q        = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2));
            DP       = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            DQ       = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2));
            InverseQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            D        = FromBigEndian(m.GetArray <byte>((int)header.cbModulus));
        }
Exemple #12
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);
        }
        /// <summary>
        ///  Generates new key pair using OS CSP
        /// </summary>
        /// <param name="numBits"></param>
        /// <param name="publicExponent"></param>
        public RawRsa(int numBits, int publicExponent = 65537)
        {
            AsymmetricKeyAlgorithmProvider prov = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaOaepSha256);
            CryptographicKey key = prov.CreateKeyPair((uint)numBits);
            IBuffer          buf = key.Export(CryptographicPrivateKeyBlobType.BCryptPrivateKey);

            byte[] blob;
            CryptographicBuffer.CopyToByteArray(buf, out blob);

            var m      = new Marshaller(blob, DataRepresentation.LittleEndian);
            var header = m.Get <BCryptRsaKeyBlob>();

            E        = FromBigEndian(m.GetArray <byte>((int)header.cbPublicExp));
            N        = FromBigEndian(m.GetArray <byte>((int)header.cbModulus));
            P        = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            Q        = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2));
            DP       = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            DQ       = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2));
            InverseQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            D        = FromBigEndian(m.GetArray <byte>((int)header.cbModulus));
        }
Exemple #14
0
        /// <summary>
        ///  Generates new key pair using OS CSP
        /// </summary>
        /// <param name="numBits"></param>
        /// <param name="publicExponent"></param>
        public RawRsa(int numBits, int publicExponent = 65537)
        {
#if TSS_USE_BCRYPT
            var    key    = AsymCryptoSystem.Generate(Native.BCRYPT_RSA_ALGORITHM, (uint)numBits);
            byte[] blob   = key.Export(Native.BCRYPT_RSAFULLPRIVATE_BLOB);
            var    m      = new Marshaller(blob, DataRepresentation.LittleEndian);
            var    header = m.Get <BCryptRsaKeyBlob>();
            E        = FromBigEndian(m.GetArray <byte>((int)header.cbPublicExp));
            N        = FromBigEndian(m.GetArray <byte>((int)header.cbModulus));
            P        = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            Q        = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2));
            DP       = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            DQ       = FromBigEndian(m.GetArray <byte>((int)header.cbPrime2));
            InverseQ = FromBigEndian(m.GetArray <byte>((int)header.cbPrime1));
            D        = FromBigEndian(m.GetArray <byte>((int)header.cbModulus));
#else
            using (var prov = new RSACryptoServiceProvider(numBits))
            {
                Init(prov.ExportParameters(true), numBits);
            }
#endif
        }
            } // class PrivateKeyBlob


            // Trailing parameters are used to populate TpmPublic generated for the key from the blob.
            public static TpmPrivate CspToTpm(byte[] cspPrivateBlob, out TpmPublic tpmPub,
                                              TpmAlgId nameAlg        = TpmAlgId.Sha1,
                                              ObjectAttr keyAttrs     = ObjectAttr.Decrypt | ObjectAttr.UserWithAuth,
                                              IAsymSchemeUnion scheme = null,
                                              SymDefObject symDef     = null)
            {
                if (scheme == null)
                {
                    scheme = new NullAsymScheme();
                }
                if (symDef == null)
                {
                    symDef = new SymDefObject();
                }

                var m          = new Marshaller(cspPrivateBlob, DataRepresentation.LittleEndian);
                var cspPrivate = m.Get <Csp.PrivateKeyBlob>();
                var keyAlg     = cspPrivate.publicKeyStruc.aiKeyAlg;

                if (keyAlg != Csp.AlgId.CAlgRsaKeyX && keyAlg != Csp.AlgId.CAlgRsaSign)
                {
                    Globs.Throw <NotSupportedException>("CSP blobs for keys of type " + keyAlg.ToString("X") + " are not supported");
                    tpmPub = new TpmPublic();
                    return(new TpmPrivate());
                }

                var rsaPriv = new Tpm2bPrivateKeyRsa(Globs.ReverseByteOrder(cspPrivate.prime1));
                var sens    = new Sensitive(new byte[0], new byte[0], rsaPriv);

                tpmPub = new TpmPublic(nameAlg, keyAttrs, new byte[0],
                                       new RsaParms(symDef,
                                                    scheme,
                                                    (ushort)cspPrivate.rsaPubKey.bitlen,
                                                    cspPrivate.rsaPubKey.pubexp),
                                       new Tpm2bPublicKeyRsa(Globs.ReverseByteOrder(cspPrivate.modulus)));

                return(new TpmPrivate(sens.GetTpm2BRepresentation()));
            }
Exemple #16
0
        internal virtual void ToHost(Marshaller m)
        {
            var members = GetFieldsToMarshal(true);

            dbg.Indent();
            for (int i = 0; i < members.Length; ++i)
            {
                TpmStructMemberInfo memInfo = members[i];
                Type memType = Globs.GetMemberType(memInfo);
                var  wt      = members[i].WireType;
                switch (wt)
                {
                case MarshalType.Union:
                {
                    dbg.Trace("Union " + memType.Name + " with selector " + memInfo.Tag.Value);
                    memInfo.Value = m.Get(UnionElementFromSelector(memType, memInfo.Tag.Value), memType.Name);
                    break;
                }

                case MarshalType.FixedLengthArray:
                {
                    object arr = Globs.GetMember(memInfo, this);
                    memInfo.Value = m.GetArray(memType.GetElementType(), (arr as Array).Length, memInfo.Name);
                    break;
                }

                case MarshalType.VariableLengthArray:
                {
                    int size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName);
                    memInfo.Value = m.GetArray(memType.GetElementType(), size, memInfo.Name);
                    Debug.Assert(size == ((Array)memInfo.Value).Length);
                    dbg.Trace("Received Array " + memInfo.Name + " of size " + size);
                    break;
                }

                case MarshalType.SizedStruct:
                {
                    int size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName);
                    if (size != 0)
                    {
                        memInfo.Value = m.Get(memType, memInfo.Name);
                        Debug.Assert(size == Marshaller.GetTpmRepresentation(memInfo.Value).Length);
                    }
                    dbg.Trace("Received Struct " + memInfo.Name + " of size " + size);
                    break;
                }

                default:
                    // Only attempt unmarshaling a field, if it is not sized or
                    // if its size is non-zero.
                    if (memInfo.Tag == null ||
                        memInfo.Tag.GetValueAsUInt() != 0)
                    {
                        memInfo.Value = m.Get(memType, memInfo.Name);
                    }
                    break;
                }
                dbg.Trace((i + 1) + ": " + memInfo.Name + " = " + memInfo.Value);
                // Some property values are dynamically obtained from their linked fields.
                // Correspondingly, they do not have a setter, so we bypass them here.
                Debug.Assert(wt != MarshalType.LengthOfStruct && wt != MarshalType.ArrayCount);
                if (wt != MarshalType.UnionSelector)
                {
                    Globs.SetMember(memInfo, this, memInfo.Value);
                }
            }
            dbg.Unindent();
        }
Exemple #17
0
        /// <summary>
        /// Implements unmarshaling logic for most of the TPM object types.
        /// Can be overridden if a custom unmarshaling logic is required (e.g.
        /// when unmarshaling of a field depends on other field's value).
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        internal virtual void ToHost(Marshaller m)
        {
            dbg.Indent();
            var  members      = GetFieldsToMarshal(true);
            uint mshlStartPos = m.GetGetPos();

            for (int i = 0; i < members.Length; ++i)
            {
                TpmStructMemberInfo memInfo = members[i];
                Type memType  = Globs.GetMemberType(memInfo);
                var  wireType = memInfo.WireType;
                int  size     = -1;
                switch (wireType)
                {
                case MarshalType.Union:
                {
                    dbg.Trace("Union " + memType.Name +
                              " with selector " + memInfo.Tag.Value);
                    var elt = UnionElementFromSelector(memType, memInfo.Tag.Value);
                    memInfo.Value = m.Get(elt, memType.Name);
                    break;
                }

                case MarshalType.FixedLengthArray:
                {
                    object arr = Globs.GetMember(memInfo, this);
                    memInfo.Value = m.GetArray(memType.GetElementType(),
                                               (arr as Array).Length, memInfo.Name);
                    break;
                }

                case MarshalType.SpecialVariableLengthArray:
                {
                    size = CryptoLib.DigestSize((TpmAlgId)members[i - 1].Value);
                    UnmarshalArray(m, memInfo, memType, size);
                    break;
                }

                case MarshalType.VariableLengthArray:
                {
                    size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName);
                    UnmarshalArray(m, memInfo, memType, size);
                    break;
                }

                case MarshalType.EncryptedVariableLengthArray:
                {
                    uint unmarshaled = m.GetGetPos() - mshlStartPos;
                    size = m.SizedStructLen[m.SizedStructLen.Count - 1] - (int)unmarshaled;
                    UnmarshalArray(m, memInfo, memType, size);
                    break;
                }

                case MarshalType.SizedStruct:
                {
                    size = m.GetSizeTag(memInfo.SizeLength, memInfo.SizeName);
                    if (size == 0)
                    {
                        break;
                    }
                    m.SizedStructLen.Add(size);
                    memInfo.Value = m.Get(memType, memInfo.Name);
                    int unmSize = Marshaller.GetTpmRepresentation(memInfo.Value).Length;
                    if (unmSize != size)
                    {
                        if (unmSize < size && memType.Name == "TpmPublic")
                        {
                            var pub     = memInfo.Value as TpmPublic;
                            var label   = Marshaller.GetTpmRepresentation(pub.unique);
                            var context = m.GetArray(typeof(byte), size - unmSize, "")
                                          as byte[];
                            pub.unique = new TpmDerive(label, context);
                        }
                        else
                        {
                            var msg = string.Format("Invalid size {0} (instead of "
                                                    + "{1}) for unmarshaled {2}.{3}",
                                                    unmSize, size, this.GetType(), memInfo.Name);
                            throw new TssException(msg);
                        }
                    }
                    m.SizedStructLen.RemoveAt(m.SizedStructLen.Count - 1);
                    break;
                }

                default:
                    // Only attempt unmarshaling a field, if it is not sized or
                    // if its size is non-zero.
                    if (memInfo.Tag == null ||
                        memInfo.Tag.GetValueAsUInt() != 0)
                    {
                        memInfo.Value = m.Get(memType, memInfo.Name);
                    }
                    break;
                }
                dbg.Trace((i + 1) + ": " + wireType + " " + memInfo.Name +
                          (size != -1 ? " of size " + size : ""));
                // Some property values are dynamically obtained from their linked fields.
                // Correspondingly, they do not have a setter, so we bypass them here.
                Debug.Assert(wireType != MarshalType.LengthOfStruct && wireType != MarshalType.ArrayCount);
                if (wireType != MarshalType.UnionSelector)
                {
                    Globs.SetMember(memInfo, this, memInfo.Value);
                }
            }
            dbg.Unindent();
        }
Exemple #18
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;
#if TSS_USE_BCRYPT
                Key = Generate(Native.BCRYPT_RSA_ALGORITHM, rsaParams.keyBits);
                if (Key == UIntPtr.Zero)
                {
                    Globs.Throw("Failed to generate RSA key");
                    return;
                }
                byte[] blob   = Export(Native.BCRYPT_RSAPUBLIC_BLOB);
                var    m      = new Marshaller(blob, DataRepresentation.LittleEndian);
                var    header = m.Get <BCryptRsaKeyBlob>();
                /*var exponent = */ m.GetArray <byte>((int)header.cbPublicExp);
                var modulus = m.GetArray <byte>((int)header.cbModulus);
#else
                RsaProvider = new RSACryptoServiceProvider(rsaParams.keyBits);
                var modulus = RsaProvider.ExportParameters(true).Modulus;
#endif
                var pubId = new Tpm2bPublicKeyRsa(modulus);
                PublicParms.unique = pubId;
                break;
            }

#if !__MonoCS__
            case TpmAlgId.Ecc:
            {
                var eccParms = keyParams.parameters as EccParms;
                var alg      = RawEccKey.GetEccAlg(keyParams);
                if (alg == null)
                {
                    Globs.Throw <ArgumentException>("Unknown ECC curve");
                    return;
                }
#if TSS_USE_BCRYPT
                Key = Generate(alg, (uint)RawEccKey.GetKeyLength(eccParms.curveID));
#else
                var keyParmsX = new CngKeyCreationParameters {
                    ExportPolicy = CngExportPolicies.AllowPlaintextExport
                };
                using (CngKey key = CngKey.Create(alg, null, keyParmsX))
                {
                    byte[] keyIs = key.Export(CngKeyBlobFormat.EccPublicBlob);
                    CngKey.Import(keyIs, CngKeyBlobFormat.EccPublicBlob);

                    if (keyParams.objectAttributes.HasFlag(ObjectAttr.Sign))
                    {
                        EcdsaProvider = new ECDsaCng(key);
                    }
                    else
                    {
                        EcDhProvider = new ECDiffieHellmanCng(key);
                    }
                }
#endif // !TSS_USE_BCRYPT && !__MonoCS__
                break;
            }
#endif // !__MonoCS__
            default:
                Globs.Throw <ArgumentException>("Algorithm not supported");
                break;
            }
        }