NVbit : Accessing Bitlocker volumes from linux.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
4.0KB

  1. /*
  2. nvbit Bitlocker for linux
  3. ------------------------------
  4. Nitin Kumar nitin at nvlabs.in
  5. Vipin Kumar vipin at nvlabs.in
  6. web: http://www.nvlabs.in
  7. Licensed under GPL Version 3
  8. -------------------
  9. Copyright (c) 2008
  10. Released under the GPL Version 3
  11. http://www.gnu.org/licenses/gpl-3.0.txt
  12. */
  13. /* this file implements functions to decrypt in AESS, CCM mode as done by bitlocker
  14. */
  15. #include <string.h>
  16. #include "decryptkey.h"
  17. #include "../aes/aes.h"
  18. #include "../header.h"
  19. /*
  20. when encrypting a microsoft compatible style a 16 byte hash is prepended to data
  21. which contains AES form authentication code, but really we don't care about
  22. or should we start caring ????
  23. */
  24. // user is responsible for aligning the input to align on 6 byte boundary
  25. void aes_ccm_encrypt_decrypt(aes_context *ctxt,
  26. unsigned char *iv, unsigned long iv_length,
  27. unsigned char *input, unsigned long input_length,
  28. unsigned char *output)
  29. {
  30. unsigned char internal_iv[20];
  31. unsigned char loop_var;
  32. unsigned char temp_buf[16];
  33. int32 local_input_length;
  34. /*
  35. here is how the counter works in microsoft compatible ccm implementation
  36. user supplies less than 16 byte iv
  37. after copying it forms into this format
  38. 1 byte field
  39. 15-iv_length-1 | iv (max 14 bytes) | a single byte counter counting from zero
  40. now applying counter mode of aes
  41. */
  42. memset(internal_iv,0,sizeof(internal_iv));
  43. memcpy(internal_iv+1 , iv, (iv_length % 16)); // avoiding buffer overflow
  44. *internal_iv = 15 -iv_length -1;
  45. /* aes_crypt_ecb( ctxt, mode, internal_iv, temp_buf );
  46. // xor it encoded internal_iv (present in temp_buf
  47. for(loop_var =0 ; loop_var <=15;loop_var++)
  48. output[loop_var] = input[loop_var] ^ temp_buf[loop_var];
  49. // increment internal_iv
  50. internal_iv[15] = 1;
  51. // now process the whole data
  52. input = input+16;
  53. output = output+16;
  54. */
  55. local_input_length = input_length;
  56. while ( local_input_length > 0) {
  57. aes_crypt_ecb( ctxt, AES_ENCRYPT, internal_iv, temp_buf );
  58. for(loop_var =0 ; loop_var <=15;loop_var++)
  59. output[loop_var] = input[loop_var] ^ temp_buf[loop_var];
  60. internal_iv[15]++;
  61. local_input_length -= 16;
  62. input = input+16;
  63. output = output+16;
  64. // handle last block since data could be misaligned
  65. if ( local_input_length > 0 &&
  66. local_input_length < 16)
  67. {
  68. aes_crypt_ecb( ctxt, AES_ENCRYPT, internal_iv, temp_buf );
  69. for(loop_var =0 ; loop_var <=15;loop_var++)
  70. output[loop_var] = input[loop_var] ^ temp_buf[loop_var];
  71. break; // jump out of loop
  72. }
  73. }
  74. }
  75. long decrypt(unsigned char *input,
  76. unsigned char *key,
  77. unsigned long *output,
  78. unsigned long *output_size)
  79. {
  80. aes_context ctx;
  81. unsigned char local_input_buffer[1024];
  82. unsigned char local_output_buffer[1024];
  83. unsigned long input_size;
  84. unsigned long local_output_size;
  85. unsigned char *output_buffer;
  86. HEADER *header = (HEADER *)input;
  87. //allocate output_buffer
  88. output_buffer = malloc(header->Size - 36); /* 8 byte header
  89. 12 byte nounce
  90. 16 byte authenticator */
  91. local_output_size= header->Size - 36;
  92. input_size = header->Size - 20 ; /* 8 byte header
  93. 12 byte nounce
  94. auhtenticator is used while decrypting
  95. */
  96. memcpy ( local_input_buffer , input + 20 , input_size) ;
  97. // set key which is used to decrypt
  98. aes_setkey_enc( &ctx, key + 12, 256);
  99. aes_ccm_encrypt_decrypt (&ctx,
  100. input+8,
  101. 0xc , // nounce is hardcode to be 0xc or 12 bytes
  102. local_input_buffer,
  103. input_size,
  104. output);
  105. //local_output_buffer);
  106. *output_size = local_output_size;
  107. memmove(output, ((long)output + 16),local_output_size);
  108. memset ( ((long)output+local_output_size), 0 , 32);
  109. //memset(local_output_buffer,0,output_size+16);
  110. free(output_buffer);
  111. return 0;
  112. }