P1sec / pycrate

A Python library to ease the development of encoders and decoders for various protocols and file formats; contains ASN.1 and CSN.1 compilers.
GNU Lesser General Public License v2.1
380 stars 130 forks source link

MAC verification of 5GMMRegistrationRequest fails with TypeError: can't concat list to bytes #220

Closed dziugas-wg2 closed 1 year ago

dziugas-wg2 commented 1 year ago

mac_verify() function of the FGMMSecProtNASMessage class verifies the message authentication code of byte stream that is a concatenation of the NAS sequence number and the NAS payload. Bytes for the latter is obtained by calling a get_val() function of the NAS payload (that in case of protected message will by the self[3]).

https://github.com/P1sec/pycrate/blob/bedeaf30ad5762b3e67b5c66a08d3840b5ad8b3b/pycrate_mobile/TS24501_FGMM.py#L758

While this works for most of the NAS messages, it does result in a TypeError: can't concat list to bytes exception for the 5GMMRegistrationRequest NAS message since in this case get_val() returns not bytes, but a list of list that contains representation of each NAS IE in the form of integers or bytes. One possible fix that seems to work is to use to_bytes() instead of get_val() to get the bytes of the NAS payload.

Below are the contents of different variables when having a breakpoint set inside FGMMSecProtNASMessage::mac_verify():

>>> self.to_bytes()
b'~\x01\xc5/\x18&\x1a~\x00A\t\x00\x0b\xf2\x00\xf1\x10\x01\x00A^\xf0\x820.\x04\xf0p\xf0pq\x008~\x00A\t\x00\x0b\xf2\x00\xf1\x10\x01\x00A^\xf0\x820\x10\x01\x07.\x04\xf0p\xf0p/\x02\x01\x01R\x00\xf1\x10\x00\x00\x01\x17\x07\xf0p\xc0@\x19\x80\xb0\x18\x01\x00t\x00\x00\x90S\x01\x01'

>>> self
<5GMMSecProtNASMessage : <5GMMHeaderSec : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 1 (Integrity protected)>><MAC : 0xc52f1826><Seqn : 26><5GMMRegistrationRequest : <5GMMHeader : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 0 (No security)><Type : 65 (Registration request)>><NAS_KSI : <NAS_KSI : <TSC : 0 (native security context)><Value : 0>>><5GSRegType : <5GSRegType : <FOR : 1 (Follow-on request pending)><Value : 1 (initial registration)>>><5GSID : <L : 11><5GSID : <ind : 0xf><spare : 0><Type : 2 (5G-GUTI)><PLMN : 00101><AMFRegionID : 1><AMFSetID : 1><AMFPtr : 1><5GTMSI : 0x5ef08230>>><NonCurrentNativeNAS_KSI [transparent] : <T : 12><V : 0>><5GMMCap [transparent] : <T : 16><L : 1><V : 0x00>><UESecCap : <T : 46><L : 4><UESecCap : <5G-EA0 : 1><5G-EA1_128 : 1><5G-EA2_128 : 1><5G-EA3_128 : 1><5G-EA4 : 0><5G-EA5 : 0><5G-EA6 : 0><5G-EA7 : 0><5G-IA0 : 0><5G-IA1_128 : 1><5G-IA2_128 : 1><5G-IA3_128 : 1><5G-IA4 : 0><5G-IA5 : 0><5G-IA6 : 0><5G-IA7 : 0><EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><spare [transparent] : 0x>>><NSSAI [transparent] : <T : 47><L : 2><V : 0x0101>><TAI [transparent] : <T : 82><V : 0x000000000000>><EPSUENetCap [transparent] : <T : 23><L : 2><V : 0x0000>><ULDataStat [transparent] : <T : 64><L : 2><V : 0x0000>><PDUSessStat [transparent] : <T : 80><L : 2><V : 0x0000>><MICOInd [transparent] : <T : 11><V : 0>><UEStatus [transparent] : <T : 43><L : 1><V : 0x00>><AddGUTI [transparent] : <T : 119><L : 11><V : 0xf200000000000000000000>><AllowedPDUSessStat [transparent] : <T : 37><L : 2><V : 0x0000>><UEUsage [transparent] : <T : 24><L : 1><V : 0x00>><5GSDRXParam [transparent] : <T : 81><L : 1><V : 0x00>><EPSNASContainer [transparent] : <T : 112><L : 2><V : 0x0700>><LADNInd [transparent] : <T : 116><L : 0><V : 0x>><PayloadContainerType [transparent] : <T : 8><V : 1 (N1 SM information)>><PayloadContainer [transparent] : <T : 123><L : 1><V : 0x00>><NetSlicingInd [transparent] : <T : 9><V : 0>><5GSUpdateType [transparent] : <T : 83><L : 1><V : 0x00>><MSCm2 [transparent] : <T : 65><L : 3><V : 0x400000>><SuppCodecs [transparent] : <T : 66><L : 3><V : 0x000100>><NASContainer : <T : 113><L : 56><5GMMRegistrationRequest : <5GMMHeader : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 0 (No security)><Type : 65 (Registration request)>><NAS_KSI : <NAS_KSI : <TSC : 0 (native security context)><Value : 0>>><5GSRegType : <5GSRegType : <FOR : 1 (Follow-on request pending)><Value : 1 (initial registration)>>><5GSID : <L : 11><5GSID : <ind : 0xf><spare : 0><Type : 2 (5G-GUTI)><PLMN : 00101><AMFRegionID : 1><AMFSetID : 1><AMFPtr : 1><5GTMSI : 0x5ef08230>>><NonCurrentNativeNAS_KSI [transparent] : <T : 12><V : 0>><5GMMCap : <T : 16><L : 1><5GMMCap : <SGC : 0><5G-HC-CP-CIoT : 0><N3Data : 0><5G-CP-CIoT : 0><RestrictEC : 0><LPP : 1><HOAttach : 1><S1Mode : 1><RACS [transparent] : 0><NSSAA [transparent] : 0><5G-LCS [transparent] : 0><V2XCNPC5 [transparent] : 0><V2XCEPC5 [transparent] : 0><V2X [transparent] : 0><5G-UP-CIoT [transparent] : 0><5GSRVCC [transparent] : 0><spare [transparent] : 0><5G-EHC-CP-CIoT [transparent] : 0><MultipleUP [transparent] : 0><WUSA [transparent] : 0><CAG [transparent] : 0><spare [transparent] : 0x>>><UESecCap : <T : 46><L : 4><UESecCap : <5G-EA0 : 1><5G-EA1_128 : 1><5G-EA2_128 : 1><5G-EA3_128 : 1><5G-EA4 : 0><5G-EA5 : 0><5G-EA6 : 0><5G-EA7 : 0><5G-IA0 : 0><5G-IA1_128 : 1><5G-IA2_128 : 1><5G-IA3_128 : 1><5G-IA4 : 0><5G-IA5 : 0><5G-IA6 : 0><5G-IA7 : 0><EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><spare [transparent] : 0x>>><NSSAI : <T : 47><L : 2><NSSAI : <SNSSAI : <Len : 1><SNSSAI : <SST : 1 (eMBB)><SD [transparent] : 0x><MappedHPLMNSST [transparent] : 0><MappedHPLMNSD [transparent] : 0x>>>>><TAI : <T : 82><5GSTAI : <PLMN : 00101><TAC : 0x000001>>><EPSUENetCap : <T : 23><L : 7><UENetCap : <EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><UEA0 : 1><UEA1 : 1><UEA2 : 0><UEA3 : 0><UEA4 : 0><UEA5 : 0><UEA6 : 0><UEA7 : 0><UCS2 : 0><UIA1 : 1><UIA2 : 0><UIA3 : 0><UIA4 : 0><UIA5 : 0><UIA6 : 0><UIA7 : 0><ProSe_dd : 0><ProSe : 0><H245_ASH : 0><ACC_CSFB : 1><LPP : 1><LCS : 0><X1_SRVCC : 0><NF : 1><ePCO : 1><HC_CP_CIoT : 0><ERw_oPDN : 0><S1U_data : 0><UP_CIoT : 0><CP_CIoT : 0><ProSe_relay : 0><ProSe_dc : 0><spare : 1><spare : 0><spare : 1><spare : 1><spare : 0><spare : 0><spare : 0><MultiDRB : 0><spare [transparent] : 0x>>><ULDataStat [transparent] : <T : 64><L : 2><V : 0x0000>><PDUSessStat [transparent] : <T : 80><L : 2><V : 0x0000>><MICOInd [transparent] : <T : 11><V : 0>><UEStatus [transparent] : <T : 43><L : 1><V : 0x00>><AddGUTI [transparent] : <T : 119><L : 11><V : 0xf200000000000000000000>><AllowedPDUSessStat [transparent] : <T : 37><L : 2><V : 0x0000>><UEUsage : <T : 24><L : 1><UEUsage : <spare : 0x00><Value : 0 (voice centric)>>><5GSDRXParam [transparent] : <T : 81><L : 1><V : 0x00>><EPSNASContainer [transparent] : <T : 112><L : 2><V : 0x0700>><LADNInd : <T : 116><L : 0><LADNInd : >><PayloadContainerType [transparent] : <T : 8><V : 1 (N1 SM information)>><PayloadContainer [transparent] : <T : 123><L : 1><V : 0x00>><NetSlicingInd : <T : 9><NetSlicingInd : <spare : 0><DCNI : 0 (requested NSSAI not created from default configured NSSAI)><NSSCI : 0 (network slicing subscription not changed)>>><5GSUpdateType : <T : 83><L : 1><5GSUpdateType : <spare : 0><EPS-PNB-CIoT : 0><5GS-PNB-CIoT : 0><NG-RAN-RCU : 0><SMSRequested : 1>>><MSCm2 [transparent] : <T : 65><L : 3><V : 0x400000>><SuppCodecs [transparent] : <T : 66><L : 3><V : 0x000100>><NASContainer [transparent] : <T : 113><L : 2><V : 0x0000>><EPSBearerCtxtStat [transparent] : <T : 96><L : 2><V : 0x0000>><ExtDRXParam [transparent] : <T : 110><L : 1><V : 0x00>><T3324 [transparent] : <T : 106><L : 1><V : 0x00>><UERadioCapID [transparent] : <T : 103><L : 1><V : 0x00>><MappedNSSAI [transparent] : <T : 53><L : 1><V : 0x00>><AddInfoReq [transparent] : <T : 72><L : 1><V : 0x00>><WUSAssistInfo [transparent] : <T : 26><L : 1><V : 0x00>><N5GCInd [transparent] : <T : 10>><NBN1ModeDRXParam [transparent] : <T : 48><L : 1><V : 0x00>>>><EPSBearerCtxtStat [transparent] : <T : 96><L : 2><V : 0x0000>><ExtDRXParam [transparent] : <T : 110><L : 1><V : 0x00>><T3324 [transparent] : <T : 106><L : 1><V : 0x00>><UERadioCapID [transparent] : <T : 103><L : 1><V : 0x00>><MappedNSSAI [transparent] : <T : 53><L : 1><V : 0x00>><AddInfoReq [transparent] : <T : 72><L : 1><V : 0x00>><WUSAssistInfo [transparent] : <T : 26><L : 1><V : 0x00>><N5GCInd [transparent] : <T : 10>><NBN1ModeDRXParam [transparent] : <T : 48><L : 1><V : 0x00>>>>

