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 BYTE[] to DWORD in a portable way 30 * s_vPutUINT32 - Convert from DWORD to BYTE[] 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 42#include "tmacro.h" 43#include "michael.h" 44 45/*--------------------- Static Definitions -------------------------*/ 46 47/*--------------------- Static Variables --------------------------*/ 48 49/*--------------------- Static Functions --------------------------*/ 50/* 51 * static DWORD s_dwGetUINT32(BYTE * p); Get DWORD from 52 * 4 bytes LSByte first 53 * static void s_vPutUINT32(BYTE* p, DWORD val); Put DWORD into 54 * 4 bytes LSByte first 55 */ 56static void s_vClear(void); /* Clear the internal message, 57 * resets the object to the 58 * state just after construction. */ 59static void s_vSetKey(DWORD dwK0, DWORD dwK1); 60static void s_vAppendByte(BYTE b); /* Add a single byte to the internal 61 * message */ 62 63/*--------------------- Export Variables --------------------------*/ 64static DWORD L, R; /* Current state */ 65static DWORD K0, K1; /* Key */ 66static DWORD M; /* Message accumulator (single word) */ 67static unsigned int nBytesInM; /* # bytes in M */ 68 69/*--------------------- Export Functions --------------------------*/ 70 71/* 72static DWORD s_dwGetUINT32 (BYTE * p) 73// Convert from BYTE[] to DWORD in a portable way 74{ 75 DWORD res = 0; 76 unsigned int i; 77 for (i = 0; i < 4; i++) 78 res |= (*p++) << (8*i); 79 return res; 80} 81 82static void s_vPutUINT32(BYTE *p, DWORD val) 83// Convert from DWORD to BYTE[] in a portable way 84{ 85 unsigned int i; 86 for (i = 0; i < 4; i++) { 87 *p++ = (BYTE) (val & 0xff); 88 val >>= 8; 89 } 90} 91*/ 92 93static void s_vClear(void) 94{ 95 /* Reset the state to the empty message. */ 96 L = K0; 97 R = K1; 98 nBytesInM = 0; 99 M = 0; 100} 101 102static void s_vSetKey(DWORD dwK0, DWORD dwK1) 103{ 104 /* Set the key */ 105 K0 = dwK0; 106 K1 = dwK1; 107 /* and reset the message */ 108 s_vClear(); 109} 110 111static void s_vAppendByte(BYTE b) 112{ 113 /* Append the byte to our word-sized buffer */ 114 M |= b << (8*nBytesInM); 115 nBytesInM++; 116 /* Process the word if it is full. */ 117 if (nBytesInM >= 4) { 118 L ^= M; 119 R ^= ROL32(L, 17); 120 L += R; 121 R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); 122 L += R; 123 R ^= ROL32(L, 3); 124 L += R; 125 R ^= ROR32(L, 2); 126 L += R; 127 /* Clear the buffer */ 128 M = 0; 129 nBytesInM = 0; 130 } 131} 132 133void MIC_vInit(DWORD dwK0, DWORD dwK1) 134{ 135 /* Set the key */ 136 s_vSetKey(dwK0, dwK1); 137} 138 139 140void MIC_vUnInit(void) 141{ 142 /* Wipe the key material */ 143 K0 = 0; 144 K1 = 0; 145 146 /* And the other fields as well. */ 147 /* Note that this sets (L,R) to (K0,K1) which is just fine. */ 148 s_vClear(); 149} 150 151void MIC_vAppend(PBYTE src, unsigned int nBytes) 152{ 153 /* This is simple */ 154 while (nBytes > 0) { 155 s_vAppendByte(*src++); 156 nBytes--; 157 } 158} 159 160void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR) 161{ 162 /* Append the minimum padding */ 163 s_vAppendByte(0x5a); 164 s_vAppendByte(0); 165 s_vAppendByte(0); 166 s_vAppendByte(0); 167 s_vAppendByte(0); 168 /* and then zeroes until the length is a multiple of 4 */ 169 while (nBytesInM != 0) 170 s_vAppendByte(0); 171 /* The s_vAppendByte function has already computed the result. */ 172 *pdwL = L; 173 *pdwR = R; 174 /* Reset to the empty message. */ 175 s_vClear(); 176} 177