// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 3: Commands
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include "InternalRoutines.h"
#include "EncryptDecrypt_fp.h"
//
//
//     Error Returns                   Meaning
//
//     TPM_RC_KEY                      is not a symmetric decryption key with both public and private
//                                     portions loaded
//     TPM_RC_SIZE                     IvIn size is incompatible with the block cipher mode; or inData size is
//                                     not an even multiple of the block size for CBC or ECB mode
//     TPM_RC_VALUE                    keyHandle is restricted and the argument mode does not match the
//                                     key's mode
//
TPM_RC
TPM2_EncryptDecrypt(
   EncryptDecrypt_In    *in,                 // IN: input parameter list
   EncryptDecrypt_Out   *out                 // OUT: output parameter list
   )
{
   OBJECT               *symKey;
   UINT16               keySize;
   UINT16               blockSize;
   BYTE                 *key;
   TPM_ALG_ID           alg;

// Input Validation
   symKey = ObjectGet(in->keyHandle);

   // The input key should be a symmetric decrypt key.
   if(    symKey->publicArea.type != TPM_ALG_SYMCIPHER
      || symKey->attributes.publicOnly == SET)
       return TPM_RC_KEY + RC_EncryptDecrypt_keyHandle;

   // If the input mode is TPM_ALG_NULL, use the key's mode
   if( in->mode == TPM_ALG_NULL)
       in->mode = symKey->publicArea.parameters.symDetail.mode.sym;

   // If the key is restricted, the input symmetric mode should match the key's
   // symmetric mode
   if(   symKey->publicArea.objectAttributes.restricted == SET
      && symKey->publicArea.parameters.symDetail.mode.sym != in->mode)
       return TPM_RC_VALUE + RC_EncryptDecrypt_mode;

   // If the mode is null, then we have a problem.
   // Note: Construction of a TPMT_SYM_DEF does not allow the 'mode' to be
   // TPM_ALG_NULL so setting in->mode to the mode of the key should have
   // produced a valid mode. However, this is suspenders.
   if(in->mode == TPM_ALG_NULL)
       return TPM_RC_VALUE + RC_EncryptDecrypt_mode;

   // The input iv for ECB mode should be null. All the other modes should
   // have an iv size same as encryption block size

   keySize = symKey->publicArea.parameters.symDetail.keyBits.sym;
   alg = symKey->publicArea.parameters.symDetail.algorithm;
   blockSize = CryptGetSymmetricBlockSize(alg, keySize);
   if(   (in->mode == TPM_ALG_ECB && in->ivIn.t.size != 0)
      || (in->mode != TPM_ALG_ECB && in->ivIn.t.size != blockSize))
       return TPM_RC_SIZE + RC_EncryptDecrypt_ivIn;

   // The input data size of CBC mode or ECB mode must be an even multiple of
   // the symmetric algorithm's block size
   if(   (in->mode == TPM_ALG_CBC || in->mode == TPM_ALG_ECB)
      && (in->inData.t.size % blockSize) != 0)
       return TPM_RC_SIZE + RC_EncryptDecrypt_inData;

   // Copy IV
   // Note: This is copied here so that the calls to the encrypt/decrypt functions
   // will modify the output buffer, not the input buffer
   out->ivOut = in->ivIn;

// Command Output

   key = symKey->sensitive.sensitive.sym.t.buffer;
   // For symmetric encryption, the cipher data size is the same as plain data
   // size.
   out->outData.t.size = in->inData.t.size;
   if(in->decrypt == YES)
   {
       // Decrypt data to output
       CryptSymmetricDecrypt(out->outData.t.buffer,
                             alg,
                             keySize, in->mode, key,
                             &(out->ivOut),
                             in->inData.t.size,
                             in->inData.t.buffer);
   }
   else
   {
       // Encrypt data to output
       CryptSymmetricEncrypt(out->outData.t.buffer,
                             alg,
                             keySize,
                             in->mode, key,
                             &(out->ivOut),
                             in->inData.t.size,
                             in->inData.t.buffer);
   }

   return TPM_RC_SUCCESS;
}
