Ejemplo n.º 1
0
 def make_2g_vector(self, IMSI, RAND=None):
     """
     return a 2G authentication vector "triplet":
     RAND [16 bytes], RES [4 bytes], Kc [8 bytes]
     or None if the IMSI is not defined in the db or ALG is invalid
     
     RAND can be passed as argument
     """
     # lookup db for authentication Key and algorithm id for IMSI
     try:
         K_ALG_SQN_OP = self.db[IMSI]
     except KeyError:
         self._log('WNG', '[make_2g_vector] IMSI %s not present in AuC.db' % IMSI)
         return None
     if len(K_ALG_SQN_OP) == 4:
         K, ALG, SQN, OP = K_ALG_SQN_OP
     else:
         K, ALG, SQN = K_ALG_SQN_OP
         OP = None
     #
     if not RAND:
         RAND = genrand(16)
     #
     if ALG == 0:
         # Milenage, adapted to 2G
         if OP is not None:
             XRES, CK, IK, AK = self.Milenage.f2345(RAND, K, OP)
         else:
             XRES, CK, IK, AK = self.Milenage.f2345(RAND, K)
         RES, Kc = conv_102_C2(XRES), conv_102_C3(CK, IK)
     elif ALG == 4:
         # TUAK, adapted to 2G
         if OP is not None:
             # which is actually TOP, for TUAK
             XRES, CK, IK, AK = self.TUAK.f2345(RAND, K, OP)
         else:
             XRES, CK, IK, AK = self.TUAK.f2345(RAND, K)
         RES, Kc = conv_102_C2(XRES), conv_102_C3(CK, IK)
     else:
         # COMP128
         if ALG == 1:
             RES, Kc = comp128v1(K, RAND)
         elif ALG == 2:
             RES, Kc = comp128v2(K, RAND)
         elif ALG == 3:
             RES, Kc = comp128v3(K, RAND)
         else:
             # invalid ALG
             return None
     #
     # return auth vector
     self._log('DBG', '[make_2g_vector] IMSI %s: RAND %s, RES %s, Kc %s'\
               % (IMSI, hexlify(RAND).decode('ascii'), hexlify(RES).decode('ascii'), 
                  hexlify(Kc).decode('ascii')))
     return RAND, RES, Kc
Ejemplo n.º 2
0
    def make_3g_vector(self, IMSI, AMF=b'\0\0', RAND=None):
        '''
        return a 3G authentication vector "quintuplet":
        RAND [16 bytes], XRES [8 bytes], AUTN [16 bytes], CK [16 bytes], IK [16 bytes]
        or None if the IMSI is not defined in the db or does not support Milenage
        
        RAND can be passed as argument
        '''
        # lookup db for authentication Key and counter for IMSI
        try:
            K_ALG2_SQN_OP = self.db[IMSI]
        except:
            self._log('WNG',
                      '[make_3g_vector] IMSI %s not present in AuC.db' % IMSI)
            return None
        #
        K, ALG2, SQN, OP = K_ALG2_SQN_OP
        #
        if SQN == -1:
            # Milenage not supported
            self._log(
                'WNG',
                '[make_3g_vector] IMSI %s does not support Milenage' % IMSI)
            return None
        #
        # increment SQN counter in the db
        K_ALG2_SQN_OP[2] += 1
        self._save_required = True

        # pack SQN from integer to a 48-bit buffer
        SQNb = b'\0\0' + pack('>I', SQN)

        # generate challenge if necessary
        if RAND is None:
            RAND = genrand(16)

        # compute Milenage functions
        if OP is not None:
            XRES, CK, IK, AK = self.Milenage.f2345(K, RAND, OP)
            MAC_A = self.Milenage.f1(K, RAND, SQNb, AMF, OP)
            AUTN = xor_buf(SQNb, AK) + AMF + MAC_A
        else:
            XRES, CK, IK, AK = self.Milenage.f2345(K, RAND)
            MAC_A = self.Milenage.f1(K, RAND, SQNb, AMF)
            AUTN = xor_buf(SQNb, AK) + AMF + MAC_A

        # return auth vector
        self._log('DBG', '[make_3g_vector] IMSI %s, SQN %i: RAND %s, XRES %s, AUTN %s, CK %s, IK %s'\
                  % (IMSI, SQN, hexlify(RAND).decode('ascii'), hexlify(XRES).decode('ascii'),
                     hexlify(AUTN).decode('ascii'), hexlify(CK).decode('ascii'),
                     hexlify(IK).decode('ascii')))
        return RAND, XRES, AUTN, CK, IK
Ejemplo n.º 3
0
 def make_2g_vector(self, IMSI, RAND=None):
     """
     return a 2G authentication vector "triplet":
     RAND [16 bytes], RES [4 bytes], Kc [8 bytes]
     or None if the IMSI is not defined in the db or ALG2 is invalid
     
     RAND can be passed as argument
     """
     # lookup db for authentication Key and algorithm id for IMSI
     try:
         K, ALG2, SQN, OP = self.db[IMSI]
     except KeyError:
         self._log('WNG',
                   '[make_2g_vector] IMSI %s not present in AuC.db' % IMSI)
         return None
     #
     if not RAND:
         RAND = genrand(16)
     #
     if ALG2 == 0:
         if OP is not None:
             XRES, CK, IK, AK = self.Milenage.f2345(RAND, K, OP)
         else:
             XRES, CK, IK, AK = self.Milenage.f2345(RAND, K)
         RES, Ck = conv_C2(XRES), conv_C3(CK, IK)
     else:
         if ALG2 == 1:
             RES, Ck = comp128v1(K, RAND)
         elif ALG2 == 2:
             RES, Ck = comp128v2(K, RAND)
         elif ALG2 == 3:
             RES, Ck = comp128v3(K, RAND)
         else:
             return None
     #
     # return auth vector
     self._log('DBG', '[make_2g_vector] IMSI %s: RAND %s, RES %s, Kc %s'\
               % (IMSI, hexlify(RAND).decode('ascii'), hexlify(RES).decode('ascii'),
                  hexlify(Kc).decode('ascii')))
     return RAND, RES, Kc
Ejemplo n.º 4
0
    def make_4g_vector(self, IMSI, SN_ID, AMF=b'\x80\x00', RAND=None):
        """
        return a 4G authentication vector "quadruplet":
        RAND [16 bytes], XRES [8 bytes], AUTN [16 bytes], KASME [32 bytes]
        or None if the IMSI is not defined in the db or does not support Milenage
        or SN_ID is invalid or not allowed
        
        SN_ID is the serving network identity, bcd-encoded buffer
        RAND can be passed as argument
        """
        if not isinstance(SN_ID, bytes_types) or len(SN_ID) != 3:
            self._log(
                'WNG', '[make_4g_vector] SN_ID invalid, %s' %
                hexlify(SN_ID).decode('ascii'))
            return None
        elif self.PLMN_FILTER is not None and SN_ID not in self.PLMN_FILTER:
            self._log(
                'WNG', '[make_4g_vector] SN_ID not allowed, %s' %
                hexlify(SN_ID).decode('ascii'))
            return None
        #
        # lookup db for authentication Key and counter for IMSI
        try:
            K_ALG2_SQN_OP = self.db[IMSI]
        except:
            self._log('WNG',
                      '[make_4g_vector] IMSI %s not present in AuC.db' % IMSI)
            return None
        #
        K, ALG2, SQN, OP = K_ALG2_SQN_OP
        #
        if SQN == -1:
            # Milenage not supported
            self._log(
                'WNG',
                '[make_4g_vector] IMSI %s does not support Milenage' % IMSI)
            return None
        #
        # increment SQN counter in the db
        K_ALG2_SQN_OP[2] += 1
        self._save_required = True

        # pack SQN from integer to a 48-bit buffer
        SQNb = b'\0\0' + pack('>I', SQN)
        #
        # generate challenge
        if RAND is None:
            RAND = genrand(16)

        # compute Milenage functions
        if OP is not None:
            XRES, CK, IK, AK = self.Milenage.f2345(K, RAND, OP)
            MAC_A = self.Milenage.f1(K, RAND, SQNb, AMF, OP)
            SQN_X_AK = xor_buf(SQNb, AK)
            AUTN = SQN_X_AK + AMF + MAC_A
        else:
            XRES, CK, IK, AK = self.Milenage.f2345(K, RAND)
            MAC_A = self.Milenage.f1(K, RAND, SQNb, AMF)
            SQN_X_AK = xor_buf(SQNb, AK)
            AUTN = SQN_X_AK + AMF + MAC_A

        # convert to LTE master key
        KASME = conv_A2(CK, IK, SN_ID, SQN_X_AK)

        # return auth vector
        self._log('DBG', '[make_4g_vector] IMSI %s, SQN %i, SN_ID %s: RAND %s, XRES %s, AUTN %s, KASME %s'\
                  % (IMSI, SQN, hexlify(SN_ID).decode('ascii'), hexlify(RAND).decode('ascii'),
                     hexlify(XRES).decode('ascii'), hexlify(AUTN).decode('ascii'),
                     hexlify(KASME).decode('ascii')))
        return RAND, XRES, AUTN, KASME
Ejemplo n.º 5
0
 def make_5g_vector(self, IMSI, SNName, AMF=b'\x80\x00', RAND=None):
     """
     return a 5G authentication vector "quadruplet":
     RAND [16 bytes], XRES* [8 bytes], AUTN [16 bytes], KAUSF [32 bytes]
     or None if the IMSI is not defined in the db or does not support Milenage or TUAK
     or SNName is invalid or not allowed
     
     SNName is the serving network name, ascii-encoded bytes buffer
     RAND can be passed as argument
     """
     if not isinstance(SNName, bytes_types) or not 32 <= len(SNName) <= 255:
         self._log('WNG', '[make_5g_vector] SNName invalid, %s' % SNName.decode('ascii'))
         return None
     elif self.PLMN_FILTER is not None:
         # extract MCC, MNC from SNName (e.g. "5G:mnc012.mcc345.3gppnetwork.org")
         snname_parts = SNName.split(':')[1].split('.')
         mcc, mnc =  snname_parts[1][3:], snname_parts[0][3:]
         if mcc + mnc not in self.PLMN_FILTER:
             self._log('WNG', '[make_5g_vector] SNName not allowed, %s' % SNName.decode('ascii'))
             return None
     #
     # lookup db for authentication Key and counter for IMSI
     try:
         K_ALG_SQN_OP = self.db[IMSI]
     except Exception:
         self._log('WNG', '[make_5g_vector] IMSI %s not present in AuC.db' % IMSI)
         return None
     if len(K_ALG_SQN_OP) == 4:
         K, ALG, SQN, OP = K_ALG_SQN_OP
     else:
         K, ALG, SQN = K_ALG_SQN_OP
         OP = None
     #
     if ALG not in (0, 4):
         # Milenage / TUAK not supported
         self._log('WNG', '[make_4g_vector] IMSI %s does not support Milenage or TUAK' % IMSI)
         return None
     #
     # increment SQN counter in the db
     if SQN >= 0:
         K_ALG_SQN_OP[2] += 1
         self._save_required = True
     #
     # pack SQN from integer to a 48-bit buffer
     SQNb = pack('>Q', SQN)[2:]
     #
     # generate challenge
     if RAND is None:
         RAND = genrand(16)
     #
     if ALG == 0:
         # compute Milenage functions
         if OP is not None:
             XRES, CK, IK, AK = self.Milenage.f2345( K, RAND, OP )
             MAC_A            = self.Milenage.f1( K, RAND, SQNb, AMF, OP )
         else:
             XRES, CK, IK, AK = self.Milenage.f2345( K, RAND )
             MAC_A            = self.Milenage.f1( K, RAND, SQNb, AMF )
     else:
         # ALG == 4, compute TUAK functions
         if OP is not None:
             XRES, CK, IK, AK = self.TUAK.f2345( K, RAND, OP )
             MAC_A            = self.TUAK.f1( K, RAND, SQNb, AMF, OP )
         else:
             XRES, CK, IK, AK = self.TUAK.f2345( K, RAND )
             MAC_A            = self.TUAK.f1( K, RAND, SQNb, AMF )
     #
     SQN_X_AK = xor_buf( SQNb, AK )
     AUTN = SQN_X_AK + AMF + MAC_A
     # convert to AUSF master key
     KAUSF = conv_501_A2(CK, IK, SNName, SQN_X_AK)
     XRESstar = conv_501_A4(CK, IK, SNName, RAND, XRES)
     #
     # return auth vector
     self._log('DBG', '[make_4g_vector] IMSI %s, SQN %i, SNName %s: RAND %s, XRES* %s, AUTN %s, KASME %s'\
               % (IMSI, SQN, hexlify(SNName).decode('ascii'), hexlify(RAND).decode('ascii'), 
                  hexlify(XRESstar).decode('ascii'), hexlify(AUTN).decode('ascii'), 
                  hexlify(KAUSF).decode('ascii')))
     return RAND, XRESstar, AUTN, KAUSF