>>> seqnoff
0

>>> bearer
1

>>> dir
0

>>> self[2]
<Seqn : 26>

>>> self[2].to_bytes()
b'\x1a'

>>> self[3]
<5GMMRegistrationRequest : <5GMMHeader : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 0 (No security)><Type : 65 (Registration request)>><NAS_KSI : <NAS_KSI : <TSC : 0 (native security context)><Value : 0>>><5GSRegType : <5GSRegType : <FOR : 1 (Follow-on request pending)><Value : 1 (initial registration)>>><5GSID : <L : 11><5GSID : <ind : 0xf><spare : 0><Type : 2 (5G-GUTI)><PLMN : 00101><AMFRegionID : 1><AMFSetID : 1><AMFPtr : 1><5GTMSI : 0x5ef08230>>><NonCurrentNativeNAS_KSI [transparent] : <T : 12><V : 0>><5GMMCap [transparent] : <T : 16><L : 1><V : 0x00>><UESecCap : <T : 46><L : 4><UESecCap : <5G-EA0 : 1><5G-EA1_128 : 1><5G-EA2_128 : 1><5G-EA3_128 : 1><5G-EA4 : 0><5G-EA5 : 0><5G-EA6 : 0><5G-EA7 : 0><5G-IA0 : 0><5G-IA1_128 : 1><5G-IA2_128 : 1><5G-IA3_128 : 1><5G-IA4 : 0><5G-IA5 : 0><5G-IA6 : 0><5G-IA7 : 0><EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><spare [transparent] : 0x>>><NSSAI [transparent] : <T : 47><L : 2><V : 0x0101>><TAI [transparent] : <T : 82><V : 0x000000000000>><EPSUENetCap [transparent] : <T : 23><L : 2><V : 0x0000>><ULDataStat [transparent] : <T : 64><L : 2><V : 0x0000>><PDUSessStat [transparent] : <T : 80><L : 2><V : 0x0000>><MICOInd [transparent] : <T : 11><V : 0>><UEStatus [transparent] : <T : 43><L : 1><V : 0x00>><AddGUTI [transparent] : <T : 119><L : 11><V : 0xf200000000000000000000>><AllowedPDUSessStat [transparent] : <T : 37><L : 2><V : 0x0000>><UEUsage [transparent] : <T : 24><L : 1><V : 0x00>><5GSDRXParam [transparent] : <T : 81><L : 1><V : 0x00>><EPSNASContainer [transparent] : <T : 112><L : 2><V : 0x0700>><LADNInd [transparent] : <T : 116><L : 0><V : 0x>><PayloadContainerType [transparent] : <T : 8><V : 1 (N1 SM information)>><PayloadContainer [transparent] : <T : 123><L : 1><V : 0x00>><NetSlicingInd [transparent] : <T : 9><V : 0>><5GSUpdateType [transparent] : <T : 83><L : 1><V : 0x00>><MSCm2 [transparent] : <T : 65><L : 3><V : 0x400000>><SuppCodecs [transparent] : <T : 66><L : 3><V : 0x000100>><NASContainer : <T : 113><L : 56><5GMMRegistrationRequest : <5GMMHeader : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 0 (No security)><Type : 65 (Registration request)>><NAS_KSI : <NAS_KSI : <TSC : 0 (native security context)><Value : 0>>><5GSRegType : <5GSRegType : <FOR : 1 (Follow-on request pending)><Value : 1 (initial registration)>>><5GSID : <L : 11><5GSID : <ind : 0xf><spare : 0><Type : 2 (5G-GUTI)><PLMN : 00101><AMFRegionID : 1><AMFSetID : 1><AMFPtr : 1><5GTMSI : 0x5ef08230>>><NonCurrentNativeNAS_KSI [transparent] : <T : 12><V : 0>><5GMMCap : <T : 16><L : 1><5GMMCap : <SGC : 0><5G-HC-CP-CIoT : 0><N3Data : 0><5G-CP-CIoT : 0><RestrictEC : 0><LPP : 1><HOAttach : 1><S1Mode : 1><RACS [transparent] : 0><NSSAA [transparent] : 0><5G-LCS [transparent] : 0><V2XCNPC5 [transparent] : 0><V2XCEPC5 [transparent] : 0><V2X [transparent] : 0><5G-UP-CIoT [transparent] : 0><5GSRVCC [transparent] : 0><spare [transparent] : 0><5G-EHC-CP-CIoT [transparent] : 0><MultipleUP [transparent] : 0><WUSA [transparent] : 0><CAG [transparent] : 0><spare [transparent] : 0x>>><UESecCap : <T : 46><L : 4><UESecCap : <5G-EA0 : 1><5G-EA1_128 : 1><5G-EA2_128 : 1><5G-EA3_128 : 1><5G-EA4 : 0><5G-EA5 : 0><5G-EA6 : 0><5G-EA7 : 0><5G-IA0 : 0><5G-IA1_128 : 1><5G-IA2_128 : 1><5G-IA3_128 : 1><5G-IA4 : 0><5G-IA5 : 0><5G-IA6 : 0><5G-IA7 : 0><EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><spare [transparent] : 0x>>><NSSAI : <T : 47><L : 2><NSSAI : <SNSSAI : <Len : 1><SNSSAI : <SST : 1 (eMBB)><SD [transparent] : 0x><MappedHPLMNSST [transparent] : 0><MappedHPLMNSD [transparent] : 0x>>>>><TAI : <T : 82><5GSTAI : <PLMN : 00101><TAC : 0x000001>>><EPSUENetCap : <T : 23><L : 7><UENetCap : <EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><UEA0 : 1><UEA1 : 1><UEA2 : 0><UEA3 : 0><UEA4 : 0><UEA5 : 0><UEA6 : 0><UEA7 : 0><UCS2 : 0><UIA1 : 1><UIA2 : 0><UIA3 : 0><UIA4 : 0><UIA5 : 0><UIA6 : 0><UIA7 : 0><ProSe_dd : 0><ProSe : 0><H245_ASH : 0><ACC_CSFB : 1><LPP : 1><LCS : 0><X1_SRVCC : 0><NF : 1><ePCO : 1><HC_CP_CIoT : 0><ERw_oPDN : 0><S1U_data : 0><UP_CIoT : 0><CP_CIoT : 0><ProSe_relay : 0><ProSe_dc : 0><spare : 1><spare : 0><spare : 1><spare : 1><spare : 0><spare : 0><spare : 0><MultiDRB : 0><spare [transparent] : 0x>>><ULDataStat [transparent] : <T : 64><L : 2><V : 0x0000>><PDUSessStat [transparent] : <T : 80><L : 2><V : 0x0000>><MICOInd [transparent] : <T : 11><V : 0>><UEStatus [transparent] : <T : 43><L : 1><V : 0x00>><AddGUTI [transparent] : <T : 119><L : 11><V : 0xf200000000000000000000>><AllowedPDUSessStat [transparent] : <T : 37><L : 2><V : 0x0000>><UEUsage : <T : 24><L : 1><UEUsage : <spare : 0x00><Value : 0 (voice centric)>>><5GSDRXParam [transparent] : <T : 81><L : 1><V : 0x00>><EPSNASContainer [transparent] : <T : 112><L : 2><V : 0x0700>><LADNInd : <T : 116><L : 0><LADNInd : >><PayloadContainerType [transparent] : <T : 8><V : 1 (N1 SM information)>><PayloadContainer [transparent] : <T : 123><L : 1><V : 0x00>><NetSlicingInd : <T : 9><NetSlicingInd : <spare : 0><DCNI : 0 (requested NSSAI not created from default configured NSSAI)><NSSCI : 0 (network slicing subscription not changed)>>><5GSUpdateType : <T : 83><L : 1><5GSUpdateType : <spare : 0><EPS-PNB-CIoT : 0><5GS-PNB-CIoT : 0><NG-RAN-RCU : 0><SMSRequested : 1>>><MSCm2 [transparent] : <T : 65><L : 3><V : 0x400000>><SuppCodecs [transparent] : <T : 66><L : 3><V : 0x000100>><NASContainer [transparent] : <T : 113><L : 2><V : 0x0000>><EPSBearerCtxtStat [transparent] : <T : 96><L : 2><V : 0x0000>><ExtDRXParam [transparent] : <T : 110><L : 1><V : 0x00>><T3324 [transparent] : <T : 106><L : 1><V : 0x00>><UERadioCapID [transparent] : <T : 103><L : 1><V : 0x00>><MappedNSSAI [transparent] : <T : 53><L : 1><V : 0x00>><AddInfoReq [transparent] : <T : 72><L : 1><V : 0x00>><WUSAssistInfo [transparent] : <T : 26><L : 1><V : 0x00>><N5GCInd [transparent] : <T : 10>><NBN1ModeDRXParam [transparent] : <T : 48><L : 1><V : 0x00>>>><EPSBearerCtxtStat [transparent] : <T : 96><L : 2><V : 0x0000>><ExtDRXParam [transparent] : <T : 110><L : 1><V : 0x00>><T3324 [transparent] : <T : 106><L : 1><V : 0x00>><UERadioCapID [transparent] : <T : 103><L : 1><V : 0x00>><MappedNSSAI [transparent] : <T : 53><L : 1><V : 0x00>><AddInfoReq [transparent] : <T : 72><L : 1><V : 0x00>><WUSAssistInfo [transparent] : <T : 26><L : 1><V : 0x00>><N5GCInd [transparent] : <T : 10>><NBN1ModeDRXParam [transparent] : <T : 48><L : 1><V : 0x00>>>

