Exemplo n.º 1
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());

}
Exemplo n.º 2
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());

}