def milenage_generate(opc: bytes, amf: bytes, k: bytes, sqn: bytes, rand: bytes) -> Dict[str, bytes]: """Generate an MILENAGE Authentication Tuple.""" m = Milenage(None) m.set_opc(opc) mac_a = m.f1(k, rand, sqn, amf) res, ck, ik, ak = m.f2345(k, rand) # AUTN = (SQN ^ AK) || AMF || MAC sqn_ak = xor_buf(sqn, ak) autn = b''.join([sqn_ak, amf, mac_a]) return {'res': res, 'ck': ck, 'ik': ik, 'autn': autn}
def milenage_auts(opc: bytes, k: bytes, rand: bytes, auts: bytes) -> Optional[bytes]: """Validate AUTS. If successful, returns SQN_MS""" amf = b'\x00\x00' # TS 33.102 Section 6.3.3 m = Milenage(None) m.set_opc(opc) ak = m.f5star(k, rand) sqn_ak = auts[:6] sqn = xor_buf(sqn_ak, ak[:6]) mac_s = m.f1star(k, rand, sqn, amf) if mac_s == auts[6:14]: return sqn else: return False