GSM A5 ciphering algorithm

## Files

file | a5.h
| Osmocom GSM A5 ciphering algorithm header.
file | a5.c
| Osmocom GSM A5 ciphering algorithm implementation.

## 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)
| Generate a GSM A5/1 cipher stream. More...
void | osmo_a5_2 (const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
| Generate a GSM A5/1 cipher stream. More...
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...
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...

## Detailed Description

## Function Documentation

## _a5_12_clock()

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

inline static

Compute the next LFSR state.

Parameters

  [in] | r | Current state
  [in] | mask | LFSR mask
  [in] | taps | LFSR taps

Returns
  Next state

References _a5_12_parity().

## _a5_12_majority()

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

inline static

Compute majority bit from 3 taps.

Parameters

  [in] | v1 | LFSR state ANDed with tap-bit
  [in] | v2 | LFSR state ANDed with tap-bit
  [in] | v3 | LFSR state ANDed with tap-bit

Returns
  The majority bit (0 or 1)

## _a5_12_parity()

static uint32_t _a5_12_parity | ( | uint32_t | x | ) |

inline static

Computes parity of a 32-bit word.

Parameters

  [in] | x | 32 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
| ) |  |

inline static

GSM A5/1 Clocking function.

Parameters

  [in] | r | Register state
  [in] | force | Non-zero value disable conditional clocking

Referenced by osmo_a5_1().

## _a5_1_get_output()

static uint8_t _a5_1_get_output | ( | uint32_t | r[] | ) |

inline static

GSM A5/1 Output function.

Parameters

  [in] | r | Register state

Returns
  The A5/1 output function bit

Referenced by osmo_a5_1().

## _a5_2_clock()

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

inline static

GSM A5/2 Clocking function.

Parameters

  [in] | r | Register state
  [in] | force | Non-zero value disable conditional clocking

Referenced by osmo_a5_2().

## _a5_2_get_output()

static uint8_t _a5_2_get_output | ( | uint32_t | r[] | ) |

inline static

GSM A5/2 Output function.

Parameters

  [in] | r | Register state

Returns
  The A5/2 output function bit

Referenced by osmo_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] | key | 8 byte array for the key (as received from the SIM)
  [in] | fn | Frame number
  [out] | dl | Pointer to array of ubits to return Downlink cipher stream
  [out] | ul | Pointer to array of ubits to return Uplink cipher stream
  [in] | fn_correct | true 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().

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] | key | 16 byte array for the key (as received from the SIM)
  [in] | fn | Frame number
  [out] | dl | Pointer to array of ubits to return Downlink cipher stream
  [out] | ul | Pointer to array of ubits to return Uplink cipher stream
  [in] | fn_correct | true 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 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] | n | Which A5/x method to use
  [in] | key | 8 or 16 (for a5/4) byte array for the key (as received from the SIM)
  [in] | fn | Frame number
  [out] | dl | Pointer to array of ubits to return Downlink cipher stream
  [out] | ul | Pointer 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_3(), _a5_4(), osmo_a5_1(), and osmo_a5_2().

Referenced by osmo_a5_fn_count().

## osmo_a5_1()

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

Generate a GSM A5/1 cipher stream.

Parameters

  [in] | key | 8 byte array for the key (as received from the SIM)
  [in] | fn | Frame number
  [out] | dl | Pointer to array of ubits to return Downlink cipher stream
  [out] | ul | Pointer 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(), and osmo_a5_fn_count().

## osmo_a5_2()

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

Generate a GSM A5/1 cipher stream.

Parameters

  [in] | key | 8 byte array for the key (as received from the SIM)
  [in] | fn | Frame number
  [out] | dl | Pointer to array of ubits to return Downlink cipher stream
  [out] | ul | Pointer 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(), and osmo_a5_fn_count().

## osmo_a5_fn_count()

static uint32_t osmo_a5_fn_count | ( | uint32_t | fn | ) |

inline static

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

Parameters

  [in] | fn | The true framenumber

Returns
  22 bit word

References osmo_a5(), osmo_a5_1(), and osmo_a5_2().

Referenced by _a5_4(), osmo_a5_1(), and osmo_a5_2().