Inheritance: TpmStructureBase
Esempio n. 1
0
        /// <summary>
        /// Creates a Private area for this key that will be loadable on a TPM though TPM2_Load() if the target TPM already has the parent
        /// storage key "parent" loaded.  This function lets applications create key-hierarchies in software that can be loaded into
        /// a TPM once the parent has been "TPM2_Import'ed."
        /// TPM2_Import() supports plaintext import.  To get this sort of import blob set intendedParent
        /// to null
        /// </summary>
        /// <param name="intendedParent"></param>
        /// <returns></returns>
        public TpmPrivate GetPrivate(TssObject intendedParent)
        {
            SymDefObject symDef = GetSymDef(intendedParent.publicPart);

            // Figure out how many bits we will need from the KDF
            byte[] parentSymValue = intendedParent.sensitivePart.seedValue;
            byte[] iv             = Globs.GetRandomBytes(SymmCipher.GetBlockSize(symDef));

            // The encryption key is calculated with a KDF
            byte[] symKey = KDF.KDFa(intendedParent.publicPart.nameAlg,
                                     parentSymValue,
                                     "STORAGE",
                                     GetName(),
                                     new byte[0],
                                     symDef.KeyBits);

            byte[] newPrivate = KeyWrapper.CreatePrivateFromSensitive(symDef,
                                                                      symKey,
                                                                      iv,
                                                                      sensitivePart,
                                                                      publicPart.nameAlg,
                                                                      publicPart.GetName(),
                                                                      intendedParent.publicPart.nameAlg,
                                                                      intendedParent.sensitivePart.seedValue);

            return(new TpmPrivate(newPrivate));
        }
