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:
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
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
Great blog! I have one question. Are you using all of the 16 bytes of AUTN to derive KASME?
ReplyDeleteCould 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?
ReplyDeleteHi PG,
ReplyDeleteNo, 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
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThanks Ferraz for such a nice tool.
ReplyDeleteThanks Chandra.
DeleteHi Ferraz, thank you for the very useful tool.
ReplyDeleteBut 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.
Hi Sanil,
DeleteYou 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.
Hi Ferraz, For NAS calculation of KASME we need to provide key = CK || IK (|| -> OR)
Deletehere 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
Hi Ravi,
Delete|| 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
Hi Ferraz,
ReplyDeleteThanks for the clarification, can you please provide me EIA1 & EIA2 algorithms reference, is there any opensource for these algorithms implementation?
Hi,
ReplyDeleteCould 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?
Oops, just noticed that the content of S should be
Delete0x10, 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
"MCC+MNC as "310028"
Deleteis that plmn in already encoded format ?
then, mcc 1 = 1, mcc2 = 3, mcc3 = 0 &
s = 0x31, 00, .. , right ?
No. mcc1=3, mcc2=1, mcc3= 0 , mnc1=0, mnc2=2, mnc3=8
Deleteif for example the mcc+mnc is 5 digits, the third mnc digit is a F
the hex coding:
mcc2, mcc1, mnc3, mcc3, mnc2, mnc1
so, thats not in plmn format; just mcc + mnc.
DeleteThen, that's how values should be filled in S, not in ascii according to 33.220 ?
Hi Ferraz,
ReplyDeleteIm 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
The test sets have the non used bits all set to zero.
ReplyDeleteIn 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.
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi Fabrício;
ReplyDeleteThank 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?
Hi Fabrício,
ReplyDeleteThanks 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
Hi,
ReplyDeleteThe 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 :)
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
ReplyDeleteHi
ReplyDeleteCan I get c/c++ code for snow3g algorithm ???
http://www.gsma.com/aboutus/wp-content/uploads/2014/12/snow3gspec.doc
DeleteHi Fabricio,
ReplyDeleteI 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
Your keys are correct. i'm getting this result in my app:
ReplyDelete73BB2FC1D8F3E5B2B1294C9F84CD2DC15D922B7C1249A450991B53D86BFE38CB
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
Thanks Fabricio for the confirmation. I think there might be some wrong with my HMAC-SHA-256 function implementation :)
DeleteDear Fabricio,
ReplyDeleteIf you have code, please share it so that I will try to do some enhancements like nas integrity and ciphering
Hi Fabricio,
ReplyDeleteCan 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.
Hi Fabricio,
DeleteI forgot the S value while generating KASME.
S_KASME:1000f1100003813d93cdad6d0006
Thanks,
Veerendra.
Hi,
DeleteEverything 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
Hi Fabricio,
DeleteThanks for the reply.And i am getting Security mode Rejected, Unspecified. Can you have any idea on it.
Thanks,
Veerendra.
Hi,
DeleteCan you send me the trace to my email (fasferraz@gmail.com) s1 and s6a (just to confirm the keys)?
This comment has been removed by the author.
ReplyDeletehello Fabricio,
ReplyDeletevery good !
regards!
valdemar
Hi Fabricio
ReplyDeletei 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
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.
Deletethanks!
Deletehow did you create the S value?
probably i dont know how to achieve this value
it's explained in the blog:
Delete"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."
Hi Fabricio
ReplyDeletei 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?
i have found my mistake,
ReplyDeletethe S parameter is 11000000000004
Thanks
Exactly. Annex A of 33.401 shows how the S string is built for each function.
DeleteHi Fabricio,
ReplyDeleteWill 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!
Can you please contact me by email?
Deletethanks.
Thanks, admin for sharing such an interesting blog with us.Mobile Application Developer
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDelete