Compare commits

...

38 Commits

Author SHA1 Message Date
NIIBE Yutaka
55ee1cd30f version 1.1.6 2015-07-21 09:25:06 +09:00
NIIBE Yutaka
5f21a44058 ECC keygen 2015-07-20 18:01:21 +09:00
NIIBE Yutaka
edf1a0cdd7 always enable keygen 2015-07-18 13:55:28 +09:00
NIIBE Yutaka
be5c052531 cleanup USB string things 2015-07-16 10:35:08 +09:00
NIIBE Yutaka
e041a2aa7d configure update 2015-07-16 10:19:12 +09:00
NIIBE Yutaka
31c7a42c73 common binary support fix 2015-07-16 09:31:44 +09:00
NIIBE Yutaka
8ddcc1e896 support Board 2015-07-15 16:37:19 +09:00
NIIBE Yutaka
6a8f8dffcb common binary support 2015-07-15 14:29:37 +09:00
NIIBE Yutaka
f2744bec30 upgrade to chopstx 0.07 2015-07-15 14:09:36 +09:00
NIIBE Yutaka
074f479962 update 2015-07-15 14:02:49 +09:00
NIIBE Yutaka
a60fe371a4 improve stlinkv2.py 2015-07-15 14:01:40 +09:00
NIIBE Yutaka
3ea5e54eb9 Add debug test files 2015-07-15 14:01:22 +09:00
NIIBE Yutaka
ed8c41a0ca Support STM32 Primer 2 2015-07-11 17:49:52 +09:00
NIIBE Yutaka
9ed3bb5353 Fix stlinkv2 for STM32F103xE 2015-07-11 17:46:50 +09:00
NIIBE Yutaka
9bbca07033 Curve25519 support 2015-07-08 08:49:05 +09:00
NIIBE Yutaka
9ba59de212 stlinkv2.py: merge Cortex-M0 support for FSM-55 2015-07-06 15:52:04 +09:00
NIIBE Yutaka
35c880fc0c remove boards/ since we have now STM32 Primer2 and CQ STARM 2015-07-06 12:46:45 +09:00
NIIBE Yutaka
7b116d614e update chopstx 2015-06-30 16:07:46 +09:00
NIIBE Yutaka
a73d04cf82 serial number change 2015-06-30 16:03:00 +09:00
NIIBE Yutaka
2471616f74 version 1.1.5 2015-06-03 17:22:56 +09:00
NIIBE Yutaka
3926f42647 add test/ecc_nistp256_keys.py 2015-06-03 16:27:41 +09:00
NIIBE Yutaka
ce070f85ff Improve tool/ 2015-06-03 16:27:15 +09:00
NIIBE Yutaka
bd02cbfdb0 OpenPGPcard spec v3.0 change 2015-06-02 20:46:30 +09:00
NIIBE Yutaka
16149ff960 show MAPLE_MINI in help message 2015-06-02 20:44:38 +09:00
NIIBE Yutaka
c4a5681f35 upgrade Chopstx 0.05 2015-06-02 20:44:09 +09:00
NIIBE Yutaka
3d5a776ab1 works on Windows 2015-04-19 09:55:51 +09:00
NIIBE Yutaka
9f4671eaf6 ccid_card_change_signal change 2015-04-18 14:34:53 +09:00
NIIBE Yutaka
5af5d18310 Use chopstx_main_init. 2015-04-18 14:13:00 +09:00
NIIBE Yutaka
3765c9233b shell syntax fix 2015-04-18 12:30:21 +09:00
NIIBE Yutaka
0bd0af1fe1 USB clean up 2015-03-31 14:05:52 +09:00
NIIBE Yutaka
92189e2d12 Update README and THANKS 2015-03-12 14:52:41 +09:00
NIIBE Yutaka
6dcd5aa00c doc fix 2015-03-06 16:14:12 +09:00
NIIBE Yutaka
09d3068222 fix EdDSA auth 2015-03-06 16:13:57 +09:00
NIIBE Yutaka
0f11d320e6 bug fix of OPENPGP.3 singing 2015-02-25 10:03:41 +09:00
NIIBE Yutaka
365308f374 Fix the doc. Thanks to Micah 2015-02-18 10:19:10 +09:00
NIIBE Yutaka
0e510b32c1 Fix EdDSA signature counter 2015-02-10 09:58:45 +09:00
NIIBE Yutaka
a9244d9b13 Fix the bug of EdDSA signing 2015-02-09 16:28:26 +09:00
NIIBE Yutaka
c268e59813 fix doc: Thanks to Micah 2015-01-19 11:08:13 +09:00
61 changed files with 1603 additions and 1940 deletions

31
AUTHORS
View File

@@ -1,35 +1,10 @@
Kaz Kojima:
Added STM32 Primer2 support:
boards/STM32_PRIMER2/board.c
boards/STM32_PRIMER2/board.h
boards/STM32_PRIMER2/mcuconf.h
Added STM32 Primer2 support.
NIIBE Yutaka:
Founder of the project.
Added FST_01 support:
boards/FST_01/board.c
boards/FST_01/board.h
boards/FST_01/mcuconf.h
Added FST_01_00 support:
boards/FST_01_00/board.c
boards/FST_01_00/board.h
boards/FST_01_00/mcuconf.h
Added STBee support:
boards/STBEE/board.c
boards/STBEE/board.h
boards/STBEE/mcuconf.h
Added STM8S Discovery Kit support:
boards/STM8S_DISCOVERY/board.c
boards/STM8S_DISCOVERY/board.h
boards/STM8S_DISCOVERY/mcuconf.h
Added STBee Mini support:
boards/STBEE_MINI/board.c
boards/STBEE_MINI/board.h
boards/STBEE_MINI/mcuconf.h
Added CQ STARM support:
boards/CQ_STARM/board.c
boards/CQ_STARM/board.h
boards/CQ_STARM/mcuconf.h
Wrote tools for STLink/V2:
tool/stlinkv2.py
Wrote tools for DfuSe:
tool/dfuse.py
tool/dump_mem.py

178
ChangeLog
View File

@@ -1,3 +1,181 @@
2015-07-21 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 1.1.6.
2015-07-20 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp-do.c (gpg_do_keygen): Support ECC.
* src/call-ec.c (ecc_check_secret): New.
* src/ecc.c (check_secret): New.
2015-07-18 Niibe Yutaka <gniibe@fsij.org>
* src/configure (keygen): It's always enabled.
* src/openpgp-do.c (gpg_do_keygen): Support key generation.
* src/openpgp.c (cmd_pgp_gakp): Likewise.
* src/call-rsa.c (rsa_genkey): Likewise.
* src/random.c (random_gen): Likewise.
* src/Makefile.in (KEYGEN_SUPPORT): Remove.
* polarssl/include/polarssl/config.h (POLARSSL_GENPRIME): Define.
2015-07-16 Niibe Yutaka <gniibe@fsij.org>
* src/configure (FLASH_PAGE_SIZE, FLASH_SIZE, MEMORY_SIZE)
[sys1_compat]: Use safe values for common binary.
(TARGET_DEFINE): Remove.
2015-07-15 Niibe Yutaka <gniibe@fsij.org>
* tool/usb_strings.py (field): Add 'Board'.
* regnual/regnual.c (usb_cb_get_descriptor): Update.
* src/usb_ctrl.c (usb_cb_interface): Call usb_lld_write.
* src/usb_desc.c (usb_cb_get_descriptor): Support sys_board_name,
using usb_lld_write.
* src/usb_lld.h (usb_cb_get_descriptor): Add last argument length
for asked length.
* src/usb_stm32f103.c (handle_setup0): Allow setup callback to
call usb_lld_write with ENDP0.
* src/usb_conf.h (NUM_STRING_DESC): Remove.
* src/configure [!sys1_compat] (CONFIG): Don't include target
board name.
* src/flash.c: Detect flash_page_size at runtime.
* src/main.c: Remove dependency to board.h.
* src/neug.c: Update from NeuG 1.0.2.
* src/adc_stm32f103.c: Update.
* chopstx: Update to 0.07.
* src/sys.c: Update.
* src/sys.h: Update.
* src/gnuk.ld.in: Update.
* tool/stlinkv2.py (stlinkv2.get_chip_id): New. Detect flash
size, too.
(main): Call stlinkv2.get_chip_id after MCU reset and stop.
Verify read out fix.
2015-07-11 Niibe Yutaka <gniibe@fsij.org>
* src/configure (help): Add STM32_PRIMER2 and CQ_STARM.
* chopstx: Update to 0.06.
* tool/stlinkv2.py: Support 512kB version of STM32F103.
The size of executable file should be even.
2015-07-07 Niibe Yutaka <gniibe@fsij.org>
* src/Makefile.in (CSRC): Add ecc-mont.c.
* src/ecc-mont.c (mod25638_mul_121665): Fix.
(ecdh_compute_public_25519, ecdh_decrypt_curve25519): New.
* src/openpgp.c (cmd_pso): Support ALGO_CURVE25519.
* src/openpgp-do.c (algorithm_attr_cv25519): New.
(rw_algorithm_attr, get_algo_attr_data_object)
(gpg_get_algo_attr_key_size, gpg_do_write_prvkey)
(proc_key_import, gpg_do_public_key): Support ALGO_CURVE25519.
* src/gnuk.h (ALGO_CURVE25519): New.
2015-07-06 Niibe Yutaka <gniibe@fsij.org>
Enhancement for FSM-55.
* tool/stlinkv2.py (stlinkv2.control_nrst): New.
(stlinkv2.get_rdp_key,has_spi_flash,has_protection): New.
(stlinkv2.get_core_id): Rename.
(stlinkv2.blank_check): Use self.flash_size.
(stlinkv2.start): Call control_nrst. Call get_core_id.
Distinguishing chip, and set rdp_key, flash_size and require_nrst.
(stlinkv2.flash_write): Use self.flash_block_size.
(main): Call control_nrst.
(prog_flash_write_body, prog_option_bytes_write_body)
(prog_blank_check_body): Support Cortex-M0.
(main): Call API V2 halt twice.
* tool/asm-thumb/*.S: Updated for Cortex-M0.
2015-06-30 Niibe Yutaka <gniibe@fsij.org>
* src/sys.c: Update from chopstx/example-cdc/sys.c.
* src/main.c (device_initialize_once): Apply change of NeuG.
2015-06-03 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 1.1.5.
* test/ecc_nistp256_keys.py: New.
* tool/upgrade_by_passwd.py: Remove -p option and add -f option.
* tool/gnuk_token.py (gnuk_token.download): Add verbose flag.
(regnual.download): Ditto.
* tool/gnuk_upgrade.py: Use gnuk_token module.
2015-06-02 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_pso): Support OpenPGPcard spec v3.0.
2015-04-20 Niibe Yutaka <gniibe@fsij.org>
* chopstx: Upgrade to 0.05.
2015-04-19 Niibe Yutaka <gniibe@fsij.org>
* src/gnuk.h (CCID_CARD_INIT): New.
* src/usb_desc.c (gnukConfigDescriptor): Update dwDefaultClock,
dwMaximumClock, dwFeatures, and bClassEnvelope.
* src/usb_ctrl.c (freq_table): Change the value to 4000MHz.
(usb_cb_handle_event): Call ccid_card_change_signal after configure.
* src/usb-icc.c (ccid_thread): Change EV_CARD_CHANGE handling.
2015-04-18 Niibe Yutaka <gniibe@fsij.org>
* src/main.c (main): Call chopstx_main_init.
* src/Makefile.in (DEFS): Remove CHX_PRIO_MAIN.
2015-04-17 Niibe Yutaka <gniibe@fsij.org>
* src/configure: Fix shell syntax.
2015-03-31 Niibe Yutaka <gniibe@fsij.org>
* src/usb_conf.h (ICC_NUM_INTERFACES, HID_NUM_INTERFACES)
(HID_NUM_INTERFACES, VCOM_NUM_INTERFACES, MSC_NUM_INTERFACES)
(NUM_INTERFACES): Define here (moved from usb_desc.c).
(ICC_INTERFACE, HID_INTERFACE, VCOM_INTERFACE_0, VCOM_INTERFACE_1)
(MSC_INTERFACE): New.
* src/usb_ctrl.c (gnuk_setup_endpoints_for_interface)
(usb_cb_setup, usb_cb_ctrl_write_finish): Use *_INTERFACE.
* src/usb_desc.c (gnukConfigDescriptor): Likewise.
2015-03-06 Niibe Yutaka <gniibe@fsij.org>
* src/ecc-edwards.c (eddsa_sign_25519): Return 0.
2015-02-25 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_internal_authenticate): Fix storing to
res_APDU_size.
2015-02-10 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_pso): Fix counter update for EdDSA. Thanks
to Jonathan Schleifer.
* src/call-rsa.c (rsa_sign): Don't set res_APDU_len.
(rsa_decrypt): Likewise, but get OUTPUT_LEN_P as an argument.
2015-02-09 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_pso): Fix EdDSA. Use GPG_KEY_FOR_SIGNING.
2014-12-15 Niibe Yutaka <gniibe@fsij.org>
* VERSION: 1.1.4.

45
NEWS
View File

@@ -1,5 +1,50 @@
Gnuk NEWS - User visible changes
* Major changes in Gnuk 1.1.6
Released 2015-07-21
** USB SerialNumber String
The way to determine a serial number of Gnuk Token has been changed.
It uses the 96-bit unique bits of MCU, but the portion for use is
changed.
** Upgrade of Chopstx
We use Chopstx 0.07, which supports STM32 Primer2 and CQ STARM, too.
** Experimental Curve25519 support.
Gnuk can support Curve25519 (for deecryption). Note that this is
pretty much experimental, and subjects to change. The low level code
is somehow stable, but there are no consensus in higer level.
Especially, OID in the key attribute would be changed in future.
** No --enable-keygen option
It is now standard feature included always. Note that it doesn't mean
this feature is stable now. It is becoming stable, hopefully.
* Major changes in Gnuk 1.1.5
Released 2015-06-03, by NIIBE Yutaka
** upgrade_by_passwd.py is not so noisy any more.
Since it's getting stable, no debug output any more.
** Maple mini support.
Although its random number generation is not tested, Maple mini
support is added.
** Windows interoperability fix.
1.1.x (0 to 4) didn't work with Windows because of INTERRUPT transfer.
It's fixed and it works now.
** OpenPGPcard specification v3.0 compatibility.
OpenPGPcard specification v3.0 now include NIST curves (and other
curves) and ECDSA and ECDH operations are defined. Gnuk follows
this specification.
* Major changes in Gnuk 1.1.4
Released 2014-12-15, by NIIBE Yutaka

79
README
View File

@@ -1,31 +1,36 @@
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
Version 1.1.4
2014-12-15
Version 1.1.6
2015-07-21
Niibe Yutaka
Free Software Initiative of Japan
Warning
=======
This is another experimental release of Gnuk, version 1.1.4, which has
This is another experimental release of Gnuk, version 1.1.6, which has
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
overriding key import, but importing keys (or generating keys) results
password reset. Please update your documentation for Gnuk Token, so
that the instruction of importing keys won't cause any confusion. It
has supports of ECDSA (with NIST P256 and secp256k1) and EdDSA with
EdDSA, but this feature is pretty much experimental, and it requires
development version of GnuPG with newest version of libgcrypt. You
will not able to keep using EdDSA keys, as the key format is subject
to change. It also support RSA-4096 experimentally, but users should
know that it takes more than 8 second to sign/decrypt.
has supports of ECDSA (with NIST P256 and secp256k1), EdDSA, and ECDH
(with NIST P256, secp256k1, and Curve25519), but this ECC feature is
pretty much experimental, and it requires development version of GnuPG
with newest version of libgcrypt (Further, for Curve25519, it requires
additional patches by me).
It also support RSA-4096 experimentally, but users should know that it
takes more than 8 second to sign/decrypt.
You will not able to keep using Curve25519 keys, as the key format is
subject to change.
What's Gnuk?
============
Gnuk is an implementation of USB cryptographic token for GNU Privacy
Guard. Gnuk supports OpenPGP card protocol version 2, and it runs on
Guard. Gnuk supports OpenPGP card protocol version 3, and it runs on
STM32F103 processor.
I wish that Gnuk will be a developer's soother who uses GnuPG. I have
@@ -114,18 +119,23 @@ Ab: That's because gnome-keyring-daemon interferes GnuPG. Type:
and at the tab of "Startup Programs", disable check buttons for
"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
Qc: With GNOME 3.x (x >= 8?), I can't use Gnuk Token at all. Why?
Ac: That's because gnome-keyring-daemon interferes GnuPG. Please
disable the invocation of gnome-keyring-daemon. In Debian
wheezy, it's in the files /etc/xdg/autostart/gnome-keyring-ssh.desktop
and /etc/xdg/autostart/gnome-keyring-gpg.desktop.
We have a line something like:
OnlyShowIn=GNOME;Unity;MATE;
Please edit this line to:
OnlyShowIn=
Qd: Do you know a good SWD debugger to connect FST-01 or something?
Ad: ST-Link/V2 is cheap one. We have a tool/stlinkv2.py as flash ROM
writer program.
Qd: With GNOME 3.x (x >= 8?), I can't use Gnuk Token at all. Why?
Ad: Please set the configration variable OnlyShowIn as none. Like:
OnlyShowIn=
In the files of /etc/xdg/autostart/gnome-keyring-gpg.desktop and
/etc/xdg/autostart/gnome-keyring-ssh.desktop
@@ -135,10 +145,11 @@ Release notes
This is third experimental release in version 1.1 series of Gnuk.
While it is daily use by its developer, some newly introduced features
(including ECDSA/EdDSA, key generation and firmware upgrade) should be
considered experimental. ECDSA/EdDSA is really experimental.
Further, EdDSA is much experimental. You won't be able to keep using
the EdDSA key, as the key format of GnuPG is subject to change.
(including ECDSA/EdDSA/ECDH, key generation and firmware upgrade)
should be considered experimental. ECDSA/EdDSA/ECDH is really
experimental. Further, ECDH on Curve25519 is much experimental. You
won't be able to keep using the key, since the key format of GnuPG is
not defined and it's subject to change.
Tested features are:
@@ -229,14 +240,14 @@ External source code
Gnuk is distributed with external source code.
* chopstx/ -- Chopstx 0.04
* chopstx/ -- Chopstx 0.07
We use Chopstx as the kernel for Gnuk.
Chopstx is distributed under GPLv3+ (with a special exception).
* polarssl/ -- PolarSSL 1.2.10
* polarssl/ -- based on PolarSSL 1.2.10 (now mbedTLS)
Souce code taken from: http://polarssl.org/
@@ -388,11 +399,10 @@ Flying Stone Tiny 01
If you are using Flying Stone Tiny 01, you need a SWD writer.
OpenOCD 0.6.1 now supports ST-Link/V2. We can use it:
OpenOCD 0.9 now supports ST-Link/V2. We can use it:
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x_stlink.cfg
But it doesn't support option bytes handling (protection) yet.
STBee
@@ -544,11 +554,11 @@ See doc/note/firmware-update.
Git Repositories
================
Please use: http://gitorious.org/gnuk
Please use: https://anonscm.debian.org/cgit/gnuk/gnuk/
You can get it by:
$ git clone git://gitorious.org/gnuk/gnuk.git
$ git clone git://anonscm.debian.org/gnuk/gnuk/gnuk.git
It's also available at: www.gniibe.org
You can browse at: http://git.gniibe.org/gitweb?p=gnuk/gnuk.git;a=summary
@@ -570,6 +580,14 @@ Information on the Web
Please visit: http://www.fsij.org/gnuk/
Please see the FST-01 support pages:
http://www.gniibe.org/category/fst-01.html
Please consider to join Gnuk-users mailing list:
https://lists.alioth.debian.org/mailman/listinfo/gnuk-users
Your Contributions
==================
@@ -580,5 +598,6 @@ to FSIJ (if possible).
Foot note
==========
* NUK(R) is a registered trademark owend by MAPA GmbH, Germany.
--

3
THANKS
View File

@@ -8,6 +8,7 @@ encouraging the development, testing the implementation, suggesting
improvements, or fixing bugs. Here is a list of those people.
Achim Pietig achim@pietig.com
Aidan Thornton
Andre Zepezauer andre.zepezauer@student.uni-halle.de
Hironobu SUZUKI hironobu@h2np.net
Jan Suhr jan@suhr.info
@@ -17,7 +18,9 @@ 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
NOKUBI Takatsugu knok@daionet.gr.jp
Paul Bakker polarssl_maintainer@polarssl.org
Shane Coughlan scoughlan@openinventionnetwork.com
Vasily Evseenko
Werner Koch wk@gnupg.org
Yuji Imai ug@xcast.jp

View File

@@ -1 +1 @@
release/1.1.4
release/1.1.6

View File

@@ -1,10 +0,0 @@
#include "config.h"
#include "ch.h"
#include "hal.h"
/*
* Board-specific initialization code.
*/
void boardInit(void)
{
}

View File

