Commit f363bd12 authored by Thomas Gambier's avatar Thomas Gambier 🚴🏼

Upgrade uicc to version 3.3

parent 80893308
program_uicc: program_uicc.c uicc.h milenage.h
g++ --std=c++11 -g3 -I. -Wall program_uicc.c -o program_uicc
program_uicc_pcsc: program_uicc.c uicc.h milenage.h
g++ --std=c++11 -g3 -DPCSC -I. -I/usr/include/PCSC -Wall program_uicc.c -L/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux -lccid -o program_uicc_pcsc
clean:
rm program_uicc program_uicc_pcsc
To compile
================
# make
For raw protocol reader
or
# make program_uicc_pcsc
For raw and pc/sc readers support
You may have to adapt Makefile to your directories for the libccid.so file and the PCSC include directory
The package, on debian style can be installed with
#apt install libccid
To use
===============
*** With raw reader, full options (set all values in the card)
# sudo program_uicc --port /dev/ttyUSB0 --adm 12345678 --iccid 89860061100000000123 --imsi 208920100001123 --isdn 00000$i --acc 0001 --key 6874736969202073796d4b2079650a73 --opc 504f20634f6320504f50206363500a4f -spn OpenCells --authenticate
*** If you use PC/SC reader
# apt install libpcsclite-dev
# LD_LIBRARY_PATH=/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux ./program_uicc_pcsc --port usb:08e6/3437 --adm 12345678 --iccid 89860061100000000123 --imsi 208920100001123 --isdn 00000$i --acc 0001 --key 6874736969202073796d4b2079650a73 --opc 504f20634f6320504f50206363500a4f -spn OpenCells --authenticate
The library path may change on your linux distrbution
*** The port value setting is:
For raw readers
If you have no other serial, it should be /dev/ttyUSB0 (default). Else, the tty number will be in "dmesg" command result for example
For PC/SC readers
#lsusb
You will recognize your reader like:
Bus 001 Device 011: ID 08e6:3437 Gemalto (was Gemplus) GemPC Twin SmartCard Reader
The --port value for this example is usb:08e6/3437 (note the ":" is replaced by "/" in libccid)
......@@ -31,6 +31,7 @@ struct uicc_vals {
string acc="";
string key="";
string spn="open cells";
string act="7c00";
string ust="866F1F1C231E0000400050";
int mncLen=2;
bool authenticate=false;
......@@ -38,10 +39,6 @@ struct uicc_vals {
string rand="";
};
#define sc(in, out) \
USIMcard.send_check( string( (char*)in +37 ,sizeof(in) -37), \
string( (char*)out+37 ,sizeof(out)-37) )
bool readSIMvalues(char *port) {
SIM SIMcard;
string ATR;
......@@ -62,7 +59,11 @@ int readUSIMvalues(char *port) {
Assert((ATR=USIMcard.open(port))!="", "Failed to open %s", port);
//dump_hex("ATR", ATR);
res=USIMcard.readFile("ICCID");
string iccid=to_hex(res[0], true);
string iccid="No iccid readable";
if (res.size() )
iccid=to_hex(res[0], true);
cout << "ICCID: " << iccid <<endl;
if (!luhn( iccid))
......@@ -71,9 +72,22 @@ int readUSIMvalues(char *port) {
USIMcard.openUSIM();
string imsi=USIMcard.readFile("IMSI")[0];
cout << "USIM IMSI: " << USIMcard.decodeIMSI(imsi) << endl;
res=USIMcard.readFile("PLMN selector with Access Technology");
//cout << "USIM PLMN selector: " << bcdToAscii(res[0]) <<endl;
// Show only the first isdn (might be several)
auto last=res[0].find_last_not_of(string(u8"\xff",1));
if (last!=std::string::npos)
dump_hex("PLMN selector: ", res[0].substr(0,last));
res=USIMcard.readFile("Operator controlled PLMN selector with Access Technology");
last=res[0].find_last_not_of(string(u8"\xff",1));
if (last!=std::string::npos)
dump_hex("Operator Control PLMN selector: ", res[0].substr(0,last));
res=USIMcard.readFile("Home PLMN selector with Access Technology");
last=res[0].find_last_not_of(string(u8"\xff",1));
if (last!=std::string::npos)
dump_hex("Home PLMN selector: ", res[0].substr(0,last));
string msisdn=USIMcard.readFile("MSISDN")[0];
cout << "USIM MSISDN: " << USIMcard.decodeISDN(msisdn) <<endl;
string spn=USIMcard.readFile("Service Provider Name")[0];
......@@ -213,9 +227,6 @@ bool writeSIMv2values(char *port, struct uicc_vals &values) {
card.encodeISDN("9" + values.isdn, card.fileRecordSize("MSISDN"))),
"can't set msisdn %s",values.isdn.c_str());
Assert(card.writeFile("SMSC",
makeBcdVect("FFFFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFF0191"),true),
"can't set SMS center");
//
// Set USIM values, from GSM APDU CLA, proprietary method but regular file names
//
......@@ -241,8 +252,7 @@ bool writeSIMv2values(char *port, struct uicc_vals &values) {
vector<string> VectMccMnc;
VectMccMnc.push_back(MccMnc);
vector<string> MccMncWithAct=VectMccMnc;
// Add EUTRAN access techno only
MccMncWithAct[0]+=string(u8"\x40\x00",2);
MccMncWithAct[0]+=makeBcd(values.act,false,2);
Assert(card.writeFile("USIM PLMN selector with Access Technology",
MccMncWithAct, true), "Can't write PLMN Selector");
Assert(card.writeFile("USIM Operator controlled PLMN selector with Access Technology",
......@@ -372,7 +382,8 @@ bool writeSIMvalues(char *port, struct uicc_vals &values) {
card.encodeISDN(values.isdn, card.fileRecordSize("MSISDN"))),
"can't set msisdn %s",values.isdn.c_str());
Assert(card.writeFile("SMSC", makeBcdVect(""),true), "can't set SMS center");
Assert(card.writeFile("Short Message Service Parameters", makeBcdVect("FFFFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFF 0191",true,40)),
"can't set SMSC");
return true;
}
......@@ -417,7 +428,7 @@ bool writeUSIMvalues(char *port, struct uicc_vals &values) {
ad[0]+=(char) values.mncLen;
Assert(card.writeFile("Administrative data", ad),
"can't set Administrative data");
Assert(card.writeFile("SMSC", makeBcdVect("",true,40)),
Assert(card.writeFile("Short Message Service Parameters", makeBcdVect("FFFFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFF 0191",true,40)),
"can't set SMSC");
if (values.isdn.size() > 0)
......@@ -436,8 +447,7 @@ bool writeUSIMvalues(char *port, struct uicc_vals &values) {
vector<string> VectMccMnc;
VectMccMnc.push_back(MccMnc);
vector<string> MccMncWithAct=VectMccMnc;
// Add EUTRAN access techno only
MccMncWithAct[0]+=string(u8"\x40\x00",2);
MccMncWithAct[0]+=makeBcd(values.act,false,2);
Assert(card.writeFile("PLMN selector with Access Technology",
MccMncWithAct, true), "Can't write PLMN Selector");
Assert(card.writeFile("Operator controlled PLMN selector with Access Technology",
......@@ -658,10 +668,11 @@ int main(int argc, char **argv) {
{"xx", required_argument, 0, 9},
{"authenticate", no_argument, 0, 10},
{"spn", required_argument, 0, 11},
{"noreadafter", no_argument, 0, 12},
{"ust", required_argument, 0, 13},
{"sqn", required_argument, 0, 14},
{"rand", required_argument, 0, 15},
{"act", required_argument, 0, 12},
{"noreadafter", no_argument, 0, 13},
{"ust", required_argument, 0, 14},
{"sqn", required_argument, 0, 15},
{"rand", required_argument, 0, 16},
{0, 0, 0, 0}
};
static map<string,string> help_text= {
......@@ -673,12 +684,13 @@ int main(int argc, char **argv) {
{"isdn", "The mobile phone number (not used in simple 4G)"},
{"acc", "One of the defined security codes"},
{"key", "The authentication key (called Ki in 3G/4G, Kc in GSM), must be the same in HSS"},
{"MNCsize","Mobile network code size in digits (default to 2)"},
{"MNCsize","Mobile network code size in digits (default 2)"},
{"xx", "OP field: OPerator code: must be also set in HSS (exclusive with OPc)"},
{"spn", "service provider name: the name that the UE will show as 'network'"},
{"spn", "service provider name: the name that the UE will show as 'network' (default \"open cells\")"},
{"act", "bitmap describing supported RAN technologies (default \"7c00\" see TS31.102 chap 4.2.5)"},
{"authenticate", "Test the milenage authentication and discover the current sequence number"},
{"noreadafter", "no read after write"},
{"ust", "usim service table in hexa decimal (first byte is services 1-8, so 81 enable service 1 and service 8 ...)"},
{"ust", "usim service table in hexa decimal (first byte is services 1-8,\n so 81 enable service 1 and service 8 ...)"},
{"sqn", "only for test, no UICC dialog, prints the generated AUTN for debugging"},
{"rand", "only for test, no UICC dialog, prints the generated AUTN for debugging"},
};
......@@ -745,18 +757,22 @@ int main(int argc, char **argv) {
break;
case 12:
readAfter=false;
new_vals.act=optarg;
break;
case 13:
new_vals.ust=optarg;
readAfter=false;
break;
case 14:
new_vals.sqn=optarg;
new_vals.ust=optarg;
break;
case 15:
new_vals.sqn=optarg;
break;
case 16:
new_vals.rand=optarg;
break;
......@@ -827,7 +843,7 @@ int main(int argc, char **argv) {
if ( new_vals.authenticate) {
if ( new_vals.opc.size() == 0 || new_vals.key.size() == 0)
printf("\nNeed the key (Ki) and the OPc to test Milenage and dispaly the SQN\n");
printf("\nNeed the key (Ki) and the OPc to test Milenage and display the SQN\n");
else
authenticate(portName, new_vals);
}
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment