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.

199 lines
5.6 KiB

  1. // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
  2. //
  3. // Copyright (c) 1985-2000 Microsoft Corporation
  4. //
  5. // This file is part of the Microsoft Research IPv6 Network Protocol Stack.
  6. // You should have received a copy of the Microsoft End-User License Agreement
  7. // for this software along with this release; see the file "license.txt".
  8. // If not, please see http://www.research.microsoft.com/msripv6/license.htm,
  9. // or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
  10. //
  11. // Abstract:
  12. //
  13. // HMAC (Hashed? Message Authentication Code) wrapper for MD5 algorithm.
  14. // This code is based on the algorithm given in RFC 2104, which for
  15. // HMAC-MD5 is MD5(Key XOR outer pad, MD5(Key XOR inner pad, text)), where
  16. // the inner pad is 64 bytes of 0x36 and the outer pad is 64 bytes of 0x5c.
  17. //
  18. #include <string.h>
  19. #include "oscfg.h"
  20. #include "md5.h"
  21. //* HMAC_MD5KeyPrep - preprocess raw keying data into directly usuable form.
  22. //
  23. // This routine is called to convert raw keying information into the most
  24. // convienient form for later processing. For MD5, we hash keys larger than
  25. // 64 bytes down to 64 bytes. We also perform the XOR operations between the
  26. // key and the inner and outer pads here since they don't change once we have
  27. // the key. Thus we return 128 bytes of data: 64 bytes of the (possibly
  28. // folded) key XOR'd with the inner pad, and 64 bytes of the key XOR'd with
  29. // the outer pad.
  30. //
  31. // REVIEW: Instead of "Temp", we could operate directly "*Key".
  32. //
  33. void
  34. HMAC_MD5KeyPrep(
  35. uchar *RawKey, // Raw keying information.
  36. uint RawKeySize, // Size of above in bytes.
  37. uchar *Key) // Resulting 128 bytes of preprocessed key info.
  38. {
  39. uchar Temp[128];
  40. uint Loop;
  41. //
  42. // Load raw key into temp storage.
  43. // Constrain size of keying information to 64 bytes.
  44. //
  45. memset(Temp, 0, 64);
  46. if (RawKeySize > 64) {
  47. MD5_CTX Context;
  48. //
  49. // Use MD5 to hash key down to 16 bytes.
  50. //
  51. MD5Init(&Context);
  52. MD5Update(&Context, RawKey, RawKeySize);
  53. MD5Final(&Context);
  54. memcpy(Temp, Context.digest, MD5DIGESTLEN);
  55. } else
  56. memcpy(Temp, RawKey, RawKeySize);
  57. //
  58. // The first 64 bytes of "Temp" contain our (possibly hashed) key.
  59. // Make a copy of this in the second 64 bytes.
  60. //
  61. memcpy(&Temp[64], Temp, 64);
  62. //
  63. // XOR the first 64 bytes with the inner pad, and the second 64 bytes
  64. // with the outer pad.
  65. //
  66. for (Loop = 0; Loop < 64; Loop++) {
  67. Temp[Loop] ^= 0x36; // Inner Pad.
  68. Temp[Loop + 64] ^= 0x5c; // Outer Pad.
  69. }
  70. //
  71. // Return the result to location designated by our caller.
  72. //
  73. memcpy(Key, Temp, 128);
  74. //
  75. // Zero sensitive information.
  76. // REVIEW: bother?
  77. //
  78. RtlSecureZeroMemory(Temp, 128);
  79. }
  80. //* HMAC_MD5Init - prepare to process data.
  81. //
  82. void
  83. HMAC_MD5Init(
  84. void *Context, // HMAC-MD5 context maintained across operations.
  85. uchar *Key) // Keying information.
  86. {
  87. MD5_CTX *MD5_Context = Context;
  88. //
  89. // Start off the inner hash. I.e. "MD5(Key XOR inner pad, ...".
  90. //
  91. MD5Init(MD5_Context);
  92. MD5Update(MD5_Context, Key, 64);
  93. }
  94. //* HMAC_MD5Op - Process a chunk of data.
  95. //
  96. void
  97. HMAC_MD5Op(
  98. void *Context, // HMAC-MD5 context maintained across operations.
  99. uchar *Key, // Keying information.
  100. uchar *Data, // Data to process.
  101. uint Len) // Amount of above in bytes.
  102. {
  103. MD5_CTX *MD5_Context = Context;
  104. UNREFERENCED_PARAMETER(Key);
  105. //
  106. // Continue the inner hash. I.e. "MD5(..., text)".
  107. //
  108. MD5Update(MD5_Context, Data, Len);
  109. }
  110. //* HMAC_MD5Finalize - close off processing current data and return result.
  111. //
  112. // REVIEW: Instead of "Temp", we could operate directly "*Result".
  113. //
  114. void
  115. HMAC_MD5Final(
  116. void *Context, // HMAC-MD5 context maintained across operations.
  117. uchar *Key, // Keying information.
  118. uchar *Result) // Where to put result of this process.
  119. {
  120. uchar Temp[16];
  121. MD5_CTX *MD5_Context = Context;
  122. //
  123. // Finish the inner hash.
  124. //
  125. MD5Final(MD5_Context);
  126. memcpy(Temp, MD5_Context->digest, MD5DIGESTLEN);
  127. //
  128. // Perform the outer hash. I.e. MD5(Key XOR outer pad, ...).
  129. // MD5Final returns the result directly to our caller.
  130. //
  131. MD5Init(MD5_Context);
  132. MD5Update(MD5_Context, &Key[64], 64);
  133. MD5Update(MD5_Context, Temp, 16);
  134. MD5Final(MD5_Context);
  135. memcpy(Result, MD5_Context->digest, MD5DIGESTLEN);
  136. //
  137. // Zero sensitive information.
  138. // REVIEW: bother?
  139. //
  140. RtlSecureZeroMemory(Temp, 16);
  141. }
  142. void
  143. HMAC_MD5_96Final(
  144. void *Context, // HMAC-MD5 context maintained across operations.
  145. uchar *Key, // Keying information.
  146. uchar *Result) // Where to put result of this process.
  147. {
  148. uchar Temp[16];
  149. MD5_CTX *MD5_Context = Context;
  150. //
  151. // Finish the inner hash.
  152. //
  153. MD5Final(MD5_Context);
  154. memcpy(Temp, MD5_Context->digest, MD5DIGESTLEN);
  155. //
  156. // Perform the outer hash. I.e. MD5(Key XOR outer pad, ...).
  157. //
  158. MD5Init(MD5_Context);
  159. MD5Update(MD5_Context, &Key[64], 64);
  160. MD5Update(MD5_Context, Temp, 16);
  161. MD5Final(MD5_Context);
  162. //
  163. // Truncate the MD5 16 byte output to 12 bytes.
  164. // The first 12 bytes from the left are stored.
  165. //
  166. memcpy(Result, MD5_Context->digest, 12);
  167. //
  168. // Zero sensitive information.
  169. // REVIEW: bother?
  170. //
  171. RtlSecureZeroMemory(Temp, 16);
  172. }