Esempio n. 2
0
 public static byte[] Decrypt(SymDefObject symDef, byte[] key, byte[] iv, byte[] dataToDecrypt)
 {
     using (SymmCipher cipher = Create(symDef, key, iv))
     {
         return(cipher.Decrypt(dataToDecrypt));
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Creates a Private area for this key so that it can be loaded into a TPM by
        /// TPM2_Load() if the target TPM already has the storage key 'parent' loaded.
        /// This function lets an application to create key hierarchies in software
        /// that can be loaded into a TPM once the parent has been TPM2_Import'ed.
        /// TPM2_Import() supports plaintext import. To get this sort of import blob,
        /// set 'parent' to null.
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        public TpmPrivate GetPrivate(TssObject parent)
        {
            SymDefObject symDef = GetSymDef(parent.Public);

            // Figure out how many bits we will need from the KDF
            byte[] parentSymSeed = parent.Sensitive.seedValue;
            Transform(parentSymSeed);
            byte[] iv = (symDef.Mode == TpmAlgId.Ecb) ? new byte[0]
                                : Globs.GetRandomBytes(SymCipher.GetBlockSize(symDef));

            // The encryption key is calculated with a KDF
            byte[] symKey = KDF.KDFa(parent.Public.nameAlg,
                                     parentSymSeed,
                                     "STORAGE",
                                     GetName(),
                                     new byte[0],
                                     symDef.KeyBits);

            Transform(symKey);

            byte[] newPrivate = KeyWrapper.CreatePrivateFromSensitive(
                symDef,
                symKey,
                iv,
                Sensitive,
                Public.nameAlg,
                Public.GetName(),
                parent.Public.nameAlg,
                parent.Sensitive.seedValue,
                TransformerCallback);
            Transform(newPrivate);
            return(new TpmPrivate(newPrivate));
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a *software* root 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.
        /// </summary>
        /// <returns></returns>
        public static TssObject CreateStorageParent(TpmPublic keyParameters, AuthValue authVal)
        {
            var newKey = new TssObject();
            // Create a new asymmetric key from the supplied parameters
            IPublicIdUnion           publicId;
            ISensitiveCompositeUnion sensitiveData = CreateSensitiveComposite(keyParameters, out publicId);

            // fill in the public data
            newKey.publicPart        = keyParameters.Copy();
            newKey.publicPart.unique = publicId;

            // Create the associated symmetric key -
            SymDefObject symDef = GetSymDef(keyParameters);

            byte[] symmKey;
            if (symDef.Algorithm != TpmAlgId.Null)
            {
                using (var symmCipher = SymmCipher.Create(symDef))
                {
                    symmKey = symmCipher.KeyData;
                }
            }
            else
            {
                symmKey = new byte[0];
            }
            // Fill in the fields for the symmetric private-part of the asymmetric key
            var sens = new Sensitive(authVal.AuthVal, symmKey, sensitiveData);

            newKey.sensitivePart = sens;

            // And return the new key
            return(newKey);
        }
Esempio n. 5
0
 public static int GetBlockSize(SymDefObject symDef)
 {
     if (symDef.Algorithm != TpmAlgId.Aes)
     {
         Globs.Throw<ArgumentException>("Unsupported algorithm " + symDef.Algorithm);
         return 0;
     }
     return 16;
 }
Esempio n. 6
0
 public static int GetBlockSize(SymDefObject symDef)
 {
     if (symDef.Algorithm != TpmAlgId.Aes)
     {
         Globs.Throw <ArgumentException>("Unsupported algorithm " + symDef.Algorithm);
         return(0);
     }
     return(16);
 }
Esempio n. 7
0
        /// <summary>
        /// Create activation blobs that can be passed to ActivateCredential.  Two blobs are returned -
        /// (a) - encryptedSecret - is the symmetric key cfb-symmetrically encrypted with an enveloping key
        /// (b) credentialBlob (the return value of this function) - is the enveloping key OEAP (RSA) encrypted
        ///         by the public part of this key.
        /// </summary>
        /// <param name="secret"></param>
        /// <param name="nameAlgId"></param>
        /// <param name="nameOfKeyToBeActivated"></param>
        /// <param name="encryptedSecret"></param>
        /// <returns>CredentialBlob (</returns>
        public byte[] CreateActivationCredentials(
            byte[] secret,
            TpmAlgId nameAlgId,
            byte[] nameOfKeyToBeActivated,
            out byte[] encryptedSecret)
        {
            byte[] seed, encSecret;

            switch (type)
            {
            case TpmAlgId.Rsa:
                // The seed should be the same size as the symmKey
                seed      = Globs.GetRandomBytes((CryptoLib.DigestSize(nameAlg) + 7) / 8);
                encSecret = EncryptOaep(seed, ActivateEncodingParms);
                break;

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

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

            var cvx = new Tpm2bDigest(secret);

            byte[] cvTpm2B = Marshaller.GetTpmRepresentation(cvx);

            SymDefObject symDef = TssObject.GetSymDef(this);

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

            byte[] encIdentity;
            using (SymmCipher symm2 = SymmCipher.Create(symDef, symKey))
            {
                encIdentity = symm2.Encrypt(cvTpm2B);
            }

            var hmacKeyBits = CryptoLib.DigestSize(nameAlg);

            byte[] hmacKey   = KDF.KDFa(nameAlg, seed, "INTEGRITY", new byte[0], new byte[0], hmacKeyBits * 8);
            byte[] outerHmac = CryptoLib.HmacData(nameAlg,
                                                  hmacKey,
                                                  Globs.Concatenate(encIdentity, nameOfKeyToBeActivated));

            byte[] activationBlob = Globs.Concatenate(
                Marshaller.ToTpm2B(outerHmac),
                encIdentity);
            encryptedSecret = encSecret;

            return(activationBlob);
        }
Esempio n. 8
0
        /// <summary>
        /// Create an enveloped (encrypted and integrity protected) private area from a provided sensitive.
        /// </summary>
        /// <param name="iv"></param>
        /// <param name="sens"></param>
        /// <param name="nameHash"></param>
        /// <param name="publicName"></param>
        /// <param name="symWrappingAlg"></param>
        /// <param name="symKey"></param>
        /// <param name="parentNameAlg"></param>
        /// <param name="parentSeed"></param>
        /// <param name="f"></param>
        /// <returns></returns>
        public static byte[] CreatePrivateFromSensitive(
            SymDefObject symWrappingAlg,
            byte[] symKey,
            byte[] iv,
            Sensitive sens,
            TpmAlgId nameHash,
            byte[] publicName,
            TpmAlgId parentNameAlg,
            byte[] parentSeed,
            TssObject.Transformer f = null)
        {
            // ReSharper disable once InconsistentNaming
            byte[] tpm2bIv = Marshaller.ToTpm2B(iv);
            Transform(tpm2bIv, f);

            byte[] sensitive = sens.GetTpmRepresentation();
            Transform(sensitive, f);

            // ReSharper disable once InconsistentNaming
            byte[] tpm2bSensitive = Marshaller.ToTpm2B(sensitive);
            Transform(tpm2bSensitive, f);

            byte[] encSensitive = SymCipher.Encrypt(symWrappingAlg, symKey, iv, tpm2bSensitive);
            Transform(encSensitive, f);
            byte[] decSensitive = SymCipher.Decrypt(symWrappingAlg, symKey, iv, encSensitive);
            Debug.Assert(f != null || Globs.ArraysAreEqual(decSensitive, tpm2bSensitive));

            var hmacKeyBits = CryptoLib.DigestSize(parentNameAlg) * 8;

            byte[] hmacKey = KDF.KDFa(parentNameAlg, parentSeed, "INTEGRITY", new byte[0], new byte[0], hmacKeyBits);
            Transform(hmacKey, f);

            byte[] dataToHmac = Marshaller.GetTpmRepresentation(tpm2bIv,
                                                                encSensitive,
                                                                publicName);
            Transform(dataToHmac, f);

            byte[] outerHmac = CryptoLib.Hmac(parentNameAlg, hmacKey, dataToHmac);
            Transform(outerHmac, f);

            byte[] priv = Marshaller.GetTpmRepresentation(Marshaller.ToTpm2B(outerHmac),
                                                          tpm2bIv,
                                                          encSensitive);
            Transform(priv, f);
            return(priv);
        }
Esempio n. 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 = SymmCipher.Encrypt(symWrappingAlg, symKey, iv, tpm2bSensitive);
            Transform(encSensitive, f);
            byte[] decSensitive = SymmCipher.Decrypt(symWrappingAlg, symKey, iv, encSensitive);
            Debug.Assert(f != null || Globs.ArraysAreEqual(decSensitive, tpm2bSensitive));

            uint hmacKeyBits = (uint)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.HmacData(parentNameAlg, hmacKey, dataToHmac);
            Transform(outerHmac, f);

            byte[] priv = Marshaller.GetTpmRepresentation(Marshaller.ToTpm2B(outerHmac),
                                                          tpm2bIv,
                                                          encSensitive);
            Transform(priv, f);
            return priv;
        }
Esempio n. 10
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 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);
        }
Esempio n. 11
0
            } // 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()));
            }
        /// <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)
        {
            // ReSharper disable once InconsistentNaming
            byte[] tpm2bIv = Marshaller.ToTpm2B(iv);

            byte[] sensitive = sens.GetTpmRepresentation();

            // ReSharper disable once InconsistentNaming
            byte[] tpm2bSensitive = Marshaller.ToTpm2B(sensitive);

            byte[] encSensitive = SymmCipher.Encrypt(symWrappingAlg, symKey, iv, tpm2bSensitive);
            byte[] decSensitive = SymmCipher.Decrypt(symWrappingAlg, symKey, iv, encSensitive);

            var hmacKeyBits = CryptoLib.DigestSize(parentNameAlg) * 8;

            byte[] hmacKey = KDF.KDFa(parentNameAlg, parentSeed, "INTEGRITY", new byte[0], new byte[0], hmacKeyBits);

            byte[] dataToHmac = Marshaller.GetTpmRepresentation(tpm2bIv,
                                                                encSensitive,
                                                                publicName);

            byte[] outerHmac = CryptoLib.HmacData(parentNameAlg, hmacKey, dataToHmac);

            byte[] priv = Marshaller.GetTpmRepresentation(Marshaller.ToTpm2B(outerHmac),
                                                          tpm2bIv,
                                                          encSensitive);
            return(priv);
        }
