Compare commits
26 Commits
release/1.
...
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>
|
2013-02-15 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* Version 1.0.2.
|
* 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 __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
31
NEWS
@@ -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
23
README
@@ -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
4
THANKS
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 = .;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
2
src/configure
vendored
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
27
src/main.c
27
src/main.c
@@ -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 */
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user