Skip to main content

AES-CBC-CTS Decryption using OpenSSL

Recently I was testing few test streams encrypted with AES-CBC-CTS mode, which is another block cipher mode that allows encrypting of data that is not evenly divisible into blocks (unlike AES-CBC mode).

I also found that decryption of such streams is not possible using OpenSSL, as it does not support this block cipher mode. Since OpenSSL does support encryption/decryption for AES-CBC mode, I decided to extend this logic to support AES-CBC-CTS mode.

I found following article on wikipedia which explains CBC-CTS encryption/decryption in detail.

Following C Routine can be used to decrypt data encrypted with AES-CBC-CTS block cipher mode.

_DecryptData(DRM_KeyCtx_T  KEY_CTX, // KeyCtx_T is a structure containing the Key and IV.
                     UINT8 *data, // encrypted data
                     UINT32 inputLength, // encrypted data length
                     UINT8 *outData, // decrypted data
                     UINT32 *outputLength ) // decrypted data length
{
UINT8 Iv[WV_IV_SIZE];
void* lastIvData = NULL;
UINT8 Tn1[16], Tn[16], resBlk[16];
int extraBytes = 0;
int olen=0;
UINT32 tlen=0;
int actualLength = inputLength;

 if (inputLength<16)
 {
    if (data!=outData)
    memcpy(outData, data, inputLength);
    *outputLength = inputLength;
     return SUCCESS;
 }
 // Get Last IV
 if (inputLength&0xf) // not aligned by 16 : CTS
 {
    if (inputLength>=32) // Use Cn-2 Block
    {
       lastIvData = (void*)(data+(inputLength&0xfffffff0)-(IV_SIZE*2)); // IV_SIZE is maximum size of IV.
       memcpy(Iv, lastIvData, 16);
     }
  }

  *outputLength = 0;

   if(!EVP_DecryptInit (&opensslCtx.ctx, opensslCtx.cipher, KEY_CTX.key, KEY_CTX.iv))
        {
            return FAILURE;
        }

   EVP_CIPHER_CTX_set_padding(&opensslCtx.ctx, 0);

   extraBytes = inputLength%16;
   if(extraBytes)
   {
      inputLength -= extraBytes+IV_SIZE;
      if(!inputLength)
         {
              return SUCCESS;
          }
    }

    if (EVP_DecryptUpdate (&opensslCtx.ctx, outData, &olen, data, inputLength) != 1)
    {
       return FAILURE;
    }

    if (EVP_DecryptFinal (&opensslCtx.ctx, outData + olen, (int *)&tlen) != 1)
    {
       return FAILURE;
    }

    olen +=tlen;
    *outputLength += olen;

    // For CBC CTS and handling extrabytes at the end of the inputbuffer
    if(extraBytes)
    {
        memset(resBlk, 0, IV_SIZE);
        memcpy(resBlk, data+inputLength+IV_SIZE, extraBytes);

        olen = 0;
        tlen = 0;

        if(!EVP_DecryptInit (&opensslCtx.ctx, opensslCtx.cipher, KEY_CTX.key, resBlk))
        {
            return FAILURE;
        }

          
        EVP_CIPHER_CTX_set_padding(&opensslCtx.ctx, 0);

        if (EVP_DecryptUpdate (&opensslCtx.ctx, Tn1, &olen, data+inputLength, IV_SIZE) != 1)
        {
           return FAILURE;
         }

         if (EVP_DecryptFinal (&opensslCtx.ctx, Tn1 + olen, (int *)&tlen) != 1)
         {
            return FAILURE;
         }

         olen = 0;
         tlen = 0;

         memcpy(resBlk+extraBytes, Tn1+extraBytes, IV_SIZE-extraBytes);

         if(!EVP_DecryptInit (&opensslCtx.ctx, opensslCtx.cipher, KEY_CTX.key, Iv))
         {
             return FAILURE;
         }

         EVP_CIPHER_CTX_set_padding(&opensslCtx.ctx, 0);

         if (EVP_DecryptUpdate (&opensslCtx.ctx, Tn, &olen, resBlk, IV_SIZE) != 1)
         {
             return FAILURE;
         }

         if (EVP_DecryptFinal (&opensslCtx.ctx, Tn + olen, (int *)&tlen) != 1)
         {
             return FAILURE;
         }

         memcpy(outData+*outputLength, Tn, IV_SIZE);
         memcpy(outData+*outputLength+IV_SIZE, Tn1, extraBytes);
         *outputLength = actualLength;
    }
    return SUCCESS;
}

Comments

  1. Hello Guys, Use this online converter for file converting to other formats like these;

    Best File Converter

    ReplyDelete
  2. And this converter will transfer one file to other formats like these;

    Pptm to Pdf

    Psd to Ai

    Caf to Aiff

    Tga to Jpg

    Swf to Mp4

    ReplyDelete

Post a Comment

Popular posts from this blog

Getting and Setting Microphone Gain or Microphone Boost on Windows 7 / 8 Programmatically

After hours of searching the net I have finally figured out a way to programmatically get and set the microphone gain (boost) value. The code mentioned below can be built on VS and does the job of setting gain value. #include "stdafx.h" #include <mmdeviceapi.h> #include <endpointvolume.h> #include <Functiondiscoverykeys_devpkey.h> #include "Audioclient.h" #include "comutil.h" #define EXIT_ON_ERROR(hres)   if (FAILED(hres)) { goto Exit; } #define SAFE_RELEASE(punk)   if ((punk) != NULL)  { (punk)->Release(); (punk) = NULL; } HRESULT getMicrophoneBoostVolumeLevel(IMMDevice *pEndptDev, IAudioVolumeLevel** ppVolumeLevel) { HRESULT hr = S_OK; DataFlow flow; IDeviceTopology *pDeviceTopology = NULL; IConnector *pConnFrom = NULL; IConnector *pConnTo = NULL; IPart *pPartPrev = NULL; IPart *pPartNext = NULL; *ppVolumeLevel = NULL; wchar_t microphoneBoostName[] = L"Microphone Boost";//if your system ...

Simple example of strong and weak pointers on Android using RefBase class

Here is a simple example explaining the usage of strong and weak pointers using android's RefBase class and the Android.mk to compile the same. Its a modified version of code written by Daniel in the following link. http://himmele.blogspot.com/2012/03/androids-c-reference-counting.html strong_pointer.cpp file:  #include <stdio.h> #include "utils/RefBase.h" namespace android {  class RefTest : public RefBase { public:     RefTest(int32_t id) : mID(id) {         printf("RefTest ctor: %d\n", mID);     }     virtual ~RefTest() {         printf("RefTest dtor: %d\n", mID);     }     int32_t id() const {         return mID;     } private:     int32_t mID; }; int strong_pointer() {     sp<RefTest> ref1 = new RefTest(1);     sp<RefTest> ref5;   ...

MPEG2,4 AAC Decoder

I have modified latm aac decoder based on open source python decoder written by Arkq. https://gist.github.com/Arkq/66fe948c1051684d8909d730c34396d8 This decoder will decode AAC audio(IOS devices) captured with FTS HCI A2DP dump and save it in a playable audio WAV format. Using the tool :  1. Install latest python version > 3 on either windows or linux. 2. Download ffmpeg binaries from following link https://ffmpeg.zeranoe.com/builds/ 3. Extract the ffmpeg binaries and add the extracted bin folder to system path, for linux it can be done by exporting PATH variable and for windows it can be done by changing environment path variable. 4. Install pydub using following command pip install pydub 5. To decode the latm mpeg2,4 aac audio run following command with the attached python script.       latm_aac_decoder.py <extracted latm mpeg2,4 aac audio> eg :  latm_aac_decoder.py Bookmarked_snoop(A2DP)(1).mpeg2...