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