Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't perform AES encryption in context of session #2

Open
alexey3nemckovich opened this issue Jan 27, 2022 · 2 comments
Open

Can't perform AES encryption in context of session #2

alexey3nemckovich opened this issue Jan 27, 2022 · 2 comments

Comments

@alexey3nemckovich
Copy link

alexey3nemckovich commented Jan 27, 2022

Hello, @Prakhar314 and @sicario001 . Your project is really useful to dive into TPM2 API, it has a really lot of nice samples. But maybe you could help to understand what i am doing wrong here.
I want to create a session for encrypting/decrypting tpm commands and responses.
And in context of this session create aes key, make it persistent and perform some encryption/decryption with it. But unfortunately that doesn't work. Could you help me to figure it out?
Here is sample code of how I am trying to do it.

// Session encryption is essentially transparent to the application programmer.
// All that is needed is to create a session with the necessary characteristics and
// TSS.C++ adds all necessary parameter encryption and decryption.

// At the time of writing only unseeded and unbound session enc and dec are supported.
// First set up a session that encrypts communications TO the TPM. To do this
// we tell the TPM to decrypt via TPMA_SESSION::decrypt.
AUTH_SESSION sess = tpm.StartAuthSession(TPM_SE::HMAC, TPM_ALG_ID::SHA1,
	TPMA_SESSION::continueSession | TPMA_SESSION::decrypt,
	TPMT_SYM_DEF(TPM_ALG_ID::AES, 128, TPM_ALG_ID::CFB));

Announce("EncryptDecryptSample");

TPM_HANDLE prim = MakeStoragePrimary(&sess);

// Make an AES key
TPMT_PUBLIC inPublic(TPM_ALG_ID::SHA256,
	TPMA_OBJECT::decrypt | TPMA_OBJECT::sign | TPMA_OBJECT::userWithAuth
	| TPMA_OBJECT::sensitiveDataOrigin,
	null,
	TPMS_SYMCIPHER_PARMS(Aes256Cfb),
	TPM2B_DIGEST_SYMCIPHER());

// Set the use-auth for the nex key. Note the second parameter is
// NULL because we are asking the TPM to create a new key.
ByteVec userAuth = { 1, 2, 3, 4 };
TPMS_SENSITIVE_CREATE sensCreate(userAuth, null);

auto aesKey = tpm[sess].Create(prim, sensCreate, inPublic, null, null);

TPM_HANDLE aesHandle = tpm[sess].Load(prim, aesKey.outPrivate, aesKey.outPublic);

TPM_HANDLE& keyHandle = aesHandle;

// We can put the primary key into NV with EvictControl
TPM_HANDLE persistentHandle = TPM_HANDLE::Persistent(1001);

// First delete anything that might already be there
tpm._AllowErrors()[sess].EvictControl(TPM_RH::OWNER, persistentHandle, persistentHandle);

// Make our primary persistent
tpm[sess].EvictControl(TPM_RH::OWNER, aesHandle, persistentHandle);

//// Flush the old one
tpm[sess].FlushContext(aesHandle);


ByteVec toEncrypt{ 1, 2, 3, 4, 5, 4, 3, 2, 12, 3, 4, 5 };
ByteVec iv(16);

persistentHandle.SetAuth(userAuth);

auto encrypted = tpm[sess].EncryptDecrypt(persistentHandle, (BYTE)0, TPM_ALG_ID::CFB, iv, toEncrypt);
auto decrypted = tpm[sess].EncryptDecrypt(persistentHandle, (BYTE)1, TPM_ALG_ID::CFB, iv, encrypted.outData);

cout << "AES encryption" << endl <<
	"in:  " << toEncrypt << endl <<
	"enc: " << encrypted.outData << endl <<
	"dec: " << decrypted.outData << endl;

_ASSERT(decrypted.outData == toEncrypt);

