This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/baseband-devel@lists.osmocom.org/.
Max Suraev Max.Suraev at fairwaves.ru--- src/gsm/a5.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/gsm/a5.c b/src/gsm/a5.c index 93b22c7..5815aa7 100644 --- a/src/gsm/a5.c +++ b/src/gsm/a5.c @@ -39,6 +39,7 @@ #include <string.h> #include <osmocom/core/bits.h> #include <osmocom/gsm/a5.h> +#include <osmocom/gsm/kasumi.h> /*! \brief Main method to generate a A5/x cipher stream * \param[in] n Which A5/x method to use @@ -71,6 +72,10 @@ osmo_a5(int n, const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul) osmo_a5_2(key, fn, dl, ul); break; + case 3: + osmo_a5_3(key, fn, dl, ul); + break; + default: /* a5/[4..7] not supported here/yet */ return -ENOTSUP; @@ -368,4 +373,42 @@ osmo_a5_2(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul) } } +/* ------------------------------------------------------------------------ */ +/* A5/3 */ +/* ------------------------------------------------------------------------ */ + +/*! \brief Generate a GSM A5/3 cipher stream + * \param[in] key 8 byte array for the key (as received from the SIM) + * \param[in] fn Frame number + * \param[out] dl Pointer to array of ubits to return Downlink cipher stream + * \param[out] ul Pointer to array of ubits to return Uplink cipher stream + * + * 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). + */ +void +osmo_a5_3(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul) +{ + /* internal function require 128 bit key so we expand by concatenating supplied 64 bit key */ + uint8_t i, ck[16], gamma[32], _key[8]; + memcpy(_key, key, 8); + osmo_revbytes_buf(_key, 8); /* reverse key byte order to match the way it's stored in SIM */ + memcpy(ck, _key, 8); + memcpy(ck + 8, _key, 8); + + uint32_t fn_count = osmo_a5_fn_count(fn); /* Frame count load */ + if (dl) { + kgcore(0xF, 0, fn_count, 0, ck, gamma, 114); + osmo_pbit2ubit(dl, gamma, 114); + } + if (ul) { + kgcore(0xF, 0, fn_count, 0, ck, gamma, 228); + uint8_t uplink[15]; + for(i = 0; i < 15; i++) uplink[i] = (gamma[i + 14] << 2) + (gamma[i + 15] >> 6); + osmo_pbit2ubit(ul, uplink, 114); + } +} + /*! @} */ -- 1.7.10.4 --------------000004050908040808070403--