@@ -1,163 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/*
* Setup for the CQ STARM board.
*/
#undef SET_USB_CONDITION /* No functionality to disconnect USB */
#define SET_LED_CONDITION(on) on /* To emit light, call palSetPad */
#define GPIO_LED GPIOC_LED
#define IOPORT_LED GPIOC
/*
* Board identifier.
*/
#define BOARD_CQ_STARM
#define BOARD_NAME "CQ STARM"
/*
* Board frequencies.
*/
#define STM32_LSECLK 32768
#define STM32_HSECLK 8000000
/*
* MCU type, this macro is used by both the ST library and the ChibiOS/RT
* native STM32 HAL.
*/
#define STM32F10X_MD
/*
* IO pins assignments.
*/
#define GPIOC_LED 6
#if 0
#define GPIOA_BUTTON 0
#define GPIOA_SPI1NSS 4
#define GPIOB_SPI2NSS 12
#define GPIOC_MMCWP 6
#define GPIOC_MMCCP 7
#define GPIOC_CANCNTL 10
#define GPIOC_DISC 11
#endif
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
*
* The digits have the following meaning:
* 0 - Analog input.
* 1 - Push Pull output 10MHz.
* 2 - Push Pull output 2MHz.
* 3 - Push Pull output 50MHz.
* 4 - Digital input.
* 5 - Open Drain output 10MHz.
* 6 - Open Drain output 2MHz.
* 7 - Open Drain output 50MHz.
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
* 9 - Alternate Push Pull output 10MHz.
* A - Alternate Push Pull output 2MHz.
* B - Alternate Push Pull output 50MHz.
* C - Reserved.
* D - Alternate Open Drain output 10MHz.
* E - Alternate Open Drain output 2MHz.
* F - Alternate Open Drain output 50MHz.
* Please refer to the STM32 Reference Manual for details.
*/
/*
* Port A setup.
* Everything input with pull-up except:
* PA4 - Normal input (ADC_IN4 : VoutX of LIS344ALH).
* PA5 - Alternate output (MMC SPI1 SCK).
* PA6 - Normal input (MMC SPI1 MISO).
* PA7 - Alternate output (MMC SPI1 MOSI).
* PA11 - (USBDM)
* PA12 - (USBDP)
*/
#define VAL_GPIOACRL 0xB4B48888 /* PA7...PA0 */
#define VAL_GPIOACRH 0x88888888 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFFFFF
/*
* Port B setup.
* Everything input with pull-up except:
* PB13 - Alternate output (MMC SPI2 SCK).
* PB14 - Normal input (MMC SPI2 MISO).
* PB15 - Alternate output (MMC SPI2 MOSI).
*/
#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIOBCRH 0xB4B88888 /* PB15...PB8 */
#define VAL_GPIOBODR 0xFFFFFFFF
/*
* Port C setup.
* Everything input with pull-up except:
* PC4 - Normal input (ADC_IN14 : VoutY of LIS344ALH).
* PC5 - Normal input (ADC_IN15 : VoutZ of LIS344ALH).
* PC6 - Push Pull output (LED).
* (PC9 - SDCard CD)
* (PC12 - SDCard CS)
* PC14 - Normal input (XTAL).
* PC15 - Normal input (XTAL).
*/
#define VAL_GPIOCCRL 0x83448888 /* PC7...PC0 */
#define VAL_GPIOCCRH 0x44888888 /* PC15...PC8 */
#define VAL_GPIOCODR 0xFFFFFFFF
/*
* Port D setup.
* Everything input with pull-up except:
* (PD9 - USB_DC)
*/
#define VAL_GPIODCRL 0x88888888 /* PD7...PD0 */
#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
#define VAL_GPIODODR 0xFFFFFFFF
/*
* Port E setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
#define VAL_GPIOEODR 0xFFFFFFFF
#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
void boardInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _FROM_ASM_ */
#endif /* _BOARD_H_ */

View File

@@ -1,14 +0,0 @@
/*
* HAL driver system settings.
*/
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PPRE2 STM32_PPRE2_DIV1
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK
#include "mcuconf-common.h"

View File

@@ -1,15 +0,0 @@
#include "config.h"
#include "ch.h"
#include "hal.h"
/*
* Board-specific initialization code.
*/
void boardInit(void)
{
/*
* Clear LED and SHUTDOWN output.
*/
palClearPad (IOPORT5, GPIOE_LED);
palClearPad (IOPORT3, GPIOC_SHUTDOWN);
}

View File

@@ -1,175 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/*
* Setup for the STM32 Primer2.
*/
#define SET_USB_CONDITION(en) (!en) /* To connect USB, call palClearPad */
#define SET_LED_CONDITION(on) (!on) /* To emit light, call palClearPad */
#define GPIO_USB GPIOD_DISC
#define IOPORT_USB GPIOD
#define GPIO_LED GPIOE_LEDR
#define IOPORT_LED GPIOE
/* NeuG settings for ADC2. */
/*
* Board identifier.
*/
#define BOARD_STM32_PRIMER2
#define BOARD_NAME "STM32 Primer2"
/*
* Board frequencies.
*/
#define STM32_LSECLK 32768
#define STM32_HSECLK 12000000
/*
* MCU type, this macro is used by both the ST library and the ChibiOS/RT
* native STM32 HAL.
*/
#define STM32F10X_MD
/*
* IO pins assignments.
*/
#define GPIOA_BUTTON 8
#define GPIOC_SHUTDOWN 13
#define GPIOD_DISC 3
#define GPIOE_LED 0
#define GPIOE_LEDR 1
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
*
* The digits have the following meaning:
* 0 - Analog input.
* 1 - Push Pull output 10MHz.
* 2 - Push Pull output 2MHz.
* 3 - Push Pull output 50MHz.
* 4 - Digital input.
* 5 - Open Drain output 10MHz.
* 6 - Open Drain output 2MHz.
* 7 - Open Drain output 50MHz.
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
* 9 - Alternate Push Pull output 10MHz.
* A - Alternate Push Pull output 2MHz.
* B - Alternate Push Pull output 50MHz.
* C - Reserved.
* D - Alternate Open Drain output 10MHz.
* E - Alternate Open Drain output 2MHz.
* F - Alternate Open Drain output 50MHz.
* Please refer to the STM32 Reference Manual for details.
*/
/*
* Port A setup.
* Everything input with pull-up except:
* PA0 - Digital input with PullUp. AN0
* PA1 - Digital input with PullUp. AN1
* PA2 - Alternate output (USART2 TX).
* PA3 - Normal input (USART2 RX).
* PA8 - Input with pull-down (PBUTTON).
*/
#define VAL_GPIOACRL 0x88884B88 /* PA7...PA0 */
#define VAL_GPIOACRH 0x88888888 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFFEFF
/*
* Port B setup.
* Everything input with pull-up except:
* PB13 - Alternate output (AUDIO SPI2 SCK).
* PB14 - Normal input (AUDIO SPI2 MISO).
* PB15 - Alternate output (AUDIO SPI2 MOSI).
*/
#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIOBCRH 0xB4B88888 /* PB15...PB8 */
#define VAL_GPIOBODR 0xFFFFFFFF
/*
* Port C setup.
* Everything input with pull-up except:
* PC6 - Normal input because there is an external resistor.
* PC7 - Normal input because there is an external resistor.
* PC13 - Push Pull output (SHUTDOWN)
*/
#define VAL_GPIOCCRL 0x44888888 /* PC7...PC0 */
#define VAL_GPIOCCRH 0x88388888 /* PC15...PC8 */
#define VAL_GPIOCODR 0xFFFFFFFF
/*
* Port D setup.
* Everything input with pull-up except:
* PD3 - Push Pull output (USB_DISCONNECT)
*/
#define VAL_GPIODCRL 0x88883888 /* PD7...PD0 */
#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
#define VAL_GPIODODR 0xFFFFFFFF
/*
* Port E setup.
* Everything input with pull-up except:
* PE0 - Push Pull output (LED0).
* PD1 - Push Pull output (LED1).
*/
#define VAL_GPIOECRL 0x88888833 /* PE7...PE0 */
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
#define VAL_GPIOEODR 0xFFFFFFFF
#if 0
/*
* Port F setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOFCRL 0x88888888 /* PF7...PF0 */
#define VAL_GPIOFCRH 0x88888888 /* PF15...PF8 */
#define VAL_GPIOFODR 0xFFFFFFFF
/*
* Port G setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOGCRL 0x88888888 /* PG7...PG0 */
#define VAL_GPIOGCRH 0x88888888 /* PG15...PG8 */
#define VAL_GPIOGODR 0xFFFFFFFF
#endif
#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
void boardInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _FROM_ASM_ */
#endif /* _BOARD_H_ */

View File

@@ -1,14 +0,0 @@
/*
* HAL driver system settings.
*/
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV2
#define STM32_PLLMUL_VALUE 12
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PPRE2 STM32_PPRE2_DIV1
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK
#include "mcuconf-common.h"

View File

@@ -1,69 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
#include "ch.h"
#include "hal.h"
#include "config.h"
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
* This variable is used by the HAL when initializing the PAL driver.
*/
#if HAL_USE_PAL || defined(__DOXYGEN__)
const PALConfig pal_default_config =
{
{VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
{VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
{VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH},
{VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH},
{VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH},
#if defined(STM32F10X_HD)
{VAL_GPIOFODR, VAL_GPIOFCRL, VAL_GPIOFCRH},
{VAL_GPIOGODR, VAL_GPIOGCRL, VAL_GPIOGCRH},
#endif
};
#endif
/*
* Early initialization code.
* This initialization must be performed just after stack setup and before
* any other initialization.
*/
void
__early_init(void)
{
stm32_clock_init();
}
const uint8_t *
unique_device_id (void)
{
/* STM32F103 has 96-bit unique device identifier */
const uint8_t *addr = (const uint8_t *)0x1ffff7e8;
return addr;
}

View File

@@ -1,116 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/*
* STM32 drivers configuration.
* The following settings override the default settings present in
* the various device driver implementation headers.
* Note that the settings for each driver only have effect if the driver
* is enabled in halconf.h.
*
* IRQ priorities:
* 15...0 Lowest...Highest.
*
* DMA priorities:
* 0...3 Lowest...Highest.
*/
/*
* HAL driver system settings.
*/
#define STM32_NO_INIT FALSE
#define STM32_HSI_ENABLED TRUE
#define STM32_LSI_ENABLED FALSE
#define STM32_HSE_ENABLED TRUE
#define STM32_LSE_ENABLED FALSE
#define STM32_USB_CLOCK_REQUIRED TRUE
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
#define STM32_PVD_ENABLE FALSE
#define STM32_PLS STM32_PLS_LEV0
/*
* ADC driver system settings.
*/
#define USE_STM32_ADC1 TRUE
#define STM32_ADC1_DMA_PRIORITY 3
#define STM32_ADC1_IRQ_PRIORITY 5
#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
/*
* CAN driver system settings.
*/
#define USE_STM32_CAN1 FALSE
#define STM32_CAN1_IRQ_PRIORITY 11
/*
* PWM driver system settings.
*/
#define USE_STM32_PWM1 FALSE
#define USE_STM32_PWM2 FALSE
#define USE_STM32_PWM3 FALSE
#define USE_STM32_PWM4 FALSE
#define STM32_PWM1_IRQ_PRIORITY 7
#define STM32_PWM2_IRQ_PRIORITY 7
#define STM32_PWM3_IRQ_PRIORITY 7
#define STM32_PWM4_IRQ_PRIORITY 7
/*
* SERIAL driver system settings.
*/
#define USE_STM32_USART1 FALSE
#define USE_STM32_USART2 FALSE
#define USE_STM32_USART3 FALSE
#if defined(STM32F10X_HD) || defined(STM32F10X_CL)
#define USE_STM32_UART4 FALSE
#define USE_STM32_UART5 FALSE
#endif
#define STM32_USART1_PRIORITY 12
#define STM32_USART2_PRIORITY 12
#define STM32_USART3_PRIORITY 12
#if defined(STM32F10X_HD) || defined(STM32F10X_CL)
#define STM32_UART4_PRIORITY 12
#define STM32_UART5_PRIORITY 12
#endif
/*
* SPI driver system settings.
*/
#define USE_STM32_SPI1 FALSE
#define USE_STM32_SPI2 FALSE
#define STM32_SPI1_DMA_PRIORITY 2
#define STM32_SPI2_DMA_PRIORITY 2
#define STM32_SPI1_IRQ_PRIORITY 10
#define STM32_SPI2_IRQ_PRIORITY 10
#define STM32_SPI1_DMA_ERROR_HOOK() chSysHalt()
/*
* USB driver system settings.
*/
#define STM32_USB_USE_USB1 TRUE
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
#define STM32_USB_USB1_HP_IRQ_PRIORITY 6
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14

Submodule chopstx updated: 23893d9b73...bdaae5661d

View File

@@ -1,8 +1,8 @@
==========================
GnuPG settings for GNOME 3
==========================
===========================================
GnuPG settings for GNOME 3.1x and GNOME 3.0
===========================================
In the article `GnuPG settings`_, I wrote how I disable GNOME-keyrings for SSH.
In the section `GnuPG settings`_, I wrote how I disable GNOME-keyrings for SSH.
It was for GNOME 2. The old days was good, we just disabled GNOME-keyrings
interference to SSH and customizing our desktop was easy for GNU and UNIX users.
@@ -10,29 +10,33 @@ interference to SSH and customizing our desktop was easy for GNU and UNIX users.
.. _GnuPG settings: gpg-settings
GNOME keyrings in GNOME 3
=========================
GNOME keyrings in GNOME 3.1x
============================
It seems that it is more integrated into the desktop.
It is difficult to kill it. It would be possible to kill it simply,
but then, I can't use, say, wi-fi access (which needs to access "secrets")
any more.
In the files /etc/xdg/autostart/gnome-keyring-ssh.desktop
and /etc/xdg/autostart/gnome-keyring-gpg.desktop,
we have a line something like: ::
We can't use GNOME configuration tool to disable interference by
GNOME keyrings any more. It seems that desktop should not have
customization these days.
OnlyShowIn=GNOME;Unity;MATE;
Please edit this line to: ::
OnlyShowIn=
Then, no desktop environment invokes gnome-keyring for ssh and gpg. I think that it is The Right Thing.
GNOME-SESSION-PROPERTIES
========================
GNOME keyrings in GNOME 3.0 by GNOME-SESSION-PROPERTIES
=======================================================
After struggling some hours, I figured out it is GNOME-SESSION-PROPERTIES
to disable the interference. Invoking::
We can't use GNOME configuration tool (like GNOME 2) to disable interference by
GNOME keyrings in GNOME 3.0.
It is GNOME-SESSION-PROPERTIES to disable the interference. Invoking::
$ gnome-session-properties
and at the tab of "Startup Programs", I removed radio check buttons
for "GPG Password Agent" and "SSH Key Agent".
Now, I use gpg-agent for GnuPG Agent and SSH agent with Gnuk Token.
Then, I can use proper gpg-agent for GnuPG Agent Service and SSH Agent Service with Gnuk Token in GNOME 3.0.

View File

@@ -5,174 +5,14 @@ Key import from PC to Gnuk Token (no removal)
This document describes how I put my **keys on PC** to the Token
without removing keys from PC.
The difference is just not-to-save changes after key imports.
The difference is only the last step.
I don't save changes on PC after keytocard.
After personalization, I put my keys into the Token.
For the steps before the last step, please see `keytocard with removing keys on PC`_.
Here is the log.
.. _keytocard removing keys: gnuk-keytocard
I invoke GnuPG with my key (4ca7babe) and with ``--homedir`` option
to specify the directory which contains my secret keys. ::
$ gpg --homedir=/home/gniibe/tmp/gnuk-testing-dir --edit-key 4ca7babe
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
trust: ultimate validity: ultimate
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
Then, GnuPG enters its own command interaction mode. The prompt is ``gpg>``.
To enable ``keytocard`` command, I type ``toggle`` command. ::
gpg> toggle
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
ssb 2048R/084239CF created: 2010-10-15 expires: never
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
(1) NIIBE Yutaka <gniibe@fsij.org>
Firstly, I import my primary key into Gnuk Token.
I type ``keytocard`` command, answer ``y`` to confirm keyimport,
and type ``1`` to say it's signature key. ::
gpg> keytocard
Really move the primary key? (y/N) y
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
Then, GnuPG asks two passwords. One is the passphrase of **keys on PC**
and another is the password of **Gnuk Token**. Note that the password of
the token and the password of the keys on PC are different things,
although they can be same.
Here, I assume that Gnuk Token's admin password of factory setting (12345678).
I enter these passwords. ::
You need a passphrase to unlock the secret key for
user: "NIIBE Yutaka <gniibe@fsij.org>"
2048-bit RSA key, ID 4CA7BABE, created 2010-10-15
<PASSWORD-KEY-4CA7BABE>
gpg: writing new key
gpg: 3 Admin PIN attempts remaining before card is permanently locked
Please enter the Admin PIN
Enter Admin PIN: 12345678
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
card-no: F517 00000001
ssb 2048R/084239CF created: 2010-10-15 expires: never
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
(1) NIIBE Yutaka <gniibe@fsij.org>
The primary key is now on the Token and GnuPG says its card-no (F517 00000001),
where F517 is the vendor ID of FSIJ.
Secondly, I import my subkey of encryption. I select key number '1'. ::
gpg> key 1
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
card-no: F517 00000001
ssb* 2048R/084239CF created: 2010-10-15 expires: never
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
(1) NIIBE Yutaka <gniibe@fsij.org>
You can see that the subkey is marked by '*'.
I type ``keytocard`` command to import this subkey to Gnuk Token.
I select ``2`` as it's encryption key. ::
gpg> keytocard
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
Please select where to store the key:
(2) Encryption key
Your selection? 2
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
You need a passphrase to unlock the secret key for
user: "NIIBE Yutaka <gniibe@fsij.org>"
2048-bit RSA key, ID 084239CF, created 2010-10-15
<PASSWORD-KEY-4CA7BABE>
gpg: writing new key
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
card-no: F517 00000001
ssb* 2048R/084239CF created: 2010-10-15 expires: never
card-no: F517 00000001
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
(1) NIIBE Yutaka <gniibe@fsij.org>
The sub key is now on the Token and GnuPG says its card-no for it.
I type ``key 1`` to deselect key number '1'. ::
gpg> key 1
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
card-no: F517 00000001
ssb 2048R/084239CF created: 2010-10-15 expires: never
card-no: F517 00000001
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
(1) NIIBE Yutaka <gniibe@fsij.org>
Thirdly, I select sub key of authentication which has key number '2'. ::
gpg> key 2
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
card-no: F517 00000001
ssb 2048R/084239CF created: 2010-10-15 expires: never
card-no: F517 00000001
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
(1) NIIBE Yutaka <gniibe@fsij.org>
You can see that the subkey number '2' is marked by '*'.
I type ``keytocard`` command to import this subkey to Gnuk Token.
I select ``3`` as it's authentication key. ::
gpg> keytocard
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
Please select where to store the key:
(3) Authentication key
Your selection? 3
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
You need a passphrase to unlock the secret key for
user: "NIIBE Yutaka <gniibe@fsij.org>"
2048-bit RSA key, ID 5BB065DC, created 2010-10-22
<PASSWORD-KEY-4CA7BABE>
gpg: writing new key
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
card-no: F517 00000001
ssb 2048R/084239CF created: 2010-10-15 expires: never
card-no: F517 00000001
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
card-no: F517 00000001
(1) NIIBE Yutaka <gniibe@fsij.org>
The sub key is now on the Token and GnuPG says its card-no for it.
Here is the session log of the last step.
Lastly, I quit GnuPG. Note that I **don't** save changes. ::

View File

@@ -22,7 +22,7 @@ See `another document`_ to import keys to the Token from copied directory.
After personalization, I put my keys into the Token.
Here is the log.
Here is the session log.
I invoke GnuPG with my key (4ca7babe). ::

View File

@@ -31,7 +31,7 @@ For GnuPG 2.0.x, gpg-agent is always used, so there is no need to specify the ``
Let gpg-agent manage SSH key
============================
I deactivate seahose-agent. Also, for GNOME 2, I deactivate gnome-keyring managing SSH key. ::
I deactivate seahorse-agent. Also, for GNOME 2, I deactivate gnome-keyring managing SSH key. ::
$ gconftool-2 --type bool --set /apps/gnome-keyring/daemon-components/ssh false

View File

@@ -48,9 +48,9 @@ I have three keys in my token.
With the script below, I extract public key of the keygrip
5D6C89682D07CCFC034AF508420BF2276D8018ED into the file: 5D6C8968.bin::
$ ./get_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
$ ./get_raw_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
Here is the script, get_public_key.py::
Here is the script, get_raw_public_key.py::
#! /usr/bin/python

220
misc/debug-bn.c Normal file
View File

@@ -0,0 +1,220 @@
/*
* debug-bn.c - Debug Bignum
* Copyright (C) 2014 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "bn.h"
void
print_le_bn256 (const bn256 *X)
{
int i;
const uint8_t *p = (const uint8_t *)X;
for (i = 0; i < 32; i++)
printf ("%02x", p[i]);
puts ("");
}
void
print_be_bn256 (const bn256 *X)
{
int i;
for (i = 7; i >= 0; i--)
printf ("%08x", X->word[i]);
puts ("");
}
#define MAXLINE 4096
static int lineno;
static int test_no;
static bn256 sk[1];
static bn256 pk[1];
static unsigned char msg[MAXLINE];
static size_t msglen;
static bn512 sig[1];
const char *
skip_white_space (const char *l)
{
while (*l != '\n' && isspace (*l))
l++;
return l;
}
static int
read_hex_4bit (char c)
{
int r;
if (c >= '0' && c <= '9')
r = c - '0';
else if (c >= 'a' && c <= 'f')
r = c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
r = c - 'A' + 10;
else
r = -1;
return r;
}
static int
read_hex_8bit (const char **l_p)
{
const char *l = *l_p;
int r, v;
r = read_hex_4bit (*l++);
if (r < 0)
return -1;
v = r*16;
r = read_hex_4bit (*l++);
if (r < 0)
return -1;
v += r;
*l_p = l;
return v;
}
static int
read_msg (unsigned char *msg, const char *l, int len)
{
int i, r;
for (i = 0; i < len; i++)
{
r = read_hex_8bit (&l);
if (r < 0)
return -1;
msg[i] = r;
}
return 0;
}
static int
read_le_bn256 (bn256 *sk, const char *l)
{
int i;
uint8_t *p = (uint8_t *)sk;
for (i = 0; i < sizeof (bn256); i++)
{
int r;
if (*l == '\n')
{
/* should support small input??? */
return -1;
}
r = read_hex_8bit (&l);
if (r < 0)
return -1;
p[i] = r;
}
return 0;
}
static int
read_be_bn256 (bn256 *sk, const char *l)
{
int i;
uint8_t *p = (uint8_t *)sk;
for (i = 0; i < sizeof (bn256); i++)
{
int r;
if (*l == '\n')
{
/* should support small input??? */
return -1;
}
r = read_hex_8bit (&l);
if (r < 0)
return -1;
p[31 - i] = r;
}
return 0;
}
static int
read_pk (bn256 *pk, const char *l, int len)
{
int r;
if (len == 64) /* 64 chars == 32-byte */
{ /* compressed form */
r = read_le_bn256 (pk, l);
if (r < 0)
return -1;
return 0;
}
else
{
bn256 x[1];
r = read_hex_8bit (&l);
if (r < 0)
return -1;
if (r != 4)
return -1;
r = read_be_bn256 (x, l);
if (r < 0)
return -1;
r = read_be_bn256 (pk, l+64);
if (r < 0)
return -1;
pk->word[7] ^= (x->word[0] & 1) * 0x80000000;
return 0;
}
}
static int
read_le_bn512 (bn512 *sig, const char *l)
{
int i;
uint8_t *p = (uint8_t *)sig;
for (i = 0; i < sizeof (bn512); i++)
{
int r;
if (*l == '\n')
{
/* should support small input??? */
return -1;
}
r = read_hex_8bit (&l);
if (r < 0)
return -1;
p[i] = r;
}
return 0;
}

92
misc/t-mont.c Normal file
View File

@@ -0,0 +1,92 @@
/*
* t-eddsa.c - testing EdDSA
* Copyright (C) 2014 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* Run following commands. The file t-ed25519.inp is available in GNU
* libgcrypt source code under 'tests' directory.
gcc -Wall -c -DBN256_C_IMPLEMENTATION ecc-mont.c
gcc -Wall -c -DBN256_NO_RANDOM -DBN256_C_IMPLEMENTATION bn.c
gcc -Wall -c mod.c
gcc -Wall -c -DBN256_C_IMPLEMENTATION mod25638.c
gcc -Wall -c t-mont.c
gcc -Wall -c debug-bn.c
gcc -o t-mont t-mont.o ecc-mont.o bn.o mod.o mod25638.o debug-bn.o
*
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "bn.h"
const uint8_t k[32] = {
0x30, 0x01, 0x33, 0xE7, 0xDC, 0x52, 0xAD, 0x9F,
0x89, 0xFE, 0xC0, 0x59, 0x4A, 0x6D, 0x65, 0xE5,
0xF8, 0x7A, 0xD6, 0xA9, 0xA4, 0x89, 0x00, 0xB1,
0x93, 0x7E, 0xD3, 0x6F, 0x09, 0x1E, 0xB7, 0x76,
};
int
main (int argc, char *argv[])
{
int all_good = 1;
int r;
bn256 *pk;
bn256 a[1];
uint8_t out[32];
extern void ecdh_decrypt_curve25519 (const uint8_t *input,
uint8_t *output,
const bn256 *k);
extern uint8_t *ecdh_compute_public_25519 (const uint8_t*k);
extern void print_le_bn256 (const bn256 *X);
while (1)
{
#if 0
hash[0] &= 248;
hash[31] &= 127;
hash[31] |= 64;
memcpy (a, hash, sizeof (bn256)); /* Lower half of hash */
#endif
pk = ecdh_compute_public_25519 (k);
print_le_bn256 (pk);
return 0;
#if 0
if (memcmp (pk, pk_calculated, sizeof (bn256)) != 0)
{
printf ("ERR PK: %d\n", test_no);
print_be_bn256 (sk);
print_be_bn256 (pk);
print_be_bn256 (pk_calculated);
all_good = 0;
continue;
}
ecdh_decrypt_25519 (msg, out, a);
if (memcmp (sig, R, sizeof (bn256)) != 0
|| memcmp (((const uint8_t *)sig)+32, S, sizeof (bn256)) != 0)
{
printf ("ERR SIG: %d\n", test_no);
print_le_bn256 (R);
print_le_bn256 (S);
print_le_bn256 ((const bn256 *)sig);
print_le_bn256 ((const bn256 *)(((const uint8_t *)sig)+32));
all_good = 0;
continue;
}
printf ("%d\n", test_no);
#endif
}
return all_good == 1?0:1;
}

View File

@@ -209,9 +209,7 @@
*
* Enable the RSA prime-number generation code.
*/
#ifdef KEYGEN_SUPPORT
#define POLARSSL_GENPRIME
#endif
/**
* \def POLARSSL_FS_IO

View File

@@ -250,9 +250,10 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
int
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
uint16_t index)
uint16_t index, uint16_t length)
{
(void)index;
(void)length;
if (rcp != DEVICE_RECIPIENT)
return USB_UNSUPPORT;

View File

@@ -15,7 +15,7 @@ CSRC = main.c usb_stm32f103.c adc_stm32f103.c \
bn.c mod.c \
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
mod25638.c ecc-edwards.c sha512.c \
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
random.c neug.c sha256.c sys.c
INCDIR =
@@ -55,7 +55,7 @@ OBJCOPY = $(CROSS)objcopy
MCU = cortex-m3
CWARN = -Wall -Wextra -Wstrict-prototypes
# DEFS: Add
DEFS = -DCHX_PRIO_MAIN=5 @KEYGEN_SUPPORT@ @HAVE_SYS_H@
DEFS = @HAVE_SYS_H@
OPT = -O3 -Os -g
LIBS =

View File

@@ -3,7 +3,8 @@
* In this ADC driver, there are NeuG specific parts.
* You need to modify to use this as generic ADC driver.
*
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
* Copyright (C) 2011, 2012, 2013, 2015
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of NeuG, a True Random Number Generator
@@ -92,15 +93,6 @@
| ADC_SQR3_SQ4_N(ADC_CHANNEL_VREFINT)
#define NEUG_ADC_SETTING1_NUM_CHANNELS 4
#if !defined(NEUG_ADC_SETTING2_SMPR1)
#define NEUG_ADC_SETTING2_SMPR1 0
#define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) \
| ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) \
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2
#endif
/*
* Do calibration for both of ADCs.
@@ -133,9 +125,67 @@ void adc_init (void)
RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
}
#include "sys.h"
#if defined(HAVE_SYS_H)
# define SYS_BOARD_ID sys_board_id
#else
# include "board.h"
# define SYS_BOARD_ID BOARD_ID
#endif
static void
get_adc_config (uint32_t config[4])
{
config[2] = ADC_SQR1_NUM_CH(2);
switch (SYS_BOARD_ID)
{
case BOARD_ID_FST_01:
config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
| ADC_SMPR2_SMP_AN9(ADC_SAMPLE_1P5);
config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN9);
break;
case BOARD_ID_OLIMEX_STM32_H103:
case BOARD_ID_STBEE:
config[0] = ADC_SMPR1_SMP_AN10(ADC_SAMPLE_1P5)
| ADC_SMPR1_SMP_AN11(ADC_SAMPLE_1P5);
config[1] = 0;
config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN10)
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN11);
break;
case BOARD_ID_STBEE_MINI:
config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
| ADC_SMPR2_SMP_AN2(ADC_SAMPLE_1P5);
config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN1)
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN2);
break;
case BOARD_ID_CQ_STARM:
case BOARD_ID_FST_01_00:
case BOARD_ID_MAPLE_MINI:
case BOARD_ID_STM32_PRIMER2:
case BOARD_ID_STM8S_DISCOVERY:
default:
config[0] = 0;
config[1] = ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)
| ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5);
config[3] = ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1);
break;
}
}
void adc_start (void)
{
uint32_t config[4];
get_adc_config (config);
/* Use DMA channel 1. */
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
@@ -156,11 +206,11 @@ void adc_start (void)
ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
| ADC_CR1_SCAN);
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC2->SMPR1 = NEUG_ADC_SETTING2_SMPR1;
ADC2->SMPR2 = NEUG_ADC_SETTING2_SMPR2;
ADC2->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING2_NUM_CHANNELS);
ADC2->SMPR1 = config[0];
ADC2->SMPR2 = config[1];
ADC2->SQR1 = config[2];
ADC2->SQR2 = 0;
ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
ADC2->SQR3 = config[3];
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
/*

View File

@@ -124,3 +124,20 @@ FUNC(ecdh_decrypt) (const uint8_t *input, uint8_t *output,
return r;
}
/**
* @brief Check if a secret d0 is valid or not
*
* @param D0 scalar D0: secret
* @param D1 scalar D1: secret candidate N-D0
*
* Return 0 on error.
* Return -1 when D1 should be used as the secret
* Return 1 when D0 should be used as the secret
*/
int
FUNC(ecc_check_secret) (const uint8_t *d0, uint8_t *d1)
{
return FUNC(check_secret) ((const bn256 *)d0, (bn256 *)d1);
}

View File

@@ -83,7 +83,6 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
}
else
{
res_APDU_size = pubkey_len;
DEBUG_INFO ("done.\r\n");
GPG_SUCCESS ();
return 0;
@@ -120,14 +119,13 @@ modulus_calc (const uint8_t *p, int len)
int
rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
struct key_data *kd)
struct key_data *kd, unsigned int *output_len_p)
{
mpi P1, Q1, H;
int ret;
unsigned int output_len;
DEBUG_INFO ("RSA decrypt:");
DEBUG_WORD ((uint32_t)&output_len);
DEBUG_WORD ((uint32_t)&ret);
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
mpi_init (&P1); mpi_init (&Q1); mpi_init (&H);
@@ -154,7 +152,7 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
{
DEBUG_INFO ("RSA decrypt ...");
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
RSA_PRIVATE, &output_len, input,
RSA_PRIVATE, output_len_p, input,
output, MAX_RES_APDU_DATA_SIZE);
}
@@ -167,7 +165,6 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
}
else
{
res_APDU_size = output_len;
DEBUG_INFO ("done.\r\n");
GPG_SUCCESS ();
return 0;
@@ -207,7 +204,6 @@ rsa_verify (const uint8_t *pubkey, int pubkey_len,
#define RSA_EXPONENT 0x10001
#ifdef KEYGEN_SUPPORT
uint8_t *
rsa_genkey (int pubkey_len)
{
@@ -248,4 +244,3 @@ rsa_genkey (int pubkey_len)
else
return p_q_modulus;
}
#endif

View File

@@ -7,4 +7,4 @@
@PINPAD_MORE_DEFINE@
@CERTDO_DEFINE@
@HID_CARD_CHANGE_DEFINE@
@SERIALNO_STR_LEN@
@SERIALNO_STR_LEN_DEFINE@

169
src/configure vendored
View File

@@ -3,7 +3,7 @@
#
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
#
# Copyright (C) 2010, 2011, 2012, 2013, 2014
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
# Free Software Initiative of Japan
#
# This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -27,12 +27,18 @@ target=FST_01
verbose=no
with_dfu=default
debug=no
sys1_compat=yes
pinpad=no
certdo=no
keygen=no
sys1_compat=yes
hid_card_change=no
# Revision number
if test -d ../.git; then
REVISION=`git describe --dirty="-modified"`
else
REVISION=`cat ../VERSION`
fi
# Process each option
for option; do
case $option in
@@ -61,18 +67,14 @@ for option; do
certdo=yes ;;
--disable-certdo)
certdo=no ;;
--enable-keygen)
keygen=yes ;;
--disable-keygen)
keygen=no ;;
--enable-sys1-compat)
sys1_compat = yes ;;
--disable-sys1-compat)
sys1_compat = no ;;
--enable-hid-card-change)
hid_card_change = yes ;;
hid_card_change=yes ;;
--disable-hid-card-change)
hid_card_change = no ;;
hid_card_change=no ;;
--enable-sys1-compat)
sys1_compat=yes ;;
--disable-sys1-compat)
sys1_compat=no ;;
--with-dfu)
with_dfu=yes ;;
--without-dfu)
@@ -98,14 +100,16 @@ Configuration:
supported targets are:
FST_01
OLIMEX_STM32_H103
STM32_PRIMER2
STBEE
STBEE_MINI
MAPLE_MINI
CQ_STARM
FST_01_00 (unreleased version with 8MHz XTAL)
--enable-debug debug with virtual COM port [no]
--enable-pinpad=cir
PIN entry support [no]
--enable-certdo support CERT.3 data object [no]
--enable-keygen support key generation [no]
--enable-sys1-compat enable SYS 1.0 compatibility [yes]
executable is target dependent
--disable-sys1-compat disable SYS 1.0 compatibility [no]
@@ -121,14 +125,13 @@ if test "$vidpid" = "none"; then
exit 1
fi
TARGET_DEFINE="#define BOARD_$target 1"
BOARD_HEADER_FILE=board-`echo $target | tr '_[:upper:]' '-[:lower:]'`.h
echo Header file is: $BOARD_HEADER_FILE
ln -sf ../chopstx/board/$BOARD_HEADER_FILE board.h
# Flash page size in byte
FLASH_PAGE_SIZE=1024
# Flash memory size in KB
# Flash memory size in KiB
FLASH_SIZE=128
# Memory size in KiB
MEMORY_SIZE=20
@@ -172,7 +175,7 @@ fi
# --with-dfu option
if test "$with_dfu" = "yes"; then
if test "$target" = "FST_01" -o "$target" = "FST_01_00"; then
echo "FST-01 doesn't have DFU loader, you should not enable this."
echo "FST-01 doesn't have DFU loader, you should not use --with-dfu."
exit 1
fi
echo "Configured for DFU"
@@ -219,15 +222,6 @@ else
echo "CERT.3 Data Object is NOT supported"
fi
# --enable-keygen option
if test "$keygen" = "yes"; then
KEYGEN_SUPPORT="-DKEYGEN_SUPPORT"
echo "Key generation on device is supported"
else
KEYGEN_SUPPORT=""
echo "Key generation on device is NOT supported"
fi
# --enable-hid-card-change option
if test "$hid_card_change" = "yes"; then
HID_CARD_CHANGE_DEFINE="#define HID_CARD_CHANGE_SUPPORT 1"
@@ -237,65 +231,82 @@ else
echo "Card insert/removal by HID device is NOT supported"
fi
if test -d ../.git; then
REVISION=`git describe --dirty="-modified"`
else
REVISION=`cat ../VERSION`
fi
### !!! Replace following string of "FSIJ" to yours !!! ####
SERIALNO="FSIJ-`cat ../VERSION | sed -e 's%^[^/]*/%%'`-"
SERIALNO_STR_LEN_DEFINE="#define SERIALNO_STR_LEN ${#SERIALNO}"
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo:keygen=$keygen"
if test "$sys1_compat" = "yes"; then
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo"
else
if test "$with_dfu" = "yes"; then
echo "Common binary can't support DFU loader, don't use --with-dfu."
exit 1
fi
# Override settings for common binary. Safer side.
FLASH_PAGE_SIZE=2048
FLASH_SIZE=128
MEMORY_SIZE=20
CONFIG="common:debug=$debug:pinpad=$pinpad:certdo=$certdo"
fi
output_vid_pid_version () {
echo $VIDPID | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\n 0x\4, 0x\3, /* idProduct */%p"
echo $VERSION | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
}
output_vendor_product_serial_strings () {
prefix=$1
echo "static const uint8_t ${prefix}string_vendor[] = {"
echo " ${#VENDOR}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Manufacturer: \"$VENDOR\" */"
echo $VENDOR | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo
echo "static const uint8_t ${prefix}string_product[] = {"
echo " ${#PRODUCT}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Product name: \"$PRODUCT\" */"
echo $PRODUCT | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
if test -n "$prefix"; then
echo
echo "uint8_t ${prefix}string_serial[] = {"
echo " ${#SERIALNO}*2+2+16, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Serial number: \"$SERIALNO\" */"
echo $SERIALNO | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
echo '};'
echo
echo '#ifdef USB_STRINGS_FOR_GNUK'
echo "static const uint8_t ${prefix}revision_detail[] = {"
echo " ${#REVISION}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* revision detail: \"$REVISION\" */"
echo $REVISION | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo
echo "static const uint8_t ${prefix}config_options[] = {"
echo " ${#CONFIG}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* configure options: \"$CONFIG\" */"
echo $CONFIG | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo '#endif'
fi
}
if !(IFS=" "
while read VIDPID VERSION PRODUCT VENDOR; do
if test "$vidpid" = "$VIDPID"; then
(echo $VIDPID | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\n 0x\4, 0x\3, /* idProduct */%p"
echo $VERSION | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
) > usb-vid-pid-ver.c.inc
(echo 'static const uint8_t gnukStringVendor[] = {'
echo " ${#VENDOR}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Manufacturer: \"$VENDOR\" */"
echo $VENDOR | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo
echo 'static const uint8_t gnukStringProduct[] = {'
echo " ${#PRODUCT}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Product name: \"$PRODUCT\" */"
echo $PRODUCT | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo
echo 'const uint8_t gnukStringSerial[] = {'
echo " ${#SERIALNO}*2+2+16, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Serial number: \"$SERIALNO\" */"
echo $SERIALNO | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
echo '};'
echo
echo '#ifdef USB_STRINGS_FOR_GNUK'
echo 'static const uint8_t gnuk_revision_detail[] = {'
echo " ${#REVISION}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* revision detail: \"$REVISION\" */"
echo $REVISION | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo
echo 'static const uint8_t gnuk_config_options[] = {'
echo " ${#CONFIG}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* configure options: \"$CONFIG\" */"
echo $CONFIG | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo '#endif'
) >usb-strings.c.inc
output_vid_pid_version > usb-vid-pid-ver.c.inc
output_vendor_product_serial_strings gnuk_ >usb-strings.c.inc
exit 0
fi
done; exit 1) < ../GNUK_USB_DEVICE_ID
@@ -306,8 +317,8 @@ then
fi
if test "$sys1_compat" = "no"; then
# Disable when you are sure that it's sys version 2.0.
# Note that Gnuk 1.0 and Neug (until 0.06) uses sys version 1.0.
# Disable when you are sure that it's sys version 2.1.
# Note that Gnuk 1.0 and NeuG (until 0.06) uses sys version 1.0.
# Disabling the compatibility, executable will be target independent,
# assuming the clock initialization will be done by SYS (before entry).
have_sys_h="-DHAVE_SYS_H"
@@ -315,10 +326,10 @@ else
have_sys_h=""
fi
sed -e "s%@HAVE_SYS_H@%$have_sys_h%" \
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
-e "s%@KEYGEN_SUPPORT@%$KEYGEN_SUPPORT%" \
-e "s%@HEXOUTPUT_MAKE_OPTION@%$HEXOUTPUT_MAKE_OPTION%" \
< Makefile.in > Makefile
if test "$certdo" = "yes"; then
@@ -346,6 +357,6 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
-e "s/@CERTDO_DEFINE@/$CERTDO_DEFINE/" \
-e "s/@HID_CARD_CHANGE_DEFINE@/$HID_CARD_CHANGE_DEFINE/" \
-e "s/@SERIALNO_STR_LEN@/$SERIALNO_STR_LEN_DEFINE/" \
-e "s/@SERIALNO_STR_LEN_DEFINE@/$SERIALNO_STR_LEN_DEFINE/" \
< config.h.in > config.h
exit 0

View File

@@ -1,4 +1,4 @@
int compute_kP_p256k1 (ac *X, const bn256 *K, const ac *P);
int compute_kG_p256k1 (ac *X, const bn256 *K);
void ecdsa_p256k1 (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d);
int check_secret_p256k1 (const bn256 *q, bn256 *d1);

View File

@@ -1,5 +1,4 @@
int compute_kP_p256r1 (ac *X, const bn256 *K, const ac *P);
int compute_kG_p256r1 (ac *X, const bn256 *K);
void ecdsa_p256r1 (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d);
int check_secret_p256r1 (const bn256 *q, bn256 *d1);

