If you need some example pcap traces generated by any of these tools, just send an email to fasferraz@gmail.com


5/17/12

LTE Security

This is an application that I’ve done recently that implements all the security procedures for LTE referred in Annex A and Annex B of 3GPP 33.401. The reason to start doing this application was the fact that I was analysing some S1AP traces and due to the ciphering I was unable to see the NAS messages. Since the trace also included authentication information retrieved from the HSS through s6a Diameter interface, I had all the information I needed to decrypt the message. Since in that specific trace the chosen algorithm was the 128-EEA1, after some reading I start implementing the 3G SNOW algorithm, since that was the algorithm that 128-EEA1 is based on. 
After that I decided to implement also the integrity algorithms and the other ciphering algorithm that are in Annex B.

In resume:
  • Ciphering algorithm 128-EEA-1 and Integrity algortihm 128-EIA-1 are based on SNOW 3G and UEA2 defined in 3GPP
  • Ciphering algorithm 128-EEA-2 and Integrity algortihm 128-EIA-2 are based on AES defined in NIST specifications
  • Ciphering algorithm 128-EEA-3 and Integrity algortihm 128-EIA-3 are based on ZUC defined in 3GPP specifications
The key derivation from KASME needed for the NAS decryption is defined in Annex A and is based on HMAC-SHA-256. 

The Key derivation function that is needed for every key derivation in LTE is explained in 33.220, and is the following:

“The input parameters and their lengths shall be concatenated into a string S as follows:

1. The length of each input parameter measured in octets shall be encoded into a two octet-long string:

a) express the number of octets in input parameter Pi as a number k in the range [0, 65535].

b) Li is then a 16-bit long encoding of the number k, encoded as described in clause B.2.1.

2. String S shall be constructed from n+1 input parameters as follows:

S = FC || P0 || L0 || P1 || L1 || P2 || L2 || P3 || L3 ||... || Pn || Ln

where

FC is single octet used to distinguish between different instances of the algorithm,

P0 ... Pn are the n+1 input parameter encodings, and

L0 ... Ln are the two-octet representations of the length of the corresponding input parameter encodings P0.. Pn.

In this specification the following restriction applies to P0:  P0 is a static ASCII-encoded string.
This restriction is not part of the KDF definition and does not apply to the KDF when used by other 3GPP specifications unless explicitly stated so in those specifications.

3. The final output, i.e. the derived key is equal to the KDF computed on the string S using the key, denoted Key. The present document defines the following KDF:

derived key = HMAC-SHA-256 ( Key , S )

as specified in [22] and [23].”



In Annex A of 3GPP 33.401 we have for each Key Derivation the FC, Pn and Ln values to apply.


The app has several tabs and is divided between Annex A functions and Annex B Algorithms.


For Annex A, there is a tab for each chapter of this Annex. For example Annex A.7 is for deriving the algorithm keys for each one of these situations:

  • Nas encryption
  • Nas integrity
  • Rrc encryption
  • Rrc integrity
  • User encryption
  • User integrity

For NAS algorithm key derivations, the input key shall be the 256-bit KASME, and for UP and RRC algorithm key derivations, the input key shall be the 256-bit KeNB.


For Annex B, there are two tabs, one for the ciphering and another one for the integrity.



In the ciphering tab is possible after doing the decryption of the message, to replace the bytes in the pcap file, in order to properly see the decoded message. 



This was the major goal of this app, since in this way I can use the wireshark decoding capabilities.



The other tab, is just to confirm that the mac is correctly calculated in a given message, since this is always in clear text.



Lets see an example of a real use of this application:



In this image we can see the KASME generated in the HSS:



With this KASME, and since in the trace I saw that the chosen encryption and integrity algorithm were respectively the 128-EEA1 and 128-EIA, I used the tab for annex A.7 to calculate the keys for encryption and integrity:


With theses keys, I can then use the tab Annex.B to decrypt and check the integrity of the NAS message.


For encryption, I need to get the following information from the S1AP:
  • Ciphered message
  • Sequence number
  • Bearer ID
  • Direction (i.e. Uplink/downlink)


One of the ciphered NAS messages was this one:

Applying this ciphered message in the app we get the following result:

The resulted decrypted message was then used to replace the bytes in pcap file.
The new file is then loaded in wireshark, and the previously ciphered bytes become decoded:

In terms of integrity, the parameters needed for the input of the algorithm are the same, but in this case the complete message to hash also includes the sequence number along with the NAS message.

The result confirms the MAC present in the trace:


Another use for this application, is the derivation of the KASME it self, from the CK, IK, AUTN, and SNid, which is mainly the MCC/MNC of the MME network in which the UE is registering. This way we can obtain the Authentication vector for LTE (quartet) from the quintuplet generated from the Milenage algorithm. 
So this is app is also a clear complement of another application that i have made in 2004:



So for the example above, the generated KASME for a "imaginary" MCC/MNC network like 12345, is the following:



But let's use a real example to see if the application is calculating the KASME correctly.

The next trace shows a LTE vector from a USIM:




My application needs the CK, IK, AUTN and MCC/MNC.
The AUTN is present in the vector.
The MCC/MNC of the registering network is also known.

So, how can i get the CK and IK from the RAND present in the vector?

Solution: I need to run the AUTHENTICATE algorithm in the USIM!
To do this I need a modem that supports the following AT Commands:

AT+CRSM
AT+CSIM

I used a ZTE dongle, which supports these AT commands.

Next i need to know the AID from the USIM 3G application that is inside the EFdir file (ID=H2F00, Application Directory EF):

AT+CRSM=178,12032,1,4,0 (I'm reading record 1 of the EFdir)
+CRSM: 144,0,"61214F10A0000000871002FFFFFFFF8903050001...."

Next, I will go through the USIM directory till the USIM Application:


AT+CSIM=16,"00A40000023F0000" (I'm selecting the Master File)
AT+CSIM=16,"00A40000022F0000" (I'm selecting the EFdir)
AT+CSIM=42,"00A4040010A0000000871002FFFFFFFF8903050001" (I'm activating the USIM 3G Application AID)

After this steps i can run the Milenage Algorithm in the USIM using the command AUTHENTICATE with the RAND and AUTN from the trace above:

AT+CSIM=80,"008800812210D6BA0C396BCE3189EF8B49FAF3F6746210B46F17E0F84F8000E6693AE37446963E00"

+CSIM: 4,"6135"

The "61" means success, and the "35" is the length of the answer, that we need to get using the GET RESPONSE command:


AT+CSIM=10,"00C0000035"
+CSIM: 110,"DB08FCCB24ADFBA66882105AFF52E6AAC652024111C33D3F8867861026D77E75251C7DA4BB5645367115E4A808866FAA98C147AC889000"

This answer can be decomposed in the following parts:

DB - Sucess

08 - Length of RES

FCCB24ADFBA66882 - RES

10 - Length of CK
5AFF52E6AAC652024111C33D3F886786 - CK

10 - Length of IK
26D77E75251C7DA4BB5645367115E4A8 - IK

08 - Length of Kc
866FAA98C147AC88 - Kc


As we can see the RES matches the XRES in the LTE vector in the trace above.

So let's use the application to calculate the KASME using the CK, IK, AUTN and MCC/MNC:




As we can see the resulting KASME is the same as the KASME present in the trace, so the app is working properly!

This app can be downloaded here.
The 2004 app can also be downloaded for free in a previous post.

Update (September/2013): A new version with support for 128-EEA-3 and 128-EIA-3 can be downloaded here

Update (February/2020): A new version with support for A.15 up to A.19 can be downloaded here

Update (August/2020): A new version with a bug correction for 128-EIA-3 algorithm can be downloaded here







51 comments:

  1. Great blog! I have one question. Are you using all of the 16 bytes of AUTN to derive KASME?

    ReplyDelete
  2. Could you also go into more detail about encoding S . "In this specification the following restriction applies to P0: P0 is a static ASCII-encoded string." For example if P0=SNID=0x32F121. Would the P0 hex representation part of S look like 0x333246313231?

    ReplyDelete
  3. Hi PG,
    No, KASME needs SQN XOR AK, which happens to be the first 6 bytes of AUTN. My app just has the two possibilities: you insert the AUTN, and i will use the first 6 bytes of it, or you insert SQN and AK, and i do the XOR and use the result to calculate the KASME.
    Regarding the other question, in the example you provide the hex will be 0x32F121. But 33.401 has all the values for LTE

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Thanks Ferraz for such a nice tool.

    ReplyDelete
  7. Hi Ferraz, thank you for the very useful tool.
    But why is the Integrity Protection (AS/NAS) algo takes 256-bit Key as input? EIA and EEA are 128-bit algorithms as per 33.401.

    ReplyDelete
    Replies
    1. Hi Sanil,

      You are right when you say that the current algorithms are 128 bits, but that doesn't mean the 3GPP will in future define 256 bits algorithms. The specification is wide to include this future scenarios, because 33.401 states that:

      "For NAS algorithm key derivations, the input key shall be the 256-bit KASME, and for UP and RRC algorithm key derivations, the input key shall be the 256-bit KeNB.
      For an algorithm key of length n bits, where n is less or equal to 256, the n least significant bits of the 256 bits of the KDF output shall be used as the algorithm key. "

      So if you are using a algorithm with less keys (128), you should only use the (128) least significant bits.

      Delete
    2. Hi Ferraz, For NAS calculation of KASME we need to provide key = CK || IK (|| -> OR)

      here CK is 128 bit and IK is 128 bit hence key is 128 bits but i believe key length should be 256 bits.. how we are going to manage here .... i'm confused passing input key to KDF to generate KASME ....please clarify

      Delete
    3. Hi Ravi,
      || is not OR. || => concatenation, so if you concatenate two variables of 128 bits you get one of 256 :)
      " the input key shall be equal to the concatenation CK || IK of CK and IK", 33.401

      Delete
  8. Hi Ferraz,
    Thanks for the clarification, can you please provide me EIA1 & EIA2 algorithms reference, is there any opensource for these algorithms implementation?

    ReplyDelete
  9. Hi,

    Could you please publish your source code for generate Kasme (A.2)?

    I have MCC+MNC as "310028" , So I was using 14 bytes S with content

    0x10, 0x13,0x00,0x82,0x00,0x03,6-bytes-sqn-xor-ak,0x00,0x06

    and CK||IK. then calling openssl HMAC(EVP_sha256(), ckik, 32, S, 14, kasme, &kasmelength);

    But I get a different result from your app's result?

    ReplyDelete
    Replies
    1. Oops, just noticed that the content of S should be

      0x10, 0x13,0x80,0x20,0x00,0x03,6-bytes-sqn-xor-ak,0x00,0x06

      That is MCC1,MCC2,MCC3,MNC3,MNC1,MNC2, not
      MCC1,MCC2,MCC3,MNC1,MNC2,MNC3

      Delete
    2. "MCC+MNC as "310028"
      is that plmn in already encoded format ?
      then, mcc 1 = 1, mcc2 = 3, mcc3 = 0 &
      s = 0x31, 00, .. , right ?

      Delete
    3. No. mcc1=3, mcc2=1, mcc3= 0 , mnc1=0, mnc2=2, mnc3=8
      if for example the mcc+mnc is 5 digits, the third mnc digit is a F

      the hex coding:
      mcc2, mcc1, mnc3, mcc3, mnc2, mnc1

      Delete
    4. so, thats not in plmn format; just mcc + mnc.

      Then, that's how values should be filled in S, not in ascii according to 33.220 ?

      Delete
  10. Hi Ferraz,
    Im looking to implement the EIA2 algorithm. For this I am using test sets from spec 33.401 - Release 9(Annex C - C.2 128-EIA2). My doubt is regarding the message length which is provided to the algorithm to calculate the MAC. The length value given in the test set is not using a standard pattern in each of the test sets. Some padding/truncation is done differently for each of the messages. Could you please asssist me with the same.

    Example:
    Count-I = 36af6144
    Bearer = 18
    Direction = 1
    IK = 7e5e9443 1e11d738 28d739cc 6ced4573
    Length = 254 bits
    Message = b3d3c917 0a4e1632 f60f8610 13d22d84 b726b6a2 78d802d1 eeaf1321 ba5929dc

    MACT = 1f60b01d


    Regards,
    Zeeshan

    ReplyDelete
  11. The test sets have the non used bits all set to zero.
    In your example, the length 254 corresponds to 32 Bytes, less 2 bits (32*8=256 -2 = 254)
    So the hexa letter of the last byte "C" in your example, which is 1100 in bit format, has the last 2 bits equal to 0.
    For the algorithm you should use the first 254 bits of the message to get the MAC of the test set.

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. This comment has been removed by the author.

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
  15. Hi Fabrício;

    Thank you for this very useful tutorial, i have some question on your work:

    1. where do you have extracted the Bearer id
    2. S1ap messages IntialContextSetupRequest contains an information element named, id-SecurityKey which has 256 bits length. Is this key what you have calculated in your tutorial?

    ReplyDelete
  16. Hi Fabrício,

    Thanks for this blog.

    I am trying to be familiar with the new version of the tool, so I am trying the test sets in 33401 but the output was not as expected as in 33401.

    Example :

    1- Reference Specs 33401 section C.2.1 Test Set 1:
    inputs :
    Algorith : 128-EIA2
    KEY = 000000000000000000000000000000002bd6459f82c5b300952c49104881ff48
    Count = 38a6f056
    Direction = Uplink
    Bearer ID = 18

    Message = 3332346263393840

    Actual Output of MACI is C28458E9
    Expected Output of MACI is 118c6eb8

    Please let me know why the values of MAC-I are not the same

    ReplyDelete
  17. Hi,

    The message length of that Test Set is 58 bits, so the last byte (40), only the first two bits should be used. My application does not have any field to say what is the bit size, because it uses all bytes from the message, in this case 64 bits. As far as i know all real scenarios use 8 bits multiples, since byte is the smallest unit, at least in the interfaces i use this app for :)

    ReplyDelete
  18. So you should use Test Sets that have a bit length that is a multiple of 8 with my app. For example test set 5 or 8

    ReplyDelete
  19. Hi
    Can I get c/c++ code for snow3g algorithm ???

    ReplyDelete
    Replies
    1. http://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.doc

      Delete
  20. Hi Fabricio,
    I am using A.2 KDF Spec. with below input
    Are my Key and S value are correct?
    As my result from application and my kasme calculation is not matching

    Input
    Ck= B40BA9A3C58B2A05BBF0D987B21BF8CB
    IK= F769BCD751044604127672711C6D3441
    MCC= 311
    MNC=280
    SQN=FF9BB4D0B607
    AK=AA689C648370

    SQN^AK= 55f328b43577


    Genrated Value
    KEY = B40BA9A3C58B2A05BBF0D987B21BF8CB F769BCD751044604127672711C6D3441 (CK || IK )
    S=10 130182 0003 55f328b43577 0006



    KASME = HMAC-SHA-256(Key,S)
    = HMAC-SHA-256(B40BA9A3C58B2A05BBF0D987B21BF8CBF769BCD751044604127672711C6D3441 , 10130182000355f328b435770006);

    Please confirm if any wrong in Key and S value?

    Thanks

    ReplyDelete
  21. Your keys are correct. i'm getting this result in my app:
    73BB2FC1D8F3E5B2B1294C9F84CD2DC15D922B7C1249A450991B53D86BFE38CB

    i've used an onlice hmac-sha calculator (https://www.liavaag.org/English/SHA-Generator/HMAC/) and i'm getting also the same result:

    73bb2fc1d8f3e5b2b1294c9f84cd2dc15d922b7c1249a450991b53d86bfe38cb

    I don't understand why you are getting a different output

    ReplyDelete
    Replies
    1. Thanks Fabricio for the confirmation. I think there might be some wrong with my HMAC-SHA-256 function implementation :)

      Delete
  22. Dear Fabricio,

    If you have code, please share it so that I will try to do some enhancements like nas integrity and ciphering

    ReplyDelete
  23. Hi Fabricio,
    Can you check the key and S values. I think having issue while generating the keys.
    Inputs:
    -------
    SQN:000000000227
    MCC:001
    MNC:01
    CK:0544dbba021279e799d28e1bd87c1454
    IK:e821de2175d4874e7ae971a89588bfd2
    AK:813d93cdaf4a
    SQN^AK:813d93cdad6d

    Output:
    -------
    KASME:83ecc522e1a24e85a26f728ffe2e2147d2ed75fe25fa191ad66437e9cd922cf9
    S:15020001010001(integrity)
    S:15010001000001(encryption)
    KNAS-int:eb0d9b7fe062fd8d49ddc854cf152a07
    KNAS-enc:9ad1c0bdea9cda6e976548b013c9360c


    Please confirm if any wrong in the above values?

    Thanks,
    Veerendra.

    ReplyDelete
    Replies
    1. Hi Fabricio,
      I forgot the S value while generating KASME.
      S_KASME:1000f1100003813d93cdad6d0006

      Thanks,
      Veerendra.

      Delete
    2. Hi,
      Everything is correct for the values you uded. For NAS-Encryption you are considering algorithm 0 to calculate the key, but algorithm 0 is no encryption, so no key is needed.
      I think this is not intentional right? if you want to use EEA-1 you need to change the S to S:15010001010001(encryption), and then you get NAS Key 30642CAF3F5724ADE10860621678A5A7

      Delete
    3. Hi Fabricio,
      Thanks for the reply.And i am getting Security mode Rejected, Unspecified. Can you have any idea on it.

      Thanks,
      Veerendra.

      Delete
    4. Hi,
      Can you send me the trace to my email (fasferraz@gmail.com) s1 and s6a (just to confirm the keys)?

      Delete
  24. This comment has been removed by the author.

    ReplyDelete
  25. hello Fabricio,

    very good !

    regards!
    valdemar

    ReplyDelete
  26. Hi Fabricio

    i tried to generate k nas integrity key from KASME.
    when i use your app (Annex A, A.7), i input are:
    KASME = 13064354e637d9b4de97f64fae6a4b20f5c3c899bfeb58871afbbbcb9b2a5157
    Algorith distingusher: NAS-int-alg
    Algorithm identity: 01

    the output is:
    KNAS INTEGRIty = 2530449545C525C87D8896F47E96129157F78D5C79DD42566872BEEB758A953A

    when i use this:
    1. derived key = HMAC-SHA-256 ( Key , S )
    2. KDF(KASME,NAS_INT_ALG) -> KNASint
    --> HMAC-SHA-256 ( KASME , 128-EIA1 ) = KNASint
    i didn't recieve the same output,
    what am i doing wrong?

    Thank

    ReplyDelete
    Replies
    1. What is the S you are using? for NASInt and algorithm id =1 you should use S= 0x15020001010001 and you should get the same output.

      Delete
    2. thanks!
      how did you create the S value?
      probably i dont know how to achieve this value

      Delete
    3. it's explained in the blog:

      "2. String S shall be constructed from n+1 input parameters as follows:

      S = FC || P0 || L0 || P1 || L1 || P2 || L2 || P3 || L3 ||... || Pn || Ln

      where

      FC is single octet used to distinguish between different instances of the algorithm,

      P0 ... Pn are the n+1 input parameter encodings, and

      L0 ... Ln are the two-octet representations of the length of the corresponding input parameter encodings P0.. Pn.

      In this specification the following restriction applies to P0: P0 is a static ASCII-encoded string.
      This restriction is not part of the KDF definition and does not apply to the KDF when used by other 3GPP specifications unless explicitly stated so in those specifications.

      3. The final output, i.e. the derived key is equal to the KDF computed on the string S using the key, denoted Key. The present document defines the following KDF:

      derived key = HMAC-SHA-256 ( Key , S )

      as specified in [22] and [23].”



      In Annex A of 3GPP 33.401 we have for each Key Derivation the FC, Pn and Ln values to apply."

      Delete
  27. Hi Fabricio

    i tried to generate k_eNB from KASME.
    when i use your app (Annex A, A.3), the input are:
    KASME = 13064354e637d9b4de97f64fae6a4b20f5c3c899bfeb58871afbbbcb9b2a5157
    UPLINK_NAS_COUNT = 00000000

    the output is:
    77E118F3C6D0DBE2D07CF904FB6BAC9BB2C0AB28A5D0D4F1A0DA307AE8AD37DC

    when i use this function:
    derived key = HMAC-SHA-256 ( Key , S )
    S = 00000000
    KEY = 13064354e637d9b4de97f64fae6a4b20f5c3c899bfeb58871afbbbcb9b2a5157

    the output is different, what am i doing wrong?

    ReplyDelete
  28. i have found my mistake,
    the S parameter is 11000000000004

    Thanks

    ReplyDelete
    Replies
    1. Exactly. Annex A of 33.401 shows how the S string is built for each function.

      Delete
  29. Hi Fabricio,

    Will your app be supporting 33.401 - A.15 Derivation of S-KeNB or S-KgNB for dual connectivity anytime soon?

    I couldn't find anything about dual connectivity in your 5G security app either, since 33.501 doesn't cover that part.

    Thank you for your reply in advance!

    ReplyDelete
  30. Thanks, admin for sharing such an interesting blog with us.Mobile Application Developer

    ReplyDelete
  31. This comment has been removed by the author.

    ReplyDelete
  32. This comment has been removed by the author.

    ReplyDelete