Esempio n. 1
0
 public TpmPolicyNameHash(byte[] expectedNameHash, string branchName = "", string nodeId = null)
     : base(branchName, nodeId)
 {
     NameHash = Globs.CopyData(expectedNameHash);
 }
Esempio n. 2
0
        public byte[] Decrypt(byte[] data, byte[] iv = null)
        {
            byte[] paddedData;
            int    unpadded = data.Length % BlockSize;

            paddedData = unpadded == 0 ? data : Globs.AddZeroToEnd(data, BlockSize - unpadded);
#if TSS_USE_BCRYPT
            paddedData = Key.Decrypt(paddedData, null, iv ?? IV);
            return(Globs.CopyData(paddedData, 0, data.Length));
#else
            bool externalIV = iv != null && iv.Length > 0;
            if (externalIV)
            {
                Alg.IV = iv;
            }

            byte[] tempOut = null;
            if (Alg.Mode == CipherMode.ECB && Mode == CipherMode.CFB)
            {
                DecryptCFB(paddedData, Alg.IV, Alg.CreateEncryptor());
                tempOut = unpadded == 0 ? paddedData : Globs.CopyData(paddedData, 0, data.Length);
            }
            else
            {
                ICryptoTransform dec = Alg.CreateDecryptor();
                tempOut = new byte[data.Length];
                using (var outStream = new MemoryStream(paddedData))
                {
                    var s = new CryptoStream(outStream, dec, CryptoStreamMode.Read);
                    int numPlaintextBytes = s.Read(tempOut, 0, data.Length);
                    Debug.Assert(numPlaintextBytes == data.Length);
                }
            }

            if (externalIV)
            {
                var src = data;
                var res = tempOut;
                if (res.Length > iv.Length)
                {
                    src = Globs.CopyData(paddedData, src.Length / iv.Length, iv.Length);
                    res = Globs.CopyData(tempOut, res.Length / iv.Length, iv.Length);
                }

                switch (Mode)
                {
                case CipherMode.CBC:
                case CipherMode.CFB:
                    src.CopyTo(iv, 0);
                    break;

                case CipherMode.OFB:
                    XorEngine.Xor(res, src).CopyTo(iv, 0);
                    break;

                case CipherMode.ECB:
                    break;

                case CipherMode.CTS:
                    Globs.Throw <ArgumentException>("Decrypt: Unsupported symmetric mode");
                    break;
                }
            }
            return(tempOut);
#endif // !TSS_USE_BCRYPT
        }
Esempio n. 3
0
 private SymmCipher(CryptographicKey key, byte[] keyData, byte[] iv)
 {
     Key       = key;
     KeyBuffer = keyData;
     IV        = Globs.CopyData(iv) ?? new byte[BlockSize];
 }
Esempio n. 4
0
        CreateSensitiveComposite(TpmPublic pub,
                                 ref byte[] keyData,
                                 out IPublicIdUnion publicId)
        {
            ISensitiveCompositeUnion newSens = null;

            publicId = null;

            if (pub.type == TpmAlgId.Rsa)
            {
                if (keyData != null)
                {
                    newSens  = new Tpm2bPrivateKeyRsa(keyData);
                    publicId = pub.unique;
                }
                else
                {
                    var newKeyPair = new RawRsa((pub.parameters as RsaParms).keyBits);

                    // Put the key bits into the required structure envelopes
                    newSens  = new Tpm2bPrivateKeyRsa(newKeyPair.Private);
                    publicId = new Tpm2bPublicKeyRsa(newKeyPair.Public);
                }
            }
            else if (pub.type == TpmAlgId.Symcipher)
            {
                var symDef = (SymDefObject)pub.parameters;
                if (symDef.Algorithm != TpmAlgId.Aes)
                {
                    Globs.Throw <ArgumentException>("Unsupported symmetric algorithm");
                    return(null);
                }

                int keySize = (symDef.KeyBits + 7) / 8;
                if (keyData == null)
                {
                    keyData = Globs.GetRandomBytes(keySize);
                }
                else if (keyData.Length != keySize)
                {
                    keyData = Globs.CopyData(keyData);
                }
                else
                {
                    Globs.Throw <ArgumentException>("Wrong symmetric key length");
                    return(null);
                }
                newSens = new Tpm2bSymKey(keyData);
            }
            else if (pub.type == TpmAlgId.Keyedhash)
            {
                var      scheme  = (pub.parameters as KeyedhashParms).scheme;
                TpmAlgId hashAlg = scheme is SchemeHash ? (scheme as SchemeHash).hashAlg
                                 : scheme is SchemeXor  ? (scheme as SchemeXor).hashAlg
                                                        : pub.nameAlg;
                var digestSize = CryptoLib.DigestSize(hashAlg);

                if (keyData == null)
                {
                    keyData = Globs.GetRandomBytes(digestSize);
                }
                else if (keyData.Length <= CryptoLib.BlockSize(hashAlg))
                {
                    keyData = Globs.CopyData(keyData);
                }
                else
                {
                    Globs.Throw <ArgumentException>("HMAC key is too big");
                    return(null);
                }
                newSens = new Tpm2bSensitiveData(keyData);
            }
            else
            {
                Globs.Throw <ArgumentException>("Unsupported key type");
            }

            return(newSens);
        }
