Skip to content

Commit

Permalink
Add possibility to set/get NAD on T=1 for MEP
Browse files Browse the repository at this point in the history
MEP is Multiple Enabled Profiles and allows to have more than one SIM
profile in an eSIM.
See https://source.android.com/docs/core/connect/esim-mep

This API is NOT a standard but a Thales implementation.

dwControlCode with value set to SCARD_CTL_CODE(3600) allows to set/get
NAD value using SCardControl().

pbSendBuffer can take two TLV commands:

Set_T1_Logical_Interface_Number
3E 00 01 NN: Set NAD value command.
with
 3E = tag
 00 01 = length
 NN = NAD value
Responde is: 3E 00 01 SS
with
 3E = tag
 00 01 = length
 SS = status
 - 0x00: Status OK
 - 0x01: Status KO

Get_T1_Logical_Interface_Number
3F 00 00: Get current NAD value command.
with
 3F = tag
 00 00 = length
Response is: 3F 00 02 SS NN
with
 3F = tag
 00 02 = length
 SS = status
 - 0x00: Status OK
 - 0x01: Status KO
 NN = NAD
  • Loading branch information
rzaiti authored and LudovicRousseau committed May 25, 2024
1 parent b2b0c07 commit 2364929
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -2288,7 +2288,8 @@ static RESPONSECODE CmdXfrBlockTPDU_T1(unsigned int reader_index,

DEBUG_COMM3("T=1: %d and %d bytes", tx_length, *rx_length);

ret = t1_transceive(&((get_ccid_slot(reader_index)) -> t1), 0,
ret = t1_transceive(&((get_ccid_slot(reader_index)) -> t1),
get_ccid_slot(reader_index) -> t1.nad,
tx_buffer, tx_length, rx_buffer, *rx_length);

if (ret < 0)
Expand Down
56 changes: 56 additions & 0 deletions src/ifdhandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,62 @@ EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode,
}
}

/* Multiple Enabled Profiles (MEP)
* https://source.android.com/docs/core/connect/esim-mep */
if (SCARD_CTL_CODE(3600) == dwControlCode)
{
DEBUG_INFO1("Control command for MEP");

/* Set T=1 NAD */
if (TxLength == 4
&& (TxBuffer[0] == 0x3E)
&& (TxBuffer[1] == 0x00)
&& (TxBuffer[2] == 0x01))
{
RxBuffer[0] = 0x3E;
RxBuffer[1] = 0x00;
RxBuffer[2] = 0x01;
DEBUG_INFO1("Set NAD value");
if (t1_set_param(&CcidSlots[reader_index].t1, IFD_PROTOCOL_T1_NAD,
TxBuffer[3]))
/* error */
RxBuffer[3] = 0x01;
else
RxBuffer[3] = 0x00;
*pdwBytesReturned = 4;
return_value = IFD_SUCCESS;
}

/* Get T=1 NAD */
if (TxLength == 3
&& (TxBuffer[0] == 0x3F)
&& (TxBuffer[1] == 0x00)
&& (TxBuffer[2] == 0x00))
{
int value = 0;

RxBuffer[0] = 0x3F;
RxBuffer[1] = 0x00;
RxBuffer[2] = 0x02;
DEBUG_INFO1("Get NAD value");
value = t1_get_param(&CcidSlots[reader_index].t1,
IFD_PROTOCOL_T1_NAD);
if (-1 == value)
{
/* error */
RxBuffer[3] = 0x01;
RxBuffer[4] = 0x00;
}
else
{
RxBuffer[3] = 0x00;
RxBuffer[4] = value;
}
*pdwBytesReturned = 5;
return_value = IFD_SUCCESS;
}
}

if (IFD_SUCCESS != return_value)
*pdwBytesReturned = 0;

Expand Down
21 changes: 21 additions & 0 deletions src/openct/proto-t1.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ int t1_init(t1_state_t * t1, int lun)
t1_set_param(t1, IFD_PROTOCOL_T1_CHECKSUM_LRC, 0);
t1_set_param(t1, IFD_PROTOCOL_T1_STATE, SENDING);
t1_set_param(t1, IFD_PROTOCOL_T1_MORE, false);
t1_set_param(t1, IFD_PROTOCOL_T1_NAD, 0);

t1->lun = lun;

Expand Down Expand Up @@ -136,6 +137,9 @@ int t1_set_param(t1_state_t * t1, int type, long value)
case IFD_PROTOCOL_T1_MORE:
t1->more = value;
break;
case IFD_PROTOCOL_T1_NAD:
t1->nad = value;
break;
default:
DEBUG_INFO2("Unsupported parameter %d", type);
return -1;
Expand All @@ -144,6 +148,23 @@ int t1_set_param(t1_state_t * t1, int type, long value)
return 0;
}

int t1_get_param(t1_state_t * t1, int type)
{
int value = -1;

switch (type)
{
case IFD_PROTOCOL_T1_NAD:
value = t1->nad;
break;

default:
DEBUG_INFO2("Unsupported parameter %d", type);
}

return value;
}

/*
* Send an APDU through T=1
*/
Expand Down
6 changes: 5 additions & 1 deletion src/openct/proto-t1.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ enum {
IFD_PROTOCOL_T1_IFSC,
IFD_PROTOCOL_T1_IFSD,
IFD_PROTOCOL_T1_STATE,
IFD_PROTOCOL_T1_MORE
IFD_PROTOCOL_T1_MORE,
IFD_PROTOCOL_T1_NAD
};

#define T1_BUFFER_SIZE (3 + 254 + 2)
Expand All @@ -58,6 +59,8 @@ typedef struct {
unsigned int ifsc;
unsigned int ifsd;

unsigned int nad;

unsigned char wtx;
unsigned int retries;
unsigned int rc_bytes;
Expand All @@ -74,6 +77,7 @@ int t1_transceive(t1_state_t *t1, unsigned int dad,
int t1_init(t1_state_t *t1, int lun);
void t1_release(t1_state_t *t1);
int t1_set_param(t1_state_t *t1, int type, long value);
int t1_get_param(t1_state_t *t1, int type);
int t1_negotiate_ifsd(t1_state_t *t1, unsigned int dad, int ifsd);
unsigned int t1_build(t1_state_t *, unsigned char *,
unsigned char, unsigned char, ct_buf_t *, size_t *);
Expand Down

0 comments on commit 2364929

Please sign in to comment.