Пример #1
0
/**
 * Answer To Reset (ATR)
 * \param pAtr    ATR buffer
 * \param pLength Pointer for store the ATR length
 */
void ISO7816_Datablock_ATR( uint8_t* pAtr, uint8_t* pLength )
{
    uint32_t i;
    uint32_t j;
    uint32_t y;

    *pLength = 0;

    /* Read ATR TS */
    ISO7816_GetChar(&pAtr[0]);
    /* Read ATR T0 */
    ISO7816_GetChar(&pAtr[1]);
    y = pAtr[1] & 0xF0;
    i = 2;

    /* Read ATR Ti */
    while (y) {

        if (y & 0x10) {  /* TA[i] */
            ISO7816_GetChar(&pAtr[i++]);
        }
        if (y & 0x20) {  /* TB[i] */
            ISO7816_GetChar(&pAtr[i++]);
        }
        if (y & 0x40) {  /* TC[i] */
            ISO7816_GetChar(&pAtr[i++]);
        }
        if (y & 0x80) {  /* TD[i] */
            ISO7816_GetChar(&pAtr[i]);
            y =  pAtr[i++] & 0xF0;
        }
        else {
            y = 0;
        }
    }

    /* Historical Bytes */
    y = pAtr[1] & 0x0F;
    for( j=0; j < y; j++ ) {
        ISO7816_GetChar(&pAtr[i++]);
    }

    TRACE_DEBUG_WP("Length = %d", i);
    TRACE_DEBUG_WP("ATR = ");

    for (j=0; j < i; j++) {
        TRACE_DEBUG_WP("%02x ", pAtr[j]);
    }


    TRACE_DEBUG_WP("\n\r");

    *pLength = i;

}
Пример #2
0
/**
 * Answer To Reset (ATR)
 * \param pAtr    ATR buffer
 * \param pLength Pointer for store the ATR length
 */
void ISO7816_Datablock_ATR( uint8_t* pAtr, uint8_t* pLength )
{
    uint32_t i;
    uint32_t j;
    uint32_t y;

    *pLength = 0;

    /* Read ATR TS */
    ISO7816_GetChar(&pAtr[0]);
    /* Read ATR T0 */
    ISO7816_GetChar(&pAtr[1]);
    y = pAtr[1] & 0xF0;
    i = 2;

    /* Read ATR Ti */
    while (y) {

        if (y & 0x10) {  /* TA[i] */
            ISO7816_GetChar(&pAtr[i++]);
        }
        if (y & 0x20) {  /* TB[i] */
            ISO7816_GetChar(&pAtr[i++]);
        }
        if (y & 0x40) {  /* TC[i] */
            ISO7816_GetChar(&pAtr[i++]);
        }
        if (y & 0x80) {  /* TD[i] */
            ISO7816_GetChar(&pAtr[i]);
            y =  pAtr[i++] & 0xF0;
        }
        else {
            y = 0;
        }
    }

    /* Historical Bytes */
    y = pAtr[1] & 0x0F;
    for( j=0; j < y; j++ ) {
        ISO7816_GetChar(&pAtr[i++]);
    }

    *pLength = i;

}
Пример #3
0
/**
 * Transfert Block TPDU T=0
 * \param pAPDU    APDU buffer
 * \param pMessage Message buffer
 * \param wLength  Block length
 * \return         Message index
 */
uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
                                        uint8_t *pMessage,
                                        uint16_t wLength )
{
    uint16_t NeNc;
    uint16_t indexApdu = 4;
    uint16_t indexMessage = 0;
    uint8_t SW1 = 0;
    uint8_t procByte;
    uint8_t cmdCase;

    TRACE_DEBUG("pAPDU[0]=0x%X\n\r",pAPDU[0]);
    TRACE_DEBUG("pAPDU[1]=0x%X\n\r",pAPDU[1]);
    TRACE_DEBUG("pAPDU[2]=0x%X\n\r",pAPDU[2]);
    TRACE_DEBUG("pAPDU[3]=0x%X\n\r",pAPDU[3]);
    TRACE_DEBUG("pAPDU[4]=0x%X\n\r",pAPDU[4]);
    TRACE_DEBUG("pAPDU[5]=0x%X\n\r",pAPDU[5]);
    TRACE_DEBUG("wlength=%d\n\r",wLength);

    ISO7816_SendChar( pAPDU[0] ); /* CLA */
    ISO7816_SendChar( pAPDU[1] ); /* INS */
    ISO7816_SendChar( pAPDU[2] ); /* P1 */
    ISO7816_SendChar( pAPDU[3] ); /* P2 */
    ISO7816_SendChar( pAPDU[4] ); /* P3 */

    /* Handle the four structures of command APDU */
    indexApdu = 4;

    if( wLength == 4 ) {
        cmdCase = CASE1;
        NeNc = 0;
    }
    else if( wLength == 5) {
        cmdCase = CASE2;
        NeNc = pAPDU[4]; /* C5 */
        if (NeNc == 0) {
            NeNc = 256;
        }
    }
    else if( wLength == 6) {
        NeNc = pAPDU[4]; /* C5 */
        cmdCase = CASE3;
    }
    else if( wLength == 7) {
        NeNc = pAPDU[4]; /* C5 */
        if( NeNc == 0 ) {
            cmdCase = CASE2;
            NeNc = (pAPDU[5]<<8)+pAPDU[6];
        }
        else {
            cmdCase = CASE3;
        }
    }
    else {
        NeNc = pAPDU[4]; /* C5 */
        if( NeNc == 0 ) {
            cmdCase = CASE3;
            NeNc = (pAPDU[5]<<8)+pAPDU[6];
        }
        else {
            cmdCase = CASE3;
        }
    }

    TRACE_DEBUG("CASE=0x%X NeNc=0x%X\n\r", cmdCase, NeNc);

    /* Handle Procedure Bytes */
    do {
        ISO7816_GetChar(&procByte);
        /* Handle NULL */
        if ( procByte == ISO_NULL_VAL ) {
            TRACE_DEBUG("INS\n\r");
            continue;
        }
        /* Handle SW1 */
        else if ( ((procByte & 0xF0) ==0x60) || ((procByte & 0xF0) ==0x90) ) {
            TRACE_DEBUG("SW1\n\r");
            SW1 = 1;
        }
        /* Handle INS */
        else if ( pAPDU[1] == procByte) {
            TRACE_DEBUG("HdlINS\n\r");
            if (cmdCase == CASE2) {
                /* receive data from card */
                do {
                    ISO7816_GetChar(&pMessage[indexMessage++]);
                } while( 0 != --NeNc );
            }
            else {
                 /* Send data */
                do {
                    ISO7816_SendChar(pAPDU[indexApdu++]);
                } while( 0 != --NeNc );
            }
        }
        /* Handle INS ^ 0xff */
        else if ( pAPDU[1] == (procByte ^ 0xff)) {
            TRACE_DEBUG("HdlINS+\n\r");
            if (cmdCase == CASE2) {
                /* receive data from card */
                ISO7816_GetChar(&pMessage[indexMessage++]);
            }
            else {
                ISO7816_SendChar(pAPDU[indexApdu++]);
            }
            NeNc--;
        }
        else {
            /* ?? */
            TRACE_DEBUG("procByte=0x%X\n\r", procByte);
            break;
        }
    } while (NeNc != 0);

    /* Status Bytes */
    if (SW1 == 0) {
        ISO7816_GetChar(&pMessage[indexMessage++]); /* SW1 */
    }
    else {
        pMessage[indexMessage++] = procByte;
    }
    ISO7816_GetChar(&pMessage[indexMessage++]); /* SW2 */

    return( indexMessage );

}