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.

144 lines
3.3KB

  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 implement recovery password related functions such as verify, testing etc
  14. sample recovery password 428593-377069-419914-450824-036729-210243-469029-482394
  15. */
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <malloc.h>
  19. #include "../common.h"
  20. #include "recoverypassword.h"
  21. #include "../sha256/sha.h"
  22. long Calculate_Recovery_Key_From_Password(unsigned char *recovery_password,
  23. unsigned char *header, unsigned long *output);
  24. long Calculate_Key(unsigned char *recovery_password, unsigned long
  25. recovery_password_length, unsigned char *salt, unsigned long *output);
  26. long Calculate_Recovery_Key_From_Password(unsigned char *recovery_password,
  27. unsigned char *header, unsigned long *output){
  28. //since recovery key consists of 8 blocks of data,
  29. // preprocess them, at this stage recovery password is of the form
  30. // 1111-1111-11111-11111 and so on
  31. unsigned long temporary_password_block[8];
  32. int16 recovery_pass[8];
  33. unsigned long loop_var_i;
  34. unsigned char buffer[2000];
  35. unsigned char buffer2[2000];
  36. memset(temporary_password_block, 0, sizeof(temporary_password_block));
  37. sscanf(recovery_password, "%d-%d-%d-%d-%d-%d-%d-%d",
  38. &temporary_password_block[0], &temporary_password_block[1],
  39. &temporary_password_block[2], &temporary_password_block[3],
  40. &temporary_password_block[4], &temporary_password_block[5],
  41. &temporary_password_block[6], &temporary_password_block[7]);
  42. for (loop_var_i = 0; loop_var_i <= 7; loop_var_i++){
  43. // each block should be independantly perfectly divisible by 11
  44. if ((temporary_password_block[loop_var_i] % 11) == 0)
  45. recovery_pass[loop_var_i] = (int16)(temporary_password_block[loop_var_i]
  46. / 11);
  47. else
  48. return 0;
  49. }
  50. // we are here means password looks valid
  51. // now try to obtain actual key
  52. return Calculate_Key((unsigned char*)recovery_pass, 16,
  53. // since this is 128 bit key
  54. header + 12, output);
  55. }
  56. long Calculate_Key(unsigned char *recovery_password, unsigned long
  57. recovery_password_length, unsigned char *salt, unsigned long *output){
  58. blob my_blob;
  59. unsigned char *output_buffer;
  60. unsigned long max_loop_count = 0x100000;
  61. memset(&my_blob, 0, sizeof(blob));
  62. memcpy(my_blob.salt, salt, 0x10); // we only take 16 bytes of salt
  63. if (recovery_password_length < 0x65535){
  64. sha256(recovery_password, recovery_password_length, my_blob.sha_password);
  65. }
  66. else
  67. return 0;
  68. /// return due to error caused
  69. while (max_loop_count){
  70. sha256((unsigned char*) &my_blob, sizeof(blob), my_blob.sha_current);
  71. my_blob.hash_count++;
  72. max_loop_count--;
  73. }
  74. output_buffer = malloc(0xc + 0x20);
  75. memset(output_buffer, 0, 0x2c);
  76. // copy the resultant key out to the buffer
  77. memcpy((output_buffer + 0xC), &my_blob.sha_current, 0x20);
  78. *output = (int32)output_buffer;
  79. // TODO zero out the buffers
  80. // also clear up the the internal state of SHA function
  81. return 0;
  82. }