Compare commits
26 Commits
master
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93867d0c8b | ||
|
|
a1a112d213 | ||
|
|
e679b4da7a | ||
|
|
095f854fa8 | ||
|
|
f9292f1157 | ||
|
|
b619db59d2 | ||
|
|
8870d58b69 | ||
|
|
4abcddef93 | ||
|
|
ca46cc465c | ||
|
|
3cf5ed482f | ||
|
|
87d95d0864 | ||
|
|
428adc7ac6 | ||
|
|
cc185eabb5 | ||
|
|
80e3cda267 | ||
|
|
ee867794e7 | ||
|
|
a4f7386b8a | ||
|
|
7d4d6cff5e | ||
|
|
b09460f0ae | ||
|
|
4298809ffb | ||
|
|
b297cf22b6 | ||
|
|
f84f52156c | ||
|
|
1564a4fbe6 | ||
|
|
16610ca5c7 | ||
|
|
352f81a61f | ||
|
|
7c82839fba | ||
|
|
10c685be16 |
136
ChangeLog
136
ChangeLog
@@ -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>
|
||||
|
||||
* Version 1.0.2.
|
||||
|
||||
@@ -731,7 +731,7 @@ uint32_t __LDREXW(uint32_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) );
|
||||
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 result=0;
|
||||
register uint32_t result asm ("r2");
|
||||
|
||||
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
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 result=0;
|
||||
register uint32_t result asm ("r2");
|
||||
|
||||
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
|
||||
31
NEWS
31
NEWS
@@ -1,5 +1,32 @@
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
23
README
23
README
@@ -1,7 +1,7 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 1.0.2
|
||||
2013-02-15
|
||||
Version 1.0.4
|
||||
2013-03-15
|
||||
Niibe Yutaka
|
||||
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".
|
||||
|
||||
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
|
||||
=============
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
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/
|
||||
|
||||
It is based on GCC 4.6. For version 4.6-2012-q2-update, you'd
|
||||
need "-O3 -Os" instead of "-O2" and it will be slightly better.
|
||||
It is based on GCC 4.6 or 4.7.
|
||||
|
||||
|
||||
Change directory to `src':
|
||||
@@ -657,7 +661,8 @@ linux/Documentation/usb/usbmon.txt
|
||||
Firmware update
|
||||
===============
|
||||
|
||||
See doc/note/firmware-update.
|
||||
See doc/note/firmware-update. Note that this is an experimental
|
||||
feature.
|
||||
|
||||
|
||||
Git Repositories
|
||||
|
||||
4
THANKS
4
THANKS
@@ -1,3 +1,5 @@
|
||||
-*- coding: utf-8 -*-
|
||||
|
||||
We would like to express our gratitudes to Werner Koch for GnuPG, and
|
||||
Giovanni Di Sirio for ChibiOS/RT.
|
||||
|
||||
@@ -14,5 +16,7 @@ Ludovic Rousseau ludovic.rousseau@free.fr
|
||||
Luis Felipe R. Murillo luisfelipe@ucla.edu
|
||||
MATSUU Takuto matsuu@gentoo.org
|
||||
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
|
||||
Werner Koch wk@gnupg.org
|
||||
|
||||
@@ -22,6 +22,7 @@ MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
|
||||
DEFS = -DFREE_STANDING
|
||||
|
||||
CFLAGS = -O2 -g
|
||||
CFLAGS += -Wa,-alms=$(notdir $(<:.c=.lst)) -fpie
|
||||
CFLAGS += $(CWARN) -I . -I ../src -fno-common $(MCFLAGS) $(TOPT) $(DEFS)
|
||||
|
||||
LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
* 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,
|
||||
};
|
||||
|
||||
const struct Descriptor device_desc = {
|
||||
regnual_device_desc,
|
||||
sizeof (regnual_device_desc)
|
||||
};
|
||||
|
||||
const struct Descriptor config_desc = {
|
||||
regnual_config_desc,
|
||||
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)
|
||||
void
|
||||
usb_cb_device_reset (void)
|
||||
{
|
||||
/* Set DEVICE as not configured */
|
||||
usb_lld_set_configuration (0);
|
||||
|
||||
/* Current Feature initialization */
|
||||
usb_lld_set_feature (config_desc.Descriptor[7]);
|
||||
usb_lld_set_feature (regnual_config_desc[7]);
|
||||
|
||||
usb_lld_reset ();
|
||||
|
||||
@@ -141,11 +123,9 @@ regnual_device_reset (void)
|
||||
#define USB_REGNUAL_PROTECT 4
|
||||
#define USB_REGNUAL_FINISH 5
|
||||
|
||||
static uint8_t mem[256];
|
||||
static uint32_t mem[256/4];
|
||||
static uint32_t result;
|
||||
|
||||
static const uint8_t *const mem_info[] = { &_flash_start, &_flash_end, };
|
||||
|
||||
|
||||
static uint32_t rbit (uint32_t v)
|
||||
{
|
||||
@@ -159,7 +139,7 @@ static uint32_t fetch (int i)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
v = *(uint32_t *)(&mem[i*4]);
|
||||
v = mem[i];
|
||||
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,
|
||||
uint16_t value, uint16_t index,
|
||||
uint16_t len)
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len)
|
||||
{
|
||||
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);
|
||||
|
||||
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
|
||||
&& value == 0 && index == 0)
|
||||
@@ -211,9 +190,9 @@ static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
regnual_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
@@ -240,7 +223,8 @@ regnual_setup (uint8_t req, uint8_t req_no,
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
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);
|
||||
return USB_SUCCESS;
|
||||
@@ -264,38 +248,58 @@ regnual_setup (uint8_t req, uint8_t req_no,
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int
|
||||
regnual_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
|
||||
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_desc.Descriptor,
|
||||
device_desc.Descriptor_Size);
|
||||
usb_lld_set_data_to_send (regnual_device_desc,
|
||||
sizeof (regnual_device_desc));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (config_desc.Descriptor,
|
||||
config_desc.Descriptor_Size);
|
||||
usb_lld_set_data_to_send (regnual_config_desc,
|
||||
sizeof (regnual_config_desc));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
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,
|
||||
string_descs[desc_index].Descriptor_Size);
|
||||
return USB_SUCCESS;
|
||||
case 0:
|
||||
str = regnual_string_lang_id;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -311,20 +315,12 @@ static int regnual_usb_event (uint8_t event_type, uint16_t value)
|
||||
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;
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -23,22 +23,11 @@ SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
|
||||
.bss :
|
||||
{
|
||||
_bss_start = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
*(.bss.*)
|
||||
. = ALIGN(4);
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_bss_end = .;
|
||||
} > ram0
|
||||
|
||||
.text : ALIGN(16) SUBALIGN(16)
|
||||
{
|
||||
_text = .;
|
||||
KEEP(*(.vectors))
|
||||
*(.text.entry)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.rodata)
|
||||
@@ -48,6 +37,12 @@ SECTIONS
|
||||
*(.gcc*)
|
||||
} > ram1
|
||||
|
||||
.got :
|
||||
{
|
||||
*(.got)
|
||||
*(.got.*)
|
||||
} > ram1
|
||||
|
||||
.ctors :
|
||||
{
|
||||
PROVIDE(_ctors_start_ = .);
|
||||
@@ -90,6 +85,18 @@ SECTIONS
|
||||
_edata = .;
|
||||
} > ram1
|
||||
|
||||
.bss :
|
||||
{
|
||||
_bss_start = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
*(.bss.*)
|
||||
. = ALIGN(4);
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_bss_end = .;
|
||||
} > ram1
|
||||
|
||||
PROVIDE(end = .);
|
||||
_end = .;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
asm volatile ("ldr r0, =__ram_end__\n\t"
|
||||
"ldr r1, =__main_stack_size__\n\t"
|
||||
"sub r0, r0, r1\n\t"
|
||||
"mov sp, r0\n\t"
|
||||
asm volatile ("mov r0, pc\n\t"
|
||||
"bic r0, r0, #255\n\t" /* R0 := vector_table address */
|
||||
"mov r1, #0x90\n\t" /* R1 := numbers of entries * 4 */
|
||||
"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"
|
||||
"ldr r1, =_bss_start\n\t"
|
||||
"ldr r2, =_bss_end\n"
|
||||
"ldr r4, .L00+4\n\t"
|
||||
"ldr r1, [r3, r4]\n\t"
|
||||
"ldr r4, .L00+8\n\t"
|
||||
"ldr r2, [r3, r4]\n"
|
||||
"0:\n\t"
|
||||
"str r0, [r1], #4\n\t"
|
||||
"cmp r2, r1\n\t"
|
||||
@@ -29,7 +50,14 @@ void entry (void)
|
||||
"mov r1, r0\n\t"
|
||||
"bl main\n"
|
||||
"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");
|
||||
}
|
||||
|
||||
|
||||
2
src/configure
vendored
2
src/configure
vendored
@@ -84,7 +84,7 @@ Configuration:
|
||||
-h, --help display this help and exit [no]
|
||||
--vidpid=VID:PID specify vendor/product ID [<NONE>]
|
||||
--target=TARGET specify target [OLIMEX_STM32_H103]
|
||||
supported targes are:
|
||||
supported targets are:
|
||||
OLIMEX_STM32_H103
|
||||
STM32_PRIMER2
|
||||
CQ_STARM
|
||||
|
||||
@@ -171,8 +171,8 @@ struct key_data {
|
||||
};
|
||||
|
||||
struct key_data_internal {
|
||||
uint8_t data[KEY_CONTENT_LEN]; /* p and q */
|
||||
uint8_t checksum[DATA_ENCRYPTION_KEY_SIZE];
|
||||
uint32_t data[KEY_CONTENT_LEN/4]; /* p and q */
|
||||
uint32_t checksum[DATA_ENCRYPTION_KEY_SIZE/4];
|
||||
};
|
||||
|
||||
struct prvkey_data {
|
||||
|
||||
27
src/main.c
27
src/main.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -319,6 +319,23 @@ led_blink (int 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.
|
||||
@@ -330,6 +347,7 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
unsigned int count = 0;
|
||||
uint32_t entry;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
@@ -338,7 +356,7 @@ main (int argc, char *argv[])
|
||||
|
||||
flash_unlock ();
|
||||
device_initialize_once ();
|
||||
usb_lld_init (Config_Descriptor.Descriptor[7]);
|
||||
usb_lld_init (usb_initial_feature);
|
||||
random_init ();
|
||||
|
||||
while (1)
|
||||
@@ -429,6 +447,7 @@ main (int argc, char *argv[])
|
||||
port_disable ();
|
||||
/* Set vector */
|
||||
SCB->VTOR = (uint32_t)&_regnual_start;
|
||||
entry = calculate_regnual_entry_address (&_regnual_start);
|
||||
#ifdef DFU_SUPPORT
|
||||
#define FLASH_SYS_START_ADDR 0x08000000
|
||||
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
|
||||
@@ -447,12 +466,12 @@ main (int argc, char *argv[])
|
||||
flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
|
||||
|
||||
/* Leave Gnuk to exec reGNUal */
|
||||
(*func) (*((void (**)(void))(&_regnual_start+4)));
|
||||
(*func) ((void (*)(void))entry);
|
||||
for (;;);
|
||||
}
|
||||
#else
|
||||
/* Leave Gnuk to exec reGNUal */
|
||||
flash_erase_all_and_exec (*((void (**)(void))(&_regnual_start+4)));
|
||||
flash_erase_all_and_exec ((void (*)(void))entry);
|
||||
#endif
|
||||
|
||||
/* Never reached */
|
||||
|
||||
@@ -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_CH_DATA 0x0065
|
||||
#define GPG_DO_APP_DATA 0x006e
|
||||
/* XXX: 0x0073 ??? */
|
||||
#define GPG_DO_DISCRETIONARY 0x0073
|
||||
#define GPG_DO_SS_TEMP 0x007a
|
||||
#define GPG_DO_DS_COUNT 0x0093
|
||||
#define GPG_DO_EXTCAP 0x00c0
|
||||
@@ -447,7 +447,7 @@ const uint8_t openpgpcard_aid[] = {
|
||||
static int
|
||||
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)
|
||||
{
|
||||
@@ -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 };
|
||||
|
||||
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 */
|
||||
{
|
||||
@@ -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));
|
||||
|
||||
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)
|
||||
modulus_free (modulus);
|
||||
|
||||
@@ -989,10 +989,14 @@ static const uint16_t cmp_ch_data[] = {
|
||||
};
|
||||
|
||||
static const uint16_t cmp_app_data[] = {
|
||||
10,
|
||||
3,
|
||||
GPG_DO_AID,
|
||||
GPG_DO_HIST_BYTES,
|
||||
/* XXX Discretionary data objects 0x0073 ??? */
|
||||
GPG_DO_DISCRETIONARY,
|
||||
};
|
||||
|
||||
static const uint16_t cmp_discretionary[] = {
|
||||
8,
|
||||
GPG_DO_EXTCAP,
|
||||
GPG_DO_ALG_SIG, GPG_DO_ALG_DEC, GPG_DO_ALG_AUT,
|
||||
GPG_DO_PW_STATUS,
|
||||
@@ -1038,6 +1042,7 @@ gpg_do_table[] = {
|
||||
/* Compound data: Read access only */
|
||||
{ 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_DISCRETIONARY, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_discretionary },
|
||||
{ GPG_DO_SS_TEMP, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ss_temp },
|
||||
/* Simple data: write access only */
|
||||
{ GPG_DO_RESETTING_CODE, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED,
|
||||
|
||||
@@ -321,10 +321,8 @@ static void no_buf (struct ep_in *epi, size_t len)
|
||||
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)
|
||||
{
|
||||
c->sw1sw2[0] = 0x90;
|
||||
@@ -333,10 +331,10 @@ static void set_sw1sw2 (struct ep_in *epi)
|
||||
else
|
||||
{
|
||||
c->sw1sw2[0] = 0x61;
|
||||
if (c->len >= 256)
|
||||
if (c->len - chunk_len >= 256)
|
||||
c->sw1sw2[1] = 0;
|
||||
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);
|
||||
|
||||
set_sw1sw2 (c->epi);
|
||||
set_sw1sw2 (c, chunk_len);
|
||||
|
||||
if (chunk_len <= USB_LL_BUF_SIZE - ICC_MSG_HEADER_SIZE)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
* 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
|
||||
}
|
||||
|
||||
static void
|
||||
gnuk_device_reset (void)
|
||||
void
|
||||
usb_cb_device_reset (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -156,7 +156,7 @@ gnuk_device_reset (void)
|
||||
usb_lld_set_configuration (0);
|
||||
|
||||
/* Current Feature initialization */
|
||||
usb_lld_set_feature (Config_Descriptor.Descriptor[7]);
|
||||
usb_lld_set_feature (usb_initial_feature);
|
||||
|
||||
usb_lld_reset ();
|
||||
|
||||
@@ -214,9 +214,9 @@ static int download_check_crc32 (const uint32_t *end_p)
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int
|
||||
gnuk_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
@@ -310,9 +310,8 @@ gnuk_setup (uint8_t req, uint8_t req_no,
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static void gnuk_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index,
|
||||
uint16_t len)
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len)
|
||||
{
|
||||
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
|
||||
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 usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
||||
{
|
||||
int i;
|
||||
uint8_t current_conf;
|
||||
@@ -401,7 +369,7 @@ static int gnuk_usb_event (uint8_t event_type, uint16_t value)
|
||||
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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
#include "usb_conf.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_SUBCLASS 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)
|
||||
|
||||
|
||||
|
||||
#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 */
|
||||
static const uint8_t gnukConfigDescriptor[] = {
|
||||
9, /* bLength: Configuation Descriptor size */
|
||||
@@ -61,11 +77,7 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
NUM_INTERFACES, /* bNumInterfaces: */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
#if defined(USB_SELF_POWERED)
|
||||
0xC0, /* bmAttributes: self powered */
|
||||
#else
|
||||
0x80, /* bmAttributes: bus powered */
|
||||
#endif
|
||||
USB_INITIAL_FEATURE, /* bmAttributes*/
|
||||
50, /* MaxPower 100 mA */
|
||||
|
||||
/* Interface Descriptor */
|
||||
@@ -260,25 +272,25 @@ static const uint8_t gnukStringLangID[] = {
|
||||
const uint8_t gnukStringSerial[] = {
|
||||
19*2+2, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
/* FSIJ-1.0.1- */
|
||||
/* FSIJ-1.0.3- */
|
||||
'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,
|
||||
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,
|
||||
sizeof (gnukDeviceDescriptor)
|
||||
};
|
||||
|
||||
const struct Descriptor Config_Descriptor = {
|
||||
static const struct Descriptor Config_Descriptor = {
|
||||
gnukConfigDescriptor,
|
||||
sizeof (gnukConfigDescriptor)
|
||||
};
|
||||
|
||||
const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
|
||||
static const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
|
||||
{gnukStringLangID, sizeof (gnukStringLangID)},
|
||||
{gnukStringVendor, sizeof (gnukStringVendor)},
|
||||
{gnukStringProduct, sizeof (gnukStringProduct)},
|
||||
@@ -287,3 +299,34 @@ const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
|
||||
{gnuk_config_options, sizeof (gnuk_config_options)},
|
||||
{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;
|
||||
}
|
||||
|
||||
@@ -74,12 +74,10 @@ struct DEVICE_INFO
|
||||
static struct CONTROL_INFO control_info;
|
||||
static struct DEVICE_INFO device_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 DEVICE_INFO *const dev_p = &device_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 PMA_ADDR (0x40006000UL) /* USB_IP Packet Memory Area base address */
|
||||
@@ -399,7 +397,7 @@ usb_interrupt_handler (void)
|
||||
if (istr_value & ISTR_RESET)
|
||||
{
|
||||
st103_set_istr (CLR_RESET);
|
||||
method_p->reset ();
|
||||
usb_cb_device_reset ();
|
||||
}
|
||||
|
||||
if (istr_value & ISTR_DOVR)
|
||||
@@ -529,7 +527,7 @@ static int std_get_status (uint8_t req,
|
||||
if (dev_p->current_configuration == 0)
|
||||
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)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
@@ -700,7 +698,7 @@ static int std_get_descriptor (uint8_t req, uint16_t value,
|
||||
|
||||
(void)length;
|
||||
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;
|
||||
}
|
||||
@@ -736,7 +734,7 @@ static int std_set_configuration (uint8_t req, uint16_t value,
|
||||
{
|
||||
int r;
|
||||
|
||||
r = (*method_p->event) (USB_EVENT_CONFIG, value);
|
||||
r = usb_cb_handle_event (USB_EVENT_CONFIG, value);
|
||||
if (r == 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)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
return (*method_p->interface) (USB_GET_INTERFACE, index, 0);
|
||||
return usb_cb_interface (USB_GET_INTERFACE, index, 0);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
@@ -784,7 +782,7 @@ static int std_set_interface (uint8_t req, uint16_t value,
|
||||
if (dev_p->current_configuration != 0)
|
||||
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)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
@@ -792,21 +790,6 @@ static int std_set_interface (uint8_t req, uint16_t value,
|
||||
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)
|
||||
{
|
||||
@@ -836,14 +819,27 @@ static void handle_setup0 (void)
|
||||
{
|
||||
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,
|
||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
||||
}
|
||||
}
|
||||
else
|
||||
r = (*method_p->setup) (ctrl_p->bmRequestType, req,
|
||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
||||
r = usb_cb_setup (ctrl_p->bmRequestType, req,
|
||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
||||
|
||||
if (r != USB_SUCCESS)
|
||||
dev_p->state = STALLED;
|
||||
@@ -890,12 +886,12 @@ static void handle_in0 (void)
|
||||
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
|
||||
{
|
||||
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
|
||||
(*method_p->ctrl_write_finish) (ctrl_p->bmRequestType,
|
||||
ctrl_p->bRequest, ctrl_p->wValue,
|
||||
ctrl_p->wIndex, ctrl_p->wLength);
|
||||
usb_cb_ctrl_write_finish (ctrl_p->bmRequestType,
|
||||
ctrl_p->bRequest, ctrl_p->wValue,
|
||||
ctrl_p->wIndex, ctrl_p->wLength);
|
||||
|
||||
dev_p->state = STALLED;
|
||||
}
|
||||
@@ -938,26 +934,6 @@ void WEAK EP5_OUT_Callback (void);
|
||||
void WEAK EP6_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
|
||||
usb_handle_transfer (void)
|
||||
{
|
||||
@@ -1008,13 +984,31 @@ usb_handle_transfer (void)
|
||||
if ((ep_value & EP_CTR_RX) != 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,29 +49,20 @@ enum DESCRIPTOR_TYPE
|
||||
#define USB_SETUP_SET(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
|
||||
{
|
||||
USB_UNSUPPORT = 0,
|
||||
USB_SUCCESS = 1,
|
||||
};
|
||||
|
||||
struct usb_device_method
|
||||
{
|
||||
void (*reset) (void);
|
||||
void (*ctrl_write_finish) (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len);
|
||||
int (*setup) (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len);
|
||||
int (*get_descriptor) (uint8_t desc_type, uint16_t index, uint16_t value);
|
||||
int (*event) (uint8_t event_type, uint16_t value);
|
||||
int (*interface) (uint8_t cmd, uint16_t interface, uint16_t value);
|
||||
};
|
||||
void usb_cb_device_reset (void);
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len);
|
||||
int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len);
|
||||
int usb_cb_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value);
|
||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
|
||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value);
|
||||
|
||||
enum {
|
||||
USB_EVENT_ADDRESS,
|
||||
@@ -87,14 +78,6 @@ enum {
|
||||
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
|
||||
{
|
||||
UNCONNECTED,
|
||||
@@ -106,6 +89,7 @@ enum DEVICE_STATE
|
||||
};
|
||||
|
||||
extern uint32_t bDeviceState;
|
||||
extern const uint8_t usb_initial_feature;
|
||||
|
||||
#define STM32_USB_IRQ_PRIORITY 11
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
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>
|
||||
|
||||
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)
|
||||
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):
|
||||
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)
|
||||
|
||||
def enter_swd(self):
|
||||
self.__devhandle.bulkWrite(self.__bulkout, "\xf2\x20\xa3", self.__timeout)
|
||||
self.execute_put("\xf2\x20\xa3")
|
||||
time.sleep(1)
|
||||
|
||||
def get_status(self):
|
||||
@@ -208,6 +216,9 @@ class stlinkv2(object):
|
||||
def write_reg(self, regno, value):
|
||||
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):
|
||||
v = self.execute_get("\xf2\x09\x00", 2)
|
||||
return (v[1] << 8) + v[0]
|
||||
@@ -216,6 +227,11 @@ class stlinkv2(object):
|
||||
v = self.execute_get("\xf2\x22\x00", 4)
|
||||
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
|
||||
def setup_gpio(self):
|
||||
apb2enr = self.read_memory_u32(0x40021018)
|
||||
@@ -444,15 +460,25 @@ class stlinkv2(object):
|
||||
def start(self):
|
||||
mode = self.stl_mode()
|
||||
if mode == 2:
|
||||
return
|
||||
elif mode != 1:
|
||||
self.exit_from_debug_swd()
|
||||
elif mode == 5:
|
||||
self.exit_from_debug_swim()
|
||||
elif mode != 1 and mode != 4:
|
||||
self.exit_from_dfu()
|
||||
mode = self.stl_mode()
|
||||
print "Change ST-Link/V2 mode to: %04x" % mode
|
||||
new_mode = self.stl_mode()
|
||||
print "Change ST-Link/V2 mode %04x -> %04x" % (mode, new_mode)
|
||||
self.enter_swd()
|
||||
s = self.get_status()
|
||||
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()
|
||||
if mode != 2:
|
||||
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:
|
||||
raise ValueError("No ST-Link/V2 device found.", None)
|
||||
|
||||
print "ST-Link/V2 version info: %d %d %d" % stl.version()
|
||||
stl.start()
|
||||
core_id = stl.core_id()
|
||||
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()
|
||||
status = stl.get_status()
|
||||
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 status_only:
|
||||
|
||||
Reference in New Issue
Block a user