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