Ejemplo 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());
}
Ejemplo 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());
}
Ejemplo n.º 3
0
// Encrypt data in vector
void RC5Simple::RC5_Encrypt(vector<unsigned char> &in, vector<unsigned char> &out)
{
 // Clear output vector
 out.clear();


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

 
 // Save input data size
 unsigned int clean_data_size=in.size();
 RC5_LOG(( "Input data size: %d\n", clean_data_size ));


 // IV block
 unsigned char iv[RC5_BLOCK_LEN];
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  iv[i]=(unsigned char)RC5_Rand(0, 0xFF);


 // Block with data size
 unsigned char data_size[RC5_BLOCK_LEN];

 for(int i=0; i<RC5_BLOCK_LEN; i++)
  {
   data_size[i]=RC5_GetByteFromInt( clean_data_size, i );
   RC5_LOG(( "Data size byte %d: %.2X\n", i, data_size[i] ));
  }


 // Insert data size to begin data
 in.insert( in.begin(), RC5_BLOCK_LEN, 0);
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  in[i]=data_size[i];


 // Align end of data to block size
 int last_unalign_len=clean_data_size%RC5_BLOCK_LEN;
 RC5_LOG(( "Last unalign len: %d\n", last_unalign_len ));

 if(last_unalign_len>0)
  {
   // Add random data to end for align to block size
   for(int i=0; i<(RC5_BLOCK_LEN-last_unalign_len); i++)
    {
     RC5_LOG(( "Add byte: %d\n", i ));
     in.push_back( (unsigned char)RC5_Rand(0, 0xFF) );
    }
  }

 #if RC5_ENABLE_DEBUG_PRINT==1
  RC5_LOG(( "Data size after crypt setup: %d\n", in.size() ));
  RC5_LOG(( "Plain byte after crypt setup: " ));
  for(int i=0; i<in.size(); i++)
   RC5_LOG(( "%.2X ", in[i] ));
  RC5_LOG(( "\n" ));
 #endif


 // ------  
 // Encode
 // ------  

 // Create cell in output vector
 out.resize(in.size()+RC5_BLOCK_LEN, 0);


 // Save start IV to first block in output data
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  out[i]=iv[i];


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


 // Encode by blocks
 unsigned int block=0;
 while( (RC5_BLOCK_LEN*(block+1))<=in.size() )
  {
   unsigned int shift=block*RC5_BLOCK_LEN;

   // Temp input buffer for dont modify input data
   unsigned char temp_in[RC5_BLOCK_LEN];

   // XOR block with current IV
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    temp_in[i]=in[shift+i] ^ iv[i];

   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(temp_in[0],
                                   temp_in[1],
                                   temp_in[2],
                                   temp_in[3]);

   temp_word_2=RC5_GetWordFromByte(temp_in[RC5_WORD_LEN+0],
                                   temp_in[RC5_WORD_LEN+1],
                                   temp_in[RC5_WORD_LEN+2],
                                   temp_in[RC5_WORD_LEN+3]);

   pt[0]=temp_word_1; 
   pt[1]=temp_word_2;


   // Encode
   RC5_EncryptBlock(pt, ct);


   #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

   // Save crypt data
   for(int i=0; i<RC5_WORD_LEN; i++)
    {
     // Save crypt data with shift to RC5_BLOCK_LEN
     // btw. in first block putted IV 
     out[RC5_BLOCK_LEN+shift+i]=RC5_GetByteFromWord(ct[0], i);
     out[RC5_BLOCK_LEN+shift+RC5_WORD_LEN+i]=RC5_GetByteFromWord(ct[1], i);
    }


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


   block++;
  }


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


 // -----------------------------------
 // Return input vector to firsted data
 // -----------------------------------

 // Clear input vector from service data
 in.erase(in.begin(), in.begin()+RC5_BLOCK_LEN);

 // Remove from input vector last random byte for aligning
 if(in.size()>clean_data_size)
  in.erase(in.begin()+clean_data_size, in.end());

}
Ejemplo n.º 4
0
// Encrypt data in vector
void RC5Simple::RC5_Encrypt(vector<unsigned char> &in, vector<unsigned char> &out)
{
 // Clear output vector
 out.clear();
 
 // No crypt null data
 if(in.size()==0) 
  {
   errorCode=RC5_ERROR_CODE_5;
   return;
  }

 
 // Save input data size
 unsigned int clean_data_size=in.size();
 RC5_LOG(( "Input data size: %d\n", clean_data_size ));


 // IV block
 unsigned char iv[RC5_BLOCK_LEN];
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  iv[i]=(unsigned char)RC5_Rand(0, 0xFF);


 // Block with data size
 unsigned char data_size[RC5_BLOCK_LEN];

 for(int i=0; i<RC5_BLOCK_LEN; i++)
  {
   data_size[i]=RC5_GetByteFromInt( clean_data_size, i );
   RC5_LOG(( "Data size byte %d: %.2X\n", i, data_size[i] ));
  }


 // Insert data size to begin data
 in.insert( in.begin(), RC5_BLOCK_LEN, 0);
 for(int i=0; i<RC5_BLOCK_LEN; i++)
  in[i]=data_size[i];

 // Add firsted random data
 unsigned int firsRandomDataBlocks=0;
 if(rc5_formatVersion==RC5_FORMAT_VERSION_2)
  firsRandomDataBlocks=1; // At start at format version 2, in begin data add one block with random data

 if(rc5_formatVersion==RC5_FORMAT_VERSION_3)
  firsRandomDataBlocks=2; // At start at format version 3, in begin data add two blocks with random data (full width is 128 bit)

 if(firsRandomDataBlocks>0) 
  for(unsigned int n=1; n<=firsRandomDataBlocks; n++)
   {
    in.insert( in.begin(), RC5_BLOCK_LEN, 0);
    for(int i=0; i<RC5_BLOCK_LEN; i++)
     in[i]=(unsigned char)RC5_Rand(0, 0xFF);
   }


 // Align end of data to block size
 int last_unalign_len=clean_data_size%RC5_BLOCK_LEN;
 RC5_LOG(( "Last unalign len: %d\n", last_unalign_len ));

 if(last_unalign_len>0)
  {
   // Add random data to end for align to block size
   for(int i=0; i<(RC5_BLOCK_LEN-last_unalign_len); i++)
    {
     RC5_LOG(( "Add byte: %d\n", i ));
     in.push_back( (unsigned char)RC5_Rand(0, 0xFF) );
    }
  }

 #if RC5_ENABLE_DEBUG_PRINT==1
  RC5_LOG(( "Data size after crypt setup: %d\n", in.size() ));
  RC5_LOG(( "Plain byte after crypt setup: " ));
  for(int i=0; i<in.size(); i++)
   RC5_LOG(( "%.2X ", in[i] ));
  RC5_LOG(( "\n" ));
 #endif


 // ------  
 // Encode
 // ------  

 // Create and fill cell in output vector

 unsigned int notCryptDataSize=0;

 // In format version 1 save only IV as open data in block 0
 if(rc5_formatVersion==RC5_FORMAT_VERSION_1)
  {
   out.resize(in.size()+RC5_BLOCK_LEN, 0); 

   // Save start IV to block 0 in output data
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    out[i]=iv[i];

   notCryptDataSize=RC5_BLOCK_LEN;
  }

 // In format version 2 or higth save format header (block 0) and IV (block 1)
 if(rc5_formatVersion>=RC5_FORMAT_VERSION_2)
  {
   out.resize(in.size()+RC5_BLOCK_LEN*2, 0);

   // Signature bytes in header
   const char *signature=RC5_SIMPLE_SIGNATURE;
   for(int i=0; i<(RC5_BLOCK_LEN-1); i++)
    out[i]=signature[i];

   // Format version byte in header
   if(rc5_isSetFormatVersionForce)
    out[RC5_BLOCK_LEN-1]=rc5_formatVersion;
   else
    out[RC5_BLOCK_LEN-1]=RC5_FORMAT_VERSION_CURRENT;

   // Save start IV to second block in output data
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    out[i+RC5_BLOCK_LEN]=iv[i];

   notCryptDataSize=RC5_BLOCK_LEN*2;
  }


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


 // Encode by blocks
 unsigned int block=0;
 while( (RC5_BLOCK_LEN*(block+1))<=in.size() )
  {
   unsigned int shift=block*RC5_BLOCK_LEN;

   // Temp input buffer for dont modify input data
   unsigned char temp_in[RC5_BLOCK_LEN];

   // XOR block with current IV
   for(int i=0; i<RC5_BLOCK_LEN; i++)
    temp_in[i]=in[shift+i] ^ iv[i];

   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(temp_in[0],
                                   temp_in[1],
                                   temp_in[2],
                                   temp_in[3]);

   temp_word_2=RC5_GetWordFromByte(temp_in[RC5_WORD_LEN+0],
                                   temp_in[RC5_WORD_LEN+1],
                                   temp_in[RC5_WORD_LEN+2],
                                   temp_in[RC5_WORD_LEN+3]);

   pt[0]=temp_word_1; 
   pt[1]=temp_word_2;


   // Encode
   RC5_EncryptBlock(pt, ct);


   #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

   // Save crypt data
   for(int i=0; i<RC5_WORD_LEN; i++)
    {
     // Save crypt data with shift to RC5_BLOCK_LEN
     // btw. in first block putted IV 
     out[notCryptDataSize+shift+i]=RC5_GetByteFromWord(ct[0], i);
     out[notCryptDataSize+shift+RC5_WORD_LEN+i]=RC5_GetByteFromWord(ct[1], i);
    }


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


   block++;
  }


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


 // -----------------------------------
 // Return input vector to firsted data
 // -----------------------------------

 // Remove size block (for all formats)
 in.erase(in.begin(), in.begin()+RC5_BLOCK_LEN);

 // Remove random data blocks
 if(firsRandomDataBlocks>0) 
  for(unsigned int n=1; n<=firsRandomDataBlocks; n++)
   in.erase(in.begin(), in.begin()+RC5_BLOCK_LEN);

 // Remove from input vector last random byte for aligning
 if(in.size()>clean_data_size)
  in.erase(in.begin()+clean_data_size, in.end());

}