Root/ks7010/src/michael_mic.c

1/*
2 * Driver for KeyStream wireless LAN
3 *
4 * michael_mic.c
5 * $Id: michael_mic.c 991 2009-09-14 01:38:58Z sekine $
6 *
7 * Copyright (C) 2005-2008 KeyStream Corp.
8 * Copyright (C) 2009 Renesas Technology Corp.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it undr the terms of the GNU General Public License version 2 as
12 * published by the Free Sotware Foundation.
13 */
14
15#include <linux/types.h>
16#include <linux/string.h>
17#include "michael_mic.h"
18
19// Rotation functions on 32 bit values
20#define ROL32( A, n ) ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
21#define ROR32( A, n ) ROL32( (A), 32-(n) )
22// Convert from Byte[] to UInt32 in a portable way
23#define getUInt32( A, B ) (uint32_t)(A[B+0] << 0) + (A[B+1] << 8) + (A[B+2] << 16) + (A[B+3] << 24)
24
25// Convert from UInt32 to Byte[] in a portable way
26#define putUInt32( A, B, C ) A[B+0] = (uint8_t) (C & 0xff); \
27                A[B+1] = (uint8_t) ((C>>8) & 0xff); \
28                A[B+2] = (uint8_t) ((C>>16) & 0xff); \
29                A[B+3] = (uint8_t) ((C>>24) & 0xff)
30
31// Reset the state to the empty message.
32#define MichaelClear( A ) A->L = A->K0; \
33                A->R = A->K1; \
34                A->nBytesInM = 0;
35
36static
37void MichaelInitializeFunction( struct michel_mic_t *Mic, uint8_t *key )
38{
39    // Set the key
40    Mic->K0 = getUInt32( key , 0 );
41    Mic->K1 = getUInt32( key , 4 );
42
43    //clear();
44    MichaelClear(Mic);
45}
46
47#define MichaelBlockFunction(L, R) \
48do{ \
49    R ^= ROL32( L, 17 ); \
50    L += R; \
51    R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); \
52    L += R; \
53    R ^= ROL32( L, 3 ); \
54    L += R; \
55    R ^= ROR32( L, 2 ); \
56    L += R; \
57}while(0)
58
59
60static
61void MichaelAppend( struct michel_mic_t *Mic, uint8_t *src, int nBytes )
62{
63    int addlen ;
64    if (Mic->nBytesInM) {
65        addlen = 4 - Mic->nBytesInM;
66        if (addlen > nBytes)
67            addlen = nBytes;
68        memcpy(&Mic->M[Mic->nBytesInM], src, addlen);
69        Mic->nBytesInM += addlen;
70        src += addlen;
71        nBytes -= addlen;
72
73        if (Mic->nBytesInM < 4)
74            return;
75
76        Mic->L ^= getUInt32(Mic->M,0);
77        MichaelBlockFunction(Mic->L, Mic->R);
78        Mic->nBytesInM = 0;
79    }
80
81    while(nBytes >= 4){
82        Mic->L ^= getUInt32(src,0);
83        MichaelBlockFunction(Mic->L, Mic->R);
84        src += 4;
85        nBytes -= 4;
86    }
87
88    if (nBytes > 0) {
89        Mic->nBytesInM = nBytes;
90        memcpy(Mic->M, src, nBytes);
91    }
92}
93
94static
95void MichaelGetMIC( struct michel_mic_t *Mic, uint8_t *dst )
96{
97    uint8_t *data = Mic->M;
98    switch (Mic->nBytesInM) {
99    case 0:
100        Mic->L ^= 0x5a;
101        break;
102    case 1:
103        Mic->L ^= data[0] | 0x5a00;
104        break;
105    case 2:
106        Mic->L ^= data[0] | (data[1] << 8) | 0x5a0000;
107        break;
108    case 3:
109        Mic->L ^= data[0] | (data[1] << 8) | (data[2] << 16) |
110            0x5a000000;
111        break;
112    }
113    MichaelBlockFunction(Mic->L, Mic->R);
114    MichaelBlockFunction(Mic->L, Mic->R);
115    // The appendByte function has already computed the result.
116    putUInt32( dst, 0, Mic->L );
117    putUInt32( dst, 4, Mic->R );
118
119    // Reset to the empty message.
120    MichaelClear(Mic);
121}
122
123void MichaelMICFunction( struct michel_mic_t *Mic, uint8_t *Key,
124             uint8_t *Data, int Len, uint8_t priority,
125             uint8_t *Result )
126{
127    uint8_t pad_data[4] = {priority,0,0,0};
128    // Compute the MIC value
129    /*
130     * IEEE802.11i page 47
131     * Figure 43g TKIP MIC processing format
132     * +--+--+--------+--+----+--+--+--+--+--+--+--+--+
133     * |6 |6 |1 |3 |M |1 |1 |1 |1 |1 |1 |1 |1 | Octet
134     * +--+--+--------+--+----+--+--+--+--+--+--+--+--+
135     * |DA|SA|Priority|0 |Data|M0|M1|M2|M3|M4|M5|M6|M7|
136     * +--+--+--------+--+----+--+--+--+--+--+--+--+--+
137     */
138    MichaelInitializeFunction( Mic, Key ) ;
139    MichaelAppend( Mic, (uint8_t*)Data, 12 ); /* |DA|SA| */
140    MichaelAppend( Mic, pad_data, 4 ); /* |Priority|0|0|0| */
141    MichaelAppend( Mic, (uint8_t*)(Data+12), Len -12 ); /* |Data| */
142    MichaelGetMIC( Mic, Result ) ;
143}
144

Archive Download this file



interactive