Esempio n. 13
0
        /// <summary>
        /// De-envelope inner-wrapped duplication blob.
        /// TODO: Move this to TpmPublic and make it fully general
        /// </summary>
        /// <param name="exportedPrivate"></param>
        /// <param name="encAlg"></param>
        /// <param name="encKey"></param>
        /// <param name="nameAlg"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static Sensitive SensitiveFromDuplicateBlob(TpmPrivate exportedPrivate, SymDefObject encAlg, byte[] encKey, TpmAlgId nameAlg, byte[] name)
        {
            byte[] dupBlob = exportedPrivate.buffer;
            byte[] sensNoLen;
            using (SymmCipher c = Create(encAlg, encKey))
            {
                byte[] innerObject = c.Decrypt(dupBlob);
                byte[] innerIntegrity, sensitive;

                KDF.Split(innerObject,
                          16 + CryptoLib.DigestSize(nameAlg) * 8,
                          out innerIntegrity,
                          8 * (innerObject.Length - CryptoLib.DigestSize(nameAlg) - 2),
                          out sensitive);

                byte[] expectedInnerIntegrity = Marshaller.ToTpm2B(CryptoLib.HashData(nameAlg, sensitive, name));

                if (!Globs.ArraysAreEqual(expectedInnerIntegrity, innerIntegrity))
                {
                    Globs.Throw("SensitiveFromDuplicateBlob: Bad inner integrity");
                }

                sensNoLen = Marshaller.Tpm2BToBuffer(sensitive);
            }
            var sens = Marshaller.FromTpmRepresentation<Sensitive>(sensNoLen);
            return sens;
        }
Esempio n. 14
0
 public static byte[] Decrypt(SymDefObject symDef, byte[] key, byte[] iv, byte[] dataToDecrypt)
 {
     using (SymmCipher cipher = Create(symDef, key, iv))
     {
         return cipher.Decrypt(dataToDecrypt);
     }
 }
Esempio n. 15
0
 ///<param name = "the_parentHandle">the handle of the new parent for the object Auth Index: 1 Auth Role: USER</param>
 ///<param name = "the_encryptionKey">the optional symmetric encryption key used as the inner wrapper for duplicate If symmetricAlg is TPM_ALG_NULL, then this parameter shall be the Empty Buffer.</param>
 ///<param name = "the_objectPublic">the public area of the object to be imported This is provided so that the integrity value for duplicate and the object attributes can be checked. NOTE	Even if the integrity value of the object is not checked on input, the object Name is required to create the integrity value for the imported object.</param>
 ///<param name = "the_duplicate">the symmetrically encrypted duplicate object that may contain an inner symmetric wrapper</param>
 ///<param name = "the_inSymSeed">symmetric key used to encrypt duplicate inSymSeed is encrypted/encoded using the algorithms of newParent.</param>
 ///<param name = "the_symmetricAlg">definition for the symmetric algorithm to use for the inner wrapper If this algorithm is TPM_ALG_NULL, no inner wrapper is present and encryptionKey shall be the Empty Buffer.</param>
 public Tpm2ImportRequest(
 TpmHandle the_parentHandle,
 byte[] the_encryptionKey,
 TpmPublic the_objectPublic,
 TpmPrivate the_duplicate,
 byte[] the_inSymSeed,
 SymDefObject the_symmetricAlg
 )
 {
     this.parentHandle = the_parentHandle;
     this.encryptionKey = the_encryptionKey;
     this.objectPublic = the_objectPublic;
     this.duplicate = the_duplicate;
     this.inSymSeed = the_inSymSeed;
     this.symmetricAlg = the_symmetricAlg;
 }
Esempio n. 16
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="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));
        }
Esempio n. 17
0
        /// <summary>
        /// Create activation blobs that can be passed to ActivateCredential. Two
        /// blobs are returned:
        /// 1) encryptedSecret - symmetric key cfb-symmetrically encrypted with the
        ///                      enveloping key;
        /// 2) credentialBlob -  the enveloping key OEAP (RSA) encrypted by the public
        ///                      part of this key. This is the return value of this
        ///                      function
        /// </summary>
        /// <param name="secret"></param>
        /// <param name="nameOfKeyToBeActivated"></param>
        /// <param name="encryptedSecret"></param>
        /// <returns>CredentialBlob (</returns>
        public IdObject CreateActivationCredentials(byte[] secret,
                                                    byte[] nameOfKeyToBeActivated,
                                                    out byte[] encryptedSecret)
        {
            byte[] seed, encSecret;

            switch (type)
            {
            case TpmAlgId.Rsa:
                // The seed should be the same size as the name algorithmdigest
                seed      = Globs.GetRandomBytes(CryptoLib.DigestSize(nameAlg));
                encSecret = EncryptOaep(seed, ActivateEncodingParms);
                break;

            case TpmAlgId.Ecc:
                EccPoint ephemPubPt;
                seed      = EcdhGetKeyExchangeKey(ActivateEncodingParms, out ephemPubPt);
                encSecret = Marshaller.GetTpmRepresentation(ephemPubPt);
                break;

            default:
                Globs.Throw <NotImplementedException>(
                    "CreateActivationCredentials: Unsupported algorithm");
                encryptedSecret = new byte[0];
                return(null);
            }

            Transform(seed);
            Transform(encSecret);

            var cvx = new Tpm2bDigest(secret);

            byte[] cvTpm2B = Marshaller.GetTpmRepresentation(cvx);
            Transform(cvTpm2B);

            SymDefObject symDef = TssObject.GetSymDef(this);

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

            byte[] encIdentity;
            // TPM only uses CFB mode in its command implementations
            var sd = symDef.Copy();

            sd.Mode = TpmAlgId.Cfb;
            using (var sym = SymCipher.Create(sd, symKey))
            {
                // Not all keys specs are supported by SW crypto
                if (sym == null)
                {
                    encryptedSecret = null;
                    return(null);
                }
                encIdentity = sym.Encrypt(cvTpm2B);
            }
            Transform(encIdentity);

            var hmacKeyBits = CryptoLib.DigestSize(nameAlg);

            byte[] hmacKey = KDF.KDFa(nameAlg, seed, "INTEGRITY",
                                      new byte[0], new byte[0], hmacKeyBits * 8);
            Transform(hmacKey);
            byte[] outerHmac = CryptoLib.Hmac(nameAlg, hmacKey,
                                              Globs.Concatenate(encIdentity, nameOfKeyToBeActivated));
            Transform(outerHmac);


            encryptedSecret = encSecret;
            return(new IdObject(outerHmac, encIdentity));
        }
Esempio n. 18
0
 public Tpm2DuplicateRequest()
 {
     objectHandle = new TpmHandle();
     newParentHandle = new TpmHandle();
     encryptionKeyIn = new byte[0];
     symmetricAlg = new SymDefObject();
 }