View File

@@ -660,7 +660,7 @@ mod_reduce_M (bn256 *R, const bn512 *A)
}
void
int
eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *out,
const bn256 *a, const uint8_t *seed, const bn256 *pk)
{
@@ -704,6 +704,8 @@ eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *out,
bn256_add (s, s, M);
else
bn256_add (tmp, s, M);
return 0;
}
void

View File

@@ -2,7 +2,7 @@
* ecc-mont.c - Elliptic curve computation for
* the Montgomery curve: y^2 = x^3 + 486662*x^2 + x.
*
* Copyright (C) 2014 Free Software Initiative of Japan
* Copyright (C) 2014, 2015 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "bn.h"
#include "mod25638.h"
#include "mod.h"
@@ -78,6 +79,7 @@ mod25638_mul_121665 (bn256 *x, const bn256 *a)
s = a->word;
d = x->word;
memset (d, 0, sizeof (bn256));
w = 121665;
MULADD_256_ASM (s, d, w, c);
#else
@@ -143,7 +145,7 @@ mont_d_and_a (pt *prd, pt *sum, pt *q0, pt *q1, const bn256 *dif_x)
* @param Q_X x-coordinate of Q
*
*/
void
static void
compute_nQ (bn256 *res, const bn256 *n, const bn256 *q_x)
{
int i, j;
@@ -194,3 +196,37 @@ compute_nQ (bn256 *res, const bn256 *n, const bn256 *q_x)
mod25638_mul (res, res, p0->x);
mod25519_reduce (res);
}
uint8_t *
ecdh_compute_public_25519 (const uint8_t *key_data)
{
uint8_t *p;
bn256 gx[1];
bn256 k[1];
memset (gx, 0, sizeof (bn256));
gx[0].word[0] = 9; /* Gx = 9 */
memcpy (k, key_data, sizeof (bn256));
p = (uint8_t *)malloc (sizeof (bn256));
if (p == NULL)
return NULL;
compute_nQ ((bn256 *)p, k, gx);
return p;
}
int
ecdh_decrypt_curve25519 (const uint8_t *input, uint8_t *output,
const uint8_t *key_data)
{
bn256 q_x[1];
bn256 k[1];
bn256 shared[1];
memcpy (q_x, input, sizeof (bn256));
memcpy (k, key_data, sizeof (bn256));
compute_nQ (shared, k, q_x);
memcpy (output, shared, sizeof (bn256));
return 0;
}

View File

@@ -1,7 +1,8 @@
/* -*- coding: utf-8 -*-
* ecc.c - Elliptic curve over GF(prime)
*
* Copyright (C) 2011, 2013, 2014 Free Software Initiative of Japan
* Copyright (C) 2011, 2013, 2014, 2015
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -366,3 +367,32 @@ FUNC(ecdsa) (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d)
#undef tmp_k
#undef borrow
}
/**
* @brief Check if a secret d0 is valid or not
*
* @param D0 scalar D0: secret
* @param D1 scalar D1: secret candidate N-D0
*
* Return 0 on error.
* Return -1 when D1 should be used as the secret
* Return 1 when D0 should be used as the secret
*/
int
FUNC(check_secret) (const bn256 *d0, bn256 *d1)
{
ac Q0[1], Q1[1];
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) <= 0)
/* == 0 or >= N, it's not valid. */
return 0;
FUNC(compute_kG) (Q0, d0);
FUNC(compute_kG) (Q1, d1);
/*
* Jivsov compliant key check
*/
return bn256_cmp (Q1[0].y, Q0[0].y);
}

View File

@@ -1,7 +1,7 @@
/*
* flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -35,7 +35,6 @@
#include "config.h"
#include "board.h"
#include "sys.h"
#include "gnuk.h"
@@ -65,7 +64,9 @@
*/
#define FLASH_DATA_POOL_HEADER_SIZE 2
#define FLASH_DATA_POOL_SIZE (FLASH_PAGE_SIZE*2)
#define FLASH_DATA_POOL_SIZE (flash_page_size*2)
static uint16_t flash_page_size;
static const uint8_t *data_pool;
extern uint8_t _keystore_pool;
@@ -99,22 +100,30 @@ static int key_available_at (const uint8_t *k, int key_size)
return 1;
}
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
const uint8_t *
flash_init (void)
{
uint16_t gen0, gen1;
uint16_t *gen0_p = (uint16_t *)&_data_pool;
uint16_t *gen1_p = (uint16_t *)(&_data_pool + FLASH_PAGE_SIZE);
uint16_t *gen1_p;
flash_page_size = 1024;
if (((*CHIP_ID_REG) & 0xfff) == 0x0414)
flash_page_size = 2048;
gen1_p = (uint16_t *)(&_data_pool + flash_page_size);
/* Check data pool generation and choose the page */
gen0 = *gen0_p;
gen1 = *gen1_p;
if (gen0 == 0xffff)
data_pool = &_data_pool + FLASH_PAGE_SIZE;
data_pool = &_data_pool + flash_page_size;
else if (gen1 == 0xffff)
data_pool = &_data_pool;
else if (gen1 > gen0)
data_pool = &_data_pool + FLASH_PAGE_SIZE;
data_pool = &_data_pool + flash_page_size;
else
data_pool = &_data_pool;
@@ -135,7 +144,7 @@ flash_init_keys (void)
int key_size = gpg_get_algo_attr_key_size (i, GPG_KEY_STORAGE);
kd[i].pubkey = NULL;
for (k = p; k < p + FLASH_PAGE_SIZE; k += key_size)
for (k = p; k < p + flash_page_size; k += key_size)
if (key_available_at (k, key_size))
{
int prv_len = gpg_get_algo_attr_key_size (i, GPG_KEY_PRIVATE);
@@ -144,7 +153,7 @@ flash_init_keys (void)
break;
}
p += FLASH_PAGE_SIZE;
p += flash_page_size;
}
}
@@ -189,11 +198,11 @@ flash_copying_gc (void)
if (data_pool == &_data_pool)
{
src = &_data_pool;
dst = &_data_pool + FLASH_PAGE_SIZE;
dst = &_data_pool + flash_page_size;
}
else
{
src = &_data_pool + FLASH_PAGE_SIZE;
src = &_data_pool + flash_page_size;
dst = &_data_pool;
}
@@ -208,7 +217,7 @@ flash_copying_gc (void)
static int
is_data_pool_full (size_t size)
{
return last_p + size > data_pool + FLASH_PAGE_SIZE;
return last_p + size > data_pool + flash_page_size;
}
static uint8_t *
@@ -322,7 +331,7 @@ static uint8_t *
flash_key_getpage (enum kind_of_key kk)
{
/* There is a page for each KK. */
return &_keystore_pool + (FLASH_PAGE_SIZE * kk);
return &_keystore_pool + (flash_page_size * kk);
}
uint8_t *
@@ -333,7 +342,7 @@ flash_key_alloc (enum kind_of_key kk)
int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
/* Seek free space in the page. */
for (k = k0; k < k0 + FLASH_PAGE_SIZE; k += key_size)
for (k = k0; k < k0 + flash_page_size; k += key_size)
{
const uint32_t *p = (const uint32_t *)k;
@@ -382,10 +391,10 @@ flash_key_write (uint8_t *key_addr,
static int
flash_check_all_other_keys_released (const uint8_t *key_addr, int key_size)
{
uint32_t start = (uint32_t)key_addr & ~(FLASH_PAGE_SIZE - 1);
uint32_t start = (uint32_t)key_addr & ~(flash_page_size - 1);
const uint32_t *p = (const uint32_t *)start;
while (p < (const uint32_t *)(start + FLASH_PAGE_SIZE))
while (p < (const uint32_t *)(start + flash_page_size))
if (p == (const uint32_t *)key_addr)
p += key_size/4;
else
@@ -411,7 +420,7 @@ void
flash_key_release (uint8_t *key_addr, int key_size)
{
if (flash_check_all_other_keys_released (key_addr, key_size))
flash_erase_page (((uint32_t)key_addr & ~(FLASH_PAGE_SIZE - 1)));
flash_erase_page (((uint32_t)key_addr & ~(flash_page_size - 1)));
else
flash_key_fill_zero_as_released (key_addr, key_size);
}
@@ -619,9 +628,8 @@ flash_erase_binary (uint8_t file_id)
if (flash_check_blank (p, FLASH_CH_CERTIFICATE_SIZE) == 0)
{
flash_erase_page ((uint32_t)p);
#if FLASH_CH_CERTIFICATE_SIZE > FLASH_PAGE_SIZE
flash_erase_page ((uint32_t)p + FLASH_PAGE_SIZE);
#endif
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
flash_erase_page ((uint32_t)p + flash_page_size);
}
return 0;

View File

@@ -62,6 +62,8 @@ enum icc_state {
ICC_STATE_EXEC_REQUESTED, /* Exec requested */
};
#define CCID_CARD_INIT CARD_CHANGE_INSERT
extern enum icc_state *icc_state_p;
extern volatile uint8_t auth_status;
@@ -114,6 +116,7 @@ const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
#define ALGO_NISTP256R1 1
#define ALGO_SECP256K1 2
#define ALGO_ED25519 3
#define ALGO_CURVE25519 4
#define ALGO_RSA2K 255
enum kind_of_key {
@@ -256,19 +259,22 @@ void put_binary (const char *s, int len);
int rsa_sign (const uint8_t *, uint8_t *, int, struct key_data *, int);
uint8_t *modulus_calc (const uint8_t *, int);
int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *);
int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *,
unsigned int *);
int rsa_verify (const uint8_t *, int, const uint8_t *, const uint8_t *);
uint8_t *rsa_genkey (int);
int ecdsa_sign_p256r1 (const uint8_t *hash, uint8_t *output,
const uint8_t *key_data);
uint8_t *ecc_compute_public_p256r1 (const uint8_t *key_data);
int ecc_check_secret_p256r1 (const uint8_t *d0, uint8_t *d1);
int ecdh_decrypt_p256r1 (const uint8_t *input, uint8_t *output,
const uint8_t *key_data);
int ecdsa_sign_p256k1 (const uint8_t *hash, uint8_t *output,
const uint8_t *key_data);
uint8_t *ecc_compute_public_p256k1 (const uint8_t *key_data);
int ecc_check_secret_p256k1 (const uint8_t *d0, uint8_t *d1);
int ecdh_decrypt_p256k1 (const uint8_t *input, uint8_t *output,
const uint8_t *key_data);
@@ -276,6 +282,9 @@ int eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *output,
const uint8_t *sk_a, const uint8_t *seed,
const uint8_t *pk);
uint8_t *eddsa_compute_public_25519 (const uint8_t *a);
uint8_t *ecdh_compute_public_25519 (const uint8_t *a);
int ecdh_decrypt_curve25519 (const uint8_t *input, uint8_t *output,
const uint8_t *key_data);
const uint8_t *gpg_do_read_simple (uint8_t);
void gpg_do_write_simple (uint8_t, const uint8_t *, int);
@@ -406,7 +415,7 @@ void flash_cnt123_write_internal (const uint8_t *p, int which, int v);
void flash_do_write_internal (const uint8_t *p, int nr,
const uint8_t *data, int len);
extern const uint8_t gnukStringSerial[];
extern const uint8_t gnuk_string_serial[];
#define LED_ONESHOT (1)
#define LED_TWOSHOTS (2)

View File

@@ -18,10 +18,6 @@ MEMORY
ram : org = 0x20000000, len = @MEMORY_SIZE@k
}
/* __flash_start__: flash ROM start address regardless of DFU_SUPPORT */
__flash_start__ = 0x08001000;
__flash_end__ = ORIGIN(flash) + LENGTH(flash);
__ram_start__ = ORIGIN(ram);
__ram_size__ = LENGTH(ram);
__ram_end__ = __ram_start__ + __ram_size__;
@@ -32,18 +28,20 @@ SECTIONS
.sys : ALIGN(4) SUBALIGN(4)
{
_sys = .;
KEEP(*(.vectors))
. = ALIGN(16);
*(.sys.version)
build/sys.o(.text)
build/sys.o(.text.*)
build/sys.o(.rodata)
build/sys.o(.rodata.*)
. = ALIGN(1024);
*(.sys.0)
*(.sys.1)
*(.sys.2)
_sys = .;
KEEP(*(.vectors))
. = ALIGN(16);
KEEP(*(.sys.version))
KEEP(*(.sys.board_id))
KEEP(*(.sys.board_name))
build/sys.o(.text)
build/sys.o(.text.*)
build/sys.o(.rodata)
build/sys.o(.rodata.*)
. = ALIGN(1024);
*(.sys.0)
*(.sys.1)
*(.sys.2)
} > flash0
_text = .;
@@ -64,6 +62,7 @@ SECTIONS
*(.glue_7t)
*(.glue_7)
*(.gcc*)
. = ALIGN(8);
} > flash
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash

View File

