libosmogsm 1.9.0.196-9975
Osmocom GSM library
GSM A5 ciphering algorithm

Osmocom GSM ciphering algorithm implementation. More...

Files

file  a5.h
 

Macros

#define ENOTSUP   EINVAL
 
#define A5_R1_LEN   19
 
#define A5_R2_LEN   22
 
#define A5_R3_LEN   23
 
#define A5_R4_LEN   17 /* A5/2 only */
 
#define A5_R1_MASK   ((1<<A5_R1_LEN)-1)
 
#define A5_R2_MASK   ((1<<A5_R2_LEN)-1)
 
#define A5_R3_MASK   ((1<<A5_R3_LEN)-1)
 
#define A5_R4_MASK   ((1<<A5_R4_LEN)-1)
 
#define A5_R1_TAPS   0x072000 /* x^19 + x^18 + x^17 + x^14 + 1 */
 
#define A5_R2_TAPS   0x300000 /* x^22 + x^21 + 1 */
 
#define A5_R3_TAPS   0x700080 /* x^23 + x^22 + x^21 + x^8 + 1 */
 
#define A5_R4_TAPS   0x010800 /* x^17 + x^12 + 1 */
 
#define A51_R1_CLKBIT   0x000100
 
#define A51_R2_CLKBIT   0x000400
 
#define A51_R3_CLKBIT   0x000400
 
#define A52_R4_CLKBIT0   0x000400
 
#define A52_R4_CLKBIT1   0x000008
 
#define A52_R4_CLKBIT2   0x000080
 

Functions

static uint32_t osmo_a5_fn_count (uint32_t fn)
 Converts a frame number into the 22 bit number used in A5/x. More...
 
int osmo_a5 (int n, const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
 Main method to generate a A5/x cipher stream. More...
 
void osmo_a5_1 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul) OSMO_DEPRECATED("Use generic osmo_a5() instead")
 
void osmo_a5_2 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul) OSMO_DEPRECATED("Use generic osmo_a5() instead")
 
void _a5_4 (const uint8_t *ck, uint32_t fn, ubit_t *dl, ubit_t *ul, bool fn_correct)
 Generate a GSM A5/4 cipher stream. More...
 
void _a5_3 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul, bool fn_correct)
 Generate a GSM A5/3 cipher stream. More...
 
static uint32_t _a5_12_parity (uint32_t x)
 Computes parity of a 32-bit word. More...
 
static uint32_t _a5_12_majority (uint32_t v1, uint32_t v2, uint32_t v3)
 Compute majority bit from 3 taps. More...
 
static uint32_t _a5_12_clock (uint32_t r, uint32_t mask, uint32_t taps)
 Compute the next LFSR state. More...
 
static void _a5_1_clock (uint32_t r[], int force)
 GSM A5/1 Clocking function. More...
 
static uint8_t _a5_1_get_output (uint32_t r[])
 GSM A5/1 Output function. More...
 
void _a5_1 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
 Generate a GSM A5/1 cipher stream. More...
 
static void _a5_2_clock (uint32_t r[], int force)
 GSM A5/2 Clocking function. More...
 
static uint8_t _a5_2_get_output (uint32_t r[])
 GSM A5/2 Output function. More...
 
void _a5_2 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
 Generate a GSM A5/1 cipher stream. More...
 

Detailed Description

Osmocom GSM ciphering algorithm implementation.

Full reimplementation of A5/1,2,3,4 (split and threadsafe).

The logic behind the algorithm is taken from "A pedagogical implementation of the GSM A5/1 and A5/2 "voice privacy" encryption algorithms." by Marc Briceno, Ian Goldberg, and David Wagner.

Macro Definition Documentation

◆ A51_R1_CLKBIT

#define A51_R1_CLKBIT   0x000100

◆ A51_R2_CLKBIT

#define A51_R2_CLKBIT   0x000400

◆ A51_R3_CLKBIT

#define A51_R3_CLKBIT   0x000400

◆ A52_R4_CLKBIT0

#define A52_R4_CLKBIT0   0x000400

◆ A52_R4_CLKBIT1

#define A52_R4_CLKBIT1   0x000008

◆ A52_R4_CLKBIT2

#define A52_R4_CLKBIT2   0x000080

◆ A5_R1_LEN

#define A5_R1_LEN   19

◆ A5_R1_MASK

#define A5_R1_MASK   ((1<<A5_R1_LEN)-1)

◆ A5_R1_TAPS

#define A5_R1_TAPS   0x072000 /* x^19 + x^18 + x^17 + x^14 + 1 */

◆ A5_R2_LEN

#define A5_R2_LEN   22

◆ A5_R2_MASK

#define A5_R2_MASK   ((1<<A5_R2_LEN)-1)

◆ A5_R2_TAPS

#define A5_R2_TAPS   0x300000 /* x^22 + x^21 + 1 */

◆ A5_R3_LEN

#define A5_R3_LEN   23

◆ A5_R3_MASK

#define A5_R3_MASK   ((1<<A5_R3_LEN)-1)

◆ A5_R3_TAPS

#define A5_R3_TAPS   0x700080 /* x^23 + x^22 + x^21 + x^8 + 1 */

◆ A5_R4_LEN

#define A5_R4_LEN   17 /* A5/2 only */

◆ A5_R4_MASK

#define A5_R4_MASK   ((1<<A5_R4_LEN)-1)

◆ A5_R4_TAPS

#define A5_R4_TAPS   0x010800 /* x^17 + x^12 + 1 */

◆ ENOTSUP

#define ENOTSUP   EINVAL

Function Documentation

◆ _a5_1()

void _a5_1 ( const uint8_t *  key,
uint32_t  fn,
ubit_t dl,
ubit_t ul 
)

Generate a GSM A5/1 cipher stream.

Parameters
[in]key8 byte array for the key (as received from the SIM)
[in]fnFrame number
[out]dlPointer to array of ubits to return Downlink cipher stream
[out]ulPointer to array of ubits to return Uplink cipher stream

Either (or both) of dl/ul can be NULL if not needed.

References _a5_1_clock(), _a5_1_get_output(), and osmo_a5_fn_count().

Referenced by osmo_a5().

◆ _a5_12_clock()

static uint32_t _a5_12_clock ( uint32_t  r,
uint32_t  mask,
uint32_t  taps 
)
inlinestatic

Compute the next LFSR state.

Parameters
[in]rCurrent state
[in]maskLFSR mask
[in]tapsLFSR taps
Returns
Next state

References _a5_12_parity().

Referenced by _a5_1_clock(), and _a5_2_clock().

◆ _a5_12_majority()

static uint32_t _a5_12_majority ( uint32_t  v1,
uint32_t  v2,
uint32_t  v3 
)
inlinestatic

Compute majority bit from 3 taps.

Parameters
[in]v1LFSR state ANDed with tap-bit
[in]v2LFSR state ANDed with tap-bit
[in]v3LFSR state ANDed with tap-bit
Returns
The majority bit (0 or 1)

Referenced by _a5_1_clock(), and _a5_2_get_output().

◆ _a5_12_parity()

static uint32_t _a5_12_parity ( uint32_t  x)
inlinestatic

Computes parity of a 32-bit word.

Parameters
[in]x32 bit word
Returns
Parity bit (xor of all bits) as 0 or 1

Referenced by _a5_12_clock().

◆ _a5_1_clock()

static void _a5_1_clock ( uint32_t  r[],
int  force 
)
inlinestatic

GSM A5/1 Clocking function.

Parameters
[in]rRegister state
[in]forceNon-zero value disable conditional clocking

References _a5_12_clock(), _a5_12_majority(), A51_R1_CLKBIT, A51_R2_CLKBIT, A51_R3_CLKBIT, A5_R1_MASK, A5_R1_TAPS, A5_R2_MASK, A5_R2_TAPS, A5_R3_MASK, and A5_R3_TAPS.

Referenced by _a5_1().

◆ _a5_1_get_output()

static uint8_t _a5_1_get_output ( uint32_t  r[])
inlinestatic

GSM A5/1 Output function.

Parameters
[in]rRegister state
Returns
The A5/1 output function bit

References A5_R1_LEN, A5_R2_LEN, and A5_R3_LEN.

Referenced by _a5_1().

◆ _a5_2()

void _a5_2 ( const uint8_t *  key,
uint32_t  fn,
ubit_t dl,
ubit_t ul 
)

Generate a GSM A5/1 cipher stream.

Parameters
[in]key8 byte array for the key (as received from the SIM)
[in]fnFrame number
[out]dlPointer to array of ubits to return Downlink cipher stream
[out]ulPointer to array of ubits to return Uplink cipher stream

Either (or both) of dl/ul can be NULL if not needed.

References _a5_2_clock(), _a5_2_get_output(), and osmo_a5_fn_count().

Referenced by osmo_a5().

◆ _a5_2_clock()

static void _a5_2_clock ( uint32_t  r[],
int  force 
)
inlinestatic

GSM A5/2 Clocking function.

Parameters
[in]rRegister state
[in]forceNon-zero value disable conditional clocking

References _a5_12_clock(), A52_R4_CLKBIT0, A52_R4_CLKBIT1, A52_R4_CLKBIT2, A5_R1_MASK, A5_R1_TAPS, A5_R2_MASK, A5_R2_TAPS, A5_R3_MASK, A5_R3_TAPS, A5_R4_MASK, and A5_R4_TAPS.

Referenced by _a5_2().

◆ _a5_2_get_output()

static uint8_t _a5_2_get_output ( uint32_t  r[])
inlinestatic

GSM A5/2 Output function.

Parameters
[in]rRegister state
Returns
The A5/2 output function bit

References _a5_12_majority(), A5_R1_LEN, A5_R2_LEN, and A5_R3_LEN.

Referenced by _a5_2().

◆ _a5_3()

void _a5_3 ( const uint8_t *  key,
uint32_t  fn,
ubit_t dl,
ubit_t ul,
bool  fn_correct 
)

Generate a GSM A5/3 cipher stream.

Parameters
[in]key8 byte array for the key (as received from the SIM)
[in]fnFrame number
[out]dlPointer to array of ubits to return Downlink cipher stream
[out]ulPointer to array of ubits to return Uplink cipher stream
[in]fn_correcttrue if fn is a real GSM frame number and thus requires internal conversion

Either (or both) of dl/ul should be NULL if not needed.

Implementation based on specifications from 3GPP TS 55.216, 3GPP TR 55.919 and ETSI TS 135 202 with slight simplifications (CE hardcoded to 0).

References _a5_4(), and osmo_c4().

Referenced by osmo_a5().

◆ _a5_4()

void _a5_4 ( const uint8_t *  ck,
uint32_t  fn,
ubit_t dl,
ubit_t ul,
bool  fn_correct 
)

Generate a GSM A5/4 cipher stream.

Parameters
[in]key16 byte array for the key (as received from the SIM)
[in]fnFrame number
[out]dlPointer to array of ubits to return Downlink cipher stream
[out]ulPointer to array of ubits to return Uplink cipher stream
[in]fn_correcttrue if fn is a real GSM frame number and thus requires internal conversion

Either (or both) of dl/ul should be NULL if not needed.

Implementation based on specifications from 3GPP TS 55.216, 3GPP TR 55.919 and ETSI TS 135 202 with slight simplifications (CE hardcoded to 0).

References _kasumi_kgcore(), osmo_a5_fn_count(), and osmo_pbit2ubit().

Referenced by _a5_3(), and osmo_a5().

◆ osmo_a5()

int osmo_a5 ( int  n,
const uint8_t *  key,
uint32_t  fn,
ubit_t dl,
ubit_t ul 
)

Main method to generate a A5/x cipher stream.

Parameters
[in]nWhich A5/x method to use
[in]key8 or 16 (for a5/4) byte array for the key (as received from the SIM)
[in]fnFrame number
[out]dlPointer to array of ubits to return Downlink cipher stream
[out]ulPointer to array of ubits to return Uplink cipher stream
Returns
0 for success, -ENOTSUP for invalid cipher selection.

Currently A5/[0-4] are supported. Either (or both) of dl/ul can be NULL if not needed.

References _a5_1(), _a5_2(), _a5_3(), _a5_4(), ENOTSUP, and n.

Referenced by osmo_a5_1(), and osmo_a5_2().

◆ osmo_a5_1()

void osmo_a5_1 ( const uint8_t *  key,
uint32_t  fn,
ubit_t dl,
ubit_t ul 
)

References osmo_a5().

◆ osmo_a5_2()

void osmo_a5_2 ( const uint8_t *  key,
uint32_t  fn,
ubit_t dl,
ubit_t ul 
)

References osmo_a5().

◆ osmo_a5_fn_count()

static uint32_t osmo_a5_fn_count ( uint32_t  fn)
inlinestatic

Converts a frame number into the 22 bit number used in A5/x.

Parameters
[in]fnThe true framenumber
Returns
22 bit word

Referenced by _a5_1(), _a5_2(), and _a5_4().