Esempio n. 19
0
 public SymDefObject(SymDefObject the_SymDefObject)
 {
     if((Object) the_SymDefObject == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     Algorithm = the_SymDefObject.Algorithm;
     KeyBits = the_SymDefObject.KeyBits;
     Mode = the_SymDefObject.Mode;
 }
Esempio n. 20
0
 public byte[] Duplicate(
     TpmHandle objectHandle,
     TpmHandle newParentHandle,
     byte[] encryptionKeyIn,
     SymDefObject symmetricAlg,
     [SuppressMessage("Microsoft.Design", "CA1021")]
     out TpmPrivate duplicate,
     [SuppressMessage("Microsoft.Design", "CA1021")]
     out byte[] outSymSeed
 )
 {
     Tpm2DuplicateRequest inS = new Tpm2DuplicateRequest();
     inS.objectHandle = objectHandle;
     inS.newParentHandle = newParentHandle;
     inS.encryptionKeyIn = encryptionKeyIn;
     inS.symmetricAlg = symmetricAlg;
     TpmStructureBase outSBase;
     DispatchMethod(TpmCc.Duplicate, (TpmStructureBase) inS, typeof(Tpm2DuplicateResponse), out outSBase, 2, 0);
     Tpm2DuplicateResponse outS = (Tpm2DuplicateResponse) outSBase;
     duplicate = outS.duplicate;
     outSymSeed = outS.outSymSeed;
     return outS.encryptionKeyOut;
 }
Esempio n. 21
0
 public AsymParms()
 {
     symmetric = new SymDefObject();
 }
Esempio n. 22
0
 ///<param name = "the_symmetric">the companion symmetric algorithm for a restricted decryption key and shall be set to a supported symmetric algorithm This field is optional for keys that are not decryption keys and shall be set to TPM_ALG_NULL if not used.</param>
 ///<param name = "the_scheme">for a key with the sign attribute SET, a valid signing scheme for the key type for a key with the decrypt attribute SET, a valid key exchange protocol for a key with sign and decrypt attributes, shall be TPM_ALG_NULL(One of KeySchemeEcdh, KeySchemeEcmqv, SigSchemeRsassa, SigSchemeRsapss, SigSchemeEcdsa, SigSchemeEcdaa, SigSchemeSm2, SigSchemeEcschnorr, EncSchemeRsaes, EncSchemeOaep, SchemeHash, NullAsymScheme)</param>
 public AsymParms(
 SymDefObject the_symmetric,
 IAsymSchemeUnion the_scheme
 )
 {
     this.symmetric = the_symmetric;
     this.scheme = the_scheme;
 }
Esempio n. 23
0
 ///<param name = "the_sym">a symmetric block cipher</param>
 public SymcipherParms(
 SymDefObject the_sym
 )
 {
     this.sym = the_sym;
 }
Esempio n. 24
0
 public SymcipherParms(SymcipherParms the_SymcipherParms)
 {
     if((Object) the_SymcipherParms == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     sym = the_SymcipherParms.sym;
 }
Esempio n. 25
0
 public SymcipherParms()
 {
     sym = new SymDefObject();
 }
Esempio n. 26
0
        /// <summary>
        /// Create a new SymmCipher object with a random key based on the alg and mode supplied.
        /// </summary>
        /// <param name="algId"></param>
        /// <param name="numBits"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static SymmCipher Create(SymDefObject symDef = null, byte[] keyData = null, byte[] iv = null)
        {
            if (symDef == null)
            {
                symDef = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);
            }

#if TSS_USE_BCRYPT
            BCryptAlgorithm alg = null;

            switch (symDef.Algorithm)
            {
                case TpmAlgId.Aes:
                    alg = new BCryptAlgorithm(Native.BCRYPT_AES_ALGORITHM);
                    break;
                case TpmAlgId.Tdes:
                    alg = new BCryptAlgorithm(Native.BCRYPT_3DES_ALGORITHM);
                    break;
                default:
                    Globs.Throw<ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                    break;
            }

            if (keyData == null)
            {
                keyData = Globs.GetRandomBytes(symDef.KeyBits / 8);
            }
            var key = alg.GenerateSymKey(symDef, keyData, GetBlockSize(symDef));
            //key = BCryptInterface.ExportSymKey(keyHandle);
            //keyHandle = alg.LoadSymKey(key, symDef, GetBlockSize(symDef));
            alg.Close();
            return key == null ? null : new SymmCipher(key, keyData, iv);
#else
            SymmetricAlgorithm alg = null; // = new RijndaelManaged();
            bool limitedSupport = false;
            // DES and __3DES are not supported in TPM 2.0 rev. 0.96 to 1.30
            switch (symDef.Algorithm) {
                case TpmAlgId.Aes:
                    alg = new RijndaelManaged();
                    break;
                case TpmAlgId.Tdes:
                    alg = new TripleDESCryptoServiceProvider();
                    limitedSupport = true;
                    break;
                default:
                    Globs.Throw<ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                    break;
            }

            int blockSize = GetBlockSize(symDef);
            alg.KeySize = symDef.KeyBits;
            alg.BlockSize = blockSize * 8;
            alg.Padding = PaddingMode.None;
            alg.Mode = GetCipherMode(symDef.Mode);

            // REVISIT: Get this right for other modes
            if (symDef.Algorithm == TpmAlgId.Tdes && symDef.Mode == TpmAlgId.Cfb)
            {
                alg.FeedbackSize = 8;
            }
            else
            {
                alg.FeedbackSize = alg.BlockSize;
            }

            if (keyData == null)
            {
                // Generate random key
                alg.IV = Globs.GetZeroBytes(blockSize);
                try
                {
                    alg.GenerateKey();
                }
                catch (Exception)
                {
                    alg.Dispose();
                    throw;
                }
            }
            else
            {
                // Use supplied key bits
                alg.Key = keyData;
                if (iv == null)
                {
                    iv = Globs.GetZeroBytes(blockSize);
                }
                else if (iv.Length != blockSize)
                {
                    Array.Resize(ref iv, blockSize);
                }
                alg.IV = iv;
            }

            var symCipher = new SymmCipher(alg);
            symCipher.LimitedSupport = limitedSupport;
            return symCipher;
#endif
        }
Esempio n. 27
0
 public Tpm2DuplicateRequest(Tpm2DuplicateRequest the_Tpm2DuplicateRequest)
 {
     if((Object) the_Tpm2DuplicateRequest == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     objectHandle = the_Tpm2DuplicateRequest.objectHandle;
     newParentHandle = the_Tpm2DuplicateRequest.newParentHandle;
     encryptionKeyIn = the_Tpm2DuplicateRequest.encryptionKeyIn;
     symmetricAlg = the_Tpm2DuplicateRequest.symmetricAlg;
 }
Esempio n. 28
0
 public RsaParms()
 {
     symmetric = new SymDefObject();
 }
Esempio n. 29
0
 public TpmPrivate Import(
     TpmHandle parentHandle,
     byte[] encryptionKey,
     TpmPublic objectPublic,
     TpmPrivate duplicate,
     byte[] inSymSeed,
     SymDefObject symmetricAlg
 )
 {
     Tpm2ImportRequest inS = new Tpm2ImportRequest();
     inS.parentHandle = parentHandle;
     inS.encryptionKey = encryptionKey;
     inS.objectPublic = objectPublic;
     inS.duplicate = duplicate;
     inS.inSymSeed = inSymSeed;
     inS.symmetricAlg = symmetricAlg;
     TpmStructureBase outSBase;
     DispatchMethod(TpmCc.Import, (TpmStructureBase) inS, typeof(Tpm2ImportResponse), out outSBase, 1, 0);
     Tpm2ImportResponse outS = (Tpm2ImportResponse) outSBase;
     return outS.outPrivate;
 }
Esempio n. 30
0
        /// <summary>
        /// Create a new SymCipher object with a random key based on the alg and mode supplied.
        /// </summary>
        /// <param name="symDef"></param>
        /// <param name="keyData"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static SymCipher Create(SymDefObject symDef = null,
                                       byte[] keyData      = null, byte[] iv = null)
        {
            if (symDef == null)
            {
                symDef = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);
            }

#if TSS_USE_BCRYPT
            BCryptAlgorithm alg = null;

            switch (symDef.Algorithm)
            {
            case TpmAlgId.Aes:
                alg = new BCryptAlgorithm(Native.BCRYPT_AES_ALGORITHM);
                break;

            case TpmAlgId.Tdes:
                alg = new BCryptAlgorithm(Native.BCRYPT_3DES_ALGORITHM);
                break;

            default:
                Globs.Throw <ArgumentException>("Unsupported symmetric algorithm "
                                                + symDef.Algorithm);
                return(null);
            }

            if (keyData == null)
            {
                keyData = Globs.GetRandomBytes(symDef.KeyBits / 8);
            }
            var key = alg.GenerateSymKey(symDef, keyData, GetBlockSize(symDef));
            //key = BCryptInterface.ExportSymKey(keyHandle);
            //keyHandle = alg.LoadSymKey(key, symDef, GetBlockSize(symDef));
            alg.Close();
            return(key == null ? null : new SymCipher(key, keyData, iv, GetBlockSize(symDef)));
#else // !TSS_USE_BCRYPT
            if (symDef.Mode == TpmAlgId.Ofb)
            {
                return(null);
            }

            var mode = GetCipherMode(symDef.Mode);
            if (mode == CipherMode_None)
            {
                return(null);
            }

            SymmetricAlgorithm alg = null; // = new RijndaelManaged();
            bool limitedSupport    = false;
            int  feedbackSize      = 0;

            switch (symDef.Algorithm)
            {
            case TpmAlgId.Aes:
                alg      = new RijndaelManaged();
                alg.Mode = mode == CipherMode.CFB ? CipherMode.ECB : mode;
                break;

            case TpmAlgId.Tdes:
                // DES and __3DES are not supported in TPM 2.0 rev. < 1.32
                alg      = new TripleDESCryptoServiceProvider();
                alg.Mode = mode;
                if (mode == CipherMode.CFB)
                {
                    feedbackSize = 8;
                }
                limitedSupport = true;
                break;

            default:
                //Globs.Throw<ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                return(null);
            }

            int blockSize = GetBlockSize(symDef);
            alg.KeySize      = symDef.KeyBits;
            alg.BlockSize    = blockSize * 8;
            alg.Padding      = PaddingMode.None;
            alg.FeedbackSize = feedbackSize == 0 ? alg.BlockSize : feedbackSize;

            if (keyData == null)
            {
                // Generate random key
                alg.IV = Globs.GetZeroBytes(blockSize);
                try
                {
                    alg.GenerateKey();
                }
                catch (Exception)
                {
                    alg.Dispose();
                    throw;
                }
            }
            else
            {
                // Use supplied key bits
                alg.Key = keyData;
                if (iv == null)
                {
                    iv = Globs.GetZeroBytes(blockSize);
                }
                else if (iv.Length != blockSize)
                {
                    Array.Resize(ref iv, blockSize);
                }
                alg.IV = iv;
            }

            var symCipher = new SymCipher(alg, mode);
            symCipher.LimitedSupport = limitedSupport;
            return(symCipher);
#endif // !TSS_USE_BCRYPT
        } // Create()
