示例#1
0
// internal sending function. not a RAMFUNC.
bool intMfSniffSend() {

	int pckSize = 0;
	int pckLen = traceLen;
	int pckNum = 0;

	FpgaDisableSscDma();
	while (pckLen > 0) {
		pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
		LED_B_ON();
		cmd_send(CMD_ACK, 1, pckSize, pckNum, trace + traceLen - pckLen, pckSize);
		LED_B_OFF();

		pckLen -= pckSize;
		pckNum++;
	}

	LED_B_ON();
	cmd_send(CMD_ACK,2,0,0,0,0);
	LED_B_OFF();

	iso14a_clear_trace();
	
	return TRUE;
}
示例#2
0
// internal sending function. not a RAMFUNC.
bool intMfSniffSend() {

	int pckSize = 0;
	int pckLen = BigBuf_get_traceLen();
	int pckNum = 0;
	uint8_t *trace = BigBuf_get_addr();
	
	FpgaDisableSscDma();
	while (pckLen > 0) {
		pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
		LED_B_ON();
		cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
		LED_B_OFF();
		pckLen -= pckSize;
		pckNum++;
	}

	LED_B_ON();
	cmd_send(CMD_ACK,2,0,0,0,0);
	LED_B_OFF();

	clear_trace();
	
	return TRUE;
}
示例#3
0
int main(int argc, char **argv)
{
  int bufsize = 1024*1024;
  char buffer[bufsize], *bstate;
  int n;
  Net_timeout_t dt;
  NetStream_t *ns;
  char cmd[512];
  char *host;
  int port = 6714;
  int timeout = 15;


  if (argc < 2) {
     printf("get_version -a | host [port timeout]\n");
     printf("   -a   -Use the local host and default port\n");
     return(0);
  }

  if (strcmp(argv[1], "-a") == 0) {
    host = (char *)malloc(1024);
    gethostname(host, 1023);
  } else {
    host = argv[1];
  }

  if (argc > 2) port = atoi(argv[2]);
  if (argc == 4) timeout = atoi(argv[3]);
  set_net_timeout(&dt, timeout, 0);

  sprintf(cmd, "1 4 5 %d\n", timeout);  // IBP_ST_VERSION command

  assert(apr_initialize() == APR_SUCCESS);

  dns_cache_init(10);

  ns = cmd_send(host, port, cmd, &bstate, timeout);
  if (ns == NULL) return(-1);
  if (bstate != NULL) free(bstate);

  //** Read the result.  Termination occurs when the line "END" is read.
  //** Note that readline_netstream strips the "\n" from the end of the line
  n = NS_OK;
  while (n == NS_OK) {
     n = readline_netstream(ns, buffer, bufsize, dt);
     if (n == NS_OK) {
        if (strcmp(buffer, "END") == 0) {
           n = NS_OK+1;
        } else {
           printf("%s\n", buffer);
        }
     }
  }

  //** Close the connection
  close_netstream(ns);

  apr_terminate();
  return(0);
}
示例#4
0
int
cmd_handler_mc1322x(const uint8_t *data, int len)
{
  if(data[0] == '!') {
    if(data[1] == 'C') {
      printf("mc1322x_cmd: setting channel: %d\n", data[2]);
      set_channel(data[2]-11);
      return 1;
    } else if(data[1] == 'M') {
      printf("mc1322x_cmd: Got MAC\n");
      memcpy(uip_lladdr.addr, data+2, sizeof(uip_lladdr.addr));
      rimeaddr_set_node_addr((rimeaddr_t *) uip_lladdr.addr);
      return 1;
    }
  } else if(data[0] == '?') {
    if(data[1] == 'C') {
      uint8_t buf[4];
      printf("mc1322x_cmd: getting channel: %d\n", data[2]);
      buf[0] = '!';
      buf[1] = 'C';
      //Not implemented in MACA driver
      buf[2] = 0;
      cmd_send(buf, 3);
      return 1;
    }
  }
  return 0;
}
示例#5
0
bool MfSniffEnd(void){
	LED_B_ON();
	cmd_send(CMD_ACK,0,0,0,0,0);
	LED_B_OFF();

	return FALSE;
}
示例#6
0
文件: slip-radio.c 项目: Jakl555/6lbr
/*---------------------------------------------------------------------------*/
static int
slip_radio_cmd_handler(const uint8_t *data, int len)
{
  int i;
  if(data[0] == '!') {
    /* should send out stuff to the radio - ignore it as IP */
    /* --- s e n d --- */
    if(data[1] == 'S') {
      int pos;
      packet_ids[packet_pos] = data[2];

      packetbuf_clear();
      pos = packetutils_deserialize_atts(&data[3], len - 3);
      if(pos < 0) {
        PRINTF("slip-radio: illegal packet attributes\n");
        return 1;
      }
      pos += 3;
      len -= pos;
      if(len > PACKETBUF_SIZE) {
        len = PACKETBUF_SIZE;
      }
      memcpy(packetbuf_dataptr(), &data[pos], len);
      packetbuf_set_datalen(len);

      PRINTF("slip-radio: sending %u (%d bytes)\n",
             data[2], packetbuf_datalen());

      /* parse frame before sending to get addresses, etc. */
      no_framer.parse();
      NETSTACK_MAC.send(packet_sent, &packet_ids[packet_pos]);

      packet_pos++;
      if(packet_pos >= sizeof(packet_ids)) {
	packet_pos = 0;
      }
      return 1;
    } else if(data[1] == 'R' && len == 2) {
#if !CONTIKI_TARGET_CC2538DK
      PRINTF("Rebooting\n");
      watchdog_reboot();
#endif
      return 1;
    }
  } else if(uip_buf[0] == '?') {
    PRINTF("Got request message of type %c\n", uip_buf[1]);
    if(data[1] == 'M' && len == 2) {
      /* this is just a test so far... just to see if it works */
      uip_buf[0] = '!';
      uip_buf[1] = 'M';
      for(i = 0; i < 8; i++) {
        uip_buf[2 + i] = uip_lladdr.addr[i];
      }
      uip_len = 10;
      cmd_send(uip_buf, uip_len);
      return 1;
    }
  }
  return 0;
}
示例#7
0
int
cmd_handler_cc2420(const uint8_t *data, int len)
{
  if(data[0] == '!') {
    if(data[1] == 'C' && len == 3) {
      printf("cc2420_cmd: setting channel: %d\n", data[2]);
      cc2420_set_channel(data[2]);
      return 1;
    } else if(data[1] == 'M' && len == 10) {
        printf("cc2420_cmd: Got MAC\n");
        memcpy(uip_lladdr.addr, data+2, sizeof(uip_lladdr.addr));
        linkaddr_set_node_addr((linkaddr_t *) uip_lladdr.addr);
        uint16_t shortaddr = (linkaddr_node_addr.u8[0] << 8) +
          linkaddr_node_addr.u8[1];
        cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, linkaddr_node_addr.u8);
        return 1;
      }
  } else if(data[0] == '?') {
    if(data[1] == 'C' && len == 2) {
      uint8_t buf[4];
      printf("cc2420_cmd: getting channel: %d\n", data[2]);
      buf[0] = '!';
      buf[1] = 'C';
      buf[2] = cc2420_get_channel();
      cmd_send(buf, 3);
      return 1;
    }
  }
  return 0;
}
示例#8
0
//-----------------------------------------------------------------------------
// Abort helper function for EPA_PACE_Collect_Nonce
// sets relevant data in ack, sends the response
//-----------------------------------------------------------------------------
static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
{
	// power down the field
	EPA_Finish();

	// send the USB packet
	cmd_send(CMD_ACK,step,func_return,0,0,0);
}
示例#9
0
文件: gc_3.c 项目: ivanignatiev/zappy
int	gcmd_edi(char *cmd, t_pm *pm)
{
  if (nsp_get(cmd) != 1)
    {
      cmd_put(-1, cmd);
      cmd_send(pm, "mct\n");
      return (-1);
    }
  ping_save(pm);
  cmd_put(1, cmd);
  return (1);
}
示例#10
0
void
cmd_list_send(struct cmd_list *cmdlist, struct buffer *b)
{
	struct cmd	*cmd;
	u_int		 n;

	n = 0;
	TAILQ_FOREACH(cmd, cmdlist, qentry)
	    	n++;

	buffer_write(b, &n, sizeof n);
	TAILQ_FOREACH(cmd, cmdlist, qentry)
	    	cmd_send(cmd, b);
}
示例#11
0
static int
ws_execute(struct http_client *c, const char *frame, size_t frame_len) {

	struct cmd*(*fun_extract)(struct http_client *, const char *, size_t) = NULL;
	formatting_fun fun_reply = NULL;

	if((c->path_sz == 1 && strncmp(c->path, "/", 1) == 0) ||
	   strncmp(c->path, "/.json", 6) == 0) {
		fun_extract = json_ws_extract;
		fun_reply = json_reply;
	} else if(strncmp(c->path, "/.raw", 5) == 0) {
		fun_extract = raw_ws_extract;
		fun_reply = raw_reply;
	}

	if(fun_extract) {

		/* Parse websocket frame into a cmd object. */
		struct cmd *cmd = fun_extract(c, frame, frame_len);

		if(cmd) {
			/* copy client info into cmd. */
			cmd_setup(cmd, c);
			cmd->is_websocket = 1;

			if (c->pub_sub != NULL) {
				/* This client already has its own connection
				 * to Redis due to a subscription; use it from
				 * now on. */
				cmd->ac = c->pub_sub->ac;
			} else if (cmd_is_subscribe(cmd)) {
				/* New subscribe command; make new Redis context
				 * for this client */
				cmd->ac = pool_connect(c->w->pool, cmd->database, 0);
				c->pub_sub = cmd;
				cmd->pub_sub_client = c;
			} else {
				/* get Redis connection from pool */
				cmd->ac = (redisAsyncContext*)pool_get_context(c->w->pool);
			}

			/* send it off */
			cmd_send(cmd, fun_reply);

			return 0;
		}
	}

	return -1;
}
示例#12
0
文件: cmd.c 项目: EmuxEvans/calipso
/*---------------------------------------------------------------------------*/
void
cmd_input(const uint8_t *data, int data_len)
{
  int i;
  for(i = 0; cmd_handlers[i] != NULL; i++) {
    if(cmd_handlers[i](data, data_len)) {
      /* Command has been handled */
      return;
    }
  }

  /* Unknown command */
  cmd_send((uint8_t *)"EUnknown command", 16);
}
示例#13
0
文件: epa.c 项目: richo/proxmark3
//-----------------------------------------------------------------------------
// Abort helper function for EPA_PACE_Collect_Nonce
// sets relevant data in ack, sends the response
//-----------------------------------------------------------------------------
static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
{
//	// step in which the failure occured
//	ack->arg[0] = step;
//	// last return code
//	ack->arg[1] = func_return;

	// power down the field
	EPA_Finish();
	
	// send the USB packet
  cmd_send(CMD_ACK,step,func_return,0,0,0);
//UsbSendPacket((void *)ack, sizeof(UsbCommand));
}
示例#14
0
/*---------------------------------------------------------------------------*/
int
border_router_cmd_handler(const uint8_t *data, int len)
{
  /* handle global repair, etc here */
  if(data[0] == '!') {
    PRINTF("Got configuration message of type %c\n", data[1]);
    if(data[1] == 'G') {
      /* This is supposed to be from stdin */
      printf("Performing Global Repair...\n");
      rpl_repair_root(RPL_DEFAULT_INSTANCE);
      return 1;
    } else if(data[1] == 'M') {
      /* We need to know that this is from the slip-radio here. */
      PRINTF("Setting MAC address\n");
      border_router_set_mac(&data[2]);
      return 1;
    } else if(data[1] == 'C') {
      /* We need to know that this is from the slip-radio here. */
      printf("Channel is:%d\n", data[2]);
      return 1;
    } else if(data[1] == 'R') {
      /* We need to know that this is from the slip-radio here. */
      PRINTF("Packet data report for sid:%d st:%d tx:%d\n",
	     data[2], data[3], data[4]);
      packet_sent(data[2], data[3], data[4]);
      return 1;
    } else if(data[1] == 'D') {
      /* We need to know that this is from the slip-radio here... */
      PRINTF("Sensor data received\n");
      border_router_set_sensors((const char *)&data[2], len - 2);
      return 1;
    }
  } else if(data[0] == '?') {
    PRINTF("Got request message of type %c\n", data[1]);
    if(data[1] == 'M') {
      uint8_t buf[20];
      char* hexchar = "0123456789abcdef";
      int j;
      /* this is just a test so far... just to see if it works */
      buf[0] = '!';
      buf[1] = 'M';
      for(j = 0; j < 8; j++) {
        buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4];
        buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15];
      }
      cmd_send(buf, 18);
      return 1;
    } else if(data[1] == 'C') {
示例#15
0
文件: cmd.c 项目: dengjunyong/brouter
/*---------------------------------------------------------------------------*/
void
cmd_input(const uint8_t *data, int data_len)
{
  int i;
  char text[30];
  for(i = 0; cmd_handlers[i] != NULL; i++) {
    if(cmd_handlers[i](data, data_len)) {
      /* Command has been handled */
      return;
    }
  }

  /* Unknown command */
  sprintf(text, "EUnknown command %x%x (%d)", data[0], data[1], data_len);
  cmd_send((uint8_t *)text, strlen(text));
}
示例#16
0
int main(int argc, char **argv)
{
  int bufsize = 1024*1024;
  char buffer[bufsize], *bstate;
  int i, port, delay, timeout, slen;
  char *host, *rid, *msg;
  NetStream_t *ns;

  if (argc < 5) {
     printf("ibp_detach_rid host port RID delay_before_umount [msg]\n");
     printf("\n");
     return(0);
  }

  i = 1;
  host = argv[i]; i++;
  port = atoi(argv[i]); i++;
  rid = argv[i]; i++;
  delay = atoi(argv[i]); i++;

  timeout = 3600;
  if (timeout < delay) timeout = delay + 30;  //** Make sure the timeout is longer than the delay

  msg = "";
  if (argc > i) msg = argv[i];

  slen = strlen(msg);
  sprintf(buffer, "1 92 %s %d %d %d %s\n", rid, delay, timeout, slen, msg);  // IBP_INTERNAL_RID_UMOUNT command

//printf("argc=%d i=%d command=%s\n", argc, i, buffer);
//return(0);
  assert(apr_initialize() == APR_SUCCESS);

  dns_cache_init(10);

  ns = cmd_send(host, port, buffer, &bstate, timeout);
  if (ns == NULL) return(-1);
  if (bstate != NULL) free(bstate);

  //** Close the connection
  close_netstream(ns);

  apr_terminate();

  return(0);
}
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
	
	/* ARG0 contains flags.
		0x01 = init card.
		0x02 = Disconnect
		0x03
	*/
	uint8_t flags = arg0;
	size_t datalen = arg1;
	uint8_t resp[RECEIVE_SIZE];
	memset(resp,0,sizeof(resp));
	
	if (MF_DBGLEVEL >= 4) {
		Dbprintf(" flags : %02X", flags);
		Dbprintf(" len   : %02X", datalen);
		print_result(" RX    : ", datain, datalen);
	}
	
	if ( flags & CLEARTRACE )
		clear_trace();
	
	if ( flags & INIT ){
		if ( !InitDesfireCard() )
			return;
	}
	
	int len = DesfireAPDU(datain, datalen, resp);
	if (MF_DBGLEVEL >= 4)
		print_result("ERR <--: ", resp, len);

	if ( !len ) {
		OnError(2);
		return;
	}
	
	// reset the pcb_blocknum,
	pcb_blocknum = 0;
	
	if ( flags & DISCONNECT )
		OnSuccess();
	
	cmd_send(CMD_ACK,1,len,0,resp,len);
}
示例#18
0
/*---------------------------------------------------------------------------*/
static void
packet_sent(void *ptr, int status, int transmissions)
{
  uint8_t buf[20];
  uint8_t sid;
  int pos;
  sid = *((uint8_t *)ptr);
  PRINTF("Slip-radio: packet sent! sid: %d, status: %d, tx: %d\n",
  	 sid, status, transmissions);
  /* packet callback from lower layers */
  /*  neighbor_info_packet_sent(status, transmissions); */
  pos = 0;
  buf[pos++] = '!';
  buf[pos++] = 'R';
  buf[pos++] = sid;
  buf[pos++] = status; /* one byte ? */
  buf[pos++] = transmissions;
  cmd_send(buf, pos);
}
示例#19
0
int
cmd_handler_cooja(const uint8_t *data, int len)
{
  if(data[0] == '!') {
    if(data[1] == 'C' && len == 3) {
      printf("cooja_cmd: setting channel: %d\n", data[2]);
      radio_set_channel(data[2]);
      //Enable radio
      NETSTACK_RDC.off(1);
      return 1;
    } else if(data[1] == 'M' && len == 10) {
        if(!linkaddr_cmp((linkaddr_t *)(data+2), &linkaddr_null)) {
          printf("cooja_cmd: Got MAC\n");
          if(linkaddr_cmp(&default_link_addr, &linkaddr_null)) {
            linkaddr_copy(&default_link_addr, &linkaddr_node_addr);
          }
          memcpy(uip_lladdr.addr, data+2, sizeof(uip_lladdr.addr));
          linkaddr_set_node_addr((linkaddr_t *) uip_lladdr.addr);
        } else {
          printf("cooja_cmd: Clear MAC disabled\n");
          if(!linkaddr_cmp(&default_link_addr, &linkaddr_null)) {
            memcpy(uip_lladdr.addr, &default_link_addr, sizeof(uip_lladdr.addr));
            linkaddr_set_node_addr(&default_link_addr);
          }
          //Stop radio
          NETSTACK_RDC.off(0);
        }
        return 1;
      }
  } else if(data[0] == '?') {
    if(data[1] == 'C' && len == 2) {
      uint8_t buf[4];
      printf("cooja_cmd: getting channel: %d\n", data[2]);
      buf[0] = '!';
      buf[1] = 'C';
      buf[2] = 0;
      cmd_send(buf, 3);
      return 1;
    }
  }
  return 0;
}
示例#20
0
static int
ws_execute(struct http_client *c, const char *frame, size_t frame_len) {

	struct cmd*(*fun_extract)(struct http_client *, const char *, size_t) = NULL;
	formatting_fun fun_reply = NULL;

	if((c->path_sz == 1 && strncmp(c->path, "/", 1) == 0) ||
	   strncmp(c->path, "/.json", 6) == 0) {
		fun_extract = json_ws_extract;
		fun_reply = json_reply;
	} else if(strncmp(c->path, "/.raw", 5) == 0) {
		fun_extract = raw_ws_extract;
		fun_reply = raw_reply;
	}

	if(fun_extract) {

		/* Parse websocket frame into a cmd object. */
		struct cmd *cmd = fun_extract(c, frame, frame_len);

		if(cmd) {
			/* copy client info into cmd. */
			cmd_setup(cmd, c);
			cmd->is_websocket = 1;

			/* get Redis connection from pool */
			cmd->ac = (redisAsyncContext*)pool_get_context(c->w->pool);

			/* send it off */
			cmd_send(cmd, fun_reply);

			return 0;
		}
	}

	return -1;
}
void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno,  uint8_t *datain){

	int len = 0;
	//uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
	uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
	uint8_t null_key_data8[8] = {0x00};
	//uint8_t null_key_data16[16] = {0x00};	
	//uint8_t new_key_data8[8]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
	//uint8_t new_key_data16[16]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};

	uint8_t resp[256] = {0x00};
	uint8_t IV[16] = {0x00};

	size_t datalen = datain[0];
	
	uint8_t cmd[40] = {0x00};
	uint8_t encRndB[16] = {0x00};
	uint8_t decRndB[16] = {0x00};
	uint8_t nonce[16] = {0x00};
	uint8_t both[32] = {0x00};
	uint8_t encBoth[32] = {0x00};

	InitDesfireCard();
	
	LED_A_ON();
	LED_B_OFF();
	LED_C_OFF();
	
	// 3 olika sätt att authenticera.   AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
	// 4 olika crypto algo   DES, 3DES, 3K3DES, AES
	// 3 olika kommunikations sätt,   PLAIN,MAC,CRYPTO
	
	// des, nyckel 0, 
	switch (mode){
        case 1:{
            uint8_t keybytes[16];
            uint8_t RndA[8] = {0x00};
            uint8_t RndB[8] = {0x00};
            
            if (algo == 2) {
            if (datain[1] == 0xff){
                    memcpy(keybytes,PICC_MASTER_KEY16,16);
                } else {
                    memcpy(keybytes, datain+1, datalen);
                }
            } else {
                if (algo == 1) {
                    if (datain[1] == 0xff){
                memcpy(keybytes,null_key_data8,8);
            } else{
                memcpy(keybytes, datain+1, datalen);
            }
                }
            }
            
            struct desfire_key defaultkey = {0};
            desfirekey_t key = &defaultkey;
            
            if (algo == 2)
                Desfire_3des_key_new_with_version(keybytes, key);
            else if (algo ==1)
            Desfire_des_key_new(keybytes, key);
            
            cmd[0] = AUTHENTICATE;
            cmd[1] = keyno;  //keynumber
            len = DesfireAPDU(cmd, 2, resp);
            if ( !len ) {
                if (MF_DBGLEVEL >= MF_DBG_ERROR) {
                    DbpString("Authentication failed. Card timeout.");
                }
                OnError(3);
                return;
            }
            
            if ( resp[2] == 0xaf ){
            } else {
                DbpString("Authetication failed. Invalid key number.");
                OnError(3);
                return;
            }
            
            memcpy( encRndB, resp+3, 8);
            if (algo == 2)
                tdes_dec(&decRndB, &encRndB, key->data);
            else if (algo == 1)
            des_dec(&decRndB, &encRndB, key->data);
            
            memcpy(RndB, decRndB, 8);
            rol(decRndB,8);
            
            // This should be random
            uint8_t decRndA[8] = {0x00};
            memcpy(RndA, decRndA, 8);
            uint8_t encRndA[8] = {0x00};
            
            if (algo == 2)
                tdes_dec(&encRndA, &decRndA, key->data);
            else if (algo == 1)
            des_dec(&encRndA, &decRndA, key->data);
            
            memcpy(both, encRndA, 8);
            
            for (int x = 0; x < 8; x++) {
                decRndB[x] = decRndB[x] ^ encRndA[x];
                
            }
            
            if (algo == 2)
                tdes_dec(&encRndB, &decRndB, key->data);
            else if (algo == 1)
            des_dec(&encRndB, &decRndB, key->data);
            
            memcpy(both + 8, encRndB, 8);
            
            cmd[0] = ADDITIONAL_FRAME;
            memcpy(cmd+1, both, 16 );
            
            len = DesfireAPDU(cmd, 17, resp);
            if ( !len ) {
                if (MF_DBGLEVEL >= MF_DBG_ERROR) {
                    DbpString("Authentication failed. Card timeout.");
                }
                OnError(3);
                return;
            }
            
            if ( resp[2] == 0x00 ){
                
                struct desfire_key sessionKey = {0};
                desfirekey_t skey = &sessionKey;
                Desfire_session_key_new( RndA, RndB , key, skey );
                //print_result("SESSION : ", skey->data, 8);
                
                memcpy(encRndA, resp+3, 8);
                
                if (algo == 2)
                    tdes_dec(&encRndA, &encRndA, key->data);
                else if (algo == 1)
                des_dec(&encRndA, &encRndA, key->data);
                
                rol(decRndA,8);
                for (int x = 0; x < 8; x++) {
                    if (decRndA[x] != encRndA[x]) {
                        DbpString("Authetication failed. Cannot varify PICC.");
                        OnError(4);
                        return;
                    }
                }
                
                //Change the selected key to a new value.
                /*
                 
                 // Current key is a 3DES key, change it to a DES key
                 if (algo == 2) {
                cmd[0] = CHANGE_KEY;
                cmd[1] = keyno;
                
                uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
                
                uint8_t first, second;
                uint8_t buff1[8] = {0x00};
                uint8_t buff2[8] = {0x00};
                uint8_t buff3[8] = {0x00};
                
                memcpy(buff1,newKey, 8);
                memcpy(buff2,newKey + 8, 8);
                
                ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
                memcpy(buff3, &first, 1);
                memcpy(buff3 + 1, &second, 1);
                
                 tdes_dec(&buff1, &buff1, skey->data);
                 memcpy(cmd+2,buff1,8);
                 
                 for (int x = 0; x < 8; x++) {
                 buff2[x] = buff2[x] ^ buff1[x];
                 }
                 tdes_dec(&buff2, &buff2, skey->data);
                 memcpy(cmd+10,buff2,8);
                 
                 for (int x = 0; x < 8; x++) {
                 buff3[x] = buff3[x] ^ buff2[x];
                 }
                 tdes_dec(&buff3, &buff3, skey->data);
                 memcpy(cmd+18,buff3,8);
                 
                 // The command always times out on the first attempt, this will retry until a response
                 // is recieved.
                 len = 0;
                 while(!len) {
                 len = DesfireAPDU(cmd,26,resp);
                 }
                 
                 } else {
                    // Current key is a DES key, change it to a 3DES key
                    if (algo == 1) {
                        cmd[0] = CHANGE_KEY;
                        cmd[1] = keyno;
                        
                        uint8_t newKey[16] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
                        
                        uint8_t first, second;
                        uint8_t buff1[8] = {0x00};
                        uint8_t buff2[8] = {0x00};
                        uint8_t buff3[8] = {0x00};
                        
                        memcpy(buff1,newKey, 8);
                        memcpy(buff2,newKey + 8, 8);
                        
                        ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
                        memcpy(buff3, &first, 1);
                        memcpy(buff3 + 1, &second, 1);
                        
                des_dec(&buff1, &buff1, skey->data);
                memcpy(cmd+2,buff1,8);
                
                for (int x = 0; x < 8; x++) {
                    buff2[x] = buff2[x] ^ buff1[x];
                }
                des_dec(&buff2, &buff2, skey->data);
                memcpy(cmd+10,buff2,8);
                
                for (int x = 0; x < 8; x++) {
                    buff3[x] = buff3[x] ^ buff2[x];
                }
                des_dec(&buff3, &buff3, skey->data);
                memcpy(cmd+18,buff3,8);
                
                // The command always times out on the first attempt, this will retry until a response
                // is recieved.
                len = 0;
                while(!len) {
                    len = DesfireAPDU(cmd,26,resp);
                }
                    }
                 }
                */
                
                OnSuccess();
                if (algo == 2)
                    cmd_send(CMD_ACK,1,0,0,skey->data,16);
                else if (algo == 1)
                cmd_send(CMD_ACK,1,0,0,skey->data,8);
            } else {
                DbpString("Authetication failed.");
                OnError(6);
                return;
            }
            }
			break;
		case 2:
			//SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
			break;
		case 3:{
		
			//defaultkey
			uint8_t keybytes[16] = {0x00};
			if (datain[1] == 0xff){
				memcpy(keybytes,PICC_MASTER_KEY16,16); 
			} else{
				memcpy(keybytes, datain+1, datalen);
			}
			
			struct desfire_key defaultkey = {0x00};
			desfirekey_t key = &defaultkey;
			Desfire_aes_key_new( keybytes, key);
		
			AesCtx ctx;
			if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
				if( MF_DBGLEVEL >= 4) {
					Dbprintf("AES context failed to init");
				}
				OnError(7);
				return;
			}
			
			cmd[0] = AUTHENTICATE_AES;
			cmd[1] = 0x00;  //keynumber
			len = DesfireAPDU(cmd, 2, resp);
			if ( !len ) {
				if (MF_DBGLEVEL >= MF_DBG_ERROR) {
					DbpString("Authentication failed. Card timeout.");
				}
				OnError(3);
				return;
			}
			
			memcpy( encRndB, resp+3, 16);
		
			// dekryptera tagnonce.
			AesDecrypt(&ctx, encRndB, decRndB, 16);
			rol(decRndB,16);
			memcpy(both, nonce,16);
			memcpy(both+16, decRndB ,16 );
			AesEncrypt(&ctx, both, encBoth, 32 );
			
			cmd[0] = ADDITIONAL_FRAME;
			memcpy(cmd+1, encBoth, 32 );
			
			len = DesfireAPDU(cmd, 33, resp);  // 1 + 32 == 33
			if ( !len ) {
				if (MF_DBGLEVEL >= MF_DBG_ERROR) {
					DbpString("Authentication failed. Card timeout.");
				}
                OnError(3);
				return;
			}
			
			if ( resp[2] == 0x00 ){
				// Create AES Session key		
				struct desfire_key sessionKey = {0};
				desfirekey_t skey = &sessionKey;
				Desfire_session_key_new( nonce, decRndB , key, skey );
				print_result("SESSION : ", skey->data, 16);
			} else {
				DbpString("Authetication failed.");
				OnError(7);
				return;
			}
			
			break;
		}	
	}
	
	OnSuccess();
	cmd_send(CMD_ACK,1,len,0,resp,len);
}
示例#22
0
文件: main.c 项目: GrayTShirt/bolo
int main(int argc, char **argv)
{
	int run_help = 0;
	int run_version = 0;

	char proc[256];
	char path[256];
	pid_t pid = getpid();
	sprintf(proc, "/proc/%d/exe", pid);
	if (readlink(proc, path, 256) == -1) {
		fprintf(stderr, "failed to read execution path from /proc\n");
		return 1;
	}

	if (strcmp(path, "/usr/sbin/bolo") == 0)
		return cmd_aggregator(argc, argc, argv);

	int i;
	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-h") == 0
		 || strcmp(argv[i], "-?") == 0
		 || strcmp(argv[i], "--help") == 0) {
			run_help = 1;
			continue;
		}
		if (strcmp(argv[i], "-V") == 0
		 || strcmp(argv[i], "--version") == 0) {
			run_version = 1;
			continue;
		}
		if (argv[i][0] == '-') {
			fprintf(stderr, "Invalid option `%s'\n", argv[i]);
			return 1;
		}
		break;
	}

	if (run_help)    return cmd_help(i, argc, argv);
	if (run_version) return cmd_version(i, argc, argv);
	if (i == argc)   return cmd_help(i, argc, argv);

	if (strcmp(argv[i], "help") == 0)
		return cmd_help(i, argc, argv);

	if (strcmp(argv[i], "version") == 0)
		return cmd_version(i, argc, argv);

	if (strcmp(argv[i], "aggr") == 0
	 || strcmp(argv[i], "aggregator") == 0)
		return cmd_aggregator(i, argc, argv);

	if (strcmp(argv[i], "cache") == 0)
		return cmd_cache(i, argc, argv);

	if (strcmp(argv[i], "forget") == 0)
		return cmd_forget(i, argc, argv);

	if (strcmp(argv[i], "name") == 0)
		return cmd_name(i, argc, argv);

	if (strcmp(argv[i], "query") == 0)
		return cmd_query(i, argc, argv);

	if (strcmp(argv[i], "send") == 0)
		return cmd_send(i, argc, argv);

	if (strcmp(argv[i], "spy") == 0)
		return cmd_spy(i, argc, argv);

	if (strcmp(argv[i], "tail") == 0)
		return cmd_tail(i, argc, argv);

	fprintf(stderr, "Unrecognized command `%s'.  See bolo --help.\n", argv[i]);
	return 1;
}
示例#23
0
文件: epa.c 项目: richo/proxmark3
//-----------------------------------------------------------------------------
// Acquire one encrypted PACE nonce
//-----------------------------------------------------------------------------
void EPA_PACE_Collect_Nonce(UsbCommand *c)
{
	/*
	 * ack layout:
	 * 	arg:
	 * 		1. element
	 *           step where the error occured or 0 if no error occured
     *       2. element
     *           return code of the last executed function
	 * 	d:
	 * 		Encrypted nonce
	 */

	// return value of a function
	int func_return;

//	// initialize ack with 0s
//	memset(ack->arg, 0, 12);
//	memset(ack->d.asBytes, 0, 48);
	
	// set up communication
	func_return = EPA_Setup();
	if (func_return != 0) {
		EPA_PACE_Collect_Nonce_Abort(1, func_return);
		return;
	}

	// increase the timeout (at least some cards really do need this!)
	iso14a_set_timeout(0x0002FFFF);
	
	// read the CardAccess file
	// this array will hold the CardAccess file
	uint8_t card_access[256] = {0};
	int card_access_length = EPA_Read_CardAccess(card_access, 256);
	// the response has to be at least this big to hold the OID
	if (card_access_length < 18) {
		EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
		return;
	}

	// this will hold the PACE info of the card
	pace_version_info_t pace_version_info;
	// search for the PACE OID
	func_return = EPA_Parse_CardAccess(card_access,
	                                   card_access_length,
	                                   &pace_version_info);
	if (func_return != 0 || pace_version_info.version == 0) {
		EPA_PACE_Collect_Nonce_Abort(3, func_return);
		return;
	}
	
	// initiate the PACE protocol
	// use the CAN for the password since that doesn't change
	func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
	
	// now get the nonce
	uint8_t nonce[256] = {0};
	uint8_t requested_size = (uint8_t)c->arg[0];
	func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
	// check if the command succeeded
	if (func_return < 0)
	{
		EPA_PACE_Collect_Nonce_Abort(4, func_return);
		return;
	}
  
  // all done, return
	EPA_Finish();
	
	// save received information
//	ack->arg[1] = func_return;
//	memcpy(ack->d.asBytes, nonce, func_return);
//	UsbSendPacket((void *)ack, sizeof(UsbCommand));
  cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
}
示例#24
0
cmd_res_t cmd_lic(char *args)
{
	cmd_send("GPL");
	return CMD_SILENT;
}
示例#25
0
cmd_res_t cmd_fwv(char *args)
{
	cmd_send(FW_VERSION);
	return CMD_SILENT;
}
示例#26
0
文件: cmd.c 项目: 9612jhf/webdis
cmd_response_t
cmd_run(struct worker *w, struct http_client *client,
		const char *uri, size_t uri_len,
		const char *body, size_t body_len) {

	char *qmark = memchr(uri, '?', uri_len);
	char *slash;
	const char *p, *cmd_name = uri;
	int cmd_len;
	int param_count = 0, cur_param = 1;

	struct cmd *cmd;
	formatting_fun f_format;

	/* count arguments */
	if(qmark) {
		uri_len = qmark - uri;
	}
	for(p = uri; p && p < uri + uri_len; param_count++) {
		p = memchr(p+1, '/', uri_len - (p+1-uri));
	}

	if(body && body_len) { /* PUT request */
		param_count++;
	}
	if(param_count == 0) {
		return CMD_PARAM_ERROR;
	}

	cmd = cmd_new(param_count);
	cmd->fd = client->fd;
	cmd->database = w->s->cfg->database;

	/* get output formatting function */
	uri_len = cmd_select_format(client, cmd, uri, uri_len, &f_format);

	/* add HTTP info */
	cmd_setup(cmd, client);

	/* check if we only have one command or more. */
	slash = memchr(uri, '/', uri_len);
	if(slash) {

		/* detect DB number by checking if first arg is only numbers */
		int has_db = 1;
		int db_num = 0;
		for(p = uri; p < slash; ++p) {
			if(*p < '0' || *p > '9') {
				has_db = 0;
				break;
			}
			db_num = db_num * 10 + (*p - '0');
		}

		/* shift to next arg if a db was set up */
		if(has_db) {
			char *next;
			cmd->database = db_num;
			cmd->count--; /* overcounted earlier */
			cmd_name = slash + 1;

			if((next = memchr(cmd_name, '/', uri_len - (slash - uri)))) {
				cmd_len = next - cmd_name;
			} else {
				cmd_len = uri_len - (slash - uri + 1);
			}
		} else {
			cmd_len = slash - uri;
		}
	} else {
		cmd_len = uri_len;
	}

	/* there is always a first parameter, it's the command name */
	cmd->argv[0] = malloc(cmd_len);
	memcpy(cmd->argv[0], cmd_name, cmd_len);
	cmd->argv_len[0] = cmd_len;

	/* check that the client is able to run this command */
	if(!acl_allow_command(cmd, w->s->cfg, client)) {
		cmd_free(cmd);
		return CMD_ACL_FAIL;
	}

	if(cmd_is_subscribe(cmd)) {
		/* create a new connection to Redis */
		cmd->ac = (redisAsyncContext*)pool_connect(w->pool, cmd->database, 0);

		/* register with the client, used upon disconnection */
		client->pub_sub = cmd;
		cmd->pub_sub_client = client;
	} else if(cmd->database != w->s->cfg->database) {
		/* create a new connection to Redis for custom DBs */
		cmd->ac = (redisAsyncContext*)pool_connect(w->pool, cmd->database, 0);
	} else {
		/* get a connection from the pool */
		cmd->ac = (redisAsyncContext*)pool_get_context(w->pool);
	}

	/* no args (e.g. INFO command) */
	if(!slash) {
		if(!cmd->ac) {
			cmd_free(cmd);
			return CMD_REDIS_UNAVAIL;
		}
		redisAsyncCommandArgv(cmd->ac, f_format, cmd, 1,
				(const char **)cmd->argv, cmd->argv_len);
		return CMD_SENT;
	}
	p = cmd_name + cmd_len + 1;
	while(p < uri + uri_len) {

		const char *arg = p;
		int arg_len;
		char *next = memchr(arg, '/', uri_len - (arg-uri));
		if(!next || next > uri + uri_len) { /* last argument */
			p = uri + uri_len;
			arg_len = p - arg;
		} else { /* found a slash */
			arg_len = next - arg;
			p = next + 1;
		}

		/* record argument */
		cmd->argv[cur_param] = decode_uri(arg, arg_len, &cmd->argv_len[cur_param], 1);
		cur_param++;
	}

	if(body && body_len) { /* PUT request */
		cmd->argv[cur_param] = malloc(body_len);
		memcpy(cmd->argv[cur_param], body, body_len);
		cmd->argv_len[cur_param] = body_len;
	}

	/* send it off! */
	if(cmd->ac) {
		cmd_send(cmd, f_format);
		return CMD_SENT;
	}
	/* failed to find a suitable connection to Redis. */
	cmd_free(cmd);
	client->pub_sub = NULL;
	return CMD_REDIS_UNAVAIL;
}
void OnError(uint8_t reason){
	cmd_send(CMD_ACK,0,reason,0,0,0);
	OnSuccess();
}
示例#28
0
//-----------------------------------------------------------------------------
// Perform the PACE protocol by replaying given APDUs
//-----------------------------------------------------------------------------
void EPA_PACE_Replay(UsbCommand *c)
{
	uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0};

	// if an APDU has been passed, save it
	if (c->arg[0] != 0) {
		// make sure it's not too big
		if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
		{
			cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
		}
		memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
	           c->d.asBytes,
	           c->arg[2]);
		// save/update APDU length
		if (c->arg[1] == 0) {
			apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
		} else {
			apdu_lengths_replay[c->arg[0] - 1] += c->arg[2];
		}
		cmd_send(CMD_ACK, 0, 0, 0, NULL, 0);
		return;
	}

	// return value of a function
	int func_return;

	// set up communication
	func_return = EPA_Setup();
	if (func_return != 0) {
		EPA_Finish();
		cmd_send(CMD_ACK, 2, func_return, 0, NULL, 0);
		return;
	}

	// increase the timeout (at least some cards really do need this!)/////////////
	// iso14a_set_timeout(0x0003FFFF);

	// response APDU
	uint8_t response_apdu[300] = {0};

	// now replay the data and measure the timings
	for (int i = 0; i < sizeof(apdu_lengths_replay); i++) {
		StartCountUS();
		func_return = EPA_APDU(apdus_replay[i].data,
		                         apdu_lengths_replay[i],
		                         response_apdu);
		timings[i] = GetCountUS();
		// every step but the last one should succeed
		if (i < sizeof(apdu_lengths_replay) - 1
		    && (func_return < 6
		        || response_apdu[func_return - 4] != 0x90
		        || response_apdu[func_return - 3] != 0x00))
		{
			EPA_Finish();
			cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20);
			return;
		}
	}
	EPA_Finish();
	cmd_send(CMD_ACK,0,0,0,timings,20);
	return;
}
示例#29
0
void ReadPCF7931() {
	uint8_t Blocks[8][17];
	uint8_t tmpBlocks[4][16];
	int i, j, ind, ind2, n;
	int num_blocks = 0;
	int max_blocks = 8;
	int ident = 0;
	int error = 0;
	int tries = 0;

	memset(Blocks, 0, 8*17*sizeof(uint8_t));

	do {
		memset(tmpBlocks, 0, 4*16*sizeof(uint8_t));
		n = DemodPCF7931((uint8_t**)tmpBlocks);
		if(!n)
			error++;
		if(error==10 && num_blocks == 0) {
			Dbprintf("Error, no tag or bad tag");
			return;
		}
		else if (tries==20 || error==10) {
			Dbprintf("Error reading the tag");
			Dbprintf("Here is the partial content");
			goto end;
		}

		for(i=0; i<n; i++)
			Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
					 tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
					tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
		if(!ident) {
			for(i=0; i<n; i++) {
				if(IsBlock0PCF7931(tmpBlocks[i])) {
					// Found block 0 ?
					if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
						// Found block 1!
						// \o/
						ident = 1;
						memcpy(Blocks[0], tmpBlocks[i], 16);
						Blocks[0][ALLOC] = 1;
						memcpy(Blocks[1], tmpBlocks[i+1], 16);
						Blocks[1][ALLOC] = 1;
						max_blocks = MAX((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
						// Debug print
						Dbprintf("(dbg) Max blocks: %d", max_blocks);
						num_blocks = 2;
						// Handle following blocks
						for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
							if(j==n) j=0;
							if(j==i) break;
							memcpy(Blocks[ind2], tmpBlocks[j], 16);
							Blocks[ind2][ALLOC] = 1;
						}
						break;
					}
				}
			}
		}
		else {
			for(i=0; i<n; i++) { // Look for identical block in known blocks
				if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
					for(j=0; j<max_blocks; j++) {
						if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
							// Found an identical block
							for(ind=i-1,ind2=j-1; ind >= 0; ind--,ind2--) {
								if(ind2 < 0)
									ind2 = max_blocks;
								if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
									// Dbprintf("Tmp %d -> Block %d", ind, ind2);
									memcpy(Blocks[ind2], tmpBlocks[ind], 16);
									Blocks[ind2][ALLOC] = 1;
									num_blocks++;
									if(num_blocks == max_blocks) goto end;
								}
							}
							for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) {
								if(ind2 > max_blocks)
									ind2 = 0;
								if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
									// Dbprintf("Tmp %d -> Block %d", ind, ind2);
									memcpy(Blocks[ind2], tmpBlocks[ind], 16);
									Blocks[ind2][ALLOC] = 1;
									num_blocks++;
									if(num_blocks == max_blocks) goto end;
								}
							}
						}
					}
				}
			}
		}
		tries++;
		if (BUTTON_PRESS()) return;
	} while (num_blocks != max_blocks);
 end:
	Dbprintf("-----------------------------------------");
	Dbprintf("Memory content:");
	Dbprintf("-----------------------------------------");
	for(i=0; i<max_blocks; i++) {
		if(Blocks[i][ALLOC]==1)
			Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
					 Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
					Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
		else
			Dbprintf("<missing block %d>", i);
	}
	Dbprintf("-----------------------------------------");

	cmd_send(CMD_ACK,0,0,0,0,0);
}
void MifareDesfireGetInformation(){
		
	int len = 0;
	uint8_t resp[USB_CMD_DATA_SIZE] = {0x00};
	uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00};
	byte_t cardbuf[USB_CMD_DATA_SIZE] = {0x00};
	
	/*
		1 = PCB					1
		2 = cid					2
		3 = desfire command		3 
		4-5 = crc				4  key
								5-6 crc								
		PCB == 0x0A because sending CID byte.
		CID == 0x00 first card?		
	*/
	clear_trace();
	set_tracing(TRUE);
	iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);

	// card select - information
	iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
	byte_t isOK = iso14443a_select_card(NULL, card, NULL, true, 0);
	if ( isOK == 0) {
		if (MF_DBGLEVEL >= MF_DBG_ERROR) {
			Dbprintf("Can't select card");
		}
		OnError(1);
		return;
	}

	memcpy(dataout,card->uid,7);

	LED_A_ON();
	LED_B_OFF();
	LED_C_OFF();
	
	uint8_t cmd[] = {GET_VERSION};	
	size_t cmd_len = sizeof(cmd);
	
	len =  DesfireAPDU(cmd, cmd_len, resp);
	if ( !len ) {
		print_result("ERROR <--: ", resp, len);	
		OnError(2);
		return;
	}
	
	LED_A_OFF();
	LED_B_ON();
	memcpy(dataout+7,resp+3,7);
	
	// ADDITION_FRAME 1
	cmd[0] = ADDITIONAL_FRAME;
	len =  DesfireAPDU(cmd, cmd_len, resp);
	if ( !len ) {
		print_result("ERROR <--: ", resp, len);	
		OnError(2);
		return;
	}	
	
	LED_B_OFF();
	LED_C_ON();
	memcpy(dataout+7+7,resp+3,7);

	// ADDITION_FRAME 2
	len =  DesfireAPDU(cmd, cmd_len, resp);
	if ( !len ) {
		print_result("ERROR <--: ", resp, len);	
		OnError(2);
		return;
	}
	
	memcpy(dataout+7+7+7,resp+3,14);
	
	cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout));
		
	// reset the pcb_blocknum,
	pcb_blocknum = 0;
	OnSuccess();
}