Esempio n. 5
0
        /// <summary>
        /// Performs the TPM-defined CFB encrypt using the associated algorithm.
        /// This routine assumes that the integrity value has been prepended.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public byte[] Encrypt(byte[] data, byte[] iv = null)
        {
            byte[] paddedData;
            int    unpadded = data.Length % BlockSize;

            paddedData = unpadded == 0 ? data : Globs.AddZeroToEnd(data, BlockSize - unpadded);
#if TSS_USE_BCRYPT
            paddedData = Key.Encrypt(paddedData, null, iv ?? IV);
#else
            bool externalIV = iv != null && iv.Length > 0;
            if (externalIV)
            {
                Alg.IV = iv;
            }

            ICryptoTransform enc = Alg.CreateEncryptor();
            if (Alg.Mode == CipherMode.ECB && Mode == CipherMode.CFB)
            {
                EncryptCFB(paddedData, Alg.IV, enc);
            }
            else
            {
                using (var outStream = new MemoryStream())
                {
                    var s = new CryptoStream(outStream, enc, CryptoStreamMode.Write);
                    s.Write(paddedData, 0, paddedData.Length);
                    s.FlushFinalBlock();
                    paddedData = outStream.ToArray();
                }
            }

            if (externalIV)
            {
                var src = data;
                var res = paddedData;
                if (res.Length > iv.Length)
                {
                    src = Globs.CopyData(data, src.Length - iv.Length, iv.Length);
                    res = Globs.CopyData(paddedData, res.Length - iv.Length, iv.Length);
                }

                switch (Mode)
                {
                case CipherMode.CBC:
                case CipherMode.CFB:
                    res.CopyTo(iv, 0);
                    break;

                case CipherMode.OFB:
                    XorEngine.Xor(res, src).CopyTo(iv, 0);
                    break;

                case CipherMode.ECB:
                    break;

                case CipherMode.CTS:
                    Globs.Throw <ArgumentException>("Encrypt: Unsupported symmetric mode");
                    break;
                }
            }
#endif // !TSS_USE_BCRYPT
            return(unpadded == 0 ? paddedData : Globs.CopyData(paddedData, 0, data.Length));
        }
Esempio n. 6
0
 public void SetNonceTpm(byte[] nonceTpm)
 {
     NonceTpm = Globs.CopyData(nonceTpm);
 }
Esempio n. 7
0
        /// <summary>
        /// Sign using a non-default hash algorithm.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="sigHash"></param>
        /// <returns></returns>
        public ISignatureUnion SignData(byte[] data, TpmAlgId sigHash)
        {
#if TSS_USE_BCRYPT
            Debug.Assert(Key != UIntPtr.Zero);
#endif
            var rsaParams = PublicParms.parameters as RsaParms;
            if (rsaParams != null)
            {
#if !TSS_USE_BCRYPT
                Debug.Assert(RsaProvider != null);
#endif
                TpmAlgId sigScheme = rsaParams.scheme.GetUnionSelector();

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

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

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

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

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(null);
        } // SignData()
Esempio n. 8
0
        /// <summary>
        /// PSS verify.  Note: we expect the caller to do the hash.
        /// </summary>
        /// <param name="m"></param>
        /// <param name="em"></param>
        /// <param name="sLen"></param>
        /// <param name="emBits"></param>
        /// <param name="hashAlg"></param>
        /// <returns></returns>
        public static bool PssVerify(byte[] m, byte[] em, int sLen, int emBits, TpmAlgId hashAlg)
        {
            var emLen = (int)Math.Ceiling(1.0 * emBits / 8);
            int hLen  = CryptoLib.DigestSize(hashAlg);

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

            // 3
            if (emLen < hLen + sLen + 2)
            {
                return(false);
            }

            // 4
            if (em[em.Length - 1] != 0xbc)
            {
                return(false);
            }

            // 5
            byte[] maskedDB = Globs.CopyData(em, 0, emLen - hLen - 1);
            byte[] h        = Globs.CopyData(em, emLen - hLen - 1, hLen);

            // 6
            int numZeroBits = 8 * emLen - emBits;
            // First numZero bits is zero in mask
            byte mask = GetByteMask(numZeroBits);

            if ((maskedDB[0] & mask) != maskedDB[0])
            {
                return(false);
            }

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

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

            // 9
            int  numZeroBits2 = 8 * emLen - emBits;
            byte mask2        = GetByteMask(numZeroBits2);

            db[0] &= mask2;

            // 10
            for (int j = 0; j < emLen - hLen - sLen - 2; j++)
            {
                if (db[j] != 0)
                {
                    return(false);
                }
            }
            if (db[emLen - hLen - sLen - 1 - 1] != 1)
            {
                return(false);
            }

            // 11
            byte[] salt = Globs.CopyData(db, db.Length - sLen);

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

            // 13
            byte[] hPrime = TpmHash.FromData(hashAlg, mPrime);

            // 14
            bool match = Globs.ArraysAreEqual(h, hPrime);

            if (match == false)
            {
                return(false);
            }
            return(true);
        }
Esempio n. 9
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);
                    }
                    // Store the public key
                    const int offset  = 8;
                    int       keySize = 0;
                    switch (eccParms.curveID)
                    {
                    case EccCurve.TpmEccNistP256:
                    case EccCurve.TpmEccBnP256:
                    case EccCurve.TpmEccSm2P256:
                        keySize = 32;
                        break;

                    case EccCurve.TpmEccNistP384:
                        keySize = 48;
                        break;

                    case EccCurve.TpmEccNistP521:
                        keySize = 66;
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                    var pubId = new EccPoint(
                        Globs.CopyData(keyIs, offset, keySize),
                        Globs.CopyData(keyIs, offset + keySize, keySize));
                    PublicParms.unique = pubId;
                }
#endif // !TSS_USE_BCRYPT
                break;
            }
#endif // !__MonoCS__
            default:
                Globs.Throw <ArgumentException>("Algorithm not supported");
                break;
            }
        }
Esempio n. 10
0
        public static bool OaepDecode(byte[] eMx, byte[] encodingParms,
                                      TpmAlgId hashAlg, out byte[] decoded)
        {
            decoded = new byte[0];

            var em = new byte[eMx.Length + 1];

            Array.Copy(eMx, 0, em, 1, eMx.Length);

            int hLen = CryptoLib.DigestSize(hashAlg);
            int k    = em.Length;

            // a.
            byte[] lHash = CryptoLib.HashData(hashAlg, encodingParms);

            // b.
            byte y = em[0];

            byte[] maskedSeed = Globs.CopyData(em, 1, hLen);
            byte[] maskedDB   = Globs.CopyData(em, 1 + hLen);

            // c.
            byte[] seedMask = CryptoLib.MGF(maskedDB, hLen, hashAlg);

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

            // e.
            byte[] dbMask = CryptoLib.MGF(seed, k - hLen - 1, hashAlg);

            // f.
            byte[] db = XorEngine.Xor(maskedDB, dbMask);

            // g.
            byte[] lHashPrime = Globs.CopyData(db, 0, hLen);

            // Look for the zero..
            int j;

            for (j = hLen; j < db.Length; j++)
            {
                if (db[j] == 0)
                {
                    continue;
                }

                if (db[j] == 1)
                {
                    break;
                }

                return(false);
            }

            if (j == db.Length - 1)
            {
                return(false);
            }

            byte[] m = Globs.CopyData(db, j + 1);

            if (y != 0)
            {
                return(false);
            }

            if (!Globs.ArraysAreEqual(lHash, lHashPrime))
            {
                return(false);
            }

            decoded = m;
            return(true);
        }
Esempio n. 11
0
 public TpmPolicyTicket(TpmPublic authorizingKey, byte[] policyRef, TpmSt ticketType) : base("")
 {
     AuthorizingKey = authorizingKey;
     PolicyRef      = Globs.CopyData(policyRef);
     TicketType     = ticketType;
 }
Esempio n. 12
0
 /// <summary>
 /// This command allows a policy to be bound to a specific set of handles
 /// without being bound to the parameters of the command. This is most
 /// useful for commands such as TPM2_Duplicate() and for TPM2_PCR_Event()
 /// when the referenced PCR requires a policy.
 /// </summary>
 public TpmPolicyNameHash(byte[] expectedNameHash, string branchName = "") : base(branchName)
 {
     NameHash = Globs.CopyData(expectedNameHash);
 }
Esempio n. 13
0
 /// <summary>
 /// Associates the name with the handle. Only needed for transient, persistent
 /// and NV handles.
 /// Normally this association is done automatically either by TPM commands
 /// producing the corresponding handle, or when the handle is passed as a
 /// parameter to a command requiring HMAC authorization (the name is implicitly
 /// requested from the TPM by means of TPM2_ReadPublic or TPM2_NV_ReadPublic
 /// commands).
 /// Thus this method has to be used only either when Tpm2 object is in the strict
 /// mode (i.e. it is prohibited to issue commands not explicitly requested by
 /// the user), or for the sake of performance optimization (if the client code
 /// has the name pre-computed).
 /// </summary>
 /// <param name="name"></param>
 /// <returns>Reference to this object, which can be used for chaining.</returns>
 public TpmHandle SetName(byte[] name)
 {
     _Name = Globs.CopyData(name);
     return(this);
 }
Esempio n. 14
0
 /// <summary>
 /// Create an AuthValue with the specified value.  Note that trailing zeros are not removed.
 /// </summary>
 /// <param name="val"></param>
 public AuthValue(byte[] auth)
 {
     AuthVal = Globs.CopyData(auth);
 }