def f4(self, rand=None): """Calculate integrity key. rand - str or int, if None, use the stored value return IK as 16B str""" self._check_rand(rand) arg = rot(self.temp ^ self.OPc, self.R[4]) ^ self.C[4] out4 = s2int(self.Ek.encrypt(int2s(arg, 128))) ^ self.OPc return int2s(out4, 128)
def f3(self, rand=None): """Calculate confidentiality key. rand - str or int, if None, use the stored value return CK as 16B str""" self._check_rand(rand) arg = rot(self.temp ^ self.OPc, self.R[3]) ^ self.C[3] out3 = s2int(self.Ek.encrypt(int2s(arg, 128))) ^ self.OPc return int2s(out3, 128)
def f2(self, rand=None): """Calculate authentication response. rand - str or int, if None, use the stored value return RES as 8B str""" self._check_rand(rand) arg = rot(self.temp ^ self.OPc, self.R[2]) ^ self.C[2] out2 = s2int(self.Ek.encrypt(int2s(arg, 128))) ^ self.OPc out2s = int2s(out2, 128) return out2s[8:]
def _check_rand(self, rand): """Check provided rand and calculate temp. Use stored values if None""" if self.rand is None or rand is not None: self.rand = s2int(randomBytes(16)) if rand is None else \ self._check_int(rand, "RAND", 128) temp = self.Ek.encrypt(int2s(self.rand ^ self.OPc, 128)) self.temp = s2int(temp)
def _check_str(self, param, label, bitlen=128): """Convert param to int and check its value""" if isinstance(param, int) or isinstance(param, long): param = int2s(param, bitlen) assert isinstance(param, str) and 8*len(param) == bitlen, \ "Wrong " + label return param
def f5s(self, rand=None): """Calculate anonimity keys for resync. rand - str or int, if None, use the stored value return AK as 48b integer""" self._check_rand(rand) arg = rot(self.temp ^ self.OPc, self.R[5]) ^ self.C[5] out5 = s2int(self.Ek.encrypt(int2s(arg, 128))) ^ self.OPc return out5 >> 80
def f5(self, rand=None): """Calculate anonimity keys for authentication. rand - str or int, if None, use the stored value return AK as 48b integer""" self._check_rand(rand) arg = rot(self.temp ^ self.OPc, self.R[2]) ^ self.C[2] out2 = s2int(self.Ek.encrypt(int2s(arg, 128))) ^ self.OPc return out2 >> 80
def f1(self, rand=None, sqn=None, amf=None): """Calculate network & resync authentication code. rand, sqn, amf - str or int, if None, use the stored value return (MAC-A, MAC-S) as two 8B str""" self._check_rand(rand) if sqn is None: assert self.sqn is not None, "SQN not stored" else: self.sqn = self._check_int(sqn, "SQN", 48) if amf is None: assert self.amf is not None, "AMF not stored" else: self.amf = self._check_int(amf, "AMF", 16) in1 = (self.sqn << 16) | self.amf in1 |= in1 << 64 arg = self.temp ^ rot(in1 ^ self.OPc, self.R[1]) ^ self.C[1] out1 = s2int(self.Ek.encrypt(int2s(arg, 128))) ^ self.OPc out1s = int2s(out1, 128) return out1s[:8], out1s[8:]
def bytestr(self): """ Get byte string representation of TLV, depending on type. """ # BER, COMPREH: length as in ISO 8825-1 aka X.690 # COMPACT: length 00-FE or FF xx yy tags = int2s(self.tag) l = len(self.value) if self.typ == TLV.COMPACT: if l < 0xFF: lens = chr(l) else: lens = '\xFF' + pack(">H", l) else: lens = derLen(l) return tags + lens + self.value
def bytestr(self): """ Get byte string representation of TLV, depending on type. """ # BER, COMPREH: length as in ISO 8825-1 aka X.690 # COMPACT: length 00-FE or FF xx yy tags = int2s(self.tag) l = len(self.value) if self.typ == TLV.COMPACT: if l < 0xFF: lens = chr(l) else: lens = "\xFF" + pack(">H", l) else: lens = derLen(l) return tags + lens + self.value