laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/33092 )
Change subject: libosmogsm: Factor out the C2 derivation function ......................................................................
libosmogsm: Factor out the C2 derivation function
3GPP specifies the C2 derivation function (generating GSM SRES from UMTS XRES) independent of the MILENAGE algorithm. So instead of open-coding it in milenage.c:gsm_milenage(), let's create a separate public function osmo_auth_c2() similar to the already-existing osmo_auth_c3() function.
gsm_milenage() can then simply use that function.
Change-Id: I0e7cd55f5578f891cb6cc1b0442920ba5beddae4 --- M include/osmocom/crypt/auth.h M src/gsm/auth_core.c M src/gsm/libosmogsm.map M src/gsm/milenage/milenage.c 4 files changed, 47 insertions(+), 7 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/92/33092/1
diff --git a/include/osmocom/crypt/auth.h b/include/osmocom/crypt/auth.h index 2f8804b..a42ad7a 100644 --- a/include/osmocom/crypt/auth.h +++ b/include/osmocom/crypt/auth.h @@ -142,5 +142,6 @@ enum osmo_auth_algo osmo_auth_alg_parse(const char *name);
void osmo_auth_c3(uint8_t kc[], const uint8_t ck[], const uint8_t ik[]); +void osmo_auth_c2(uint8_t sres[4], const uint8_t *res, size_t res_len, uint8_t sres_deriv_func);
/* @} */ diff --git a/src/gsm/auth_core.c b/src/gsm/auth_core.c index 1fa1d79..e99f71d 100644 --- a/src/gsm/auth_core.c +++ b/src/gsm/auth_core.c @@ -343,4 +343,32 @@ kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8]; }
+/*! Derive GSM SRES from UMTS [X]RES (auth function c2 from 3GPP TS 33.103 Section 6.8.1.2 + * \param[out] sres GSM SRES value, 4 byte target buffer + * \param[in] res UMTS XRES, 4..16 bytes input buffer + * \param[in] res_len length of res parameter (in bytes) + * \param[in] SRES derivation function (1 or 2, see 3GPP TS 55.205 Section 4 + */ +void osmo_auth_c2(uint8_t sres[4], const uint8_t *res, size_t res_len, uint8_t sres_deriv_func) +{ + uint8_t xres[16]; + + OSMO_ASSERT(sres_deriv_func == 1 || sres_deriv_func == 2); + + memcpy(xres, res, res_len); + + /* zero-pad the end, if XRES is < 16 bytes */ + if (res_len < sizeof(xres)) + memset(xres+res_len, 0, sizeof(xres)-res_len); + + if (sres_deriv_func == 1) { + /* SRES derivation function #1 */ + for (unsigned int i = 0; i < 4; i++) + sres[i] = xres[i] ^ xres[4+i] ^ xres[8+i] ^ xres[12+i]; + } else { + /* SRES derivation function #2 */ + memcpy(sres, xres, 4); + } +} + /*! @} */ diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 8de3b54..dc7663e 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -561,6 +561,7 @@ osmo_auth_load; osmo_auth_register; osmo_auth_supported; +osmo_auth_c2; osmo_auth_c3; osmo_sub_auth_type_names;
diff --git a/src/gsm/milenage/milenage.c b/src/gsm/milenage/milenage.c index 3c14ab9..ba9ab33 100644 --- a/src/gsm/milenage/milenage.c +++ b/src/gsm/milenage/milenage.c @@ -244,19 +244,13 @@ int gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc) { u8 res[8], ck[16], ik[16]; - int i;
if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL)) return -1;
osmo_auth_c3(kc, ck, ik); + osmo_auth_c2(sres, res, sizeof(res), 1);
-#ifdef GSM_MILENAGE_ALT_SRES - os_memcpy(sres, res, 4); -#else /* GSM_MILENAGE_ALT_SRES */ - for (i = 0; i < 4; i++) - sres[i] = res[i] ^ res[i + 4]; -#endif /* GSM_MILENAGE_ALT_SRES */ return 0; }