Exemple #1
0
static int32_t griffin_exec_cmd(struct s_reader *rdr, uint8_t cmd_op, const uint8_t *data, uint8_t data_len, uint8_t *response, uint16_t *response_length)
{
	struct griffin_data *csystem_data = rdr->csystem_data;
	uint8_t buf[cmd_buf_len];

	int32_t ret = reader_cmd2icc(rdr, buf,
		griffin_init_cmd(rdr, buf, csystem_data->cmd_base + cmd_op, data, data_len),
		response, response_length);
	if (DEBUG) {
		char tmp[1024];
		rdr_log(rdr, "RECV[1] <- %s (ret=%d resp_len=%d)", cs_hexdump(1, response, *response_length, tmp, sizeof(tmp)), ret, *response_length);
	}
	if (ret || *response_length < 2) return ERROR; // Response is two short
	if (response[0] != 0x90)         return ERROR; // Invalid response
	if (response[1] == 0)            return OK;    // Nothing to retrieve, command OK

	// Retrieve response
	uint8_t cmd_read_response = 0x02;
	if (csystem_data->cmd_base > 0x10)
		cmd_read_response += csystem_data->cmd_base - 0x10;

	ret = reader_cmd2icc(rdr, buf,
		griffin_init_cmd(rdr, buf, cmd_read_response, NULL, response[1]),
		response, response_length);

	if (DEBUG) {
		char tmp[1024];
		rdr_log(rdr, "RECV[2] <- %s (ret=%d resp_len=%d)", cs_hexdump(1, response, *response_length, tmp, sizeof(tmp)), ret, *response_length);
	}
	if (ret || *response_length < 2)            return ERROR; // Response is two short
	if (response[*response_length - 2] != 0x90) return ERROR; // Invalid response
	if (response[*response_length - 1] != 0x00) return ERROR; // We don't expect command_op 0x12 to return more data
	return OK;
}
int32_t card_write(struct s_reader * reader, const uchar *cmd, const uchar *data, uchar *response, uint16_t * response_length)
{
  uchar buf[260];
  // always copy to be able to be able to use const buffer without changing all code
  memcpy(buf, cmd, CMD_LEN);

  if (data) {
    if (cmd[4]) memcpy(buf+CMD_LEN, data, cmd[4]);
    return(reader_cmd2icc(reader, buf, CMD_LEN+cmd[4], response, response_length));
  }
  else
    return(reader_cmd2icc(reader, buf, CMD_LEN, response, response_length));
}
static int32_t dgcrypt_cmd(struct s_reader *rdr, const uint8_t *buf, const int32_t buflen, uint8_t *response, uint16_t *response_length, uint16_t min_response_len)
{
	rdr->ifsc = 195;
	rdr->ns   = 1;
	if (DEBUG) {
		char tmp[512];
		rdr_log(rdr, "SEND -> %s(%d)", cs_hexdump(1, buf, buflen, tmp, sizeof(tmp)), buflen);
	}
	int32_t ret = reader_cmd2icc(rdr, buf, buflen, response, response_length);
	if (DEBUG) {
		char tmp[512];
		rdr_log(rdr, "RECV <- %s(%d) ret=%d", cs_hexdump(1, response, *response_length, tmp, sizeof(tmp)), *response_length, ret);
	}
	// reader_cmd2icc retuns ERROR=1, OK=0 - the opposite of OK and ERROR defines in reader-common.h
	if (ret) {
		rdr_log(rdr, "ERROR: reader_cmd2icc() ret=%d", ret);
		return ERROR;
	}
	if (*response_length < 2 || *response_length < min_response_len) {
		rdr_log(rdr, "ERROR: response_length=%d < min_response_length=%d", *response_length, min_response_len);
		return ERROR; // Response is two short
	}
	if (response[*response_length - 2] != 0x90 || response[*response_length - 1] != 0x00) {
		rdr_log(rdr, "ERROR: response[-2] != 0x90 its 0x%02X", response[*response_length - 2]);
		rdr_log(rdr, "ERROR: response[-1] != 0x00 its 0x%02X", response[*response_length - 1]);
		return ERROR; // The reader responded with "command not OK"
	}
	return OK;
}
Exemple #4
0
int32_t card_write(struct s_reader *reader, const uchar *cmd, const uchar *data, uchar *response, uint16_t *response_length)
{
	int32_t datalen = MAX_ECM_SIZE; // default datalen is max ecm size defined
	uchar buf[MAX_ECM_SIZE + CMD_LEN];
	// always copy to be able to be able to use const buffer without changing all code
	memcpy(buf, cmd, CMD_LEN); // copy command

	if(data)
	{
		if(cmd[4])
		{
			datalen = cmd[4];			
		}
		memcpy(buf + CMD_LEN, data, datalen);
		return (reader_cmd2icc(reader, buf, CMD_LEN + datalen, response, response_length));
	}
	else
		{ return (reader_cmd2icc(reader, buf, CMD_LEN, response, response_length)); }
}
Exemple #5
0
static void dre_read_ee(struct s_reader *reader, const char *path, uchar provid)
{
    def_resp;
    int i, n;
    uchar *ee = malloc(2048);
    if(ee == NULL) return;

    uchar drecmd43[] = { 0x80, 0x00, 0x00, 0x00, 0x05,  0x59, 0x03, 0x43, 0x11, 0xAD };
    uchar drecmd45[] = { 0x45, 0x11 };

    drecmd43[8] = drecmd45[1] = provid;
    drecmd43[9] = ~xor(&drecmd43[7], 2);


    for(i = 0; i < 8; i++)
    {
        for(n = 0; n < 8; n++)
        {
            reader_cmd2icc(reader, drecmd43, 10, cta_res, &cta_lr);

            dre_cmd_c(drecmd45, n, i*32);

            if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
            {
                free(ee);
                rdr_log(reader, "ERROR read ee.bin from card");
                return;
            }

            memcpy(&ee[((n*8)+i)*32] ,&cta_res[2] ,32);

        }
    }

    FILE *pFile = fopen(path, "wb");

    if(pFile == NULL)
    {
        free(ee);
        return ;
    }

    fwrite(ee, 2048, 1, pFile);
    fclose(pFile);
    free(ee);
    rdr_log(reader, "ee.bin saved to %s", path);
}
Exemple #6
0
static int32_t dre_command(struct s_reader *reader, const uchar *cmd, int32_t cmdlen, unsigned char *cta_res, uint16_t *p_cta_lr, 
                                                            uint8_t crypted, uint8_t keynum, uint8_t dre_v, uint8_t cmd_type)
                                                            //attention: inputcommand will be changed!!!! answer will be in cta_res, length cta_lr ; returning 1 = no error, return ERROR = err
{
	uchar startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 };  //any command starts with this,
	//last byte is nr of bytes of the command that will be sent
	//after the startcmd
	//response on startcmd+cmd:     = { 0x61, 0x05 }  //0x61 = "OK", last byte is nr. of bytes card will send
	uchar reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 };    //after command answer has to be requested,
	//last byte must be nr. of bytes that card has reported to send
	uchar command[256];
	uchar checksum;
	char tmp[256];
	int32_t headerlen = sizeof(startcmd);

    if(dre_v > 0)
    {
        startcmd[1] = 0;
        startcmd[2] = crypted;
        startcmd[3] = keynum;
    }

    startcmd[4] = cmdlen + 3 - cmd_type; //commandlength + type + len + checksum bytes
	memcpy(command, startcmd, headerlen);
    command[headerlen++] = cmd_type ? 0x86 : CMD_BYTE;  //type
    command[headerlen++] = cmdlen + (cmd_type == 1 ? 0 : 1);    //len = command + 1 checksum byte
	memcpy(command + headerlen, cmd, cmdlen);

    if(!cmd_type)
    {
        checksum = ~xor(cmd, cmdlen);
        //rdr_log_dbg(reader, D_READER, "Checksum: %02x", checksum);
        cmdlen += headerlen;
        command[cmdlen++] = checksum;
    }
    else cmdlen += headerlen;

	reader_cmd2icc(reader, command, cmdlen, cta_res, p_cta_lr);

	if((*p_cta_lr != 2) || (cta_res[0] != OK_RESPONSE))
	{
		rdr_log(reader, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
		rdr_log(reader, "unexpected answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
		return ERROR;           //error
	}

    rdr_log_dbg(reader, D_READER, "command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
    rdr_log_dbg(reader, D_READER, "answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));

	reqans[4] = cta_res[1];   //adapt length byte
	reader_cmd2icc(reader, reqans, 5, cta_res, p_cta_lr);

	if(cta_res[0] != CMD_BYTE)
	{
		rdr_log(reader, "unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
		return ERROR;
	}

	if((cta_res[1] == 0x03) && (cta_res[2] == 0xe2))
	{
		switch(cta_res[3+dre_v])
		{
		case 0xe1:
			rdr_log(reader, "checksum error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
		case 0xe2:
			rdr_log(reader, "wrong cmd len: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
		case 0xe3:
			rdr_log(reader, "illegal command: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
        case 0xe4:
            rdr_log(reader, "wrong adress type: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe5:
            rdr_log(reader, "wrong CMD param: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe6:
            rdr_log(reader, "wrong UA: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe7:
            rdr_log(reader, "wrong group: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe8:
            rdr_log(reader, "wrong key num: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xeb:
            rdr_log(reader, "No key or subscribe : %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
		case 0xec:
			rdr_log(reader, "wrong signature: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
        case 0xed:
            rdr_log(reader, "wrong provider: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xef:
            rdr_log(reader, "wrong GEO code: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
		default:
			rdr_log_dbg(reader, D_READER, "unknown error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
			break;
		}
		return ERROR;           //error
	}

	int32_t length_excl_leader = *p_cta_lr;

	if((cta_res[*p_cta_lr - 2] == 0x90) && (cta_res[*p_cta_lr - 1] == 0x00))
		{ length_excl_leader -= 2; }

	checksum = ~xor(cta_res + 2, length_excl_leader - 3);

	if(cta_res[length_excl_leader - 1] != checksum)
	{
		rdr_log(reader, "checksum does not match, expected %02x received %02x:%s", checksum,
				cta_res[length_excl_leader - 1], cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
		return ERROR;           //error
	}
	return OK;
}
Exemple #7
0
static int32_t dre_command (struct s_reader * reader, const uchar * cmd, int32_t cmdlen, unsigned char * cta_res, uint16_t * p_cta_lr)	//attention: inputcommand will be changed!!!! answer will be in cta_res, length cta_lr ; returning 1 = no error, return ERROR = err
{
    uchar startcmd[] = { 0x80, 0xFF, 0x10, 0x01, 0x05 };	//any command starts with this,
    //last byte is nr of bytes of the command that will be sent
    //after the startcmd
//response on startcmd+cmd:     = { 0x61, 0x05 }  //0x61 = "OK", last byte is nr. of bytes card will send
    uchar reqans[] = { 0x00, 0xC0, 0x00, 0x00, 0x08 };	//after command answer has to be requested,
    //last byte must be nr. of bytes that card has reported to send
    uchar command[256];
    char tmp[256];
    int32_t headerlen = sizeof (startcmd);
    startcmd[4] = cmdlen + 3;	//commandlength + type + len + checksum bytes
    memcpy (command, startcmd, headerlen);
    command[headerlen++] = CMD_BYTE;	//type
    command[headerlen++] = cmdlen + 1;	//len = command + 1 checksum byte
    memcpy (command + headerlen, cmd, cmdlen);

    uchar checksum = ~xor (cmd, cmdlen);
    //cs_debug_mask(D_READER, "[dre-reader] Checksum: %02x", checksum);
    cmdlen += headerlen;
    command[cmdlen++] = checksum;

    reader_cmd2icc (reader, command, cmdlen, cta_res, p_cta_lr);

    if ((*p_cta_lr != 2) || (cta_res[0] != OK_RESPONSE)) {
        cs_log ("[dre-reader] command sent to card: %s", cs_hexdump(0, command, cmdlen, tmp, sizeof(tmp)));
        cs_log ("[dre-reader] unexpected answer from card: %s", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
        return ERROR;			//error
    }

    reqans[4] = cta_res[1];	//adapt length byte
    reader_cmd2icc (reader, reqans, 5, cta_res, p_cta_lr);

    if (cta_res[0] != CMD_BYTE) {
        cs_log ("[dre-reader] unknown response: cta_res[0] expected to be %02x, is %02x", CMD_BYTE, cta_res[0]);
        return ERROR;
    }
    if ((cta_res[1] == 0x03) && (cta_res[2] == 0xe2)) {
        switch (cta_res[3]) {
        case 0xe1:
            cs_log ("[dre-reader] checksum error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe2:
            cs_log ("[dre-reader] wrong provider: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xe3:
            cs_log ("[dre-reader] illegal command: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        case 0xec:
            cs_log ("[dre-reader] wrong signature: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        default:
            cs_debug_mask(D_READER, "[dre-reader] unknown error: %s.", cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
            break;
        }
        return ERROR;			//error
    }
    int32_t length_excl_leader = *p_cta_lr;
    if ((cta_res[*p_cta_lr - 2] == 0x90) && (cta_res[*p_cta_lr - 1] == 0x00))
        length_excl_leader -= 2;

    checksum = ~xor (cta_res + 2, length_excl_leader - 3);

    if (cta_res[length_excl_leader - 1] != checksum) {
        cs_log ("[dre-reader] checksum does not match, expected %02x received %02x:%s", checksum,
                cta_res[length_excl_leader - 1], cs_hexdump(0, cta_res, *p_cta_lr, tmp, sizeof(tmp)));
        return ERROR;			//error
    }
    return OK;
}