@@ -1,7 +1,8 @@
/*
* main.c - main routine of Gnuk
*
* Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
* Copyright (C) 2010, 2011, 2012, 2013, 2015
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -27,7 +28,6 @@
#include <eventflag.h>
#include "config.h"
#include "board.h"
#include "sys.h"
#include "adc.h"
@@ -126,7 +126,7 @@ extern void *USBthread (void *arg);
static void
device_initialize_once (void)
{
const uint8_t *p = &gnukStringSerial[ID_OFFSET];
const uint8_t *p = &gnuk_string_serial[ID_OFFSET];
if (p[0] == 0xff && p[1] == 0xff && p[2] == 0xff && p[3] == 0xff)
{
@@ -134,12 +134,12 @@ device_initialize_once (void)
* This is the first time invocation.
* Setup serial number by unique device ID.
*/
const uint8_t *u = unique_device_id ();
const uint8_t *u = unique_device_id () + 8;
int i;
for (i = 0; i < 4; i++)
{
uint8_t b = u[i];
uint8_t b = u[3-i];
uint8_t nibble;
nibble = (b >> 4);
@@ -290,6 +290,7 @@ const size_t __stacksize_usb = (size_t)&__process4_stack_size__;
#define PRIO_CCID 3
#define PRIO_USB 4
#define PRIO_MAIN 5
extern void *usb_intr (void *arg);
@@ -343,6 +344,8 @@ main (int argc, char *argv[])
usb_thd = chopstx_create (PRIO_USB, __stackaddr_usb, __stacksize_usb,
usb_intr, NULL);
chopstx_main_init (PRIO_MAIN);
while (1)
{
if (bDeviceState != UNCONNECTED)
@@ -422,15 +425,20 @@ main (int argc, char *argv[])
#ifdef DFU_SUPPORT
#define FLASH_SYS_START_ADDR 0x08000000
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
#define CHIP_ID_REG ((uint32_t *)0xE0042000)
{
extern uint8_t _sys;
uint32_t addr;
handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
uint32_t flash_page_size = 1024; /* 1KiB default */
if ((*CHIP_ID_ADDR)&0x07 == 0x04) /* High dencity device. */
flash_page_size = 2048; /* It's 2KiB. */
/* Kill DFU */
for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
addr += FLASH_PAGE_SIZE)
addr += flash_page_size)
flash_erase_page (addr);
/* copy system service routines */

View File

@@ -215,7 +215,7 @@ static int ep_process (int mode)
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR & 0xff;
v = CRC->DR & 0xff; /* First byte of CRC->DR is used here. */
noise_source_continuous_test (v);
sha256_ctx_data.wbuf[i] = v;
ep_init (NEUG_MODE_CONDITIONED); /* The rest three-byte of
@@ -280,8 +280,6 @@ uint16_t neug_rc_max;
uint16_t neug_p64_max;
uint16_t neug_p4k_max;
#include "board.h"
static void noise_source_cnt_max_reset (void)
{
neug_err_cnt = neug_err_cnt_rc = neug_err_cnt_p64 = neug_err_cnt_p4k = 0;

View File

@@ -3,9 +3,9 @@
#define NEUG_PRE_LOOP 32
#define NEUG_MODE_CONDITIONED 0
#define NEUG_MODE_RAW 1
#define NEUG_MODE_RAW_DATA 2
#define NEUG_MODE_CONDITIONED 0 /* Conditioned data. */
#define NEUG_MODE_RAW 1 /* CRC-32 filtered sample data. */
#define NEUG_MODE_RAW_DATA 2 /* Sample data directly. */
extern uint8_t neug_mode;
extern uint16_t neug_err_cnt;

View File

@@ -1,7 +1,7 @@
/*
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -170,6 +170,13 @@ static const uint8_t algorithm_attr_ed25519[] __attribute__ ((aligned (1))) = {
0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01
};
static const uint8_t algorithm_attr_cv25519[] __attribute__ ((aligned (1))) = {
11,
OPENPGP_ALGO_ECDH,
/* OID of the curve Curve25519 */
0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01
};
/*
* Representation of PW1_LIFETIME:
@@ -246,16 +253,21 @@ get_algo_attr_data_object (enum kind_of_key kk)
if (algo_attr_p == NULL)
return algorithm_attr_rsa2k;
if (algo_attr_p[1] == ALGO_RSA4K)
return algorithm_attr_rsa4k;
else if (algo_attr_p[1] == ALGO_NISTP256R1)
return algorithm_attr_p256r1;
else if (algo_attr_p[1] == ALGO_SECP256K1)
return algorithm_attr_p256k1;
else if (algo_attr_p[1] == ALGO_ED25519)
return algorithm_attr_ed25519;
return algorithm_attr_rsa2k;
switch (algo_attr_p[1])
{
case ALGO_RSA4K:
return algorithm_attr_rsa4k;
case ALGO_NISTP256R1:
return algorithm_attr_p256r1;
case ALGO_SECP256K1:
return algorithm_attr_p256k1;
case ALGO_ED25519:
return algorithm_attr_ed25519;
case ALGO_CURVE25519:
return algorithm_attr_cv25519;
default:
return algorithm_attr_rsa2k;
}
}
int
@@ -263,30 +275,43 @@ gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s)
{
const uint8_t *algo_attr_p = *get_algo_attr_pointer (kk);
if (algo_attr_p == NULL)
if (s == GPG_KEY_STORAGE)
return 512;
else
return 256;
else if (algo_attr_p[1] == ALGO_RSA4K)
if (s == GPG_KEY_STORAGE)
return 1024;
else
return 512;
else if (algo_attr_p[1] == ALGO_NISTP256R1 || algo_attr_p[1] == ALGO_SECP256K1)
if (s == GPG_KEY_STORAGE)
return 128;
else if (s == GPG_KEY_PUBLIC)
return 64;
else
return 32;
else /* ED25519 */
if (s == GPG_KEY_STORAGE)
return 128;
else if (s == GPG_KEY_PUBLIC)
return 32;
else
return 64;
if (algo_attr_p == NULL) /* RSA-2048 */
goto rsa2k;
switch (algo_attr_p[1])
{
case ALGO_RSA4K:
if (s == GPG_KEY_STORAGE)
return 1024;
else
return 512;
case ALGO_NISTP256R1:
case ALGO_SECP256K1:
if (s == GPG_KEY_STORAGE)
return 128;
else if (s == GPG_KEY_PUBLIC)
return 64;
else
return 32;
case ALGO_ED25519:
if (s == GPG_KEY_STORAGE)
return 128;
else if (s == GPG_KEY_PUBLIC)
return 32;
else
return 64;
case ALGO_CURVE25519:
if (s == GPG_KEY_STORAGE)
return 64;
else
return 32;
default:
rsa2k:
if (s == GPG_KEY_STORAGE)
return 512;
else
return 256;
}
}
@@ -724,6 +749,8 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
algo = ALGO_NISTP256R1;
else if (len == 10 && memcmp (data, algorithm_attr_ed25519+1, 10) == 0)
algo = ALGO_ED25519;
else if (len == 11 && memcmp (data, algorithm_attr_cv25519+1, 11) == 0)
algo = ALGO_CURVE25519;
if (algo < 0)
return 0; /* Error */
@@ -1049,6 +1076,12 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
if (prvkey_len != 64)
return -1;
}
else if (attr == ALGO_CURVE25519)
{
pubkey_len = prvkey_len;
if (prvkey_len != 32)
return -1;
}
else /* RSA */
{
int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
@@ -1066,6 +1099,8 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
pubkey_allocated_here = ecc_compute_public_p256r1 (key_data);
else if (attr == ALGO_ED25519)
pubkey_allocated_here = eddsa_compute_public_25519 (key_data);
else if (attr == ALGO_CURVE25519)
pubkey_allocated_here = ecdh_compute_public_25519 (key_data);
else /* RSA */
pubkey_allocated_here = modulus_calc (key_data, prvkey_len);
@@ -1292,7 +1327,7 @@ kkb_to_kk (uint8_t kk_byte)
static int
proc_key_import (const uint8_t *data, int len)
{
int r;
int r = -1;
enum kind_of_key kk;
const uint8_t *keystring_admin;
int attr;
@@ -1328,7 +1363,7 @@ proc_key_import (const uint8_t *data, int len)
attr = gpg_get_algo_attr (kk);
if ((len <= 12 && (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1
|| attr == ALGO_ED25519))
|| attr == ALGO_ED25519 || attr == ALGO_CURVE25519))
|| (len <= 22 && attr == ALGO_RSA2K) || (len <= 24 && attr == ALGO_RSA4K))
{ /* Deletion of the key */
gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
@@ -1343,7 +1378,7 @@ proc_key_import (const uint8_t *data, int len)
r = gpg_do_write_prvkey (kk, &data[28], len - 28, keystring_admin, NULL);
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
r = gpg_do_write_prvkey (kk, &data[12], len - 12, keystring_admin, NULL);
else /* if (attr == ALGO_ED25519) */
else if (attr == ALGO_ED25519)
{
uint8_t hash[64];
@@ -1356,6 +1391,18 @@ proc_key_import (const uint8_t *data, int len)
hash[31] |= 64;
r = gpg_do_write_prvkey (kk, hash, 64, keystring_admin, NULL);
}
else if (attr == ALGO_CURVE25519)
{
uint8_t priv[32];
int i;
if (len - 12 != 32)
return 1; /* Error. */
for (i = 0; i < 32; i++)
priv[31-i] = data[12+i];
r = gpg_do_write_prvkey (kk, priv, 32, keystring_admin, NULL);
}
if (r < 0)
return 0;
@@ -1910,14 +1957,14 @@ gpg_do_public_key (uint8_t kk_byte)
res_p += 64;
}
}
else if (attr == ALGO_ED25519)
{ /* EdDSA */
else if (attr == ALGO_ED25519 || attr == ALGO_CURVE25519)
{ /* EdDSA or ECDH on curve25519 */
/* LEN */
*res_p++ = 2 + 32;
{
/*TAG*/ /* LEN = 32 */
*res_p++ = 0x86; *res_p++ = 0x20;
/* 32-byte binary (little endian): Y with parity */
/* 32-byte binary (little endian): Y with parity or X*/
memcpy (res_p, pubkey, 32);
res_p += 32;
}
@@ -1983,16 +2030,18 @@ gpg_do_write_simple (uint8_t nr, const uint8_t *data, int size)
*do_data_p = NULL;
}
#ifdef KEYGEN_SUPPORT
void
gpg_do_keygen (uint8_t kk_byte)
{
enum kind_of_key kk = kkb_to_kk (kk_byte);
int pubkey_len = gpg_get_algo_attr_key_size (kk, GPG_KEY_PUBLIC);
int attr = gpg_get_algo_attr (kk);;
int prvkey_len = gpg_get_algo_attr_key_size (kk, GPG_KEY_PRIVATE);
const uint8_t *keystring_admin;
uint8_t *p_q_modulus;
const uint8_t *p_q;
const uint8_t *modulus;
uint8_t *p_q_modulus = NULL;
uint8_t d[64];
const uint8_t *rnd;
const uint8_t *prv;
const uint8_t *pubkey;
int r;
DEBUG_INFO ("Keygen\r\n");
@@ -2003,19 +2052,85 @@ gpg_do_keygen (uint8_t kk_byte)
else
keystring_admin = NULL;
p_q_modulus = rsa_genkey (pubkey_len);
if (p_q_modulus == NULL)
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
{
GPG_MEMORY_FAILURE ();
p_q_modulus = rsa_genkey (prvkey_len);
if (p_q_modulus == NULL)
{
GPG_MEMORY_FAILURE ();
return;
}
prv = p_q_modulus;
pubkey = p_q_modulus + prvkey_len;
}
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
{
uint8_t d1[32];
const uint8_t *p;
int i, r;
rnd = NULL;
do
{
if (rnd)
random_bytes_free (rnd);
rnd = random_bytes_get ();
if (attr == ALGO_NISTP256R1)
r = ecc_check_secret_p256r1 (rnd, d1);
else
r = ecc_check_secret_p256k1 (rnd, d1);
}
while (r == 0);
/* Convert it to big endian */
if (r < 0)
p = (const uint8_t *)d1;
else
p = rnd;
for (i = 0; i < 32; i++)
d[32 - i - 1] = p[i];
random_bytes_free (rnd);
prv = d;
pubkey = NULL;
}
else if (attr == ALGO_ED25519)
{
rnd = random_bytes_get ();
sha512 (rnd, 32, d);
random_bytes_free (rnd);
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
prv = d;
pubkey = NULL;
}
else if (attr == ALGO_CURVE25519)
{
rnd = random_bytes_get ();
memcpy (d, rnd, 32);
random_bytes_free (rnd);
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
prv = d;
pubkey = NULL;
}
else
{
GPG_CONDITION_NOT_SATISFIED ();
return;
}
p_q = p_q_modulus;
modulus = p_q_modulus + pubkey_len;
r = gpg_do_write_prvkey (kk, p_q, pubkey_len, keystring_admin, modulus);
memset (p_q_modulus, 0, pubkey_len * 2);
free (p_q_modulus);
r = gpg_do_write_prvkey (kk, prv, prvkey_len, keystring_admin, pubkey);
if (p_q_modulus)
{
memset (p_q_modulus, 0, prvkey_len * 2);
free (p_q_modulus);
}
if (r < 0)
{
GPG_ERROR ();
@@ -2041,4 +2156,3 @@ gpg_do_keygen (uint8_t kk_byte)
gpg_do_public_key (kk_byte);
}
#endif

View File

@@ -1,7 +1,7 @@
/*
* openpgp.c -- OpenPGP card protocol support
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -620,12 +620,7 @@ cmd_pgp_gakp (void)
{
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
GPG_SECURITY_FAILURE ();
#ifdef KEYGEN_SUPPORT
/* Generate key pair */
gpg_do_keygen (apdu.cmd_apdu_data[0]);
#else
GPG_FUNCTION_NOT_SUPPORTED ();
#endif
}
}
@@ -812,6 +807,8 @@ cmd_get_data (void)
#define EDDSA_HASH_LEN_MAX 256
#define EDDSA_SIGNATURE_LENGTH 64
#define ECC_CIPHER_DO_HEADER_SIZE 7
static void
cmd_pso (void)
{
@@ -819,6 +816,7 @@ cmd_pso (void)
int r = -1;
int attr;
int pubkey_len;
unsigned int result_len = 0;
DEBUG_INFO (" - PSO: ");
DEBUG_WORD ((uint32_t)&r);
@@ -855,13 +853,9 @@ cmd_pso (void)
DEBUG_BINARY (kd[GPG_KEY_FOR_SIGNING].data, pubkey_len);
result_len = pubkey_len;
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
&kd[GPG_KEY_FOR_SIGNING], pubkey_len);
if (r < 0)
ac_reset_pso_cds ();
else
/* Success */
gpg_increment_digital_signature_counter ();
}
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
{
@@ -873,19 +867,13 @@ cmd_pso (void)
return;
}
result_len = ECDSA_SIGNATURE_LENGTH;
if (attr == ALGO_NISTP256R1)
r = ecdsa_sign_p256r1 (apdu.cmd_apdu_data, res_APDU,
kd[GPG_KEY_FOR_SIGNING].data);
else /* ALGO_SECP256K1 */
r = ecdsa_sign_p256k1 (apdu.cmd_apdu_data, res_APDU,
kd[GPG_KEY_FOR_SIGNING].data);
if (r < 0)
ac_reset_pso_cds ();
else
{ /* Success */
gpg_increment_digital_signature_counter ();
res_APDU_size = ECDSA_SIGNATURE_LENGTH;
}
}
else if (attr == ALGO_ED25519)
{
@@ -898,13 +886,27 @@ cmd_pso (void)
return;
}
res_APDU_size = EDDSA_SIGNATURE_LENGTH;
result_len = EDDSA_SIGNATURE_LENGTH;
r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output,
kd[GPG_KEY_FOR_AUTHENTICATION].data,
kd[GPG_KEY_FOR_AUTHENTICATION].data+32,
kd[GPG_KEY_FOR_AUTHENTICATION].pubkey);
kd[GPG_KEY_FOR_SIGNING].data,
kd[GPG_KEY_FOR_SIGNING].data+32,
kd[GPG_KEY_FOR_SIGNING].pubkey);
memcpy (res_APDU, output, EDDSA_SIGNATURE_LENGTH);
}
else
{
DEBUG_INFO ("unknown algo.");
GPG_FUNCTION_NOT_SUPPORTED ();
return;
}
if (r == 0)
{
res_APDU_size = result_len;
gpg_increment_digital_signature_counter ();
}
else /* Failure */
ac_reset_pso_cds ();
}
else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
{
@@ -931,27 +933,51 @@ cmd_pso (void)
return;
}
r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
&kd[GPG_KEY_FOR_DECRYPTION]);
&kd[GPG_KEY_FOR_DECRYPTION], &result_len);
}
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
{
int header = ECC_CIPHER_DO_HEADER_SIZE;
/* Format is in big endian MPI: 04 || x || y */
if (len != 65 || apdu.cmd_apdu_data[0] != 4)
if (len != 65 + ECC_CIPHER_DO_HEADER_SIZE
|| apdu.cmd_apdu_data[header] != 0x04)
{
GPG_CONDITION_NOT_SATISFIED ();
return;
}
result_len = 65;
if (attr == ALGO_NISTP256R1)
r = ecdh_decrypt_p256r1 (apdu.cmd_apdu_data, res_APDU,
r = ecdh_decrypt_p256r1 (apdu.cmd_apdu_data + header, res_APDU,
kd[GPG_KEY_FOR_DECRYPTION].data);
else
r = ecdh_decrypt_p256k1 (apdu.cmd_apdu_data, res_APDU,
r = ecdh_decrypt_p256k1 (apdu.cmd_apdu_data + header, res_APDU,
kd[GPG_KEY_FOR_DECRYPTION].data);
if (r == 0)
res_APDU_size = 65;
}
else if (attr == ALGO_CURVE25519)
{
int header = ECC_CIPHER_DO_HEADER_SIZE;
if (len != 32 + ECC_CIPHER_DO_HEADER_SIZE)
{
GPG_CONDITION_NOT_SATISFIED ();
return;
}
result_len = 32;
r = ecdh_decrypt_curve25519 (apdu.cmd_apdu_data + header, res_APDU,
kd[GPG_KEY_FOR_DECRYPTION].data);
}
else
{
DEBUG_INFO ("unknown algo.");
GPG_FUNCTION_NOT_SUPPORTED ();
return;
}
if (r == 0)
res_APDU_size = result_len;
}
if (r < 0)
@@ -976,6 +1002,7 @@ cmd_internal_authenticate (void)
GPG_KEY_PUBLIC);
int len = apdu.cmd_apdu_data_len;
int r = -1;
unsigned int result_len = 0;
DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n");
@@ -1006,6 +1033,7 @@ cmd_internal_authenticate (void)
return;
}
result_len = pubkey_len;
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
&kd[GPG_KEY_FOR_AUTHENTICATION], pubkey_len);
}
@@ -1018,7 +1046,7 @@ cmd_internal_authenticate (void)
return;
}
res_APDU_size = ECDSA_SIGNATURE_LENGTH;
result_len = ECDSA_SIGNATURE_LENGTH;
r = ecdsa_sign_p256r1 (apdu.cmd_apdu_data, res_APDU,
kd[GPG_KEY_FOR_AUTHENTICATION].data);
}
@@ -1031,7 +1059,7 @@ cmd_internal_authenticate (void)
return;
}
res_APDU_size = ECDSA_SIGNATURE_LENGTH;
result_len = ECDSA_SIGNATURE_LENGTH;
r = ecdsa_sign_p256k1 (apdu.cmd_apdu_data, res_APDU,
kd[GPG_KEY_FOR_AUTHENTICATION].data);
}
@@ -1046,7 +1074,7 @@ cmd_internal_authenticate (void)
return;
}
res_APDU_size = EDDSA_SIGNATURE_LENGTH;
result_len = EDDSA_SIGNATURE_LENGTH;
r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output,
kd[GPG_KEY_FOR_AUTHENTICATION].data,
kd[GPG_KEY_FOR_AUTHENTICATION].data+32,
@@ -1054,7 +1082,9 @@ cmd_internal_authenticate (void)
memcpy (res_APDU, output, EDDSA_SIGNATURE_LENGTH);
}
if (r < 0)
if (r == 0)
res_APDU_size = result_len;
else
GPG_ERROR ();
DEBUG_INFO ("INTERNAL AUTHENTICATE done.\r\n");

View File

@@ -1,7 +1,8 @@
/*
* random.c -- get random bytes
*
* Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
* Copyright (C) 2010, 2011, 2012, 2013, 2015
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -24,8 +25,6 @@
#include <stdint.h>
#include <string.h>
#include "config.h"
#include "gnuk.h"
#include "neug.h"
@@ -85,7 +84,6 @@ random_get_salt (uint8_t *p)
}
#ifdef KEYGEN_SUPPORT
/*
* Random byte iterator
*/
@@ -120,4 +118,3 @@ random_gen (void *arg, unsigned char *out, size_t out_len)
return 0;
}
#endif

262
src/sys.c
View File

@@ -1,7 +1,7 @@
/*
* sys.c - system routines for the initial page for STM32F103.
*
* Copyright (C) 2013, 2014 Flying Stone Technology
* Copyright (C) 2013, 2014, 2015 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* Copying and distribution of this file, with or without modification,
@@ -17,53 +17,13 @@
#include <stdlib.h>
#include "board.h"
#include "clk_gpio_init.c"
#define CORTEX_PRIORITY_BITS 4
#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
#define USB_LP_CAN1_RX0_IRQn 20
#define STM32_USB_IRQ_PRIORITY 11
#define STM32_SW_HSI (0 << 0)
#define STM32_SW_PLL (2 << 0)
#define STM32_PLLSRC_HSI (0 << 16)
#define STM32_PLLSRC_HSE (1 << 16)
#define STM32_PLLXTPRE_DIV1 (0 << 17)
#define STM32_PLLXTPRE_DIV2 (1 << 17)
#define STM32_HPRE_DIV1 (0 << 4)
#define STM32_PPRE1_DIV1 (0 << 8)
#define STM32_PPRE1_DIV2 (4 << 8)
#define STM32_PPRE2_DIV1 (0 << 11)
#define STM32_PPRE2_DIV2 (4 << 11)
#define STM32_ADCPRE_DIV4 (1 << 14)
#define STM32_ADCPRE_DIV6 (2 << 14)
#define STM32_USBPRE_DIV1P5 (0 << 22)
#define STM32_MCO_NOCLOCK (0 << 24)
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_FLASHBITS 0x00000012
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
#define STM32_SW STM32_SW_PLL
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE2 STM32_PPRE2_DIV1
#define STM32_ADCPRE STM32_ADCPRE_DIV6
#define STM32_MCOSEL STM32_MCO_NOCLOCK
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
#define STM32_SYSCLK STM32_PLLCLKOUT
#define STM32_HCLK (STM32_SYSCLK / 1)
struct NVIC {
uint32_t ISER[8];
uint32_t unused1[24];
@@ -93,191 +53,6 @@ nvic_enable_vector (uint32_t n, uint32_t prio)
NVIC_ISER (n) = 1 << (n & 0x1F);
}
#define PERIPH_BASE 0x40000000
#define APBPERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
struct RCC {
volatile uint32_t CR;
volatile uint32_t CFGR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
};
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
#define RCC_APB1ENR_USBEN 0x00800000
#define RCC_APB1RSTR_USBRST 0x00800000
#define RCC_CR_HSION 0x00000001
#define RCC_CR_HSIRDY 0x00000002
#define RCC_CR_HSITRIM 0x000000F8
#define RCC_CR_HSEON 0x00010000
#define RCC_CR_HSERDY 0x00020000
#define RCC_CR_PLLON 0x01000000
#define RCC_CR_PLLRDY 0x02000000
#define RCC_CFGR_SWS 0x0000000C
#define RCC_CFGR_SWS_HSI 0x00000000
#define RCC_AHBENR_CRCEN 0x0040
#define RCC_APB2RSTR_AFIORST 0x00000001
#define RCC_APB2RSTR_IOPARST 0x00000004
#define RCC_APB2RSTR_IOPBRST 0x00000008
#define RCC_APB2RSTR_IOPCRST 0x00000010
#define RCC_APB2RSTR_IOPDRST 0x00000020
#define RCC_APB2ENR_AFIOEN 0x00000001
#define RCC_APB2ENR_IOPAEN 0x00000004
#define RCC_APB2ENR_IOPBEN 0x00000008
#define RCC_APB2ENR_IOPCEN 0x00000010
#define RCC_APB2ENR_IOPDEN 0x00000020
struct FLASH {
volatile uint32_t ACR;
volatile uint32_t KEYR;
volatile uint32_t OPTKEYR;
volatile uint32_t SR;
volatile uint32_t CR;
volatile uint32_t AR;
volatile uint32_t RESERVED;
volatile uint32_t OBR;
volatile uint32_t WRPR;
};
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE);
static void
clock_init (void)
{
/* HSI setup */
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY))
;
/* Reset HSEON, HSEBYP, CSSON, and PLLON, not touching RCC_CR_HSITRIM */
RCC->CR &= (RCC_CR_HSITRIM | RCC_CR_HSION);
RCC->CFGR = 0;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
;
/* HSE setup */
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY))
;
/* PLL setup */
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
;
/* Clock settings */
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
| STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
/*
* We don't touch RCC->CR2, RCC->CFGR2, RCC->CFGR3, and RCC->CIR.
*/
/* Flash setup */
FLASH->ACR = STM32_FLASHBITS;
/* CRC */
RCC->AHBENR |= RCC_AHBENR_CRCEN;
/* Switching on the configured clock source. */
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
;
}
struct AFIO
{
volatile uint32_t EVCR;
volatile uint32_t MAPR;
volatile uint32_t EXTICR[4];
uint32_t RESERVED0;
volatile uint32_t MAPR2;
};
#define AFIO_BASE 0x40010000
static struct AFIO *const AFIO = (struct AFIO *const)AFIO_BASE;
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
struct GPIO {
volatile uint32_t CRL;
volatile uint32_t CRH;
volatile uint32_t IDR;
volatile uint32_t ODR;
volatile uint32_t BSRR;
volatile uint32_t BRR;
volatile uint32_t LCKR;
};
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((struct GPIO *) GPIOA_BASE)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB ((struct GPIO *) GPIOB_BASE)
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOC ((struct GPIO *) GPIOC_BASE)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOD ((struct GPIO *) GPIOD_BASE)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOE ((struct GPIO *) GPIOE_BASE)
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
#ifdef GPIO_USB_BASE
static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
#endif
#ifdef GPIO_OTHER_BASE
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
#endif
static void
gpio_init (void)
{
/* Enable GPIO clock. */
RCC->APB2ENR |= RCC_ENR_IOP_EN;
RCC->APB2RSTR = RCC_RSTR_IOP_RST;
RCC->APB2RSTR = 0;
#ifdef AFIO_MAPR_SOMETHING
AFIO->MAPR |= AFIO_MAPR_SOMETHING;
#endif
GPIO_USB->ODR = VAL_GPIO_ODR;
GPIO_USB->CRH = VAL_GPIO_CRH;
GPIO_USB->CRL = VAL_GPIO_CRL;
#if GPIO_USB_BASE != GPIO_LED_BASE
GPIO_LED->ODR = VAL_GPIO_LED_ODR;
GPIO_LED->CRH = VAL_GPIO_LED_CRH;
GPIO_LED->CRL = VAL_GPIO_LED_CRL;
#endif
#ifdef GPIO_OTHER_BASE
GPIO_OTHER->ODR = VAL_GPIO_OTHER_ODR;
GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH;
GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL;
#endif
}
static void
usb_cable_config (int enable)
{
@@ -468,16 +243,19 @@ flash_check_blank (const uint8_t *p_start, size_t size)
return 1;
}
extern uint8_t __flash_start__, __flash_end__;
#define FLASH_START_ADDR 0x08000000 /* Fixed for all STM32F1. */
#define FLASH_OFFSET 0x1000 /* First pages are not-writable. */
#define FLASH_START (FLASH_START_ADDR+FLASH_OFFSET)
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
#define FLASH_SIZE_REG ((uint16_t *)0x1ffff7e0)
static int
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
{
int status;
uint32_t flash_start = (uint32_t)&__flash_start__;
uint32_t flash_end = (uint32_t)&__flash_end__;
uint32_t flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
if (dst_addr < flash_start || dst_addr + len > flash_end)
if (dst_addr < FLASH_START || dst_addr + len > flash_end)
return 0;
while (len)
@@ -530,17 +308,21 @@ flash_protect (void)
static void __attribute__((naked))
flash_erase_all_and_exec (void (*entry)(void))
{
uint32_t addr = (uint32_t)&__flash_start__;
uint32_t end = (uint32_t)&__flash_end__;
uint32_t addr = FLASH_START;
uint32_t end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
uint32_t page_size = 1024;
int r;
if (((*CHIP_ID_REG) & 0xfff) == 0x0414)
page_size = 2048;
while (addr < end)
{
r = flash_erase_page (addr);
if (r != 0)
break;
addr += FLASH_PAGE_SIZE;
addr += page_size;
}
if (addr >= end)
@@ -640,7 +422,13 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
3*2+2, /* bLength */
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/
/* sys version: "2.0" */
'2', 0, '.', 0, '0', 0,
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
/* sys version: "2.1" */
'2', 0, '.', 0, '1', 0,
};
const uint32_t __attribute__((section(".sys.board_id")))
sys_board_id = BOARD_ID;
const uint8_t __attribute__((section(".sys.board_name")))
sys_board_name[] = BOARD_NAME;

View File

@@ -1,4 +1,16 @@
#define BOARD_ID_CQ_STARM 0xc5480875
#define BOARD_ID_FST_01_00 0x613870a9
#define BOARD_ID_FST_01 0x696886af
#define BOARD_ID_MAPLE_MINI 0x7a445272
#define BOARD_ID_OLIMEX_STM32_H103 0xf92bb594
#define BOARD_ID_STBEE_MINI 0x1f341961
#define BOARD_ID_STBEE 0x945c37e8
#define BOARD_ID_STM32_PRIMER2 0x21e5798d
#define BOARD_ID_STM8S_DISCOVERY 0x2f0976bb
extern const uint8_t sys_version[8];
extern const uint32_t sys_board_id;
extern const uint8_t sys_board_name[];
typedef void (*handler)(void);
extern handler vector[16];

View File

@@ -139,6 +139,7 @@ static uint8_t icc_buffer[USB_BUF_SIZE];
#define ICC_SLOT_STATUS 0x65 /* non-ICCD command */
#define ICC_SECURE 0x69 /* non-ICCD command */
#define ICC_GET_PARAMS 0x6C /* non-ICCD command */
#define ICC_RESET_PARAMS 0x6D /* non-ICCD command */
#define ICC_XFR_BLOCK 0x6F
#define ICC_DATA_BLOCK_RET 0x80
#define ICC_SLOT_STATUS_RET 0x81 /* non-ICCD result */
@@ -253,7 +254,7 @@ static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
{
icc_state_p = &c->icc_state;
c->icc_state = ICC_STATE_START;
c->icc_state = ICC_STATE_NOCARD;
c->state = APDU_STATE_WAIT_COMMAND;
/*
* Note: a is not yet initialized yet, we can't use c->a->cmd_apdu_data here.
@@ -1178,7 +1179,8 @@ icc_handle_data (struct ccid *c)
}
}
else if (c->icc_header.msg_type == ICC_SET_PARAMS
|| c->icc_header.msg_type == ICC_GET_PARAMS)
|| c->icc_header.msg_type == ICC_GET_PARAMS
|| c->icc_header.msg_type == ICC_RESET_PARAMS)
icc_send_params (c);
else if (c->icc_header.msg_type == ICC_SECURE)
{
@@ -1297,6 +1299,8 @@ icc_handle_timeout (struct ccid *c)
return next_state;
}
static struct ccid ccid;
/*
* Another Tx done callback
*/
@@ -1308,8 +1312,6 @@ EP2_IN_Callback (void)
#define USB_ICC_TIMEOUT (1950*1000)
static struct ccid ccid;
#define GPG_THREAD_TERMINATED 0xffff
static void *ccid_thread (chopstx_t) __attribute__ ((noinline));
@@ -1336,6 +1338,8 @@ ccid_card_change_signal (int how)
}
#define NOTIFY_SLOT_CHANGE 0x50
static void * __attribute__ ((noinline))
ccid_thread (chopstx_t thd)
{
@@ -1343,7 +1347,9 @@ ccid_thread (chopstx_t thd)
struct ep_out *epo = &endpoint_out;
struct ccid *c = &ccid;
struct apdu *a = &apdu;
int card_change_requested = 0;
uint8_t int_msg[2];
int_msg[0] = NOTIFY_SLOT_CHANGE;
epi_init (epi, ENDP1, notify_tx, c);
epo_init (epo, ENDP1, notify_icc, c);
@@ -1359,34 +1365,26 @@ ccid_thread (chopstx_t thd)
if (m == EV_CARD_CHANGE)
{
if (card_change_requested)
{
uint8_t notify_slot_change[2] = { 0x50, 0x02 };
led_blink (LED_TWOSHOTS);
if (c->icc_state == ICC_STATE_NOCARD)
{ /* Inserted! */
c->icc_state = ICC_STATE_START;
notify_slot_change[1] |= 1;
}
else
{
if (c->application)
{
eventflag_signal (&c->openpgp_comm, EV_EXIT);
chopstx_join (c->application, NULL);
c->application = 0;
}
c->icc_state = ICC_STATE_NOCARD;
}
card_change_requested = 0;
usb_lld_write (ENDP2, notify_slot_change, 2);
if (c->icc_state == ICC_STATE_NOCARD)
{ /* Inserted! */
c->icc_state = ICC_STATE_START;
int_msg[1] = 0x03;
}
else
card_change_requested = 1;
{ /* Removed! */
if (c->application)
{
eventflag_signal (&c->openpgp_comm, EV_EXIT);
chopstx_join (c->application, NULL);
c->application = 0;
}
c->icc_state = ICC_STATE_NOCARD;
int_msg[1] = 0x02;
}
usb_lld_write (ENDP2, int_msg, sizeof int_msg);
led_blink (LED_TWOSHOTS);
}
else if (m == EV_RX_DATA_READY)
c->icc_state = icc_handle_data (c);
@@ -1444,10 +1442,7 @@ ccid_thread (chopstx_t thd)
icc_prepare_receive (c);
}
else /* Timeout */
{
c->icc_state = icc_handle_timeout (c);
card_change_requested = 0;
}
c->icc_state = icc_handle_timeout (c);
}
if (c->application)

View File

@@ -3,7 +3,29 @@
#ifndef __USB_CONF_H
#define __USB_CONF_H
#define NUM_STRING_DESC 7
#define ICC_NUM_INTERFACES 1
#define ICC_INTERFACE 0
#ifdef HID_CARD_CHANGE_SUPPORT
#define HID_NUM_INTERFACES 1
#define HID_INTERFACE 1
#else
#define HID_NUM_INTERFACES 0
#endif
#ifdef ENABLE_VIRTUAL_COM_PORT
#define VCOM_NUM_INTERFACES 2
#define VCOM_INTERFACE_0 (ICC_NUM_INTERFACES + HID_NUM_INTERFACES)
#define VCOM_INTERFACE_1 (ICC_NUM_INTERFACES + HID_NUM_INTERFACES + 1)
#else
#define VCOM_NUM_INTERFACES 0
#endif
#ifdef PINPAD_DND_SUPPORT
#define MSC_NUM_INTERFACES 1
#define MSC_INTERFACE (ICC_NUM_INTERFACES + HID_NUM_INTERFACES + VCOM_NUM_INTERFACES)
#else
#define MSC_NUM_INTERFACES 0
#endif
#define NUM_INTERFACES (ICC_NUM_INTERFACES + HID_NUM_INTERFACES \
+ VCOM_NUM_INTERFACES + MSC_NUM_INTERFACES)
#if defined(USB_SELF_POWERED)
#define USB_INITIAL_FEATURE 0xC0 /* bmAttributes: self powered */

View File

@@ -103,22 +103,12 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value)
return USB_UNSUPPORT;
}
#define VCOM_NUM_INTERFACES 2
#else
#define VCOM_NUM_INTERFACES 0
#endif
#ifdef PINPAD_DND_SUPPORT
#include "usb-msc.h"
#define MSC_NUM_INTERFACES 1
#else
#define MSC_NUM_INTERFACES 0
#endif
#define NUM_INTERFACES (2+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES)
#define MSC_INTERFACE_NO (2+VCOM_NUM_INTERFACES)
uint32_t bDeviceState = UNCONNECTED; /* USB device status */
#define USB_HID_REQ_GET_REPORT 1
@@ -142,7 +132,7 @@ static uint16_t hid_report;
static void
gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
{
if (interface == 0)
if (interface == ICC_INTERFACE)
{
if (!stop)
{
@@ -158,7 +148,7 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
}
}
#ifdef HID_CARD_CHANGE_SUPPORT
else if (interface == 1)
else if (interface == HID_INTERFACE)
{
if (!stop)
usb_lld_setup_endpoint (ENDP7, EP_INTERRUPT, 0, 0, ENDP7_TXADDR, 0);
@@ -167,14 +157,14 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
}
#endif
#ifdef ENABLE_VIRTUAL_COM_PORT
else if (interface == 2)
else if (interface == VCOM_INTERFACE_0)
{
if (!stop)
usb_lld_setup_endpoint (ENDP4, EP_INTERRUPT, 0, 0, ENDP4_TXADDR, 0);
else
usb_lld_stall_tx (ENDP4);
}
else if (interface == 3)
else if (interface == VCOM_INTERFACE_1)
{
if (!stop)
{
@@ -190,7 +180,7 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
}
#endif
#ifdef PINPAD_DND_SUPPORT
else if (interface == MSC_INTERFACE_NO)
else if (interface == MSC_INTERFACE)
{
if (!stop)
usb_lld_setup_endpoint (ENDP6, EP_BULK, 0,
@@ -231,8 +221,7 @@ usb_cb_device_reset (void)
#define USB_CCID_REQ_GET_CLOCK_FREQUENCIES 0x02
#define USB_CCID_REQ_GET_DATA_RATES 0x03
static const uint8_t freq_table[] = { 0xf3, 0x0d, 0, 0, }; /* dwDefaultClock */
static const uint8_t freq_table[] = { 0xa0, 0x0f, 0, 0, }; /* dwDefaultClock */
static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
#if defined(PINPAD_DND_SUPPORT)
@@ -328,7 +317,7 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
}
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
if (index == 0)
if (index == ICC_INTERFACE)
{
if (USB_SETUP_GET (req))
{
@@ -353,7 +342,7 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
}
}
#ifdef HID_CARD_CHANGE_SUPPORT
else if (index == 1)
else if (index == HID_INTERFACE)
{
switch (req_no)
{
@@ -386,11 +375,11 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
}
#endif
#ifdef ENABLE_VIRTUAL_COM_PORT
else if (index == 2)
else if (index == VCOM_INTERFACE_0)
return vcom_port_data_setup (req, req_no, value);
#endif
#ifdef PINPAD_DND_SUPPORT
else if (index == MSC_INTERFACE_NO)
else if (index == MSC_INTERFACE)
{
if (USB_SETUP_GET (req))
{
@@ -433,7 +422,7 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
#ifdef HID_CARD_CHANGE_SUPPORT
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
if (index == 1 && req_no == USB_HID_REQ_SET_REPORT)
if (index == HID_INTERFACE && req_no == USB_HID_REQ_SET_REPORT)
{
if ((hid_report ^ hid_report_saved) & HID_LED_STATUS_CARDCHANGE)
ccid_card_change_signal (CARD_CHANGE_TOGGLE);
@@ -465,6 +454,7 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
usb_lld_set_configuration (value);
for (i = 0; i < NUM_INTERFACES; i++)
gnuk_setup_endpoints_for_interface (i, 0);
ccid_card_change_signal (CCID_CARD_INIT);
bDeviceState = CONFIGURED;
}
else if (current_conf != value)
@@ -488,7 +478,7 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
{
static const uint8_t zero = 0;
const uint8_t zero = 0;
if (interface >= NUM_INTERFACES)
return USB_UNSUPPORT;
@@ -505,7 +495,8 @@ int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
}
case USB_GET_INTERFACE:
usb_lld_set_data_to_send (&zero, 1);
usb_lld_write (ENDP0, &zero, 1);
usb_lld_set_data_to_send (NULL, 1);
return USB_SUCCESS;
default:

View File

@@ -75,37 +75,27 @@ static const uint8_t gnukDeviceDescriptor[] = {
};
#define ICC_TOTAL_LENGTH (9+9+54+7+7+7)
#define ICC_NUM_INTERFACES 1
#ifdef HID_CARD_CHANGE_SUPPORT
#define HID_TOTAL_LENGTH (9+9+7)
#define HID_NUM_INTERFACES 1
#else
#define HID_TOTAL_LENGTH 0
#define HID_NUM_INTERFACES 0
#endif
#ifdef ENABLE_VIRTUAL_COM_PORT
#define VCOM_TOTAL_LENGTH (9+5+5+4+5+7+9+7+7)
#define VCOM_NUM_INTERFACES 2
#else
#define VCOM_TOTAL_LENGTH 0
#define VCOM_NUM_INTERFACES 0
#endif
#ifdef PINPAD_DND_SUPPORT
#define MSC_TOTAL_LENGTH (9+7+7)
#define MSC_NUM_INTERFACES 1
#else
#define MSC_TOTAL_LENGTH 0
#define MSC_NUM_INTERFACES 0
#endif
#define W_TOTAL_LENGTH (ICC_TOTAL_LENGTH + HID_TOTAL_LENGTH \
+ VCOM_TOTAL_LENGTH + MSC_TOTAL_LENGTH)
#define NUM_INTERFACES (ICC_NUM_INTERFACES + HID_NUM_INTERFACES \
+ VCOM_NUM_INTERFACES + MSC_NUM_INTERFACES)
/* Configuation Descriptor */
@@ -122,7 +112,7 @@ static const uint8_t gnukConfigDescriptor[] = {
/* Interface Descriptor */
9, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
0, /* bInterfaceNumber: Index of this interface */
ICC_INTERFACE, /* bInterfaceNumber: Index of this interface */
0, /* Alternate setting for this interface */
3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
USB_ICC_INTERFACE_CLASS,
@@ -135,42 +125,36 @@ static const uint8_t gnukConfigDescriptor[] = {
0x21, /* bDescriptorType: USBDESCR_ICC */
0x10, 0x01, /* bcdCCID: revision 1.1 (of CCID) */
0, /* bMaxSlotIndex: */
1, /* bVoltageSupport: FIXED VALUE */
1, /* bVoltageSupport: 5V-only */
0x02, 0, 0, 0, /* dwProtocols: T=1 */
0xf3, 0x0d, 0, 0, /* dwDefaultClock: 3571 (non-ICCD): 3580 (ICCD) */
0xf3, 0x0d, 0, 0, /* dwMaximumClock: 3571 (non-ICCD): 3580 (ICCD) */
1, /* bNumClockSupported: FIXED VALUE */
0x80, 0x25, 0, 0, /* dwDataRate: 9600: FIXED VALUE */
0x80, 0x25, 0, 0, /* dwMaxDataRate: 9600: FIXED VALUE */
1, /* bNumDataRateSupported: FIXED VALUE */
0xa0, 0x0f, 0, 0, /* dwDefaultClock: 4000 */
0xa0, 0x0f, 0, 0, /* dwMaximumClock: 4000 */
0, /* bNumClockSupported: 0x00 */
0x80, 0x25, 0, 0, /* dwDataRate: 9600 */
0x80, 0x25, 0, 0, /* dwMaxDataRate: 9600 */
0, /* bNumDataRateSupported: 0x00 */
0xfe, 0, 0, 0, /* dwMaxIFSD: 254 */
0, 0, 0, 0, /* dwSynchProtocols: FIXED VALUE */
0, 0, 0, 0, /* dwMechanical: FIXED VALUE */
/*
* According to Specification for USB ICCD (revision 1.0),
* dwFeatures should be 0x00040840.
*
* It is different now for better interaction to GPG's in-stock
* ccid-driver.
*/
0x42, 0x08, 0x02, 0x00, /* dwFeatures (not ICCD):
* Short APDU level : 0x20000 *
* (what? means ICCD?) : 0x00800 *
* Automatic IFSD : 0x00400
0, 0, 0, 0, /* dwSynchProtocols: 0 */
0, 0, 0, 0, /* dwMechanical: 0 */
0x7a, 0x04, 0x02, 0x00, /* dwFeatures:
* Short and extended APDU level: 0x40000 ----
* Short APDU level : 0x20000 *
* (ICCD?) : 0x00800 ----
* Automatic IFSD : 0x00400 *
* NAD value other than 0x00 : 0x00200
* Can set ICC in clock stop : 0x00100
* Automatic PPS CUR : 0x00080
* Automatic PPS PROP : 0x00040 *
* Auto baud rate change : 0x00020
* Auto clock change : 0x00010
* Auto voltage selection : 0x00008
* Auto baud rate change : 0x00020 *
* Auto clock change : 0x00010 *
* Auto voltage selection : 0x00008 *
* Auto activaction of ICC : 0x00004
* Automatic conf. based on ATR : 0x00002 g
* Automatic conf. based on ATR : 0x00002 *
*/
0x0f, 0x01, 0, 0, /* dwMaxCCIDMessageLength: 271 */
0xff, /* bClassGetResponse: */
0xff, /* bClassEnvelope: */
0, 0, /* wLCDLayout: FIXED VALUE */
0xff, /* bClassGetResponse: 0xff */
0x00, /* bClassEnvelope: 0 */
0, 0, /* wLCDLayout: 0 */
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DND_SUPPORT)
1, /* bPinSupport: with PIN pad (verify) */
@@ -200,14 +184,14 @@ static const uint8_t gnukConfigDescriptor[] = {
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x82, /* bEndpointAddress: (IN2) */
0x03, /* bmAttributes: Interrupt */
4, 0x00, /* wMaxPacketSize: */
0x04, 0x00, /* wMaxPacketSize: 4 */
0xFF, /* bInterval (255ms) */
#ifdef HID_CARD_CHANGE_SUPPORT
/* Interface Descriptor */
9, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
0x01, /* bInterfaceNumber: Number of Interface */
HID_INTERFACE, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
0x03, /* bInterfaceClass: HID */
@@ -236,7 +220,7 @@ static const uint8_t gnukConfigDescriptor[] = {
/* Interface Descriptor */
9, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
0x02, /* bInterfaceNumber: Number of Interface */
VCOM_INTERFACE_0, /* bInterfaceNumber: Index of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
@@ -247,14 +231,13 @@ static const uint8_t gnukConfigDescriptor[] = {
5, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
0x10, 0x01, /* bcdCDC: spec release number */
/*Call Managment Functional Descriptor*/
5, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x03, /* bmCapabilities: D0+D1 */
0x02, /* bDataInterface: 2 */
VCOM_INTERFACE_1, /* bDataInterface */
/*ACM Functional Descriptor*/
4, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
@@ -264,8 +247,8 @@ static const uint8_t gnukConfigDescriptor[] = {
5, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x01, /* bMasterInterface: Communication class interface */
0x02, /* bSlaveInterface0: Data Class Interface */
VCOM_INTERFACE_0, /* bMasterInterface: Communication class interface */
VCOM_INTERFACE_1, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 4 Descriptor*/
7, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
@@ -277,7 +260,7 @@ static const uint8_t gnukConfigDescriptor[] = {
/*Data class interface descriptor*/
9, /* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
0x03, /* bInterfaceNumber: Number of Interface */
VCOM_INTERFACE_1, /* bInterfaceNumber: Index of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
@@ -303,11 +286,7 @@ static const uint8_t gnukConfigDescriptor[] = {
/* Interface Descriptor.*/
9, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
#ifdef ENABLE_VIRTUAL_COM_PORT
0x04, /* bInterfaceNumber. */
#else
0x02, /* bInterfaceNumber. */
#endif
MSC_INTERFACE, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x02, /* bNumEndpoints. */
0x08, /* bInterfaceClass (Mass Stprage). */
@@ -336,7 +315,7 @@ static const uint8_t gnukConfigDescriptor[] = {
/* USB String Descriptors */
static const uint8_t gnukStringLangID[] = {
static const uint8_t gnuk_string_lang_id[] = {
4, /* bLength */
USB_STRING_DESCRIPTOR_TYPE,
0x09, 0x04 /* LangID = 0x0409: US-English */
@@ -351,22 +330,23 @@ struct desc
uint16_t size;
};
static const struct desc String_Descriptors[NUM_STRING_DESC] = {
{gnukStringLangID, sizeof (gnukStringLangID)},
{gnukStringVendor, sizeof (gnukStringVendor)},
{gnukStringProduct, sizeof (gnukStringProduct)},
{gnukStringSerial, sizeof (gnukStringSerial)},
static const struct desc string_descriptors[] = {
{gnuk_string_lang_id, sizeof (gnuk_string_lang_id)},
{gnuk_string_vendor, sizeof (gnuk_string_vendor)},
{gnuk_string_product, sizeof (gnuk_string_product)},
{gnuk_string_serial, sizeof (gnuk_string_serial)},
{gnuk_revision_detail, sizeof (gnuk_revision_detail)},
{gnuk_config_options, sizeof (gnuk_config_options)},
{sys_version, sizeof (sys_version)},
};
#define NUM_STRING_DESC (sizeof (string_descriptors) / sizeof (struct desc))
#define USB_DT_HID 0x21
#define USB_DT_REPORT 0x22
int
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
uint16_t index)
uint16_t index, uint16_t length)
{
if (rcp == DEVICE_RECIPIENT)
{
@@ -386,8 +366,30 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
{
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].desc,
String_Descriptors[desc_index].size);
usb_lld_set_data_to_send (string_descriptors[desc_index].desc,
string_descriptors[desc_index].size);
return USB_SUCCESS;
}
else if (desc_index == NUM_STRING_DESC)
{
uint8_t usbbuf[64];
int i;
size_t len;
for (i = 0; i < (int)sizeof (usbbuf)/2 - 2; i++)
{
if (sys_board_name[i] == 0)
break;
usbbuf[i*2+2] = sys_board_name[i];
usbbuf[i*2+3] = 0;
}
usbbuf[0] = len = i*2 + 2;
usbbuf[1] = USB_STRING_DESCRIPTOR_TYPE;
if (len > length)
len = length;
usb_lld_write (ENDP0, usbbuf, len);
usb_lld_set_data_to_send (NULL, len);
return USB_SUCCESS;
}
}
@@ -413,15 +415,6 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
#else
(void)index;
#endif
if (desc_type == STRING_DESCRIPTOR)
{
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].desc,
String_Descriptors[desc_index].size);
return USB_SUCCESS;
}
}
}
return USB_UNSUPPORT;

View File

@@ -61,7 +61,7 @@ void usb_cb_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 index, uint16_t len);
int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
uint16_t index);
uint16_t index, uint16_t length);
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);

View File

@@ -698,7 +698,8 @@ static int std_get_descriptor (uint8_t req, uint16_t value,
return USB_UNSUPPORT;
(void)length;
return usb_cb_get_descriptor (rcp, (value >> 8), (value & 0xff), index);
return usb_cb_get_descriptor (rcp, (value >> 8), (value & 0xff),
index, length);
}
static int std_get_configuration (uint8_t req, uint16_t value,
@@ -851,13 +852,22 @@ static void handle_setup0 (void)
if (data_p->len > len)
data_p->len = len;
if ((data_p->len % USB_MAX_PACKET_SIZE) == 0)
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
data_p->require_zlp = TRUE;
else
data_p->require_zlp = FALSE;
dev_p->state = IN_DATA;
handle_datastage_in ();
if (data_p->addr == NULL)
{
/* usb_lld_wite was called already by the setup callback. */
dev_p->state = LAST_IN_DATA;
data_p->len = 0;
}
else
{
dev_p->state = IN_DATA;
handle_datastage_in ();
}
}
else if (ctrl_p->wLength == 0)
{

31
test/ecc_nistp256_keys.py Normal file
View File

@@ -0,0 +1,31 @@
# Data taken from:
# A. Jivsov, Sample Keys and Messages:
# https://sites.google.com/site/brainhub/pgpecckeys
# uid ec_dsa_dh_256 <openpgp@brainhub.org>
# sign key:
# nistp256/BAA59D9C 2010-09-17
# keygrip: 8E06A180EFFE4C65B812150CAF19BF30C0689A4C
#
# q=(x, y) and d
key[0] = (0x0bc7a7baebd5f08c74c77b71ee44e7bb0b5a18317b996da5393e33acc52932c6,
0xd2f60f4d1efe35a0b9fb8d3787ed4bee97ca012d07b8f5835be7093545d532e6,
0xd8f28c530c99821faa5ee2ff4dd8d1df01995d4e98fb45f8768cb65abd4adaa9)
# decryption key:
# sub nistp256/4089AB73 2010-09-17 nistp256
# keygrip: E4403F3FD7A443FAC29FEF288FA0D20AC212851E
#
# q=(x, y) and d
key[1] = (0x7f70c0a8184cdcaea5db20ba8fed17e47bdefb744d575ec449130af37edade65,
0x8ae7ee35d20e8897911c9f564be33d9a94bc1e5c927b1aa07ff750d2d11c2971,
0xa05cd14749bea3f3d14c92dc438e45e351efe860360c431705b7d42410581843)
# auth key from: uid ec_dsa_dh_256_no_pass <openpgp@brainhub.org>
#
# q=(x, y) and d
key[2] = (0x81fbbc20eea9e8d1c3ceabb0a8185925b113d1ac42cd5c78403bd83da19235c6,
0x5ed6db13d91db34507d0129bf88981878d29adbf8fcd1720afdb767bb3fcaaff,
0xa355916f8665eb99c1af48d9560b5c6889e5287bc75aa693aaae9bdb15e8b3fd)
# This file is here to extend the test suite for ECC.

View File

@@ -1,7 +1,7 @@
/* ARM Thumb Assembler code */
// arm-none-eabi-gcc -Wa,-amhls=blank_check.lst -c blank_check.S
.cpu cortex-m3
.cpu cortex-m0
.thumb
ldr r1, .START_ADDR
ldr r2, .END_ADDR

View File

@@ -8,11 +8,9 @@
#define FLASH_SR_OFFSET 0x0c
#define FLASH_CR_OFFSET 0x10
#define COUNT 0x1000
.cpu cortex-m3
.cpu cortex-m0
.thumb
movw r2, #COUNT
ldr r2, .SIZE
ldr r0, .SRC_ADDR
ldr r1, .TARGET_ADDR
ldr r4, .FLASH_BASE_ADDR
@@ -35,5 +33,6 @@
bkpt #0x00
.align 2
.FLASH_BASE_ADDR: .word 0x40022000
.SRC_ADDR: .word 0x20000038
.SRC_ADDR: .word 0x2000003C
.TARGET_ADDR: .word 0x08000000
.SIZE: .word 0x00000000

View File

@@ -7,11 +7,9 @@
#define FLASH_SR_OFFSET 0x0c
#define FLASH_CR_OFFSET 0x10
#define OB_RDP_UNLOCK 0x00a5
.cpu cortex-m3
.cpu cortex-m0
.thumb
movw r0, #OB_RDP_UNLOCK
ldr r0, .OPTION_BYTES
ldr r1, .TARGET_ADDR
ldr r2, .FLASH_BASE_ADDR
mov r3, #FLASH_CR_OPTPG
@@ -21,9 +19,16 @@
1: ldr r0, [r2, #FLASH_SR_OFFSET]
tst r0, r4
bne 1b
add r1, #2
mov r0, #255
strh r0, [r1]
2: ldr r0, [r2, #FLASH_SR_OFFSET]
tst r0, r4
bne 2b
mov r0, #0
str r0, [r2, #FLASH_CR_OFFSET]
bkpt #0x00
.align 2
.FLASH_BASE_ADDR: .word 0x40022000
.TARGET_ADDR: .word 0x1FFFF800
.OPTION_BYTES: .word 0x00000000

View File

@@ -123,15 +123,16 @@ class gnuk_token(object):
end = ((mem[7]*256 + mem[6])*256 + mem[5])*256 + mem[4]
return (start, end)
def download(self, start, data):
def download(self, start, data, verbose=False):
addr = start
addr_end = (start + len(data)) & 0xffffff00
i = (addr - 0x20000000) / 0x100
j = 0
print "start %08x" % addr
print "end %08x" % addr_end
print("start %08x" % addr)
print("end %08x" % addr_end)
while addr < addr_end:
print "# %08x: %d : %d" % (addr, i, 256)
if verbose:
print("# %08x: %d : %d" % (addr, i, 256))
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = i, index = 0,
buffer = data[j*256:j*256+256],
@@ -141,7 +142,8 @@ class gnuk_token(object):
addr = addr + 256
residue = len(data) % 256
if residue != 0:
print "# %08x: %d : %d" % (addr, i, residue)
if verbose:
print("# %08x: %d : %d" % (addr, i, residue))
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = i, index = 0,
buffer = data[j*256:],
@@ -157,7 +159,7 @@ class gnuk_token(object):
def icc_get_result(self):
msg = self.__devhandle.bulkRead(self.__bulkin, 1024, self.__timeout)
if len(msg) < 10:
print msg
print(msg)
raise ValueError("icc_get_result")
msg_type = msg[0]
data_len = msg[1] + (msg[2]<<8) + (msg[3]<<16) + (msg[4]<<24)
@@ -491,15 +493,16 @@ class regnual(object):
end = ((mem[7]*256 + mem[6])*256 + mem[5])*256 + mem[4]
return (start, end)
def download(self, start, data):
def download(self, start, data, verbose=False):
addr = start
addr_end = (start + len(data)) & 0xffffff00
i = (addr - 0x08000000) / 0x100
j = 0
print "start %08x" % addr
print "end %08x" % addr_end
print("start %08x" % addr)
print("end %08x" % addr_end)
while addr < addr_end:
print "# %08x: %d: %d : %d" % (addr, i, j, 256)
if verbose:
print("# %08x: %d: %d : %d" % (addr, i, j, 256))
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = 0, index = 0,
buffer = data[j*256:j*256+256],
@@ -510,7 +513,7 @@ class regnual(object):
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if (crc32code ^ r_value) != 0xffffffff:
print "failure"
print("failure")
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
value = i, index = 0,
buffer = None,
@@ -521,13 +524,14 @@ class regnual(object):
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if r_value == 0:
print "failure"
print("failure")
i = i+1
j = j+1
addr = addr + 256
residue = len(data) % 256
if residue != 0:
print "# %08x: %d : %d" % (addr, i, residue)
if verbose:
print("# %08x: %d : %d" % (addr, i, residue))
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = 0, index = 0,
buffer = data[j*256:],
@@ -538,7 +542,7 @@ class regnual(object):
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if (crc32code ^ r_value) != 0xffffffff:
print "failure"
print("failure")
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
value = i, index = 0,
buffer = None,
@@ -549,7 +553,7 @@ class regnual(object):
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if r_value == 0:
print "failure"
print("failure")
def protect(self):
self.__devhandle.controlMsg(requestType = 0x40, request = 4,
@@ -561,7 +565,7 @@ class regnual(object):
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if r_value == 0:
print "protection failure"
print("protection failure")
def finish(self):
self.__devhandle.controlMsg(requestType = 0x40, request = 5,
@@ -611,9 +615,9 @@ def get_gnuk_device():
for (dev, config, intf) in gnuk_devices():
try:
icc = gnuk_token(dev, config, intf)
print "Device: ", dev.filename
print "Configuration: ", config.value
print "Interface: ", intf.interfaceNumber
print("Device: %s" % dev.filename)
print("Configuration: %d" % config.value)
print("Interface: %d" % intf.interfaceNumber)
break
except:
pass

View File

@@ -3,7 +3,7 @@
"""
gnuk_upgrade.py - a tool to upgrade firmware of Gnuk Token
Copyright (C) 2012 Free Software Initiative of Japan
Copyright (C) 2012, 2015 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -31,354 +31,7 @@ import sys, time, os, binascii, string
import usb
# USB class, subclass, protocol
CCID_CLASS = 0x0B
CCID_SUBCLASS = 0x00
CCID_PROTOCOL_0 = 0x00
def icc_compose(msg_type, data_len, slot, seq, param, data):
return pack('<BiBBBH', msg_type, data_len, slot, seq, 0, param) + data
def iso7816_compose(ins, p1, p2, data, cls=0x00):
data_len = len(data)
if data_len == 0:
return pack('>BBBB', cls, ins, p1, p2)
else:
return pack('>BBBBB', cls, ins, p1, p2, data_len) + data
class regnual(object):
def __init__(self, dev):
conf = dev.configurations[0]
intf_alt = conf.interfaces[0]
intf = intf_alt[0]
if intf.interfaceClass != 0xff:
raise ValueError, "Wrong interface class"
self.__devhandle = dev.open()
try:
self.__devhandle.setConfiguration(conf)
except:
pass
self.__devhandle.claimInterface(intf)
self.__devhandle.setAltInterface(0)
def mem_info(self):
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
value = 0, index = 0, buffer = 8,
timeout = 10000)
start = ((mem[3]*256 + mem[2])*256 + mem[1])*256 + mem[0]
end = ((mem[7]*256 + mem[6])*256 + mem[5])*256 + mem[4]
return (start, end)
def download(self, start, data):
addr = start
addr_end = (start + len(data)) & 0xffffff00
i = (addr - 0x08000000) / 0x100
j = 0
print "start %08x" % addr
print "end %08x" % addr_end
while addr < addr_end:
print "# %08x: %d: %d : %d" % (addr, i, j, 256)
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = 0, index = 0,
buffer = data[j*256:j*256+256],
timeout = 10000)
crc32code = crc32(data[j*256:j*256+256])
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
value = 0, index = 0, buffer = 4,
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if (crc32code ^ r_value) != 0xffffffff:
print "failure"
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
value = i, index = 0,
buffer = None,
timeout = 10000)
time.sleep(0.010)
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
value = 0, index = 0, buffer = 4,
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if r_value == 0:
print "failure"
i = i+1
j = j+1
addr = addr + 256
residue = len(data) % 256
if residue != 0:
print "# %08x: %d : %d" % (addr, i, residue)
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = 0, index = 0,
buffer = data[j*256:],
timeout = 10000)
crc32code = crc32(data[j*256:].ljust(256,chr(255)))
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
value = 0, index = 0, buffer = 4,
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if (crc32code ^ r_value) != 0xffffffff:
print "failure"
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
value = i, index = 0,
buffer = None,
timeout = 10000)
time.sleep(0.010)
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
value = 0, index = 0, buffer = 4,
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if r_value == 0:
print "failure"
def protect(self):
self.__devhandle.controlMsg(requestType = 0x40, request = 4,
value = 0, index = 0, buffer = None,
timeout = 10000)
time.sleep(0.100)
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
value = 0, index = 0, buffer = 4,
timeout = 10000)
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
if r_value == 0:
print "protection failure"
def finish(self):
self.__devhandle.controlMsg(requestType = 0x40, request = 5,
value = 0, index = 0, buffer = None,
timeout = 10000)
def reset_device(self):
try:
self.__devhandle.reset()
except:
pass
# This class only supports Gnuk (for now)
class gnuk_token(object):
def __init__(self, device, configuration, interface):
"""
__init__(device, configuration, interface) -> None
Initialize the device.
device: usb.Device object.
configuration: configuration number.
interface: usb.Interface object representing the interface and altenate setting.
"""
if interface.interfaceClass != CCID_CLASS:
raise ValueError, "Wrong interface class"
if interface.interfaceSubClass != CCID_SUBCLASS:
raise ValueError, "Wrong interface sub class"
self.__devhandle = device.open()
try:
self.__devhandle.setConfiguration(configuration)
except:
pass
self.__devhandle.claimInterface(interface)
self.__devhandle.setAltInterface(0)
self.__intf = interface.interfaceNumber
self.__alt = interface.alternateSetting
self.__conf = configuration
self.__bulkout = 1
self.__bulkin = 0x81
self.__timeout = 10000
self.__seq = 0
def reset_device(self):
try:
self.__devhandle.reset()
except:
pass
def stop_gnuk(self):
self.__devhandle.releaseInterface()
self.__devhandle.setConfiguration(0)
return
def mem_info(self):
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
value = 0, index = 0, buffer = 8,
timeout = 10)
start = ((mem[3]*256 + mem[2])*256 + mem[1])*256 + mem[0]
end = ((mem[7]*256 + mem[6])*256 + mem[5])*256 + mem[4]
return (start, end)
def download(self, start, data):
addr = start
addr_end = (start + len(data)) & 0xffffff00
i = (addr - 0x20000000) / 0x100
j = 0
print "start %08x" % addr
print "end %08x" % addr_end
while addr < addr_end:
print "# %08x: %d : %d" % (addr, i, 256)
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = i, index = 0,
buffer = data[j*256:j*256+256],
timeout = 10)
i = i+1
j = j+1
addr = addr + 256
residue = len(data) % 256
if residue != 0:
print "# %08x: %d : %d" % (addr, i, residue)
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = i, index = 0,
buffer = data[j*256:],
timeout = 10)
def execute(self, last_addr):
i = (last_addr - 0x20000000) / 0x100
o = (last_addr - 0x20000000) % 0x100
self.__devhandle.controlMsg(requestType = 0x40, request = 2,
value = i, index = o, buffer = None,
timeout = 10)
def icc_get_result(self):
msg = self.__devhandle.bulkRead(self.__bulkin, 1024, self.__timeout)
if len(msg) < 10:
raise ValueError, "icc_get_result"
msg_type = msg[0]
data_len = msg[1] + (msg[2]<<8) + (msg[3]<<16) + (msg[4]<<24)
slot = msg[5]
seq = msg[6]
status = msg[7]
error = msg[8]
chain = msg[9]
data = msg[10:]
# XXX: check msg_type, data_len, slot, seq, error
return (status, chain, data)
def icc_get_status(self):
msg = icc_compose(0x65, 0, 0, self.__seq, 0, "")
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
self.__seq += 1
status, chain, data = self.icc_get_result()
# XXX: check chain, data
return status
def icc_power_on(self):
msg = icc_compose(0x62, 0, 0, self.__seq, 0, "")
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
self.__seq += 1
status, chain, data = self.icc_get_result()
# XXX: check status, chain
return data # ATR
def icc_power_off(self):
msg = icc_compose(0x63, 0, 0, self.__seq, 0, "")
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
self.__seq += 1
status, chain, data = self.icc_get_result()
# XXX: check chain, data
return status
def icc_send_data_block(self, data):
msg = icc_compose(0x6f, len(data), 0, self.__seq, 0, data)
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
self.__seq += 1
return self.icc_get_result()
def icc_send_cmd(self, data):
status, chain, data_rcv = self.icc_send_data_block(data)
if chain == 0:
return data_rcv
elif chain == 1:
d = data_rcv
while True:
msg = icc_compose(0x6f, 0, 0, self.__seq, 0x10, "")
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
self.__seq += 1
status, chain, data_rcv = self.icc_get_result()
# XXX: check status
d += data_rcv
if chain == 2:
break
elif chain == 3:
continue
else:
raise ValueError, "icc_send_cmd chain"
return d
else:
raise ValueError, "icc_send_cmd"
def cmd_get_response(self, expected_len):
cmd_data = iso7816_compose(0xc0, 0x00, 0x00, '') + pack('>B', expected_len)
response = self.icc_send_cmd(cmd_data)
return response[:-2]
def cmd_verify(self, who, passwd):
cmd_data = iso7816_compose(0x20, 0x00, 0x80+who, passwd)
sw = self.icc_send_cmd(cmd_data)
if len(sw) != 2:
raise ValueError, sw
if not (sw[0] == 0x90 and sw[1] == 0x00):
raise ValueError, sw
def cmd_select_openpgp(self):
cmd_data = iso7816_compose(0xa4, 0x04, 0x0c, "\xD2\x76\x00\x01\x24\x01")
sw = self.icc_send_cmd(cmd_data)
if len(sw) != 2:
raise ValueError, sw
if not (sw[0] == 0x90 and sw[1] == 0x00):
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
def cmd_external_authenticate(self, signed):
cmd_data = iso7816_compose(0x82, 0x00, 0x00, signed[0:128], cls=0x10)
sw = self.icc_send_cmd(cmd_data)
if len(sw) != 2:
raise ValueError, sw
if not (sw[0] == 0x90 and sw[1] == 0x00):
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
cmd_data = iso7816_compose(0x82, 0x00, 0x00, signed[128:])
sw = self.icc_send_cmd(cmd_data)
if len(sw) != 2:
raise ValueError, sw
if not (sw[0] == 0x90 and sw[1] == 0x00):
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
def cmd_get_challenge(self):
cmd_data = iso7816_compose(0x84, 0x00, 0x00, '')
sw = self.icc_send_cmd(cmd_data)
if len(sw) != 2:
raise ValueError, sw
if sw[0] != 0x61:
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
return self.cmd_get_response(sw[1])
def compare(data_original, data_in_device):
i = 0
for d in data_original:
if ord(d) != data_in_device[i]:
raise ValueError, "verify failed at %08x" % i
i += 1
def ccid_devices():
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
for config in dev.configurations:
for intf in config.interfaces:
for alt in intf:
if alt.interfaceClass == CCID_CLASS and \
alt.interfaceSubClass == CCID_SUBCLASS and \
alt.interfaceProtocol == CCID_PROTOCOL_0:
yield dev, config, alt
USB_VENDOR_FSIJ=0x234b
USB_PRODUCT_GNUK=0x0000
def gnuk_devices():
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
if dev.idVendor != USB_VENDOR_FSIJ:
continue
if dev.idProduct != USB_PRODUCT_GNUK:
continue
yield dev
from gnuk_token import *
def to_string(t):
result = ""
@@ -420,24 +73,17 @@ def gpg_sign(keygrip, hash):
pos = signed.index("D ") + 2
signed = signed[pos:-4] # \nOK\n
if len(signed) != 256:
raise ValueError, binascii.hexlify(signed)
raise ValueError(binascii.hexlify(signed))
return signed
def UNSIGNED(n):
return n & 0xffffffff
def crc32(bytestr):
crc = binascii.crc32(bytestr)
return UNSIGNED(crc)
def main(keygrip, data_regnual, data_upgrade):
def main(keyno,keygrip, data_regnual, data_upgrade):
l = len(data_regnual)
if (l & 0x03) != 0:
data_regnual = data_regnual.ljust(l + 4 - (l & 0x03), chr(0))
crc32code = crc32(data_regnual)
print "CRC32: %04x\n" % crc32code
data_regnual += pack('<I', crc32code)
for (dev, config, intf) in ccid_devices():
for (dev, config, intf) in gnuk_devices():
try:
icc = gnuk_token(dev, config, intf)
print "Device: ", dev.filename
@@ -447,13 +93,13 @@ def main(keygrip, data_regnual, data_upgrade):
except:
icc = None
if icc.icc_get_status() == 2:
raise ValueError, "No ICC present"
raise ValueError("No ICC present")
elif icc.icc_get_status() == 1:
icc.icc_power_on()
icc.cmd_select_openpgp()
challenge = icc.cmd_get_challenge()
signed = gpg_sign(keygrip, binascii.hexlify(to_string(challenge)))
icc.cmd_external_authenticate(signed)
icc.cmd_external_authenticate(keyno, signed)
icc.stop_gnuk()
mem_info = icc.mem_info()
print "%08x:%08x" % mem_info
@@ -471,7 +117,7 @@ def main(keygrip, data_regnual, data_upgrade):
time.sleep(3)
# Then, send upgrade program...
reg = None
for dev in gnuk_devices():
for dev in gnuk_devices_by_vidpid():
try:
reg = regnual(dev)
print "Device: ", dev.filename
@@ -489,6 +135,7 @@ def main(keygrip, data_regnual, data_upgrade):
if __name__ == '__main__':
keyno = 0
keygrip = None
if sys.argv[1] == '-k':
sys.argv.pop(1)
@@ -504,4 +151,4 @@ if __name__ == '__main__':
data_upgrade = f.read()
f.close()
print "%s: %d" % (filename_upgrade, len(data_upgrade))
main(keygrip, data_regnual, data_upgrade[4096:])
main(keyno, keygrip, data_regnual, data_upgrade[4096:])

View File

@@ -3,7 +3,7 @@
"""
stlinkv2.py - a tool to control ST-Link/V2
Copyright (C) 2012, 2013 Free Software Initiative of Japan
Copyright (C) 2012, 2013, 2015 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -31,11 +31,19 @@ from colorama import init as colorama_init, Fore, Back, Style
# Assumes only single ST-Link/V2 device is attached to computer.
CORE_ID_CORTEX_M3=0x1ba01477
CORE_ID_CORTEX_M0=0x0bb11477
CHIP_ID_STM32F103xB=0x20036410
CHIP_ID_STM32F103xE=0x10016414
# CHIP_ID_STM32F0 0x20006440
# CHIP_ID_STM32F030?? 0x10006444; FSM-55
GPIOA=0x40010800
GPIOB=0x40010C00
OPTION_BYTES_ADDR=0x1ffff800
RDP_KEY=0x00a5 # Unlock readprotection
RDP_KEY_F1=0x00a5 # Unlock readprotection
RDP_KEY_F0=0x00aa # Unlock readprotection
FLASH_BASE_ADDR=0x40022000
FLASH_KEYR= FLASH_BASE_ADDR+0x04
@@ -62,44 +70,42 @@ FLASH_CR_STRT= 0x0040
FLASH_CR_LOCK= 0x0080
FLASH_CR_OPTWRE= 0x0200
SPI1= 0x40013000
def uint32(v):
return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24)
## HERE comes: "movw r2,#SIZE" instruction
prog_flash_write_body = "\x0A\x48" + "\x0B\x49" + \
"\x08\x4C" + "\x01\x25" + "\x14\x26" + "\x00\x27" + "\x25\x61" + \
prog_flash_write_body = "\x0D\x4A" + "\x0B\x48" + "\x0B\x49" + \
"\x09\x4C" + "\x01\x25" + "\x14\x26" + "\x00\x27" + "\x25\x61" + \
"\xC3\x5B" + "\xCB\x53" + "\xE3\x68" + "\x2B\x42" + "\xFC\xD1" + \
"\x33\x42" + "\x02\xD1" + "\x02\x37" + "\x97\x42" + "\xF5\xD1" + \
"\x00\x27" + "\x27\x61" + "\x00\xBE" + "\x00\x20\x02\x40" + \
"\x38\x00\x00\x20"
# .SRC_ADDR: 0x20000038
"\x00\x27" + "\x27\x61" + "\x00\xBE" + "\xC0\x46" + "\x00\x20\x02\x40" + \
"\x3C\x00\x00\x20"
# .SRC_ADDR: 0x2000003C
## HERE comes: target_addr in 4-byte
# .TARGET_ADDR
## HERE comes: size in 4-byte
# .SIZE
def gen_prog_flash_write(addr,size):
return pack("<BBBB", (0x40 | (size&0xf000)>>12), (0xf2 | (size&0x0800)>>9),
(size & 0x00ff), (0x02 | ((size&0x0700) >> 4))) + \
prog_flash_write_body + pack("<I", addr)
return prog_flash_write_body + pack("<I", addr) + pack("<I", size)
## HERE comes: "movw r0,#VAL" instruction
prog_option_bytes_write_body = "\x06\x49" + "\x05\x4A" + "\x10\x23" + \
"\x01\x24" + "\x13\x61" + "\x08\x80" + "\xD0\x68" + "\x20\x42" + \
"\xFC\xD1" + "\x00\x20" + "\x10\x61" + "\x00\xBE" + "\x00\x20\x02\x40"
prog_option_bytes_write_body = "\x0B\x48" + "\x0A\x49" + "\x08\x4A" + \
"\x10\x23" + "\x01\x24" + "\x13\x61" + "\x08\x80" + "\xD0\x68" + \
"\x20\x42" + "\xFC\xD1" + "\x02\x31" + "\xFF\x20" + "\x08\x80" + \
"\xD0\x68" + "\x20\x42" + "\xFC\xD1" + "\x00\x20" + "\x10\x61" + \
"\x00\xBE" + "\xC0\x46" + "\x00\x20\x02\x40"
## HERE comes: target_addr in 4-byte
# .TARGET_ADDR
## HERE comes: option_bytes in 4-byte
# .OPTION_BYTES
def gen_prog_option_bytes_write(addr,val):
return pack("<BBBB", (0x40 | (val&0xf000)>>12), (0xf2 | (val&0x0800)>>9),
(val & 0x00ff), (0x00 | ((val&0x0700) >> 4))) + \
prog_option_bytes_write_body + pack("<I", addr)
return prog_option_bytes_write_body + pack("<I", addr) + pack("<I", val)
prog_blank_check_body = "\x04\x49" + "\x05\x4A" + "\x08\x68" + "\x01\x30" + \
"\x02\xD1" + "\x04\x31" + "\x91\x42" + "\xF9\xD1" + "\x00\xBE" + \
"\x00\xBF" + "\x00\x00\x00\x08"
"\xC0\x46" + "\x00\x00\x00\x08"
## HERE comes: end_addr in 4-byte
# .END_ADDR
@@ -108,7 +114,8 @@ def gen_prog_blank_check(size):
SRAM_ADDRESS=0x20000000
BLOCK_SIZE=16384 # Should be less than (20KiB - 0x0038)
FLASH_BLOCK_SIZE_F1=16384 # Should be less than (20KiB - 0x0038)
FLASH_BLOCK_SIZE_F0=2048 # Should be less than (4KiB - 0x0038)
BLOCK_WRITE_TIMEOUT=80 # Increase this when you increase BLOCK_SIZE
@@ -219,11 +226,14 @@ class stlinkv2(object):
def write_debug_reg(self, addr, value):
return self.execute_get("\xf2\x35" + pack('<II', addr, value), 2)
def control_nrst(self, value):
return self.execute_get("\xf2\x3c" + pack('<B', value), 2)
def run(self):
v = self.execute_get("\xf2\x09\x00", 2)
return (v[1] << 8) + v[0]
def core_id(self):
def get_core_id(self):
v = self.execute_get("\xf2\x22\x00", 4)
return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24)
@@ -309,7 +319,7 @@ class stlinkv2(object):
return (self.read_memory_u32(FLASH_OBR) & 0x0002) != 0
def blank_check(self):
prog = gen_prog_blank_check(0x20000) # 128KiB XXX: table lookup???
prog = gen_prog_blank_check(self.flash_size)
self.write_memory(SRAM_ADDRESS, prog)
self.write_reg(15, SRAM_ADDRESS)
self.run()
@@ -398,8 +408,8 @@ class stlinkv2(object):
off = 0
while True:
if len(data[off:]) > BLOCK_SIZE:
size = BLOCK_SIZE
if len(data[off:]) > self.flash_block_size:
size = self.flash_block_size
self.flash_write_internal(addr, data, off, size)
off = off + size
addr = addr + size
@@ -466,11 +476,12 @@ class stlinkv2(object):
elif mode != 1 and mode != 4:
self.exit_from_dfu()
new_mode = self.stl_mode()
print "Change ST-Link/V2 mode %04x -> %04x" % (mode, new_mode)
print("Change ST-Link/V2 mode %04x -> %04x" % (mode, new_mode))
self.control_nrst(2)
self.enter_swd()
s = self.get_status()
if s != 0x0080:
print "Status is %04x" % s
print("Status is %04x" % s)
self.run()
s = self.get_status()
if s != 0x0080:
@@ -483,6 +494,52 @@ class stlinkv2(object):
if mode != 2:
raise ValueError("Failed to switch debug mode.", mode)
self.core_id = self.get_core_id()
if self.core_id == CORE_ID_CORTEX_M3:
self.chip_stm32 = True
elif self.core_id == CORE_ID_CORTEX_M0:
self.chip_stm32 = False
else:
raise ValueError("Unknown core ID", self.core_id)
if self.chip_stm32:
self.rdp_key = RDP_KEY_F1
self.flash_block_size = FLASH_BLOCK_SIZE_F1
self.require_nrst = False
self.external_spi_flash = True
self.protection_feature = True
else:
self.rdp_key = RDP_KEY_F0
self.flash_block_size = FLASH_BLOCK_SIZE_F0
self.require_nrst = True
self.external_spi_flash = False
self.protection_feature = False
return self.core_id
def get_chip_id(self):
if self.chip_stm32:
self.chip_id = self.read_memory_u32(0xE0042000)
self.flash_size = (self.read_memory_u32(0x1ffff7e0) & 0xffff)*1024
if self.chip_id == CHIP_ID_STM32F103xB:
pass
elif self.chip_id == CHIP_ID_STM32F103xE:
pass
else:
raise ValueError("Unknown chip ID", self.chip_id)
else:
self.chip_id = self.read_memory_u32(0x40015800)
self.flash_size = (self.read_memory_u32(0x1ffff7cc) & 0xffff)*1024
print("Flash size: %dKiB" % (self.flash_size/1024))
return self.chip_id
def get_rdp_key(self):
return self.rdp_key
def has_spi_flash(self):
return self.external_spi_flash
def has_protection(self):
return self.protection_feature
USB_VENDOR_ST=0x0483 # 0x0483 SGS Thomson Microelectronics
USB_VENDOR_STLINKV2=0x3748 # 0x3748 ST-LINK/V2
@@ -515,15 +572,15 @@ def open_stlinkv2():
return None
def help():
print "stlinkv2.py [-h]: Show this help message"
print "stlinkv2.py [-e]: Erase flash ROM"
print "stlinkv2.py [-u]: Unlock flash ROM"
print "stlinkv2.py [-s]: Show status"
print "stlinkv2.py [-b] [-n] [-r] [-i] FILE: Write content of FILE to flash ROM"
print " -b: Blank check before write (auto erase when not blank)"
print " -n: Don't enable read protection after write"
print " -r: Don't reset after write"
print " -i: Don't test SPI flash"
print("stlinkv2.py [-h]: Show this help message")
print("stlinkv2.py [-e]: Erase flash ROM")
print("stlinkv2.py [-u]: Unlock flash ROM")
print("stlinkv2.py [-s]: Show status")
print("stlinkv2.py [-b] [-n] [-r] [-i] FILE: Write content of FILE to flash ROM")
print(" -b: Blank check before write (auto erase when not blank)")
print(" -n: Don't enable read protection after write")
print(" -r: Don't reset after write")
print(" -i: Don't test SPI flash")
def main(show_help, erase_only, no_protect, spi_flash_check,
@@ -537,40 +594,39 @@ 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)
# FST-01 chip id: 0x20036410
print "CORE: %08x, CHIP_ID: %08x" % (core_id, chip_id)
print "Flash ROM read protection:",
protection = stl.protection()
if protection:
print "ON"
else:
print "off"
option_bytes = stl.option_bytes_read()
print "Option bytes: %08x" % option_bytes
if (option_bytes & 0xff) == RDP_KEY:
ob_protection_enable = False
else:
ob_protection_enable = True
print("ST-Link/V2 version info: %d %d %d" % stl.version())
core_id = stl.start()
stl.control_nrst(2)
stl.enter_debug()
status = stl.get_status()
if status != 0x0081:
print "Core does not halt, try API V2 halt."
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()
stl.write_debug_reg(0xE000EDF0, 0xA05F0003)
status = stl.get_status()
if status != 0x0081:
raise ValueError("Status of core is not halt.", status)
chip_id = stl.get_chip_id()
# FST-01 chip id: 0x20036410
print("CORE: %08x, CHIP_ID: %08x" % (core_id, chip_id))
protection = stl.protection()
print("Flash ROM read protection: " + ("ON" if protection else "off"))
option_bytes = stl.option_bytes_read()
print("Option bytes: %08x" % option_bytes)
rdp_key = stl.get_rdp_key()
if (option_bytes & 0xff) == rdp_key:
ob_protection_enable = False
else:
ob_protection_enable = True
if protection:
if status_only:
print "The MCU is now stopped."
print("The MCU is now stopped.")
return 0
elif not unlock:
raise OperationFailure("Flash ROM is protected")
@@ -578,7 +634,7 @@ def main(show_help, erase_only, no_protect, spi_flash_check,
if not skip_blank_check:
stl.reset_sys()
blank = stl.blank_check()
print "Flash ROM blank check: %s" % blank
print("Flash ROM blank check: %s" % blank)
else:
blank = True
if status_only:
@@ -587,12 +643,12 @@ def main(show_help, erase_only, no_protect, spi_flash_check,
stl.exit_debug()
return 0
elif unlock and not ob_protection_enable:
print "No need to unlock. Protection is not enabled."
print("No need to unlock. Protection is not enabled.")
return 1
if erase_only:
if blank:
print "No need to erase"
print("No need to erase")
return 0
stl.setup_gpio()
@@ -602,22 +658,22 @@ def main(show_help, erase_only, no_protect, spi_flash_check,
stl.reset_sys()
stl.option_bytes_erase()
stl.reset_sys()
stl.option_bytes_write(OPTION_BYTES_ADDR,RDP_KEY)
stl.option_bytes_write(OPTION_BYTES_ADDR,rdp_key)
stl.usb_disconnect()
time.sleep(0.100)
stl.finish_gpio()
print "Flash ROM read protection disabled. Reset the board, now."
print("Flash ROM read protection disabled. Reset the board, now.")
return 0
if spi_flash_check:
if spi_flash_check and stl.has_spi_flash():
stl.spi_flash_init()
id = stl.spi_flash_read_id()
print "SPI Flash ROM ID: %06x" % id
print("SPI Flash ROM ID: %06x" % id)
if id != 0xbf254a:
raise ValueError("bad spi flash ROM ID")
if not blank:
print "ERASE ALL"
print("ERASE ALL")
stl.reset_sys()
stl.flash_erase_all()
@@ -629,10 +685,10 @@ def main(show_help, erase_only, no_protect, spi_flash_check,
time.sleep(0.100)
print "WRITE"
print("WRITE")
stl.flash_write(0x08000000, data)
print "VERIFY"
print("VERIFY")
data_received = ()
size = len(data)
off = 0
@@ -641,17 +697,18 @@ def main(show_help, erase_only, no_protect, spi_flash_check,
blk_size = 1024
else:
blk_size = size
data_received = data_received + stl.read_memory(0x08000000+off, 1024)
data_received = data_received + stl.read_memory(0x08000000+off, blk_size)
size = size - blk_size
off = off + blk_size
compare(data, data_received)
if not no_protect:
print "PROTECT"
if not no_protect and stl.has_protection():
print("PROTECT")
stl.option_bytes_erase()
print "Flash ROM read protection enabled. Reset the board to enable protection."
print("Flash ROM read protection enabled. Reset the board to enable protection.")
if reset_after_successful_write:
stl.control_nrst(2)
stl.usb_disconnect()
stl.reset_sys()
stl.run()
@@ -705,6 +762,8 @@ if __name__ == '__main__':
f = open(filename,'rb')
data = f.read()
f.close()
if len(data) % 1:
raise ValueError("The size of file should be even")
sys.argv.pop(1)
colorama_init()
@@ -714,7 +773,7 @@ if __name__ == '__main__':
reset_after_successful_write,
skip_blank_check, status_only, unlock, data)
if r == 0:
print Fore.WHITE + Back.BLUE + Style.BRIGHT + "SUCCESS" + Style.RESET_ALL
print(Fore.WHITE + Back.BLUE + Style.BRIGHT + "SUCCESS" + Style.RESET_ALL)
sys.exit(r)
except Exception as e:
print Back.RED + Style.BRIGHT + repr(e) + Style.RESET_ALL
print(Back.RED + Style.BRIGHT + repr(e) + Style.RESET_ALL)

View File

@@ -4,7 +4,7 @@
upgrade_by_passwd.py - a tool to install another firmware for Gnuk Token
which is just shipped from factory
Copyright (C) 2012, 2013 Free Software Initiative of Japan
Copyright (C) 2012, 2013, 2015 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -37,7 +37,7 @@ def main(keyno, passwd, data_regnual, data_upgrade):
if (l & 0x03) != 0:
data_regnual = data_regnual.ljust(l + 4 - (l & 0x03), chr(0))
crc32code = crc32(data_regnual)
print "CRC32: %04x\n" % crc32code
print("CRC32: %04x\n" % crc32code)
data_regnual += pack('<I', crc32code)
rsa_key = rsa.read_key_from_file('rsa_example.key')
@@ -55,11 +55,11 @@ def main(keyno, passwd, data_regnual, data_upgrade):
gnuk.cmd_external_authenticate(keyno, signed_bytes)
gnuk.stop_gnuk()
mem_info = gnuk.mem_info()
print "%08x:%08x" % mem_info
print("%08x:%08x" % mem_info)
print "Downloading flash upgrade program..."
print("Downloading flash upgrade program...")
gnuk.download(mem_info[0], data_regnual)
print "Run flash upgrade program..."
print("Run flash upgrade program...")
gnuk.execute(mem_info[0] + len(data_regnual) - 4)
#
time.sleep(3)
@@ -67,51 +67,56 @@ def main(keyno, passwd, data_regnual, data_upgrade):
del gnuk
gnuk = None
#
print "Wait 3 seconds..."
print("Wait 3 seconds...")
time.sleep(3)
# Then, send upgrade program...
reg = None
for dev in gnuk_devices_by_vidpid():
try:
reg = regnual(dev)
print "Device: ", dev.filename
print("Device: %s" % dev.filename)
break
except:
pass
mem_info = reg.mem_info()
print "%08x:%08x" % mem_info
print "Downloading the program"
print("%08x:%08x" % mem_info)
print("Downloading the program")
reg.download(mem_info[0], data_upgrade)
reg.protect()
reg.finish()
reg.reset_device()
return 0
from getpass import getpass
if __name__ == '__main__':
if os.getcwd() != os.path.dirname(os.path.abspath(__file__)):
print "Please change working directory to: %s" % os.path.dirname(os.path.abspath(__file__))
print("Please change working directory to: %s" % os.path.dirname(os.path.abspath(__file__)))
exit(1)
passwd = DEFAULT_PW3
keyno = 0
passwd = None
while len(sys.argv) > 3:
option = sys.argv[1]
sys.argv.pop(1)
if option == '-p':
from getpass import getpass
passwd = getpass("Admin password: ")
elif option == '-k':
if option == '-f': # F for Factory setting
passwd = DEFAULT_PW3
elif option == '-k': # K for Key number
keyno = int(sys.argv[1])
sys.argv.pop(1)
else:
raise ValueError("unknown option", option)
if not passwd:
passwd = getpass("Admin password: ")
filename_regnual = sys.argv[1]
filename_upgrade = sys.argv[2]
f = open(filename_regnual)
data_regnual = f.read()
f.close()
print "%s: %d" % (filename_regnual, len(data_regnual))
print("%s: %d" % (filename_regnual, len(data_regnual)))
f = open(filename_upgrade)
data_upgrade = f.read()
f.close()
print "%s: %d" % (filename_upgrade, len(data_upgrade))
print("%s: %d" % (filename_upgrade, len(data_upgrade)))
# First 4096-byte in data_upgrade is SYS, so, skip it.
main(keyno, passwd, data_regnual, data_upgrade[4096:])

View File

@@ -38,7 +38,7 @@ def gnuk_devices():
continue
yield dev
title = [ '', 'Vendor', 'Product', 'Serial', 'Revision', 'Config', 'Sys' ]
field = ['', 'Vendor', 'Product', 'Serial', 'Revision', 'Config', 'Sys', 'Board']
def main(n):
for dev in gnuk_devices():
@@ -47,7 +47,7 @@ def main(n):
try:
for i in range(1,n):
str = handle.getString(i, 512)
print "%10s: %s" % (title[i], str)
print "%10s: %s" % (field[i], str)
except:
pass
del dev
@@ -56,5 +56,5 @@ if __name__ == '__main__':
if len(sys.argv) > 1:
n = int(sys.argv[1])
else:
n = 7 # Gnuk has seven strings
n = 8 # Gnuk has eight strings
main(n)