Merge branch 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / staging / vt6655 / michael.c
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
42 #include "tmacro.h"
43 #include "michael.h"
44
45 /*---------------------  Static Definitions -------------------------*/
46
47 /*---------------------  Static Variables  --------------------------*/
48
49 /*---------------------  Static Functions  --------------------------*/
50
51 static void s_vClear(void);                       // Clear the internal message,
52 // resets the object to the state just after construction.
53 static void s_vSetKey(u32  dwK0, u32  dwK1);
54 static void s_vAppendByte(unsigned char b);            // Add a single byte to the internal message
55
56 /*---------------------  Export Variables  --------------------------*/
57 static u32 L, R;        /* Current state */
58
59 static u32 K0, K1;      /* Key */
60 static u32 M;           /* Message accumulator (single word) */
61 static unsigned int nBytesInM;      // # bytes in M
62
63 /*---------------------  Export Functions  --------------------------*/
64
65 static void s_vClear(void)
66 {
67         // Reset the state to the empty message.
68         L = K0;
69         R = K1;
70         nBytesInM = 0;
71         M = 0;
72 }
73
74 static void s_vSetKey(u32 dwK0, u32 dwK1)
75 {
76         // Set the key
77         K0 = dwK0;
78         K1 = dwK1;
79         // and reset the message
80         s_vClear();
81 }
82
83 static void s_vAppendByte(unsigned char b)
84 {
85         // Append the byte to our word-sized buffer
86         M |= b << (8*nBytesInM);
87         nBytesInM++;
88         // Process the word if it is full.
89         if (nBytesInM >= 4) {
90                 L ^= M;
91                 R ^= ROL32(L, 17);
92                 L += R;
93                 R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
94                 L += R;
95                 R ^= ROL32(L, 3);
96                 L += R;
97                 R ^= ROR32(L, 2);
98                 L += R;
99                 // Clear the buffer
100                 M = 0;
101                 nBytesInM = 0;
102         }
103 }
104
105 void MIC_vInit(u32 dwK0, u32 dwK1)
106 {
107         // Set the key
108         s_vSetKey(dwK0, dwK1);
109 }
110
111 void MIC_vUnInit(void)
112 {
113         // Wipe the key material
114         K0 = 0;
115         K1 = 0;
116
117         // And the other fields as well.
118         //Note that this sets (L,R) to (K0,K1) which is just fine.
119         s_vClear();
120 }
121
122 void MIC_vAppend(unsigned char *src, unsigned int nBytes)
123 {
124         // This is simple
125         while (nBytes > 0) {
126                 s_vAppendByte(*src++);
127                 nBytes--;
128         }
129 }
130
131 void MIC_vGetMIC(u32 *pdwL, u32 *pdwR)
132 {
133         // Append the minimum padding
134         s_vAppendByte(0x5a);
135         s_vAppendByte(0);
136         s_vAppendByte(0);
137         s_vAppendByte(0);
138         s_vAppendByte(0);
139         // and then zeroes until the length is a multiple of 4
140         while (nBytesInM != 0)
141                 s_vAppendByte(0);
142
143         // The s_vAppendByte function has already computed the result.
144         *pdwL = L;
145         *pdwR = R;
146         // Reset to the empty message.
147         s_vClear();
148 }