>>> self[3].get_val()
[[126, 0, 0, 65], [[0, 0]], [[1, 1]], [11, [15, 0, 2, b'\x00\xf1\x10', 1, 1, 1, 1592820272]], [46, 4, [1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0]], [113, 56, [[126, 0, 0, 65], [[0, 0]], [[1, 1]], [11, [15, 0, 2, b'\x00\xf1\x10', 1, 1, 1, 1592820272]], [16, 1, [0, 0, 0, 0, 0, 1, 1, 1]], [46, 4, [1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0]], [47, 2, [[1, [1]]]], [82, [b'\x00\xf1\x10', 1]], [23, 7, [1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0]], [24, 1, [0, 0]], [116, 0, []], [9, [0, 0, 0]], [83, 1, [0, 0, 0, 0, 1]]]]]

>>> FGIA(key, seqnoff + self[2].get_val(), bearer, dir, self[2].to_bytes() + self[3].get_val())
Traceback (most recent call last):
  File "/Users/dziugas/Library/Application Support/JetBrains/IntelliJIdea2022.2/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
TypeError: can't concat list to bytes

>>> FGIA(key, seqnoff + self[2].get_val(), bearer, dir, self[2].to_bytes() + self[3].to_bytes())
b'\xc5/\x18&'

>>> FGIA(key, seqnoff + self[2].get_val(), bearer, dir, self[2].to_bytes() + self[3].to_bytes()) == self[1].get_val()
True 

Note that exactly the same problem is with the EMMAuthenticationResponse (that is an LTE message, handled by EMMSecProtNASMessage in TS24301_EMM.py):

>>> self.to_bytes()
b'\x17\xed\xdc\x9c\t\x13\x07S\x08\x10\\\xb1,k\xbblB'

>>> self
<EMMSecProtNASMessage : <EMMHeaderSec : <SecHdr : 1 (Integrity protected)><ProtDisc : 7 (EMM)>><MAC : 0xeddc9c09><Seqn : 19><EMMAuthenticationResponse : <EMMHeader : <SecHdr : 0 (No security)><ProtDisc : 7 (EMM)><Type : 83 (Authentication response)>><RES : <L : 8><V : 0x105cb12c6bbb6c42>>>>

>>> seqnoff
0

>>> dir
0

>>> self[2]
<Seqn : 19>

>>> self[2].to_bytes()
b'\x13'

>>> self[3]
<EMMAuthenticationResponse : <EMMHeader : <SecHdr : 0 (No security)><ProtDisc : 7 (EMM)><Type : 83 (Authentication response)>><RES : <L : 8><V : 0x105cb12c6bbb6c42>>>

>>> self[3].get_val()
[[0, 7, 83], [8, b'\x10\\\xb1,k\xbblB']]

>>> EIA(key, seqnoff + self[2].get_val(), 0, dir, self[2].to_bytes() + self[3].get_val())
Traceback (most recent call last):
  File "/Users/dziugas/Library/Application Support/JetBrains/IntelliJIdea2022.2/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
TypeError: can't concat list to bytes

>>> EIA(key, seqnoff + self[2].get_val(), 0, dir, self[2].to_bytes() + self[3].to_bytes())
b'\x9c\xd1R\xa5'
p1-bmu commented 1 year ago

How have you set the values in your messages' structures ? In FGMMSecProtNASMessage and EMMSecProtNASMessage, the NASMessage field is a Buf, hence supposed to be assigned with a bytes buffer.

Maybe this happens because you decode a message with parse_NAS5G(buf, inner=True) : in this case, the NASMessage part gets substituted with the structured inner NAS message. But, that will make cryptographic transforms fail on it.

Maybe I should switch the default value for inner to False in parse_NAS() and parse_NAS5G(), to avoid that kind of confusion ?

dziugas-wg2 commented 1 year ago

Thanks for reply, @p1-bmu. We are using parse_NAS_MO() to parse NAS messages and MAC verification seem to be working just fine for other MO NAS messages.

Here is an attempt to parse and verify the MAC of the the same 5GMMRegistrationRequest from the above.

>>> nas_bytes = b'~\x01\xc5/\x18&\x1a~\x00A\t\x00\x0b\xf2\x00\xf1\x10\x01\x00A^\xf0\x820.\x04\xf0p\xf0pq\x008~\x00A\t\x00\x0b\xf2\x00\xf1\x10\x01\x00A^\xf0\x820\x10\x01\x07.\x04\xf0p\xf0p/\x02\x01\x01R\x00\xf1\x10\x00\x00\x01\x17\x07\xf0p\xc0@\x19\x80\xb0\x18\x01\x00t\x00\x00\x90S\x01\x01'

>>> nas, err = NAS.parse_NAS_MO(nas_bytes)

>>> err
0

>>> nas
<5GMMSecProtNASMessage : <5GMMHeaderSec : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 1 (Integrity protected)>><MAC : 0xc52f1826><Seqn : 26><5GMMRegistrationRequest : <5GMMHeader : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 0 (No security)><Type : 65 (Registration request)>><NAS_KSI : <NAS_KSI : <TSC : 0 (native security context)><Value : 0>>><5GSRegType : <5GSRegType : <FOR : 1 (Follow-on request pending)><Value : 1 (initial registration)>>><5GSID : <L : 11><5GSID : <ind : 0xf><spare : 0><Type : 2 (5G-GUTI)><PLMN : 00101><AMFRegionID : 1><AMFSetID : 1><AMFPtr : 1><5GTMSI : 0x5ef08230>>><NonCurrentNativeNAS_KSI [transparent] : <T : 12><V : 0>><5GMMCap [transparent] : <T : 16><L : 1><V : 0x00>><UESecCap : <T : 46><L : 4><UESecCap : <5G-EA0 : 1><5G-EA1_128 : 1><5G-EA2_128 : 1><5G-EA3_128 : 1><5G-EA4 : 0><5G-EA5 : 0><5G-EA6 : 0><5G-EA7 : 0><5G-IA0 : 0><5G-IA1_128 : 1><5G-IA2_128 : 1><5G-IA3_128 : 1><5G-IA4 : 0><5G-IA5 : 0><5G-IA6 : 0><5G-IA7 : 0><EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><spare [transparent] : 0x>>><NSSAI [transparent] : <T : 47><L : 2><V : 0x0101>><TAI [transparent] : <T : 82><V : 0x000000000000>><EPSUENetCap [transparent] : <T : 23><L : 2><V : 0x0000>><ULDataStat [transparent] : <T : 64><L : 2><V : 0x0000>><PDUSessStat [transparent] : <T : 80><L : 2><V : 0x0000>><MICOInd [transparent] : <T : 11><V : 0>><UEStatus [transparent] : <T : 43><L : 1><V : 0x00>><AddGUTI [transparent] : <T : 119><L : 11><V : 0xf200000000000000000000>><AllowedPDUSessStat [transparent] : <T : 37><L : 2><V : 0x0000>><UEUsage [transparent] : <T : 24><L : 1><V : 0x00>><5GSDRXParam [transparent] : <T : 81><L : 1><V : 0x00>><EPSNASContainer [transparent] : <T : 112><L : 2><V : 0x0700>><LADNInd [transparent] : <T : 116><L : 0><V : 0x>><PayloadContainerType [transparent] : <T : 8><V : 1 (N1 SM information)>><PayloadContainer [transparent] : <T : 123><L : 1><V : 0x00>><NetSlicingInd [transparent] : <T : 9><V : 0>><5GSUpdateType [transparent] : <T : 83><L : 1><V : 0x00>><MSCm2 [transparent] : <T : 65><L : 3><V : 0x400000>><SuppCodecs [transparent] : <T : 66><L : 3><V : 0x000100>><NASContainer : <T : 113><L : 56><5GMMRegistrationRequest : <5GMMHeader : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 0 (No security)><Type : 65 (Registration request)>><NAS_KSI : <NAS_KSI : <TSC : 0 (native security context)><Value : 0>>><5GSRegType : <5GSRegType : <FOR : 1 (Follow-on request pending)><Value : 1 (initial registration)>>><5GSID : <L : 11><5GSID : <ind : 0xf><spare : 0><Type : 2 (5G-GUTI)><PLMN : 00101><AMFRegionID : 1><AMFSetID : 1><AMFPtr : 1><5GTMSI : 0x5ef08230>>><NonCurrentNativeNAS_KSI [transparent] : <T : 12><V : 0>><5GMMCap : <T : 16><L : 1><5GMMCap : <SGC : 0><5G-HC-CP-CIoT : 0><N3Data : 0><5G-CP-CIoT : 0><RestrictEC : 0><LPP : 1><HOAttach : 1><S1Mode : 1><RACS [transparent] : 0><NSSAA [transparent] : 0><5G-LCS [transparent] : 0><V2XCNPC5 [transparent] : 0><V2XCEPC5 [transparent] : 0><V2X [transparent] : 0><5G-UP-CIoT [transparent] : 0><5GSRVCC [transparent] : 0><spare [transparent] : 0><5G-EHC-CP-CIoT [transparent] : 0><MultipleUP [transparent] : 0><WUSA [transparent] : 0><CAG [transparent] : 0><spare [transparent] : 0x>>><UESecCap : <T : 46><L : 4><UESecCap : <5G-EA0 : 1><5G-EA1_128 : 1><5G-EA2_128 : 1><5G-EA3_128 : 1><5G-EA4 : 0><5G-EA5 : 0><5G-EA6 : 0><5G-EA7 : 0><5G-IA0 : 0><5G-IA1_128 : 1><5G-IA2_128 : 1><5G-IA3_128 : 1><5G-IA4 : 0><5G-IA5 : 0><5G-IA6 : 0><5G-IA7 : 0><EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><spare [transparent] : 0x>>><NSSAI : <T : 47><L : 2><NSSAI : <SNSSAI : <Len : 1><SNSSAI : <SST : 1 (eMBB)><SD [transparent] : 0x><MappedHPLMNSST [transparent] : 0><MappedHPLMNSD [transparent] : 0x>>>>><TAI : <T : 82><5GSTAI : <PLMN : 00101><TAC : 0x000001>>><EPSUENetCap : <T : 23><L : 7><UENetCap : <EEA0 : 1><EEA1_128 : 1><EEA2_128 : 1><EEA3_128 : 1><EEA4 : 0><EEA5 : 0><EEA6 : 0><EEA7 : 0><EIA0 : 0><EIA1_128 : 1><EIA2_128 : 1><EIA3_128 : 1><EIA4 : 0><EIA5 : 0><EIA6 : 0><EIA7 : 0><UEA0 : 1><UEA1 : 1><UEA2 : 0><UEA3 : 0><UEA4 : 0><UEA5 : 0><UEA6 : 0><UEA7 : 0><UCS2 : 0><UIA1 : 1><UIA2 : 0><UIA3 : 0><UIA4 : 0><UIA5 : 0><UIA6 : 0><UIA7 : 0><ProSe_dd : 0><ProSe : 0><H245_ASH : 0><ACC_CSFB : 1><LPP : 1><LCS : 0><X1_SRVCC : 0><NF : 1><ePCO : 1><HC_CP_CIoT : 0><ERw_oPDN : 0><S1U_data : 0><UP_CIoT : 0><CP_CIoT : 0><ProSe_relay : 0><ProSe_dc : 0><spare : 1><spare : 0><spare : 1><spare : 1><spare : 0><spare : 0><spare : 0><MultiDRB : 0><spare [transparent] : 0x>>><ULDataStat [transparent] : <T : 64><L : 2><V : 0x0000>><PDUSessStat [transparent] : <T : 80><L : 2><V : 0x0000>><MICOInd [transparent] : <T : 11><V : 0>><UEStatus [transparent] : <T : 43><L : 1><V : 0x00>><AddGUTI [transparent] : <T : 119><L : 11><V : 0xf200000000000000000000>><AllowedPDUSessStat [transparent] : <T : 37><L : 2><V : 0x0000>><UEUsage : <T : 24><L : 1><UEUsage : <spare : 0x00><Value : 0 (voice centric)>>><5GSDRXParam [transparent] : <T : 81><L : 1><V : 0x00>><EPSNASContainer [transparent] : <T : 112><L : 2><V : 0x0700>><LADNInd : <T : 116><L : 0><LADNInd : >><PayloadContainerType [transparent] : <T : 8><V : 1 (N1 SM information)>><PayloadContainer [transparent] : <T : 123><L : 1><V : 0x00>><NetSlicingInd : <T : 9><NetSlicingInd : <spare : 0><DCNI : 0 (requested NSSAI not created from default configured NSSAI)><NSSCI : 0 (network slicing subscription not changed)>>><5GSUpdateType : <T : 83><L : 1><5GSUpdateType : <spare : 0><EPS-PNB-CIoT : 0><5GS-PNB-CIoT : 0><NG-RAN-RCU : 0><SMSRequested : 1>>><MSCm2 [transparent] : <T : 65><L : 3><V : 0x400000>><SuppCodecs [transparent] : <T : 66><L : 3><V : 0x000100>><NASContainer [transparent] : <T : 113><L : 2><V : 0x0000>><EPSBearerCtxtStat [transparent] : <T : 96><L : 2><V : 0x0000>><ExtDRXParam [transparent] : <T : 110><L : 1><V : 0x00>><T3324 [transparent] : <T : 106><L : 1><V : 0x00>><UERadioCapID [transparent] : <T : 103><L : 1><V : 0x00>><MappedNSSAI [transparent] : <T : 53><L : 1><V : 0x00>><AddInfoReq [transparent] : <T : 72><L : 1><V : 0x00>><WUSAssistInfo [transparent] : <T : 26><L : 1><V : 0x00>><N5GCInd [transparent] : <T : 10>><NBN1ModeDRXParam [transparent] : <T : 48><L : 1><V : 0x00>>>><EPSBearerCtxtStat [transparent] : <T : 96><L : 2><V : 0x0000>><ExtDRXParam [transparent] : <T : 110><L : 1><V : 0x00>><T3324 [transparent] : <T : 106><L : 1><V : 0x00>><UERadioCapID [transparent] : <T : 103><L : 1><V : 0x00>><MappedNSSAI [transparent] : <T : 53><L : 1><V : 0x00>><AddInfoReq [transparent] : <T : 72><L : 1><V : 0x00>><WUSAssistInfo [transparent] : <T : 26><L : 1><V : 0x00>><N5GCInd [transparent] : <T : 10>><NBN1ModeDRXParam [transparent] : <T : 48><L : 1><V : 0x00>>>>

