コード例 #1
0
NTSTATUS
CBTransmit(
          PSMARTCARD_EXTENSION SmartcardExtension
          )
/*++

CBTransmit:
        callback handler for SMCLIB RDF_TRANSMIT

Arguments:
        SmartcardExtension      context of call

Return Value:
        STATUS_SUCCESS
        STATUS_NO_MEDIA
        STATUS_TIMEOUT
        STATUS_INVALID_DEVICE_REQUEST

--*/
{
    NTSTATUS  NTStatus = STATUS_SUCCESS;

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBTransmit: Enter\n" )
                  );

        //      dispatch on the selected protocol
    switch ( SmartcardExtension->CardCapabilities.Protocol.Selected ) {
    case SCARD_PROTOCOL_T0:
        NTStatus = CBT0Transmit( SmartcardExtension );
        break;

    case SCARD_PROTOCOL_T1:
        NTStatus = CBT1Transmit( SmartcardExtension );
        break;

    case SCARD_PROTOCOL_RAW:
        NTStatus = CBRawTransmit( SmartcardExtension );
        break;

    default:
        NTStatus = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBTransmit: Exit (%lx)\n", NTStatus )
                  );

    return( NTStatus );
}
コード例 #2
0
NTSTATUS
CBRawTransmit(
             PSMARTCARD_EXTENSION SmartcardExtension
             )
/*++

CBRawTransmit:
        finishes the callback RDF_TRANSMIT for the RAW protocol

Arguments:
        SmartcardExtension      context of call

Return Value:
        STATUS_SUCCESS
        STATUS_NO_MEDIA
        STATUS_TIMEOUT
        STATUS_INVALID_DEVICE_REQUEST

--*/
{
    NTSTATUS                    NTStatus = STATUS_SUCCESS;
    UCHAR                           TLVList[ TLV_BUFFER_SIZE ],
    Val,
    Len;
    ULONG                           TLVListLen;
    PREADER_EXTENSION       ReaderExtension;

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBRawTransmit: Enter\n" )
                  );

    ReaderExtension = SmartcardExtension->ReaderExtension;
        //
        //      read the status file of ICC1 from the reader
        //
    TLVListLen = TLV_BUFFER_SIZE;
    NTStatus = CmdReadStatusFile(
                                ReaderExtension,
                                ReaderExtension->Device,
                                TLVList,
                                &TLVListLen
                                );

        //
        //      check the active protocol of the reader
        //
    if ( NT_SUCCESS( NTStatus )) {
        Len = sizeof(Val);
        NTStatus = CmdGetTagValue(
                                 TAG_ICC_PROTOCOLS,
                                 TLVList,
                                 TLVListLen,
                                 &Len,
                                 ( PVOID ) &Val
                                 );

                //      execute the active protocol
        if ( NT_SUCCESS( NTStatus )) {

                        //      translate the actual protocol to a value the lib can understand
            switch ( Val ) {
            case PSCR_PROTOCOL_T0:
                NTStatus = CBT0Transmit( SmartcardExtension );
                break;
            case PSCR_PROTOCOL_T1:
                NTStatus = CBT1Transmit( SmartcardExtension );
                break;
            default:
                NTStatus = STATUS_UNSUCCESSFUL;
                break;
            }
        }
    }
    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBRawTransmit: Exit (%lx)\n", NTStatus )
                  );
    return( NTStatus );
}
コード例 #3
0
ファイル: Ifd_protocol.c プロジェクト: lazhartel/tinythread
/**
  * @brief  Transmission by T=1 Short APDU Mode
  * @param  portno			Indicate which port to open (0:Port0; 1:Port1)
  * @param  pBlockBuffer	Command Data
  * @param  pBlockSize		The size of command data
  * @retval Slot Status Error Code
  */
unsigned char Ifd_XfrShortApduT1(	int32_t portno,
											unsigned char *pBlockBuffer,
											unsigned int *pBlockSize	)
{
	int32_t retransmit = 0;
	int32_t ErrorCode;
	uint8_t rbuf[MIN_BUFFER_SIZE], rsp_type;
	uint32_t idx, rlen;
	S_SC_DEV_T *dev;	
	dev =  (S_SC_DEV_T *)((uint32_t)&sc_device[portno]);
	
	if(portno == 0) {
    	dev->rcv_buf = (uint8_t *)&g_Port0_RxBUF;//(uint8_t *)malloc(MAX_BUF_LEN * sizeof(uint8_t));
    	dev->snd_buf = (uint8_t *)&g_Port0_TxBUF;
	} else {
		dev->rcv_buf = (uint8_t *)&g_Port1_RxBUF;//(uint8_t *)malloc(MAX_BUF_LEN * sizeof(uint8_t));
		dev->snd_buf = (uint8_t *)&g_Port1_TxBUF;
	}

	CCIDSCDEBUG("Ifd_XfrShortApduT1: header=%02x %02x %02x %02x, len=%d\n",  
		pBlockBuffer[0], pBlockBuffer[1], pBlockBuffer[2], pBlockBuffer[3], *pBlockSize);

	/* IFS request only for EMV T=1 */
	/* First block (S-block IFS request) transmits after ATR */
	if(g_ifs_req_flag==1)
	{
		retransmit++;
		g_ifs_req_flag = 0;
		ErrorCode = SendSBlock( dev, T1_BLOCK_S_IFS_REQ, 0xFE);
		rsp_type = T1BlockGetType(dev->rcv_buf);
		if(rsp_type==T1_BLOCK_S)
		{
			/* check IFS RESPONSE */
			if(dev->rcv_buf[1]!=T1_BLOCK_S_IFS_RES) 
				ErrorCode = PROTOCOL_T1_ERROR;
			/* IFSC shall have a value in the range '10' to 'FE' && check NAD && response's inf data must be 0xFE */
			if ( T1BlockGetLength(dev->rcv_buf)!=0x01 || T1BlockGetNAD(dev->rcv_buf)!=0x00 ||
				dev->rcv_buf[3]!=0xFE)
				ErrorCode = PROTOCOL_T1_ERROR;
		}
		while( (ErrorCode!=SC_STATUS_SUCCESS || rsp_type!=T1_BLOCK_S) && retransmit!=3 )
		{
			ErrorCode = SendSBlock( dev, T1_BLOCK_S_IFS_REQ, 0xFE);
			rsp_type = T1BlockGetType(dev->rcv_buf);
			if(rsp_type==T1_BLOCK_S)
			{
				/* check IFS RESPONSE */
				if(dev->rcv_buf[1]!=T1_BLOCK_S_IFS_RES) 
					ErrorCode = PROTOCOL_T1_ERROR;
				/* IFSC shall have a value in the range '10' to 'FE' && check NAD && response's inf data must be 0xFE */
				if ( T1BlockGetLength(dev->rcv_buf)!=0x01 || T1BlockGetNAD(dev->rcv_buf)!=0x00 ||
					dev->rcv_buf[3]!=0xFE)
					ErrorCode = PROTOCOL_T1_ERROR;
			}
			retransmit++;
		}
		
		if(ErrorCode != SC_STATUS_SUCCESS)
			return Ifd_SC2CCIDErrorCode(ErrorCode);
	}

	//for(idx=0; idx<*pBlockSize; idx++) 	// skip checksum byte
	//	CCIDSCDEBUG("Sending Data: Data[%d]=0x%02x \n", idx, pBlockBuffer[idx]);

	// Sending procedure
	ErrorCode = CBT1Transmit( dev, pBlockBuffer, *pBlockSize, &rbuf[0], &rlen);
	if(ErrorCode != SC_STATUS_SUCCESS)
		return Ifd_SC2CCIDErrorCode(ErrorCode);

	CCIDSCDEBUG("Ifd_XfrShortApduT1: dwLength = %d, Data = ", rlen);
	
	// received data
	for(idx=0; idx<rlen; idx++)
	{
		//CCIDSCDEBUG("Received Data: Data[%d]=0x%02x \n", idx, rbuf[idx]);
		CCIDSCDEBUG("%02x", rbuf[idx]);
		*pBlockBuffer = rbuf[idx];
		pBlockBuffer++;
	}
	CCIDSCDEBUG("\n");
			
	// length of received data
	*pBlockSize = rlen;	

	return SLOT_NO_ERROR;
	
}
コード例 #4
0
ファイル: Ifd_protocol.c プロジェクト: lazhartel/tinythread
/**
  * @brief  Transmission by T=1 Extend APDU Mode
  * @param  portno			Indicate which port to open (0:Port0; 1:Port1)
  * @param  pBlockBuffer	Command Data
  * @param  pBlockSize		The size of command data
  * @retval Slot Status Error Code
  */
