public byte[] EncryptDecrypt(byte[] data, bool decrypt, ref byte[] ivIn, out byte[] ivOut) { ivOut = null; if (Public.type != TpmAlgId.Symcipher) { Globs.Throw <ArgumentException>("Only symmetric encryption/decryption is " + "supported by this overloaded version"); return(null); } var symDef = GetSymDef(); using (var sym = SymCipher.Create(symDef, (Sensitive.sensitive as Tpm2bSymKey).buffer)) { if (sym == null) { Globs.Throw <ArgumentException>("Unsupported symmetric key configuration"); return(null); } if (Globs.IsEmpty(ivIn)) { ivIn = (symDef.Mode == TpmAlgId.Ecb) ? new byte[0] : Globs.GetRandomBytes(SymCipher.GetBlockSize(symDef)); } ivOut = Globs.CopyData(ivIn); return(decrypt ? sym.Decrypt(data, ivOut) : sym.Encrypt(data, ivOut)); } } // EncryptDecrypt
/// <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)); }
internal byte[] ParmEncrypt(byte[] parm, Direction inOrOut) { if (Symmetric == null) { Globs.Throw("parameter encryption cipher not defined"); return(parm); } if (Symmetric.Algorithm == TpmAlgId.Null) { return(parm); } byte[] nonceNewer, nonceOlder; if (inOrOut == Direction.Command) { nonceNewer = NonceCaller; nonceOlder = NonceTpm; } else { nonceNewer = NonceTpm; nonceOlder = NonceCaller; } byte[] encKey = (AuthHandle != null && AuthHandle.Auth != null) ? SessionKey.Concat(Globs.TrimTrailingZeros(AuthHandle.Auth)).ToArray() : SessionKey; if (Symmetric.Algorithm == TpmAlgId.Xor) { return(CryptoLib.KdfThenXor(AuthHash, encKey, nonceNewer, nonceOlder, parm)); } int keySize = (Symmetric.KeyBits + 7) / 8, blockSize = SymCipher.GetBlockSize(Symmetric), bytesRequired = keySize + blockSize; byte[] keyInfo = KDF.KDFa(AuthHash, encKey, "CFB", nonceNewer, nonceOlder, bytesRequired * 8); var key = new byte[keySize]; Array.Copy(keyInfo, 0, key, 0, keySize); var iv = new byte[blockSize]; Array.Copy(keyInfo, keySize, iv, 0, blockSize); // Make a new SymCipher from the key and IV and do the encryption. using (SymCipher s = SymCipher.Create(Symmetric, key, iv)) { return(inOrOut == Direction.Command ? s.Encrypt(parm) : s.Decrypt(parm)); } }