Example #1
0
void decrypt_key(unsigned char* decryptedSap, unsigned char* keyIn, unsigned char* iv, unsigned char* keyOut)
{
   unsigned char blockIn[16];
   uint32_t key_schedule[11][4];
   uint32_t mode_key_schedule[11][4];
   generate_key_schedule(&decryptedSap[8], key_schedule);
   printf("Generating mode key:\n");
   generate_key_schedule(initial_session_key, mode_key_schedule);
   z_xor(keyIn, blockIn, 1);
   print_block("Input to cycle is: ", blockIn);
   cycle(blockIn, key_schedule);
   for (int j = 0; j < 16; j++)
      keyOut[j] = blockIn[j] ^ iv[j];
   print_block("Output from cycle is: ", keyOut);
   x_xor(keyOut, keyOut, 1);
}
void test_generate_key_schedule()
{
    des_block_t key;
    key.c = 0x13345779;
    key.d = 0x9BBCDFF1;
    des_block_t* key_schedule = generate_key_schedule(key);
    assert(key_schedule[0].c == 0x1B02EF);
    assert(key_schedule[0].d == 0xFC7072);
    assert(key_schedule[15].c == 0xCB3D8B);
    assert(key_schedule[15].d == 0x0E17F5);
}
void test_block_decode()
{
    des_block_t key;
    key.c = 0x13345779;
    key.d = 0x9BBCDFF1;
    des_block_t* key_schedule = generate_key_schedule(key);

    des_block_t message_block;
    message_block.c = 0x01234567;
    message_block.d = 0x89ABCDEF;
    des_block_t decoded = encode_block(message_block, key_schedule, DECODE);
    assert(decoded.c == 0xEE0F7C12);
    assert(decoded.d == 0xE0B09338);

    free(key_schedule);
}
void test_block_encode()
{
    des_block_t key;
    key.c = 0x13345779;
    key.d = 0x9BBCDFF1;
    des_block_t* key_schedule = generate_key_schedule(key);

    des_block_t message_block;
    message_block.c = 0x01234567;
    message_block.d = 0x89ABCDEF;
    des_block_t encoded = encode_block(message_block, key_schedule, ENCODE);
    assert(encoded.c == 0x85E81354);
    assert(encoded.d == 0x0F0AB405);

    free(key_schedule);
}
Example #5
0
void decrypt_sap(unsigned char* sapIn, unsigned char* sapOut)
{
   uint32_t key_schedule[11][4];
   unsigned char* iv;
   print_block("Base sap: ", &sapIn[0xf0]);
   z_xor(sapIn, sapOut, 16);
   generate_key_schedule(sap_key_material, key_schedule);
   print_block("lastSap before cycle: ", &sapOut[0xf0]);
   for (int i = 0xf0; i >= 0x00; i-=0x10)
   {
      printf("Ready to cycle %02X\n", i);
      cycle(&sapOut[i], key_schedule);
      print_block("After cycling, block is: ", &sapOut[i]);
      if (i > 0)
      { // xor with previous block
         iv = &sapOut[i-0x10];
      }
      else
      { // xor with sap IV
         iv = sap_iv;
      }
      for (int j = 0; j < 16; j++)
      {
         printf("%02X ^ %02X -> %02X\n", sapOut[i+j],  iv[j], sapOut[i+j] ^ iv[j]);
         sapOut[i+j] = sapOut[i+j] ^ iv[j];
      }
      printf("Decrypted SAP %02X-%02X:\n", i, i+0xf);
      print_block("", &sapOut[i]);
   }
   // Lastly grind the whole thing through x_key. This is the last time we modify sap
   x_xor(sapOut, sapOut, 16);
   printf("Sap is decrypted to\n");
   for (int i = 0xf0; i >= 0x00; i-=0x10)
   {
      printf("Final SAP %02X-%02X: ", i, i+0xf);
      print_block("", &sapOut[i]);
   }
}
Example #6
0
void decryptMessage(unsigned char* messageIn, unsigned char* decryptedMessage)
{
   unsigned char buffer[16];
   int i, j;
   unsigned char tmp;
   uint32_t key_schedule[11][4];
   int mode = messageIn[12];  // 0,1,2,3
   printf("mode = %02x\n", mode);
   generate_key_schedule(initial_session_key, key_schedule);
      
   // For M0-M6 we follow the same pattern
   for (i = 0; i < 8; i++)
   {      
      // First, copy in the nth block (we must start with the last one)
      for (j = 0; j < 16; j++)
      {
         if (mode == 3)
            buffer[j] = messageIn[(0x80-0x10*i)+j];
         else if (mode == 2 || mode == 1 || mode == 0)
            buffer[j] = messageIn[(0x10*(i+1))+j];   
      }
      // do this permutation and update 9 times. Could this be cycle(), or the reverse of cycle()?
      for (j = 0; j < 9; j++)
      {
         int base = 0x80 - 0x10*j;
         //print_block("About to cycle. Buffer is currently: ", buffer);
         buffer[0x0] = message_table_index(base+0x0)[buffer[0x0]] ^ message_key[mode][base+0x0];
         buffer[0x4] = message_table_index(base+0x4)[buffer[0x4]] ^ message_key[mode][base+0x4];
         buffer[0x8] = message_table_index(base+0x8)[buffer[0x8]] ^ message_key[mode][base+0x8];
         buffer[0xc] = message_table_index(base+0xc)[buffer[0xc]] ^ message_key[mode][base+0xc];

         tmp = buffer[0x0d];
         buffer[0xd] = message_table_index(base+0xd)[buffer[0x9]] ^ message_key[mode][base+0xd];
         buffer[0x9] = message_table_index(base+0x9)[buffer[0x5]] ^ message_key[mode][base+0x9];
         buffer[0x5] = message_table_index(base+0x5)[buffer[0x1]] ^ message_key[mode][base+0x5];
         buffer[0x1] = message_table_index(base+0x1)[tmp]         ^ message_key[mode][base+0x1];

         tmp = buffer[0x02];
         buffer[0x2] = message_table_index(base+0x2)[buffer[0xa]] ^ message_key[mode][base+0x2];
         buffer[0xa] = message_table_index(base+0xa)[tmp]         ^ message_key[mode][base+0xa];
         tmp = buffer[0x06];
         buffer[0x6] = message_table_index(base+0x6)[buffer[0xe]] ^ message_key[mode][base+0x6];
         buffer[0xe] = message_table_index(base+0xe)[tmp]         ^ message_key[mode][base+0xe];

         tmp = buffer[0x3];
         buffer[0x3] = message_table_index(base+0x3)[buffer[0x7]] ^ message_key[mode][base+0x3];
         buffer[0x7] = message_table_index(base+0x7)[buffer[0xb]] ^ message_key[mode][base+0x7];
         buffer[0xb] = message_table_index(base+0xb)[buffer[0xf]] ^ message_key[mode][base+0xb];
         buffer[0xf] = message_table_index(base+0xf)[tmp]         ^ message_key[mode][base+0xf];

         // Now we must replace the entire buffer with 4 words that we read and xor together
         uint32_t word;
         uint32_t* block = (uint32_t*)buffer;
         
         block[0] = table_s9[0x000 + buffer[0x0]] ^ 
                    table_s9[0x100 + buffer[0x1]] ^ 
                    table_s9[0x200 + buffer[0x2]] ^ 
                    table_s9[0x300 + buffer[0x3]];
         block[1] = table_s9[0x000 + buffer[0x4]] ^ 
                    table_s9[0x100 + buffer[0x5]] ^ 
                    table_s9[0x200 + buffer[0x6]] ^ 
                    table_s9[0x300 + buffer[0x7]];
         block[2] = table_s9[0x000 + buffer[0x8]] ^
                    table_s9[0x100 + buffer[0x9]] ^
                    table_s9[0x200 + buffer[0xa]] ^
                    table_s9[0x300 + buffer[0xb]];
         block[3] = table_s9[0x000 + buffer[0xc]] ^
                    table_s9[0x100 + buffer[0xd]] ^
                    table_s9[0x200 + buffer[0xe]] ^
                    table_s9[0x300 + buffer[0xf]];
      }
      // Next, another permute with a different table
      buffer[0x0] = table_s10[(0x0 << 8) + buffer[0x0]];
      buffer[0x4] = table_s10[(0x4 << 8) + buffer[0x4]];
      buffer[0x8] = table_s10[(0x8 << 8) + buffer[0x8]];
      buffer[0xc] = table_s10[(0xc << 8) + buffer[0xc]];

      tmp = buffer[0x0d];
      buffer[0xd] = table_s10[(0xd << 8) + buffer[0x9]];
      buffer[0x9] = table_s10[(0x9 << 8) + buffer[0x5]];
      buffer[0x5] = table_s10[(0x5 << 8) + buffer[0x1]];
      buffer[0x1] = table_s10[(0x1 << 8) + tmp];

      tmp = buffer[0x02];
      buffer[0x2] = table_s10[(0x2 << 8) + buffer[0xa]];
      buffer[0xa] = table_s10[(0xa << 8) + tmp];
      tmp = buffer[0x06];
      buffer[0x6] = table_s10[(0x6 << 8) + buffer[0xe]];
      buffer[0xe] = table_s10[(0xe << 8) + tmp];

      tmp = buffer[0x3];
      buffer[0x3] = table_s10[(0x3 << 8) + buffer[0x7]];
      buffer[0x7] = table_s10[(0x7 << 8) + buffer[0xb]];
      buffer[0xb] = table_s10[(0xb << 8) + buffer[0xf]];
      buffer[0xf] = table_s10[(0xf << 8) + tmp];

      // And finally xor with the previous block of the message, except in mode-2 where we do this in reverse
      if (mode == 2 || mode == 1 || mode == 0)
      {
         if (i > 0)
         {
            xor_blocks(buffer, &messageIn[0x10*i], &decryptedMessage[0x10*i]); // remember that the first 0x10 bytes are the header
         }
         else
            xor_blocks(buffer, message_iv[mode], &decryptedMessage[0x10*i]);
         print_block(" ", &decryptedMessage[0x10*i]);
      }
      else
      {
         if (i < 7)
            xor_blocks(buffer, &messageIn[0x70 - 0x10*i], &decryptedMessage[0x70 - 0x10*i]);
         else
            xor_blocks(buffer, message_iv[mode], &decryptedMessage[0x70 - 0x10*i]);
         printf("Decrypted message block %02X-%02X:", 0x70 - 0x10*i, 0x70 - 0x10*i+0xf);
         print_block(" ", &decryptedMessage[0x70 - 0x10*i]);
      }
   }
}