Compare commits

...

26 Commits

Author SHA1 Message Date
NIIBE Yutaka
93867d0c8b version 1.0.4 2013-03-15 16:21:07 +09:00
NIIBE Yutaka
a1a112d213 add changelog 2013-03-15 16:07:01 +09:00
NIIBE Yutaka
e679b4da7a more improvement on reGNUal 2013-03-15 16:06:42 +09:00
NIIBE Yutaka
095f854fa8 add changelog 2013-03-15 10:40:02 +09:00
NIIBE Yutaka
f9292f1157 fix regnual 2013-03-15 10:39:47 +09:00
NIIBE Yutaka
b619db59d2 version 1.0.3 2013-03-14 14:46:53 +09:00
NIIBE Yutaka
8870d58b69 stabilize stlinkv2.py 2013-03-14 14:02:23 +09:00
NIIBE Yutaka
4abcddef93 fix for newer GNU Toolchain 2013-03-14 13:24:35 +09:00
NIIBE Yutaka
ca46cc465c more 2013-03-12 14:49:52 +09:00
NIIBE Yutaka
3cf5ed482f more 2013-03-12 14:24:47 +09:00
NIIBE Yutaka
87d95d0864 more change for stlinkv2.py 2013-03-12 14:10:50 +09:00
NIIBE Yutaka
428adc7ac6 add changelog 2013-03-12 11:43:44 +09:00
NIIBE Yutaka
cc185eabb5 Improve initialization 2013-03-12 11:42:07 +09:00
NIIBE Yutaka
80e3cda267 change main.c for relocatable reGNUal 2013-03-09 10:18:24 +09:00
NIIBE Yutaka
ee867794e7 update regnual 2013-03-09 10:17:16 +09:00
NIIBE Yutaka
a4f7386b8a relocatable reGNUal 2013-03-09 10:16:51 +09:00
NIIBE Yutaka
7d4d6cff5e fix usb. 2013-03-07 13:07:31 +09:00
NIIBE Yutaka
b09460f0ae follow change of USB stack 2013-03-07 09:42:49 +09:00
NIIBE Yutaka
4298809ffb USB stack implementation improvement 2013-03-07 09:37:49 +09:00
NIIBE Yutaka
b297cf22b6 add changelog entry for the bug fix of usb-icc 2013-02-27 20:23:01 +09:00
NIIBE Yutaka
f84f52156c bug fix 2013-02-27 20:20:59 +09:00
NIIBE Yutaka
1564a4fbe6 Fix configure typo, type punning pointers 2013-02-25 15:46:02 +09:00
NIIBE Yutaka
16610ca5c7 Merge branch 'STABLE-BRANCH-1-0' of www.gniibe.org:git/gnuk into STABLE-BRANCH-1-0 2013-02-22 21:34:16 +09:00
NIIBE Yutaka
352f81a61f Add Quan to THANKS 2013-02-22 21:32:58 +09:00
NIIBE Yutaka
7c82839fba apply GPG_DO_DISCRETIONARY from master 2013-02-22 21:29:27 +09:00
NIIBE Yutaka
10c685be16 add Paul to THANKS (should be done at the beginning) 2013-02-20 16:56:10 +09:00
19 changed files with 496 additions and 257 deletions

136
ChangeLog
View File

@@ -1,3 +1,139 @@
2013-03-15 Niibe Yutaka <gniibe@fsij.org>
* Version 1.0.4.
* src/usb_desc.c (gnukStringSerial): Updated.
* regnual/regnual.ld (.bss): Put at RAM1. This makes reGNUal can
be loaded on the lower address.
* regnual/sys.c (entry): Don't change SP. Put alignment.
* regnual/regnual.c (usb_cb_get_descriptor): Fix adding break.
2013-03-14 Niibe Yutaka <gniibe@fsij.org>
* Version 1.0.3.
* src/usb_desc.c (gnukStringSerial): Updated.
* tool/stlinkv2.py (stlinkv2.start): Call write_debug_reg to run
the core again.
2013-03-13 Niibe Yutaka <gniibe@fsij.org>
* ChibiOS_2.0.8/os/ports/GCC/ARMCMx/cmsis/core_cm3.c (__STREXB)
(__STREXH, __STREXW): Specify R2 to avoid %0 and %2 will be same
register. This is for newer GNU binutils (>= 2.22).
2013-03-12 Niibe Yutaka <gniibe@fsij.org>
* tool/stlinkv2.py (stlinkv2.exit_from_debug_swd)
(stlinkv2.exit_from_debug_swim): New.
(stlinkv2.start): Call exit_from_debug_swd or
exit_from_debug_swim.
2013-03-09 Niibe Yutaka <gniibe@fsij.org>
* src/main.c (calculate_regnual_entry_address): New.
(main): Use calculate_regnual_entry_address for entry point.
2013-03-08 Niibe Yutaka <gniibe@fsij.org>
Relocatable reGNUal.
* regnual/regnual.ld (MEMORY): 0x1400 was the value of Gnuk 1.0.1.
Keep this value.
(.text): Include .text.entry next to the .vectors.
(.got): New.
* regnual/sys.c (entry): Now, it's at .text.entry section.
Do relocations.
Don't use absolute values which causes relocations, but
access at GOT.
* regnual/Makefile (CFLAGS): Add -fpie.
2013-03-07 Niibe Yutaka <gniibe@fsij.org>
* src/usb_stm32f103.c (handle_setup0): Fix selecting handler.
Follow the USB stack change.
* regnual/regnual.c (usb_cb_device_reset): Rename from
regnual_device_reset.
(mem): Change type to uint32_t.
(mem_info): Removed.
(fetch): Avoid pointer punning.
(usb_cb_ctrl_write_finish): Rename from regnual_ctrl_write_finish.
(usb_cb_setup): Rename from regnual_setup.
(usb_cb_get_descriptor): Rename from regnual_get_descriptor.
(usb_cb_handle_event): Rename regnual_usb_event.
(usb_cb_interface): Rename regnual_interface.
(Device_Method): Remove.
(usb_cb_get_descriptor): Not use struct Descriptor.
2013-03-06 Niibe Yutaka <gniibe@fsij.org>
USB stack implementation improvement.
* src/usb_lld.c (Device_Method, method_p): Remove.
(usb_interrupt_handler): Call usb_cb_device_reset.
(std_get_descriptor): Call usb_cb_get_descriptor.
(std_set_configuration): Call usb_cb_handle_event.
(std_get_status, std_get_interface, std_set_interface): Call
usb_cb_interface.
(handle_setup0): Call usb_cb_setup.
(handle_in0): Call usb_cb_handle_event and
usb_cb_ctrl_write_finish.
(request_handler): Remove.
(handle_setup0): Call std_* directly, not indirectly by
request_handler.
(ep_intr_handler_IN, ep_intr_handler_OUT): Remove.
(usb_handle_transfer): Call EP*_Callback directly, not indirectly
by ep_intr_handler_IN, ep_intr_handler_OUT.
* src/usb_lld.h (struct usb_device_method, Device_Method): Remove.
(usb_cb_device_reset, usb_cb_ctrl_write_finish)
(usb_cb_setup, usb_cb_get_descriptor, usb_cb_handle_event)
(usb_cb_interface): Define callbacks.
(usb_initial_feature): New.
(struct Descriptor): Move to ...
* src/usb_desc.c: ... here.
(usb_initial_feature): New.
(usb_cb_get_descriptor): Rename from gnuk_get_descriptor and move
from usb_ctrl.c.
* src/usb_ctrl.c (usb_cb_device_reset): Rename from
gnuk_device_reset.
(usb_cb_setup): Rename from gnuk_setup.
(usb_cb_ctrl_write_finish): Rename from gnuk_ctrl_write_finish.
(usb_cb_event): Rename from gnuk_usb_event.
(usb_cb_interface): Rename from gnuk_interface.
(Device_Method): Remove.
* src/main.c (main): Use usb_initial_feature.
2013-02-27 Niibe Yutaka <gniibe@fsij.org>
* src/usb-icc.c (set_sw1sw2): Arguments are C and CHUNK_LEN.
Fix reporting remaining bytes.
(icc_send_data_block_gr): Follow the arguments change of
set_sw1sw2.
2013-02-25 Niibe Yutaka <gniibe@fsij.org>
* src/configure: Correct typo in help text.
* src/gnuk.h (struct key_data_internal): Use uint32_t.
* src/openpgp-do.c (do_openpgpcard_aid): Fix calculation of VID.
(compute_key_data_checksum): Don't use type-punning pointer.
(gpg_do_write_prvkey): Use coercing to char *.
2013-02-22 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp-do.c (GPG_DO_DISCRETIONARY, cmp_discretionary): New.
(cmp_app_data): Change to factor out GPG_DO_DISCRETIONARY.
(gpg_do_table): Add GPG_DO_DISCRETIONARY.
2013-02-15 Niibe Yutaka <gniibe@fsij.org> 2013-02-15 Niibe Yutaka <gniibe@fsij.org>
* Version 1.0.2. * Version 1.0.2.

View File

@@ -731,7 +731,7 @@ uint32_t __LDREXW(uint32_t *addr)
*/ */
uint32_t __STREXB(uint8_t value, uint8_t *addr) uint32_t __STREXB(uint8_t value, uint8_t *addr)
{ {
uint32_t result=0; register uint32_t result asm ("r2");
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result); return(result);
@@ -748,7 +748,7 @@ uint32_t __STREXB(uint8_t value, uint8_t *addr)
*/ */
uint32_t __STREXH(uint16_t value, uint16_t *addr) uint32_t __STREXH(uint16_t value, uint16_t *addr)
{ {
uint32_t result=0; register uint32_t result asm ("r2");
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result); return(result);
@@ -765,7 +765,7 @@ uint32_t __STREXH(uint16_t value, uint16_t *addr)
*/ */
uint32_t __STREXW(uint32_t value, uint32_t *addr) uint32_t __STREXW(uint32_t value, uint32_t *addr)
{ {
uint32_t result=0; register uint32_t result asm ("r2");
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result); return(result);

31
NEWS
View File

@@ -1,5 +1,32 @@
Gnuk NEWS - User visible changes Gnuk NEWS - User visible changes
* Major changes in Gnuk 1.0.4
Released 2013-03-15, by NIIBE Yutaka
** Relocatable reGNUal, really
In 1.0.3, reGNUal was not fully relocatable. It worked loaded on higher
address, but didn't work for lower address. This was fixed.
* Major changes in Gnuk 1.0.3
Released 2013-03-14, by NIIBE Yutaka
** Relocatable reGNUal
The upgrade helper, reGNUal, is now relocatable (other than the first
vector table). It runs well when loaded at different address. This
makes the upgrade procedure more stable.
** Compilation by newer GNU Toolchain
Now, Gnuk can be compiled with newer GNU Toolchain, specifically GCC
4.7.x and GNU Binutils 2.22. Old versions of Gnuk had problem for
ChibiOS_2.0.8/os/ports/GCC/ARMCMx/cmsis/core_cm3.c, which was fixed.
** Data object 0x0073
Data object 0x0073 is now available.
* Major changes in Gnuk 1.0.2 * Major changes in Gnuk 1.0.2
Released 2013-02-15, by NIIBE Yutaka Released 2013-02-15, by NIIBE Yutaka
@@ -36,6 +63,10 @@ Now, VERIFY command accepts empty data and returns remaining trial
counts, or 0x9000 (OK) when it's already authenticated. This is counts, or 0x9000 (OK) when it's already authenticated. This is
useful for application to synchronize card's authentication status. useful for application to synchronize card's authentication status.
** Extended Capabilities
Since Gnuk supports GET CHALLENGE command, the flag for GET CHALLENGE
in extended capabilities are now on.
* Major changes in Gnuk 1.0.1 * Major changes in Gnuk 1.0.1

23
README
View File

@@ -1,7 +1,7 @@
Gnuk - An Implementation of USB Cryptographic Token for GnuPG Gnuk - An Implementation of USB Cryptographic Token for GnuPG
Version 1.0.2 Version 1.0.4
2013-02-15 2013-03-15
Niibe Yutaka Niibe Yutaka
Free Software Initiative of Japan Free Software Initiative of Japan
@@ -108,14 +108,19 @@ Ab: That's because gnome-keyring-daemon interferes GnuPG. Type:
"GPG Password Agent" and "SSH Key Agent". "GPG Password Agent" and "SSH Key Agent".
Qc: Do you know a good SWD debugger to connect FST-01 or something? Qc: Do you know a good SWD debugger to connect FST-01 or something?
Ac: ST-Link/V2 is cheap one. We have a tool/stlinkv2.py as flash ROM
writer program. Ac: ST-Link/V2 is cheap one and works, although it's not very good
(for example, we have not yet been able to use OpenOCD to write
option bytes of STM32F103). We have a tool/stlinkv2.py as a flash
ROM writer program. Note that some "Discovery Kit" from ST has
the feature of ST-Link/V2, but it is not as stable as the real
one.
Release notes Release notes
============= =============
This is a second minor release in version 1.0 series of Gnuk. This is a fourth minor release in version 1.0 series of Gnuk.
While it is daily use for a year and a half, some newly introduced While it is daily use for a year and a half, some newly introduced
features (including key generation and firmware upgrade) should be features (including key generation and firmware upgrade) should be
@@ -174,7 +179,7 @@ disable read from flash. For real use, please consider killing DfuSe
and enabling read protection using JTAG debugger. and enabling read protection using JTAG debugger.
I think that it could run on Olimex STM32-P103, or other boards with I think that it could run on Olimex STM32-P103, or other boards with
STM32F103. Besides, we are porting it to STM32 Primer 2. STM32F103. Besides, we did an experiment with STM32 Primer 2.
For PIN-pad support, I connect a consumer IR receive module to STBee For PIN-pad support, I connect a consumer IR receive module to STBee
Mini and STM8S Discovery Kit, and use controller for TV. PIN Mini and STM8S Discovery Kit, and use controller for TV. PIN
@@ -338,8 +343,7 @@ Recently, there is "gcc-arm-embedded" project. See:
https://launchpad.net/gcc-arm-embedded/ https://launchpad.net/gcc-arm-embedded/
It is based on GCC 4.6. For version 4.6-2012-q2-update, you'd It is based on GCC 4.6 or 4.7.
need "-O3 -Os" instead of "-O2" and it will be slightly better.
Change directory to `src': Change directory to `src':
@@ -657,7 +661,8 @@ linux/Documentation/usb/usbmon.txt
Firmware update Firmware update
=============== ===============
See doc/note/firmware-update. See doc/note/firmware-update. Note that this is an experimental
feature.
Git Repositories Git Repositories

4
THANKS
View File

@@ -1,3 +1,5 @@
-*- coding: utf-8 -*-
We would like to express our gratitudes to Werner Koch for GnuPG, and We would like to express our gratitudes to Werner Koch for GnuPG, and
Giovanni Di Sirio for ChibiOS/RT. Giovanni Di Sirio for ChibiOS/RT.
@@ -14,5 +16,7 @@ Ludovic Rousseau ludovic.rousseau@free.fr
Luis Felipe R. Murillo luisfelipe@ucla.edu Luis Felipe R. Murillo luisfelipe@ucla.edu
MATSUU Takuto matsuu@gentoo.org MATSUU Takuto matsuu@gentoo.org
NAGAMI Takeshi nagami-takeshi@aist.go.jp NAGAMI Takeshi nagami-takeshi@aist.go.jp
Nguyễn Hồng Quân quannguyen@mbm.vn
Paul Bakker polarssl_maintainer@polarssl.org
Shane Coughlan scoughlan@openinventionnetwork.com Shane Coughlan scoughlan@openinventionnetwork.com
Werner Koch wk@gnupg.org Werner Koch wk@gnupg.org

View File

@@ -22,6 +22,7 @@ MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
DEFS = -DFREE_STANDING DEFS = -DFREE_STANDING
CFLAGS = -O2 -g CFLAGS = -O2 -g
CFLAGS += -Wa,-alms=$(notdir $(<:.c=.lst)) -fpie
CFLAGS += $(CWARN) -I . -I ../src -fno-common $(MCFLAGS) $(TOPT) $(DEFS) CFLAGS += $(CWARN) -I . -I ../src -fno-common $(MCFLAGS) $(TOPT) $(DEFS)
LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT) LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT)

View File

@@ -1,7 +1,7 @@
/* /*
* regnual.c -- Firmware installation for STM32F103 Flash ROM * regnual.c -- Firmware installation for STM32F103 Flash ROM
* *
* Copyright (C) 2012 Free Software Initiative of Japan * Copyright (C) 2012, 2013 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Gnuk, a GnuPG USB Token implementation. * This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -99,33 +99,15 @@ static const uint8_t regnual_string_serial[] = {
'0', 0, '.', 0, '0', 0, '0', 0, '.', 0, '0', 0,
}; };
const struct Descriptor device_desc = {
regnual_device_desc,
sizeof (regnual_device_desc)
};
const struct Descriptor config_desc = { void
regnual_config_desc, usb_cb_device_reset (void)
sizeof (regnual_config_desc)
};
const struct Descriptor string_descs[] = {
{regnual_string_lang_id, sizeof (regnual_string_lang_id)},
{gnukStringVendor, sizeof (gnukStringVendor)},
{gnukStringProduct, sizeof (gnukStringProduct)},
{regnual_string_serial, sizeof (regnual_string_serial)},
};
#define NUM_STRING_DESC (sizeof (string_descs)/sizeof (struct Descriptor))
static void
regnual_device_reset (void)
{ {
/* Set DEVICE as not configured */ /* Set DEVICE as not configured */
usb_lld_set_configuration (0); usb_lld_set_configuration (0);
/* Current Feature initialization */ /* Current Feature initialization */
usb_lld_set_feature (config_desc.Descriptor[7]); usb_lld_set_feature (regnual_config_desc[7]);
usb_lld_reset (); usb_lld_reset ();
@@ -141,11 +123,9 @@ regnual_device_reset (void)
#define USB_REGNUAL_PROTECT 4 #define USB_REGNUAL_PROTECT 4
#define USB_REGNUAL_FINISH 5 #define USB_REGNUAL_FINISH 5
static uint8_t mem[256]; static uint32_t mem[256/4];
static uint32_t result; static uint32_t result;
static const uint8_t *const mem_info[] = { &_flash_start, &_flash_end, };
static uint32_t rbit (uint32_t v) static uint32_t rbit (uint32_t v)
{ {
@@ -159,7 +139,7 @@ static uint32_t fetch (int i)
{ {
uint32_t v; uint32_t v;
v = *(uint32_t *)(&mem[i*4]); v = mem[i];
return rbit (v); return rbit (v);
} }
@@ -186,9 +166,8 @@ static uint32_t calc_crc32 (void)
} }
static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no, void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t value, uint16_t index, uint16_t index, uint16_t len)
uint16_t len)
{ {
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
@@ -200,7 +179,7 @@ static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
{ {
uint32_t dst_addr = (0x08000000 + value * 0x100); uint32_t dst_addr = (0x08000000 + value * 0x100);
result = flash_write (dst_addr, mem, 256); result = flash_write (dst_addr, (const uint8_t *)mem, 256);
} }
else if (req_no == USB_REGNUAL_PROTECT && len == 0 else if (req_no == USB_REGNUAL_PROTECT && len == 0
&& value == 0 && index == 0) && value == 0 && index == 0)
@@ -211,9 +190,9 @@ static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
} }
} }
static int int
regnual_setup (uint8_t req, uint8_t req_no, usb_cb_setup (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len) uint16_t value, uint16_t index, uint16_t len)
{ {
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
@@ -223,6 +202,10 @@ regnual_setup (uint8_t req, uint8_t req_no,
{ {
if (req_no == USB_REGNUAL_MEMINFO) if (req_no == USB_REGNUAL_MEMINFO)
{ {
static const uint8_t *mem_info[2];
mem_info[0] = &_flash_start;
mem_info[1] = &_flash_end;
usb_lld_set_data_to_send (mem_info, sizeof (mem_info)); usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
return USB_SUCCESS; return USB_SUCCESS;
} }
@@ -240,7 +223,8 @@ regnual_setup (uint8_t req, uint8_t req_no,
return USB_UNSUPPORT; return USB_UNSUPPORT;
if (index + len < 256) if (index + len < 256)
memset (mem + index + len, 0xff, 256 - (index + len)); memset ((uint8_t *)mem + index + len, 0xff,
256 - (index + len));
usb_lld_set_data_to_recv (mem + index, len); usb_lld_set_data_to_recv (mem + index, len);
return USB_SUCCESS; return USB_SUCCESS;
@@ -264,38 +248,58 @@ regnual_setup (uint8_t req, uint8_t req_no,
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static int int
regnual_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value) usb_cb_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
{ {
(void)index; (void)index;
if (desc_type == DEVICE_DESCRIPTOR) if (desc_type == DEVICE_DESCRIPTOR)
{ {
usb_lld_set_data_to_send (device_desc.Descriptor, usb_lld_set_data_to_send (regnual_device_desc,
device_desc.Descriptor_Size); sizeof (regnual_device_desc));
return USB_SUCCESS; return USB_SUCCESS;
} }
else if (desc_type == CONFIG_DESCRIPTOR) else if (desc_type == CONFIG_DESCRIPTOR)
{ {
usb_lld_set_data_to_send (config_desc.Descriptor, usb_lld_set_data_to_send (regnual_config_desc,
config_desc.Descriptor_Size); sizeof (regnual_config_desc));
return USB_SUCCESS; return USB_SUCCESS;
} }
else if (desc_type == STRING_DESCRIPTOR) else if (desc_type == STRING_DESCRIPTOR)
{ {
uint8_t desc_index = value & 0xff; uint8_t desc_index = value & 0xff;
const uint8_t *str;
int size;
if (desc_index < NUM_STRING_DESC) switch (desc_index)
{ {
usb_lld_set_data_to_send (string_descs[desc_index].Descriptor, case 0:
string_descs[desc_index].Descriptor_Size); str = regnual_string_lang_id;
return USB_SUCCESS; size = sizeof (regnual_string_lang_id);
break;
case 1:
str = gnukStringVendor;
size = sizeof (gnukStringVendor);
break;
case 2:
str = gnukStringProduct;
size = sizeof (gnukStringProduct);
break;
case 3:
str = regnual_string_serial;
size = sizeof (regnual_string_serial);
break;
default:
return USB_UNSUPPORT;
} }
usb_lld_set_data_to_send (str, size);
return USB_SUCCESS;
} }
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static int regnual_usb_event (uint8_t event_type, uint16_t value) int usb_cb_handle_event (uint8_t event_type, uint16_t value)
{ {
(void)value; (void)value;
@@ -311,20 +315,12 @@ static int regnual_usb_event (uint8_t event_type, uint16_t value)
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static int regnual_interface (uint8_t cmd, uint16_t interface, uint16_t alt) int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
{ {
(void)cmd; (void)interface; (void)alt; (void)cmd; (void)interface; (void)alt;
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
const struct usb_device_method Device_Method = {
regnual_device_reset,
regnual_ctrl_write_finish,
regnual_setup,
regnual_get_descriptor,
regnual_usb_event,
regnual_interface,
};
static void wait (int count) static void wait (int count)
{ {

View File

@@ -23,22 +23,11 @@ SECTIONS
{ {
. = 0; . = 0;
.bss :
{
_bss_start = .;
*(.bss)
. = ALIGN(4);
*(.bss.*)
. = ALIGN(4);
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > ram0
.text : ALIGN(16) SUBALIGN(16) .text : ALIGN(16) SUBALIGN(16)
{ {
_text = .; _text = .;
KEEP(*(.vectors)) KEEP(*(.vectors))
*(.text.entry)
*(.text) *(.text)
*(.text.*) *(.text.*)
*(.rodata) *(.rodata)
@@ -48,6 +37,12 @@ SECTIONS
*(.gcc*) *(.gcc*)
} > ram1 } > ram1
.got :
{
*(.got)
*(.got.*)
} > ram1
.ctors : .ctors :
{ {
PROVIDE(_ctors_start_ = .); PROVIDE(_ctors_start_ = .);
@@ -90,6 +85,18 @@ SECTIONS
_edata = .; _edata = .;
} > ram1 } > ram1
.bss :
{
_bss_start = .;
*(.bss)
. = ALIGN(4);
*(.bss.*)
. = ALIGN(4);
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > ram1
PROVIDE(end = .); PROVIDE(end = .);
_end = .; _end = .;
} }

View File

@@ -9,17 +9,38 @@ static void none (void)
{ {
} }
/* Note: it is not reset */ /*
static __attribute__ ((naked)) * Note: the address of this routine 'entry' will be in the vectors as
* RESET, but this will be called from application. It's not RESET
* state, then.
*
* This routine doesn't change PSP and MSP. Application should
* prepare those stack pointers.
*/
static __attribute__ ((naked,section(".text.entry")))
void entry (void) void entry (void)
{ {
asm volatile ("ldr r0, =__ram_end__\n\t" asm volatile ("mov r0, pc\n\t"
"ldr r1, =__main_stack_size__\n\t" "bic r0, r0, #255\n\t" /* R0 := vector_table address */
"sub r0, r0, r1\n\t" "mov r1, #0x90\n\t" /* R1 := numbers of entries * 4 */
"mov sp, r0\n\t" "ldr r3, .L01\n" /* R3 := -0x20001400 fixed addr */
"0:\n\t"
"ldr r2, [r0, r1]\n\t"
"add r2, r0\n\t" /* Relocate: R0 - 0x20001400 */
"add r2, r3\n\t"
"str r2, [r0, r1]\n\t"
"subs r1, r1, #4\n\t"
"bne 0b\n\t"
/* Relocation done. */
"ldr r3, .L00\n"
".LPIC00:\n\t"
"add r3, pc\n\t" /* R3 := @_GLOBAL_OFFSET_TABLE_ */
/* Clear BSS. */
"mov r0, #0\n\t" "mov r0, #0\n\t"
"ldr r1, =_bss_start\n\t" "ldr r4, .L00+4\n\t"
"ldr r2, =_bss_end\n" "ldr r1, [r3, r4]\n\t"
"ldr r4, .L00+8\n\t"
"ldr r2, [r3, r4]\n"
"0:\n\t" "0:\n\t"
"str r0, [r1], #4\n\t" "str r0, [r1], #4\n\t"
"cmp r2, r1\n\t" "cmp r2, r1\n\t"
@@ -29,7 +50,14 @@ void entry (void)
"mov r1, r0\n\t" "mov r1, r0\n\t"
"bl main\n" "bl main\n"
"1:\n\t" "1:\n\t"
"b 1b\n" "b 1b\n\t"
".align 2\n"
".L01:\n\t"
".word -0x20001400\n"
".L00:\n\t"
".word _GLOBAL_OFFSET_TABLE_-(.LPIC00+4)\n\t"
".word _bss_start(GOT)\n\t"
".word _bss_end(GOT)"
: /* no output */ : /* no input */ : "memory"); : /* no output */ : /* no input */ : "memory");
} }

2
src/configure vendored
View File

@@ -84,7 +84,7 @@ Configuration:
-h, --help display this help and exit [no] -h, --help display this help and exit [no]
--vidpid=VID:PID specify vendor/product ID [<NONE>] --vidpid=VID:PID specify vendor/product ID [<NONE>]
--target=TARGET specify target [OLIMEX_STM32_H103] --target=TARGET specify target [OLIMEX_STM32_H103]
supported targes are: supported targets are:
OLIMEX_STM32_H103 OLIMEX_STM32_H103
STM32_PRIMER2 STM32_PRIMER2
CQ_STARM CQ_STARM

View File

@@ -171,8 +171,8 @@ struct key_data {
}; };
struct key_data_internal { struct key_data_internal {
uint8_t data[KEY_CONTENT_LEN]; /* p and q */ uint32_t data[KEY_CONTENT_LEN/4]; /* p and q */
uint8_t checksum[DATA_ENCRYPTION_KEY_SIZE]; uint32_t checksum[DATA_ENCRYPTION_KEY_SIZE/4];
}; };
struct prvkey_data { struct prvkey_data {

View File

@@ -1,7 +1,7 @@
/* /*
* main.c - main routine of Gnuk * main.c - main routine of Gnuk
* *
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan * Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Gnuk, a GnuPG USB Token implementation. * This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -319,6 +319,23 @@ led_blink (int spec)
chEvtSignal (main_thread, spec); chEvtSignal (main_thread, spec);
} }
/*
* In Gnuk 1.0.[12], reGNUal was not relocatable.
* Now, it's relocatable, but we need to calculate its entry address
* based on it's pre-defined address.
*/
#define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
static uint32_t
calculate_regnual_entry_address (const uint8_t *addr)
{
const uint8_t *p = addr + 4;
uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
v -= REGNUAL_START_ADDRESS_COMPATIBLE;
v += (uint32_t)addr;
return v;
}
/* /*
* Entry point. * Entry point.
@@ -330,6 +347,7 @@ int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
unsigned int count = 0; unsigned int count = 0;
uint32_t entry;
(void)argc; (void)argc;
(void)argv; (void)argv;
@@ -338,7 +356,7 @@ main (int argc, char *argv[])
flash_unlock (); flash_unlock ();
device_initialize_once (); device_initialize_once ();
usb_lld_init (Config_Descriptor.Descriptor[7]); usb_lld_init (usb_initial_feature);
random_init (); random_init ();
while (1) while (1)
@@ -429,6 +447,7 @@ main (int argc, char *argv[])
port_disable (); port_disable ();
/* Set vector */ /* Set vector */
SCB->VTOR = (uint32_t)&_regnual_start; SCB->VTOR = (uint32_t)&_regnual_start;
entry = calculate_regnual_entry_address (&_regnual_start);
#ifdef DFU_SUPPORT #ifdef DFU_SUPPORT
#define FLASH_SYS_START_ADDR 0x08000000 #define FLASH_SYS_START_ADDR 0x08000000
#define FLASH_SYS_END_ADDR (0x08000000+0x1000) #define FLASH_SYS_END_ADDR (0x08000000+0x1000)
@@ -447,12 +466,12 @@ main (int argc, char *argv[])
flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000); flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
/* Leave Gnuk to exec reGNUal */ /* Leave Gnuk to exec reGNUal */
(*func) (*((void (**)(void))(&_regnual_start+4))); (*func) ((void (*)(void))entry);
for (;;); for (;;);
} }
#else #else
/* Leave Gnuk to exec reGNUal */ /* Leave Gnuk to exec reGNUal */
flash_erase_all_and_exec (*((void (**)(void))(&_regnual_start+4))); flash_erase_all_and_exec ((void (*)(void))entry);
#endif #endif
/* Never reached */ /* Never reached */

View File

@@ -241,7 +241,7 @@ static const struct do_table_entry *get_do_entry (uint16_t tag);
#define GPG_DO_LOGIN_DATA 0x005e #define GPG_DO_LOGIN_DATA 0x005e
#define GPG_DO_CH_DATA 0x0065 #define GPG_DO_CH_DATA 0x0065
#define GPG_DO_APP_DATA 0x006e #define GPG_DO_APP_DATA 0x006e
/* XXX: 0x0073 ??? */ #define GPG_DO_DISCRETIONARY 0x0073
#define GPG_DO_SS_TEMP 0x007a #define GPG_DO_SS_TEMP 0x007a
#define GPG_DO_DS_COUNT 0x0093 #define GPG_DO_DS_COUNT 0x0093
#define GPG_DO_EXTCAP 0x00c0 #define GPG_DO_EXTCAP 0x00c0
@@ -447,7 +447,7 @@ const uint8_t openpgpcard_aid[] = {
static int static int
do_openpgpcard_aid (uint16_t tag, int with_tag) do_openpgpcard_aid (uint16_t tag, int with_tag)
{ {
uint16_t vid = *((const volatile uint16_t *)&openpgpcard_aid[8]); uint16_t vid = (openpgpcard_aid[8] << 8) | openpgpcard_aid[9];
if (with_tag) if (with_tag)
{ {
@@ -664,7 +664,7 @@ compute_key_data_checksum (struct key_data_internal *kdi, int check_or_calc)
uint32_t d[4] = { 0, 0, 0, 0 }; uint32_t d[4] = { 0, 0, 0, 0 };
for (i = 0; i < KEY_CONTENT_LEN / sizeof (uint32_t); i++) for (i = 0; i < KEY_CONTENT_LEN / sizeof (uint32_t); i++)
d[i&3] ^= *(uint32_t *)(&kdi->data[i*4]); d[i&3] ^= kdi->data[i];
if (check_or_calc == 0) /* store */ if (check_or_calc == 0) /* store */
{ {
@@ -790,7 +790,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
encrypt (dek, iv, (uint8_t *)&kdi, sizeof (struct key_data_internal)); encrypt (dek, iv, (uint8_t *)&kdi, sizeof (struct key_data_internal));
r = flash_key_write (key_addr, kdi.data, modulus); r = flash_key_write (key_addr, (const uint8_t *)kdi.data, modulus);
if (modulus_allocated_here) if (modulus_allocated_here)
modulus_free (modulus); modulus_free (modulus);
@@ -989,10 +989,14 @@ static const uint16_t cmp_ch_data[] = {
}; };
static const uint16_t cmp_app_data[] = { static const uint16_t cmp_app_data[] = {
10, 3,
GPG_DO_AID, GPG_DO_AID,
GPG_DO_HIST_BYTES, GPG_DO_HIST_BYTES,
/* XXX Discretionary data objects 0x0073 ??? */ GPG_DO_DISCRETIONARY,
};
static const uint16_t cmp_discretionary[] = {
8,
GPG_DO_EXTCAP, GPG_DO_EXTCAP,
GPG_DO_ALG_SIG, GPG_DO_ALG_DEC, GPG_DO_ALG_AUT, GPG_DO_ALG_SIG, GPG_DO_ALG_DEC, GPG_DO_ALG_AUT,
GPG_DO_PW_STATUS, GPG_DO_PW_STATUS,
@@ -1038,6 +1042,7 @@ gpg_do_table[] = {
/* Compound data: Read access only */ /* Compound data: Read access only */
{ GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data }, { GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data },
{ GPG_DO_APP_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_app_data }, { GPG_DO_APP_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_app_data },
{ GPG_DO_DISCRETIONARY, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_discretionary },
{ GPG_DO_SS_TEMP, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ss_temp }, { GPG_DO_SS_TEMP, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ss_temp },
/* Simple data: write access only */ /* Simple data: write access only */
{ GPG_DO_RESETTING_CODE, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED, { GPG_DO_RESETTING_CODE, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED,

View File

@@ -321,10 +321,8 @@ static void no_buf (struct ep_in *epi, size_t len)
epi->buf_len = 0; epi->buf_len = 0;
} }
static void set_sw1sw2 (struct ep_in *epi) static void set_sw1sw2 (struct ccid *c, size_t chunk_len)
{ {
struct ccid *c = (struct ccid *)epi->priv;
if (c->a->expected_res_size >= c->len) if (c->a->expected_res_size >= c->len)
{ {
c->sw1sw2[0] = 0x90; c->sw1sw2[0] = 0x90;
@@ -333,10 +331,10 @@ static void set_sw1sw2 (struct ep_in *epi)
else else
{ {
c->sw1sw2[0] = 0x61; c->sw1sw2[0] = 0x61;
if (c->len >= 256) if (c->len - chunk_len >= 256)
c->sw1sw2[1] = 0; c->sw1sw2[1] = 0;
else else
c->sw1sw2[1] = (uint8_t)c->len; c->sw1sw2[1] = (uint8_t)(c->len - chunk_len);
} }
} }
@@ -968,7 +966,7 @@ icc_send_data_block_gr (struct ccid *c, size_t chunk_len)
usb_lld_txcpy (p, c->epi->ep_num, 0, ICC_MSG_HEADER_SIZE); usb_lld_txcpy (p, c->epi->ep_num, 0, ICC_MSG_HEADER_SIZE);
set_sw1sw2 (c->epi); set_sw1sw2 (c, chunk_len);
if (chunk_len <= USB_LL_BUF_SIZE - ICC_MSG_HEADER_SIZE) if (chunk_len <= USB_LL_BUF_SIZE - ICC_MSG_HEADER_SIZE)
{ {

View File

@@ -1,7 +1,7 @@
/* /*
* usb_ctrl.c - USB control pipe device specific code for Gnuk * usb_ctrl.c - USB control pipe device specific code for Gnuk
* *
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan * Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Gnuk, a GnuPG USB Token implementation. * This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -147,8 +147,8 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
#endif #endif
} }
static void void
gnuk_device_reset (void) usb_cb_device_reset (void)
{ {
int i; int i;
@@ -156,7 +156,7 @@ gnuk_device_reset (void)
usb_lld_set_configuration (0); usb_lld_set_configuration (0);
/* Current Feature initialization */ /* Current Feature initialization */
usb_lld_set_feature (Config_Descriptor.Descriptor[7]); usb_lld_set_feature (usb_initial_feature);
usb_lld_reset (); usb_lld_reset ();
@@ -214,9 +214,9 @@ static int download_check_crc32 (const uint32_t *end_p)
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static int int
gnuk_setup (uint8_t req, uint8_t req_no, usb_cb_setup (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len) uint16_t value, uint16_t index, uint16_t len)
{ {
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
@@ -310,9 +310,8 @@ gnuk_setup (uint8_t req, uint8_t req_no,
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static void gnuk_ctrl_write_finish (uint8_t req, uint8_t req_no, void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t value, uint16_t index, uint16_t index, uint16_t len)
uint16_t len)
{ {
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
@@ -329,38 +328,7 @@ static void gnuk_ctrl_write_finish (uint8_t req, uint8_t req_no,
} }
static int int usb_cb_handle_event (uint8_t event_type, uint16_t value)
gnuk_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
{
(void)index;
if (desc_type == DEVICE_DESCRIPTOR)
{
usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
Device_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == CONFIG_DESCRIPTOR)
{
usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
Config_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == STRING_DESCRIPTOR)
{
uint8_t desc_index = value & 0xff;
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
String_Descriptors[desc_index].Descriptor_Size);
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}
static int gnuk_usb_event (uint8_t event_type, uint16_t value)
{ {
int i; int i;
uint8_t current_conf; uint8_t current_conf;
@@ -401,7 +369,7 @@ static int gnuk_usb_event (uint8_t event_type, uint16_t value)
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static int gnuk_interface (uint8_t cmd, uint16_t interface, uint16_t alt) int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
{ {
static uint8_t zero = 0; static uint8_t zero = 0;
@@ -429,18 +397,6 @@ static int gnuk_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
} }
} }
/*
* Interface to USB core
*/
const struct usb_device_method Device_Method = {
gnuk_device_reset,
gnuk_ctrl_write_finish,
gnuk_setup,
gnuk_get_descriptor,
gnuk_usb_event,
gnuk_interface,
};
CH_IRQ_HANDLER (Vector90) CH_IRQ_HANDLER (Vector90)
{ {

View File

@@ -9,6 +9,13 @@
#include "usb_conf.h" #include "usb_conf.h"
#include "usb-cdc.h" #include "usb-cdc.h"
struct Descriptor
{
const uint8_t *Descriptor;
uint16_t Descriptor_Size;
};
#define USB_ICC_INTERFACE_CLASS 0x0B #define USB_ICC_INTERFACE_CLASS 0x0B
#define USB_ICC_INTERFACE_SUBCLASS 0x00 #define USB_ICC_INTERFACE_SUBCLASS 0x00
#define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00 #define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00
@@ -53,6 +60,15 @@ static const uint8_t gnukDeviceDescriptor[] = {
#define NUM_INTERFACES (ICC_NUM_INTERFACES+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES) #define NUM_INTERFACES (ICC_NUM_INTERFACES+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES)
#if defined(USB_SELF_POWERED)
#define USB_INITIAL_FEATURE 0xC0 /* bmAttributes: self powered */
#else
#define USB_INITIAL_FEATURE 0x80 /* bmAttributes: bus powered */
#endif
const uint8_t usb_initial_feature = USB_INITIAL_FEATURE;
/* Configuation Descriptor */ /* Configuation Descriptor */
static const uint8_t gnukConfigDescriptor[] = { static const uint8_t gnukConfigDescriptor[] = {
9, /* bLength: Configuation Descriptor size */ 9, /* bLength: Configuation Descriptor size */
@@ -61,11 +77,7 @@ static const uint8_t gnukConfigDescriptor[] = {
NUM_INTERFACES, /* bNumInterfaces: */ NUM_INTERFACES, /* bNumInterfaces: */
0x01, /* bConfigurationValue: Configuration value */ 0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if defined(USB_SELF_POWERED) USB_INITIAL_FEATURE, /* bmAttributes*/
0xC0, /* bmAttributes: self powered */
#else
0x80, /* bmAttributes: bus powered */
#endif
50, /* MaxPower 100 mA */ 50, /* MaxPower 100 mA */
/* Interface Descriptor */ /* Interface Descriptor */
@@ -260,25 +272,25 @@ static const uint8_t gnukStringLangID[] = {
const uint8_t gnukStringSerial[] = { const uint8_t gnukStringSerial[] = {
19*2+2, /* bLength */ 19*2+2, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
/* FSIJ-1.0.1- */ /* FSIJ-1.0.3- */
'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0, 'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0,
'1', 0, '.', 0, '0', 0, '.', 0, '2', 0, /* Version number of Gnuk */ '1', 0, '.', 0, '0', 0, '.', 0, '4', 0, /* Version number of Gnuk */
'-', 0, '-', 0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
}; };
const struct Descriptor Device_Descriptor = { static const struct Descriptor Device_Descriptor = {
gnukDeviceDescriptor, gnukDeviceDescriptor,
sizeof (gnukDeviceDescriptor) sizeof (gnukDeviceDescriptor)
}; };
const struct Descriptor Config_Descriptor = { static const struct Descriptor Config_Descriptor = {
gnukConfigDescriptor, gnukConfigDescriptor,
sizeof (gnukConfigDescriptor) sizeof (gnukConfigDescriptor)
}; };
const struct Descriptor String_Descriptors[NUM_STRING_DESC] = { static const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
{gnukStringLangID, sizeof (gnukStringLangID)}, {gnukStringLangID, sizeof (gnukStringLangID)},
{gnukStringVendor, sizeof (gnukStringVendor)}, {gnukStringVendor, sizeof (gnukStringVendor)},
{gnukStringProduct, sizeof (gnukStringProduct)}, {gnukStringProduct, sizeof (gnukStringProduct)},
@@ -287,3 +299,34 @@ const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
{gnuk_config_options, sizeof (gnuk_config_options)}, {gnuk_config_options, sizeof (gnuk_config_options)},
{sys_version, sizeof (sys_version)}, {sys_version, sizeof (sys_version)},
}; };
int
usb_cb_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
{
(void)index;
if (desc_type == DEVICE_DESCRIPTOR)
{
usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
Device_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == CONFIG_DESCRIPTOR)
{
usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
Config_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == STRING_DESCRIPTOR)
{
uint8_t desc_index = value & 0xff;
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
String_Descriptors[desc_index].Descriptor_Size);
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}

View File

@@ -74,12 +74,10 @@ struct DEVICE_INFO
static struct CONTROL_INFO control_info; static struct CONTROL_INFO control_info;
static struct DEVICE_INFO device_info; static struct DEVICE_INFO device_info;
static struct DATA_INFO data_info; static struct DATA_INFO data_info;
extern const struct usb_device_method Device_Method;
static struct CONTROL_INFO *const ctrl_p = &control_info; static struct CONTROL_INFO *const ctrl_p = &control_info;
static struct DEVICE_INFO *const dev_p = &device_info; static struct DEVICE_INFO *const dev_p = &device_info;
static struct DATA_INFO *const data_p = &data_info; static struct DATA_INFO *const data_p = &data_info;
static const struct usb_device_method *const method_p = &Device_Method;
#define REG_BASE (0x40005C00UL) /* USB_IP Peripheral Registers base address */ #define REG_BASE (0x40005C00UL) /* USB_IP Peripheral Registers base address */
#define PMA_ADDR (0x40006000UL) /* USB_IP Packet Memory Area base address */ #define PMA_ADDR (0x40006000UL) /* USB_IP Packet Memory Area base address */
@@ -399,7 +397,7 @@ usb_interrupt_handler (void)
if (istr_value & ISTR_RESET) if (istr_value & ISTR_RESET)
{ {
st103_set_istr (CLR_RESET); st103_set_istr (CLR_RESET);
method_p->reset (); usb_cb_device_reset ();
} }
if (istr_value & ISTR_DOVR) if (istr_value & ISTR_DOVR)
@@ -529,7 +527,7 @@ static int std_get_status (uint8_t req,
if (dev_p->current_configuration == 0) if (dev_p->current_configuration == 0)
return USB_UNSUPPORT; return USB_UNSUPPORT;
r = (*method_p->interface) (USB_QUERY_INTERFACE, index, 0); r = usb_cb_interface (USB_QUERY_INTERFACE, index, 0);
if (r != USB_SUCCESS) if (r != USB_SUCCESS)
return USB_UNSUPPORT; return USB_UNSUPPORT;
@@ -700,7 +698,7 @@ static int std_get_descriptor (uint8_t req, uint16_t value,
(void)length; (void)length;
if (rcp == DEVICE_RECIPIENT) if (rcp == DEVICE_RECIPIENT)
return (*method_p->get_descriptor) ((value >> 8), index, value); return usb_cb_get_descriptor ((value >> 8), index, value);
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
@@ -736,7 +734,7 @@ static int std_set_configuration (uint8_t req, uint16_t value,
{ {
int r; int r;
r = (*method_p->event) (USB_EVENT_CONFIG, value); r = usb_cb_handle_event (USB_EVENT_CONFIG, value);
if (r == USB_SUCCESS) if (r == USB_SUCCESS)
return USB_SUCCESS; return USB_SUCCESS;
} }
@@ -760,7 +758,7 @@ static int std_get_interface (uint8_t req, uint16_t value,
if (dev_p->current_configuration == 0) if (dev_p->current_configuration == 0)
return USB_UNSUPPORT; return USB_UNSUPPORT;
return (*method_p->interface) (USB_GET_INTERFACE, index, 0); return usb_cb_interface (USB_GET_INTERFACE, index, 0);
} }
return USB_UNSUPPORT; return USB_UNSUPPORT;
@@ -784,7 +782,7 @@ static int std_set_interface (uint8_t req, uint16_t value,
if (dev_p->current_configuration != 0) if (dev_p->current_configuration != 0)
return USB_UNSUPPORT; return USB_UNSUPPORT;
r = (*method_p->interface) (USB_SET_INTERFACE, index, value); r = usb_cb_interface (USB_SET_INTERFACE, index, value);
if (r == USB_SUCCESS) if (r == USB_SUCCESS)
return USB_SUCCESS; return USB_SUCCESS;
} }
@@ -792,21 +790,6 @@ static int std_set_interface (uint8_t req, uint16_t value,
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static const HANDLER std_request_handler[TOTAL_REQUEST] = {
std_get_status,
std_clear_feature,
std_none,
std_set_feature,
std_none,
std_set_address,
std_get_descriptor,
std_none, /* set_descriptor is not supported */
std_get_configuration,
std_set_configuration,
std_get_interface,
std_set_interface,
std_none, /* sync_frame is not supported (for now) */
};
static void handle_setup0 (void) static void handle_setup0 (void)
{ {
@@ -836,14 +819,27 @@ static void handle_setup0 (void)
{ {
if (req < TOTAL_REQUEST) if (req < TOTAL_REQUEST)
{ {
handler = std_request_handler[req]; switch (req)
{
case 0: handler = std_get_status; break;
case 1: handler = std_clear_feature; break;
case 3: handler = std_set_feature; break;
case 5: handler = std_set_address; break;
case 6: handler = std_get_descriptor; break;
case 8: handler = std_get_configuration; break;
case 9: handler = std_set_configuration; break;
case 10: handler = std_get_interface; break;
case 11: handler = std_set_interface; break;
default: handler = std_none; break;
}
r = (*handler) (ctrl_p->bmRequestType, r = (*handler) (ctrl_p->bmRequestType,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength); ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
} }
} }
else else
r = (*method_p->setup) (ctrl_p->bmRequestType, req, r = usb_cb_setup (ctrl_p->bmRequestType, req,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength); ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
if (r != USB_SUCCESS) if (r != USB_SUCCESS)
dev_p->state = STALLED; dev_p->state = STALLED;
@@ -890,12 +886,12 @@ static void handle_in0 (void)
== (STANDARD_REQUEST | DEVICE_RECIPIENT))) == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
{ {
st103_set_daddr (ctrl_p->wValue); st103_set_daddr (ctrl_p->wValue);
(*method_p->event) (USB_EVENT_ADDRESS, ctrl_p->wValue); usb_cb_handle_event (USB_EVENT_ADDRESS, ctrl_p->wValue);
} }
else else
(*method_p->ctrl_write_finish) (ctrl_p->bmRequestType, usb_cb_ctrl_write_finish (ctrl_p->bmRequestType,
ctrl_p->bRequest, ctrl_p->wValue, ctrl_p->bRequest, ctrl_p->wValue,
ctrl_p->wIndex, ctrl_p->wLength); ctrl_p->wIndex, ctrl_p->wLength);
dev_p->state = STALLED; dev_p->state = STALLED;
} }
@@ -938,26 +934,6 @@ void WEAK EP5_OUT_Callback (void);
void WEAK EP6_OUT_Callback (void); void WEAK EP6_OUT_Callback (void);
void WEAK EP7_OUT_Callback (void); void WEAK EP7_OUT_Callback (void);
void (*const ep_intr_handler_IN[7]) (void) = {
EP1_IN_Callback,
EP2_IN_Callback,
EP3_IN_Callback,
EP4_IN_Callback,
EP5_IN_Callback,
EP6_IN_Callback,
EP7_IN_Callback,
};
void (*const ep_intr_handler_OUT[7]) (void) = {
EP1_OUT_Callback,
EP2_OUT_Callback,
EP3_OUT_Callback,
EP4_OUT_Callback,
EP5_OUT_Callback,
EP6_OUT_Callback,
EP7_OUT_Callback,
};
static void static void
usb_handle_transfer (void) usb_handle_transfer (void)
{ {
@@ -1008,13 +984,31 @@ usb_handle_transfer (void)
if ((ep_value & EP_CTR_RX) != 0) if ((ep_value & EP_CTR_RX) != 0)
{ {
st103_ep_clear_ctr_rx (ep_index); st103_ep_clear_ctr_rx (ep_index);
(*ep_intr_handler_OUT[ep_index-1]) (); switch ((ep_index - 1))
{
case 0: EP1_OUT_Callback (); break;
case 1: EP2_OUT_Callback (); break;
case 2: EP3_OUT_Callback (); break;
case 3: EP4_OUT_Callback (); break;
case 4: EP5_OUT_Callback (); break;
case 5: EP6_OUT_Callback (); break;
case 6: EP7_OUT_Callback (); break;
}
} }
if ((ep_value & EP_CTR_TX) != 0) if ((ep_value & EP_CTR_TX) != 0)
{ {
st103_ep_clear_ctr_tx (ep_index); st103_ep_clear_ctr_tx (ep_index);
(*ep_intr_handler_IN[ep_index-1]) (); switch ((ep_index - 1))
{
case 0: EP1_IN_Callback (); break;
case 1: EP2_IN_Callback (); break;
case 2: EP3_IN_Callback (); break;
case 3: EP4_IN_Callback (); break;
case 4: EP5_IN_Callback (); break;
case 5: EP6_IN_Callback (); break;
case 6: EP7_IN_Callback (); break;
}
} }
} }
} }

View File

@@ -49,29 +49,20 @@ enum DESCRIPTOR_TYPE
#define USB_SETUP_SET(req) ((req & REQUEST_DIR) == 0) #define USB_SETUP_SET(req) ((req & REQUEST_DIR) == 0)
#define USB_SETUP_GET(req) ((req & REQUEST_DIR) != 0) #define USB_SETUP_GET(req) ((req & REQUEST_DIR) != 0)
struct Descriptor
{
const uint8_t *Descriptor;
uint16_t Descriptor_Size;
};
enum enum
{ {
USB_UNSUPPORT = 0, USB_UNSUPPORT = 0,
USB_SUCCESS = 1, USB_SUCCESS = 1,
}; };
struct usb_device_method void usb_cb_device_reset (void);
{ void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
void (*reset) (void); uint16_t value, uint16_t index, uint16_t len);
void (*ctrl_write_finish) (uint8_t req, uint8_t req_no, int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t value, uint16_t index, uint16_t len); uint16_t index, uint16_t len);
int (*setup) (uint8_t req, uint8_t req_no, int usb_cb_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value);
uint16_t value, uint16_t index, uint16_t len); int usb_cb_handle_event (uint8_t event_type, uint16_t value);
int (*get_descriptor) (uint8_t desc_type, uint16_t index, uint16_t value); int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value);
int (*event) (uint8_t event_type, uint16_t value);
int (*interface) (uint8_t cmd, uint16_t interface, uint16_t value);
};
enum { enum {
USB_EVENT_ADDRESS, USB_EVENT_ADDRESS,
@@ -87,14 +78,6 @@ enum {
USB_QUERY_INTERFACE, USB_QUERY_INTERFACE,
}; };
extern void USB_Cable_Config (int NewState);
extern const struct usb_device_method Device_Method;
extern const struct Descriptor Device_Descriptor;
extern const struct Descriptor Config_Descriptor;
extern const struct Descriptor String_Descriptors[];
enum DEVICE_STATE enum DEVICE_STATE
{ {
UNCONNECTED, UNCONNECTED,
@@ -106,6 +89,7 @@ enum DEVICE_STATE
}; };
extern uint32_t bDeviceState; extern uint32_t bDeviceState;
extern const uint8_t usb_initial_feature;
#define STM32_USB_IRQ_PRIORITY 11 #define STM32_USB_IRQ_PRIORITY 11

View File

@@ -3,7 +3,7 @@
""" """
stlinkv2.py - a tool to control ST-Link/V2 stlinkv2.py - a tool to control ST-Link/V2
Copyright (C) 2012 Free Software Initiative of Japan Copyright (C) 2012, 2013 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org> Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation. This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -165,12 +165,20 @@ class stlinkv2(object):
v = self.execute_get("\xf5\x00", 2) v = self.execute_get("\xf5\x00", 2)
return (v[1] * 256 + v[0]) return (v[1] * 256 + v[0])
def exit_from_debug_swd(self):
self.execute_put("\xf2\x21\x00")
time.sleep(1)
def exit_from_dfu(self): def exit_from_dfu(self):
self.__devhandle.bulkWrite(self.__bulkout, "\xf3\x07", self.__timeout) self.execute_put("\xf3\x07\x00")
time.sleep(1)
def exit_from_debug_swim(self):
self.execute_put("\xf4\x01\x00")
time.sleep(1) time.sleep(1)
def enter_swd(self): def enter_swd(self):
self.__devhandle.bulkWrite(self.__bulkout, "\xf2\x20\xa3", self.__timeout) self.execute_put("\xf2\x20\xa3")
time.sleep(1) time.sleep(1)
def get_status(self): def get_status(self):
@@ -208,6 +216,9 @@ class stlinkv2(object):
def write_reg(self, regno, value): def write_reg(self, regno, value):
return self.execute_get("\xf2\x06" + pack('<BI', regno, value), 2) return self.execute_get("\xf2\x06" + pack('<BI', regno, value), 2)
def write_debug_reg(self, addr, value):
return self.execute_get("\xf2\x35" + pack('<II', addr, value), 2)
def run(self): def run(self):
v = self.execute_get("\xf2\x09\x00", 2) v = self.execute_get("\xf2\x09\x00", 2)
return (v[1] << 8) + v[0] return (v[1] << 8) + v[0]
@@ -216,6 +227,11 @@ class stlinkv2(object):
v = self.execute_get("\xf2\x22\x00", 4) v = self.execute_get("\xf2\x22\x00", 4)
return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24) return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24)
def version(self):
v = self.execute_get("\xf1", 6)
val = (v[0] << 8) + v[1]
return ((val >> 12) & 0x0f, (val >> 6) & 0x3f, val & 0x3f)
# For FST-01-00 and FST-01: LED on, USB connect # For FST-01-00 and FST-01: LED on, USB connect
def setup_gpio(self): def setup_gpio(self):
apb2enr = self.read_memory_u32(0x40021018) apb2enr = self.read_memory_u32(0x40021018)
@@ -444,15 +460,25 @@ class stlinkv2(object):
def start(self): def start(self):
mode = self.stl_mode() mode = self.stl_mode()
if mode == 2: if mode == 2:
return self.exit_from_debug_swd()
elif mode != 1: elif mode == 5:
self.exit_from_debug_swim()
elif mode != 1 and mode != 4:
self.exit_from_dfu() self.exit_from_dfu()
mode = self.stl_mode() new_mode = self.stl_mode()
print "Change ST-Link/V2 mode to: %04x" % mode print "Change ST-Link/V2 mode %04x -> %04x" % (mode, new_mode)
self.enter_swd() self.enter_swd()
s = self.get_status() s = self.get_status()
if s != 0x0080: if s != 0x0080:
raise ValueError("Status of core is not running.", s) print "Status is %04x" % s
self.run()
s = self.get_status()
if s != 0x0080:
# DCB_DHCSR DBGKEY
self.write_debug_reg(0xE000EDF0, 0xA05F0000)
s = self.get_status()
if s != 0x0080:
raise ValueError("Status of core is not running.", s)
mode = self.stl_mode() mode = self.stl_mode()
if mode != 2: if mode != 2:
raise ValueError("Failed to switch debug mode.", mode) raise ValueError("Failed to switch debug mode.", mode)
@@ -511,6 +537,7 @@ def main(show_help, erase_only, no_protect, spi_flash_check,
if not stl: if not stl:
raise ValueError("No ST-Link/V2 device found.", None) raise ValueError("No ST-Link/V2 device found.", None)
print "ST-Link/V2 version info: %d %d %d" % stl.version()
stl.start() stl.start()
core_id = stl.core_id() core_id = stl.core_id()
chip_id = stl.read_memory_u32(0xE0042000) chip_id = stl.read_memory_u32(0xE0042000)
@@ -534,7 +561,12 @@ def main(show_help, erase_only, no_protect, spi_flash_check,
stl.enter_debug() stl.enter_debug()
status = stl.get_status() status = stl.get_status()
if status != 0x0081: if status != 0x0081:
raise ValueError("Status of core is not halt.", status) print "Core does not halt, try API V2 halt."
# DCB_DHCSR DBGKEY|C_HALT|C_DEBUGEN
stl.write_debug_reg(0xE000EDF0, 0xA05F0003)
status = stl.get_status()
if status != 0x0081:
raise ValueError("Status of core is not halt.", status)
if protection: if protection:
if status_only: if status_only: