diff options
author | Harald Welte <laforge@gnumonks.org> | 2010-06-30 20:35:02 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2010-06-30 20:35:02 +0200 |
commit | 73998b6cf33f5adabb42bde4bf77a9445d685bd8 (patch) | |
tree | 3099ab63bcc57380a5533788b2a54c6e3ac68b32 | |
parent | c42335fffbf5a786972097d0f62a2ed2d6b0856e (diff) |
import more sources from GSM/3GPP spec
-rw-r--r-- | src/a53f.c | 124 | ||||
-rw-r--r-- | src/a53f.h | 8 | ||||
-rw-r--r-- | src/kasumi.c | 2 | ||||
-rw-r--r-- | src/kasumi.h | 22 | ||||
-rw-r--r-- | src/kgcore.c | 79 |
5 files changed, 230 insertions, 5 deletions
diff --git a/src/a53f.c b/src/a53f.c new file mode 100644 index 0000000..2932d6d --- /dev/null +++ b/src/a53f.c @@ -0,0 +1,124 @@ +/*--------------------------------------------------------- + * A5/3 + *--------------------------------------------------------- + * + * A sample implementation of A5/3, the functions of the + * A5/3 algorithm set. + * + * 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. + * + * Version 0.1 13 March 2002 + * + *---------------------------------------------------------*/ +#include "kasumi.h" +#include <stdlib.h> +void KGcore( u8 ca, u8 cb, u32 cc, u8 cd, u8 *ck, u8 *co, int cl ); + +/*--------------------------------------------------------- + * BuildKey() + * The KGcore() function expects a 128-bit key. This + * function builds that key from shorter length keys. + *---------------------------------------------------------*/ +static u8 *BuildKey( u8 *k, int len ) +{ + static u8 ck[16]; /* Where the key is built */ + int i, n, sf; + u8 mask[]={0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F,0xFF}; + i = (len+7)/8; /* Round to nearest byte */ + if (i > 16 ) + i = 16; /* limit to 128 bits */ + for( n=0; n<i; ++n ) /* copy over the key */ + ck[n] = k[n]; + sf = len%8; /* Any odd key length? */ + /* If the key is less than 128-bits we need to replicate * + * it as many times as is necessary to fill the key. */ + if( len < 128 ) + { + n = 0; + if( sf ) /* Doesn't align to byte boundaries */ + { + ck[i-1] &= mask[sf]; + ck[i-1] += ck[0]<<sf; + while( i<16 ) + { + ck[i] = (ck[n]>>(8-sf)) + (ck[n+1]<<sf); + ++n; + ++i; + } + } + else + while( i<16 ) + ck[i++] = ck[n++]; + } + return( ck ); +} + +/*--------------------------------------------------------- + * The basic A5/3 functions. + * These follow a standard layout: + * - From the supplied key build the 128-bit required by + * KGcore() + * - Call the KGcora() function with te appropriate + * parameters + * - Take the generated Keystream and repackage it + * in the required format. + */ +/*--------------------------------------------------------- + * The standard GSM function + *---------------------------------------------------------*/ +void GSM( u8 *key, int klen, int count, u8 *block1, u8 *block2 ) +{ + u8 *ck, data[32]; + int i; + ck=BuildKey( key, klen ); + KGcore( 0x0F, 0, count, 0, ck, data, 228 ); + for( i=0; i<15; ++i ) + { + block1[i] = data[i]; + block2[i] = (data[i+14]<<2) + (data[i+15]>>6); + } + block1[14] &= 0xC0; + block2[14] &= 0xC0; +} + +/*--------------------------------------------------------- + * The standard GSM ECSD function + *---------------------------------------------------------*/ +void ECSD( u8 *key, int klen, int count, u8 *block1, u8 *block2 ) +{ + u8 *ck, data[87]; + int i; + ck=BuildKey( key, klen ); + KGcore( 0xF0, 0, count, 0, ck, data, 696 ); + for( i=0; i<44; ++i ) + { + block1[i] = data[i]; + block2[i] = (data[i+43]<<4) + (data[i+44]>>4); + } + block1[43] &= 0xF0; + block2[43] &= 0xF0; +} + +/*--------------------------------------------------------- + * The standard GEA3 function + *---------------------------------------------------------*/ +void GEA3( u8 *key, int klen, u32 input, u8 direction, u8 *block, int m ) +{ + u8 *ck, *data; + int i; + data = malloc( m ); + ck=BuildKey( key, klen ); + KGcore( 0xFF, 0, input, direction, ck, data, m*8 ); + for( i=0; i<m; ++i ) + block[i] = data[i]; + free( data ); +} + +/*--------------------------------------------------------- + * E n d o f A 5 3 f . c + *---------------------------------------------------------*/ + diff --git a/src/a53f.h b/src/a53f.h new file mode 100644 index 0000000..14c8a4f --- /dev/null +++ b/src/a53f.h @@ -0,0 +1,8 @@ +#ifndef A53_F_H +#define A53_F_H + +void GSM( u8 *key, int klen, int count, u8 *block1, u8 *block2 ); +void ECSD( u8 *key, int klen, int count, u8 *block1, u8 *block2 ); +void GEA3( u8 *key, int klen, u32 input, u8 direction, u8 *block, int m ); + +#endif diff --git a/src/kasumi.c b/src/kasumi.c index 7f2c43b..56e4224 100644 --- a/src/kasumi.c +++ b/src/kasumi.c @@ -14,7 +14,7 @@ *
*-----------------------------------------------------------------------*/
-#include "Kasumi.h"
+#include "kasumi.h"
/*--------- 16 bit rotate left ------------------------------------------*/
diff --git a/src/kasumi.h b/src/kasumi.h index 0c007d7..1aca3d1 100644 --- a/src/kasumi.h +++ b/src/kasumi.h @@ -1,10 +1,24 @@ +#ifndef KASUMI_H
+#define KASUMI_H
+
+#include <stdint.h>
+
/*---------------------------------------------------------
- * Kasumi.h
+ * Kasumi.h
*---------------------------------------------------------*/
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
-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 );
+
+#endif /* KASUMI_H */
diff --git a/src/kgcore.c b/src/kgcore.c new file mode 100644 index 0000000..f20889f --- /dev/null +++ b/src/kgcore.c @@ -0,0 +1,79 @@ +/*--------------------------------------------------------- + * KGCORE + *--------------------------------------------------------- + * + * A sample implementation of KGCORE, the heart of the + * A5/3 algorithm set. + * + * 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. + * + * Version 0.1 13 March 2002 + * + *---------------------------------------------------------*/ +#include "kasumi.h" +#include <stdio.h> +#include <stdint.h> + +/*--------------------------------------------------------- + * KGcore() + * Given ca, cb, cc, cd, ck, cl generate c0 + *---------------------------------------------------------*/ +void KGcore( u8 ca, u8 cb, u32 cc, u8 cd, u8 *ck, u8 *co, int cl ) +{ + REGISTER64 A; /* the modifier */ + REGISTER64 temp; /* The working register */ + int i, n; + u8 key[16],ModKey[16]; /* Modified key */ + u16 blkcnt; /* The block counter */ + /* Copy over the key */ + for( i=0; i<16; ++i ) + key[i] = ck[i]; + /* 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] = (u8) (cc>>24); + A.b8[1] = (u8) (cc>>16); + A.b8[2] = (u8) (cc>>8); + A.b8[3] = (u8) (cc); + A.b8[4] = (u8) (cb<<3); + A.b8[4] |= (u8) (cd<<2); + A.b8[5] = (u8) ca; + /* Construct the modified key and then "kasumi" A */ + for( n=0; n<16; ++n ) + ModKey[n] = (u8)(ck[n] ^ 0x55); + KeySchedule( ModKey ); + Kasumi( A.b8 ); /* First encryption to create modifier */ + /* Final initialisation steps */ + blkcnt = 0; + KeySchedule( key ); + /* Now run the key stream generator */ + while( cl > 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] ^= blkcnt; + /* 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( cl >= 64 ) + n = 8; + else + n = (cl+7)/8; + /* copy out the keystream */ + for( i=0; i<n; ++i ) + *co++ = temp.b8[i]; + cl -= 64; /* done another 64 bits */ + ++blkcnt; /* increment BLKCNT */ + } +} +/*----------------------------------------------------------- + * e n d o f K G c o r e . c + *-----------------------------------------------------------*/ |