libosmogsm 1.9.0.196-9975
Osmocom GSM library
comp128.c File Reference

COMP128 v1; common/old GSM Authentication Algorithm (A3/A8). More...

#include <string.h>
#include <stdint.h>

Functions

static void _comp128_compression_round (uint8_t *x, int n, const uint8_t *tbl)
 
static void _comp128_compression (uint8_t *x)
 
static void _comp128_bitsfrombytes (uint8_t *x, uint8_t *bits)
 
static void _comp128_permutation (uint8_t *x, uint8_t *bits)
 
void comp128v1 (const uint8_t *ki, const uint8_t *rand, uint8_t *sres, uint8_t *kc)
 Perform COMP128v1 algorithm. More...
 
void comp128 (const uint8_t *ki, const uint8_t *rand, uint8_t *sres, uint8_t *kc)
 Perform COMP128v1 algorithm. More...
 

Variables

static const uint8_t table_0 [512]
 
static const uint8_t table_1 [256]
 
static const uint8_t table_2 [128]
 
static const uint8_t table_3 [64]
 
static const uint8_t table_4 [32]
 
static const uint8_t * _comp128_table [5] = { table_0, table_1, table_2, table_3, table_4 }
 

Detailed Description

COMP128 v1; common/old GSM Authentication Algorithm (A3/A8).

This code is inspired by original code from : Marc Briceno marc@.nosp@m.scar.nosp@m.d.org, Ian Goldberg iang@.nosp@m.cs.b.nosp@m.erkel.nosp@m.ey.e.nosp@m.du, and David Wagner daw@c.nosp@m.s.be.nosp@m.rkele.nosp@m.y.ed.nosp@m.u

But it has been fully rewritten from various PDFs found online describing the algorithm because the licence of the code referenced above was unclear. A comment snippet from the original code is included below, it describes where the doc came from and how the algorithm was reverse engineered.

This code derived from a leaked document from the GSM standards. Some missing pieces were filled in by reverse-engineering a working SIM. We have verified that this is the correct COMP128 algorithm.

The first page of the document identifies it as

    _Technical Information: GSM System Security Study_.
    10-1617-01, 10th June 1988.

The bottom of the title page is marked

    Racal Research Ltd.
    Worton Drive, Worton Grange Industrial Estate,
    Reading, Berks. RG2 0SB, England.
    Telephone: Reading (0734) 868601   Telex: 847152

The relevant bits are in Part I, Section 20 (pages 66–67). Enjoy!

Note: There are three typos in the spec (discovered by reverse-engineering).

  • First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read "z = (2 * x[m] + x[n]) mod 2^(9-j)".
  • Second, the "k" loop in the "Form bits from bytes" section is severely botched: the k index should run only from 0 to 3, and clearly the range on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8, to be consistent with the subsequent section).
  • Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as claimed in the document. (And the document doesn't specify how Kc is derived, but that was also easily discovered with reverse engineering.) All of these typos have been corrected in the following code.