unsigned char Ifd_XfrExtendApduT1(	int32_t portno,
												unsigned char *pBlockBuffer,
												unsigned int *pBlockSize	)
{
	int32_t ErrorCode;
	uint8_t rbuf[MIN_BUFFER_SIZE];
	uint32_t idx, rlen;
	uint32_t datalength;
	S_SC_DEV_T *dev;	
	dev =  (S_SC_DEV_T *)((uint32_t)&sc_device[portno]);

	if(portno == 0) {
    	dev->rcv_buf = (uint8_t *)&g_Port0_RxBUF;//(uint8_t *)malloc(MAX_BUF_LEN * sizeof(uint8_t));
    	dev->snd_buf = (uint8_t *)&g_Port0_TxBUF;
	} else {
		dev->rcv_buf = (uint8_t *)&g_Port1_RxBUF;//(uint8_t *)malloc(MAX_BUF_LEN * sizeof(uint8_t));
		dev->snd_buf = (uint8_t *)&g_Port1_TxBUF;
	}

	if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x01)
	{
		datalength = (*pBlockSize) - 7;
		pBlockBuffer = pBlockBuffer + 7;

		while(datalength)
		{

			if(datalength >= 0xFE)
				ErrorCode = CBT1Transmit( dev, pBlockBuffer, 0xFE, &rbuf[0], &rlen);
			else
				ErrorCode = CBT1Transmit( dev, pBlockBuffer, datalength, &rbuf[0], &rlen);
			if(ErrorCode != SC_STATUS_SUCCESS)
				return Ifd_SC2CCIDErrorCode(ErrorCode);

			if(datalength >= 0xFE) {
				pBlockBuffer+=0xFE;
				datalength-=0xFE;
			} else
				datalength-=datalength;

		}
		
		// length of received data
		*pBlockSize = 0;

		// Chain Parameter Setting
		g_ChainParameter = 0x10;
	}
	
	else if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x02)
	{
		datalength = (*pBlockSize) - 7;
		pBlockBuffer = pBlockBuffer + 7;
		
		ErrorCode = CBT1Transmit( dev, pBlockBuffer, datalength, &rbuf[0], &rlen);
		if(ErrorCode != SC_STATUS_SUCCESS)
			return Ifd_SC2CCIDErrorCode(ErrorCode);
		
		// check if data bytes still available
		//datalength = rlen - 3 - (dev->CardCapabilities.T1.EDC?2:1);
		pBlockBuffer = pBlockBuffer -7;
		for(idx=0; idx<rlen; idx++)
			pBlockBuffer[idx] = rbuf[idx];
		
		// length of received data
		*pBlockSize = rlen;

		// Chain Parameter Setting
		g_ChainParameter = 0x01;
	}
	
	else if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x03)
	{
		datalength = (*pBlockSize) - 7;
		pBlockBuffer = pBlockBuffer + 7;

		while(datalength)
		{

			if(datalength >= 0xFE)
				ErrorCode = CBT1Transmit( dev, pBlockBuffer, 0xFE, &rbuf[0], &rlen);
			else
				ErrorCode = CBT1Transmit( dev, pBlockBuffer, datalength, &rbuf[0], &rlen);
			if(ErrorCode != SC_STATUS_SUCCESS)
				return Ifd_SC2CCIDErrorCode(ErrorCode);

			if(datalength >= 0xFE) {
				pBlockBuffer+=0xFE;
				datalength-=0xFE;
			} else
				datalength-=datalength;

		}
		
		// length of received data
		*pBlockSize = 0;

		// Chain Parameter Setting
		g_ChainParameter = 0x10;
	}

	else if( UsbMessageBuffer[OFFSET_WLEVELPARAMETER] == 0x10)
	{
		ErrorCode = SendRBlock( dev, 1, 0);
		if(ErrorCode != SC_STATUS_SUCCESS)
			return Ifd_SC2CCIDErrorCode(ErrorCode);

		datalength = dev->rcv_pos - 3 - (dev->CardCapabilities.T1.EDC?2:1);
		pBlockBuffer = pBlockBuffer -7;
		for(idx=0; idx<datalength; idx++)
			pBlockBuffer[idx] = dev->rcv_buf[3+idx];
		
		// length of received data
		if(dev->rcv_pos==0xFE+3)
			*pBlockSize = 0xFE;
		else
			*pBlockSize = dev->rcv_pos - 3;

		// Chain Parameter Setting
		if(dev->rcv_pos==0xFE)
			g_ChainParameter = 0x03;
		else
			g_ChainParameter = 0x02;
	}

	return SLOT_NO_ERROR;

}