tpm.FlushContext(prim);
tpm.FlushContext(aesHandle);`
@alexey3nemckovich
Copy link
Author

alexey3nemckovich commented Jan 27, 2022

It fails on attempt to load created key with error = TPM_RC::SIZE
TPM_HANDLE aesHandle = tpm[sess].Load(prim, aesKey.outPrivate, aesKey.outPublic);
If do this actions (key creation, making it persistent, encryption/decryption) without session everything works fine. But I need somehow to encrypt parameters passed to TPM.

@alexey3nemckovich
Copy link
Author

I realised, that EncryptDecrypt command can't be crypted, because it doesn't have TPM2B parameter first.
So, I tried to use RSA encryption instread. It supports encryption session. But unfortunately I got another error
Sample of my code
`

// At the time of writing only unseeded and unbound session enc and dec are supported.
// First set up a session that encrypts communications TO the TPM. To do this
// we tell the TPM to decrypt via TPMA_SESSION::decrypt.
AUTH_SESSION sess = tpm.StartAuthSession(TPM_SE::HMAC, TPM_ALG_ID::SHA256,
	TPMA_SESSION::continueSession | TPMA_SESSION::decrypt,
	TPMT_SYM_DEF(TPM_ALG_ID::AES, 128, TPM_ALG_ID::CFB));

AUTH_SESSION encSess = tpm.StartAuthSession(TPM_SE::HMAC, TPM_ALG_ID::SHA1,
	TPMA_SESSION::continueSession | TPMA_SESSION::encrypt,
	TPMT_SYM_DEF(TPM_ALG_ID::AES, 128, TPM_ALG_ID::CFB));

Announce("RsaEncryptDecrypt");

// This sample demostrates the use of the TPM for RSA operations.

// We will make a key in the "null hierarchy".
TPMT_PUBLIC primTempl(TPM_ALG_ID::SHA1,
                      TPMA_OBJECT::decrypt | TPMA_OBJECT::userWithAuth | TPMA_OBJECT::sensitiveDataOrigin,
                      null,  // No policy
                      TPMS_RSA_PARMS(null, TPMS_SCHEME_OAEP(TPM_ALG_ID::SHA1), 2048, 65537),
                      TPM2B_PUBLIC_KEY_RSA());

// Set the use-auth for the nex key. Note the second parameter is
// NULL because we are asking the TPM to create a new key.
ByteVec userAuth = { 1, 2, 3, 4 };
TPMS_SENSITIVE_CREATE sensCreate(userAuth, null);

// Create the key
auto storagePrimary = tpm[sess].CreatePrimary(TPM_RH::OWNER, sensCreate, primTempl, null, null);

TPM_HANDLE& keyHandle = storagePrimary.handle;

// We can put the primary key into NV with EvictControl
TPM_HANDLE persistentHandle = TPM_HANDLE::Persistent(1000);

persistentHandle.SetName(userAuth);
persistentHandle.SetAuth(userAuth);

// First delete anything that might already be there
tpm._AllowErrors().EvictControl(TPM_RH::OWNER, persistentHandle, persistentHandle);

// Make our primary persistent
tpm.EvictControl(TPM_RH::OWNER, storagePrimary.handle, persistentHandle);

//// Flush the old one
tpm.FlushContext(storagePrimary.handle);

// ReadPublic of the new persistent one
auto persistentPub = tpm.ReadPublic(persistentHandle);
cout << "Public part of persistent primary" << endl << persistentPub.ToString(false);

ByteVec dataToEncrypt = { '1', '2', '3', '\0' };//TPM_HASH::FromHashOfString(TPM_ALG_ID::SHA1, "secret");
cout << "Data to encrypt: " << dataToEncrypt << endl;

auto enc = tpm[sess].RSA_Encrypt(persistentHandle, dataToEncrypt, TPMS_NULL_ASYM_SCHEME(), null);
cout << "RSA-encrypted data: " << enc << endl;

auto dec = tpm[encSess].RSA_Decrypt(persistentHandle, enc, TPMS_NULL_ASYM_SCHEME(), null);
cout << "decrypted data: " << dec << endl;
if (dec == dataToEncrypt)
	cout << "Decryption worked" << endl;
_ASSERT(dataToEncrypt == dec);

tpm.FlushContext(keyHandle);`

Here program fails on RSA_Encrypt command with code BAD_AUTH.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant