diff --git a/src/ccid/ccid2040.c b/src/ccid/ccid2040.c index 87eacd0..fc3d3c6 100644 --- a/src/ccid/ccid2040.c +++ b/src/ccid/ccid2040.c @@ -42,8 +42,6 @@ extern void do_flash(); extern void low_flash_init(); -static uint8_t itf_num; - #define USB_CCID_TIMEOUT (50) static bool waiting_timeout = false; const uint8_t *ccid_atr = NULL; @@ -204,7 +202,8 @@ queue_t card_to_ccid_q; uint8_t ccid_status = 1; void ccid_write_offset(uint16_t size, uint16_t offset) { - DEBUG_PAYLOAD(usb_get_tx()+offset,size+10); + if (*usb_get_tx() != 0x81) + DEBUG_PAYLOAD(usb_get_tx()+offset,size+10); usb_write_offset(size+10, offset); } @@ -218,14 +217,16 @@ struct ccid_header *ccid_response; struct ccid_header *ccid_header; uint8_t *rdata_gr = NULL; uint16_t rdata_bk = 0x0; + static int usb_event_handle() { uint16_t rx_read = usb_read_available(); if (rx_read >= 10) { - struct ccid_header *tccid = usb_get_rx(); - printf("%d %d %x\r\n",tccid->dwLength,rx_read-10,tccid->bMessageType); + struct ccid_header *tccid = (struct ccid_header *)usb_get_rx(); + //printf("%d %d %x\r\n",tccid->dwLength,rx_read-10,tccid->bMessageType); if (tccid->dwLength <= rx_read-10) { usb_read(rx_copy, sizeof(rx_copy)); - DEBUG_PAYLOAD(rx_copy,rx_read); + if (ccid_header->bMessageType != 0x65) + DEBUG_PAYLOAD(rx_copy,rx_read); if (ccid_header->bMessageType == 0x65) { ccid_response->bMessageType = CCID_SLOT_STATUS_RET; ccid_response->dwLength = 0; @@ -243,13 +244,10 @@ static int usb_event_handle() { ccid_response->bSeq = ccid_header->bSeq; ccid_response->abRFU0 = 0; ccid_response->abRFU1 = 0; - printf("1 %x %x %x || %x %x %x\r\n",ccid_response->apdu,apdu.rdata,ccid_response,ccid_header,ccid_header->apdu,apdu.data); + //printf("1 %x %x %x || %x %x %x\r\n",ccid_response->apdu,apdu.rdata,ccid_response,ccid_header,ccid_header->apdu,apdu.data); memcpy(apdu.rdata, ccid_atr+1, size_atr); - printf("1\r\n"); multicore_reset_core1(); - printf("1\r\n"); multicore_launch_core1(card_thread); - printf("1\r\n"); led_set_blink(BLINK_MOUNTED); ccid_status = 0; ccid_write(size_atr); @@ -269,8 +267,6 @@ static int usb_event_handle() { } else if (ccid_header->bMessageType == 0x6F) { apdu.nc = apdu.ne = 0; - printf("6f %d %x\n",ccid_header->dwLength,ccid_header->apdu); - DEBUG_PAYLOAD(apdu.header,10); if (ccid_header->dwLength == 4) { apdu.nc = apdu.ne = 0; if (apdu.ne == 0) @@ -307,10 +303,10 @@ static int usb_event_handle() { apdu.ne = 256; } } - printf("apdu.nc %d, apdu.ne %d\r\n",apdu.nc,apdu.ne); + //printf("apdu.nc %d, apdu.ne %d\r\n",apdu.nc,apdu.ne); if (apdu.header[1] == 0xc0) { - printf("apdu.ne %d, apdu.rlen %d, bk %x\r\n",apdu.ne,apdu.rlen,rdata_bk); - ccid_response = rdata_gr-10; + //printf("apdu.ne %d, apdu.rlen %d, bk %x\r\n",apdu.ne,apdu.rlen,rdata_bk); + ccid_response = (struct ccid_header *)(rdata_gr-10); *(uint16_t *)rdata_gr = rdata_bk; if (apdu.rlen <= apdu.ne) { ccid_response->bMessageType = CCID_DATA_BLOCK_RET; @@ -342,7 +338,7 @@ static int usb_event_handle() { else { apdu.sw = 0; apdu.rlen = 0; - ccid_response = usb_get_tx(); + ccid_response = (struct ccid_header *)usb_get_tx(); ccid_response->apdu = usb_get_tx()+10; apdu.rdata = ccid_response->apdu; rdata_gr = apdu.rdata; @@ -408,8 +404,9 @@ void card_thread() { goto done; } else if (m == EV_EXIT) { - if (current_app && current_app->unload) + if (current_app && current_app->unload) { current_app->unload(); + } break; } @@ -436,10 +433,10 @@ void ccid_task(void) { uint32_t m = 0x0; bool has_m = queue_try_remove(&card_to_ccid_q, &m); if (m != 0) - printf("\r\n ------ M = %d\r\n",m); + printf("\r\n ------ M = %lu\r\n",m); if (has_m) { if (m == EV_EXEC_FINISHED) { - printf("sw %x %d, %d\r\n",apdu.sw,apdu.rlen,apdu.ne); + //printf("sw %x %d, %d\r\n",apdu.sw,apdu.rlen,apdu.ne); apdu.rdata[apdu.rlen] = apdu.sw >> 8; apdu.rdata[apdu.rlen+1] = apdu.sw & 0xff; waiting_timeout = false; @@ -471,6 +468,10 @@ void ccid_task(void) { } led_set_blink(BLINK_MOUNTED); } + else if (m == EV_PRESS_BUTTON) { + uint32_t flag = wait_button() ? EV_BUTTON_TIMEOUT : EV_BUTTON_PRESSED; + queue_try_add(&ccid_to_card_q, &flag); + } /* if (m == EV_RX_DATA_READY) { c->ccid_state = ccid_handle_data(c); @@ -519,10 +520,6 @@ void ccid_task(void) { if (c->state == APDU_STATE_WAIT_COMMAND || c->state == APDU_STATE_COMMAND_CHAINING || c->state == APDU_STATE_RESULT_GET_RESPONSE) ccid_prepare_receive(c); } - else if (m == EV_PRESS_BUTTON) { - uint32_t flag = wait_button() ? EV_BUTTON_TIMEOUT : EV_BUTTON_PRESSED; - queue_try_add(&c->card_comm, &flag); - } */ } else { @@ -660,12 +657,12 @@ void execute_tasks() { } int main(void) { - ccid_header = rx_copy; + ccid_header = (struct ccid_header *)rx_copy; ccid_header->apdu = rx_copy+10; apdu.header = ccid_header->apdu; - ccid_response = usb_get_tx(); + ccid_response = (struct ccid_header *)usb_get_tx(); ccid_response->apdu = usb_get_tx()+10; apdu.rdata = ccid_response->apdu; diff --git a/src/ccid/ccid2040.h b/src/ccid/ccid2040.h index 83f8387..af2c0cf 100644 --- a/src/ccid/ccid2040.h +++ b/src/ccid/ccid2040.h @@ -45,7 +45,7 @@ extern const uint8_t historical_bytes[]; #define DEBUG_PAYLOAD(p,s) { \ printf("Payload %s (%d bytes):\r\n", #p,s);\ for (int i = 0; i < s; i += 16) {\ - printf("%07Xh : ",i+p);\ + printf("%07Xh : ",(unsigned int)(i+p));\ for (int j = 0; j < 16; j++) {\ if (j < s-i) printf("%02X ",(p)[i+j]);\ else printf(" ");\ diff --git a/src/ccid/eac.c b/src/ccid/eac.c index 4d6e149..8fcf76c 100644 --- a/src/ccid/eac.c +++ b/src/ccid/eac.c @@ -21,7 +21,6 @@ #include "mbedtls/cmac.h" static uint8_t nonce[8]; -static uint8_t auth_token[8]; static uint8_t sm_kmac[16]; static uint8_t sm_kenc[16]; static MSE_protocol sm_protocol = MSE_NONE; @@ -113,7 +112,7 @@ int sm_unwrap() { aes_decrypt(sm_kenc, sm_iv, 128, HSM_AES_MODE_CBC, body, body_size); memmove(apdu.data, body, body_size); apdu.nc = sm_remove_padding(apdu.data, body_size); - DEBUG_PAYLOAD(apdu.data, apdu.nc); + DEBUG_PAYLOAD(apdu.data, (int)apdu.nc); return CCID_OK; } @@ -129,6 +128,8 @@ int sm_wrap() { mbedtls_mpi_add_int(&ssc, &sm_mSSC, 1); mbedtls_mpi_copy(&sm_mSSC, &ssc); int r = mbedtls_mpi_write_binary(&ssc, input, sm_blocksize); + if (r != 0) + return CCID_EXEC_ERROR; input_len += sm_blocksize; mbedtls_mpi_free(&ssc); if (res_APDU_size > 0) { diff --git a/src/fs/file.c b/src/fs/file.c index e727508..5d25cbd 100644 --- a/src/fs/file.c +++ b/src/fs/file.c @@ -36,8 +36,6 @@ extern void low_flash_available(); //puts FCI in the RAPDU void process_fci(const file_t *pe, int fmd) { - uint8_t *p = res_APDU; - uint8_t buf[64]; res_APDU_size = 0; if (fmd) { res_APDU[res_APDU_size++] = 0x6f; @@ -185,7 +183,7 @@ bool authenticate_action(const file_t *ef, uint8_t op) { return true; else if (acl == 0xff) return false; - else if (acl == 0x90 || acl & 0x9F == 0x10) { + else if (acl == 0x90 || (acl & 0x9F) == 0x10) { // PIN required. if (isUserAuthenticated) { return true; @@ -222,7 +220,6 @@ void scan_flash() { } printf("SCAN\r\n"); - uintptr_t base = flash_read_uintptr(end_data_pool); for (uintptr_t base = flash_read_uintptr(end_data_pool); base >= start_data_pool; base = flash_read_uintptr(base)) { if (base == 0x0) //all is empty break; diff --git a/src/fs/flash.c b/src/fs/flash.c index f901494..de05784 100644 --- a/src/fs/flash.c +++ b/src/fs/flash.c @@ -79,7 +79,7 @@ uintptr_t allocate_free_addr(uint16_t size) { return 0x0; } //we check if |base-(next_addr+size_next_addr)| > |base-potential_addr| only if fid != 1xxx (not size blocked) - else if (addr_alg <= potential_addr && base-(next_base+flash_read_uint16(next_base+sizeof(uintptr_t)+sizeof(uintptr_t)+sizeof(uint16_t))+2*sizeof(uint16_t)+2*sizeof(uintptr_t)) > base-potential_addr && flash_read_uint16(next_base+sizeof(uintptr_t)) & 0x1000 != 0x1000) { + else if (addr_alg <= potential_addr && base-(next_base+flash_read_uint16(next_base+sizeof(uintptr_t)+sizeof(uintptr_t)+sizeof(uint16_t))+2*sizeof(uint16_t)+2*sizeof(uintptr_t)) > base-potential_addr && (flash_read_uint16(next_base+sizeof(uintptr_t)) & 0x1000) != 0x1000) { flash_program_uintptr(potential_addr, next_base); flash_program_uintptr(potential_addr+sizeof(uintptr_t), base); flash_program_uintptr(base, potential_addr); diff --git a/src/fs/low_flash.c b/src/fs/low_flash.c index 2e0d823..9eae346 100644 --- a/src/fs/low_flash.c +++ b/src/fs/low_flash.c @@ -138,7 +138,6 @@ page_flash_t *find_free_page(uintptr_t addr) { } int flash_program_block(uintptr_t addr, const uint8_t *data, size_t len) { - uintptr_t addr_alg = addr & -FLASH_SECTOR_SIZE; page_flash_t *p = NULL; if (!data || len == 0) @@ -213,7 +212,6 @@ uint8_t flash_read_uint8(uintptr_t addr) { } int flash_erase_page (uintptr_t addr, size_t page_size) { - uintptr_t addr_alg = addr & -FLASH_SECTOR_SIZE; page_flash_t *p = NULL; mutex_enter_blocking(&mtx_flash); diff --git a/src/rng/neug.c b/src/rng/neug.c index df0ade5..7d9f779 100644 --- a/src/rng/neug.c +++ b/src/rng/neug.c @@ -144,9 +144,7 @@ void *neug_task() { void neug_init(uint32_t *buf, uint8_t size) { pico_unique_board_id_t unique_id; pico_get_unique_board_id(&unique_id); - const uint32_t *u = (const uint32_t *)unique_id.id; struct rng_rb *rb = &the_ring_buffer; - int i; rb_init(rb, buf, size); diff --git a/src/usb/usb.c b/src/usb/usb.c index 9670191..b4941ac 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -45,6 +45,15 @@ static volatile bool configured = false; // Global data buffer for EP0 static uint8_t ep0_buf[64]; + +static const unsigned char *descriptor_strings[] = { + (unsigned char *) "Virtual SC", // Vendor + (unsigned char *) "CCID", // Product + (unsigned char *) "11223344", + (unsigned char *) "Config rocks", + (unsigned char *) "Interface rocks" +}; + // Struct defining the device configuration static struct usb_device_configuration dev_config = { .device_descriptor = &device_descriptor, @@ -238,22 +247,26 @@ static inline bool ep_is_tx(struct usb_endpoint_configuration *ep) { * @param buf, the data buffer to send. Only applicable if the endpoint is TX * @param len, the length of the data in buf (this example limits max len to one packet - 64 bytes) */ -void usb_start_transfer(struct usb_endpoint_configuration *ep, uint8_t *buf, uint16_t len) { +void usb_start_transfer_last(struct usb_endpoint_configuration *ep, uint8_t *buf, uint16_t len, bool last) { // We are asserting that the length is <= 64 bytes for simplicity of the example. // For multi packet transfers see the tinyusb port. assert(len <= 64); - - //printf("Start transfer of len %d on ep addr 0x%x\n", len, ep->descriptor->bEndpointAddress); + + //if (configured == false || len == 64) + printf("Start transfer\n"); // Prepare buffer control register value - uint32_t val = len | USB_BUF_CTRL_AVAIL; - printf("VAL %d (%x)\n",val,val); + uint32_t val = len | USB_BUF_CTRL_AVAIL | USB_BUF_CTRL_SEL; + //printf("VAL %d (%x)\n",val,val); if (ep_is_tx(ep)) { // Need to copy the data from the user buffer to the usb memory - memcpy((void *) ep->data_buffer, (void *) buf, len); + if (buf) + memcpy((void *) ep->data_buffer, (void *) buf, len); // Mark as full val |= USB_BUF_CTRL_FULL; + if (last) + val |= USB_BUF_CTRL_LAST; } // Set pid and flip for next transfer @@ -262,6 +275,9 @@ void usb_start_transfer(struct usb_endpoint_configuration *ep, uint8_t *buf, uin *ep->buffer_control = val; } +void usb_start_transfer(struct usb_endpoint_configuration *ep, uint8_t *buf, uint16_t len) { + usb_start_transfer_last(ep, buf, len, true); +} /** * @brief Send device descriptor to host @@ -281,6 +297,7 @@ void usb_handle_device_descriptor(volatile struct usb_setup_packet *pkt) { * * @param pkt, the setup packet received from the host. */ + void usb_handle_config_descriptor(volatile struct usb_setup_packet *pkt) { uint8_t b[128]; uint8_t *buf = &b[0]; @@ -305,14 +322,26 @@ void usb_handle_config_descriptor(volatile struct usb_setup_packet *pkt) { buf += sizeof(struct usb_endpoint_descriptor); } } - } // Send data // Get len by working out end of buffer subtract start of buffer + uint32_t len = (uint32_t) buf - (uint32_t) &b[0]; for (int off = 0; off < len; off += 64) - usb_start_transfer(usb_get_endpoint_configuration(EP0_IN_ADDR), &b[off], MIN(MIN(len-off,64),pkt->wLength)); + usb_start_transfer_last(usb_get_endpoint_configuration(EP0_IN_ADDR), b+off, MIN(len, 64),off+64>=len); + //if (len >= 64) + // usb_start_transfer(usb_get_endpoint_configuration(EP0_IN_ADDR), NULL, 0); + //usb_start_transfer(usb_get_endpoint_configuration(EP0_IN_ADDR), NULL, 0); + //usb_start_transfer(usb_get_endpoint_configuration(EP0_IN_ADDR), NULL, 64); + //usb_start_transfer(usb_get_endpoint_configuration(EP0_OUT_ADDR), NULL, 0); + usb_start_transfer(usb_get_endpoint_configuration(EP0_OUT_ADDR), NULL, 64); + /* + usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 0); + usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64); + usb_start_transfer(usb_get_endpoint_configuration(EP2_IN_ADDR), NULL, 0); + usb_start_transfer(usb_get_endpoint_configuration(EP2_IN_ADDR), NULL, 64); + */ } /** @@ -380,7 +409,7 @@ void usb_set_device_address(volatile struct usb_setup_packet *pkt) { // Set address is a bit of a strange case because we have to send a 0 length status packet first with // address 0 dev_addr = (pkt->wValue & 0xff); - printf("Set address %d\r\n", dev_addr); + //printf("Set address %d\r\n", dev_addr); // Will set address in the callback phase should_set_address = true; usb_acknowledge_out_request(); @@ -394,7 +423,7 @@ void usb_set_device_address(volatile struct usb_setup_packet *pkt) { */ void usb_set_device_configuration(volatile struct usb_setup_packet *pkt) { // Only one configuration so just acknowledge the request - printf("Device Enumerated\r\n"); + //usb_get_endpoint_configuration(EP0_OUT_ADDR)printf("Device Enumerated\r\n"); usb_acknowledge_out_request(); configured = true; } @@ -413,19 +442,19 @@ void usb_handle_setup_packet(void) { usb_get_endpoint_configuration(EP0_IN_ADDR)->next_pid = 1u; if (req_type != USB_REQ_TYPE_STANDARD) { - printf("NON STANDARD TYPE REQUEST\r\n"); + //printf("NON STANDARD TYPE REQUEST\r\n"); } else { if (req_direction == USB_DIR_OUT) { if (req == USB_REQUEST_SET_ADDRESS) { usb_set_device_address(pkt); - printf("SET ADDRESS\r\n"); + //printf("SET ADDRESS\r\n"); } else if (req == USB_REQUEST_SET_CONFIGURATION) { usb_set_device_configuration(pkt); - printf("SET CONFIGURATION\r\n"); + //printf("SET CONFIGURATION\r\n"); } else { usb_acknowledge_out_request(); - printf("Other OUT request (0x%x)\r\n", pkt->bRequest); + //printf("Other OUT request (0x%x)\r\n", pkt->bRequest); } } else if (req_direction == USB_DIR_IN) { if (req == USB_REQUEST_GET_DESCRIPTOR) { @@ -434,28 +463,28 @@ void usb_handle_setup_packet(void) { switch (descriptor_type) { case USB_DT_DEVICE: usb_handle_device_descriptor(pkt); - printf("GET DEVICE DESCRIPTOR\r\n"); + //printf("GET DEVICE DESCRIPTOR\r\n"); break; case USB_DT_CONFIG: usb_handle_config_descriptor(pkt); - printf("GET CONFIG DESCRIPTOR\r\n"); + //printf("GET CONFIG DESCRIPTOR\r\n"); break; case USB_DT_STRING: usb_handle_string_descriptor(pkt); - printf("GET STRING DESCRIPTOR\r\n"); + //printf("GET STRING DESCRIPTOR\r\n"); break; default: - printf("Unhandled GET_DESCRIPTOR type 0x%x\r\n", descriptor_type); + //printf("Unhandled GET_DESCRIPTOR type 0x%x\r\n", descriptor_type); usb_acknowledge_out_request(); } } else if (req == USB_REQUEST_GET_STATUS) { uint16_t status = 2; usb_start_transfer(usb_get_endpoint_configuration(EP0_IN_ADDR), (uint8_t *) &status, MIN(sizeof(uint16_t),pkt->wLength)); } else { - printf("Other IN request (0x%x)\r\n", pkt->bRequest); + //printf("Other IN request (0x%x)\r\n", pkt->bRequest); usb_acknowledge_out_request(); } } @@ -579,30 +608,13 @@ void ep0_out_handler(uint8_t *buf, uint16_t len) { ; } -#define DEBUG_PAYLOAD(p,s) { \ - printf("Payload %s (%d bytes):\r\n", #p,s);\ - for (int i = 0; i < s; i += 16) {\ - printf("%07Xh : ",i+p);\ - for (int j = 0; j < 16; j++) {\ - if (j < s-i) printf("%02X ",(p)[i+j]);\ - else printf(" ");\ - if (j == 7) printf(" ");\ - } printf(": "); \ - for (int j = 0; j < MIN(16,s-i); j++) {\ - printf("%c",(p)[i+j] == 0x0a || (p)[i+j] == 0x0d ? '\\' : (p)[i+j]);\ - if (j == 7) printf(" ");\ - }\ - printf("\r\n");\ - } printf("\r\n"); \ - } - // Device specific functions static uint8_t rx_buffer[4096], tx_buffer[4096]; static uint16_t w_offset = 0, r_offset = 0; void ep1_out_handler(uint8_t *buf, uint16_t len) { - printf("RX %d bytes from host\n", len); - DEBUG_PAYLOAD(buf,len); + //printf("RX %d bytes from host\n", len); + //DEBUG_PAYLOAD(buf,len); // Send data back to host uint16_t size = MIN(sizeof(rx_buffer)-w_offset,len); if (size > 0) { @@ -622,6 +634,9 @@ uint32_t usb_write_offset(uint16_t size, uint16_t roffset) { struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR); for (uint16_t offset = roffset; offset-roffset < size; offset += 64) { usb_start_transfer(ep, tx_buffer+offset, MIN(size-offset, 64)); + if (size-offset == 64) { + usb_start_transfer(ep, NULL, 0); + } } usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64); return size; diff --git a/src/usb/usb_common.h b/src/usb/usb_common.h index 689b63e..1aff14f 100644 --- a/src/usb/usb_common.h +++ b/src/usb/usb_common.h @@ -305,13 +305,6 @@ static const unsigned char lang_descriptor[] = { 0x09, 0x04 // language id = us english }; -static const unsigned char *descriptor_strings[] = { - (unsigned char *) "Virtual SC", // Vendor - (unsigned char *) "CCID", // Product - (unsigned char *) "11223344", - (unsigned char *) "Configuration rocks", - (unsigned char *) "Interface rocks" -}; #define USB_REQ_CCID 0xA1