Manually Testing USIM Authentication » History » Version 3
laforge, 04/27/2022 05:23 PM
1 | 1 | laforge | h1. Manually Testing USIM Authentication |
---|---|---|---|
2 | |||
3 | 3 | laforge | {{>toc}} |
4 | |||
5 | 1 | laforge | This page describes how you can use Osmocom tools to manually test USIM / ISIM authentication against a SIM card. |
6 | |||
7 | h2. Prerequisites |
||
8 | |||
9 | * A USIM card of which you know the secret key K + OP/OPc |
||
10 | * A smart card interface device ("reader") supported by pysim (such as any pcsc-lite / libccid compatible reader) |
||
11 | * @osmo-auc-gen@ program (part of [[libosmocore:]]) |
||
12 | * @pySim-shell@ program (part of [[pysim:]]) |
||
13 | |||
14 | |||
15 | h2. Step-by-step guide |
||
16 | |||
17 | |||
18 | |||
19 | h3. Generate a 16-byte random challenge |
||
20 | |||
21 | Let's use @/dev/random@ to generate 16 bytes of randomness; conver it to hexadecimal |
||
22 | |||
23 | <pre> |
||
24 | $ dd if=/dev/random bs=16 count=1 2>/dev/null | xxd -p -l 100 |
||
25 | 8188388ad5cdd481b02298ff29827791 |
||
26 | </pre> |
||
27 | |||
28 | h3. Generating the actual quintuple using @osmo-auc-gen@ |
||
29 | |||
30 | This process mimics what is happening inside the Authentication Centre part of the HLR/HSS of your 2G/3G/4G network: Deriving RES from K, OP/OPc and SEQ/SQN. |
||
31 | |||
32 | We use the card-specific K + OPc values we received from the card manufacturer, as well as the random value we generated in the previous step |
||
33 | |||
34 | <pre> |
||
35 | $ osmo-auc-gen --3g --algorithm MILENAGE --key 77291F1E17132ADD86DC23A3AF601C89 --opc 831AFD01EF48692EC6FD18AEAB6CF381 --rand 8188388ad5cdd481b02298ff29827791 |
||
36 | osmo-auc-gen (C) 2011-2012 by Harald Welte |
||
37 | This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY |
||
38 | |||
39 | RAND: 8188388ad5cdd481b02298ff29827791 |
||
40 | AUTN: 7f62c464f6d60000b77b88e0f6b9449c |
||
41 | IK: 43c7bc1e8e193ed2e0e7e164126bbed5 |
||
42 | CK: a0188b5f7724878b86b9a336d8f2e327 |
||
43 | RES: b4013d66d107a2b6 |
||
44 | IMS nonce: gYg4itXN1IGwIpj/KYJ3kX9ixGT21gAAt3uI4Pa5RJw= |
||
45 | IMS res: tAE9ZtEHorY= |
||
46 | SRES: 65069fd0 |
||
47 | Kc: 8581751333a4e4ab |
||
48 | SQN: 32 |
||
49 | IND: 0 |
||
50 | </pre> |
||
51 | |||
52 | This shows us the following information |
||
53 | * input data (RAND, IND, SQN) |
||
54 | * the challenge the network would send via radio interface to the UE/phone/modem (RAND, AUTN) |
||
55 | * the data the network keeps on the network side and does *not* send over radio: |
||
56 | ** the A3 authentication result value (RES) |
||
57 | ** the A8 generated keys for integrity protection and ciphering (IK, CK) |
||
58 | ** the derived GSM values in case of fall-back to 2G (Kc, SRES) |
||
59 | |||
60 | h3. Performing authentication with the card, using @pySim-shell@ |
||
61 | |||
62 | We now perform what the phone/modem does with the SIM card when it receives the RAND + AUTN values from the cellular network via a @AUTHENTICATION REQUEST@. |
||
63 | |||
64 | 2 | laforge | For this, we use [[pysim:]], specifically the @authentication@ command in it. It takes two parameters: @rand@ and @autn@ (copy+pated from the above execution of osmo-auc-gen) |
65 | 1 | laforge | |
66 | As we want to do UMTS-AKA against the USIM application on the card, we must first select @ADF.USIM@. |
||
67 | |||
68 | <pre> |
||
69 | $ ./pySim-shell.py -p0 |
||
70 | Using PC/SC reader interface |
||
71 | Waiting for card... |
||
72 | Autodetected card type: sysmoISIM-SJA2 |
||
73 | Info: Card is of type: UICC-SIM |
||
74 | AIDs on card: |
||
75 | USIM: a0000000871002ffffffff8907090000 (EF.DIR) |
||
76 | ISIM: a0000000871004ffffffff8907090000 (EF.DIR) |
||
77 | ADF.ISD: a000000003000000 |
||
78 | ARA-M: a00000015141434c00 |
||
79 | Detected CardModel: SysmocomSJA2 |
||
80 | Welcome to pySim-shell! |
||
81 | pySIM-shell (MF)> select ADF.USIM |
||
82 | pySIM-shell (MF/ADF.USIM)> authenticate 8188388ad5cdd481b02298ff29827791 7f62c464f6d60000b77b88e0f6b9449c |
||
83 | { |
||
84 | "successful_3g_authentication": { |
||
85 | "res": "b4013d66d107a2b6", |
||
86 | "ck": "a0188b5f7724878b86b9a336d8f2e327", |
||
87 | "ik": "43c7bc1e8e193ed2e0e7e164126bbed5", |
||
88 | "kc": "8581751333a4e4ab" |
||
89 | } |
||
90 | } |
||
91 | </pre> |
||
92 | |||
93 | In this successful case, we see the card has accepted the AUTN nonce and generated the following output parameters: |
||
94 | * authentication result (RES); would be sent back to the network, where the network compares it with the expected RES value it has computed earlier. If it matches, authentication is OK. |
||
95 | * integrity protection (IK) and ciphering (CK) keys |
||
96 | ** used for air interface protection on 3G/UMTS after a @CIPHERING MODE COMMAND |
||
97 | ** used in derived forms for air interface protection and NAS protection in 4G/LTE |
||
98 | * GSM ciphering key (Kc); used for encryption on 2G/GSM/GPRS after a @CIPHERING MODE COMMAND@ |
||
99 | 3 | laforge | |
100 | h4. Unsuccessful case (re-synchronization) |
||
101 | |||
102 | If the SQN/SEQ number on the card and on the network (HSS/HLR) side don't match, the card will refuse authentication and return an @AUTS@ value for re-synchronization. |
||
103 | |||
104 | If this happens with pySim-shell, it will look like below: |
||
105 | <pre> |
||
106 | pySIM-shell (MF/ADF.USIM)> authenticate 8188388ad5cdd481b02298ff29827791 7f62c464f6d60000b77b88e0f6b9449c |
||
107 | { |
||
108 | "synchronisation_failure": { |
||
109 | "auts": "3156b88af1197c4611e142d75ef0" |
||
110 | } |
||
111 | } |
||
112 | </pre> |
||
113 | |||
114 | You must then go back to @osmo-auc-gen@ and re-execute it using the same @rand@ value, but in addition specifying @auts@ |
||
115 | |||
116 | <pre> |
||
117 | $ osmo-auc-gen --3g --algorithm MILENAGE --key 77291F1E17132ADD86DC23A3AF601C89 --opc 831AFD01EF48692EC6FD18AEAB6CF381 --rand 8188388ad5cdd481b02298ff29827791 --auts 3156b88af1197c4611e142d75ef0 |
||
118 | osmo-auc-gen (C) 2011-2012 by Harald Welte |
||
119 | This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY |
||
120 | |||
121 | RAND: 8188388ad5cdd481b02298ff29827791 |
||
122 | AUTN: 7f62c464f6b60000dc15fe983df347ae |
||
123 | IK: 43c7bc1e8e193ed2e0e7e164126bbed5 |
||
124 | CK: a0188b5f7724878b86b9a336d8f2e327 |
||
125 | RES: b4013d66d107a2b6 |
||
126 | IMS nonce: gYg4itXN1IGwIpj/KYJ3kX9ixGT2tgAA3BX+mD3zR64= |
||
127 | IMS res: tAE9ZtEHorY= |
||
128 | SRES: 65069fd0 |
||
129 | Kc: 8581751333a4e4ab |
||
130 | SQN: 64 |
||
131 | IND: 0 |
||
132 | SQN.MS: 32 |
||
133 | </pre> |
||
134 | |||
135 | This will now generate you a new AUTN value for the same RAND. Use that again in pySim, and it will succeed again: |
||
136 | |||
137 | <pre> |
||
138 | pySIM-shell (MF/ADF.USIM)> authenticate 8188388ad5cdd481b02298ff29827791 7f62c464f6b60000dc15fe983df347ae |
||
139 | { |
||
140 | "successful_3g_authentication": { |
||
141 | "res": "b4013d66d107a2b6", |
||
142 | "ck": "a0188b5f7724878b86b9a336d8f2e327", |
||
143 | "ik": "43c7bc1e8e193ed2e0e7e164126bbed5", |
||
144 | "kc": "8581751333a4e4ab" |
||
145 | } |
||
146 | } |
||
147 | </pre> |
||
148 | |||
149 | |||
150 | h4. Unsuccessful case (MAC failure) |
||
151 | |||
152 | If you used the wrong K/OP/OPc key material on the network/osmo-auc-gen side, then the card will report a MAC failure: |
||
153 | |||
154 | <pre> |
||
155 | pySIM-shell (MF/ADF.USIM)> authenticate 7188388ad5cdd481b02298ff29827791 7f62c464f6b60000dc15fe983df347ae |
||
156 | EXCEPTION of type 'SwMatchError' occurred with message: 'SW match failed! Expected 9000 and got 9862: Security management - Authentication error, incorrect MAC' |
||
157 | </pre> |