>>> knasint = b'\x86B\n\x11\xa9^\xdd\xa6\x08S\x9b\x9b\x91\x06\r\x17'

>>> nas.mac_verify(knasint, 0, 2, 0)
Traceback (most recent call last):
  File "/Users/dziugas/Library/Application Support/JetBrains/IntelliJIdea2022.2/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
  File "/private/var/tmp/_bazel_dziugas/41664892ed9f0826ac144a7b33f74680/execroot/__main__/bazel-out/darwin_arm64-fastbuild/bin/terminators/radiostar/vulcan/vulcan_unit_tests.runfiles/pycrate/pycrate_mobile/TS24501_FGMM.py", line 757, in mac_verify
    mac = FGIA(key, seqnoff + self[2].get_val(), bearer, dir, self[2].to_bytes() + self[3].get_val())
TypeError: can't concat list to bytes
dziugas-wg2 commented 1 year ago

Can confirm that when calling NAS5G.parse_NAS5G() directly with inner=False, MAC verification is successful. So yes, defaulting inner to False would make sense in this case, but I am not yet sure about other implications of such change. Note that just modifying the function signatures won't help as NAS.parse_NAS_MO() wrapper function call parse_NASLTE_MO() / parse_NAS5G() functions explicitly with inner=True:

https://github.com/P1sec/pycrate/blob/bedeaf30ad5762b3e67b5c66a08d3840b5ad8b3b/pycrate_mobile/NAS.py#L122-L124

