Multiprotocol tag support & new SCARD_ATTR added

This commit is contained in:
HariomKesh 2016-12-20 07:38:32 +05:30 коммит произвёл Ivan Cherniukh
Родитель a057446367
Коммит 5267a218eb
7 изменённых файлов: 716 добавлений и 50 удалений

Просмотреть файл

@ -145,56 +145,78 @@ NfcCxRFInterfaceClearRemoteDevList(
_Inout_ PNFCCX_RF_INTERFACE RFInterface
)
{
if (RFInterface->pLibNfcContext->pRemDevList != NULL) {
if (RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo != NULL) {
if ((RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_A_PCD) ||
(RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_B_PCD)) {
if (RFInterface->pLibNfcContext->pRemDevList != NULL)
{
for (uint8_t bIndex = 0; bIndex < RFInterface->pLibNfcContext->uNoRemoteDevices; bIndex++)
{
if (RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo != NULL)
{
if ((RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_A_PCD) ||
(RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_B_PCD))
{
RFInterface->pLibNfcContext->bIsHCEConnected = FALSE;
}
free(RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo);
RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo = NULL;
free(RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo);
RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo = NULL;
}
}
free(RFInterface->pLibNfcContext->pRemDevList);
RFInterface->pLibNfcContext->pRemDevList = NULL;
}
}
NTSTATUS FORCEINLINE
NfcCxRFInterfaceSetRemoteDevList(
_Inout_ PNFCCX_RF_INTERFACE RFInterface,
_In_ phLibNfc_RemoteDevList_t *psRemoteDevList
_In_ phLibNfc_RemoteDevList_t *psRemoteDevList,
_In_ uint8_t uNofRemoteDev
)
{
NTSTATUS status = STATUS_SUCCESS;
RFInterface->pLibNfcContext->SelectedProtocolIndex = 0;
NfcCxRFInterfaceClearRemoteDevList(RFInterface);
RFInterface->pLibNfcContext->pRemDevList = (phLibNfc_RemoteDevList_t*) malloc(sizeof(phLibNfc_RemoteDevList_t));
if (RFInterface->pLibNfcContext->pRemDevList != NULL) {
RFInterface->pLibNfcContext->pRemDevList->hTargetDev = psRemoteDevList->hTargetDev;
RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo =
RFInterface->pLibNfcContext->uNoRemoteDevices = uNofRemoteDev;
RFInterface->pLibNfcContext->pRemDevList = (phLibNfc_RemoteDevList_t*)malloc(sizeof(phLibNfc_RemoteDevList_t) * uNofRemoteDev);
if (RFInterface->pLibNfcContext->pRemDevList != NULL)
{
for (uint8_t bIndex = 0; bIndex < uNofRemoteDev; bIndex++)
{
RFInterface->pLibNfcContext->pRemDevList[bIndex].hTargetDev = psRemoteDevList[bIndex].hTargetDev;
RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo =
(phLibNfc_sRemoteDevInformation_t*)malloc(sizeof(phLibNfc_sRemoteDevInformation_t));
if (RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo != NULL) {
RtlCopyMemory(RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo,
psRemoteDevList->psRemoteDevInfo, sizeof(phLibNfc_sRemoteDevInformation_t));
if (RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo != NULL)
{
RtlCopyMemory(RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo,
psRemoteDevList[bIndex].psRemoteDevInfo, sizeof(phLibNfc_sRemoteDevInformation_t));
if ((RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_A_PCD) ||
(RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_B_PCD)) {
if ((RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_A_PCD) ||
(RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo->RemDevType == phLibNfc_eISO14443_B_PCD))
{
RFInterface->pLibNfcContext->bIsHCEConnected = TRUE;
}
}
else {
else
{
status = STATUS_INSUFFICIENT_RESOURCES;
NfcCxRFInterfaceClearRemoteDevList(RFInterface);
break;
}
}
else {
}
else
{
status = STATUS_INSUFFICIENT_RESOURCES;
NfcCxRFInterfaceClearRemoteDevList(RFInterface);
RFInterface->pLibNfcContext->pRemDevList = NULL;
}
return status;
}
@ -1262,6 +1284,89 @@ Done:
return status;
}
NTSTATUS
NfcCxRFInterfaceTargetDeactivate(
_In_ PNFCCX_RF_INTERFACE RFInterface
)
/*++
Routine Description:
This routine is called from the SC module to
reactivate a tag.
Arguments:
RFInterface - The RF Interface
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
WdfWaitLockAcquire(RFInterface->DeviceLock, NULL);
ResetEvent(RFInterface->hStartPresenceCheck);
status = NfcCxRFInterfaceExecute(RFInterface, LIBNFC_TARGET_DEACTIVATE_SLEEP, NULL, NULL);
if (!NT_SUCCESS(status)) {
TRACE_LINE(LEVEL_ERROR, "Target deactivation failed, %!STATUS!", status);
SetEvent(RFInterface->hStartPresenceCheck);
goto Done;
}
Done:
WdfWaitLockRelease(RFInterface->DeviceLock);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
NTSTATUS
NfcCxRFInterfaceTargetActivate(
_In_ PNFCCX_RF_INTERFACE RFInterface
)
/*++
Routine Description:
This routine is called from the SC module to
reactivate a tag.
Arguments:
RFInterface - The RF Interface
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
WdfWaitLockAcquire(RFInterface->DeviceLock, NULL);
status = NfcCxRFInterfaceExecute(RFInterface, LIBNFC_TARGET_ACTIVATE, NULL, NULL);
if (!NT_SUCCESS(status)) {
TRACE_LINE(LEVEL_ERROR, "Target Activation failed, %!STATUS!", status);
}
SetEvent(RFInterface->hStartPresenceCheck);
WdfWaitLockRelease(RFInterface->DeviceLock);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
NTSTATUS
NfcCxRFInterfaceTargetCheckPresence(
_In_ PNFCCX_RF_INTERFACE RFInterface
@ -1671,7 +1776,7 @@ NfcCxRFInterfaceTagConnectionEstablished(
RFInterface->pLibNfcContext->bIsTagConnected = TRUE;
NfcCxNfpInterfaceHandleTagConnectionEstablished(NfcCxRFInterfaceGetNfpInterface(RFInterface), ArrivalBitMask);
NfcCxSCInterfaceHandleSmartCardConnectionEstablished(NfcCxRFInterfaceGetScInterface(RFInterface),
RFInterface->pLibNfcContext->pRemDevList->psRemoteDevInfo);
RFInterface);
}
TRACE_FUNCTION_EXIT(LEVEL_VERBOSE);
@ -2237,12 +2342,22 @@ NfcCxRFInterfaceRemoteDevConnect(
LibNfcContext.RFInterface = RFInterface;
LibNfcContext.Sequence = RFInterface->pSeqHandler;
nfcStatus = phLibNfc_RemoteDev_Connect(RFInterface->pLibNfcContext->pRemDevList[0].hTargetDev,
nfcStatus = phLibNfc_RemoteDev_Connect(RFInterface->pLibNfcContext->pRemDevList[RFInterface->pLibNfcContext->SelectedProtocolIndex].hTargetDev,
NfcCxRFInterfaceRemoteDevConnectCB,
&LibNfcContext);
Status = NfcCxNtStatusFromNfcStatus(nfcStatus);
if (NT_SUCCESS(Status))
{
TRACE_LINE(LEVEL_INFO, "Set Target Activation To %x", RFInterface->pLibNfcContext->SelectedProtocolIndex);
}
else
{
TRACE_LINE(LEVEL_INFO, "Set Target Activation Failed for Index %x", RFInterface->pLibNfcContext->SelectedProtocolIndex);
}
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, Status);
return Status;
}
@ -2283,7 +2398,7 @@ NfcCxRFInterfaceRemoteDevDisconnect(
LibNfcContext.RFInterface = RFInterface;
LibNfcContext.Sequence = RFInterface->pSeqHandler;
nfcStatus = phLibNfc_RemoteDev_Disconnect(RFInterface->pLibNfcContext->pRemDevList->hTargetDev,
nfcStatus = phLibNfc_RemoteDev_Disconnect(RFInterface->pLibNfcContext->pRemDevList[RFInterface->pLibNfcContext->SelectedProtocolIndex].hTargetDev,
RFInterface->pLibNfcContext->eReleaseType,
NfcCxRFInterfaceRemoteDevDisconnectCB,
&LibNfcContext);
@ -2292,6 +2407,15 @@ NfcCxRFInterfaceRemoteDevDisconnect(
nfcStatus = NFCSTATUS_SUCCESS;
}
if (NT_SUCCESS(Status))
{
TRACE_LINE(LEVEL_INFO, "Set Target DeActivation To %x", RFInterface->pLibNfcContext->SelectedProtocolIndex);
}
else
{
TRACE_LINE(LEVEL_INFO, "Set Target DeActivation Failed for Index %x", RFInterface->pLibNfcContext->SelectedProtocolIndex);
}
Status = NfcCxNtStatusFromNfcStatus(nfcStatus);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, Status);
@ -2835,8 +2959,13 @@ NfcCxRFInterfaceTargetTransceive(
NFCSTATUS nfcStatus = NFCSTATUS_SUCCESS;
phLibNfc_RemoteDevList_t* pRemDevList = RFInterface->pLibNfcContext->pRemDevList;
static NFCCX_RF_LIBNFC_REQUEST_CONTEXT LibNfcContext;
DWORD SelectedProtocol = 0;
switch (pRemDevList->psRemoteDevInfo->RemDevType)
SelectedProtocol = RFInterface->pLibNfcContext->SelectedProtocolIndex;
TRACE_LINE(LEVEL_INFO, "SelectedProtocol is = %x", SelectedProtocol);
switch (pRemDevList[SelectedProtocol].psRemoteDevInfo->RemDevType)
{
case phLibNfc_eISO14443_4A_PICC:
case phLibNfc_eISO14443_4B_PICC:
@ -2892,7 +3021,7 @@ NfcCxRFInterfaceTargetTransceive(
LibNfcContext.RFInterface = RFInterface;
LibNfcContext.Sequence = RFInterface->pSeqHandler;
nfcStatus = phLibNfc_RemoteDev_Transceive(pRemDevList->hTargetDev,
nfcStatus = phLibNfc_RemoteDev_Transceive(RFInterface->pLibNfcContext->pRemDevList[SelectedProtocol].hTargetDev,
&RFInterface->sTransceiveBuffer,
NfcCxRFInterfaceTargetTransceiveCB,
&LibNfcContext);
@ -2935,7 +3064,7 @@ NfcCxRFInterfaceTargetPresenceCheck(
LibNfcContext.RFInterface = RFInterface;
LibNfcContext.Sequence = RFInterface->pSeqHandler;
nfcStatus = phLibNfc_RemoteDev_CheckPresence(RFInterface->pLibNfcContext->pRemDevList->hTargetDev,
nfcStatus = phLibNfc_RemoteDev_CheckPresence(RFInterface->pLibNfcContext->pRemDevList[RFInterface->pLibNfcContext->SelectedProtocolIndex].hTargetDev,
NfcCxRFInterfaceTargetPresenceCheckCB,
&LibNfcContext);
@ -2945,6 +3074,7 @@ NfcCxRFInterfaceTargetPresenceCheck(
return Status;
}
NTSTATUS
NfcCxRFInterfaceSENtfRegister(
_In_ PNFCCX_RF_INTERFACE RFInterface,
@ -3388,7 +3518,7 @@ NfcCxRFInterfaceRemoteDevNtfCB(
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TraceLoggingValue((DWORD)(psRemoteDev->psRemoteDevInfo->RemDevType), "DeviceType"));
status = NfcCxRFInterfaceSetRemoteDevList(rfInterface, psRemoteDev);
status = NfcCxRFInterfaceSetRemoteDevList(rfInterface, psRemoteDev, uNofRemoteDev);
if (NT_SUCCESS(status)) {
NfcCxStateInterfaceStateHandler(NfcCxRFInterfaceGetStateInterface(rfInterface), NfcCxEventDiscovered, NULL, NULL, NULL);

Просмотреть файл

@ -69,6 +69,8 @@ typedef struct _NFCCX_LIBNFC_CONTEXT {
BOOLEAN bIsTagWriteAttempted;
BOOLEAN bIsTagReadOnlyAttempted;
BOOLEAN bIsP2PConnected;
uint8_t uNoRemoteDevices;
DWORD SelectedProtocolIndex;
phLibNfc_eReleaseType_t eReleaseType;
PNFCCX_STATE_INTERFACE StateInterface;
PNFCCX_LLCP_INTERFACE LLCPInterface;
@ -287,6 +289,16 @@ NfcCxRFInterfaceTargetReactivate(
_In_ PNFCCX_RF_INTERFACE RFInterface
);
NTSTATUS
NfcCxRFInterfaceTargetDeactivate(
_In_ PNFCCX_RF_INTERFACE RFInterface
);
NTSTATUS
NfcCxRFInterfaceTargetActivate(
_In_ PNFCCX_RF_INTERFACE RFInterface
);
NTSTATUS
NfcCxRFInterfaceGetSecureElementList(
_In_ PNFCCX_RF_INTERFACE RFInterface,

Просмотреть файл

@ -907,7 +907,7 @@ Done:
VOID
NfcCxSCInterfaceHandleSmartCardConnectionEstablished(
_In_ PNFCCX_SC_INTERFACE ScInterface,
_In_ phNfc_sRemoteDevInformation_t* pRemoteDeviceInfo
_In_ PNFCCX_RF_INTERFACE RFInterface
)
/*++
@ -927,9 +927,20 @@ Return Value:
--*/
{
NTSTATUS status = STATUS_SUCCESS;
DWORD DefaultProtocol = RFInterface->pLibNfcContext->SelectedProtocolIndex;
phNfc_sRemoteDevInformation_t* pRemoteDeviceInfo = NULL;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
WdfWaitLockAcquire(ScInterface->SmartCardLock, NULL);
ScInterface->SmartCardConnected = TRUE;
TRACE_LINE(LEVEL_INFO, "SmartCardConnectionEstablished!!!");
pRemoteDeviceInfo = RFInterface->pLibNfcContext->pRemDevList[DefaultProtocol].psRemoteDevInfo;
RtlCopyMemory(&ScInterface->RemoteDeviceInfo, pRemoteDeviceInfo, sizeof(phNfc_sRemoteDevInformation_t));
switch (pRemoteDeviceInfo->RemDevType)
{
case phLibNfc_eISO14443_4A_PICC:
@ -944,13 +955,6 @@ Return Value:
TRACE_LINE(LEVEL_WARNING, "Unsupported SmartCard type %!phNfc_eRFDevType_t!", pRemoteDeviceInfo->RemDevType);
goto Done;
}
TRACE_LINE(LEVEL_INFO, "SmartCardConnectionEstablished!!!");
WdfWaitLockAcquire(ScInterface->SmartCardLock, NULL);
ScInterface->SmartCardConnected = TRUE;
RtlCopyMemory(&ScInterface->RemoteDeviceInfo, pRemoteDeviceInfo, sizeof(phNfc_sRemoteDevInformation_t));
status = NfcCxSCInterfaceLoadStorageClassFromAtrLocked(ScInterface);
WdfWaitLockRelease(ScInterface->SmartCardLock);
@ -1098,8 +1102,9 @@ Return Value:
DWORD *pdwAttributeId = (DWORD*)InputBuffer;
size_t cbOutputBuffer = OutputBufferLength;
PNFCCX_SC_INTERFACE scInterface;
PNFCCX_FDO_CONTEXT fdoContext;
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(InputBufferLength);
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
@ -1109,9 +1114,23 @@ Return Value:
//
_Analysis_assume_(sizeof(BYTE) <= OutputBufferLength);
fdoContext = NfcCxFdoGetContext(Device);
scInterface = fdoContext->SCInterface;
scInterface = NfcCxFdoGetContext(Device)->SCInterface;
if ((*pdwAttributeId == SCARD_ATTR_VENDOR_SPECIFIC_BRAND_INFO) || (*pdwAttributeId == SCARD_ATTR_VENDOR_SPECIFIC_DEVICECAP_INFO))
{
if (NULL != fdoContext->NfcCxClientGlobal->Config.EvtNfcCxDeviceIoControl) {
fdoContext->NfcCxClientGlobal->Config.EvtNfcCxDeviceIoControl(fdoContext->Device,
Request,
OutputBufferLength,
InputBufferLength,
IOCTL_SMARTCARD_GET_ATTRIBUTE);
status = STATUS_PENDING;
goto Done;
}
}
for (USHORT TableEntry = 0; TableEntry < ARRAYSIZE(g_ScAttributeDispatch); TableEntry++) {
if (g_ScAttributeDispatch[TableEntry].dwAttributeId == *pdwAttributeId) {
@ -1144,7 +1163,7 @@ Return Value:
//
status = STATUS_PENDING;
}
Done:
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
TRACE_LOG_NTSTATUS_ON_FAILURE(status);
@ -1183,9 +1202,10 @@ Return Value:
{
NTSTATUS status = STATUS_NOT_SUPPORTED;
DWORD *pdwAttributeId = (DWORD*)InputBuffer;
PNFCCX_FDO_CONTEXT fdoContext;
UNREFERENCED_PARAMETER(Device);
UNREFERENCED_PARAMETER(Request);
UNREFERENCED_PARAMETER(InputBufferLength);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(OutputBufferLength);
@ -1197,10 +1217,27 @@ Return Value:
//
_Analysis_assume_(sizeof(DWORD) <= InputBufferLength);
fdoContext = NfcCxFdoGetContext(Device);
if (*pdwAttributeId == SCARD_ATTR_VENDOR_SPECIFIC_BRAND_INFO)
{
if (NULL != fdoContext->NfcCxClientGlobal->Config.EvtNfcCxDeviceIoControl) {
fdoContext->NfcCxClientGlobal->Config.EvtNfcCxDeviceIoControl(fdoContext->Device,
Request,
OutputBufferLength,
InputBufferLength,
IOCTL_SMARTCARD_SET_ATTRIBUTE);
status = STATUS_PENDING;
goto Done;
}
}
if (*pdwAttributeId == SCARD_ATTR_DEVICE_IN_USE) {
status = STATUS_SUCCESS;
}
Done:
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
TRACE_LOG_NTSTATUS_ON_FAILURE(status);
@ -1718,6 +1755,49 @@ Return Value:
cbOutputBufferUsed = cbResponseBuffer;
}
else if (NfcCxSCInterfaceValidateSwitchProtocolCommand((PBYTE)InputBuffer + sizeof(SCARD_IO_REQUEST),
cbInputBuffer - sizeof(SCARD_IO_REQUEST)) == TRUE){
BYTE Sw1Sw2[DEFAULT_APDU_STATUS_SIZE] = { 0x90,0x00 };
status = NfcCxSCInterfaceDeactivateMultiProtocolTag(scInterface);
if (NT_SUCCESS(status)){
WdfWaitLockAcquire(scInterface->SmartCardLock, NULL);
status = NfcCxSCInterfaceLoadNewSelectedProtocol(
scInterface,
(PBYTE)InputBuffer + sizeof(SCARD_IO_REQUEST),
cbInputBuffer - sizeof(SCARD_IO_REQUEST));
if (!NT_SUCCESS(status)) {
TRACE_LINE(LEVEL_ERROR, "Failed to Load new Select protocol, %!STATUS!", status);
}
//
// Irrespective of loaded index of selected protocol, tag activation is needed as tag
// Deactivation done before.
//
WdfWaitLockRelease(scInterface->SmartCardLock);
status = NfcCxSCInterfaceActivateMultiProtocolTag(scInterface);
if (!NT_SUCCESS(status)){
TRACE_LINE(LEVEL_ERROR, "Failed to Activate New protocol, %!STATUS!", status);
RtlCopyMemory(Sw1Sw2, APDU_STATUS_ERROR_COMMAND_ABORTED, DEFAULT_APDU_STATUS_SIZE);
}
} else {
TRACE_LINE(LEVEL_ERROR, "Failed to Deactivate current protocol, %!STATUS!", status);
RtlCopyMemory(Sw1Sw2, APDU_STATUS_ERROR_COMMAND_ABORTED, DEFAULT_APDU_STATUS_SIZE);
}
status = NfcCxSCInterfaceCopyResponseData(OutputBuffer,
cbOutputBuffer,
Sw1Sw2,
sizeof(Sw1Sw2),
&cbResponseBuffer);
if (!NT_SUCCESS(status)) {
TRACE_LINE(LEVEL_ERROR, "Failed to construct response buffer, %!STATUS!", status);
goto Done;
}
TRACE_LINE(LEVEL_ERROR, "smartcard resp 90 00 sending %d", cbResponseBuffer);
cbOutputBufferUsed = cbResponseBuffer;
}
else {
status = NfcCxSCInterfaceTransmitRequest(scInterface,
(PBYTE)InputBuffer + sizeof(SCARD_IO_REQUEST),
@ -2834,6 +2914,116 @@ Done:
return fLoadKey;
}
BOOL NfcCxSCInterfaceValidateSwitchProtocolCommand(
_In_bytecount_(InputBufferLength) PBYTE InputBuffer,
_In_ DWORD InputBufferLength
)
{
BOOL retval = FALSE;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
TRACE_LINE(LEVEL_INFO, "ValidateSwitchProtocolCommand Size = %x\n", InputBufferLength);
if (InputBufferLength < PCSC_SWITCH_PROTOCOL_APDU_SIZE)
{
TRACE_LINE(LEVEL_ERROR, "Invalid APDU buffer size");
goto Done;
}
else
{
PPcscCommandApduInfo cmdApdu = (PPcscCommandApduInfo)InputBuffer;
if ((PCSC_CLASS_BYTE == cmdApdu->Cla) &&
(PcscEnvelopeCmd == cmdApdu->Ins) &&
(PCSC_PARA1_SWITCH_BYTE == cmdApdu->P1) && ((PCSC_PARA2_SWITCH_BYTE == cmdApdu->P2)))
{
TRACE_LINE(LEVEL_INFO,"Command APDU is Switch Protocol \n");
retval = TRUE;
}
else
{
TRACE_LINE(LEVEL_INFO,"Command APDU is NOT Switch Protocol \n");
}
}
Done:
TRACE_LINE(LEVEL_INFO,"%s (OUT) (return %d) \n", __FUNCTION__, retval);
return retval;
}
NTSTATUS NfcCxSCInterfaceLoadNewSelectedProtocol(
_In_ PNFCCX_SC_INTERFACE ScInterface,
_In_bytecount_(InputBufferLength) PBYTE InputBuffer,
_In_ DWORD InputBufferLength
)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PcscSwitchProtocolAPDU SelProtocolApdu;
DWORD SelectedProtocol = 0;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
memcpy(&SelProtocolApdu, InputBuffer, InputBufferLength);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.pbCLA = %x\n", SelProtocolApdu.pbCLA);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.pbINS = %x\n", SelProtocolApdu.pbINS);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.pbP1 = %x\n", SelProtocolApdu.pbP1);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.pbP2 = %x\n", SelProtocolApdu.pbP2);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.pbLc = %x\n", SelProtocolApdu.pbLc);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.TlvMsg.Type = %x\n", SelProtocolApdu.PcscSwitchProtoData.Tag);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.TlvMsg.Length = %x\n", SelProtocolApdu.PcscSwitchProtoData.Length);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.TlvMsg.value[0]= %x\n", SelProtocolApdu.PcscSwitchProtoData.value[0]);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.TlvMsg.value[1]= %x\n", SelProtocolApdu.PcscSwitchProtoData.value[1]);
TRACE_LINE(LEVEL_INFO, "\n SelProtocolApdu.pbLe = %x\n", SelProtocolApdu.pbLe);
//Parse APDU and select the prefered protocol
if (((SelProtocolApdu.PcscSwitchProtoData.value[0] == PCSC_SWITCH_PROTOCOL_STD_TYPE) && (SelProtocolApdu.PcscSwitchProtoData.value[1] == PCSC_SELECT_PROTOCOL_MIFARE)) ||
((SelProtocolApdu.PcscSwitchProtoData.value[0] == PCSC_SWITCH_PROTOCOL_STD_TYPE) && (SelProtocolApdu.PcscSwitchProtoData.value[1] == PCSC_SELECT_PROTOCOL_ISO4A)))
{
if (PCSC_SELECT_PROTOCOL_ISO4A == SelProtocolApdu.PcscSwitchProtoData.value[1])
{
//Find 4A devinfo from the RemoteDeviceList return index
SelectedProtocol = NfcCxSCInterfaceGetIndexOfProtocolType(ScInterface->FdoContext->RFInterface, phNfc_eISO14443_4A_PICC);
if (PCSC_SWITCH_PROTOCOL_INDEX_NOT_FOUND != SelectedProtocol)
{
TRACE_LINE(LEVEL_INFO, "\n Selected protocol is 4A at index %d \n", SelectedProtocol);
status = STATUS_SUCCESS;
}
else
{
TRACE_LINE(LEVEL_INFO, "\n Selected protocol is 4A not found ");
goto Done;
}
}
if (PCSC_SELECT_PROTOCOL_MIFARE == SelProtocolApdu.PcscSwitchProtoData.value[1])
{
//Find mifare devinfo from the RemoteDeviceList return index
SelectedProtocol = NfcCxSCInterfaceGetIndexOfProtocolType(ScInterface->FdoContext->RFInterface, phNfc_eMifare_PICC);
if (PCSC_SWITCH_PROTOCOL_INDEX_NOT_FOUND != SelectedProtocol)
{
TRACE_LINE(LEVEL_INFO, "\n Selected protocol is Mifare at index %d \n", SelectedProtocol);
status = STATUS_SUCCESS;
}
else
{
TRACE_LINE(LEVEL_INFO, "\n Selected protocol is Mifare not found ");
goto Done;
}
}
ScInterface->FdoContext->RFInterface->pLibNfcContext->SelectedProtocolIndex = SelectedProtocol;
}
RtlCopyMemory(&ScInterface->RemoteDeviceInfo, ScInterface->FdoContext->RFInterface->pLibNfcContext->pRemDevList[SelectedProtocol].psRemoteDevInfo, sizeof(phNfc_sRemoteDevInformation_t));
NfcCxSCInterfaceLoadStorageClassFromAtrLocked(ScInterface);
Done:
TRACE_LINE(LEVEL_INFO, "%s (OUT) (return %d) \n", __FUNCTION__, status);
return status;
}
_Requires_lock_held_(ScInterface->SmartCardLock)
NTSTATUS
NfcCxSCInterfaceLoadKeyLocked(
@ -3669,3 +3859,136 @@ Routine Description:
return tck;
}
BOOLEAN
NfcCxSCInterfaceIsMultiProtocolTag(
_In_ PNFCCX_SC_INTERFACE ScInterface
)
/*++
Routine Description:
This routine checks wheather smart card tag is multiprotocol Tag
--*/
{
BOOLEAN fResult = FALSE;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
NT_ASSERT(ScInterface->SmartCardConnected);
if (ScInterface->FdoContext->RFInterface->pLibNfcContext != NULL)
{
if (ScInterface->FdoContext->RFInterface->pLibNfcContext->uNoRemoteDevices > 1)
{
fResult = TRUE;
}
}
TRACE_FUNCTION_EXIT(LEVEL_VERBOSE);
return fResult;
}
_Requires_lock_not_held_(ScInterface->SmartCardLock)
NTSTATUS
NfcCxSCInterfaceDeactivateMultiProtocolTag(
_In_ PNFCCX_SC_INTERFACE ScInterface
)
/*++
Routine Description:
This routine DeActivates the smart card
Arguments:
ScInterface - The SC Interface
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
TRACE_LINE(LEVEL_INFO, "Card DeactivateCommand Sent");
status = NfcCxRFInterfaceTargetDeactivate(ScInterface->FdoContext->RFInterface);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
_Requires_lock_not_held_(ScInterface->SmartCardLock)
NTSTATUS
NfcCxSCInterfaceActivateMultiProtocolTag(
_In_ PNFCCX_SC_INTERFACE ScInterface
)
/*++
Routine Description:
This routine Activates the smart card
Arguments:
ScInterface - The SC Interface
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
TRACE_LINE(LEVEL_INFO, "Card ActivateCommand Sent");
status = NfcCxRFInterfaceTargetActivate(ScInterface->FdoContext->RFInterface);
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
DWORD
NfcCxSCInterfaceGetIndexOfProtocolType(
_Inout_ PNFCCX_RF_INTERFACE RFInterface,
_In_ phNfc_eRemDevType_t RemDevType
)
{
DWORD bIndex = 0x00;
DWORD SelectedProtocolIndex = PCSC_SWITCH_PROTOCOL_INDEX_NOT_FOUND;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
if (RFInterface->pLibNfcContext->pRemDevList != NULL)
{
for (bIndex = 0; bIndex < RFInterface->pLibNfcContext->uNoRemoteDevices; bIndex++)
{
if (RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo != NULL)
{
if (RFInterface->pLibNfcContext->pRemDevList[bIndex].psRemoteDevInfo->RemDevType == RemDevType)
{
SelectedProtocolIndex = bIndex;
}
else
{
TRACE_LINE(LEVEL_ERROR, "Specified Protocol not found in the list");
}
}
}
}
TRACE_FUNCTION_EXIT(LEVEL_VERBOSE);
return SelectedProtocolIndex;
}

Просмотреть файл

@ -18,6 +18,10 @@ Environment:
#pragma once
// To be removed once these Attribute IDs are defined in winsmcrd.h
#define SCARD_ATTR_VENDOR_SPECIFIC_BRAND_INFO 0x0180
#define SCARD_ATTR_VENDOR_SPECIFIC_DEVICECAP_INFO 0x0181
#define HINIBBLE(b) ((BYTE)((b >> 4) & 0x0f))
#define LONIBBLE(b) ((BYTE)(b & 0x0f))
@ -28,6 +32,7 @@ Environment:
#define APDU_STATUS_ERROR_DATA_OBJECT_MISSING "\x69\x87"
#define APDU_STATUS_ERROR_INCORRECT_DATA_OBJECT "\x69\x88"
#define APDU_STATUS_ERROR_INVALID_OBJECT_LENGTH "\x69\x89"
#define APDU_STATUS_ERROR_COMMAND_ABORTED "\x6F\x00"
#define APDU_STATUS_SUCCESS "\x90\x00"
#define SAK_MIFARE_UL 0x00
@ -87,6 +92,14 @@ Environment:
#define MIFARE_UL_AUTHENTICATE_RESPONSE_BUFFER_SIZE 9
#define MIFARE_UL_AUTHENTICATE_RESPONSE_TIMEOUT 100
#define PCSC_SELECT_PROTOCOL_MIFARE 0x03
#define PCSC_SELECT_PROTOCOL_ISO4A 0x04
#define PCSC_SWITCH_PROTOCOL_TYPE 0X8F
#define PCSC_SWITCH_PROTOCOL_LENGTH 0X02
#define PCSC_SWITCH_PROTOCOL_STD_TYPE 0X00
#define PCSC_SWITCH_PROTOCOL_APDU_SIZE 0x09
#define PCSC_SWITCH_PROTOCOL_INDEX_NOT_FOUND 0xFF
typedef
NTSTATUS
NFCCX_SC_DISPATCH_HANDLER(
@ -154,6 +167,10 @@ typedef struct _NFCCX_SC_INTERFACE {
_Guarded_by_(SmartCardLock)
phNfc_sRemoteDevInformation_t RemoteDeviceInfo;
//
// Selected DeviceInfo Number from DeviceList
//
DWORD SelectedProtocolIndex;
//
// SmartCard storage card reference counted pointer
//
@ -218,7 +235,7 @@ NfcCxSCInterfaceRemoveClient(
VOID
NfcCxSCInterfaceHandleSmartCardConnectionEstablished(
_In_ PNFCCX_SC_INTERFACE ScInterface,
_In_ phNfc_sRemoteDevInformation_t* pRemoteDeviceInfo
_In_ PNFCCX_RF_INTERFACE RFInterface
);
VOID
@ -353,6 +370,12 @@ NfcCxSCInterfaceValidateLoadKeyCommand(
_In_ DWORD InputBufferLength
);
BOOL
NfcCxSCInterfaceValidateSwitchProtocolCommand(
_In_bytecount_(InputBufferLength) PBYTE InputBuffer,
_In_ DWORD InputBufferLength
);
NTSTATUS
NfcCxSCInterfaceValidateMifareLoadKeyParameters(
_In_bytecount_(InputBufferLength) PBYTE InputBuffer,
@ -460,12 +483,48 @@ NfcCxSCInterfaceResetCard(
_In_ PNFCCX_SC_INTERFACE ScInterface
);
_Requires_lock_not_held_(ScInterface->SmartCardLock)
BOOLEAN
NfcCxSCInterfaceDetectMifareULC(
_In_ PNFCCX_SC_INTERFACE ScInterface
);
_Requires_lock_not_held_(ScInterface->SmartCardLock)
NTSTATUS
NfcCxSCInterfaceDeactivateMultiProtocolTag(
_In_ PNFCCX_SC_INTERFACE ScInterface
);
_Requires_lock_not_held_(ScInterface->SmartCardLock)
NTSTATUS
NfcCxSCInterfaceActivateMultiProtocolTag(
_In_ PNFCCX_SC_INTERFACE ScInterface
);
BYTE
NfcCxSCInterfaceComputeChecksum(
_In_reads_bytes_(cbAtr) BYTE* pAtr,
_In_ DWORD cbAtr
);
BOOLEAN
NfcCxSCInterfaceIsMultiProtocolTag(
_In_ PNFCCX_SC_INTERFACE ScInterface
);
NTSTATUS
NfcCxSCInterfaceLoadNewSelectedProtocol(
_In_ PNFCCX_SC_INTERFACE ScInterface,
_In_bytecount_(InputBufferLength) PBYTE InputBuffer,
_In_ DWORD InputBufferLength
);
DWORD
NfcCxSCInterfaceGetIndexOfProtocolType(
_Inout_ PNFCCX_RF_INTERFACE RFInterface,
_In_ phNfc_eRemDevType_t RemDevType
);
//
// Inline helper functions
//

Просмотреть файл

@ -1059,6 +1059,8 @@ NfcCxBindClient(
(PFN_NFC_CX)NfcCxEvtSetLlcpConfig,
(PFN_NFC_CX)NfcCxEvtRegisterSequenceHandler,
(PFN_NFC_CX)NfcCxEvtUnregisterSequenceHandler,
(PFN_NFC_CX)NfcCxEvtReleaseHardwareControl,
(PFN_NFC_CX)NfcCxEvtReacquireHardwareControl,
};
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
@ -1132,3 +1134,108 @@ NfcCxUnbindClient(
Done:
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
}
NTSTATUS
NfcCxEvtReleaseHardwareControl(
_In_ PNFCCX_DRIVER_GLOBALS NfcCxGlobals,
_In_ WDFDEVICE Device
)
/*++
Routine Description:
This routine is called by the CX client to make CX driver
release the NFCC access.
Arguments:
Device - WDF device to initialize
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PNFCCX_FDO_CONTEXT fdoContext;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
if (!VerifyPrivateGlobals(NfcCxGlobals)) {
TRACE_LINE(LEVEL_ERROR, "Invalid CX global pointer");
status = STATUS_INVALID_PARAMETER;
goto Done;
}
fdoContext = NfcCxFdoGetContext(Device);
if (fdoContext->RFInterface == NULL) {
TRACE_LINE(LEVEL_ERROR, "CX not initialized");
status = STATUS_INVALID_DEVICE_STATE;
goto Done;
}
status = NfcCxFdoDeInitialize(fdoContext);
Done:
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}
NTSTATUS
NfcCxEvtReacquireHardwareControl(
_In_ PNFCCX_DRIVER_GLOBALS NfcCxGlobals,
_In_ WDFDEVICE Device
)
/*++
Routine Description:
This routine is called by the CX client to make CX driver
reacquire the NFCC access.
Arguments:
Device - WDF device to initialize
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PNFCCX_FDO_CONTEXT fdoContext;
TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);
if (!VerifyPrivateGlobals(NfcCxGlobals)) {
TRACE_LINE(LEVEL_ERROR, "Invalid CX global pointer");
status = STATUS_INVALID_PARAMETER;
goto Done;
}
fdoContext = NfcCxFdoGetContext(Device);
if (fdoContext->RFInterface == NULL) {
TRACE_LINE(LEVEL_ERROR, "CX not initialized");
status = STATUS_INVALID_DEVICE_STATE;
goto Done;
}
status = NfcCxFdoInitialize(fdoContext);
if (STATUS_SUCCESS == status)
{
status = NfcCxRFInterfaceUpdateDiscoveryState(fdoContext->RFInterface);
}
else
{
TRACE_LINE(LEVEL_ERROR, "Failed to initialize the Fdo, %!STATUS!", status);
}
Done:
TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
return status;
}

Просмотреть файл

@ -158,4 +158,16 @@ NfcCxEvtUnregisterSequenceHandler(
_In_ NFC_CX_SEQUENCE Sequence
);
NTSTATUS
NfcCxEvtReleaseHardwareControl(
_In_ PNFCCX_DRIVER_GLOBALS NfcCxGlobals,
_In_ WDFDEVICE Device
);
NTSTATUS
NfcCxEvtReacquireHardwareControl(
_In_ PNFCCX_DRIVER_GLOBALS NfcCxGlobals,
_In_ WDFDEVICE Device
);
WDF_EXTERN_C_END

Просмотреть файл

@ -28,6 +28,10 @@ Environment:
#define COMMAND_BUFFER_SIZE 512
#define DEFAULT_APDU_STATUS_SIZE 2
#define PCSC_CLASS_BYTE 0xFF
#define PCSC_PARA1_SWITCH_BYTE 0x00
#define PCSC_PARA2_SWITCH_BYTE 0x02
enum ApduResult
{
RESULT_SUCCESS,
@ -133,6 +137,25 @@ typedef enum _PcscIncrementDecrement
BlkValueCmd = 0x81,
} PcscIncrementDecrement;
typedef struct _PcscSwitchProtocolDataObject
{
unsigned char Tag; // 0x8F
unsigned char Length; // 0x02
unsigned char value[2]; // For values see spec
}SwitchProtocolTlv_t;
typedef struct _PcscSwitchProtocolAPDU
{
unsigned char pbCLA; // 0xFF
unsigned char pbINS; // 0xC2
unsigned char pbP1; // 0x00
unsigned char pbP2; // 0x00
unsigned char pbLc; // 0x02
_PcscSwitchProtocolDataObject PcscSwitchProtoData;
unsigned char pbLe;
}PcscSwitchProtocolAPDU;
class IStorageCard
{
public: