aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Prestwood <james.prestwood@linux.intel.com>2017-10-20 11:22:28 -0700
committerDenis Kenzior <denkenz@gmail.com>2017-10-20 14:07:19 -0500
commitba183294afa32d67b077b7d8cf343ea623798fed (patch)
tree64055a4b3a12069fd811a46fb0a3ec7a4a671de2
parent3733502581d45bbcb847c6d3e6e909e52a267448 (diff)
downloadphonesim-ba183294afa32d67b077b7d8cf343ea623798fed.tar.gz
simauth: Update simauth to handle AUTS parameter
The support for an invalid SQN number was incomplete in the simauth module. The SIM should have an internal SQN stored (default.xml now) and verify that the SQN in AUTN matches. If not, then generate AUTS and send that back.
-rw-r--r--src/default.xml2
-rw-r--r--src/simauth.cpp77
-rw-r--r--src/simauth.h3
3 files changed, 61 insertions, 21 deletions
diff --git a/src/default.xml b/src/default.xml
index c70b907..39b0216 100644
--- a/src/default.xml
+++ b/src/default.xml
@@ -315,7 +315,7 @@
<set name="SIMSTATE" value="1" />
<!-- SIM Auth -->
-<simauth ki="90dca4eda45b53cf0f12d7c9c3bc6a89" opc="cb9cccc4b9258e6dca4760379fb82581">
+<simauth ki="90dca4eda45b53cf0f12d7c9c3bc6a89" opc="cb9cccc4b9258e6dca4760379fb82581" sqn="000000000021">
<aid>61184F10A0000000871004FFFFFFFF890619000050044953494DFFFFFFFFFFFFFF</aid>
<aid>61184F10A0000000871002FFFFFFFF890619000050045553494DFFFFFFFFFFFFFF</aid>
</simauth>
diff --git a/src/simauth.cpp b/src/simauth.cpp
index ce8263d..54184b6 100644
--- a/src/simauth.cpp
+++ b/src/simauth.cpp
@@ -34,6 +34,7 @@ SimAuth::SimAuth( QObject *parent, SimXmlNode& n )
_ki = n.getAttribute( "ki" );
_opc = n.getAttribute( "opc" );
+ _sqn = n.getAttribute( "sqn" );
_session_start = 257;
_aid_list = QStringList();
@@ -164,7 +165,7 @@ bool SimAuth::command( const QString& cmd )
break;
case UMTS_SYNC_FAILURE:
- response == QString( "34,\"DC10 %1 \"\n\nOK" ).arg( auts );
+ response += QString( "34,\"DC0E %1 \"\n\nOK" ).arg( auts );
response.replace( " ", "" );
break;
@@ -309,10 +310,11 @@ enum UmtsStatus SimAuth::umtsAuthenticate( QString rand, QString autn,
{
int i;
- uint8_t *ki = QSTRING_TO_BUF( _ki );
- uint8_t *_rand = QSTRING_TO_BUF( rand );
- uint8_t *_autn = QSTRING_TO_BUF( autn );
- uint8_t *opc = QSTRING_TO_BUF( _opc );
+ uint8_t ki[16];
+ uint8_t _rand[16];
+ uint8_t _autn[16];
+ uint8_t opc[16];
+ uint8_t sqn_stored[6];
uint8_t ak[6];
uint8_t sqn[6];
@@ -321,14 +323,22 @@ enum UmtsStatus SimAuth::umtsAuthenticate( QString rand, QString autn,
uint8_t _res[8];
uint8_t _ck[16];
uint8_t _ik[16];
+ uint8_t _auts[14];
uint8_t temp[16];
uint8_t out1[16];
uint8_t out2[16];
+ uint8_t out5[16];
uint8_t in1[16];
uint8_t tmp1[16];
uint8_t tmp2[16];
+ memcpy(ki, QSTRING_TO_BUF( _ki ), 16);
+ memcpy(_rand, QSTRING_TO_BUF( rand ), 16);
+ memcpy(_autn, QSTRING_TO_BUF( autn ), 16);
+ memcpy(opc, QSTRING_TO_BUF( _opc ), 16);
+ memcpy(sqn_stored, QSTRING_TO_BUF( _sqn ), 6);
+
// copy out AMF/MAC from AUTN
memcpy(amf, _autn + 6, 2);
memcpy(mac, _autn + 8, 8);
@@ -359,6 +369,46 @@ enum UmtsStatus SimAuth::umtsAuthenticate( QString rand, QString autn,
memcpy(in1 + 8, sqn, 6);
memcpy(in1 + 14, amf, 2);
+ // check if SQNs match
+ if (memcmp(sqn, sqn_stored, 6)) {
+ /*
+ * f5* outputs AK' (OUT5)
+ */
+ for (i = 0; i < 16; i++)
+ tmp1[(i + 4) % 16] = temp[i] ^ opc[i];
+
+ /* tmp1 ^ c5. c5 at bit 124 == 1 */
+ tmp1[15] ^= 1 << 3;
+ aes_encrypt(ki, 16, tmp1, out5, 16);
+ /* out5 ^ opc */
+ XOR(out5, out5, opc, 16);
+
+ XOR(_auts, sqn_stored, out5, 6);
+
+ /* run f1 with zero'd AMF to finish AUTS */
+ in1[6] = 0x00;
+ in1[7] = 0x00;
+ in1[14] = 0x00;
+ in1[15] = 0x00;
+
+ for (i = 0; i < 16; i++)
+ tmp1[(i + 8) % 16] = in1[i] ^ opc[i];
+
+ /* tmp2 = TEMP ^ tmp1 */
+ XOR(tmp2, temp, tmp1, 16);
+ /* tmp2 = E[tmp2]k */
+ aes_encrypt(ki, 16, tmp2, tmp1, 16);
+
+ /* out1 = OUT1 = tmp1 ^ opc */
+ XOR(out1, tmp1, opc, 16);
+
+ memcpy(_auts + 6, out1 + 8, 8);
+
+ auts = QByteArray( (const char *)_auts, 14 ).toHex();
+
+ return UMTS_SYNC_FAILURE;
+ }
+
for (i = 0; i < 16; i++)
tmp1[(i + 8) % 16] = in1[i] ^ opc[i];
@@ -369,22 +419,9 @@ enum UmtsStatus SimAuth::umtsAuthenticate( QString rand, QString autn,
/* out1 = OUT1 = tmp1 ^ opc */
XOR(out1, tmp1, opc, 16);
- if (memcmp(_autn + 8, out1, 8)) {
- // f5* algorithm
- // rot(TEMP ^ OPC, r5)
- for (i = 0; i < 16; i++)
- tmp1[(i + 4) % 16] = temp[i] ^ opc[i];
-
- // XOR with c5
- tmp1[15] ^= 1 << 3;
- aes_encrypt(ki, 16, tmp1, tmp1, 16);
- // XOR with OPc
- XOR(tmp1, opc, tmp1, 16);
-
- auts = QByteArray( (const char *)tmp1, 16 ).toHex();
-
+ // verify MAC-A matches AUTN
+ if (memcmp(_autn + 8, out1, 8))
return UMTS_INVALID_MAC;
- }
// f3 algorithm
for (i = 0; i < 16; i++)
diff --git a/src/simauth.h b/src/simauth.h
index eb733f6..a66ea52 100644
--- a/src/simauth.h
+++ b/src/simauth.h
@@ -70,6 +70,9 @@ private:
// operator variant algorithm configuration field
QString _opc;
+ // Sequence number stored on SIM
+ QString _sqn;
+
// arbitrary session ID starting number
int _session_start;