Leaked source code of windows server 2003
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.

125 lines
3.4 KiB

  1. /* Microsoft Corporation (C) 2000 */
  2. #include "crptkPCH.h"
  3. #include "bv4.h"
  4. void bv4_key_C(BV4_KEYSTRUCT *pState, DWORD dwLen, unsigned char *buf)
  5. {
  6. if (pState == NULL)
  7. {
  8. return; // Too bad we return void.
  9. }
  10. int keyLength = dwLen;
  11. BYTE *key = buf;
  12. DWORD i;
  13. for (i = 0; i < 256; i++)
  14. {
  15. pState->p_T[i] = (unsigned char)i;
  16. }
  17. // fill k with the key, repeated as many times as necessary
  18. // to fill the entire array;
  19. DWORD k[256]; // contains only 8-bit values zero-extended to 32 bits.
  20. int keyPos = 0;
  21. for (i = 0; i < 256; i++)
  22. {
  23. if (keyPos >= keyLength)
  24. {
  25. keyPos = 0;
  26. }
  27. k[i] = key[keyPos++];
  28. }
  29. DWORD j = 0;
  30. for (i = 0; i < 256; i++)
  31. {
  32. j = (j + pState->p_T[i] + k[i]) & 0xff;
  33. DWORD tmp = pState->p_T[i];
  34. pState->p_T[i] = pState->p_T[j];
  35. pState->p_T[j] = (unsigned char)tmp;
  36. }
  37. // treat alpha and beta as one contiguous array of 33 4-byte blocks.
  38. // see "Applied Cryptography", 1996, by Bruce Schneier, p. 397.
  39. i = 0;
  40. j = 0;
  41. for (int m = 0; m < 33; m++)
  42. {
  43. DWORD nextDword = 0;
  44. // gather up the next 4 bytes of keys into one DWORD
  45. for (int n = 0; n < 4; n++)
  46. {
  47. i = (i+1) & 0xff;
  48. DWORD ti = pState->p_T[i];
  49. j = (j+ti) & 0xff;
  50. // swap T[i] and T[j];
  51. DWORD tj = pState->p_T[j];
  52. pState->p_T[i] = (unsigned char)tj;
  53. pState->p_T[j] = (unsigned char)ti;
  54. DWORD t = (ti+tj) & 0xff;
  55. DWORD kk = pState->p_T[t];
  56. nextDword |= kk << (n*8);
  57. }
  58. if (m == 0)
  59. {
  60. pState->p_alpha = nextDword;
  61. }
  62. else
  63. {
  64. pState->p_beta[m-1] = nextDword;
  65. }
  66. }
  67. // keep the final state as the state we need for the new algorithm.
  68. // T has already been updated.
  69. pState->p_R = (unsigned char)i;
  70. pState->p_S = (unsigned char)j;
  71. }
  72. // cipher: generate a stream of 32-bit keys and xor them with the
  73. // contents of buffer. This can be used to encrypt/decrypt
  74. // a stream of data.
  75. void bv4_C(BV4_KEYSTRUCT *pState, DWORD dwLen, unsigned char *buf)
  76. {
  77. if (pState == NULL)
  78. {
  79. return; // Too bad we return void.
  80. }
  81. DWORD *buffer = (DWORD *)buf;
  82. DWORD bufferLength = dwLen / sizeof(DWORD);
  83. DWORD *last = buffer + bufferLength;
  84. // load field values into local variables
  85. // the following change on every iteration of the loop
  86. DWORD r = pState->p_R;
  87. DWORD s = pState->p_S;
  88. DWORD alpha = pState->p_alpha;
  89. // the following are loop invariant
  90. unsigned char *t = pState->p_T;
  91. DWORD *beta = pState->p_beta;
  92. for (last = buffer + bufferLength; buffer < last; buffer++)
  93. {
  94. r = (r+1) & 0xff;
  95. DWORD tr = t[r];
  96. s = (s+tr) & 0xff;
  97. DWORD ts = t[s];
  98. t[r] = (unsigned char)ts;
  99. t[s] = (unsigned char)tr;
  100. DWORD tmp = (ts+tr) & 0xff;
  101. DWORD randPad = alpha * t[tmp];
  102. *buffer = randPad^(*buffer);
  103. alpha = alpha + beta[s & 0x1f];
  104. }
  105. // update the field values from the local variables
  106. pState->p_R = (unsigned char)r;
  107. pState->p_S = (unsigned char)s;
  108. pState->p_alpha = alpha;
  109. }