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