libosmogsm UNKNOWN
Osmocom GSM library
Loading...
Searching...
No Matches
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.
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.
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.
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.
static uint32_t _a5_12_parity (uint32_t x)
 Computes parity of a 32-bit word.
static uint32_t _a5_12_majority (uint32_t v1, uint32_t v2, uint32_t v3)
 Compute majority bit from 3 taps.
static uint32_t _a5_12_clock (uint32_t r, uint32_t mask, uint32_t taps)
 Compute the next LFSR state.
static void _a5_1_clock (uint32_t r[], int force)
 GSM A5/1 Clocking function.
static uint8_t _a5_1_get_output (uint32_t r[])
 GSM A5/1 Output function.
void _a5_1 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
 Generate a GSM A5/1 cipher stream.
static void _a5_2_clock (uint32_t r[], int force)
 GSM A5/2 Clocking function.
static uint8_t _a5_2_get_output (uint32_t r[])
 GSM A5/2 Output function.
void _a5_2 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
 Generate a GSM A5/1 cipher stream.

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

Referenced by _a5_1_clock().

◆ A51_R2_CLKBIT

#define A51_R2_CLKBIT   0x000400

Referenced by _a5_1_clock().

◆ A51_R3_CLKBIT

#define A51_R3_CLKBIT   0x000400

Referenced by _a5_1_clock().

◆ A52_R4_CLKBIT0

#define A52_R4_CLKBIT0   0x000400

Referenced by _a5_2_clock().

◆ A52_R4_CLKBIT1

#define A52_R4_CLKBIT1   0x000008

Referenced by _a5_2_clock().

◆ A52_R4_CLKBIT2

#define A52_R4_CLKBIT2   0x000080

Referenced by _a5_2_clock().

◆ A5_R1_LEN

#define A5_R1_LEN   19

◆ A5_R1_MASK

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

Referenced by _a5_1_clock(), and _a5_2_clock().

◆ A5_R1_TAPS

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

Referenced by _a5_1_clock(), and _a5_2_clock().

◆ A5_R2_LEN

#define A5_R2_LEN   22

◆ A5_R2_MASK

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

Referenced by _a5_1_clock(), and _a5_2_clock().

◆ A5_R2_TAPS

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

Referenced by _a5_1_clock(), and _a5_2_clock().

◆ A5_R3_LEN

#define A5_R3_LEN   23

◆ A5_R3_MASK

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

Referenced by _a5_1_clock(), and _a5_2_clock().

◆ A5_R3_TAPS

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

Referenced by _a5_1_clock(), and _a5_2_clock().

◆ A5_R4_LEN

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

◆ A5_R4_MASK

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

Referenced by _a5_2_clock().

◆ A5_R4_TAPS

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

Referenced by _a5_2_clock().

◆ ENOTSUP

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()

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()

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()

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()

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()

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()

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()

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(), and osmo_a5_fn_count().

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(), and ENOTSUP.

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()

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().