linux/drivers/staging/vt6656/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 u8[] to u32 in a portable way
  30 *      s_vPutUINT32 - Convert from u32 to u8[] 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/*
  46 * static u32 s_dwGetUINT32(u8 * p);         Get u32 from
  47 *                                                      4 bytes LSByte first
  48 * static void s_vPutUINT32(u8* p, u32 val); Put u32 into
  49 *                                                      4 bytes LSByte first
  50 */
  51static void s_vClear(void);             /* Clear the internal message,
  52                                         * resets the object to the
  53                                         * state just after construction. */
  54static void s_vSetKey(u32 dwK0, u32 dwK1);
  55static void s_vAppendByte(u8 b);        /* Add a single byte to the internal
  56                                         * message */
  57
  58static u32  L, R;               /* Current state */
  59static u32  K0, K1;             /* Key */
  60static u32  M;          /* Message accumulator (single word) */
  61static unsigned int   nBytesInM;        /* # bytes in M */
  62
  63/*
  64static u32 s_dwGetUINT32 (u8 * p)
  65// Convert from u8[] to u32 in a portable way
  66{
  67        u32 res = 0;
  68        unsigned int i;
  69        for (i = 0; i < 4; i++)
  70                res |= (*p++) << (8*i);
  71        return res;
  72}
  73
  74static void s_vPutUINT32(u8 *p, u32 val)
  75// Convert from u32 to u8[] in a portable way
  76{
  77        unsigned int i;
  78        for (i = 0; i < 4; i++) {
  79                *p++ = (u8) (val & 0xff);
  80                val >>= 8;
  81        }
  82}
  83*/
  84
  85static void s_vClear(void)
  86{
  87        /* Reset the state to the empty message. */
  88        L = K0;
  89        R = K1;
  90        nBytesInM = 0;
  91        M = 0;
  92}
  93
  94static void s_vSetKey(u32 dwK0, u32 dwK1)
  95{
  96        /* Set the key */
  97        K0 = dwK0;
  98        K1 = dwK1;
  99        /* and reset the message */
 100        s_vClear();
 101}
 102
 103static void s_vAppendByte(u8 b)
 104{
 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        }
 123}
 124
 125void MIC_vInit(u32 dwK0, u32 dwK1)
 126{
 127        /* Set the key */
 128        s_vSetKey(dwK0, dwK1);
 129}
 130
 131void MIC_vUnInit(void)
 132{
 133        /* Wipe the key material */
 134        K0 = 0;
 135        K1 = 0;
 136
 137        /* And the other fields as well. */
 138        /* Note that this sets (L,R) to (K0,K1) which is just fine. */
 139        s_vClear();
 140}
 141
 142void MIC_vAppend(u8 * src, unsigned int nBytes)
 143{
 144    /* This is simple */
 145        while (nBytes > 0) {
 146                s_vAppendByte(*src++);
 147                nBytes--;
 148        }
 149}
 150
 151void MIC_vGetMIC(u32 * pdwL, u32 * pdwR)
 152{
 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();
 167}
 168