- 论坛徽章:
- 0
|
Simulation Program Listing
Header file
/*---------------------------------------------------------
* Kasumi.h
*---------------------------------------------------------*/
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
/*----- a 64-bit structure to help with endian issues -----*/
typedef union {
u32 b32[2];
u16 b16[4];
u8 b8[8];
} REGISTER64;
/*------------- prototypes --------------------------------*/
void KeySchedule( u8 *key );
void Kasumi( u8 *data );
u8 * f9( u8 *key,int count,int fresh, int dir,u8 *data,int length );
void f8( u8 *key,int count,int bearer,int dir,u8 *data,int length );
Function f8
/*-------------------------------------------------------------------
* F8 - Confidentiality Algorithm
*-------------------------------------------------------------------
*
* A sample implementation of f8, the 3GPP Confidentiality algorithm.
*
* This has been coded for clarity, not necessarily for efficiency.
*
* This will compile and run correctly on both Intel (little endian)
* and Sparc (big endian) machines. (Compilers used supported 32-bit ints)
*
* Version 1.0 05 November 1999
*
*-------------------------------------------------------------------*/
#include "kasumi.h"
#include <stdio.h>
/*---------------------------------------------------------
* f8()
* Given key, count, bearer, direction, data,
* and bit length encrypt the bit stream
*---------------------------------------------------------*/
void f8( u8 *key, int count, int bearer, int dir, u8 *data, int length )
{
REGISTER64 A; /* the modifier */
REGISTER64 temp; /* The working register */
int i, n;
u8 ModKey[16]; /* Modified key */
u16 blkcnt; /* The block counter */
/* Start by building our global modifier */
temp.b32[0] = temp.b32[1] = 0;
A.b32[0] = A.b32[1] = 0;
/* initialise register in an endian correct manner*/
A.b8[0] = (u (count>>24);
A.b8[1] = (u (count>>16);
A.b8[2] = (u (count>> ;
A.b8[3] = (u (count);
A.b8[4] = (u (bearer<<3);
A.b8[4] |= (u (dir<<2);
/* Construct the modified key and then "kasumi" A */
for( n=0; n<16; ++n )
ModKey[n] = (u (key[n] ^ 0x55);
KeySchedule( ModKey );
Kasumi( A.b8 ); /* First encryption to create modifier */
/* Final initialisation steps */
blkcnt = 0;
KeySchedule( key );
/* Now run the block cipher */
while( length > 0 )
{
/* First we calculate the next 64-bits of keystream */
/* XOR in A and BLKCNT to last value */
temp.b32[0] ^= A.b32[0];
temp.b32[1] ^= A.b32[1];
temp.b8[7] ^= (u blkcnt;
temp.b8[6] ^= (u (blkcnt>>8);
/* KASUMI it to produce the next block of keystream */
Kasumi( temp.b8 );
/* Set <n> to the number of bytes of input data *
* we have to modify. (=8 if length <= 64) */
if( length >= 64 )
n = 8;
else
n = (length+7)/8;
/* XOR the keystream with the input data stream */
for( i=0; i<n; ++i )
*data++ ^= temp.b8;
length -= 64; /* done another 64 bits */
++blkcnt; /* increment BLKCNT */
}
}
/*-----------------------------------------------------------
* e n d o f f 8 . c
*-----------------------------------------------------------*/
Function f9
/*-------------------------------------------------------------------
* F9 - Integrity Algorithm
*-------------------------------------------------------------------
*
* A sample implementation of f9, the 3GPP Integrity algorithm.
*
* This has been coded for clarity, not necessarily for efficiency.
*
* This will compile and run correctly on both Intel (little endian)
* and Sparc (big endian) machines. (Compilers used supported 32-bit ints)
*
* Version 1.1 05 September 2000
*
*-------------------------------------------------------------------*/
#include "kasumi.h"
#include <stdio.h>
/*---------------------------------------------------------
* f9()
* Given key, count, fresh, direction, data,
* and message length, calculate the hash value
*---------------------------------------------------------*/
u8 *f9( u8 *key, int count, int fresh, int dir, u8 *data, int length )
{
REGISTER64 A; /* Holds the CBC chained data */
REGISTER64 B; /* Holds the XOR of all KASUMI outputs */
u8 FinalBit[8] = {0x80, 0x40, 0x20, 0x10, 8,4,2,1};
u8 ModKey[16];
static u8 mac_i[4]; /* static memory for the result */
int i, n;
/* Start by initialising the block cipher */
KeySchedule( key );
/* Next initialise the MAC chain. Make sure we *
* have the data in the right byte order. *
* <A> holds our chaining value... *
* <B> is the running XOR of all KASUMI o/ps */
for( n=0; n<4; ++n )
{
A.b8[n] = (u8)(count>>(24-(n*8)));
A.b8[n+4] = (u8)(fresh>>(24-(n*8)));
}
Kasumi( A.b8 );
B.b32[0] = A.b32[0];
B.b32[1] = A.b32[1];
/* Now run the blocks until we reach the last block */
while( length >= 64 )
{
for( n=0; n<8; ++n )
A.b8[n] ^= *data++;
Kasumi( A.b8 );
length -= 64;
B.b32[0] ^= A.b32[0]; /* running XOR across */
B.b32[1] ^= A.b32[1]; /* the block outputs */
}
/* Process whole bytes in the last block */
n = 0;
while( length >=8 )
{
A.b8[n++] ^= *data++;
length -= 8;
}
/* Now add the direction bit to the input bit stream *
* If length (which holds the # of data bits in the *
* last byte) is non-zero we add it in, otherwise *
* it has to start a new byte. */
if( length )
{
i = *data;
if( dir )
i |= FinalBit[length];
}
else
i = dir ? 0x80 : 0;
A.b8[n++] ^= (u8)i;
/* Now add in the final '1' bit. The problem here *
* is if the message length happens to be n*64-1. *
* If so we need to process this block and then *
* create a new input block of 0x8000000000000000. */
if( (length==7) && (n==8 ) ) /* then we've filled the block */
{
Kasumi( A.b8 );
B.b32[0] ^= A.b32[0]; /* running XOR across */
B.b32[1] ^= A.b32[1]; /* the block outputs */
A.b8[0] ^= 0x80; /* toggle first bit */
i = 0x80;
n = 1;
}
else
{
if( length == 7 ) /* we finished off the last byte */
A.b8[n] ^= 0x80; /* so start a new one..... */
else
A.b8[n-1] ^= FinalBit[length+1];
}
Kasumi( A.b8 );
B.b32[0] ^= A.b32[0]; /* running XOR across */
B.b32[1] ^= A.b32[1]; /* the block outputs */
/* Final step is to KASUMI what we have using the *
* key XORd with 0xAAAA..... */
for( n=0; n<16; ++n )
ModKey[n] = (u8)*key++ ^ 0xAA;
KeySchedule( ModKey );
Kasumi( B.b8 );
/* We return the left-most 32-bits of the result */
for( n=0; n<4; ++n )
mac_i[n] = B.b8[n];
return( mac_i );
}
/*-----------------------------------------------------------
* e n d o f f 9 . c
*-----------------------------------------------------------*/
[ 本帖最后由 晨雨 于 2006-8-1 12:43 编辑 ] |
|