diff --git a/ChangeLog b/ChangeLog index 6680b87..a307ed9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,46 @@ +2010-09-08 NIIBE Yutaka + + * src/ac.c (calc_md): Make SHA1 variable auto. + + * src/debug.c (put_int): New. + + * src/gnuk.ld (__process_stack_size__): Removed. + + * src/main.c (STDOUTthread): Use Event. + (main): Make LED ON during command execution, blink usually. + + * src/openpgp-do.c (encrypt, decrypt): Make AES variables auto. + (gpg_do_table): GPG_DO_ALG_AUT is NULL. + + * src/openpgp.c (cmd_pso): Bug fix for extended Lc. + + * src/usb-icc.c (icc_power_off): Make LED ON during command + execution. + (USB_ICC_TIMEOUT): Longer value (was: 1000). + + * src/usb_desc.c (gnukConfigDescriptor): Fix bcdCCID value. + + * src/vcomport.mk (VCOMSRC): Use our own usb_endp.c. + + * src/usb_desc.c (gnukConfigDescriptor): ICC Descriptor is + Revision 1.0. + + * polarssl-0.14.0/include/polarssl/config.h: Commend out + POLARSSL_SELF_TEST. + + * polarssl-0.14.0/library/rsa.c (rsa_private): Don't check input, + so that we don't access ctx->N. + (rsa_pkcs1_decrypt): size of BUF is enough as 256. + + * polarssl-0.14.0/library/sha1.c (sha1_file): #if-out to avoid + stdio of libc. + + * polarssl-0.14.0/library/bignum.c (mpi_write_hlp) + (mpi_write_string, mpi_read_file, mpi_read_file): #if-out to avoid + stdio of libc. + + * gnuk.svg: New file. + 2010-09-06 NIIBE Yutaka * Initial version 0.0. - diff --git a/gnuk.svg b/gnuk.svg new file mode 100644 index 0000000..87f5aab --- /dev/null +++ b/gnuk.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/polarssl-0.14.0/include/polarssl/config.h b/polarssl-0.14.0/include/polarssl/config.h index c51df72..6c9b61b 100644 --- a/polarssl-0.14.0/include/polarssl/config.h +++ b/polarssl-0.14.0/include/polarssl/config.h @@ -77,8 +77,9 @@ /* * Enable the checkup functions (*_self_test). - */ + * #define POLARSSL_SELF_TEST + */ /* * Enable run-time version information functions diff --git a/polarssl-0.14.0/library/bignum.c b/polarssl-0.14.0/library/bignum.c index 78e9384..fadc760 100644 --- a/polarssl-0.14.0/library/bignum.c +++ b/polarssl-0.14.0/library/bignum.c @@ -310,6 +310,7 @@ cleanup: return( ret ); } +#if 0 /* * Helper to write the digits high-order first */ @@ -466,6 +467,7 @@ cleanup: return( ret ); } +#endif /* * Import X from unsigned binary data, big endian diff --git a/polarssl-0.14.0/library/rsa.c b/polarssl-0.14.0/library/rsa.c index 77404fc..e42aab4 100644 --- a/polarssl-0.14.0/library/rsa.c +++ b/polarssl-0.14.0/library/rsa.c @@ -245,13 +245,13 @@ int rsa_private( rsa_context *ctx, mpi_init( &T, &T1, &T2, NULL ); MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); - +#if 0 if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) { mpi_free( &T, NULL ); return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); } - +#endif #if 0 MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) ); #else @@ -358,7 +358,7 @@ int rsa_pkcs1_decrypt( rsa_context *ctx, { int ret, ilen; unsigned char *p; - unsigned char buf[1024]; + unsigned char buf[256]; ilen = ctx->len; diff --git a/polarssl-0.14.0/library/sha1.c b/polarssl-0.14.0/library/sha1.c index f320c43..a5595d0 100644 --- a/polarssl-0.14.0/library/sha1.c +++ b/polarssl-0.14.0/library/sha1.c @@ -326,6 +326,7 @@ void sha1( const unsigned char *input, int ilen, unsigned char output[20] ) memset( &ctx, 0, sizeof( sha1_context ) ); } +#if 0 /* * output = SHA-1( file contents ) */ @@ -357,6 +358,7 @@ int sha1_file( const char *path, unsigned char output[20] ) fclose( f ); return( 0 ); } +#endif /* * SHA-1 HMAC context setup diff --git a/src/ac.c b/src/ac.c index 598220e..b6c4224 100644 --- a/src/ac.c +++ b/src/ac.c @@ -74,6 +74,8 @@ verify_pso_other (const uint8_t *pw, int pw_len) || pw_status_bytes[PW_STATUS_PW1] == 0) /* locked */ return 0; + DEBUG_INFO ("verify_pso_other\r\n"); + keystring[0] = pw_len; sha1 (pw, pw_len, keystring+1); memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES); @@ -96,7 +98,6 @@ verify_pso_other (const uint8_t *pw, int pw_len) /* * For keystring of PW3, we use SALT+ITER+MD format */ -static sha1_context sha1_ctx; static uint32_t decode_iterate_count (uint8_t x) @@ -108,6 +109,8 @@ static void calc_md (int count, const uint8_t *salt, const uint8_t *pw, int pw_len, uint8_t md[KEYSTRING_MD_SIZE]) { + sha1_context sha1_ctx; + sha1_starts (&sha1_ctx); while (count > pw_len + 8) diff --git a/src/call-rsa.c b/src/call-rsa.c index 88a189e..725b818 100644 --- a/src/call-rsa.c +++ b/src/call-rsa.c @@ -21,6 +21,7 @@ * */ +#include #include "config.h" #include "ch.h" #include "gnuk.h" @@ -52,7 +53,7 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len) mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P); mpi_free (&P1, &Q1, &H, NULL); - DEBUG_INFO ("RSA..."); + DEBUG_INFO ("RSA sign..."); if ((r = rsa_check_privkey (&rsa_ctx)) == 0) DEBUG_INFO ("ok..."); @@ -114,10 +115,15 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len) int r; int output_len; + put_string ("RSA decrypt:"); + put_word ((uint32_t)&output_len); + mpi_init (&P1, &Q1, &H, NULL); rsa_init (&rsa_ctx, RSA_PKCS_V15, 0); rsa_ctx.len = msg_len; + DEBUG_WORD (msg_len); + mpi_read_string (&rsa_ctx.E, 16, "10001"); mpi_read_binary (&rsa_ctx.P, &kd.data[0], 2048 / 8 / 2); mpi_read_binary (&rsa_ctx.Q, &kd.data[128], 2048 / 8 / 2); @@ -131,8 +137,9 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len) mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P); mpi_free (&P1, &Q1, &H, NULL); - DEBUG_INFO ("RSA..."); - + DEBUG_INFO ("RSA decrypt ..."); +#if 0 + /* This consume some memory */ if ((r = rsa_check_privkey (&rsa_ctx)) == 0) DEBUG_INFO ("ok..."); else @@ -142,6 +149,7 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len) rsa_free (&rsa_ctx); return r; } +#endif r = rsa_pkcs1_decrypt (&rsa_ctx, RSA_PRIVATE, &output_len, input, output, MAX_RES_APDU_SIZE - 2); diff --git a/src/chconf.h b/src/chconf.h index dadce7e..45aef3f 100644 --- a/src/chconf.h +++ b/src/chconf.h @@ -32,9 +32,9 @@ #define CH_DBG_ENABLE_CHECKS FALSE #define CH_DBG_ENABLE_ASSERTS FALSE #define CH_DBG_ENABLE_TRACE FALSE -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK TRUE #define CH_DBG_FILL_THREADS FALSE -#define CH_DBG_THREADS_PROFILING TRUE +#define CH_DBG_THREADS_PROFILING FALSE #define THREAD_EXT_FIELDS \ struct { \ diff --git a/src/config.h b/src/config.h index 630108e..d088159 100644 --- a/src/config.h +++ b/src/config.h @@ -2,4 +2,15 @@ #define ENABLE_VIRTUAL_COM_PORT 1 #endif -#define GNUK_MAX_PACKET_SIZE 64 /* USB */ +/* Packet size of USB Bulk transfer for full speed */ +#define GNUK_MAX_PACKET_SIZE 64 + +#if 0 +/* FSIJ */ +#define MANUFACTURER_IN_AID 0xf5, 0x17 +#else +/* for random serial number*/ +#define MANUFACTURER_IN_AID 0xff, 0xfe +#endif + +#define SERIAL_NUMBER_IN_AID 0x00, 0x00, 0x00, 0x01 diff --git a/src/debug.c b/src/debug.c index c295320..43978a8 100644 --- a/src/debug.c +++ b/src/debug.c @@ -78,6 +78,30 @@ put_word (uint32_t x) _write ("\r\n", 2); } +void +put_int (uint32_t x) +{ + char s[10]; + int i; + + for (i = 0; i < 10; i++) + { + s[i] = '0' + (x % 10); + x /= 10; + if (x == 0) + break; + } + + while (i) + { + _write (s+i, 1); + i--; + } + + _write (s, 1); + _write ("\r\n", 2); +} + void put_binary (const char *s, int len) { diff --git a/src/gnuk.h b/src/gnuk.h index 9c876cd..4179396 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -1,9 +1,15 @@ extern Thread *blinker_thread; +#define EV_LED_ON ((eventmask_t)1) +#define EV_LED_OFF ((eventmask_t)2) + +extern Thread *stdout_thread; +#define EV_TX_READY ((eventmask_t)1) extern void put_byte (uint8_t b); extern void put_byte_with_no_nl (uint8_t b); extern void put_short (uint16_t x); extern void put_word (uint32_t x); +extern void put_int (uint32_t x); extern void put_string (const char *s); extern void put_binary (const char *s, int len); @@ -17,9 +23,7 @@ extern size_t strlen (const char *s); extern int strncmp(const char *s1, const char *s2, size_t n); extern void *memcpy (void *dest, const void *src, size_t n); extern void *memset (void *s, int c, size_t n); -extern void *malloc (size_t size); extern int memcmp (const void *s1, const void *s2, size_t n); -extern void free (void *ptr); /* * Interface between ICC<-->GPG @@ -29,7 +33,7 @@ extern Thread *gpg_thread; #define USB_BUF_SIZE 64 -#define EV_EXEC_FINISHED (eventmask_t)2 /* GPG Execution finished */ +#define EV_EXEC_FINISHED ((eventmask_t)2) /* GPG Execution finished */ /* maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */ #define MAX_CMD_APDU_SIZE (7+282) /* header + data */ diff --git a/src/gnuk.ld b/src/gnuk.ld index 393e770..c89ee1e 100644 --- a/src/gnuk.ld +++ b/src/gnuk.ld @@ -28,8 +28,7 @@ * ST32F103 memory setup. */ __main_stack_size__ = 0x0400; -__process_stack_size__ = 0x0400; -__stacks_total_size__ = __main_stack_size__ + __process_stack_size__; +__stacks_total_size__ = __main_stack_size__; MEMORY { diff --git a/src/main.c b/src/main.c index 694d186..766b88f 100644 --- a/src/main.c +++ b/src/main.c @@ -72,16 +72,17 @@ _write (const char *s, int size) chMtxUnlock (); } -extern uint32_t count_in; -extern __IO uint32_t count_out; -extern uint8_t buffer_in[VIRTUAL_COM_PORT_DATA_SIZE]; -extern uint8_t buffer_out[VIRTUAL_COM_PORT_DATA_SIZE]; +Thread *stdout_thread; +uint32_t count_in; +uint8_t buffer_in[VIRTUAL_COM_PORT_DATA_SIZE]; static WORKING_AREA(waSTDOUTthread, 128); + static msg_t STDOUTthread (void *arg) { (void)arg; + stdout_thread = chThdSelf (); again: @@ -127,11 +128,12 @@ STDOUTthread (void *arg) p += count_in; } + chEvtClear (EV_TX_READY); + USB_SIL_Write (EP3_IN, buffer_in, count_in); SetEPTxValid (ENDP3); - while (count_in > 0) - chThdSleepMilliseconds (1); + chEvtWaitOne (EV_TX_READY); } stdout.str = NULL; @@ -160,9 +162,11 @@ extern msg_t GPGthread (void *arg); Thread *blinker_thread; /* - * Red LEDs blinker + * LEDs blinks. + * When GPGthread execute some command, LED stop blinking, but always ON. */ -#define EV_LED (eventmask_t)1 +#define LED_BLINKER_TIMEOUT MS2ST(200) + /* * Entry point, note, the main() function is already a thread in the system @@ -172,6 +176,7 @@ int main (int argc, char **argv) { eventmask_t m; + uint8_t led_state = 0; int count = 0; (void)argc; @@ -199,30 +204,33 @@ main (int argc, char **argv) while (1) { -#if 0 - if (palReadPad(IOPORT1, GPIOA_BUTTON)) - palSetPad (IOPORT3, GPIOC_LED); -#endif + count++; - m = chEvtWaitOneTimeout (ALL_EVENTS, 100); - if (m == EV_LED) + m = chEvtWaitOneTimeout (ALL_EVENTS, LED_BLINKER_TIMEOUT); + if (m == EV_LED_ON) + led_state = 1; + else if (m == EV_LED_OFF) + led_state = 0; + + if (led_state) palClearPad (IOPORT3, GPIOC_LED); + else + { + if ((count & 1)) + palClearPad (IOPORT3, GPIOC_LED); + else + palSetPad (IOPORT3, GPIOC_LED); + } #ifdef DEBUG_MORE if (bDeviceState == CONFIGURED && (count % 100) == 0) { - DEBUG_WORD (count / 100); + DEBUG_SHORT (count / 100); _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); } #endif - - m = chEvtWaitOneTimeout (ALL_EVENTS, 100); - if (m == EV_LED) - palSetPad (IOPORT3, GPIOC_LED); - - count++; } return 0; diff --git a/src/openpgp-do.c b/src/openpgp-do.c index 770b33d..e0100c1 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -21,8 +21,9 @@ * */ -#include "config.h" +#include +#include "config.h" #include "ch.h" #include "gnuk.h" #include "openpgp.h" @@ -42,8 +43,8 @@ static const uint8_t aid[] __attribute__ ((aligned (1))) = { 16, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01, 0x02, 0x00, /* Version 2.0 */ - 0xf5, 0x17, /* Manufacturer (FSIJ) */ - 0x00, 0x00, 0x00, 0x01, /* Serial */ + MANUFACTURER_IN_AID, + SERIAL_NUMBER_IN_AID, 0x00, 0x00 }; @@ -398,10 +399,6 @@ rw_pw_status (uint16_t tag, const uint8_t *data, int len, int is_write) } } -static aes_context aes; -static uint8_t iv[16]; -static int iv_offset; - static void proc_resetting_code (const uint8_t *data, int len) { @@ -450,6 +447,10 @@ proc_resetting_code (const uint8_t *data, int len) static void encrypt (const uint8_t *key_str, uint8_t *data, int len) { + aes_context aes; + uint8_t iv[16]; + int iv_offset; + DEBUG_INFO ("ENC\r\n"); DEBUG_BINARY (data, len); @@ -464,6 +465,10 @@ struct key_data kd; static void decrypt (const uint8_t *key_str, uint8_t *data, int len) { + aes_context aes; + uint8_t iv[16]; + int iv_offset; + aes_setkey_enc (&aes, key_str, 128); memset (iv, 0, 16); iv_offset = 0; @@ -800,7 +805,7 @@ gpg_do_table[] = { { GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities }, { GPG_DO_ALG_SIG, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, { GPG_DO_ALG_DEC, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, - { GPG_DO_ALG_AUT, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, + { GPG_DO_ALG_AUT, DO_FIXED, AC_ALWAYS, AC_NEVER, NULL }, /* Compound data: Read access only */ { GPG_DO_CH_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ch_data }, { GPG_DO_APP_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_app_data }, diff --git a/src/openpgp.c b/src/openpgp.c index 677d335..711327b 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -510,10 +510,18 @@ cmd_get_data (void) static void cmd_pso (void) { - int len; + int len = cmd_APDU[4]; + int data_start = 5; int r; - DEBUG_INFO (" - PSO\r\n"); + if (len == 0) + { + len = (cmd_APDU[5]<<8) | cmd_APDU[6]; + data_start = 7; + } + + DEBUG_INFO (" - PSO: "); + DEBUG_WORD ((uint32_t)&r); if (cmd_APDU[2] == 0x9e && cmd_APDU[3] == 0x9a) { @@ -529,14 +537,13 @@ cmd_pso (void) { DEBUG_INFO (" wrong length: "); DEBUG_SHORT (cmd_APDU_size); + GPG_ERROR (); } else { - len = (cmd_APDU[5]<<8) | cmd_APDU[6]; + DEBUG_SHORT (len); /* Should be cmd_APDU_size - 6 */ - DEBUG_BYTE (len); /* Should be cmd_APDU_size - 6 */ - - r = rsa_sign (&cmd_APDU[7], res_APDU, len); + r = rsa_sign (&cmd_APDU[data_start], res_APDU, len); if (r < 0) GPG_ERROR (); else @@ -556,8 +563,6 @@ cmd_pso (void) } else if (cmd_APDU[2] == 0x80 && cmd_APDU[3] == 0x86) { - len = (cmd_APDU[5]<<8) | cmd_APDU[6]; - if (!ac_check_status (AC_PSO_OTHER_AUTHORIZED)) { DEBUG_INFO ("security error."); @@ -565,9 +570,12 @@ cmd_pso (void) return; } - DEBUG_BYTE (len); + DEBUG_SHORT (len); - r = rsa_decrypt (&cmd_APDU[7], res_APDU, len); + /* Skip padding 0x00 */ + data_start++; + len--; + r = rsa_decrypt (&cmd_APDU[data_start], res_APDU, len); if (r < 0) GPG_ERROR (); } @@ -577,7 +585,7 @@ cmd_pso (void) DEBUG_BYTE (cmd_APDU[2]); DEBUG_INFO (" - ??"); DEBUG_BYTE (cmd_APDU[3]); - GPG_SUCCESS (); + GPG_ERROR (); } DEBUG_INFO ("PSO done.\r\n"); @@ -639,7 +647,8 @@ GPGthread (void *arg) m = chEvtWaitOne (ALL_EVENTS); - DEBUG_INFO ("GPG!\r\n"); + DEBUG_INFO ("GPG!: "); + DEBUG_WORD ((uint32_t)&m); process_command_apdu (); diff --git a/src/stdlib.h b/src/stdlib.h new file mode 100644 index 0000000..9abc3f2 --- /dev/null +++ b/src/stdlib.h @@ -0,0 +1,15 @@ +/* + * stdlib.h replacement, so that we can replace malloc functions + */ + +typedef unsigned int size_t; + +#ifdef REPLACE_MALLOC +#define malloc my_malloc +#define free my_free +#define realloc my_realloc +#endif + +extern void *malloc (size_t size); +extern void free (void *ptr); +extern void *realloc (void *ptr, size_t size); diff --git a/src/usb-icc.c b/src/usb-icc.c index 809fee9..84cf700 100644 --- a/src/usb-icc.c +++ b/src/usb-icc.c @@ -229,7 +229,6 @@ icc_send_status (void) enum icc_state icc_power_off (void) { - icc_send_status (); DEBUG_INFO ("OFF\r\n"); return ICC_STATE_START; @@ -311,6 +310,7 @@ icc_handle_data (void) cmd_APDU_size = icc_data_size; chEvtSignal (gpg_thread, (eventmask_t)1); next_state = ICC_STATE_EXECUTE; + chEvtSignal (blinker_thread, EV_LED_ON); } else if (icc_header->param == 1) { @@ -364,6 +364,7 @@ icc_handle_data (void) if (icc_header->param == 2) /* Got final block */ { /* Give this message to GPG thread */ next_state = ICC_STATE_EXECUTE; + chEvtSignal (blinker_thread, EV_LED_ON); cmd_APDU_size = p_cmd - cmd_APDU; chEvtSignal (gpg_thread, (eventmask_t)1); } @@ -439,9 +440,7 @@ icc_handle_timeout (void) switch (icc_state) { case ICC_STATE_EXECUTE: -#if 0 icc_send_data_block (ICC_CMD_STATUS_TIMEEXT, 0, 0, NULL, 0); -#endif break; case ICC_STATE_RECEIVE: case ICC_STATE_SEND: @@ -450,11 +449,10 @@ icc_handle_timeout (void) break; } - chEvtSignal (blinker_thread, (eventmask_t)1); return next_state; } -#define USB_ICC_TIMEOUT MS2ST(1000) +#define USB_ICC_TIMEOUT MS2ST(1950) msg_t USBthread (void *arg) @@ -479,6 +477,8 @@ USBthread (void *arg) { if (icc_state == ICC_STATE_EXECUTE) { + chEvtSignal (blinker_thread, EV_LED_OFF); + if (res_APDU_size <= ICC_MAX_MSG_DATA_SIZE) { icc_send_data_block (0, 0, 0, res_APDU, res_APDU_size); diff --git a/src/usb_desc.c b/src/usb_desc.c index 71260a1..ca76579 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -62,7 +62,7 @@ static const uint8_t gnukConfigDescriptor[] = { /* ICC Descriptor */ 54, /* bLength: */ 0x21, /* bDescriptorType: USBDESCR_ICC */ - 0x10, 0x01, /* bcdCCID: 1.1 XXX */ + 0x00, 0x01, /* bcdCCID: revision 1.0 */ 0, /* bMaxSlotIndex: */ 1, /* bVoltageSupport: FIXED VALUE */ 0x02, 0, 0, 0, /* dwProtocols: T=1 */ diff --git a/src/usb_endp.c b/src/usb_endp.c new file mode 100644 index 0000000..cdf675c --- /dev/null +++ b/src/usb_endp.c @@ -0,0 +1,22 @@ +/* + * Virtual COM port (for debug output only) + */ + +#include "usb_lib.h" + +#include "config.h" +#include "ch.h" +#include "gnuk.h" + +void +EP3_IN_Callback(void) +{ + if (stdout_thread) + chEvtSignalI (stdout_thread, EV_TX_READY); +} + +void +EP5_OUT_Callback(void) +{ + SetEPRxValid (ENDP3); +} diff --git a/src/vcomport.mk b/src/vcomport.mk index 4a55eb7..b545ae8 100644 --- a/src/vcomport.mk +++ b/src/vcomport.mk @@ -1,6 +1,5 @@ VCOMDIR = ../Virtual_COM_Port -ifeq ($(ENABLE_VCOMPORT),) VCOMSRC= $(VCOMDIR)/usb_istr.c $(VCOMDIR)/usb_pwr.c -else -VCOMSRC= $(VCOMDIR)/usb_endp.c $(VCOMDIR)/usb_istr.c $(VCOMDIR)/usb_pwr.c +ifneq ($(ENABLE_VCOMPORT),) +VCOMSRC += usb_endp.c endif