>>> from pycrate_mobile import NAS5G

>>> nas_bytes = b'~\x01\xc5/\x18&\x1a~\x00A\t\x00\x0b\xf2\x00\xf1\x10\x01\x00A^\xf0\x820.\x04\xf0p\xf0pq\x008~\x00A\t\x00\x0b\xf2\x00\xf1\x10\x01\x00A^\xf0\x820\x10\x01\x07.\x04\xf0p\xf0p/\x02\x01\x01R\x00\xf1\x10\x00\x00\x01\x17\x07\xf0p\xc0@\x19\x80\xb0\x18\x01\x00t\x00\x00\x90S\x01\x01'

>>> knasint = b'\x0e\xe3j\x0f\x90~\x86\x87\xd9\xddfX\xf7\x0f.4'

>>> nas5g, err = NAS5G.parse_NAS5G(nas_bytes, False)

>>>err
0

>>> nas5g
<5GMMSecProtNASMessage : <5GMMHeaderSec : <EPD : 126 (5GMM)><spare : 0x0><SecHdr : 1 (Integrity protected)>><MAC : 0xc52f1826><Seqn : 26><NASMessage : 0x7e004109000bf200f1100100415ef082302e04f070f0707100387e004109000bf200f1100100415ef082301001072e04f070f0702f0201015200f1100000011707f070c0401980b018010074000090530101>>

>>> nas5g.mac_verify(knasint, 0, 2)
True
p1-bmu commented 1 year ago

Yep, I am currently adding the inner arg in parse_NAS_MO() and _MT() from NAS.py. And I am effectively hesitating to change the default of inner=True, as it's like this since years...

dziugas-wg2 commented 1 year ago

@p1-bmu Found at least one consequence of that possible change: we are iterating over IEs of a NAS container and with inner=False, I get the following:

>       for element in container:
E       TypeError: 'Buf' object is not iterable
p1-bmu commented 1 year ago

Yep, that's how your application work, I guess. And you'll have to change it if you want to apply the proper cryptographic transforms on one side, and access all inner structures on the other side.

But here, you are on your own. Moreover, I hope wg2 is compliant with both the licensing of pycrate (LGPL library) and CryptoMobile (which is GPL for its C-Python binding and Python part).

p1-bmu commented 1 year ago

The last commit https://github.com/P1sec/pycrate/commit/c7c6acb1b431518cd128ead7dd5e1ddc2cc1f996 should support the way you want to call cryptographic operations on 4G and 5G NAS messages. This is however sub-optimal, because in your case, you decode the full message, and then re-encode it to compute the MAC over the re-encoded buffer.

dziugas-wg2 commented 1 year ago

Thank you for coming up with a solution, I really appreciate that!

Regarding the licensing, to the best of my knowledge, we at WG2 are compliant. Some of my colleagues are maintaining open-source projects, so we know how hard and sometimes non-rewarding that might be, so we at WG2 like to contribute when we can, and please be assured that if we ever need to make a change to either of the projects, we'll make it in a public fork and send a pull request.

p1-bmu commented 1 year ago

Thanks for your kind feedback