Esempio n. 31
0
 ///<param name = "the_symmetric">for a restricted decryption key, shall be set to a supported symmetric algorithm, key size, and mode. if the key is not a restricted decryption key, this field shall be set to TPM_ALG_NULL.</param>
 ///<param name = "the_scheme">for an unrestricted signing key, shall be either TPM_ALG_RSAPSS TPM_ALG_RSASSA or TPM_ALG_NULL for a restricted signing key, shall be either TPM_ALG_RSAPSS or TPM_ALG_RSASSA for an unrestricted decryption key, shall be TPM_ALG_RSAES, TPM_ALG_OAEP, or TPM_ALG_NULL unless the object also has the sign attribute for a restricted decryption key, this field shall be TPM_ALG_NULL NOTE	When both sign and decrypt are SET, restricted shall be CLEAR and scheme shall be TPM_ALG_NULL.(One of KeySchemeEcdh, KeySchemeEcmqv, SigSchemeRsassa, SigSchemeRsapss, SigSchemeEcdsa, SigSchemeEcdaa, SigSchemeSm2, SigSchemeEcschnorr, EncSchemeRsaes, EncSchemeOaep, SchemeHash, NullAsymScheme)</param>
 ///<param name = "the_keyBits">number of bits in the public modulus</param>
 ///<param name = "the_exponent">the public exponent A prime number greater than 2. When zero, indicates that the exponent is the default of 216 + 1</param>
 public RsaParms(
 SymDefObject the_symmetric,
 IAsymSchemeUnion the_scheme,
 ushort the_keyBits,
 uint the_exponent
 )
 {
     this.symmetric = the_symmetric;
     this.scheme = the_scheme;
     this.keyBits = the_keyBits;
     this.exponent = the_exponent;
 }
Esempio n. 32
0
 ///<param name = "the_objectHandle">loaded object to duplicate Auth Index: 1 Auth Role: DUP</param>
 ///<param name = "the_newParentHandle">shall reference the public area of an asymmetric key Auth Index: None</param>
 ///<param name = "the_encryptionKeyIn">optional symmetric encryption key The size for this key is set to zero when the TPM is to generate the key. This parameter may be encrypted.</param>
 ///<param name = "the_symmetricAlg">definition for the symmetric algorithm to be used for the inner wrapper may be TPM_ALG_NULL if no inner wrapper is applied</param>
 public Tpm2DuplicateRequest(
 TpmHandle the_objectHandle,
 TpmHandle the_newParentHandle,
 byte[] the_encryptionKeyIn,
 SymDefObject the_symmetricAlg
 )
 {
     this.objectHandle = the_objectHandle;
     this.newParentHandle = the_newParentHandle;
     this.encryptionKeyIn = the_encryptionKeyIn;
     this.symmetricAlg = the_symmetricAlg;
 }
Esempio n. 33
0
 public RsaParms()
 {
     symmetric = new SymDefObject();
     keyBits = 0;
     exponent = 0;
 }
Esempio n. 34
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));
        }
Esempio n. 35
0
 ///<param name = "the_symmetric">for a restricted decryption key, shall be set to a supported symmetric algorithm, key size. and mode. if the key is not a restricted decryption key, this field shall be set to TPM_ALG_NULL.</param>
 ///<param name = "the_scheme">If the sign attribute of the key is SET, then this shall be a valid signing scheme. NOTE	If the sign parameter in curveID indicates a mandatory scheme, then this field shall have the same value. If the decrypt attribute of the key is SET, then this shall be a valid key exchange scheme or TPM_ALG_NULL. If the key is a Storage Key, then this field shall be TPM_ALG_NULL.(One of KeySchemeEcdh, KeySchemeEcmqv, SigSchemeRsassa, SigSchemeRsapss, SigSchemeEcdsa, SigSchemeEcdaa, SigSchemeSm2, SigSchemeEcschnorr, EncSchemeRsaes, EncSchemeOaep, SchemeHash, NullAsymScheme)</param>
 ///<param name = "the_curveID">ECC curve ID</param>
 ///<param name = "the_kdf">an optional key derivation scheme for generating a symmetric key from a Z value If the kdf parameter associated with curveID is not TPM_ALG_NULL then this is required to be NULL. NOTE	There are currently no commands where this parameter has effect and, in the reference code, this field needs to be set to TPM_ALG_NULL.(One of SchemeMgf1, SchemeKdf1Sp80056a, SchemeKdf2, SchemeKdf1Sp800108, NullKdfScheme)</param>
 public EccParms(
 SymDefObject the_symmetric,
 IAsymSchemeUnion the_scheme,
 EccCurve the_curveID,
 IKdfSchemeUnion the_kdf
 )
 {
     this.symmetric = the_symmetric;
     this.scheme = the_scheme;
     this.curveID = the_curveID;
     this.kdf = the_kdf;
 }
