Esempio n. 1
0
// Decrypt data in vector
void RC5Simple::RC5_Decrypt(vector<unsigned char> &in, vector<unsigned char> &out)
{ 
 RC5_LOG(( "\nDecrypt\n" ));

 // Cleaning output vector
 out.clear();
 out.resize(in.size(), 0);


 // No decrypt null data
 if(in.size()==0) 
  return;


 // Get IV
 unsigned char iv[RC5_BLOCK_LEN];
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  iv[i]=in[i];


 // Set secret key for decrypt
 RC5_Setup(rc5_key);


 // Decode by blocks from block with index 1 (from 0 block already read IV)
 unsigned int data_size=0;
 unsigned int block=1;
 while( (RC5_BLOCK_LEN*(block+1))<=in.size() )
  {
   unsigned int shift=block*RC5_BLOCK_LEN;

   RC5_TWORD temp_word_1;
   RC5_TWORD temp_word_2;
   RC5_TWORD pt[RC5_WORDS_IN_BLOCK];
   RC5_TWORD ct[RC5_WORDS_IN_BLOCK];

   RC5_LOG(( "Block num %d, shift %d\n", block, shift ));

   temp_word_1=RC5_GetWordFromByte(in[shift],
                                   in[shift+1],
                                   in[shift+2],
                                   in[shift+3]);

   temp_word_2=RC5_GetWordFromByte(in[shift+RC5_WORD_LEN],
                                   in[shift+RC5_WORD_LEN+1],
                                   in[shift+RC5_WORD_LEN+2],
                                   in[shift+RC5_WORD_LEN+3]);
              
   pt[0]=temp_word_1; 
   pt[1]=temp_word_2;


   // Decode
   RC5_DecryptBlock(pt, ct);


   // ---------------------------
   // Un XOR block with IV vector
   // ---------------------------

   // Convert block words to plain array
   unsigned char ct_part[RC5_BLOCK_LEN];

   for(int i=0; i<RC5_WORD_LEN; i++)
    { 
     ct_part[i]=RC5_GetByteFromWord(ct[0], i);
     ct_part[i+RC5_WORD_LEN]=RC5_GetByteFromWord(ct[1], i);
    }

   // Un XOR
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    ct_part[i]^=iv[i];  

   if(block==1)
    {
     data_size=RC5_GetIntFromByte(ct_part[0], ct_part[1], ct_part[2], ct_part[3]);

     RC5_LOG(( "Decrypt data size: %d\n", data_size ));

     // Uncorrect decrypt data size
     if((unsigned int)data_size>(unsigned int)in.size()) 
      return;
    }

   #if RC5_ENABLE_DEBUG_PRINT==1
    RC5_LOG(( "Pt %.8X, %.8X\n", pt[0], pt[1] ));
    RC5_LOG(( "Ct %.8X, %.8X\n", ct[0], ct[1] ));
   #endif


   // Generate next IV for Cipher Block Chaining (CBC)
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    iv[i]=in[shift+i];


   // Save decrypt data
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    out[shift-RC5_BLOCK_LEN+i]=ct_part[i]; 

   block++;
  }


 // Cleaning IV
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  iv[i]=0;


 // Remove from output first byte with length
 out.erase(out.begin(), out.begin()+RC5_BLOCK_LEN);

 // Remove from output last byte with random byte for aligning
 if(out.size()>data_size)
  out.erase(out.begin()+data_size, out.end());
}
Esempio n. 2
0
// Decrypt data in vector
void RC5Simple::RC5_Decrypt(vector<unsigned char> &in, vector<unsigned char> &out)
{ 
 RC5_LOG(( "\nDecrypt\n" ));

 RC5_LOG(( "\nInput data size: %d\n", in.size() ));

 // No decrypt null data
 if(in.size()==0) 
  {
   errorCode=RC5_ERROR_CODE_6;
   return;
  }


 // Detect format version
 unsigned int formatVersion=0;
 if(rc5_isSetFormatVersionForce==true)
  formatVersion=rc5_formatVersion; // If format set force, format not autodetected
 else
  {
   // Signature bytes
   const char *signature=RC5_SIMPLE_SIGNATURE;

   // Detect signature
   bool isSignatureCorrect=true;
   for(int i=0; i<(RC5_BLOCK_LEN-1); i++)
    if(in[i]!=signature[i])
     isSignatureCorrect=false;

   // If not detect signature
   if(isSignatureCorrect==false)
    formatVersion=RC5_FORMAT_VERSION_1; // In first version can't signature
   else
    {
     // Get format version
     unsigned char readFormatVersion=in[RC5_BLOCK_LEN-1];

     // If format version correct
     if(readFormatVersion>=RC5_FORMAT_VERSION_2 && readFormatVersion<=RC5_FORMAT_VERSION_CURRENT)
      formatVersion=readFormatVersion;
     else
      formatVersion=RC5_FORMAT_VERSION_1; // If version not correct, may be it format 1 ( probability 0.[hrendesyatih]1 )
    }
  }


 unsigned int ivShift=0;
 unsigned int firstDataBlock=0;
 unsigned int removeBlocksFromOutput=0;
 unsigned int blockWithDataSize=0;


 if(formatVersion==RC5_FORMAT_VERSION_1)
  {
   ivShift=0;
   firstDataBlock=1; // Start decode from block with index 1 (from block 0 read IV)
   removeBlocksFromOutput=1;
   blockWithDataSize=1;
  }

 if(formatVersion==RC5_FORMAT_VERSION_2)
  {
   ivShift=RC5_BLOCK_LEN;
   firstDataBlock=2; // Start decode from block with index 2 (0 - signature and version, 1 - IV)
   removeBlocksFromOutput=2; // Random data block and size data block
   blockWithDataSize=3;
  }

 if(formatVersion==RC5_FORMAT_VERSION_3)
  {
   ivShift=RC5_BLOCK_LEN;
   firstDataBlock=2; // Start decode from block with index 2 (0 - signature and version, 1 - IV)
   removeBlocksFromOutput=3; // Two random data block and size data block
   blockWithDataSize=4;
  }


 // Get IV
 unsigned char iv[RC5_BLOCK_LEN];
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  iv[i]=in[i+ivShift];


 // Set secret key for decrypt
 RC5_Setup(rc5_key);


 // Cleaning output vector
 out.clear();
 out.resize(in.size(), 0);


 // Decode by blocks from started data block
 unsigned int data_size=0;
 unsigned int block=firstDataBlock;
 while( (RC5_BLOCK_LEN*(block+1))<=in.size() )
  {
   unsigned int shift=block*RC5_BLOCK_LEN;

   RC5_TWORD temp_word_1;
   RC5_TWORD temp_word_2;
   RC5_TWORD pt[RC5_WORDS_IN_BLOCK];
   RC5_TWORD ct[RC5_WORDS_IN_BLOCK];

   RC5_LOG(( "Block num %d, shift %d\n", block, shift ));

   temp_word_1=RC5_GetWordFromByte(in[shift],
                                   in[shift+1],
                                   in[shift+2],
                                   in[shift+3]);

   temp_word_2=RC5_GetWordFromByte(in[shift+RC5_WORD_LEN],
                                   in[shift+RC5_WORD_LEN+1],
                                   in[shift+RC5_WORD_LEN+2],
                                   in[shift+RC5_WORD_LEN+3]);
              
   pt[0]=temp_word_1; 
   pt[1]=temp_word_2;

   RC5_LOG(( "Block data. Word 1: %.2X, Word 2: %.2X\n", temp_word_1, temp_word_2 ));


   // Decode
   RC5_DecryptBlock(pt, ct);


   // ---------------------------
   // Un XOR block with IV vector
   // ---------------------------

   // Convert block words to plain array
   unsigned char ct_part[RC5_BLOCK_LEN];

   for(int i=0; i<RC5_WORD_LEN; i++)
    { 
     ct_part[i]=RC5_GetByteFromWord(ct[0], i);
     ct_part[i+RC5_WORD_LEN]=RC5_GetByteFromWord(ct[1], i);
    }

   // Un XOR
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    ct_part[i]^=iv[i];  

   if(block==blockWithDataSize)
    {
     data_size=RC5_GetIntFromByte(ct_part[0], ct_part[1], ct_part[2], ct_part[3]);

     RC5_LOG(( "Decrypt data size: %d\n", data_size ));

     // Uncorrect decrypt data size
     if((unsigned int)data_size>(unsigned int)in.size()) 
      {
       // RC5_LOG(( "Incorrect data size. Decrypt data size: %d, estimate data size: ~%d\n", data_size,  in.size() ));
       errorCode=RC5_ERROR_CODE_7;
       return;
      }
    }

   #if RC5_ENABLE_DEBUG_PRINT==1
    RC5_LOG(( "Pt %.8X, %.8X\n", pt[0], pt[1] ));
    RC5_LOG(( "Ct %.8X, %.8X\n", ct[0], ct[1] ));
   #endif


   // Generate next IV for Cipher Block Chaining (CBC)
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    iv[i]=in[shift+i];


   // Save decrypt data
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    {
     RC5_LOG(( "Put decrypt data to vector out[%d] = %.2X\n", shift-(removeBlocksFromOutput*RC5_BLOCK_LEN)+i, ct_part[i] ));
     out[shift-(firstDataBlock*RC5_BLOCK_LEN)+i]=ct_part[i]; 
    }

   block++;
  }


 // Cleaning IV
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  iv[i]=0;

 // Remove from output a blocks with technical data (random blocks, size, etc...)
 out.erase(out.begin(), out.begin()+removeBlocksFromOutput*RC5_BLOCK_LEN);

 // Remove from output a last byte with random byte for aligning
 if(out.size()>data_size)
  out.erase(out.begin()+data_size, out.end());
}