michael.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. *
  20. * File: michael.cpp
  21. *
  22. * Purpose: The implementation of LIST data structure.
  23. *
  24. * Author: Kyle Hsu
  25. *
  26. * Date: Sep 4, 2002
  27. *
  28. * Functions:
  29. * s_dwGetUINT32 - Convert from unsigned char [] to unsigned long in a portable way
  30. * s_vPutUINT32 - Convert from unsigned long to unsigned char [] in a portable way
  31. * s_vClear - Reset the state to the empty message.
  32. * s_vSetKey - Set the key.
  33. * MIC_vInit - Set the key.
  34. * s_vAppendByte - Append the byte to our word-sized buffer.
  35. * MIC_vAppend - call s_vAppendByte.
  36. * MIC_vGetMIC - Append the minimum padding and call s_vAppendByte.
  37. *
  38. * Revision History:
  39. *
  40. */
  41. #include "tmacro.h"
  42. #include "michael.h"
  43. /*--------------------- Static Definitions -------------------------*/
  44. /*--------------------- Static Variables --------------------------*/
  45. /*--------------------- Static Functions --------------------------*/
  46. /*
  47. static unsigned long s_dwGetUINT32(unsigned char *p); // Get unsigned long from 4 bytes LSByte first
  48. static void s_vPutUINT32(unsigned char *p, unsigned long val); // Put unsigned long into 4 bytes LSByte first
  49. */
  50. static void s_vClear(void); // Clear the internal message,
  51. // resets the object to the state just after construction.
  52. static void s_vSetKey(unsigned long dwK0, unsigned long dwK1);
  53. static void s_vAppendByte(unsigned char b); // Add a single byte to the internal message
  54. /*--------------------- Export Variables --------------------------*/
  55. static unsigned long L, R; // Current state
  56. static unsigned long K0, K1; // Key
  57. static unsigned long M; // Message accumulator (single word)
  58. static unsigned int nBytesInM; // # bytes in M
  59. /*--------------------- Export Functions --------------------------*/
  60. /*
  61. static unsigned long s_dwGetUINT32 (unsigned char *p)
  62. // Convert from unsigned char [] to unsigned long in a portable way
  63. {
  64. unsigned long res = 0;
  65. unsigned int i;
  66. for(i=0; i<4; i++ )
  67. {
  68. res |= (*p++) << (8*i);
  69. }
  70. return res;
  71. }
  72. static void s_vPutUINT32 (unsigned char *p, unsigned long val)
  73. // Convert from unsigned long to unsigned char [] in a portable way
  74. {
  75. unsigned int i;
  76. for(i=0; i<4; i++ )
  77. {
  78. *p++ = (unsigned char) (val & 0xff);
  79. val >>= 8;
  80. }
  81. }
  82. */
  83. static void s_vClear (void)
  84. {
  85. // Reset the state to the empty message.
  86. L = K0;
  87. R = K1;
  88. nBytesInM = 0;
  89. M = 0;
  90. }
  91. static void s_vSetKey (unsigned long dwK0, unsigned long dwK1)
  92. {
  93. // Set the key
  94. K0 = dwK0;
  95. K1 = dwK1;
  96. // and reset the message
  97. s_vClear();
  98. }
  99. static void s_vAppendByte (unsigned char b)
  100. {
  101. // Append the byte to our word-sized buffer
  102. M |= b << (8*nBytesInM);
  103. nBytesInM++;
  104. // Process the word if it is full.
  105. if( nBytesInM >= 4 )
  106. {
  107. L ^= M;
  108. R ^= ROL32( L, 17 );
  109. L += R;
  110. R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
  111. L += R;
  112. R ^= ROL32( L, 3 );
  113. L += R;
  114. R ^= ROR32( L, 2 );
  115. L += R;
  116. // Clear the buffer
  117. M = 0;
  118. nBytesInM = 0;
  119. }
  120. }
  121. void MIC_vInit (unsigned long dwK0, unsigned long dwK1)
  122. {
  123. // Set the key
  124. s_vSetKey(dwK0, dwK1);
  125. }
  126. void MIC_vUnInit (void)
  127. {
  128. // Wipe the key material
  129. K0 = 0;
  130. K1 = 0;
  131. // And the other fields as well.
  132. //Note that this sets (L,R) to (K0,K1) which is just fine.
  133. s_vClear();
  134. }
  135. void MIC_vAppend (unsigned char *src, unsigned int nBytes)
  136. {
  137. // This is simple
  138. while (nBytes > 0)
  139. {
  140. s_vAppendByte(*src++);
  141. nBytes--;
  142. }
  143. }
  144. void MIC_vGetMIC (unsigned long *pdwL, unsigned long *pdwR)
  145. {
  146. // Append the minimum padding
  147. s_vAppendByte(0x5a);
  148. s_vAppendByte(0);
  149. s_vAppendByte(0);
  150. s_vAppendByte(0);
  151. s_vAppendByte(0);
  152. // and then zeroes until the length is a multiple of 4
  153. while( nBytesInM != 0 )
  154. {
  155. s_vAppendByte(0);
  156. }
  157. // The s_vAppendByte function has already computed the result.
  158. *pdwL = L;
  159. *pdwR = R;
  160. // Reset to the empty message.
  161. s_vClear();
  162. }