Esempio n. 36
0
        /// <summary>
        /// Create a new SymmCipher object with a random key based on the alg and mode supplied.
        /// </summary>
        /// <param name="algId"></param>
        /// <param name="numBits"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static SymmCipher Create(SymDefObject symDef = null, byte[] keyData = null, byte[] iv = null)
        {
            if (symDef == null)
            {
                symDef = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);
            }

            string algName = "";

            switch (symDef.Algorithm)
            {
            case TpmAlgId.Aes:
                switch (symDef.Mode)
                {
                case TpmAlgId.Cbc:
                    algName = SymmetricAlgorithmNames.AesCbc;
                    break;

                case TpmAlgId.Ecb:
                    algName = SymmetricAlgorithmNames.AesEcb;
                    break;

                case TpmAlgId.Cfb:
                    algName = SymmetricAlgorithmNames.AesCbcPkcs7;
                    break;

                default:
                    Globs.Throw <ArgumentException>("Unsupported mode (" + symDef.Mode + ") for algorithm " + symDef.Algorithm);
                    break;
                }
                break;

            case TpmAlgId.Tdes:
                switch (symDef.Mode)
                {
                case TpmAlgId.Cbc:
                    algName = SymmetricAlgorithmNames.TripleDesCbc;
                    break;

                case TpmAlgId.Ecb:
                    algName = SymmetricAlgorithmNames.TripleDesEcb;
                    break;

                default:
                    Globs.Throw <ArgumentException>("Unsupported mode (" + symDef.Mode + ") for algorithm " + symDef.Algorithm);
                    break;
                }
                break;

            default:
                Globs.Throw <ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                break;
            }

            if (keyData == null)
            {
                keyData = Globs.GetRandomBytes(symDef.KeyBits / 8);
            }

            SymmetricKeyAlgorithmProvider algProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algName);
            var key = algProvider.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(keyData));

            return(key == null ? null : new SymmCipher(key, keyData, iv));
        }
Esempio n. 37
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.CFBDecrypt(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))
                {
                    throw new Exception("Bad inner integrity");
                }

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

            return(sens);
        }
Esempio n. 38
0
 public Tpm2ImportRequest()
 {
     parentHandle = new TpmHandle();
     encryptionKey = new byte[0];
     objectPublic = new TpmPublic();
     duplicate = new TpmPrivate();
     inSymSeed = new byte[0];
     symmetricAlg = new SymDefObject();
 }
Esempio n. 39
0
        /// <summary>
        /// Create a new SymmCipher object with a random key based on the alg and mode supplied.
        /// </summary>
        /// <param name="algId"></param>
        /// <param name="numBits"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static SymmCipher Create(SymDefObject symDef = null, byte[] keyData = null, byte[] iv = null)
        {
            if (symDef == null)
            {
                symDef = new SymDefObject(TpmAlgId.Aes, 128, TpmAlgId.Cfb);
            }
            else if (symDef.Algorithm != TpmAlgId.Aes)
            {
                Globs.Throw <ArgumentException>("Unsupported symmetric algorithm " + symDef.Algorithm);
                return(null);
            }

#if TSS_USE_BCRYPT
            var alg = new BCryptAlgorithm(Native.BCRYPT_AES_ALGORITHM);

            if (keyData == null)
            {
                keyData = Globs.GetRandomBytes(symDef.KeyBits / 8);
            }
            var key = alg.GenerateSymKey(symDef, keyData, GetBlockSize(symDef));
            //key = BCryptInterface.ExportSymKey(keyHandle);
            //keyHandle = alg.LoadSymKey(key, symDef, GetBlockSize(symDef));
            alg.Close();
            return(new SymmCipher(key, keyData, iv));
#else
            SymmetricAlgorithm alg = new RijndaelManaged();
            // DES and __3DES are not supported in TPM 2.0 v 0.96 and above
            //switch (algId) {
            //    case TpmAlgId.Aes: alg = new RijndaelManaged(); break;
            //    case TpmAlgId.__3DES: alg = new TripleDESCryptoServiceProvider(); break;
            //    case TpmAlgId.Des: alg = new DESCryptoServiceProvider(); break;
            //}
            int blockSize = GetBlockSize(symDef);
            alg.KeySize   = symDef.KeyBits;
            alg.BlockSize = blockSize * 8;
            alg.Padding   = PaddingMode.None;
            alg.Mode      = GetCipherMode(symDef.Mode);
            // REVISIT: Get this right for other modes
            alg.FeedbackSize = alg.BlockSize;
            if (keyData == null)
            {
                // Generate random key
                alg.IV = Globs.GetZeroBytes(blockSize);
                try
                {
                    alg.GenerateKey();
                }
                catch (Exception)
                {
                    alg.Dispose();
                    throw;
                }
            }
            else
            {
                // Use supplied key bits
                alg.Key = keyData;
                if (iv == null)
                {
                    iv = Globs.GetZeroBytes(blockSize);
                }
                else if (iv.Length != blockSize)
                {
                    Array.Resize(ref iv, blockSize);
                }
                alg.IV = iv;
            }
            return(new SymmCipher(alg));
#endif
        }
Esempio n. 40
0
 public EccParms()
 {
     symmetric = new SymDefObject();
     curveID = new EccCurve();
 }
Esempio n. 41
0
 public Tpm2ImportRequest(Tpm2ImportRequest the_Tpm2ImportRequest)
 {
     if((Object) the_Tpm2ImportRequest == null ) throw new ArgumentException(Globs.GetResourceString("parmError"));
     parentHandle = the_Tpm2ImportRequest.parentHandle;
     encryptionKey = the_Tpm2ImportRequest.encryptionKey;
     objectPublic = the_Tpm2ImportRequest.objectPublic;
     duplicate = the_Tpm2ImportRequest.duplicate;
     inSymSeed = the_Tpm2ImportRequest.inSymSeed;
     symmetricAlg = the_Tpm2ImportRequest.symmetricAlg;
 }