From c4f1bc576b9d72fbc987efbe78c85fc23ab35bb6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 23 Aug 2010 14:40:33 +0900 Subject: [PATCH] works now. --- src/Makefile | 2 +- src/gnuk.h | 22 +- src/gpg-data.c | 221 +++++++++ src/gpg-data.s | 1284 ++++++++++++++++++++++++++++++++++++++++++++++++ src/gpg.c | 548 ++++++++------------- src/icc.c | 886 --------------------------------- src/main.c | 4 +- src/usb-icc.c | 529 +++++++++++--------- src/usb_desc.c | 2 +- 9 files changed, 2015 insertions(+), 1483 deletions(-) create mode 100644 src/gpg-data.c create mode 100644 src/gpg-data.s delete mode 100644 src/icc.c diff --git a/src/Makefile b/src/Makefile index 98139d1..37c34e9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -82,7 +82,7 @@ CSRC = $(PORTSRC) \ # List ASM source files here ASMSRC = $(PORTASM) \ - $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/vectors.s + $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/vectors.s gpg-data.s INCDIR = $(STMUSBINCDIR) $(USBCDCDIR) \ $(PORTINC) $(KERNINC) $(TESTINC) \ diff --git a/src/gnuk.h b/src/gnuk.h index 4ad4e5b..f10994f 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -1,9 +1,25 @@ extern Thread *blinker_thread; + +extern void put_byte (uint8_t b); + +extern void _write (const char *, int); + +extern size_t strlen(const char *s); +extern void *memcpy(void *dest, const void *src, size_t n); + +/* + * Interface between ICC<-->GPG + */ extern Thread *icc_thread; extern Thread *gpg_thread; +#define USB_BUF_SIZE 64 + #define EV_EXEC_FINISHED (eventmask_t)2 /* GPG Execution finished */ -#define put_string(STR) - -extern void _write (char *, int); +#define MAX_CMD_APDU_SIZE (256) /* XXX: Check OpenPGPcard protocol */ +#define MAX_RES_APDU_SIZE (256+2) /* Data + status */ +extern uint8_t cmd_APDU[MAX_CMD_APDU_SIZE]; +extern uint8_t res_APDU[MAX_RES_APDU_SIZE]; +extern int cmd_APDU_size; +extern int res_APDU_size; diff --git a/src/gpg-data.c b/src/gpg-data.c new file mode 100644 index 0000000..e1f2d2d --- /dev/null +++ b/src/gpg-data.c @@ -0,0 +1,221 @@ +const char const select_file_TOP_result[] __attribute__ ((aligned (1))) = + { 0x00, 0x00, 0x0b, 0x10, 0x3f, 0x00, 0x38, 0xff, 0xff, 0x44, + 0x44, 0x01, 0x05, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 }; + +const char const get_data_64_result[] __attribute__ ((aligned (1))) = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + +const char const get_data_5e_result[] __attribute__ ((aligned (1))) = + { /* Login Data */ + 'g', 'n', 'i', 'i', 'b', 'e' + }; + +/***** do_6e is compound object of { do_47, do_4f, do_c0,..,c6,cd }*/ +const char const do_6e_head[] __attribute__ ((aligned (1))) = + { + 0x6e, 0x81, 2*10+3+16+1+1+1+1+7+60+60+12 /* (> 128) */ + }; + +const char const do_47[] __attribute__ ((aligned (1))) = /* Card Capabilities */ + { + 0x47, 3, + 0x00 /*???*/, 0x00 /*???*/, 0x00 /*???*/ + /* XXX: See ISO 7816-4 for first byte and second byte */ + }; + +const char const do_4f[] __attribute__ ((aligned (1))) = /* AID */ + { + 0x4f, 16, + 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, + 0x01, 0x01, /* Version 1.1 */ + 0xF5, 0x17, /* Manufacturer (FSIJ) */ + 0x00, 0x00, 0x00, 0x02, /* Serial */ + 0x00, 0x00 + }; + +const char const do_c0[] __attribute__ ((aligned (1))) = + { /* Extended capability */ + 0xc0, 1, + 0x00 + }; + +const char const do_c1[] __attribute__ ((aligned (1))) = + { /* Algorithm Attributes Signature ??? */ + 0xc1, 1, + 0x01, /* RSA */ /*??? should have length modulus, length exponent ??? */ + }; + +const char const do_c2[] __attribute__ ((aligned (1))) = + { /* Algorithm Attributes Decryption ??? */ + 0xc2, 1, + 0x00 + }; + +const char const do_c3[] __attribute__ ((aligned (1))) = + { /* Algorithm Attributes Authentication ??? */ + 0xc3, 1, + 0x00 + }; + +const char const do_c4[] __attribute__ ((aligned (1))) = + { /* CHV status bytes */ + 0xc4, 7, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01 + }; + +const char const do_c5[] __attribute__ ((aligned (1))) = + { + 0xc5, 60, + /* sign */ + 0x5b, 0x85, 0x67, 0x3c, 0x08, 0x4f, 0x80, 0x0d, + 0x54, 0xac, 0x95, 0x1c, 0x35, 0x15, 0x97, 0xcc, + 0xe5, 0x02, 0xbf, 0xcd, + /* enc */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + /* auth */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + +const char const do_c6[] __attribute__ ((aligned (1))) = /* CA Fingerprints */ + { + 0xc6, 60, + /* c6 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + /* c7 */ + 0x5b, 0x85, 0x67, 0x3c, 0x08, 0x4f, 0x80, 0x0d, + 0x54, 0xac, 0x95, 0x1c, 0x35, 0x15, 0x97, 0xcc, + 0xe5, 0x02, 0xbf, 0xcd, + /* c8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + +const char const do_cd[] __attribute__ ((aligned (1))) = + { /* Generation time */ + 0xcd, 12, + 0x00, 0x00, 0x00, 0x00, + 0x49, 0x8a, 0x50, 0x7a, /* 0xce */ + 0x00, 0x00, 0x00, 0x00, + }; +/*************************/ + +/***** do_65 is compound object of { do_5b, do_5f2d, do_5f35 }*/ +const char const do_65_head[] __attribute__ ((aligned (1))) = + { + 0x65, 2*1+3*2+12+2+1 + }; + +const char const do_5b[] __attribute__ ((aligned (1))) = + { + 0x5b, 12, + 'N', 'I', 'I', 'B', 'E', ' ', 'Y', 'u', 't', 'a', 'k', 'a' + }; + +const char const do_5f2d[] __attribute__ ((aligned (1))) = + { + 0x5f, 0x2d, 2, + 'j', 'a' + }; + +const char const do_5f35[] __attribute__ ((aligned (1))) = + { + 0x5f, 0x35, 1, + '1' + }; +/****************************/ + +/* do_7a is compound object of { do_93 } */ +const char const do_7a_head[] __attribute__ ((aligned (1))) = + { + 0x7a, 2+3 + }; + +/* Digital Signature Counter (3-bytes) */ +const char const do_93[] __attribute__ ((aligned (1))) = + { + 0x93, 3, + 0, 0, 0 + }; +/****************************/ + + +const char const do_5f50[] __attribute__ ((aligned (1))) = + { + 0x5f, 0x50, 20, + 'h', 't', 't', 'p', ':', '/', '/', 'w', 'w', 'w', + '.', 'f', 's', 'i', 'j', '.', 'o', 'r', 'g', '/' + }; + +/* Historycal bytes */ +const char const do_5f52[] __attribute__ ((aligned (1))) = + { + 0x5f, 0x52, 10, + 0x00, + 0x31, 0xc0, /* full DF name, partial DF name supported */ + 0x73, + 0xc0, 0x01, 0x00, /* full DF name, partial DF name supported */ + /* 1-byte */ + /* no command chaining, no ext lc_le */ + 0x00, 0x90, 0x00 /* Status info */ + }; + +const char const get_data_rb_result[] __attribute__ ((aligned (1))) = { + 0x5a, 0x4, 0x01, 0x02, 0x03, 0x04 +}; + +const char const get_data_sigkey_result[] __attribute__ ((aligned (1))) = { + 0x7f, 0x49, 0x81, 0x88, + 0x81, 0x81, 0x80, + /* 128-byte data */ + /* modulus */ + 0xdb, 0xca, 0x58, 0x74, 0x44, 0x8e, 0x1a, 0x2c, + 0xa0, 0x91, 0xac, 0xc4, 0xe2, 0x77, 0x2b, 0x90, + 0xcf, 0x3c, 0x7e, 0x81, 0xdc, 0x8d, 0xb0, 0xe2, + 0xf1, 0xfe, 0x56, 0x7e, 0x54, 0x57, 0xf0, 0xd8, + 0xb1, 0xb1, 0xaa, 0x9d, 0x8f, 0xb0, 0x56, 0x01, + 0xaa, 0x6b, 0xa7, 0x2e, 0xce, 0x01, 0x20, 0xd2, + 0xf8, 0xf5, 0x85, 0x3a, 0xc2, 0x73, 0xf9, 0x66, + 0x30, 0x28, 0x65, 0x5e, 0x3f, 0x91, 0xaf, 0x3f, + 0xf6, 0x1c, 0x31, 0x2f, 0xa2, 0x91, 0xbb, 0x41, + 0x91, 0x41, 0x08, 0x0a, 0xc5, 0x3e, 0x39, 0xda, + 0x2f, 0x6f, 0x58, 0x51, 0xe2, 0xd2, 0xe9, 0x42, + 0x8a, 0x7b, 0x72, 0x7b, 0x15, 0xf6, 0xf6, 0x6a, + 0x12, 0x6e, 0x0c, 0x15, 0x24, 0x13, 0x16, 0x55, + 0x3a, 0xf1, 0xa7, 0x16, 0x3e, 0xe9, 0xc8, 0x3d, + 0x2c, 0x3d, 0xae, 0x51, 0x2d, 0x7f, 0xef, 0x92, + 0x25, 0x6a, 0xbb, 0x02, 0x03, 0x70, 0x45, 0x3d, + /* public exponent */ + 0x82, 3, 0x01, 0x00, 0x01 +}; + +const char const get_data_enckey_result[] __attribute__ ((aligned (1))) = { + 0x7f, 0x49, 0x81, 0x88, + 0x81, 0x81, 0x80, + /* 128-byte data */ + 0xB2, 0x19, 0x91, 0x42, 0x27, 0xC7, 0x97, 0xFE, + 0x92, 0x64, 0x42, 0xCA, 0xE3, 0x66, 0x4D, 0xD0, + 0x31, 0xE4, 0x10, 0x31, 0x0F, 0xC7, 0x07, 0x4A, + 0xAA, 0x6D, 0x31, 0xA2, 0x88, 0x68, 0xAF, 0x45, + 0x8E, 0x42, 0x12, 0xFF, 0xB6, 0xEF, 0x6E, 0x54, + 0x7E, 0x51, 0x8E, 0xBC, 0xE8, 0x18, 0x79, 0xA7, + 0xBC, 0xA8, 0x14, 0x8B, 0xE7, 0x91, 0x57, 0x38, + 0xCE, 0x4F, 0x6E, 0x16, 0x48, 0xCB, 0xD6, 0x0B, + 0x3A, 0x53, 0x70, 0xF3, 0xFC, 0xFA, 0xC3, 0x58, + 0x3D, 0xE7, 0x2A, 0x5E, 0xDD, 0xE1, 0x38, 0x82, + 0x57, 0x87, 0x3A, 0xDC, 0x34, 0xDE, 0xCD, 0x5D, + 0x33, 0x1C, 0xAB, 0xB0, 0x1B, 0xEE, 0x82, 0x43, + 0x7B, 0xAC, 0xF8, 0xF0, 0xB2, 0x62, 0xB2, 0x6D, + 0x09, 0xED, 0x2E, 0xD1, 0xBA, 0xB8, 0xC6, 0x96, + 0xFA, 0x3E, 0xB4, 0xE3, 0xFE, 0x68, 0xF9, 0x51, + 0x9A, 0x8C, 0x8B, 0x20, 0x93, 0xD0, 0x2E, 0x0F, + 0x82, 3, 0x01, 0x00, 0x01 +}; diff --git a/src/gpg-data.s b/src/gpg-data.s new file mode 100644 index 0000000..331f3d6 --- /dev/null +++ b/src/gpg-data.s @@ -0,0 +1,1284 @@ + .syntax unified + .cpu cortex-m3 + .fpu softvfp + .eabi_attribute 20, 1 + .eabi_attribute 21, 1 + .eabi_attribute 23, 3 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 1 + .eabi_attribute 30, 6 + .eabi_attribute 18, 4 + .thumb + .file "gpg-data.c" + .section .debug_abbrev,"",%progbits +.Ldebug_abbrev0: + .section .debug_info,"",%progbits +.Ldebug_info0: + .section .debug_line,"",%progbits +.Ldebug_line0: + .text +.Ltext0: + .global select_file_TOP_result + .section .rodata + .type select_file_TOP_result, %object + .size select_file_TOP_result, 20 +select_file_TOP_result: + .byte 0 + .byte 0 + .byte 11 + .byte 16 + .byte 63 + .byte 0 + .byte 56 + .byte -1 + .byte -1 + .byte 68 + .byte 68 + .byte 1 + .byte 5 + .byte 3 + .byte 0 + .byte 2 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .global get_data_64_result + .type get_data_64_result, %object + .size get_data_64_result, 7 +get_data_64_result: + .space 7 + .global get_data_5e_result + .type get_data_5e_result, %object + .size get_data_5e_result, 6 +get_data_5e_result: + .byte 103 + .byte 110 + .byte 105 + .byte 105 + .byte 98 + .byte 101 + .global do_6e_head + .type do_6e_head, %object + .size do_6e_head, 3 +do_6e_head: + .byte 110 + .byte -127 + .byte -74 + .global do_47 + .type do_47, %object + .size do_47, 5 +do_47: + .byte 71 + .byte 3 + .byte 0 + .byte 0 + .byte 0 + .global do_4f + .type do_4f, %object + .size do_4f, 18 +do_4f: + .byte 79 + .byte 16 + .byte -46 + .byte 118 + .byte 0 + .byte 1 + .byte 36 + .byte 1 + .byte 1 + .byte 1 + .byte -11 + .byte 23 + .byte 0 + .byte 0 + .byte 0 + .byte 2 + .byte 0 + .byte 0 + .global do_c0 + .type do_c0, %object + .size do_c0, 3 +do_c0: + .byte -64 + .byte 1 + .byte 0 + .global do_c1 + .type do_c1, %object + .size do_c1, 3 +do_c1: + .byte -63 + .byte 1 + .byte 1 + .global do_c2 + .type do_c2, %object + .size do_c2, 3 +do_c2: + .byte -62 + .byte 1 + .byte 0 + .global do_c3 + .type do_c3, %object + .size do_c3, 3 +do_c3: + .byte -61 + .byte 1 + .byte 0 + .global do_c4 + .type do_c4, %object + .size do_c4, 9 +do_c4: + .byte -60 + .byte 7 + .byte 1 + .byte 0 + .byte 0 + .byte 0 + .byte 1 + .byte 1 + .byte 1 + .global do_c5 + .type do_c5, %object + .size do_c5, 62 +do_c5: + .byte -59 + .byte 60 + .byte 91 + .byte -123 + .byte 103 + .byte 60 + .byte 8 + .byte 79 + .byte -128 + .byte 13 + .byte 84 + .byte -84 + .byte -107 + .byte 28 + .byte 53 + .byte 21 + .byte -105 + .byte -52 + .byte -27 + .byte 2 + .byte -65 + .byte -51 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .global do_c6 + .type do_c6, %object + .size do_c6, 62 +do_c6: + .byte -58 + .byte 60 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 91 + .byte -123 + .byte 103 + .byte 60 + .byte 8 + .byte 79 + .byte -128 + .byte 13 + .byte 84 + .byte -84 + .byte -107 + .byte 28 + .byte 53 + .byte 21 + .byte -105 + .byte -52 + .byte -27 + .byte 2 + .byte -65 + .byte -51 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .global do_cd + .type do_cd, %object + .size do_cd, 14 +do_cd: + .byte -51 + .byte 12 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 73 + .byte -118 + .byte 80 + .byte 122 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .global do_65_head + .type do_65_head, %object + .size do_65_head, 2 +do_65_head: + .byte 101 + .byte 23 + .global do_5b + .type do_5b, %object + .size do_5b, 14 +do_5b: + .byte 91 + .byte 12 + .byte 78 + .byte 73 + .byte 73 + .byte 66 + .byte 69 + .byte 32 + .byte 89 + .byte 117 + .byte 116 + .byte 97 + .byte 107 + .byte 97 + .global do_5f2d + .type do_5f2d, %object + .size do_5f2d, 5 +do_5f2d: + .byte 95 + .byte 45 + .byte 2 + .byte 106 + .byte 97 + .global do_5f35 + .type do_5f35, %object + .size do_5f35, 4 +do_5f35: + .byte 95 + .byte 53 + .byte 1 + .byte 49 + .global do_7a_head + .type do_7a_head, %object + .size do_7a_head, 2 +do_7a_head: + .byte 122 + .byte 5 + .global do_93 + .type do_93, %object + .size do_93, 5 +do_93: + .byte -109 + .byte 3 + .byte 0 + .byte 0 + .byte 0 + .global do_5f50 + .type do_5f50, %object + .size do_5f50, 23 +do_5f50: + .byte 95 + .byte 80 + .byte 20 + .byte 104 + .byte 116 + .byte 116 + .byte 112 + .byte 58 + .byte 47 + .byte 47 + .byte 119 + .byte 119 + .byte 119 + .byte 46 + .byte 102 + .byte 115 + .byte 105 + .byte 106 + .byte 46 + .byte 111 + .byte 114 + .byte 103 + .byte 47 + .global do_5f52 + .type do_5f52, %object + .size do_5f52, 13 +do_5f52: + .byte 95 + .byte 82 + .byte 10 + .byte 0 + .byte 49 + .byte -64 + .byte 115 + .byte -64 + .byte 1 + .byte 0 + .byte 0 + .byte -112 + .byte 0 + .global get_data_rb_result + .type get_data_rb_result, %object + .size get_data_rb_result, 6 +get_data_rb_result: + .byte 90 + .byte 4 + .byte 1 + .byte 2 + .byte 3 + .byte 4 + .global get_data_sigkey_result + .type get_data_sigkey_result, %object + .size get_data_sigkey_result, 140 +get_data_sigkey_result: + .byte 127 + .byte 73 + .byte -127 + .byte -120 + .byte -127 + .byte -127 + .byte -128 + .byte -37 + .byte -54 + .byte 88 + .byte 116 + .byte 68 + .byte -114 + .byte 26 + .byte 44 + .byte -96 + .byte -111 + .byte -84 + .byte -60 + .byte -30 + .byte 119 + .byte 43 + .byte -112 + .byte -49 + .byte 60 + .byte 126 + .byte -127 + .byte -36 + .byte -115 + .byte -80 + .byte -30 + .byte -15 + .byte -2 + .byte 86 + .byte 126 + .byte 84 + .byte 87 + .byte -16 + .byte -40 + .byte -79 + .byte -79 + .byte -86 + .byte -99 + .byte -113 + .byte -80 + .byte 86 + .byte 1 + .byte -86 + .byte 107 + .byte -89 + .byte 46 + .byte -50 + .byte 1 + .byte 32 + .byte -46 + .byte -8 + .byte -11 + .byte -123 + .byte 58 + .byte -62 + .byte 115 + .byte -7 + .byte 102 + .byte 48 + .byte 40 + .byte 101 + .byte 94 + .byte 63 + .byte -111 + .byte -81 + .byte 63 + .byte -10 + .byte 28 + .byte 49 + .byte 47 + .byte -94 + .byte -111 + .byte -69 + .byte 65 + .byte -111 + .byte 65 + .byte 8 + .byte 10 + .byte -59 + .byte 62 + .byte 57 + .byte -38 + .byte 47 + .byte 111 + .byte 88 + .byte 81 + .byte -30 + .byte -46 + .byte -23 + .byte 66 + .byte -118 + .byte 123 + .byte 114 + .byte 123 + .byte 21 + .byte -10 + .byte -10 + .byte 106 + .byte 18 + .byte 110 + .byte 12 + .byte 21 + .byte 36 + .byte 19 + .byte 22 + .byte 85 + .byte 58 + .byte -15 + .byte -89 + .byte 22 + .byte 62 + .byte -23 + .byte -56 + .byte 61 + .byte 44 + .byte 61 + .byte -82 + .byte 81 + .byte 45 + .byte 127 + .byte -17 + .byte -110 + .byte 37 + .byte 106 + .byte -69 + .byte 2 + .byte 3 + .byte 112 + .byte 69 + .byte 61 + .byte -126 + .byte 3 + .byte 1 + .byte 0 + .byte 1 + .global get_data_enckey_result + .type get_data_enckey_result, %object + .size get_data_enckey_result, 140 +get_data_enckey_result: + .byte 127 + .byte 73 + .byte -127 + .byte -120 + .byte -127 + .byte -127 + .byte -128 + .byte -78 + .byte 25 + .byte -111 + .byte 66 + .byte 39 + .byte -57 + .byte -105 + .byte -2 + .byte -110 + .byte 100 + .byte 66 + .byte -54 + .byte -29 + .byte 102 + .byte 77 + .byte -48 + .byte 49 + .byte -28 + .byte 16 + .byte 49 + .byte 15 + .byte -57 + .byte 7 + .byte 74 + .byte -86 + .byte 109 + .byte 49 + .byte -94 + .byte -120 + .byte 104 + .byte -81 + .byte 69 + .byte -114 + .byte 66 + .byte 18 + .byte -1 + .byte -74 + .byte -17 + .byte 110 + .byte 84 + .byte 126 + .byte 81 + .byte -114 + .byte -68 + .byte -24 + .byte 24 + .byte 121 + .byte -89 + .byte -68 + .byte -88 + .byte 20 + .byte -117 + .byte -25 + .byte -111 + .byte 87 + .byte 56 + .byte -50 + .byte 79 + .byte 110 + .byte 22 + .byte 72 + .byte -53 + .byte -42 + .byte 11 + .byte 58 + .byte 83 + .byte 112 + .byte -13 + .byte -4 + .byte -6 + .byte -61 + .byte 88 + .byte 61 + .byte -25 + .byte 42 + .byte 94 + .byte -35 + .byte -31 + .byte 56 + .byte -126 + .byte 87 + .byte -121 + .byte 58 + .byte -36 + .byte 52 + .byte -34 + .byte -51 + .byte 93 + .byte 51 + .byte 28 + .byte -85 + .byte -80 + .byte 27 + .byte -18 + .byte -126 + .byte 67 + .byte 123 + .byte -84 + .byte -8 + .byte -16 + .byte -78 + .byte 98 + .byte -78 + .byte 109 + .byte 9 + .byte -19 + .byte 46 + .byte -47 + .byte -70 + .byte -72 + .byte -58 + .byte -106 + .byte -6 + .byte 62 + .byte -76 + .byte -29 + .byte -2 + .byte 104 + .byte -7 + .byte 81 + .byte -102 + .byte -116 + .byte -117 + .byte 32 + .byte -109 + .byte -48 + .byte 46 + .byte 15 + .byte -126 + .byte 3 + .byte 1 + .byte 0 + .byte 1 + .text +.Letext0: + .file 1 "gpg-data.c" + .section .debug_info + .4byte 0x34b + .2byte 0x2 + .4byte .Ldebug_abbrev0 + .byte 0x4 + .uleb128 0x1 + .4byte .LASF25 + .byte 0x1 + .4byte .LASF26 + .4byte .LASF27 + .4byte .Ltext0 + .4byte .Letext0 + .4byte .Ldebug_line0 + .uleb128 0x2 + .4byte 0x38 + .4byte 0x35 + .uleb128 0x3 + .4byte 0x35 + .byte 0x13 + .byte 0x0 + .uleb128 0x4 + .byte 0x4 + .byte 0x7 + .uleb128 0x5 + .byte 0x1 + .byte 0x8 + .4byte .LASF28 + .uleb128 0x6 + .4byte .LASF0 + .byte 0x1 + .byte 0x1 + .4byte 0x51 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte select_file_TOP_result + .uleb128 0x7 + .4byte 0x25 + .uleb128 0x2 + .4byte 0x38 + .4byte 0x66 + .uleb128 0x3 + .4byte 0x35 + .byte 0x6 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF1 + .byte 0x1 + .byte 0x5 + .4byte 0x78 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte get_data_64_result + .uleb128 0x7 + .4byte 0x56 + .uleb128 0x2 + .4byte 0x38 + .4byte 0x8d + .uleb128 0x3 + .4byte 0x35 + .byte 0x5 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF2 + .byte 0x1 + .byte 0xa + .4byte 0x9f + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte get_data_5e_result + .uleb128 0x7 + .4byte 0x7d + .uleb128 0x2 + .4byte 0x38 + .4byte 0xb4 + .uleb128 0x3 + .4byte 0x35 + .byte 0x2 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF3 + .byte 0x1 + .byte 0x10 + .4byte 0xc6 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_6e_head + .uleb128 0x7 + .4byte 0xa4 + .uleb128 0x2 + .4byte 0x38 + .4byte 0xdb + .uleb128 0x3 + .4byte 0x35 + .byte 0x4 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF4 + .byte 0x1 + .byte 0x15 + .4byte 0xed + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_47 + .uleb128 0x7 + .4byte 0xcb + .uleb128 0x2 + .4byte 0x38 + .4byte 0x102 + .uleb128 0x3 + .4byte 0x35 + .byte 0x11 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF5 + .byte 0x1 + .byte 0x1c + .4byte 0x114 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_4f + .uleb128 0x7 + .4byte 0xf2 + .uleb128 0x6 + .4byte .LASF6 + .byte 0x1 + .byte 0x26 + .4byte 0x12b + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_c0 + .uleb128 0x7 + .4byte 0xa4 + .uleb128 0x6 + .4byte .LASF7 + .byte 0x1 + .byte 0x2c + .4byte 0x142 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_c1 + .uleb128 0x7 + .4byte 0xa4 + .uleb128 0x6 + .4byte .LASF8 + .byte 0x1 + .byte 0x32 + .4byte 0x159 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_c2 + .uleb128 0x7 + .4byte 0xa4 + .uleb128 0x6 + .4byte .LASF9 + .byte 0x1 + .byte 0x38 + .4byte 0x170 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_c3 + .uleb128 0x7 + .4byte 0xa4 + .uleb128 0x2 + .4byte 0x38 + .4byte 0x185 + .uleb128 0x3 + .4byte 0x35 + .byte 0x8 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF10 + .byte 0x1 + .byte 0x3e + .4byte 0x197 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_c4 + .uleb128 0x7 + .4byte 0x175 + .uleb128 0x2 + .4byte 0x38 + .4byte 0x1ac + .uleb128 0x3 + .4byte 0x35 + .byte 0x3d + .byte 0x0 + .uleb128 0x6 + .4byte .LASF11 + .byte 0x1 + .byte 0x44 + .4byte 0x1be + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_c5 + .uleb128 0x7 + .4byte 0x19c + .uleb128 0x6 + .4byte .LASF12 + .byte 0x1 + .byte 0x55 + .4byte 0x1d5 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_c6 + .uleb128 0x7 + .4byte 0x19c + .uleb128 0x2 + .4byte 0x38 + .4byte 0x1ea + .uleb128 0x3 + .4byte 0x35 + .byte 0xd + .byte 0x0 + .uleb128 0x6 + .4byte .LASF13 + .byte 0x1 + .byte 0x66 + .4byte 0x1fc + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_cd + .uleb128 0x7 + .4byte 0x1da + .uleb128 0x2 + .4byte 0x38 + .4byte 0x211 + .uleb128 0x3 + .4byte 0x35 + .byte 0x1 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF14 + .byte 0x1 + .byte 0x70 + .4byte 0x223 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_65_head + .uleb128 0x7 + .4byte 0x201 + .uleb128 0x6 + .4byte .LASF15 + .byte 0x1 + .byte 0x75 + .4byte 0x23a + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_5b + .uleb128 0x7 + .4byte 0x1da + .uleb128 0x6 + .4byte .LASF16 + .byte 0x1 + .byte 0x7b + .4byte 0x251 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_5f2d + .uleb128 0x7 + .4byte 0xcb + .uleb128 0x2 + .4byte 0x38 + .4byte 0x266 + .uleb128 0x3 + .4byte 0x35 + .byte 0x3 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF17 + .byte 0x1 + .byte 0x81 + .4byte 0x278 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_5f35 + .uleb128 0x7 + .4byte 0x256 + .uleb128 0x6 + .4byte .LASF18 + .byte 0x1 + .byte 0x89 + .4byte 0x28f + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_7a_head + .uleb128 0x7 + .4byte 0x201 + .uleb128 0x6 + .4byte .LASF19 + .byte 0x1 + .byte 0x8f + .4byte 0x2a6 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_93 + .uleb128 0x7 + .4byte 0xcb + .uleb128 0x2 + .4byte 0x38 + .4byte 0x2bb + .uleb128 0x3 + .4byte 0x35 + .byte 0x16 + .byte 0x0 + .uleb128 0x6 + .4byte .LASF20 + .byte 0x1 + .byte 0x97 + .4byte 0x2cd + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_5f50 + .uleb128 0x7 + .4byte 0x2ab + .uleb128 0x2 + .4byte 0x38 + .4byte 0x2e2 + .uleb128 0x3 + .4byte 0x35 + .byte 0xc + .byte 0x0 + .uleb128 0x6 + .4byte .LASF21 + .byte 0x1 + .byte 0x9f + .4byte 0x2f4 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte do_5f52 + .uleb128 0x7 + .4byte 0x2d2 + .uleb128 0x6 + .4byte .LASF22 + .byte 0x1 + .byte 0xab + .4byte 0x30b + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte get_data_rb_result + .uleb128 0x7 + .4byte 0x7d + .uleb128 0x2 + .4byte 0x38 + .4byte 0x320 + .uleb128 0x3 + .4byte 0x35 + .byte 0x8b + .byte 0x0 + .uleb128 0x6 + .4byte .LASF23 + .byte 0x1 + .byte 0xaf + .4byte 0x332 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte get_data_sigkey_result + .uleb128 0x7 + .4byte 0x310 + .uleb128 0x6 + .4byte .LASF24 + .byte 0x1 + .byte 0xc8 + .4byte 0x349 + .byte 0x1 + .byte 0x5 + .byte 0x3 + .4byte get_data_enckey_result + .uleb128 0x7 + .4byte 0x310 + .byte 0x0 + .section .debug_abbrev + .uleb128 0x1 + .uleb128 0x11 + .byte 0x1 + .uleb128 0x25 + .uleb128 0xe + .uleb128 0x13 + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x1b + .uleb128 0xe + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x1 + .uleb128 0x10 + .uleb128 0x6 + .byte 0x0 + .byte 0x0 + .uleb128 0x2 + .uleb128 0x1 + .byte 0x1 + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x1 + .uleb128 0x13 + .byte 0x0 + .byte 0x0 + .uleb128 0x3 + .uleb128 0x21 + .byte 0x0 + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2f + .uleb128 0xb + .byte 0x0 + .byte 0x0 + .uleb128 0x4 + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .byte 0x0 + .byte 0x0 + .uleb128 0x5 + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .byte 0x0 + .byte 0x0 + .uleb128 0x6 + .uleb128 0x34 + .byte 0x0 + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x3f + .uleb128 0xc + .uleb128 0x2 + .uleb128 0xa + .byte 0x0 + .byte 0x0 + .uleb128 0x7 + .uleb128 0x26 + .byte 0x0 + .uleb128 0x49 + .uleb128 0x13 + .byte 0x0 + .byte 0x0 + .byte 0x0 + .section .debug_pubnames,"",%progbits + .4byte 0x179 + .2byte 0x2 + .4byte .Ldebug_info0 + .4byte 0x34f + .4byte 0x3f + .ascii "select_file_TOP_result\000" + .4byte 0x66 + .ascii "get_data_64_result\000" + .4byte 0x8d + .ascii "get_data_5e_result\000" + .4byte 0xb4 + .ascii "do_6e_head\000" + .4byte 0xdb + .ascii "do_47\000" + .4byte 0x102 + .ascii "do_4f\000" + .4byte 0x119 + .ascii "do_c0\000" + .4byte 0x130 + .ascii "do_c1\000" + .4byte 0x147 + .ascii "do_c2\000" + .4byte 0x15e + .ascii "do_c3\000" + .4byte 0x185 + .ascii "do_c4\000" + .4byte 0x1ac + .ascii "do_c5\000" + .4byte 0x1c3 + .ascii "do_c6\000" + .4byte 0x1ea + .ascii "do_cd\000" + .4byte 0x211 + .ascii "do_65_head\000" + .4byte 0x228 + .ascii "do_5b\000" + .4byte 0x23f + .ascii "do_5f2d\000" + .4byte 0x266 + .ascii "do_5f35\000" + .4byte 0x27d + .ascii "do_7a_head\000" + .4byte 0x294 + .ascii "do_93\000" + .4byte 0x2bb + .ascii "do_5f50\000" + .4byte 0x2e2 + .ascii "do_5f52\000" + .4byte 0x2f9 + .ascii "get_data_rb_result\000" + .4byte 0x320 + .ascii "get_data_sigkey_result\000" + .4byte 0x337 + .ascii "get_data_enckey_result\000" + .4byte 0x0 + .section .debug_str,"MS",%progbits,1 +.LASF22: + .ascii "get_data_rb_result\000" +.LASF4: + .ascii "do_47\000" +.LASF1: + .ascii "get_data_64_result\000" +.LASF16: + .ascii "do_5f2d\000" +.LASF9: + .ascii "do_c3\000" +.LASF10: + .ascii "do_c4\000" +.LASF14: + .ascii "do_65_head\000" +.LASF24: + .ascii "get_data_enckey_result\000" +.LASF20: + .ascii "do_5f50\000" +.LASF2: + .ascii "get_data_5e_result\000" +.LASF0: + .ascii "select_file_TOP_result\000" +.LASF25: + .ascii "GNU C 4.4.2\000" +.LASF17: + .ascii "do_5f35\000" +.LASF28: + .ascii "char\000" +.LASF19: + .ascii "do_93\000" +.LASF21: + .ascii "do_5f52\000" +.LASF6: + .ascii "do_c0\000" +.LASF7: + .ascii "do_c1\000" +.LASF8: + .ascii "do_c2\000" +.LASF3: + .ascii "do_6e_head\000" +.LASF26: + .ascii "gpg-data.c\000" +.LASF11: + .ascii "do_c5\000" +.LASF12: + .ascii "do_c6\000" +.LASF23: + .ascii "get_data_sigkey_result\000" +.LASF13: + .ascii "do_cd\000" +.LASF27: + .ascii "gnuk/src\000" +.LASF5: + .ascii "do_4f\000" +.LASF15: + .ascii "do_5b\000" +.LASF18: + .ascii "do_7a_head\000" + .ident "GCC: (GNU) 4.4.2" diff --git a/src/gpg.c b/src/gpg.c index df45114..63185c1 100644 --- a/src/gpg.c +++ b/src/gpg.c @@ -25,7 +25,35 @@ #include "hal.h" #include "gnuk.h" -#define RSA_SIGNATURE_LENGTH 256 /* 256 byte == 2048-bit */ +static void +put_hex (uint8_t nibble) +{ + uint8_t c; + + if (nibble < 0x0a) + c = '0' + nibble; + else + c = 'a' + nibble - 0x0a; + + _write (&c, 1); +} + +void +put_byte (uint8_t b) +{ + put_hex (b >> 4); + put_hex (b &0x0f); + _write ("\r\n", 2); +} + +static void +put_string (const char *s) +{ + _write (s, strlen (s)); +} + + +#define RSA_SIGNATURE_LENGTH 128 /* 256 byte == 2048-bit */ extern unsigned char *rsa_sign (unsigned char *); #define INS_PUT_DATA 0xDA @@ -37,162 +65,31 @@ extern unsigned char *rsa_sign (unsigned char *); #define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR 0x47 #define INS_PSO 0x2A -static const char const select_file_TOP_result[] = - { 0x00, 0x00, 0x0b, 0x10, 0x3f, 0x00, 0x38, 0xff, 0xff, 0x44, - 0x44, 0x01, 0x05, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 }; - -static const char const get_data_64_result[] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - -static const char const get_data_5e_result[] = - { /* Login Data */ - 'g', 'n', 'i', 'i', 'b', 'e' - }; - -/***** do_65 is compound object of { do_47, do_4f, do_c0,..,c6,cd }*/ -const unsigned char const do_6e_head[] = - { - 0x6e, 0x81, 2*10+3+16+1+1+1+1+7+60+60+12 /* (> 128) */ - }; - -const char const do_47[] = /* Card Capabilities */ - { - 0x47, 3, - 0x00 /*???*/, 0x00 /*???*/, 0x00 /*???*/ - /* XXX: See ISO 7816-4 for first byte and second byte */ - }; - -const char const do_4f[] = /* AID */ - { - 0x4f, 16, - 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, - 0x01, 0x01, /* Version 1.1 */ - 0xF5, 0x17, /* Manufacturer (FSIJ) */ - 0x00, 0x00, 0x00, 0x02, /* Serial */ - 0x00, 0x00 - }; - -const char const do_c0[] = - { /* Extended capability */ - 0xc0, 1, - 0x00 - }; - -const char const do_c1[] = - { /* Algorithm Attributes Signature ??? */ - 0xc1, 1, - 0x01, /* RSA */ /*??? should have length modulus, length exponent ??? */ - }; - -const char const do_c2[] = - { /* Algorithm Attributes Decryption ??? */ - 0xc2, 1, - 0x00 - }; - -const char const do_c3[] = - { /* Algorithm Attributes Authentication ??? */ - 0xc3, 1, - 0x00 - }; - -const char const do_c4[] = - { /* CHV status bytes */ - 0xc4, 7, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01 - }; - -const char const do_c5[] = - { - 0xc5, 60, - /* sign */ - 0x5b, 0x85, 0x67, 0x3c, 0x08, 0x4f, 0x80, 0x0d, - 0x54, 0xac, 0x95, 0x1c, 0x35, 0x15, 0x97, 0xcc, - 0xe5, 0x02, 0xbf, 0xcd, - /* enc */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* auth */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - -const char const do_c6[] = /* CA Fingerprints */ - { - 0xc6, 60, - /* c6 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* c7 */ - 0x5b, 0x85, 0x67, 0x3c, 0x08, 0x4f, 0x80, 0x0d, - 0x54, 0xac, 0x95, 0x1c, 0x35, 0x15, 0x97, 0xcc, - 0xe5, 0x02, 0xbf, 0xcd, - /* c8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - -const char const do_cd[] = - { /* Generation time */ - 0xcd, 12, - 0x00, 0x00, 0x00, 0x00, - 0x49, 0x8a, 0x50, 0x7a, /* 0xce */ - 0x00, 0x00, 0x00, 0x00, - }; -/*************************/ - -/***** do_65 is compound object of { do_5b, do_5f2d, do_5f35 }*/ -const char const do_65_head[] = - { - 0x65, 2*1+3*2+12+2+1 - }; - -const char const do_5b[] = - { - 0x5b, 12, - 'N', 'I', 'I', 'B', 'E', ' ', 'Y', 'u', 't', 'a', 'k', 'a' - }; - -const char const do_5f2d[] = - { - 0x5f, 0x2d, 2, - 'j', 'a' - }; - -const char const do_5f35[] = - { - 0x5f, 0x35, 1, - '1' - }; -/****************************/ - -/* do_7a is compound object of { do_93 } */ -const char const do_7a_head[] = - { - 0x7a, 2+3 - }; - -/* Digital Signature Counter (3-bytes) */ -const char const do_93[] = - { - 0x93, 3, - 0, 0, 0 - }; -/****************************/ - - -const char const do_5f50[] = - { - 0x5f, 0x50, 20, - 'h', 't', 't', 'p', ':', '/', '/', 'w', 'w', 'w', - '.', 'f', 's', 'i', 'j', '.', 'o', 'r', 'g', '/' - }; +extern const char const select_file_TOP_result[20]; +extern const char const get_data_64_result[7]; +extern const char const get_data_5e_result[6]; +extern const char const do_6e_head[3]; +extern const char const do_47[2+3]; +extern const char const do_4f[2+16]; +extern const char const do_c0[2+1]; +extern const char const do_c1[2+1]; +extern const char const do_c2[2+1]; +extern const char const do_c3[2+1]; +extern const char const do_c4[2+7]; +extern const char const do_c5[2+60]; +extern const char const do_c6[2+60]; +extern const char const do_cd[2+12]; +extern const char const do_65_head[2]; +extern const char const do_5b[2+12]; +extern const char const do_5f2d[3+2]; +extern const char const do_5f35[3+1]; +extern const char const do_7a_head[2]; +extern const char const do_93[2+3]; +extern const char const do_5f50[3+20]; +extern const char const do_5f52[3+10]; +extern const char const get_data_rb_result[6]; +extern const char const get_data_sigkey_result[7+128]; +extern const char const get_data_enckey_result[7+128]; /* @@ -211,26 +108,20 @@ const char const do_5f50[] = * 6e L-6e [47 3 x x x ] [4f L-4f ...] [c0 L-c0 ...] ... * 7a L-7a [93 L-93 ... ] */ -#if 0 -static byte -process_command_adpu (void) +static void +write_res_apdu (const uint8_t *p, int len, uint8_t sw1, uint8_t sw2) { - if (icc_read_buf[1] == INS_GET_RESPONSE) - { - put_string (" - GET Response\r\n"); - - if ((icc_result_flag & ICC_RESULT_BUF)) - return 0; - else - { - put_string ("Wrong GET Response\r\n"); - return 1; - } - } - - icc_result_flag = 0; + res_APDU_size = 2 + len; + if (len) + memcpy (res_APDU, p, len); + res_APDU[len] = sw1; + res_APDU[len+1] = sw2; +} +static int +process_command_apdu (void) +{ /* INS_VERIFY @@ -242,20 +133,18 @@ INS_VERIFY CHV3 */ - if (icc_read_buf[1] == INS_PUT_DATA) + if (cmd_APDU[1] == INS_PUT_DATA) { put_string (" - PUT DATA\r\n"); - icc_result_value = 0x9000; /* 6a88: No record */ - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x90, 0x00); /* 0x6a, 0x88: No record */ return 0; } - if (icc_read_buf[1] == INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR) + if (cmd_APDU[1] == INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR) { put_string (" - Generate Asymmetric Key Pair\r\n"); - if (icc_read_buf[2] == 0x81) + if (cmd_APDU[2] == 0x81) { /* * tag: 0x7f49 public key data @@ -272,107 +161,44 @@ INS_VERIFY * 0x81 0x80 */ - if (icc_read_buf[6] == 0x00 && icc_read_buf[5] == 0xb6) + if (cmd_APDU[6] == 0x00 && cmd_APDU[5] == 0xb6) { /* Key for Sign */ - static const char const get_data_sigkey_result[] = - { - 0x7f, 0x49, 0x81, 0x88, - 0x81, 0x81, 0x80, - /* 128-byte data */ - /* modulus */ - 0xdb, 0xca, 0x58, 0x74, 0x44, 0x8e, 0x1a, 0x2c, - 0xa0, 0x91, 0xac, 0xc4, 0xe2, 0x77, 0x2b, 0x90, - 0xcf, 0x3c, 0x7e, 0x81, 0xdc, 0x8d, 0xb0, 0xe2, - 0xf1, 0xfe, 0x56, 0x7e, 0x54, 0x57, 0xf0, 0xd8, - 0xb1, 0xb1, 0xaa, 0x9d, 0x8f, 0xb0, 0x56, 0x01, - 0xaa, 0x6b, 0xa7, 0x2e, 0xce, 0x01, 0x20, 0xd2, - 0xf8, 0xf5, 0x85, 0x3a, 0xc2, 0x73, 0xf9, 0x66, - 0x30, 0x28, 0x65, 0x5e, 0x3f, 0x91, 0xaf, 0x3f, - 0xf6, 0x1c, 0x31, 0x2f, 0xa2, 0x91, 0xbb, 0x41, - 0x91, 0x41, 0x08, 0x0a, 0xc5, 0x3e, 0x39, 0xda, - 0x2f, 0x6f, 0x58, 0x51, 0xe2, 0xd2, 0xe9, 0x42, - 0x8a, 0x7b, 0x72, 0x7b, 0x15, 0xf6, 0xf6, 0x6a, - 0x12, 0x6e, 0x0c, 0x15, 0x24, 0x13, 0x16, 0x55, - 0x3a, 0xf1, 0xa7, 0x16, 0x3e, 0xe9, 0xc8, 0x3d, - 0x2c, 0x3d, 0xae, 0x51, 0x2d, 0x7f, 0xef, 0x92, - 0x25, 0x6a, 0xbb, 0x02, 0x03, 0x70, 0x45, 0x3d, - /* public exponent */ - 0x82, 3, 0x01, 0x00, 0x01 - }; - - icc_result_value = get_data_sigkey_result; - icc_result_len = sizeof (get_data_sigkey_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + write_res_apdu (get_data_sigkey_result, + sizeof (get_data_sigkey_result), 0x90, 0x00); } - else if (icc_read_buf[6] == 0x00 && icc_read_buf[5] == 0xb8) + else if (cmd_APDU[6] == 0x00 && cmd_APDU[5] == 0xb8) { /* Key for Encryption */ - static const char const get_data_enckey_result[] = - { - 0x7f, 0x49, 0x81, 0x88, - 0x81, 0x81, 0x80, - /* 128-byte data */ - 0xB2, 0x19, 0x91, 0x42, 0x27, 0xC7, 0x97, 0xFE, - 0x92, 0x64, 0x42, 0xCA, 0xE3, 0x66, 0x4D, 0xD0, - 0x31, 0xE4, 0x10, 0x31, 0x0F, 0xC7, 0x07, 0x4A, - 0xAA, 0x6D, 0x31, 0xA2, 0x88, 0x68, 0xAF, 0x45, - 0x8E, 0x42, 0x12, 0xFF, 0xB6, 0xEF, 0x6E, 0x54, - 0x7E, 0x51, 0x8E, 0xBC, 0xE8, 0x18, 0x79, 0xA7, - 0xBC, 0xA8, 0x14, 0x8B, 0xE7, 0x91, 0x57, 0x38, - 0xCE, 0x4F, 0x6E, 0x16, 0x48, 0xCB, 0xD6, 0x0B, - 0x3A, 0x53, 0x70, 0xF3, 0xFC, 0xFA, 0xC3, 0x58, - 0x3D, 0xE7, 0x2A, 0x5E, 0xDD, 0xE1, 0x38, 0x82, - 0x57, 0x87, 0x3A, 0xDC, 0x34, 0xDE, 0xCD, 0x5D, - 0x33, 0x1C, 0xAB, 0xB0, 0x1B, 0xEE, 0x82, 0x43, - 0x7B, 0xAC, 0xF8, 0xF0, 0xB2, 0x62, 0xB2, 0x6D, - 0x09, 0xED, 0x2E, 0xD1, 0xBA, 0xB8, 0xC6, 0x96, - 0xFA, 0x3E, 0xB4, 0xE3, 0xFE, 0x68, 0xF9, 0x51, - 0x9A, 0x8C, 0x8B, 0x20, 0x93, 0xD0, 0x2E, 0x0F, - 0x82, 3, 0x01, 0x00, 0x01 - }; - - icc_result_value = get_data_enckey_result; - icc_result_len = sizeof (get_data_enckey_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + write_res_apdu (get_data_enckey_result, + sizeof (get_data_enckey_result), 0x90, 0x00); } - /* icc_read_buf[5] == 0xa4 */ + /* cmd_APDU[5] == 0xa4 */ else { - icc_result_value = 0x6a88; /* No record */ - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x6a, 0x88); /* No record */ } } else { - icc_result_value = 0x6a88; /* No record */ - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x6a, 0x88); /* No record */ } } - else if (icc_read_buf[1] == INS_READ_BINARY) + else if (cmd_APDU[1] == INS_READ_BINARY) { /* it must be for DF 0x2f02 */ put_string (" - Read binary\r\n"); - if (icc_read_buf[3] >= 6) + if (cmd_APDU[3] >= 6) { - icc_result_value = 0x6b00; /* BAD_P0_P1 */ - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x6b, 0x00); /* BAD_P0_P1 */ } else { /* Tag 5a, serial number */ - static const char const get_data_rb_result[] = { 0x5a, 0x4, 0x01, 0x02, 0x03, 0x04 }; - - icc_result_value = (word)get_data_rb_result; - icc_result_len = sizeof (get_data_rb_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - - /* XXX: Next get response returns 6282??? eof_reached ??? */ + write_res_apdu (get_data_rb_result, + sizeof (get_data_rb_result), 0x90, 0x00); } } - else if (icc_read_buf[1] == INS_SELECT_FILE) + else if (cmd_APDU[1] == INS_SELECT_FILE) { - if (icc_read_buf[2] == 4) /* Selection by DF name */ + if (cmd_APDU[2] == 4) /* Selection by DF name */ { put_string (" - select DF by name\r\n"); /* @@ -381,176 +207,210 @@ INS_VERIFY if (1) { - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x90, 0x00); } } - else if (icc_read_buf[4] == 2 - && icc_read_buf[5] == 0x2f - && icc_read_buf[6] == 02) + else if (cmd_APDU[4] == 2 + && cmd_APDU[5] == 0x2f + && cmd_APDU[6] == 02) { put_string (" - select 0x2f02 EF\r\n"); /* * MF.EF-GDO -- Serial number of the card and name of the owner */ - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x90, 0x00); } else - if (icc_read_buf[4] == 2 - && icc_read_buf[5] == 0x3f - && icc_read_buf[6] == 0) + if (cmd_APDU[4] == 2 + && cmd_APDU[5] == 0x3f + && cmd_APDU[6] == 0) { put_string (" - select ROOT MF\r\n"); - if (icc_read_buf[3] == 0x0c) + if (cmd_APDU[3] == 0x0c) { - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x90, 0x00); } else { - icc_result_value = select_file_TOP_result; - icc_result_len = sizeof (select_file_TOP_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + write_res_apdu (select_file_TOP_result, + sizeof (select_file_TOP_result), 0x90, 0x00); } } else { put_string (" - select ?? \r\n"); - icc_result_value = 0x6a82; /* File missing */ - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x6a, 0x82); /* File missing */ } } - else if (icc_read_buf[1] == INS_GET_DATA) + else if (cmd_APDU[1] == INS_GET_DATA) { put_string (" - Get Data\r\n"); - switch (((icc_read_buf[2]<<8) | icc_read_buf[3])) + switch (((cmd_APDU[2]<<8) | cmd_APDU[3])) { case 0x4f: /* AID */ { - icc_result_value = (word)&do_4f[2]; - icc_result_len = sizeof (do_4f) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" AID\r\n"); + write_res_apdu (&do_4f[2], + sizeof (do_4f) - 2, 0x90, 0x00); break; } case 0x5e: /* Login data */ { - icc_result_value = (word)get_data_5e_result; - icc_result_len = sizeof (get_data_5e_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" Login data\r\n"); + write_res_apdu (get_data_5e_result, + sizeof (get_data_5e_result), 0x90, 0x00); break; } case 0x64: { - icc_result_value = (word)get_data_64_result; - icc_result_len = sizeof (get_data_64_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 64\r\n"); + write_res_apdu (get_data_64_result, + sizeof (get_data_64_result), 0x90, 0x00); break; } case 0xc0: { - icc_result_value = (word)&do_c0[2]; - icc_result_len = sizeof (do_c0) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" c0\r\n"); + write_res_apdu (&do_c0[2], + sizeof (do_c0) - 2, 0x90, 0x00); + break; + } + case 0xc1: + { + put_string (" c1\r\n"); + write_res_apdu (&do_c1[2], + sizeof (do_c1) - 2, 0x90, 0x00); + break; + } + case 0xc2: + { + put_string (" c2\r\n"); + write_res_apdu (&do_c2[2], + sizeof (do_c2) - 2, 0x90, 0x00); + break; + } + case 0xc3: + { + put_string (" c3\r\n"); + write_res_apdu (&do_c3[2], + sizeof (do_c3) - 2, 0x90, 0x00); break; } case 0xc4: { - icc_result_value = (word)&do_c4[2]; - icc_result_len = sizeof (do_c4) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" c4\r\n"); + write_res_apdu (&do_c4[2], + sizeof (do_c4) - 2, 0x90, 0x00); break; } case 0x5b: /* Name */ { - icc_result_value = (word)&do_5b[2]; - icc_result_len = sizeof (do_5b) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 5b\r\n"); + write_res_apdu (&do_5b[2], + sizeof (do_5b) - 2, 0x90, 0x00); break; } case 0x93: /* Digital Signature Counter (3-bytes) */ { - icc_result_value = (word)&do_93[2]; - icc_result_len = sizeof (do_93) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 93\r\n"); + write_res_apdu (&do_93[2], + sizeof (do_93) - 2, 0x90, 0x00); break; } case 0xc5: /* Fingerprints */ { - icc_result_value = &do_c5[2]; - icc_result_len = sizeof (do_c5) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" c5\r\n"); + write_res_apdu (&do_c5[2], + sizeof (do_c5) - 2, 0x90, 0x00); break; } case 0x5f2d: /* Language preference */ { - icc_result_value = (word)&do_5f2d[3]; - icc_result_len = sizeof (do_5f2d) - 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 5f2d\r\n"); + write_res_apdu (&do_5f2d[3], + sizeof (do_5f2d) - 3, 0x90, 0x00); break; } case 0x5f35: /* Sex */ { - icc_result_value = (word)&do_5f35[3]; - icc_result_len = sizeof (do_5f35) - 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 5f35\r\n"); + write_res_apdu (&do_5f35[3], + sizeof (do_5f35) - 3, 0x90, 0x00); break; } case 0x5f50: /* URL */ { - icc_result_value = (word)&do_5f50[3]; - icc_result_len = sizeof (do_5f50) - 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 5f50\r\n"); + write_res_apdu (&do_5f50[3], + sizeof (do_5f50) - 3, 0x90, 0x00); + break; + } + case 0x5f52: /* Historycal bytes */ + { + put_string (" 5f52\r\n"); + write_res_apdu (&do_5f52[3], + sizeof (do_5f52) - 3, 0x90, 0x00); break; } case 0x65: /* Card Holder Related Data (Tag) */ { - icc_result_value = (word)do_65_head; - icc_result_len = do_65_head[1] + 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 65\r\n"); + write_res_apdu (do_65_head, + do_65_head[1] + 2, 0x90, 0x00); break; } case 0x6e: /* Application Related Data (Tag) */ { - icc_result_value = (word)do_6e_head; - icc_result_len = do_6e_head[2] + 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 6e\r\n"); + write_res_apdu (do_6e_head, + do_6e_head[2] + 3, 0x90, 0x00); break; } case 0x7a: /* Security Support Template (Tag) */ { - icc_result_value = (word)do_7a_head; - icc_result_len = do_7a_head[1] + 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; + put_string (" 7a\r\n"); + write_res_apdu (do_7a_head, + do_7a_head[1] + 2, 0x90, 0x00); break; } case 0xc6: /* List of CA fingerprints */ + { + put_string (" c6\r\n"); + write_res_apdu (&do_c6[2], + sizeof (do_c6) - 2, 0x90, 0x00); + break; + } case 0xcd: /* List of generation dates/times public-key pairs */ + { + put_string (" cd\r\n"); + write_res_apdu (&do_cd[2], + sizeof (do_cd) - 2, 0x90, 0x00); + break; + } default: - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; + put_string (" ?"); + put_byte (((cmd_APDU[2]<<8) | cmd_APDU[3])); + write_res_apdu (NULL, 0, 0x90, 0x00); + break; } } - else if (icc_read_buf[1] == INS_PSO) + else if (cmd_APDU[1] == INS_PSO) { put_string (" - PSO\r\n"); - if (icc_read_buf[2] == 0x9E && icc_read_buf[3] == 0x9A) + if (cmd_APDU[2] == 0x9E && cmd_APDU[3] == 0x9A) { - if (icc_read_len != 5 + 35 && icc_read_len != 5 + 35 + 1) + if (cmd_APDU_size != 5 + 35 && cmd_APDU_size != 5 + 35 + 1) put_string (" wrong length\r\n"); else { - icc_result_value = rsa_sign (&icc_read_buf[5]); - icc_result_len = RSA_SIGNATURE_LENGTH; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_RAM; +#if 0 + r = rsa_sign (&cmd_APDU[5]); + write_res_apdu (NULL, RSA_SIGNATURE_LENGTH, 0x90, 0x00); +#endif + write_res_apdu (NULL, 0, 0x64, 0x00); } put_string ("done.\r\n"); @@ -558,22 +418,17 @@ INS_VERIFY else { put_string (" - ???\r\n"); - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x90, 0x00); } } else { put_string (" - ???\r\n"); - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; + write_res_apdu (NULL, 0, 0x90, 0x00); } return 0; } -#endif Thread *gpg_thread; @@ -592,15 +447,8 @@ GPGthread (void *arg) m = chEvtWaitOne (ALL_EVENTS); _write ("GPG!\r\n", 6); -#if 0 - receive_command_adpu (); -#endif -#if 0 - process_command_adpu (); -#endif -#if 0 - send_result_adpu (); -#endif + + process_command_apdu (); chEvtSignal (icc_thread, EV_EXEC_FINISHED); } diff --git a/src/icc.c b/src/icc.c deleted file mode 100644 index 8768ee8..0000000 --- a/src/icc.c +++ /dev/null @@ -1,886 +0,0 @@ -/* - * icc.c -- - * - * Copyright (C) 2010 Free Software Initiative of Japan - * Author: NIIBE Yutaka - * - * This file is a part of Gnuk, a GnuPG USB Token implementation. - * - * Gnuk is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Gnuk is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - * License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -enum icc_state { - ICC_STATE_INITIAL, - ICC_STATE_WAITING_ADPU, - ICC_STATE_BUSY1, - ICC_STATE_BUSY2, - ICC_STATE_BUSY3, - ICC_STATE_BUSY4, - ICC_STATE_BUSY5, - ICC_STATE_ADPU_RECEIVED_PARTIALLY, - ICC_STATE_ADPU_SENT_PARTIALLY, -}; - -#define RSA_SIGNATURE_LENGTH 128 /* 128 byte == 1024-bit */ -extern unsigned char *rsa_sign (unsigned char *); - -/* Three callbacks */ - -static byte icc_cycle; -byte icc_status; - -/* GET_ICC_STATUS */ -byte -icc_get_status (void) -{ -#if 0 - if (icc_status == ICC_STATUS_BUSY) - return ((icc_cycle++) & 0x0f) | ICC_STATUS_BUSY; -#endif - - return icc_status; -} - -/* XXX: need to be fixed... *//* T=0 */ -const char *ATR = "\x3B\x02\xbe\xef"; - -task_t icc_wait_task; -byte icc_wait_result; - - -/* ICC_POWER_ON */ -const byte * -icc_power_on (void) -{ - task_t t = icc_wait_task; - - if (t != 0) - { - icc_wait_task = 0; - need_resched = 1; - icc_wait_result = 1; - stx_wakeup (t); - } - - return ATR; -} - -word icc_initial_sp; -void icc_main (void); -extern word task[]; - -extern byte icc_write_buf[2]; -byte icc_read_buf[143]; -extern int icc_write_len; -extern int icc_read_len; - -extern task_t icc_write_task; -extern task_t icc_read_task; - -/* ICC_POWER_OFF */ -void -icc_power_off (void) -{ -#if 0 - if (icc_read_task) - { - icc_read_task = 0; - icc_read_len = 0xff; - } - - if (icc_write_task) - { - icc_write_task = 0; - icc_write_len = 0xff; - } - - if (icc_wait_task) - { - icc_wait_task = 0; - icc_wait_result = 0; - } - - icc_status = ICC_STATUS_BUSY; - stx_wakeup (ICC_TASK); -#endif -#if 1 - extern stx_cancel_write (byte); - word sp = icc_initial_sp; - - if (sp) - { - icc_status = ICC_STATUS_BUSY; - - stx_cancel_write (ICC_TASK); - - /* Push PC */ - *(byte *)(sp - 1) = ((word)icc_main >> 8); - *(byte *)sp = ((word)icc_main & 0xff); - sp -= 32 + 1 + 2; /* Registers 0-31, SREG and PC */ - - need_resched = 1; - task[ICC_TASK] = sp; - stx_wakeup (ICC_TASK); - } -#endif -} - -#define INS_PUT_DATA 0xDA -#define INS_VERIFY 0x20 -#define INS_GET_DATA 0xCA -#define INS_GET_RESPONSE 0xC0 -#define INS_SELECT_FILE 0xA4 -#define INS_READ_BINARY 0xB0 -#define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR 0x47 -#define INS_PSO 0x2A - -extern byte *icc_read_p; - -word icc_result_value; /* Buffer pointer or status word */ -byte icc_result_flag; -byte icc_result_len; - -#define ICC_RESULT_BUF 0x80 -#define ICC_RESULT_BUF_MASK 0x7f -#define ICC_RESULT_BUF_ROM 0 -#define ICC_RESULT_BUF_EEPROM 1 -#define ICC_RESULT_BUF_RAM 2 -/************************ 3 */ - -static void -icc_success (void) -{ - icc_result_flag = 0; -} - -byte -stx_icc_read (void) -{ - asm volatile ("cli"); - icc_read_p = icc_read_buf; - icc_read_len = 0; - icc_read_task = current; - task_wait_bits |= taskset_current (); - icc_status = ICC_STATUS_READY; - stx_yield (); - - if (icc_read_len == 5 - && (icc_read_buf[1] == INS_SELECT_FILE - || icc_read_buf[1] == INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR - || icc_read_buf[1] == INS_PUT_DATA - || icc_read_buf[1] == INS_VERIFY - || icc_read_buf[1] == INS_PSO)) - { /* Recieve a packet again */ - asm volatile ("cli"); - icc_read_task = current; - task_wait_bits |= taskset_current (); - icc_status = ICC_STATUS_DATA; - stx_yield (); - } - - return icc_read_len; -} - -static byte -receive_command_adpu (void) -{ - byte r; - char s[11]; - - if ((r = stx_icc_read ()) != 0xff) - { - int i; - - for (i = 0; i < icc_read_len; i++) - { - sprintf (s, " %02x", icc_read_buf[i]); - stx_put_string (s); - } - } - - return r; -} - -static const char const select_file_TOP_result[] = - { 0x00, 0x00, 0x0b, 0x10, 0x3f, 0x00, 0x38, 0xff, 0xff, 0x44, - 0x44, 0x01, 0x05, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 }; - -static const char const get_data_64_result[] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - -static const char const get_data_5e_result[] = - { /* Login Data */ - 'g', 'n', 'i', 'i', 'b', 'e' - }; - -/***** do_65 is compound object of { do_47, do_4f, do_c0,..,c6,cd }*/ -const unsigned char const do_6e_head[] = - { - 0x6e, 0x81, 2*10+3+16+1+1+1+1+7+60+60+12 /* (> 128) */ - }; - -const char const do_47[] = /* Card Capabilities */ - { - 0x47, 3, - 0x00 /*???*/, 0x00 /*???*/, 0x00 /*???*/ - /* XXX: See ISO 7816-4 for first byte and second byte */ - }; - -const char const do_4f[] = /* AID */ - { - 0x4f, 16, - 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, - 0x01, 0x01, /* Version 1.1 */ - 0xF5, 0x17, /* Manufacturer (FSIJ) */ - 0x00, 0x00, 0x00, 0x02, /* Serial */ - 0x00, 0x00 - }; - -const char const do_c0[] = - { /* Extended capability */ - 0xc0, 1, - 0x00 - }; - -const char const do_c1[] = - { /* Algorithm Attributes Signature ??? */ - 0xc1, 1, - 0x01, /* RSA */ /*??? should have length modulus, length exponent ??? */ - }; - -const char const do_c2[] = - { /* Algorithm Attributes Decryption ??? */ - 0xc2, 1, - 0x00 - }; - -const char const do_c3[] = - { /* Algorithm Attributes Authentication ??? */ - 0xc3, 1, - 0x00 - }; - -const char const do_c4[] = - { /* CHV status bytes */ - 0xc4, 7, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01 - }; - -const char const do_c5[] = - { - 0xc5, 60, - /* sign */ - 0x5b, 0x85, 0x67, 0x3c, 0x08, 0x4f, 0x80, 0x0d, - 0x54, 0xac, 0x95, 0x1c, 0x35, 0x15, 0x97, 0xcc, - 0xe5, 0x02, 0xbf, 0xcd, - /* enc */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* auth */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - -const char const do_c6[] = /* CA Fingerprints */ - { - 0xc6, 60, - /* c6 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* c7 */ - 0x5b, 0x85, 0x67, 0x3c, 0x08, 0x4f, 0x80, 0x0d, - 0x54, 0xac, 0x95, 0x1c, 0x35, 0x15, 0x97, 0xcc, - 0xe5, 0x02, 0xbf, 0xcd, - /* c8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - -const char const do_cd[] = - { /* Generation time */ - 0xcd, 12, - 0x00, 0x00, 0x00, 0x00, - 0x49, 0x8a, 0x50, 0x7a, /* 0xce */ - 0x00, 0x00, 0x00, 0x00, - }; -/*************************/ - -/***** do_65 is compound object of { do_5b, do_5f2d, do_5f35 }*/ -const char const do_65_head[] = - { - 0x65, 2*1+3*2+12+2+1 - }; - -const char const do_5b[] = - { - 0x5b, 12, - 'N', 'I', 'I', 'B', 'E', ' ', 'Y', 'u', 't', 'a', 'k', 'a' - }; - -const char const do_5f2d[] = - { - 0x5f, 0x2d, 2, - 'j', 'a' - }; - -const char const do_5f35[] = - { - 0x5f, 0x35, 1, - '1' - }; -/****************************/ - -/* do_7a is compound object of { do_93 } */ -const char const do_7a_head[] = - { - 0x7a, 2+3 - }; - -/* Digital Signature Counter (3-bytes) */ -const char const do_93[] = - { - 0x93, 3, - 0, 0, 0 - }; -/****************************/ - - -const char const do_5f50[] = - { - 0x5f, 0x50, 20, - 'h', 't', 't', 'p', ':', '/', '/', 'w', 'w', 'w', - '.', 'f', 's', 'i', 'j', '.', 'o', 'r', 'g', '/' - }; - - -/* - * 73 - * 101 - * 102 - * 103 - * 104 - * - * 65 - 5b, 5f2d, 5f35 - * 6e - 47, 4f, c0, c1, c2, c3, c4, c5, c6, cd - * 7a - 93 - * - * - * 65 L-65 [5b L-5b .... ] [5f2d 2 'j' 'a'] [5f35 1 '1'] - * 6e L-6e [47 3 x x x ] [4f L-4f ...] [c0 L-c0 ...] ... - * 7a L-7a [93 L-93 ... ] - */ - -static byte -process_command_adpu (void) -{ - if (icc_read_buf[1] == INS_GET_RESPONSE) - { - stx_put_string (" - GET Response\r\n"); - - if ((icc_result_flag & ICC_RESULT_BUF)) - return 0; - else - { - stx_put_string ("Wrong GET Response\r\n"); - return 1; - } - } - - icc_result_flag = 0; - - /* -INS_VERIFY - - 00 20 00 81 06 - ??? - CHV1 - 00 20 00 82 06 - ??? - CHV2 - 00 20 00 83 08 - ??? - CHV3 - */ - - if (icc_read_buf[1] == INS_PUT_DATA) - { - stx_put_string (" - PUT DATA\r\n"); - icc_result_value = 0x9000; /* 6a88: No record */ - icc_result_len = 0; - icc_result_flag = 0; - return 0; - } - - if (icc_read_buf[1] == INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR) - { - stx_put_string (" - Generate Asymmetric Key Pair\r\n"); - - if (icc_read_buf[2] == 0x81) - { - /* - * tag: 0x7f49 public key data - * tag: 0x0081 RSA modulus - * tag: 0x0082 RSA exponent - * - * TAG - * [0x7f 0x49][LEN][DATA] - * _______/ \_________________ - * / \ - * [0x81][128][DATA][0x82][3][DATA] - * __/ \__ 0x01, 0x00, 0x01 - * / \ - * 0x81 0x80 - */ - - if (icc_read_buf[6] == 0x00 && icc_read_buf[5] == 0xb6) - { /* Key for Sign */ - static const char const get_data_sigkey_result[] = - { - 0x7f, 0x49, 0x81, 0x88, - 0x81, 0x81, 0x80, - /* 128-byte data */ - /* modulus */ - 0xdb, 0xca, 0x58, 0x74, 0x44, 0x8e, 0x1a, 0x2c, - 0xa0, 0x91, 0xac, 0xc4, 0xe2, 0x77, 0x2b, 0x90, - 0xcf, 0x3c, 0x7e, 0x81, 0xdc, 0x8d, 0xb0, 0xe2, - 0xf1, 0xfe, 0x56, 0x7e, 0x54, 0x57, 0xf0, 0xd8, - 0xb1, 0xb1, 0xaa, 0x9d, 0x8f, 0xb0, 0x56, 0x01, - 0xaa, 0x6b, 0xa7, 0x2e, 0xce, 0x01, 0x20, 0xd2, - 0xf8, 0xf5, 0x85, 0x3a, 0xc2, 0x73, 0xf9, 0x66, - 0x30, 0x28, 0x65, 0x5e, 0x3f, 0x91, 0xaf, 0x3f, - 0xf6, 0x1c, 0x31, 0x2f, 0xa2, 0x91, 0xbb, 0x41, - 0x91, 0x41, 0x08, 0x0a, 0xc5, 0x3e, 0x39, 0xda, - 0x2f, 0x6f, 0x58, 0x51, 0xe2, 0xd2, 0xe9, 0x42, - 0x8a, 0x7b, 0x72, 0x7b, 0x15, 0xf6, 0xf6, 0x6a, - 0x12, 0x6e, 0x0c, 0x15, 0x24, 0x13, 0x16, 0x55, - 0x3a, 0xf1, 0xa7, 0x16, 0x3e, 0xe9, 0xc8, 0x3d, - 0x2c, 0x3d, 0xae, 0x51, 0x2d, 0x7f, 0xef, 0x92, - 0x25, 0x6a, 0xbb, 0x02, 0x03, 0x70, 0x45, 0x3d, - /* public exponent */ - 0x82, 3, 0x01, 0x00, 0x01 - }; - - icc_result_value = get_data_sigkey_result; - icc_result_len = sizeof (get_data_sigkey_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - } -#if 0 - else if (icc_read_buf[6] == 0x00 && icc_read_buf[5] == 0xb8) - { /* Key for Encryption */ - static const char const get_data_enckey_result[] = - { - 0x7f, 0x49, 0x81, 0x88, - 0x81, 0x81, 0x80, - /* 128-byte data */ - 0xB2, 0x19, 0x91, 0x42, 0x27, 0xC7, 0x97, 0xFE, - 0x92, 0x64, 0x42, 0xCA, 0xE3, 0x66, 0x4D, 0xD0, - 0x31, 0xE4, 0x10, 0x31, 0x0F, 0xC7, 0x07, 0x4A, - 0xAA, 0x6D, 0x31, 0xA2, 0x88, 0x68, 0xAF, 0x45, - 0x8E, 0x42, 0x12, 0xFF, 0xB6, 0xEF, 0x6E, 0x54, - 0x7E, 0x51, 0x8E, 0xBC, 0xE8, 0x18, 0x79, 0xA7, - 0xBC, 0xA8, 0x14, 0x8B, 0xE7, 0x91, 0x57, 0x38, - 0xCE, 0x4F, 0x6E, 0x16, 0x48, 0xCB, 0xD6, 0x0B, - 0x3A, 0x53, 0x70, 0xF3, 0xFC, 0xFA, 0xC3, 0x58, - 0x3D, 0xE7, 0x2A, 0x5E, 0xDD, 0xE1, 0x38, 0x82, - 0x57, 0x87, 0x3A, 0xDC, 0x34, 0xDE, 0xCD, 0x5D, - 0x33, 0x1C, 0xAB, 0xB0, 0x1B, 0xEE, 0x82, 0x43, - 0x7B, 0xAC, 0xF8, 0xF0, 0xB2, 0x62, 0xB2, 0x6D, - 0x09, 0xED, 0x2E, 0xD1, 0xBA, 0xB8, 0xC6, 0x96, - 0xFA, 0x3E, 0xB4, 0xE3, 0xFE, 0x68, 0xF9, 0x51, - 0x9A, 0x8C, 0x8B, 0x20, 0x93, 0xD0, 0x2E, 0x0F, - 0x82, 3, 0x01, 0x00, 0x01 - }; - - icc_result_value = get_data_enckey_result; - icc_result_len = sizeof (get_data_enckey_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - } -#endif - /* icc_read_buf[5] == 0xa4 */ - else - { - icc_result_value = 0x6a88; /* No record */ - icc_result_len = 0; - icc_result_flag = 0; - } - } - else - { - icc_result_value = 0x6a88; /* No record */ - icc_result_len = 0; - icc_result_flag = 0; - } - } - else if (icc_read_buf[1] == INS_READ_BINARY) - { /* it must be for DF 0x2f02 */ - stx_put_string (" - Read binary\r\n"); - - if (icc_read_buf[3] >= 6) - { - icc_result_value = 0x6b00; /* BAD_P0_P1 */ - icc_result_len = 0; - icc_result_flag = 0; - } - else - { /* Tag 5a, serial number */ - static const char const get_data_rb_result[] = { 0x5a, 0x4, 0x01, 0x02, 0x03, 0x04 }; - - icc_result_value = (word)get_data_rb_result; - icc_result_len = sizeof (get_data_rb_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - - /* XXX: Next get response returns 6282??? eof_reached ??? */ - } - } - else if (icc_read_buf[1] == INS_SELECT_FILE) - { - if (icc_read_buf[2] == 4) /* Selection by DF name */ - { - stx_put_string (" - select DF by name\r\n"); - /* - * XXX: Should return contents. - */ - - if (1) - { - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; - } - } - else if (icc_read_buf[4] == 2 - && icc_read_buf[5] == 0x2f - && icc_read_buf[6] == 02) - { - stx_put_string (" - select 0x2f02 EF\r\n"); - /* - * MF.EF-GDO -- Serial number of the card and name of the owner - */ - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; - } - else - if (icc_read_buf[4] == 2 - && icc_read_buf[5] == 0x3f - && icc_read_buf[6] == 0) - { - stx_put_string (" - select ROOT MF\r\n"); - if (icc_read_buf[3] == 0x0c) - { - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; - } - else - { - icc_result_value = select_file_TOP_result; - icc_result_len = sizeof (select_file_TOP_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - } - } - else - { - stx_put_string (" - select ?? \r\n"); - - icc_result_value = 0x6a82; /* File missing */ - icc_result_len = 0; - icc_result_flag = 0; - } - } - else if (icc_read_buf[1] == INS_GET_DATA) - { - stx_put_string (" - Get Data\r\n"); - - switch (((icc_read_buf[2]<<8) | icc_read_buf[3])) - { - case 0x4f: /* AID */ - { - icc_result_value = (word)&do_4f[2]; - icc_result_len = sizeof (do_4f) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x5e: /* Login data */ - { - icc_result_value = (word)get_data_5e_result; - icc_result_len = sizeof (get_data_5e_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x64: - { - icc_result_value = (word)get_data_64_result; - icc_result_len = sizeof (get_data_64_result); - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0xc0: - { - icc_result_value = (word)&do_c0[2]; - icc_result_len = sizeof (do_c0) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0xc4: - { - icc_result_value = (word)&do_c4[2]; - icc_result_len = sizeof (do_c4) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x5b: /* Name */ - { - icc_result_value = (word)&do_5b[2]; - icc_result_len = sizeof (do_5b) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x93: /* Digital Signature Counter (3-bytes) */ - { - icc_result_value = (word)&do_93[2]; - icc_result_len = sizeof (do_93) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0xc5: /* Fingerprints */ - { - icc_result_value = &do_c5[2]; - icc_result_len = sizeof (do_c5) - 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x5f2d: /* Language preference */ - { - icc_result_value = (word)&do_5f2d[3]; - icc_result_len = sizeof (do_5f2d) - 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x5f35: /* Sex */ - { - icc_result_value = (word)&do_5f35[3]; - icc_result_len = sizeof (do_5f35) - 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x5f50: /* URL */ - { - icc_result_value = (word)&do_5f50[3]; - icc_result_len = sizeof (do_5f50) - 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x65: /* Card Holder Related Data (Tag) */ - { - icc_result_value = (word)do_65_head; - icc_result_len = do_65_head[1] + 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x6e: /* Application Related Data (Tag) */ - { - icc_result_value = (word)do_6e_head; - icc_result_len = do_6e_head[2] + 3; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0x7a: /* Security Support Template (Tag) */ - { - icc_result_value = (word)do_7a_head; - icc_result_len = do_7a_head[1] + 2; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_ROM; - break; - } - case 0xc6: /* List of CA fingerprints */ - case 0xcd: /* List of generation dates/times public-key pairs */ - default: - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; - } - } - else if (icc_read_buf[1] == INS_PSO) - { - stx_put_string (" - PSO\r\n"); - - if (icc_read_buf[2] == 0x9E && icc_read_buf[3] == 0x9A) - { - if (icc_read_len != 5 + 35 && icc_read_len != 5 + 35 + 1) - stx_put_string (" wrong length\r\n"); - else - { - icc_result_value = rsa_sign (&icc_read_buf[5]); - icc_result_len = RSA_SIGNATURE_LENGTH; - icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_RAM; - } - - stx_put_string ("done.\r\n"); - } - else - { - stx_put_string (" - ???\r\n"); - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; - } - } - else - { - stx_put_string (" - ???\r\n"); - icc_result_value = 0x9000; - icc_result_len = 0; - icc_result_flag = 0; - } - - return 0; -} - -#define ICC_RESULT_MAX_LEN 32 - -static byte -send_result_adpu (void) -{ - byte r = 0; - - if ((icc_result_flag & ICC_RESULT_BUF)) - { - if ((icc_result_flag & ICC_RESULT_BUF_MASK) == ICC_RESULT_BUF_ROM - || (icc_result_flag & ICC_RESULT_BUF_MASK) == ICC_RESULT_BUF_RAM) - { - byte r; - - asm volatile ("cli"); - icc_status = ICC_STATUS_DATA; - icc_write_task = current; - task_wait_bits |= taskset_current (); - r = stx_yield (); - - if (r == 0) - { - if (icc_result_len <= ICC_RESULT_MAX_LEN) - { - icc_write_buf[0] = 0x90; - icc_write_buf[1] = 0x00; - } - else - { - icc_result_len -= ICC_RESULT_MAX_LEN; - icc_result_value += ICC_RESULT_MAX_LEN; - icc_write_buf[0] = 0x61; - icc_write_buf[1] = icc_result_len; - } - - icc_write_len = 2; - asm volatile ("cli"); - icc_status = ICC_STATUS_SW; - icc_write_task = current; - task_wait_bits |= taskset_current (); - stx_yield (); - } - } - else - ; - } - else /* Status word */ - { - icc_write_buf[0] = (icc_result_value >> 8); - icc_write_buf[1] = (icc_result_value & 0xff); - icc_write_len = 2; - - asm volatile ("cli"); - icc_status = ICC_STATUS_SW; - icc_write_task = current; - task_wait_bits |= taskset_current (); - stx_yield (); - } - - return r; -} - -byte -stx_icc_wait_power_on (void) -{ - stx_put_string ("W\r\n"); - asm volatile ("cli"); - icc_status = ICC_STATUS_DATA; /* Ready to send ATR */ - icc_wait_task = current; - task_wait_bits |= taskset_current (); - stx_yield (); - - stx_put_string ("w\r\n"); - if (icc_wait_result) - { - char s[10]; - sprintf(s,"On %d\r\n", icc_wait_task); - stx_put_string (s); - } - else - stx_put_string ("Off?\r\n"); - return icc_wait_result; -} - -void -icc_main (void) -{ -#if 1 - word old_sp = icc_initial_sp; - - icc_status = ICC_STATUS_BUSY; - icc_wait_task = 0; - icc_write_task = 0; - icc_read_task = 0; - - icc_initial_sp = task[ICC_TASK] + 32 + 1 + 2; - - if (old_sp != icc_initial_sp) - stx_put_string ("Start\r\n"); - else - stx_put_string ("RESET\r\n"); -#else - char s[12]; - sprintf(s, "Start %d\r\n", current); - stx_put_string (s); -#endif - - again: - if (stx_icc_wait_power_on ()) - while (1) - { - byte r; - r = receive_command_adpu (); - - if (r == 0xff) /* wait for XFR_BLOCK */ - break; - - if (r == 0) - { - stx_put_string ("zero size command packet\r\n"); - continue; - } - - if (process_command_adpu ()) - continue; - - if (send_result_adpu () == 0xff) - break; - } - - stx_put_string ("Reset\r\n"); - goto again; -} diff --git a/src/main.c b/src/main.c index 03acfd6..3b38cc4 100644 --- a/src/main.c +++ b/src/main.c @@ -207,9 +207,9 @@ int main(int argc, char **argv) chThdSleepMilliseconds (100); - if (bDeviceState == CONFIGURED && (count % 30) == 0) + if (bDeviceState == CONFIGURED && (count % 300) == 0) { - _write ("0123456789"+((count / 30)%10), 1); + _write ("0123456789"+((count / 300)%10), 1); _write ("\r\nThis is ChibiOS 2.0.2 on Olimex STM32-H103.\r\n" "Testing USB driver.\n\n" "Hello world\r\n\r\n", 47+21+15); diff --git a/src/usb-icc.c b/src/usb-icc.c index fbd552e..825c1e3 100644 --- a/src/usb-icc.c +++ b/src/usb-icc.c @@ -32,11 +32,59 @@ #include "hw_config.h" #include "usb_istr.h" -static uint8_t icc_buffer_out[64]; -static uint8_t icc_buffer_in[64]; +#define ICC_POWER_ON 0x62 +#define ICC_POWER_OFF 0x63 +#define ICC_SLOT_STATUS 0x65 +#define ICC_XFR_BLOCK 0x6F +#define ICC_DATA_BLOCK_RET 0x80 +#define ICC_SLOT_STATUS_RET 0x81 -static __IO uint32_t icc_count_out = 0; -static uint32_t icc_count_in = 0; +#define ICC_MSG_SEQ_OFFSET 6 +#define ICC_MSG_STATUS_OFFSET 7 +#define ICC_MSG_ERROR_OFFSET 8 +#define ICC_MSG_CHAIN_OFFSET 9 +#define ICC_MSG_DATA_OFFSET 10 +#define ICC_MSG_HEADER_SIZE ICC_MSG_DATA_OFFSET +#define ICC_MAX_MSG_DATA_SIZE (USB_BUF_SIZE - ICC_MSG_HEADER_SIZE) + +#define ICC_STATUS_RUN 0x00 +#define ICC_STATUS_PRESENT 0x01 +#define ICC_STATUS_NOTPRESENT 0x02 +#define ICC_CMD_STATUS_OK 0x00 +#define ICC_CMD_STATUS_ERROR 0x40 +#define ICC_CMD_STATUS_TIMEEXT 0x80 + +#define ICC_ERROR_XFR_OVERRUN 0xFC + + +struct icc_header { + uint8_t msg_type; + int32_t data_len; + uint8_t slot; + uint8_t seq; + uint8_t rsvd; + uint16_t param; +} __attribute__((packed)); + +static struct icc_header *icc_header; +static uint8_t icc_seq; + +static uint8_t *icc_data; +static int icc_data_size; + +static uint8_t icc_rcv_data[USB_BUF_SIZE]; +static uint8_t icc_tx_data[USB_BUF_SIZE]; + +static int icc_tx_size; + +static int +icc_tx_ready (void) +{ + if (icc_tx_size == -1) + return 1; + else + return 0; +} Thread *icc_thread; @@ -48,332 +96,330 @@ Thread *icc_thread; void EP4_IN_Callback (void) { - icc_count_in = 0; + if (icc_tx_size == USB_BUF_SIZE) + { + icc_tx_size = 0; + USB_SIL_Write (EP4_IN, icc_tx_data, icc_tx_size); + SetEPTxValid (ENDP4); + } + else + icc_tx_size = -1; } /* - * Rx data + * Upon arrival of Bulk-OUT packet, + * we setup the variables (icc_header, icc_data, and icc_data_size, icc_seq) + * and notify icc_thread + * (modify header's byte order to host order if needed) */ void EP5_OUT_Callback (void) { - /* Get the received data buffer and update the counter */ - icc_count_out = USB_SIL_Read (EP5_OUT, icc_buffer_out); - chEvtSignalI (icc_thread, EV_RX_DATA_READY); -} + int len; -#define ICC_POWER_ON 0x62 -#define ICC_POWER_OFF 0x63 -#define ICC_SLOT_STATUS 0x65 -#define XFR_BLOCK 0x6F - -#define ICC_MSG_SEQ_OFFSET 6 -#define ICC_MSG_STATUS_OFFSET 7 -#define ICC_MSG_ERROR_OFFSET 8 - -#if 0 -0 bMessageType 0x62 -1 dwLength 0x00000000 -5 bSlot 0x00 FIXED -6 bSeq 0x00-FF -7 bReserved 0x01 FIXED -8 abRFU 0x0000 ---> -0 bMessageType 0x80 Indicates RDR_to_PC_DataBlock -1 dwLength Size of bytes for the ATR -5 bSlot 0x00 FIXED -6 bSeq Sequence number for the corresponding command. -7 bStatus USB-ICC Status register as defined in Table 6.1-8 -8 bError USB-ICC Error register as defined in Table 6.1-9 -9 bChainParameter 0x00 Indicates that this message contains the complete ATR. -10 abData ATR - - -0 bMessageType 0x63 -1 dwLength 0x00000000 Message-specific data length -5 bSlot 0x00 FIXED -6 bSeq 0x00-FF Sequence number for command. -7 abRFU 0x000000 ---> -0 bMessageType 81h Indicates RDR_to_PC_SlotStatus -1 dwLength 0x00000000 Message-specific data length -5 bSlot 0x00 FIXED -6 bSeq Sequence number for the corresponding command. -7 bStatus USB-ICC Status register as defined in Table 6.1-8 -8 bError USB-ICC Error register as defined in Table 6.1-9 -9 bReserved 0x00 FIXED - - -0 bMessageType 0x6F Indicates PC_to_RDR_XfrBlock -1 dwLength Size of abData field of this message -5 bSlot 0x00 FIXED -6 bSeq 0x00-FF Sequence number for command. -7 bReserved 0x00 FIXED -8 wLevelParameter - 0x0000 - the command APDU begins and ends with this command - - 0x0001 - the command APDU begins with this command, and - continue in the next PC_to_RDR_XfrBlock - - 0x0002 - this abData field continues a command APDU and - ends the command APDU - - 0x0003 - the abData field continues a command APDU and - another block is to follow - - 0x0010 - empty abData field, continuation of response APDU - is expected in the next RDR_to_PC_DataBlock. - -10 abData Data block sent to the USB-ICC ---> -0 bMessageType 0x80 Indicates RDR_to_PC_DataBlock -1 dwLength Size of abData field of this message -5 bSlot 0x00 FIXED -6 bSeq Sequence number for the corresponding command. - -7 bStatus USB-ICC Status register as defined in Table 6.1-8 -8 bError USB-ICC Error register as defined in Table 6.1-9 -9 bChainParameter - Indicates if the response is complete, to be - continued or if the command APDU can continue - 0x00: The response APDU begins and ends in this command - 0x01: The response APDU begins with this command and is to continue - 0x02: This abData field continues the response - APDU and ends the response APDU - 0x03: This abData field continues the response - APDU and another block is to follow - 0x10: Empty abData field, continuation of the - command APDU is expected in next PC_to_RDR_XfrBlock command -10 abData - - -/* status code and error code */ -0 bmIccStatus 1 0, 1, 2 0= The USB-ICC is present and activated. - (2 bits) 1= The USB-ICC is present but not activated -(2 bits) 2= The USB-ICC is virtually not present - 3= RFU - (4 bits) RFU -(6 bits) bmCommandStatus (2 bits) 0, 1, 2 0= Processed without error. - 1= Failed, error condition given by bError. - 2= Time extension is requested - 3= RFU -1 bError 1 Error codes - - -/* error code */ -ICC_MUTE 0xFE The applications of the USB-ICC did not respond - or the ATR could not be sent by the USB-ICC. -XFR_OVERRUN 0xFC The USB-ICC detected a buffer overflow when - receiving a data block. -HW_ERROR 0xFB The USB-ICC detected a hardware error. - - (0xC0 to 0x81) User defined - - 0xE0, 0xEF, 0xF0, These values shall not be used by the USB-ICC - 0xF2..0xF8, 0xFD - - all others Reserved for future use - (0x80 and those filling the gaps) +#ifdef HOST_BIG_ENDIAN +#error "Here, you need to write code to correct byte order." +#else + /* nothing to do */ #endif + len = USB_SIL_Read (EP5_OUT, icc_rcv_data); + + icc_header = (struct icc_header *)icc_rcv_data; + icc_data = &icc_rcv_data[ICC_MSG_DATA_OFFSET]; + icc_data_size = len - ICC_MSG_HEADER_SIZE; + icc_seq = icc_header->seq; + + if (icc_data_size < 0 || icc_data_size != icc_header->data_len) + /* just ignore short invalid packet, enable Rx again */ + SetEPRxValid (ENDP5); + else + /* Notify icc_thread */ + chEvtSignalI (icc_thread, EV_RX_DATA_READY); +} + enum icc_state { ICC_STATE_START, /* Initial */ - ICC_STATE_WAIT, /* Waiting ADPU */ + ICC_STATE_WAIT, /* Waiting APDU */ /* Busy1, Busy2, Busy3, Busy5 */ ICC_STATE_EXECUTE, /* Busy4 */ - ICC_STATE_RECEIVE, /* ADPU Received Partially */ - ICC_STATE_SEND /* ADPU Sent Partially */ + ICC_STATE_RECEIVE, /* APDU Received Partially */ + ICC_STATE_SEND, /* APDU Sent Partially */ }; static enum icc_state icc_state; /* Direct conversion, T=1, "FSIJ" */ -static const char ATR[] = { '\x3B', '\x84', '\x01', 'F', 'S', 'I', 'J' }; +static const char ATR[] = { '\x3B', '\x84', '\x01', 'F', 'S', 'I', 'J', + ('\x84'^'F'^'S'^'I'^'J') }; /* Send back ATR (Answer To Reset) */ enum icc_state -icc_power_on (char *buf, int len) +icc_power_on (void) { - int i, size_atr; + int size_atr; size_atr = sizeof (ATR); - icc_buffer_in[0] = 0x80; - icc_buffer_in[1] = size_atr; - /* not including '\0' at the end */ - icc_buffer_in[2] = 0x00; - icc_buffer_in[3] = 0x00; - icc_buffer_in[4] = 0x00; - icc_buffer_in[5] = 0x00; /* Slot */ - icc_buffer_in[ICC_MSG_SEQ_OFFSET] = buf[ICC_MSG_SEQ_OFFSET]; - icc_buffer_in[ICC_MSG_STATUS_OFFSET] = 0x00; - icc_buffer_in[ICC_MSG_ERROR_OFFSET] = 0x00; - icc_buffer_in[9] = 0x00; - for (i = 0; i < size_atr; i++) - icc_buffer_in[i+10] = ATR[i]; + icc_tx_data[0] = ICC_DATA_BLOCK_RET; + icc_tx_data[1] = size_atr; + icc_tx_data[2] = 0x00; + icc_tx_data[3] = 0x00; + icc_tx_data[4] = 0x00; + icc_tx_data[5] = 0x00; /* Slot */ + icc_tx_data[ICC_MSG_SEQ_OFFSET] = icc_seq; + icc_tx_data[ICC_MSG_STATUS_OFFSET] = 0x00; + icc_tx_data[ICC_MSG_ERROR_OFFSET] = 0x00; + icc_tx_data[ICC_MSG_CHAIN_OFFSET] = 0x00; + memcpy (&icc_tx_data[ICC_MSG_DATA_OFFSET], ATR, size_atr); - icc_count_in = 10 + size_atr; + if (!icc_tx_ready ()) + { + _write ("ERR0B\r\n", 7); + } + else + { + icc_tx_size = ICC_MSG_DATA_OFFSET + size_atr; + USB_SIL_Write (EP4_IN, icc_tx_data, icc_tx_size); + SetEPTxValid (ENDP4); + _write ("ON\r\n", 4); + } - USB_SIL_Write (EP4_IN, icc_buffer_in, icc_count_in); - SetEPTxValid (ENDP4); - - _write ("ON\r\n", 4); return ICC_STATE_WAIT; } static void -icc_send_status (char *buf, int len) +icc_send_status (void) { - icc_buffer_in[0] = 0x81; - icc_buffer_in[1] = 0x00; - icc_buffer_in[2] = 0x00; - icc_buffer_in[3] = 0x00; - icc_buffer_in[4] = 0x00; - icc_buffer_in[5] = 0x00; /* Slot */ - icc_buffer_in[ICC_MSG_SEQ_OFFSET] = buf[ICC_MSG_SEQ_OFFSET]; + icc_tx_data[0] = ICC_SLOT_STATUS_RET; + icc_tx_data[1] = 0x00; + icc_tx_data[2] = 0x00; + icc_tx_data[3] = 0x00; + icc_tx_data[4] = 0x00; + icc_tx_data[5] = 0x00; /* Slot */ + icc_tx_data[ICC_MSG_SEQ_OFFSET] = icc_seq; if (icc_state == ICC_STATE_START) - icc_buffer_in[ICC_MSG_STATUS_OFFSET] = 2; /* No ICC present */ + /* 1: ICC present but not activated 2: No ICC present */ + icc_tx_data[ICC_MSG_STATUS_OFFSET] = 1; else - icc_buffer_in[ICC_MSG_STATUS_OFFSET] = 0; /* An ICC is present and active */ - icc_buffer_in[ICC_MSG_ERROR_OFFSET] = 0x00; - icc_buffer_in[9] = 0x00; + /* An ICC is present and active */ + icc_tx_data[ICC_MSG_STATUS_OFFSET] = 0; + icc_tx_data[ICC_MSG_ERROR_OFFSET] = 0x00; + icc_tx_data[ICC_MSG_CHAIN_OFFSET] = 0x00; - icc_count_in = 10; - USB_SIL_Write (EP4_IN, icc_buffer_in, icc_count_in); - SetEPTxValid (ENDP4); + if (!icc_tx_ready ()) + { + _write ("ERR0C\r\n", 7); + } + else + { + icc_tx_size = ICC_MSG_DATA_OFFSET; + USB_SIL_Write (EP4_IN, icc_tx_data, icc_tx_size); + SetEPTxValid (ENDP4); + } + _write ("St\r\n", 4); } enum icc_state -icc_power_off (char *buf, int len) +icc_power_off (void) { - icc_send_status (buf, len); + icc_send_status (); _write ("OFF\r\n", 5); return ICC_STATE_START; } +uint8_t cmd_APDU[MAX_CMD_APDU_SIZE]; +uint8_t res_APDU[MAX_RES_APDU_SIZE]; +int cmd_APDU_size; +int res_APDU_size; + +static uint8_t *p_cmd; +static uint8_t *p_res; + +static void +icc_send_data_block (uint8_t status, uint8_t error, uint8_t chain, + uint8_t *data, int len) +{ + icc_tx_data[0] = ICC_DATA_BLOCK_RET; + icc_tx_data[1] = len & 0xFF; + icc_tx_data[2] = (len >> 8)& 0xFF; + icc_tx_data[3] = (len >> 16)& 0xFF; + icc_tx_data[4] = (len >> 24)& 0xFF; + icc_tx_data[5] = 0x00; /* Slot */ + icc_tx_data[ICC_MSG_SEQ_OFFSET] = icc_seq; + icc_tx_data[ICC_MSG_STATUS_OFFSET] = status; + icc_tx_data[ICC_MSG_ERROR_OFFSET] = error; + icc_tx_data[ICC_MSG_CHAIN_OFFSET] = chain; + if (len) + memcpy (&icc_tx_data[ICC_MSG_DATA_OFFSET], data, len); + + if (!icc_tx_ready ()) + { /* not ready to send */ + _write ("ERR09\r\n", 7); + } + else + { + icc_tx_size = ICC_MSG_DATA_OFFSET + len; + USB_SIL_Write (EP4_IN, icc_tx_data, icc_tx_size); + SetEPTxValid (ENDP4); + _write ("DATA\r\n", 6); + } +} + static enum icc_state icc_handle_data (void) { enum icc_state next_state = icc_state; -#if 1 - char b[3]; - - b[0] = icc_buffer_out[0]; - b[1] = '\r'; - b[2] = '\n'; - - _write (b, 3); -#endif - switch (icc_state) { case ICC_STATE_START: - if (icc_buffer_out[0] == ICC_POWER_ON) - next_state = icc_power_on (icc_buffer_out, icc_count_out); - else if (icc_buffer_out[0] == ICC_POWER_OFF) - next_state = icc_power_off (icc_buffer_out, icc_count_out); - else if (icc_buffer_out[0] == ICC_SLOT_STATUS) - icc_send_status (icc_buffer_out, icc_count_out); + if (icc_header->msg_type == ICC_POWER_ON) + next_state = icc_power_on (); + else if (icc_header->msg_type == ICC_POWER_OFF) + next_state = icc_power_off (); + else if (icc_header->msg_type == ICC_SLOT_STATUS) + icc_send_status (); else { /* XXX: error */ _write ("ERR01\r\n", 7); } break; case ICC_STATE_WAIT: - if (icc_buffer_out[0] == ICC_POWER_OFF) - next_state = icc_power_off (icc_buffer_out, icc_count_out); - else if (icc_buffer_out[0] == ICC_SLOT_STATUS) - icc_send_status (icc_buffer_out, icc_count_out); - else if (icc_buffer_out[0] == XFR_BLOCK) + if (icc_header->msg_type == ICC_POWER_ON) + /* Not in the spec., but GPG 2 */ + next_state = icc_power_on (); + else if (icc_header->msg_type == ICC_POWER_OFF) + next_state = icc_power_off (); + else if (icc_header->msg_type == ICC_SLOT_STATUS) + icc_send_status (); + else if (icc_header->msg_type == ICC_XFR_BLOCK) { - if (icc_buffer_out[8] == 0 && icc_buffer_out[9] == 0) - { - /* Give this message to GPG thread */ - next_state = ICC_STATE_EXECUTE; + if (icc_header->param == 0) + { /* Give this message to GPG thread */ + p_cmd = cmd_APDU; + memcpy (p_cmd, icc_data, icc_data_size); + cmd_APDU_size = icc_data_size; chEvtSignal (gpg_thread, (eventmask_t)1); + next_state = ICC_STATE_EXECUTE; } - else if (icc_buffer_out[8] == 1 && icc_buffer_out[9] == 0) + else if (icc_header->param == 1) { - /* XXX: return back RDR_to_PC_DataBlock */ - /* bChainParameter = 0x10, abData=empty */ + p_cmd = cmd_APDU; + memcpy (p_cmd, icc_data, icc_data_size); + p_cmd += icc_data_size; + cmd_APDU_size = icc_data_size; + icc_send_data_block (0, 0, 0x10, NULL, 0); next_state = ICC_STATE_RECEIVE; } else - { - /* XXX: error */; + { /* XXX: error */; _write ("ERR02\r\n", 7); } } else { /* XXX: error */ _write ("ERR03\r\n", 7); + put_byte (icc_header->msg_type); + next_state = ICC_STATE_START; } break; case ICC_STATE_EXECUTE: - if (icc_buffer_out[0] == ICC_POWER_OFF) + if (icc_header->msg_type == ICC_POWER_OFF) { /* XXX: Kill GPG thread */ - next_state = icc_power_off (icc_buffer_out, icc_count_out); + next_state = icc_power_off (); } - else if (icc_buffer_out[0] == ICC_SLOT_STATUS) - icc_send_status (icc_buffer_out, icc_count_out); + else if (icc_header->msg_type == ICC_SLOT_STATUS) + icc_send_status (); else { /* XXX: error */ _write ("ERR04\r\n", 7); + put_byte (icc_header->msg_type); + next_state = ICC_STATE_START; } break; case ICC_STATE_RECEIVE: - if (icc_buffer_out[0] == ICC_POWER_OFF) + if (icc_header->msg_type == ICC_POWER_OFF) + next_state = icc_power_off (); + else if (icc_header->msg_type == ICC_SLOT_STATUS) + icc_send_status (); + else if (icc_header->msg_type == ICC_XFR_BLOCK) { - /* XXX: release partial ADPU received */ - next_state = icc_power_off (icc_buffer_out, icc_count_out); - } - else if (icc_buffer_out[0] == ICC_SLOT_STATUS) - icc_send_status (icc_buffer_out, icc_count_out); - else if (icc_buffer_out[0] == XFR_BLOCK) - { - if (1 /* XXX */) /* Got final block */ + if (cmd_APDU_size + icc_data_size <= MAX_CMD_APDU_SIZE) { - /* Give this message to GPG thread */ - next_state = ICC_STATE_EXECUTE; - chEvtSignal (gpg_thread, (eventmask_t)1); + memcpy (p_cmd, icc_data, icc_data_size); + p_cmd += icc_data_size; + cmd_APDU_size += icc_data_size; + + if (icc_header->param == 2) /* Got final block */ + { /* Give this message to GPG thread */ + next_state = ICC_STATE_EXECUTE; + cmd_APDU_size = p_cmd - cmd_APDU; + chEvtSignal (gpg_thread, (eventmask_t)1); + } + else if (icc_header->param == 3) + icc_send_data_block (0, 0, 0x10, NULL, 0); + else + { /* XXX: error */ + _write ("ERR08\r\n", 7); + } + } + else /* Overrun */ + { + icc_send_data_block (ICC_CMD_STATUS_ERROR, ICC_ERROR_XFR_OVERRUN, + 0, NULL, 0); + next_state = ICC_STATE_WAIT; } } else { /* XXX: error */ _write ("ERR05\r\n", 7); + put_byte (icc_header->msg_type); + next_state = ICC_STATE_START; } break; case ICC_STATE_SEND: - if (icc_buffer_out[0] == ICC_POWER_OFF) + if (icc_header->msg_type == ICC_POWER_OFF) + next_state = icc_power_off (); + else if (icc_header->msg_type == ICC_SLOT_STATUS) + icc_send_status (); + else if (icc_header->msg_type == ICC_XFR_BLOCK) { - /* XXX: release partial ADPU sending */ - next_state = icc_power_off (icc_buffer_out, icc_count_out); - } - else if (icc_buffer_out[0] == ICC_SLOT_STATUS) - icc_send_status (icc_buffer_out, icc_count_out); - else if (icc_buffer_out[0] == XFR_BLOCK) - { - /* XXX: send back to data */ - /* finished?, then go ICC_STATE_WAIT */ - next_state = ICC_STATE_WAIT; + if (icc_header->param == 0x10) + { + if (res_APDU_size <= ICC_MAX_MSG_DATA_SIZE) + { + icc_send_data_block (0, 0, 0x02, p_res, res_APDU_size); + next_state = ICC_STATE_WAIT; + } + else + { + icc_send_data_block (0, 0, 0x03, + p_res, ICC_MAX_MSG_DATA_SIZE); + p_res += ICC_MAX_MSG_DATA_SIZE; + res_APDU_size -= ICC_MAX_MSG_DATA_SIZE; + } + } + else + { /* XXX: error */ + _write ("ERR0A\r\n", 7); + put_byte (icc_header->param >> 8); + put_byte (icc_header->param & 0xff); + next_state = ICC_STATE_WAIT; + } } else { /* XXX: error */ _write ("ERR06\r\n", 7); + put_byte (icc_header->msg_type); + next_state = ICC_STATE_START; } break; } - icc_count_out = 0; SetEPRxValid (ENDP5); return next_state; } @@ -383,18 +429,16 @@ icc_handle_timeout (void) { enum icc_state next_state = icc_state; - /* - * - * XXX: ICC_STATE_EXECUTE -> kill - * XXX: ICC_STATE_RECEIVE -> cancel - * XXX: ICC_STATE_SEND -> cancel - */ - if (icc_state == ICC_STATE_START - || icc_state == ICC_STATE_WAIT) - ; - else + switch (icc_state) { - next_state = ICC_STATE_WAIT; + case ICC_STATE_EXECUTE: + icc_send_data_block (ICC_CMD_STATUS_TIMEEXT, 0, 0, NULL, 0); + break; + case ICC_STATE_RECEIVE: + case ICC_STATE_SEND: + case ICC_STATE_START: + case ICC_STATE_WAIT: + break; } chEvtSignal (blinker_thread, (eventmask_t)1); @@ -412,6 +456,7 @@ USBthread (void *arg) chEvtClear (ALL_EVENTS); icc_state = ICC_STATE_START; + icc_tx_size = -1; while (1) { @@ -425,14 +470,18 @@ USBthread (void *arg) { if (icc_state == ICC_STATE_EXECUTE) { - if (1/* message is short enough*/) + if (res_APDU_size <= ICC_MAX_MSG_DATA_SIZE) { - /* XXX: send back result */; + icc_send_data_block (0, 0, 0, res_APDU, res_APDU_size); icc_state = ICC_STATE_WAIT; } else { - /* XXX: send back part of result */; + p_res = res_APDU; + icc_send_data_block (0, 0, 0x01, + p_res, ICC_MAX_MSG_DATA_SIZE); + p_res += ICC_MAX_MSG_DATA_SIZE; + res_APDU_size -= ICC_MAX_MSG_DATA_SIZE; icc_state = ICC_STATE_SEND; } } diff --git a/src/usb_desc.c b/src/usb_desc.c index 00178da..bf175e8 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -185,7 +185,7 @@ static const uint8_t gnukStringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] = { static uint8_t gnukStringSerial[] = { 8, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ - '2', 0, '.', 0, '0', 0 + '2', 0, '0', 0, '0', 0 }; ONE_DESCRIPTOR Device_Descriptor = {