Compare commits
37 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61e4551b76 | ||
|
|
254742bc6d | ||
|
|
a6fd40d4fd | ||
|
|
9a11e954d8 | ||
|
|
b2ca03dc19 | ||
|
|
0fb6853fc7 | ||
|
|
94d6208542 | ||
|
|
eb62609c86 | ||
|
|
d596493831 | ||
|
|
70463566bf | ||
|
|
99c55fce60 | ||
|
|
ec2a2e049f | ||
|
|
43331cbeaf | ||
|
|
fbdac6a96a | ||
|
|
9e3af06141 | ||
|
|
1de2f33d23 | ||
|
|
06b364b1ac | ||
|
|
9786da7009 | ||
|
|
55ee1cd30f | ||
|
|
5f21a44058 | ||
|
|
edf1a0cdd7 | ||
|
|
be5c052531 | ||
|
|
e041a2aa7d | ||
|
|
31c7a42c73 | ||
|
|
8ddcc1e896 | ||
|
|
6a8f8dffcb | ||
|
|
f2744bec30 | ||
|
|
074f479962 | ||
|
|
a60fe371a4 | ||
|
|
3ea5e54eb9 | ||
|
|
ed8c41a0ca | ||
|
|
9ed3bb5353 | ||
|
|
9bbca07033 | ||
|
|
9ba59de212 | ||
|
|
35c880fc0c | ||
|
|
7b116d614e | ||
|
|
a73d04cf82 |
31
AUTHORS
31
AUTHORS
@@ -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
|
||||
|
||||
174
ChangeLog
174
ChangeLog
@@ -1,3 +1,177 @@
|
||||
2015-08-05 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.1.7.
|
||||
|
||||
2015-08-04 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/adc_stm32f103.c: Update from NeuG 1.0.3.
|
||||
|
||||
* chopstx: Update to 0.08.
|
||||
* src/sys.h: Update.
|
||||
|
||||
2015-08-03 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* test/features/steps.py (set_msg): Python3 fix.
|
||||
* test/generate_keys.py: Likewise.
|
||||
* test/rsa_keys.py: Likewise.
|
||||
|
||||
* tool/gnuk_token.py (gnuk_token.download, gnuk_token.execute)
|
||||
(regnual.download): Python3 fix.
|
||||
(list_to_string): Remove.
|
||||
|
||||
* tool/upgrade_by_passwd.py (maian): Python3 fix.
|
||||
* tool/usb_strings.py (main): Python3 fix.
|
||||
|
||||
2015-07-31 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (output_vendor_product_serial_strings): Fix sed
|
||||
script when string is short. Remove empty line.
|
||||
|
||||
* regnual/regnual.c (usb_cb_ctrl_write_finish, usb_cb_setup)
|
||||
(usb_cb_get_descriptor, usb_cb_interface): Follow the change
|
||||
of USB API.
|
||||
|
||||
* tool/stlinkv2.py: Support ST-Link/V2-1.
|
||||
|
||||
2015-07-28 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/stlinkv2.py: Fix for Python3. Thanks to Bertrand Jacquin.
|
||||
|
||||
* tool/gpg_agent.py: Fix for Python3.
|
||||
|
||||
* src/usb-msc.c: Update from Fraucheky.
|
||||
|
||||
* src/usb_stm32f103.c (struct DATA_INFO): Remove offset.
|
||||
(struct DEVICE_INFO): Integrate CONTROL_INFO.
|
||||
|
||||
2015-07-27 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb_stm32f103.c (usb_lld_reply_request): New.
|
||||
(usb_lld_set_data_to_send): Remove.
|
||||
(usb_lld_set_data_to_recv): Not a macro but a function.
|
||||
(std_get_status): Don't use statically allocated memory.
|
||||
(std_get_configuration): Use usb_lld_reply_request.
|
||||
(handle_setup0): Follow the change.
|
||||
* src/usb_ctrl.c (vcom_port_data_setup, usb_cb_setup)
|
||||
(usb_cb_interface): Use usb_lld_reply_request.
|
||||
* src/usb_desc.c (usb_cb_get_descriptor): Likewise.
|
||||
|
||||
2015-07-24 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/gnuk_put_binary.py: Remove.
|
||||
* tool/gnuk_remove_keys.py: Remove.
|
||||
|
||||
2015-07-23 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (nl): New. Follow the change of NeuG.
|
||||
|
||||
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.
|
||||
|
||||
34
NEWS
34
NEWS
@@ -1,5 +1,37 @@
|
||||
Gnuk NEWS - User visible changes
|
||||
|
||||
* Major changes in Gnuk 1.1.7
|
||||
|
||||
Released 2015-08-05, by NIIBE Yutaka
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 0.08, which supports STM32 Nucleo and ST Dongle.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.1.6
|
||||
|
||||
Released 2015-07-21, by NIIBE Yutaka
|
||||
|
||||
** 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
|
||||
@@ -8,7 +40,7 @@ Gnuk NEWS - User visible changes
|
||||
Since it's getting stable, no debug output any more.
|
||||
|
||||
** Maple mini support.
|
||||
Although it's random number generation is not tested, Maple mini
|
||||
Although its random number generation is not tested, Maple mini
|
||||
support is added.
|
||||
|
||||
** Windows interoperability fix.
|
||||
|
||||
86
README
86
README
@@ -1,24 +1,29 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 1.1.5
|
||||
2015-06-03
|
||||
Version 1.1.7
|
||||
2015-08-05
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
Warning
|
||||
=======
|
||||
|
||||
This is another experimental release of Gnuk, version 1.1.5, which has
|
||||
This is another experimental release of Gnuk, version 1.1.7, 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?
|
||||
@@ -114,31 +119,37 @@ 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
|
||||
|
||||
|
||||
|
||||
|
||||
Release notes
|
||||
=============
|
||||
|
||||
This is third experimental release in version 1.1 series of Gnuk.
|
||||
This is seventh 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:
|
||||
|
||||
@@ -197,6 +208,19 @@ Note that you need pinpad support for GnuPG to use PIN-pad enabled
|
||||
Gnuk. The pinpad support for GnuPG is only available in version 2.
|
||||
|
||||
|
||||
Build system and Host system
|
||||
============================
|
||||
|
||||
Makefile is written for GNU make. You need Bash 4.x for configure.
|
||||
|
||||
If your bash is not installed as /bin/bash, you need to run configure
|
||||
script prepending 'bash' before './configure'.
|
||||
|
||||
Some tools are written in Python. If your Python is not installed as
|
||||
/usr/bin/python, please prepend 'python' for your command invocation.
|
||||
Python 2.7 and PyUSB 0.4.3 is assumed.
|
||||
|
||||
|
||||
Souce code
|
||||
==========
|
||||
|
||||
@@ -229,14 +253,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/
|
||||
|
||||
@@ -356,7 +380,8 @@ Here, you need to specify USB vendor ID and product ID. For FSIJ's,
|
||||
it's: --vidpid=234b:0000 . Please read section 'USB vendor ID and
|
||||
product ID' above.
|
||||
|
||||
Type:
|
||||
|
||||
Then, type:
|
||||
|
||||
$ make
|
||||
|
||||
@@ -388,11 +413,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
|
||||
@@ -449,7 +473,7 @@ In case of PyUSB tool, you need to stop pcscd.
|
||||
|
||||
If you use fixed serial number in the file 'GNUK_SERIAL_NUMBER', you can do:
|
||||
|
||||
$ EMAIL=<YOUR-EMAIL-ADDRESS> ../tool/gnuk_put_binary.py -s ../GNUK_SERIAL_NUMBER
|
||||
$ EMAIL=<YOUR-EMAIL-ADDRESS> ../tool/gnuk_put_binary_usb.py -s ../GNUK_SERIAL_NUMBER
|
||||
Writing serial number
|
||||
...
|
||||
|
||||
@@ -457,7 +481,7 @@ If you use fixed serial number in the file 'GNUK_SERIAL_NUMBER', you can do:
|
||||
|
||||
If you have card holder certificate binary file, you can do:
|
||||
|
||||
$ ../tool/gnuk_put_binary.py ../../<YOUR-CERTIFICATE>.bin
|
||||
$ ../tool/gnuk_put_binary_usb.py ../../<YOUR-CERTIFICATE>.bin
|
||||
../../<YOUR-CERTIFICATE>.bin: <LENGTH-OF-YOUR-CERTIFICATE>
|
||||
Updating card holder certificate
|
||||
...
|
||||
|
||||
1
THANKS
1
THANKS
@@ -10,6 +10,7 @@ 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
|
||||
Bertrand Jacquin bertrand@jacquin.bzh
|
||||
Hironobu SUZUKI hironobu@h2np.net
|
||||
Jan Suhr jan@suhr.info
|
||||
Kaz Kojima kkojima@rr.iij4u.or.jp
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/*
|
||||
* Board-specific initialization code.
|
||||
*/
|
||||
void boardInit(void)
|
||||
{
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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"
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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"
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
2
chopstx
2
chopstx
Submodule chopstx updated: fc26cf0889...218102c5c4
@@ -37,9 +37,3 @@ The tool ``../tool/gnuk_put_binary_libusb.py`` examines environment variable of
|
||||
Configuration: 1
|
||||
Interface: 0
|
||||
d2 76 00 01 24 01 02 00 f5 17 00 00 00 01 00 00
|
||||
|
||||
|
||||
The example above is the case of libusb version.
|
||||
|
||||
Use the tool ``../tool/gnuk_put_binary.py`` instead , for PC/SC Lite.
|
||||
You need PyScard for this.
|
||||
|
||||
220
misc/debug-bn.c
Normal file
220
misc/debug-bn.c
Normal 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
92
misc/t-mont.c
Normal 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;
|
||||
}
|
||||
@@ -209,9 +209,7 @@
|
||||
*
|
||||
* Enable the RSA prime-number generation code.
|
||||
*/
|
||||
#ifdef KEYGEN_SUPPORT
|
||||
#define POLARSSL_GENPRIME
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def POLARSSL_FS_IO
|
||||
|
||||
@@ -32,7 +32,7 @@ LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT)
|
||||
|
||||
all: regnual.hex
|
||||
|
||||
regnual.o: regnual.c ../src/sys.h
|
||||
regnual.o: regnual.c ../src/sys.h ../src/usb_lld.h
|
||||
|
||||
regnual.hex: regnual.elf
|
||||
$(OBJCOPY) -Obinary regnual.elf regnual.bin
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* regnual.c -- Firmware installation for STM32F103 Flash ROM
|
||||
*
|
||||
* 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.
|
||||
@@ -32,12 +33,18 @@
|
||||
extern void *memset (void *s, int c, size_t n);
|
||||
|
||||
extern void set_led (int);
|
||||
extern uint8_t _flash_start, _flash_end;
|
||||
extern int flash_write (uint32_t dst_addr, const uint8_t *src, size_t len);
|
||||
extern int flash_protect (void);
|
||||
extern void nvic_system_reset (void);
|
||||
|
||||
|
||||
#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 FLASH_SIZE_REG ((uint16_t *)0x1ffff7e0)
|
||||
static uint32_t flash_end;
|
||||
|
||||
|
||||
#define ENDP0_RXADDR (0x40)
|
||||
#define ENDP0_TXADDR (0x80)
|
||||
|
||||
@@ -166,8 +173,7 @@ static uint32_t calc_crc32 (void)
|
||||
}
|
||||
|
||||
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len)
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
@@ -175,24 +181,21 @@ void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
{
|
||||
if (req_no == USB_REGNUAL_SEND && value == 0)
|
||||
result = calc_crc32 ();
|
||||
else if (req_no == USB_REGNUAL_FLASH && len == 0 && index == 0)
|
||||
else if (req_no == USB_REGNUAL_FLASH)
|
||||
{
|
||||
uint32_t dst_addr = (0x08000000 + value * 0x100);
|
||||
|
||||
result = flash_write (dst_addr, (const uint8_t *)mem, 256);
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_PROTECT && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
else if (req_no == USB_REGNUAL_PROTECT && value == 0)
|
||||
result = flash_protect ();
|
||||
else if (req_no == USB_REGNUAL_FINISH && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
else if (req_no == USB_REGNUAL_FINISH && value == 0)
|
||||
nvic_system_reset ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
@@ -202,45 +205,42 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
{
|
||||
if (req_no == USB_REGNUAL_MEMINFO)
|
||||
{
|
||||
static const uint8_t *mem_info[2];
|
||||
const uint8_t *mem_info[2];
|
||||
|
||||
mem_info[0] = &_flash_start;
|
||||
mem_info[1] = &_flash_end;
|
||||
usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
|
||||
return USB_SUCCESS;
|
||||
mem_info[0] = (const uint8_t *)FLASH_START;
|
||||
mem_info[1] = (const uint8_t *)flash_end;
|
||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), detail);
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_RESULT)
|
||||
{
|
||||
usb_lld_set_data_to_send (&result, sizeof (uint32_t));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (&result, sizeof (uint32_t), detail);
|
||||
}
|
||||
else /* SETUP_SET */
|
||||
{
|
||||
if (req_no == USB_REGNUAL_SEND)
|
||||
{
|
||||
if (value != 0 || index + len > 256)
|
||||
if (detail->value != 0 || detail->index + detail->len > 256)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (index + len < 256)
|
||||
memset ((uint8_t *)mem + index + len, 0xff,
|
||||
256 - (index + len));
|
||||
if (detail->index + detail->len < 256)
|
||||
memset ((uint8_t *)mem + detail->index + detail->len, 0xff,
|
||||
256 - (detail->index + detail->len));
|
||||
|
||||
usb_lld_set_data_to_recv (mem + index, len);
|
||||
usb_lld_set_data_to_recv (mem + detail->index, detail->len);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_FLASH && len == 0 && index == 0)
|
||||
else if (req_no == USB_REGNUAL_FLASH && detail->len == 0
|
||||
&& detail->index == 0)
|
||||
{
|
||||
uint32_t dst_addr = (0x08000000 + value * 0x100);
|
||||
uint32_t dst_addr = (0x08000000 + detail->value * 0x100);
|
||||
|
||||
if (dst_addr + 256 <= (uint32_t)&_flash_end)
|
||||
if (dst_addr + 256 <= flash_end)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_PROTECT && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
else if (req_no == USB_REGNUAL_PROTECT && detail->len == 0
|
||||
&& detail->value == 0 && detail->index == 0)
|
||||
return USB_SUCCESS;
|
||||
else if (req_no == USB_REGNUAL_FINISH && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
else if (req_no == USB_REGNUAL_FINISH && detail->len == 0
|
||||
&& detail->value == 0 && detail->index == 0)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -250,24 +250,17 @@ 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)
|
||||
struct control_info *detail)
|
||||
{
|
||||
(void)index;
|
||||
if (rcp != DEVICE_RECIPIENT)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (desc_type == DEVICE_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (regnual_device_desc,
|
||||
sizeof (regnual_device_desc));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (regnual_device_desc,
|
||||
sizeof (regnual_device_desc), detail);
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (regnual_config_desc,
|
||||
sizeof (regnual_config_desc));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (regnual_config_desc,
|
||||
sizeof (regnual_config_desc), detail);
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
const uint8_t *str;
|
||||
@@ -280,12 +273,12 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
size = sizeof (regnual_string_lang_id);
|
||||
break;
|
||||
case 1:
|
||||
str = gnukStringVendor;
|
||||
size = sizeof (gnukStringVendor);
|
||||
str = gnuk_string_vendor;
|
||||
size = sizeof (gnuk_string_vendor);
|
||||
break;
|
||||
case 2:
|
||||
str = gnukStringProduct;
|
||||
size = sizeof (gnukStringProduct);
|
||||
str = gnuk_string_product;
|
||||
size = sizeof (gnuk_string_product);
|
||||
break;
|
||||
case 3:
|
||||
str = regnual_string_serial;
|
||||
@@ -295,8 +288,7 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
usb_lld_set_data_to_send (str, size);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_reply_request (str, size, detail);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
@@ -318,9 +310,9 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
|
||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
||||
{
|
||||
(void)cmd; (void)interface; (void)alt;
|
||||
(void)cmd; (void)detail;
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
@@ -342,6 +334,7 @@ main (int argc, char *argv[])
|
||||
|
||||
set_led (0);
|
||||
|
||||
flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
|
||||
usb_lld_init (regnual_config_desc[7]);
|
||||
|
||||
while (1)
|
||||
|
||||
@@ -12,8 +12,6 @@ MEMORY
|
||||
}
|
||||
|
||||
vector = 0x08000000;
|
||||
_flash_start = 0x08001000;
|
||||
_flash_end = 0x08020000;
|
||||
|
||||
__ram_start__ = ORIGIN(ram0);
|
||||
__ram_size__ = 20k;
|
||||
|
||||
@@ -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 = @KEYGEN_SUPPORT@ @HAVE_SYS_H@
|
||||
DEFS = @HAVE_SYS_H@
|
||||
OPT = -O3 -Os -g
|
||||
LIBS =
|
||||
|
||||
|
||||
@@ -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,69 @@ 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:
|
||||
case BOARD_ID_ST_DONGLE:
|
||||
case BOARD_ID_ST_NUCLEO_F103:
|
||||
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 +208,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
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -204,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)
|
||||
{
|
||||
@@ -245,4 +244,3 @@ rsa_genkey (int pubkey_len)
|
||||
else
|
||||
return p_q_modulus;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
@PINPAD_MORE_DEFINE@
|
||||
@CERTDO_DEFINE@
|
||||
@HID_CARD_CHANGE_DEFINE@
|
||||
@SERIALNO_STR_LEN@
|
||||
@SERIALNO_STR_LEN_DEFINE@
|
||||
|
||||
165
src/configure
vendored
165
src/configure
vendored
@@ -1,5 +1,8 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This is bash which supports ANSI-C Quoting
|
||||
nl=$'\n'
|
||||
|
||||
#
|
||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||
#
|
||||
@@ -27,12 +30,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 +70,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 ;;
|
||||
--disable-hid-card-change)
|
||||
hid_card_change=no ;;
|
||||
--enable-sys1-compat)
|
||||
sys1_compat=yes ;;
|
||||
--disable-sys1-compat)
|
||||
sys1_compat=no ;;
|
||||
--with-dfu)
|
||||
with_dfu=yes ;;
|
||||
--without-dfu)
|
||||
@@ -98,15 +103,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]
|
||||
@@ -122,14 +128,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
|
||||
@@ -173,7 +178,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"
|
||||
@@ -220,15 +225,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"
|
||||
@@ -238,65 +234,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 */\\${nl} 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 -e "s/\(........\)/\1\\${nl}/g" | 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 -e "s/\(........\)/\1\\${nl}/g" | 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 -e "s/\(........\)/\1\\${nl}/g" | 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 -e "s/\(........\)/\1\\${nl}/g" | 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 -e "s/\(........\)/\1\\${nl}/g" | 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
|
||||
@@ -307,8 +320,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"
|
||||
@@ -316,10 +329,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
|
||||
@@ -347,6 +360,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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
32
src/ecc.c
32
src/ecc.c
@@ -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);
|
||||
}
|
||||
|
||||
46
src/flash.c
46
src/flash.c
@@ -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;
|
||||
|
||||
@@ -116,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 {
|
||||
@@ -162,7 +163,6 @@ int flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
|
||||
/* Linker set these two symbols */
|
||||
extern uint8_t ch_certificate_start;
|
||||
extern uint8_t random_bits_start;
|
||||
|
||||
#define FIRMWARE_UPDATE_KEY_CONTENT_LEN 256 /* RSA-2048 (p and q) */
|
||||
|
||||
@@ -266,12 +266,14 @@ 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);
|
||||
|
||||
@@ -279,6 +281,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);
|
||||
@@ -409,7 +414,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
14
src/main.c
14
src/main.c
@@ -28,7 +28,6 @@
|
||||
#include <eventflag.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "adc.h"
|
||||
@@ -127,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)
|
||||
{
|
||||
@@ -135,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);
|
||||
@@ -426,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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
236
src/openpgp-do.c
236
src/openpgp-do.c
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -464,11 +489,13 @@ static int
|
||||
do_hist_bytes (uint16_t tag, int with_tag)
|
||||
{
|
||||
/*
|
||||
* Currently, we support no life cycle management.
|
||||
* In case of Gnuk, user could flash the MCU, instead.
|
||||
* Thus, just return the template as is.
|
||||
* Currently, we support no life cycle management. In case of Gnuk,
|
||||
* user could flash the MCU with SWD/JTAG, instead. It is also
|
||||
* possible for user to do firmware upgrade through USB.
|
||||
*
|
||||
* In future (when Gnuk will be onn the real smartcard),
|
||||
* Thus, here, it just returns the template as is.
|
||||
*
|
||||
* In future (when Gnuk will be on the real smartcard),
|
||||
* we can support life cycle management by implementing
|
||||
* TERMINATE DF / ACTIVATE FILE and fix code around here.
|
||||
*/
|
||||
@@ -724,6 +751,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 +1078,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 +1101,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 +1329,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 +1365,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 +1380,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 +1393,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 +1959,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 +2032,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 +2054,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 +2158,3 @@ gpg_do_keygen (uint8_t kk_byte)
|
||||
|
||||
gpg_do_public_key (kk_byte);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -942,15 +937,11 @@ cmd_pso (void)
|
||||
}
|
||||
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
|
||||
{
|
||||
int header_size = -1;
|
||||
|
||||
if (len == 65)
|
||||
header_size = 0;
|
||||
else if (len == 65 + ECC_CIPHER_DO_HEADER_SIZE)
|
||||
header_size = ECC_CIPHER_DO_HEADER_SIZE;
|
||||
int header = ECC_CIPHER_DO_HEADER_SIZE;
|
||||
|
||||
/* Format is in big endian MPI: 04 || x || y */
|
||||
if (header_size < 0 || apdu.cmd_apdu_data[header_size] != 4)
|
||||
if (len != 65 + ECC_CIPHER_DO_HEADER_SIZE
|
||||
|| apdu.cmd_apdu_data[header] != 0x04)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
@@ -958,12 +949,26 @@ cmd_pso (void)
|
||||
|
||||
result_len = 65;
|
||||
if (attr == ALGO_NISTP256R1)
|
||||
r = ecdh_decrypt_p256r1 (apdu.cmd_apdu_data + header_size, 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 + header_size, res_APDU,
|
||||
r = ecdh_decrypt_p256k1 (apdu.cmd_apdu_data + header, res_APDU,
|
||||
kd[GPG_KEY_FOR_DECRYPTION].data);
|
||||
}
|
||||
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.");
|
||||
|
||||
@@ -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
262
src/sys.c
@@ -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;
|
||||
|
||||
14
src/sys.h
14
src/sys.h
@@ -1,4 +1,18 @@
|
||||
#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
|
||||
#define BOARD_ID_ST_DONGLE 0x2cd4e471
|
||||
#define BOARD_ID_ST_NUCLEO_F103 0x9b87c16d
|
||||
|
||||
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];
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* usb-msc.c -- USB Mass Storage Class protocol handling
|
||||
*
|
||||
* 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 Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -170,11 +171,13 @@ EP6_OUT_Callback (void)
|
||||
}
|
||||
|
||||
static const uint8_t scsi_inquiry_data_00[] = { 0, 0, 0, 0, 0 };
|
||||
static const uint8_t scsi_inquiry_data_83[] = { 0, 0x83, 0, 0 };
|
||||
|
||||
|
||||
static const uint8_t scsi_inquiry_data[] = {
|
||||
0x00, /* Direct Access Device. */
|
||||
0x80, /* RMB = 1: Removable Medium. */
|
||||
0x05, /* Version: SPC-3. */
|
||||
0x00, /* Version: not claim conformance. */
|
||||
0x02, /* Response format: SPC-3. */
|
||||
36 - 4, /* Additional Length. */
|
||||
0x00,
|
||||
@@ -330,6 +333,11 @@ msc_handle_command (void)
|
||||
|
||||
CSW.dCSWTag = CBW.dCBWTag;
|
||||
switch (CBW.CBWCB[0]) {
|
||||
case SCSI_REPORT_LUN:
|
||||
buf[0] = buf[1] = buf[2] = buf[3] = 0;
|
||||
buf[4] = buf[5] = buf[6] = buf[7] = 0;
|
||||
msc_send_result (buf, 8);
|
||||
goto done;
|
||||
case SCSI_REQUEST_SENSE:
|
||||
if (CBW.CBWCB[1] & 0x01) /* DESC */
|
||||
msc_send_result ((uint8_t *)&scsi_sense_data_desc,
|
||||
@@ -345,10 +353,18 @@ msc_handle_command (void)
|
||||
}
|
||||
goto done;
|
||||
case SCSI_INQUIRY:
|
||||
if (CBW.CBWCB[1] & 0x01) /* EVPD */
|
||||
/* assume page 00 */
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data_00,
|
||||
sizeof scsi_inquiry_data_00);
|
||||
if (CBW.CBWCB[1] & 0x01)
|
||||
/* EVPD */
|
||||
{
|
||||
if (CBW.CBWCB[2] == 0x83)
|
||||
/* Handle the case Page Code 0x83 */
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data_83,
|
||||
sizeof scsi_inquiry_data_83);
|
||||
else
|
||||
/* Otherwise, assume page 00 */
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data_00,
|
||||
sizeof scsi_inquiry_data_00);
|
||||
}
|
||||
else
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data,
|
||||
sizeof scsi_inquiry_data);
|
||||
@@ -462,6 +478,7 @@ msc_handle_command (void)
|
||||
if (CBW.CBWCB[8]-- == 0)
|
||||
CBW.CBWCB[7]--;
|
||||
CSW.dCSWDataResidue += 512;
|
||||
lba++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -507,6 +524,7 @@ msc_handle_command (void)
|
||||
if (CBW.CBWCB[8]-- == 0)
|
||||
CBW.CBWCB[7]--;
|
||||
CSW.dCSWDataResidue -= 512;
|
||||
lba++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#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
|
||||
|
||||
@@ -58,15 +58,12 @@ static struct line_coding line_coding = {
|
||||
};
|
||||
|
||||
static int
|
||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_CDC_REQ_GET_LINE_CODING)
|
||||
{
|
||||
usb_lld_set_data_to_send (&line_coding, sizeof(line_coding));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (&line_coding, sizeof(line_coding), detail);
|
||||
}
|
||||
else /* USB_SETUP_SET (req) */
|
||||
{
|
||||
@@ -79,7 +76,7 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
{
|
||||
uint8_t connected_saved = stdout.connected;
|
||||
|
||||
if (value != 0)
|
||||
if (detail->value != 0)
|
||||
{
|
||||
if (stdout.connected == 0)
|
||||
/* It's Open call */
|
||||
@@ -262,8 +259,7 @@ static int download_check_crc32 (const uint32_t *end_p)
|
||||
}
|
||||
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
@@ -272,30 +268,27 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_FSIJ_GNUK_MEMINFO)
|
||||
{
|
||||
usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), detail);
|
||||
}
|
||||
else /* SETUP_SET */
|
||||
{
|
||||
uint8_t *addr = (uint8_t *)(0x20000000 + value * 0x100 + index);
|
||||
uint8_t *addr = (uint8_t *)(0x20000000 + detail->value * 0x100 + detail->index);
|
||||
|
||||
if (req_no == USB_FSIJ_GNUK_DOWNLOAD)
|
||||
{
|
||||
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (addr < &_regnual_start || addr + len > __heap_end__)
|
||||
if (addr < &_regnual_start || addr + detail->len > __heap_end__)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (index + len < 256)
|
||||
memset (addr + index + len, 0, 256 - (index + len));
|
||||
if (detail->index + detail->len < 256)
|
||||
memset (addr + detail->index + detail->len, 0, 256 - (detail->index + detail->len));
|
||||
|
||||
usb_lld_set_data_to_recv (addr, len);
|
||||
usb_lld_set_data_to_recv (addr, detail->len);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_FSIJ_GNUK_EXEC && len == 0)
|
||||
else if (req_no == USB_FSIJ_GNUK_EXEC && detail->len == 0)
|
||||
{
|
||||
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||
return USB_UNSUPPORT;
|
||||
@@ -305,33 +298,28 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
|
||||
return download_check_crc32 ((uint32_t *)addr);
|
||||
}
|
||||
else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && len == 0)
|
||||
else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && detail->len == 0)
|
||||
{
|
||||
if (value != 0 && value != 1 && value != 2)
|
||||
if (detail->value != 0 && detail->value != 1 && detail->value != 2)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
ccid_card_change_signal (value);
|
||||
ccid_card_change_signal (detail->value);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||
{
|
||||
if (index == ICC_INTERFACE)
|
||||
if (detail->index == ICC_INTERFACE)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
||||
{
|
||||
usb_lld_set_data_to_send (freq_table, sizeof (freq_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (freq_table, sizeof (freq_table),
|
||||
detail);
|
||||
else if (req_no == USB_CCID_REQ_GET_DATA_RATES)
|
||||
{
|
||||
usb_lld_set_data_to_send (data_rate_table,
|
||||
sizeof (data_rate_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (data_rate_table,
|
||||
sizeof (data_rate_table), detail);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -347,21 +335,19 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
switch (req_no)
|
||||
{
|
||||
case USB_HID_REQ_GET_IDLE:
|
||||
usb_lld_set_data_to_send (&hid_idle_rate, 1);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_reply_request (&hid_idle_rate, 1, detail);
|
||||
case USB_HID_REQ_SET_IDLE:
|
||||
usb_lld_set_data_to_recv (&hid_idle_rate, 1);
|
||||
usb_lld_set_data_to_recv (&hid_idle_rate, 1, detail);
|
||||
return USB_SUCCESS;
|
||||
|
||||
case USB_HID_REQ_GET_REPORT:
|
||||
/* Request of LED status and key press */
|
||||
usb_lld_set_data_to_send (&hid_report, 2);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_reply_request (&hid_report, 2, detail);
|
||||
|
||||
case USB_HID_REQ_SET_REPORT:
|
||||
/* Received LED set request */
|
||||
if (len == 1)
|
||||
usb_lld_set_data_to_recv (&hid_report, len);
|
||||
if (detail->len == 1)
|
||||
usb_lld_set_data_to_recv (&hid_report, detail->len);
|
||||
return USB_SUCCESS;
|
||||
|
||||
case USB_HID_REQ_GET_PROTOCOL:
|
||||
@@ -376,7 +362,7 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
#endif
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
else if (index == VCOM_INTERFACE_0)
|
||||
return vcom_port_data_setup (req, req_no, value);
|
||||
return vcom_port_data_setup (req, req_no, detail);
|
||||
#endif
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
else if (index == MSC_INTERFACE)
|
||||
@@ -384,10 +370,8 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == MSC_GET_MAX_LUN_COMMAND)
|
||||
{
|
||||
usb_lld_set_data_to_send (lun_table, sizeof (lun_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (lun_table, sizeof (lun_table),
|
||||
detail);
|
||||
}
|
||||
else
|
||||
if (req_no == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||
@@ -402,14 +386,13 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
|
||||
|
||||
void
|
||||
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len)
|
||||
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
||||
{
|
||||
if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC && len == 0)
|
||||
if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC)
|
||||
{
|
||||
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||
return;
|
||||
@@ -476,9 +459,11 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
|
||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
||||
{
|
||||
static const uint8_t zero = 0;
|
||||
const uint8_t zero = 0;
|
||||
uint16_t interface = detail->index;
|
||||
uint16_t alt = detail->value;
|
||||
|
||||
if (interface >= NUM_INTERFACES)
|
||||
return USB_UNSUPPORT;
|
||||
@@ -495,11 +480,10 @@ 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);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_reply_request (&zero, 1, detail);
|
||||
|
||||
default:
|
||||
case USB_QUERY_INTERFACE:
|
||||
default:
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ static const uint8_t hid_report_desc[] = {
|
||||
#define USB_ICC_DATA_SIZE 64
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t gnukDeviceDescriptor[] = {
|
||||
static const uint8_t device_desc[] = {
|
||||
18, /* bLength */
|
||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||
@@ -99,7 +99,7 @@ static const uint8_t gnukDeviceDescriptor[] = {
|
||||
|
||||
|
||||
/* Configuation Descriptor */
|
||||
static const uint8_t gnukConfigDescriptor[] = {
|
||||
static const uint8_t config_desc[] = {
|
||||
9, /* bLength: Configuation Descriptor size */
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
||||
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
|
||||
@@ -315,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 */
|
||||
@@ -330,78 +330,70 @@ 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)
|
||||
struct control_info *detail)
|
||||
{
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (desc_type == DEVICE_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (gnukDeviceDescriptor,
|
||||
sizeof (gnukDeviceDescriptor));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (device_desc, sizeof (device_desc), detail);
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (gnukConfigDescriptor,
|
||||
sizeof (gnukConfigDescriptor));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (config_desc, sizeof (config_desc), detail);
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
if (desc_index < NUM_STRING_DESC)
|
||||
return usb_lld_reply_request (string_descriptors[desc_index].desc,
|
||||
string_descriptors[desc_index].size,
|
||||
detail);
|
||||
else 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;
|
||||
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;
|
||||
return usb_lld_reply_request (usbbuf, len, detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
else if (rcp == INTERFACE_RECIPIENT)
|
||||
{
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
if (index == 1)
|
||||
if (detail->index == 1)
|
||||
{
|
||||
if (desc_type == USB_DT_HID)
|
||||
{
|
||||
usb_lld_set_data_to_send (gnukConfigDescriptor+ICC_TOTAL_LENGTH+9,
|
||||
9);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (config_desc+ICC_TOTAL_LENGTH+9, 9,
|
||||
detail);
|
||||
else if (desc_type == USB_DT_REPORT)
|
||||
{
|
||||
usb_lld_set_data_to_send (hid_report_desc, HID_REPORT_DESC_SIZE);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
#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_lld_reply_request (hid_report_desc, HID_REPORT_DESC_SIZE,
|
||||
detail);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
@@ -55,15 +55,19 @@ enum
|
||||
USB_SUCCESS = 1,
|
||||
};
|
||||
|
||||
struct control_info {
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
void usb_cb_device_reset (void);
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len);
|
||||
int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len);
|
||||
int usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail);
|
||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail);
|
||||
int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
uint16_t index);
|
||||
struct control_info *detail);
|
||||
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);
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value);
|
||||
|
||||
enum {
|
||||
USB_EVENT_ADDRESS,
|
||||
@@ -89,7 +93,6 @@ enum DEVICE_STATE
|
||||
CONFIGURED
|
||||
};
|
||||
|
||||
|
||||
void usb_lld_init (uint8_t feature);
|
||||
void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
|
||||
void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
|
||||
@@ -99,6 +102,8 @@ int usb_lld_tx_data_len (int ep_num);
|
||||
void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len);
|
||||
void usb_lld_tx_enable (int ep_num, size_t len);
|
||||
void usb_lld_write (uint8_t ep_num, const void *buf, size_t len);
|
||||
int usb_lld_reply_request (const void *buf, size_t buflen,
|
||||
struct control_info *ctrl);
|
||||
void usb_lld_rx_enable (int ep_num);
|
||||
int usb_lld_rx_data_len (int ep_num);
|
||||
void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len);
|
||||
@@ -109,12 +114,7 @@ void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
|
||||
void usb_lld_set_configuration (uint8_t config);
|
||||
uint8_t usb_lld_current_configuration (void);
|
||||
void usb_lld_set_feature (uint8_t feature);
|
||||
void usb_lld_set_data_to_send (const void *p, size_t len);
|
||||
|
||||
extern inline void usb_lld_set_data_to_recv (void *p, size_t len)
|
||||
{
|
||||
usb_lld_set_data_to_send ((const void *)p, len);
|
||||
}
|
||||
void usb_lld_set_data_to_recv (const void *p, size_t len);
|
||||
|
||||
void usb_lld_prepare_shutdown (void);
|
||||
void usb_lld_shutdown (void);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#include "sys.h"
|
||||
#include "usb_lld.h"
|
||||
|
||||
@@ -49,33 +46,27 @@ enum FEATURE_SELECTOR
|
||||
|
||||
struct DATA_INFO
|
||||
{
|
||||
uint16_t len;
|
||||
uint16_t offset;
|
||||
uint8_t *addr;
|
||||
uint16_t len;
|
||||
uint8_t require_zlp;
|
||||
};
|
||||
|
||||
struct CONTROL_INFO
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
};
|
||||
|
||||
struct DEVICE_INFO
|
||||
{
|
||||
uint8_t current_configuration;
|
||||
uint8_t current_feature;
|
||||
uint8_t state;
|
||||
/**/
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
/**/
|
||||
uint16_t value;
|
||||
};
|
||||
|
||||
static struct CONTROL_INFO control_info;
|
||||
static struct DEVICE_INFO device_info;
|
||||
static struct DATA_INFO data_info;
|
||||
|
||||
static struct CONTROL_INFO *const ctrl_p = &control_info;
|
||||
static struct DEVICE_INFO *const dev_p = &device_info;
|
||||
static struct DATA_INFO *const data_p = &data_info;
|
||||
|
||||
@@ -412,16 +403,14 @@ static void handle_datastage_out (void)
|
||||
{
|
||||
if (data_p->addr && data_p->len)
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint32_t len = st103_get_rx_count (ENDP0);
|
||||
|
||||
if (len > data_p->len)
|
||||
len = data_p->len;
|
||||
|
||||
buf = data_p->addr + data_p->offset;
|
||||
usb_lld_from_pmabuf (buf, st103_get_rx_addr (ENDP0), len);
|
||||
usb_lld_from_pmabuf (data_p->addr, st103_get_rx_addr (ENDP0), len);
|
||||
data_p->len -= len;
|
||||
data_p->offset += len;
|
||||
data_p->addr += len;
|
||||
}
|
||||
|
||||
if (data_p->len == 0)
|
||||
@@ -440,13 +429,12 @@ static void handle_datastage_out (void)
|
||||
static void handle_datastage_in (void)
|
||||
{
|
||||
uint32_t len = USB_MAX_PACKET_SIZE;;
|
||||
const uint8_t *buf;
|
||||
|
||||
if ((data_p->len == 0) && (dev_p->state == LAST_IN_DATA))
|
||||
{
|
||||
if (data_p->require_zlp == TRUE)
|
||||
if (data_p->require_zlp)
|
||||
{
|
||||
data_p->require_zlp = FALSE;
|
||||
data_p->require_zlp = 0;
|
||||
|
||||
/* No more data to send. Send empty packet */
|
||||
st103_set_tx_count (ENDP0, 0);
|
||||
@@ -467,40 +455,33 @@ static void handle_datastage_in (void)
|
||||
if (len > data_p->len)
|
||||
len = data_p->len;
|
||||
|
||||
buf = (const uint8_t *)data_p->addr + data_p->offset;
|
||||
usb_lld_to_pmabuf (buf, st103_get_tx_addr (ENDP0), len);
|
||||
usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len);
|
||||
data_p->len -= len;
|
||||
data_p->offset += len;
|
||||
data_p->addr += len;
|
||||
st103_set_tx_count (ENDP0, len);
|
||||
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
||||
}
|
||||
|
||||
typedef int (*HANDLER) (uint8_t req,
|
||||
uint16_t value, uint16_t index, uint16_t length);
|
||||
typedef int (*HANDLER) (uint8_t req, struct control_info *detail);
|
||||
|
||||
static int std_none (uint8_t req,
|
||||
uint16_t value, uint16_t index, uint16_t length)
|
||||
static int std_none (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
(void)req; (void)value; (void)index; (void)length;
|
||||
(void)req; (void)detail;
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_get_status (uint8_t req,
|
||||
uint16_t value, uint16_t index, uint16_t length)
|
||||
static int std_get_status (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
static uint16_t status_info;
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
uint16_t status_info = 0;
|
||||
|
||||
status_info = 0; /* Reset Status Information */
|
||||
data_p->addr = (uint8_t *)&status_info;
|
||||
|
||||
if (value != 0 || length != 2 || (index >> 8) != 0
|
||||
if (detail->value != 0 || detail->len != 2 || (detail->index >> 8) != 0
|
||||
|| (req & REQUEST_DIR) == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (index == 0)
|
||||
if (detail->index == 0)
|
||||
{
|
||||
/* Get Device Status */
|
||||
uint8_t feature = dev_p->current_feature;
|
||||
@@ -517,8 +498,7 @@ static int std_get_status (uint8_t req,
|
||||
else /* Self-powered */
|
||||
status_info &= ~1;
|
||||
|
||||
data_p->len = 2;
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_reply_request (&status_info, 2, detail);
|
||||
}
|
||||
}
|
||||
else if (rcp == INTERFACE_RECIPIENT)
|
||||
@@ -528,22 +508,21 @@ static int std_get_status (uint8_t req,
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
r = usb_cb_interface (USB_QUERY_INTERFACE, index, 0);
|
||||
r = usb_cb_interface (USB_QUERY_INTERFACE, detail);
|
||||
if (r != USB_SUCCESS)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
data_p->len = 2;
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_reply_request (&status_info, 2, detail);
|
||||
}
|
||||
else if (rcp == ENDPOINT_RECIPIENT)
|
||||
{
|
||||
uint8_t endpoint = (index & 0x0f);
|
||||
uint8_t endpoint = (detail->index & 0x0f);
|
||||
uint16_t status;
|
||||
|
||||
if ((index & 0x70) || endpoint == ENDP0)
|
||||
if ((detail->index & 0x70) || endpoint == ENDP0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if ((index & 0x80))
|
||||
if ((detail->index & 0x80))
|
||||
{
|
||||
status = st103_ep_get_tx_status (endpoint);
|
||||
if (status == 0) /* Disabled */
|
||||
@@ -560,15 +539,13 @@ static int std_get_status (uint8_t req,
|
||||
status_info |= 1; /* OUT Endpoint stalled */
|
||||
}
|
||||
|
||||
data_p->len = 2;
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_reply_request (&status_info, 2, detail);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_clear_feature (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_clear_feature (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
@@ -577,10 +554,10 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (length != 0 || index != 0)
|
||||
if (detail->len != 0 || detail->index != 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (value == DEVICE_REMOTE_WAKEUP)
|
||||
if (detail->value == DEVICE_REMOTE_WAKEUP)
|
||||
{
|
||||
dev_p->current_feature &= ~(1 << 5);
|
||||
return USB_SUCCESS;
|
||||
@@ -588,17 +565,17 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
||||
}
|
||||
else if (rcp == ENDPOINT_RECIPIENT)
|
||||
{
|
||||
uint8_t endpoint = (index & 0x0f);
|
||||
uint8_t endpoint = (detail->index & 0x0f);
|
||||
uint16_t status;
|
||||
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (length != 0 || (index >> 8) != 0 || value != ENDPOINT_STALL
|
||||
|| endpoint == ENDP0)
|
||||
if (detail->len != 0 || (detail->index >> 8) != 0
|
||||
|| detail->value != ENDPOINT_STALL || endpoint == ENDP0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if ((index & 0x80))
|
||||
if ((detail->index & 0x80))
|
||||
status = st103_ep_get_tx_status (endpoint);
|
||||
else
|
||||
status = st103_ep_get_rx_status (endpoint);
|
||||
@@ -606,7 +583,7 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
||||
if (status == 0) /* Disabled */
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (index & 0x80) /* IN endpoint */
|
||||
if (detail->index & 0x80) /* IN endpoint */
|
||||
st103_ep_clear_dtog_tx (endpoint);
|
||||
else /* OUT endpoint */
|
||||
st103_ep_clear_dtog_rx (endpoint);
|
||||
@@ -618,8 +595,7 @@ static int std_clear_feature (uint8_t req, uint16_t value,
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_feature (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_set_feature (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
@@ -628,10 +604,10 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (length != 0 || index != 0)
|
||||
if (detail->len != 0 || detail->index != 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (value == DEVICE_REMOTE_WAKEUP)
|
||||
if (detail->value == DEVICE_REMOTE_WAKEUP)
|
||||
{
|
||||
dev_p->current_feature |= 1 << 5;
|
||||
// event??
|
||||
@@ -640,16 +616,17 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
||||
}
|
||||
else if (rcp == ENDPOINT_RECIPIENT)
|
||||
{
|
||||
uint8_t endpoint = (index & 0x0f);
|
||||
uint8_t endpoint = (detail->index & 0x0f);
|
||||
uint32_t status;
|
||||
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (length != 0 || (index >> 8) != 0 || value != 0 || endpoint == ENDP0)
|
||||
if (detail->len != 0 || (detail->index >> 8) != 0
|
||||
|| detail->value != 0 || endpoint == ENDP0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if ((index & 0x80))
|
||||
if ((detail->index & 0x80))
|
||||
status = st103_ep_get_tx_status (endpoint);
|
||||
else
|
||||
status = st103_ep_get_rx_status (endpoint);
|
||||
@@ -657,7 +634,7 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
||||
if (status == 0) /* Disabled */
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (index & 0x80)
|
||||
if (detail->index & 0x80)
|
||||
/* IN endpoint */
|
||||
st103_ep_set_tx_status (endpoint, EP_TX_STALL);
|
||||
else
|
||||
@@ -671,77 +648,59 @@ static int std_set_feature (uint8_t req, uint16_t value,
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_address (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_set_address (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (length == 0 && value <= 127 && index == 0
|
||||
&& dev_p->current_configuration == 0)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
if (rcp == DEVICE_RECIPIENT && detail->len == 0 && detail->value <= 127
|
||||
&& detail->index == 0 && dev_p->current_configuration == 0)
|
||||
return USB_SUCCESS;
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_get_descriptor (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_get_descriptor (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
(void)length;
|
||||
return usb_cb_get_descriptor (rcp, (value >> 8), (value & 0xff), index);
|
||||
return usb_cb_get_descriptor (rcp, (detail->value >> 8),
|
||||
(detail->value & 0xff), detail);
|
||||
}
|
||||
|
||||
static int std_get_configuration (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_get_configuration (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
(void)detail;
|
||||
if ((req & REQUEST_DIR) == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
(void)value; (void)index; (void)length;
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
data_p->addr = &dev_p->current_configuration;
|
||||
data_p->len = 1;
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_reply_request (&dev_p->current_configuration, 1, detail);
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_configuration (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_set_configuration (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT && index == 0 && length == 0)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = usb_cb_handle_event (USB_EVENT_CONFIG, value);
|
||||
if (r == USB_SUCCESS)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
if (rcp == DEVICE_RECIPIENT && detail->index == 0 && detail->len == 0)
|
||||
return usb_cb_handle_event (USB_EVENT_CONFIG, detail->value);
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_get_interface (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_get_interface (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
@@ -750,74 +709,61 @@ static int std_get_interface (uint8_t req, uint16_t value,
|
||||
|
||||
if (rcp == INTERFACE_RECIPIENT)
|
||||
{
|
||||
if (value != 0 || (index >> 8) != 0 || length != 1)
|
||||
if (detail->value != 0 || (detail->index >> 8) != 0 || detail->len != 1)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
return usb_cb_interface (USB_GET_INTERFACE, index, 0);
|
||||
return usb_cb_interface (USB_GET_INTERFACE, detail);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_interface (uint8_t req, uint16_t value,
|
||||
uint16_t index, uint16_t length)
|
||||
static int std_set_interface (uint8_t req, struct control_info *detail)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1)
|
||||
if ((req & REQUEST_DIR) == 1 || rcp != INTERFACE_RECIPIENT
|
||||
|| detail->len != 0 || (detail->index >> 8) != 0
|
||||
|| (detail->value >> 8) != 0 || dev_p->current_configuration != 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == INTERFACE_RECIPIENT)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (length != 0 || (index >> 8) != 0 || (value >> 8) != 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (dev_p->current_configuration != 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
r = usb_cb_interface (USB_SET_INTERFACE, index, value);
|
||||
if (r == USB_SUCCESS)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
return usb_cb_interface (USB_SET_INTERFACE, detail);
|
||||
}
|
||||
|
||||
|
||||
static void handle_setup0 (void)
|
||||
{
|
||||
const uint16_t *pw;
|
||||
struct control_info ctrl;
|
||||
uint16_t w;
|
||||
uint8_t req;
|
||||
uint8_t req_no;
|
||||
int r = USB_UNSUPPORT;
|
||||
HANDLER handler;
|
||||
|
||||
pw = (uint16_t *)(PMA_ADDR + (uint8_t *)(st103_get_rx_addr (ENDP0) * 2));
|
||||
w = *pw++;
|
||||
|
||||
ctrl_p->bmRequestType = w & 0xff;
|
||||
ctrl_p->bRequest = req = w >> 8;
|
||||
dev_p->bmRequestType = w & 0xff;
|
||||
dev_p->bRequest = req_no = w >> 8;
|
||||
pw++;
|
||||
ctrl_p->wValue = *pw++;
|
||||
ctrl.value = *pw++;
|
||||
pw++;
|
||||
ctrl_p->wIndex = *pw++;
|
||||
ctrl.index = *pw++;
|
||||
pw++;
|
||||
ctrl_p->wLength = *pw;
|
||||
ctrl.len = *pw;
|
||||
|
||||
data_p->addr = NULL;
|
||||
data_p->len = 0;
|
||||
data_p->offset = 0;
|
||||
data_p->require_zlp = 0;
|
||||
|
||||
if ((ctrl_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
|
||||
if ((dev_p->bmRequestType & REQUEST_TYPE) == STANDARD_REQUEST)
|
||||
{
|
||||
if (req < TOTAL_REQUEST)
|
||||
if (req_no < TOTAL_REQUEST)
|
||||
{
|
||||
switch (req)
|
||||
switch (req_no)
|
||||
{
|
||||
case 0: handler = std_get_status; break;
|
||||
case 1: handler = std_clear_feature; break;
|
||||
@@ -831,44 +777,30 @@ static void handle_setup0 (void)
|
||||
default: handler = std_none; break;
|
||||
}
|
||||
|
||||
r = (*handler) (ctrl_p->bmRequestType,
|
||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
||||
r = (*handler) (dev_p->bmRequestType, &ctrl);
|
||||
}
|
||||
}
|
||||
else
|
||||
r = usb_cb_setup (ctrl_p->bmRequestType, req,
|
||||
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
|
||||
r = usb_cb_setup (dev_p->bmRequestType, req_no, &ctrl);
|
||||
|
||||
if (r != USB_SUCCESS)
|
||||
dev_p->state = STALLED;
|
||||
else
|
||||
{
|
||||
if (USB_SETUP_GET (ctrl_p->bmRequestType))
|
||||
if (USB_SETUP_SET (dev_p->bmRequestType))
|
||||
{
|
||||
uint32_t len = ctrl_p->wLength;
|
||||
|
||||
/* Restrict the data length to be the one host asks for */
|
||||
if (data_p->len > len)
|
||||
data_p->len = len;
|
||||
|
||||
if ((data_p->len % USB_MAX_PACKET_SIZE) == 0)
|
||||
data_p->require_zlp = TRUE;
|
||||
dev_p->value = ctrl.value;
|
||||
if (ctrl.len == 0)
|
||||
{
|
||||
dev_p->state = WAIT_STATUS_IN;
|
||||
st103_set_tx_count (ENDP0, 0);
|
||||
st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID);
|
||||
}
|
||||
else
|
||||
data_p->require_zlp = FALSE;
|
||||
|
||||
dev_p->state = IN_DATA;
|
||||
handle_datastage_in ();
|
||||
}
|
||||
else if (ctrl_p->wLength == 0)
|
||||
{
|
||||
dev_p->state = WAIT_STATUS_IN;
|
||||
st103_set_tx_count (ENDP0, 0);
|
||||
st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev_p->state = OUT_DATA;
|
||||
st103_ep_set_rx_status (ENDP0, EP_RX_VALID);
|
||||
{
|
||||
dev_p->state = OUT_DATA;
|
||||
st103_ep_set_rx_status (ENDP0, EP_RX_VALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -879,17 +811,16 @@ static void handle_in0 (void)
|
||||
handle_datastage_in ();
|
||||
else if (dev_p->state == WAIT_STATUS_IN)
|
||||
{
|
||||
if ((ctrl_p->bRequest == SET_ADDRESS) &&
|
||||
((ctrl_p->bmRequestType & (REQUEST_TYPE | RECIPIENT))
|
||||
if ((dev_p->bRequest == SET_ADDRESS) &&
|
||||
((dev_p->bmRequestType & (REQUEST_TYPE | RECIPIENT))
|
||||
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
|
||||
{
|
||||
st103_set_daddr (ctrl_p->wValue);
|
||||
usb_cb_handle_event (USB_EVENT_ADDRESS, ctrl_p->wValue);
|
||||
st103_set_daddr (dev_p->value);
|
||||
usb_cb_handle_event (USB_EVENT_ADDRESS, dev_p->value);
|
||||
}
|
||||
else
|
||||
usb_cb_ctrl_write_finish (ctrl_p->bmRequestType,
|
||||
ctrl_p->bRequest, ctrl_p->wValue,
|
||||
ctrl_p->wIndex, ctrl_p->wLength);
|
||||
usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest,
|
||||
dev_p->value);
|
||||
|
||||
dev_p->state = STALLED;
|
||||
}
|
||||
@@ -1111,7 +1042,7 @@ void usb_lld_set_feature (uint8_t feature)
|
||||
dev_p->current_feature = feature;
|
||||
}
|
||||
|
||||
void usb_lld_set_data_to_send (const void *p, size_t len)
|
||||
void usb_lld_set_data_to_recv (const void *p, size_t len)
|
||||
{
|
||||
data_p->addr = (uint8_t *)p;
|
||||
data_p->len = len;
|
||||
@@ -1189,3 +1120,49 @@ void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n)
|
||||
*d = (w & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* BUF: Pointer to data memory. Data memory should not be allocated
|
||||
* on stack when BUFLEN > USB_MAX_PACKET_SIZE.
|
||||
*
|
||||
* BUFLEN: size of the data.
|
||||
*/
|
||||
int
|
||||
usb_lld_reply_request (const void *buf, size_t buflen, struct control_info *ctl)
|
||||
{
|
||||
uint32_t len_asked = ctl->len;
|
||||
uint32_t len;
|
||||
|
||||
data_p->addr = (void *)buf;
|
||||
data_p->len = buflen;
|
||||
|
||||
/* Restrict the data length to be the one host asks for */
|
||||
if (data_p->len > len_asked)
|
||||
data_p->len = len_asked;
|
||||
|
||||
if (data_p->len != 0 && (data_p->len % USB_MAX_PACKET_SIZE) == 0)
|
||||
data_p->require_zlp = 1;
|
||||
|
||||
if (data_p->len < USB_MAX_PACKET_SIZE)
|
||||
{
|
||||
len = data_p->len;
|
||||
dev_p->state = LAST_IN_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = USB_MAX_PACKET_SIZE;
|
||||
dev_p->state = IN_DATA;
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
usb_lld_to_pmabuf (data_p->addr, st103_get_tx_addr (ENDP0), len);
|
||||
data_p->len -= len;
|
||||
data_p->addr += len;
|
||||
}
|
||||
|
||||
st103_set_tx_count (ENDP0, len);
|
||||
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import ast
|
||||
|
||||
import gnuk_token as gnuk
|
||||
import rsa_keys
|
||||
from array import array
|
||||
|
||||
@Before
|
||||
def ini(sc):
|
||||
@@ -26,7 +27,7 @@ def cmd_change_reference_data(who_str,pass_str):
|
||||
|
||||
@Given("cmd_put_data with (.*) and (\".*\")")
|
||||
def cmd_put_data(tag_str,content_str_repr):
|
||||
content_str = ast.literal_eval(content_str_repr)
|
||||
content_str = ast.literal_eval("b" + content_str_repr + "")
|
||||
tag = int(tag_str, 16)
|
||||
tagh = tag >> 8
|
||||
tagl = tag & 0xff
|
||||
@@ -66,7 +67,7 @@ def cmd_put_data_with_result(tag_str):
|
||||
|
||||
@Given("a message (\".*\")")
|
||||
def set_msg(content_str_repr):
|
||||
msg = ast.literal_eval(content_str_repr)
|
||||
msg = ast.literal_eval(content_str_repr).encode('UTF-8')
|
||||
scc.digestinfo = rsa_keys.compute_digestinfo(msg)
|
||||
|
||||
@Given("a public key from token for OPENPGP.(.*)")
|
||||
@@ -93,7 +94,7 @@ def compute_signature_on_host(keyno_str):
|
||||
|
||||
@Given("a plain text (\".*\")")
|
||||
def set_plaintext(content_str_repr):
|
||||
scc.plaintext = ast.literal_eval(content_str_repr)
|
||||
scc.plaintext = ast.literal_eval("b" + content_str_repr + "")
|
||||
|
||||
@Given("encrypt it on host with RSA key pair (.*)$")
|
||||
def encrypt_on_host(keyno_str):
|
||||
@@ -106,7 +107,7 @@ def encrypt_on_host_public_key():
|
||||
|
||||
@Given("let a token decrypt encrypted data")
|
||||
def decrypt():
|
||||
scc.result = ftc.token.cmd_pso_longdata(0x80, 0x86, scc.ciphertext)
|
||||
scc.result = ftc.token.cmd_pso_longdata(0x80, 0x86, scc.ciphertext).tostring()
|
||||
|
||||
@Given("USB version string of the token")
|
||||
def usb_version_string():
|
||||
@@ -129,7 +130,7 @@ def remove_key(openpgp_keyno_str):
|
||||
def generate_key(openpgp_keyno_str):
|
||||
openpgp_keyno = int(openpgp_keyno_str)
|
||||
pubkey_info = ftc.token.cmd_genkey(openpgp_keyno)
|
||||
scc.data = rsa_keys.calc_fpr(pubkey_info[0], pubkey_info[1])
|
||||
scc.data = rsa_keys.calc_fpr(pubkey_info[0].tostring(), pubkey_info[1].tostring())
|
||||
|
||||
@When("put the first data to (.*)")
|
||||
def cmd_put_data_first_with_result(tag_str):
|
||||
@@ -148,8 +149,8 @@ def cmd_put_data_second_with_result(tag_str):
|
||||
|
||||
@Then("you should get: (.*)")
|
||||
def check_result(v):
|
||||
value = ast.literal_eval("'" + v + "'")
|
||||
assert_equal(scc.result, value)
|
||||
value = ast.literal_eval("b'" + v + "'")
|
||||
assert_equal(scc.result, array('B', value))
|
||||
|
||||
@Then("it should get success")
|
||||
def check_success():
|
||||
@@ -157,7 +158,7 @@ def check_success():
|
||||
|
||||
@Then("you should get NULL")
|
||||
def check_null():
|
||||
assert_equal(scc.result, "")
|
||||
assert_equal(scc.result, array('B'))
|
||||
|
||||
@Then("data should match: (.*)")
|
||||
def check_regexp(re):
|
||||
|
||||
@@ -14,10 +14,10 @@ def print_key_in_hex(k):
|
||||
q_str = hexlify(q)
|
||||
if int(p_str, 16)*int(q_str, 16) != int(n_str, 16):
|
||||
raise ValueError("wrong key", k)
|
||||
print n_str
|
||||
print e_str
|
||||
print p_str
|
||||
print q_str
|
||||
print(n_str)
|
||||
print(e_str)
|
||||
print(p_str)
|
||||
print(q_str)
|
||||
|
||||
rng = Random.new().read
|
||||
key = RSA.generate(2048, rng)
|
||||
|
||||
@@ -24,7 +24,7 @@ def calc_fpr(n,e):
|
||||
timestamp = int(time())
|
||||
timestamp_data = pack('>I', timestamp)
|
||||
m_len = 6 + 2 + 256 + 2 + 4
|
||||
m = '\x99' + pack('>H', m_len) + '\x04' + timestamp_data + '\x01' + \
|
||||
m = b'\x99' + pack('>H', m_len) + b'\x04' + timestamp_data + b'\x01' + \
|
||||
pack('>H', 2048) + n + pack('>H', 17) + e
|
||||
fpr = sha1(m).digest()
|
||||
return (fpr, timestamp_data)
|
||||
@@ -42,39 +42,39 @@ key[2] = read_key_from_file('rsa-aut.key')
|
||||
(fpr[2], timestamp[2]) = calc_fpr(key[2][0], key[2][1])
|
||||
|
||||
def build_privkey_template(openpgp_keyno, keyno):
|
||||
n_str = key[keyno][0]
|
||||
e_str = '\x00' + key[keyno][1]
|
||||
p_str = key[keyno][2]
|
||||
q_str = key[keyno][3]
|
||||
n_bytes = key[keyno][0]
|
||||
e_bytes = b'\x00' + key[keyno][1]
|
||||
p_bytes = key[keyno][2]
|
||||
q_bytes = key[keyno][3]
|
||||
|
||||
if openpgp_keyno == 1:
|
||||
keyspec = '\xb6'
|
||||
keyspec = b'\xb6'
|
||||
elif openpgp_keyno == 2:
|
||||
keyspec = '\xb8'
|
||||
keyspec = b'\xb8'
|
||||
else:
|
||||
keyspec = '\xa4'
|
||||
keyspec = b'\xa4'
|
||||
|
||||
key_template = '\x91\x04'+ '\x92\x81\x80' + '\x93\x81\x80'
|
||||
key_template = b'\x91\x04'+ b'\x92\x81\x80' + b'\x93\x81\x80'
|
||||
|
||||
exthdr = keyspec + '\x00' + '\x7f\x48' + '\x08' + key_template
|
||||
exthdr = keyspec + b'\x00' + b'\x7f\x48' + b'\x08' + key_template
|
||||
|
||||
suffix = '\x5f\x48' + '\x82\x01\x04'
|
||||
suffix = b'\x5f\x48' + b'\x82\x01\x04'
|
||||
|
||||
t = '\x4d' + '\x82\01\16' + exthdr + suffix + e_str + p_str + q_str
|
||||
t = b'\x4d' + b'\x82\01\16' + exthdr + suffix + e_bytes + p_bytes + q_bytes
|
||||
return t
|
||||
|
||||
def build_privkey_template_for_remove(openpgp_keyno):
|
||||
if openpgp_keyno == 1:
|
||||
keyspec = '\xb6'
|
||||
keyspec = b'\xb6'
|
||||
elif openpgp_keyno == 2:
|
||||
keyspec = '\xb8'
|
||||
keyspec = b'\xb8'
|
||||
else:
|
||||
keyspec = '\xa4'
|
||||
return '\x4d\02' + keyspec + '\0x00'
|
||||
keyspec = b'\xa4'
|
||||
return b'\x4d\02' + keyspec + b'\0x00'
|
||||
|
||||
def compute_digestinfo(msg):
|
||||
digest = sha256(msg).digest()
|
||||
prefix = '\x30\31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'
|
||||
prefix = b'\x30\31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'
|
||||
return prefix + digest
|
||||
|
||||
# egcd and modinv are from wikibooks
|
||||
@@ -95,14 +95,14 @@ def modinv(a, m):
|
||||
return x % m
|
||||
|
||||
def pkcs1_pad_for_sign(digestinfo):
|
||||
byte_repr = '\x00' + '\x01' + string.ljust('', 256 - 19 - 32 - 3, '\xff') \
|
||||
+ '\x00' + digestinfo
|
||||
byte_repr = b'\x00' + b'\x01' + bytes.ljust(b'', 256 - 19 - 32 - 3, b'\xff') \
|
||||
+ b'\x00' + digestinfo
|
||||
return int(hexlify(byte_repr), 16)
|
||||
|
||||
def pkcs1_pad_for_crypt(msg):
|
||||
padlen = 256 - 3 - len(msg)
|
||||
byte_repr = '\x00' + '\x02' \
|
||||
+ string.replace(urandom(padlen),'\x00','\x01') + '\x00' + msg
|
||||
byte_repr = b'\x00' + b'\x02' \
|
||||
+ bytes.replace(urandom(padlen), b'\x00', b'\x01') + b'\x00' + msg
|
||||
return int(hexlify(byte_repr), 16)
|
||||
|
||||
def compute_signature(keyno, digestinfo):
|
||||
@@ -136,13 +136,13 @@ def encrypt(keyno, plaintext):
|
||||
e = key[keyno][4]
|
||||
n = key[keyno][7]
|
||||
m = pkcs1_pad_for_crypt(plaintext)
|
||||
return '\x00' + integer_to_bytes_256(pow(m, e, n))
|
||||
return b'\x00' + integer_to_bytes_256(pow(m, e, n))
|
||||
|
||||
def encrypt_with_pubkey(pubkey_info, plaintext):
|
||||
n = int(hexlify(pubkey_info[0]), 16)
|
||||
e = int(hexlify(pubkey_info[1]), 16)
|
||||
m = pkcs1_pad_for_crypt(plaintext)
|
||||
return '\x00' + integer_to_bytes_256(pow(m, e, n))
|
||||
return b'\x00' + integer_to_bytes_256(pow(m, e, n))
|
||||
|
||||
def verify_signature(pubkey_info, digestinfo, sig):
|
||||
n = int(hexlify(pubkey_info[0]), 16)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
#! /usr/bin/python
|
||||
|
||||
"""
|
||||
gnuk_put_binary.py - a tool to put binary to Gnuk Token
|
||||
This tool is for importing certificate, writing serial number, etc.
|
||||
|
||||
Copyright (C) 2011, 2012 Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
|
||||
Gnuk 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.
|
||||
|
||||
Gnuk 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/>.
|
||||
"""
|
||||
|
||||
import sys, os, binascii, string
|
||||
|
||||
# INPUT: binary file
|
||||
|
||||
# Assume only single CCID device is attached to computer and it's Gnuk Token
|
||||
|
||||
from smartcard.CardType import AnyCardType
|
||||
from smartcard.CardRequest import CardRequest
|
||||
from smartcard.util import toHexString
|
||||
|
||||
def s2l(s):
|
||||
return [ ord(c) for c in s ]
|
||||
|
||||
class GnukToken(object):
|
||||
def __init__(self):
|
||||
cardtype = AnyCardType()
|
||||
cardrequest = CardRequest(timeout=1, cardType=cardtype)
|
||||
cardservice = cardrequest.waitforcard()
|
||||
self.connection = cardservice.connection
|
||||
|
||||
def cmd_get_response(self, expected_len):
|
||||
result = []
|
||||
while True:
|
||||
apdu = [0x00, 0xc0, 0x00, 0x00, expected_len]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
result += response
|
||||
if sw1 == 0x90 and sw2 == 0x00:
|
||||
return result
|
||||
elif sw1 != 0x61:
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
else:
|
||||
expected_len = sw2
|
||||
|
||||
def cmd_verify(self, who, passwd):
|
||||
apdu = [0x00, 0x20, 0x00, 0x80+who, len(passwd)] + s2l(passwd)
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
|
||||
def cmd_read_binary(self, fileid):
|
||||
apdu = [0x00, 0xb0, 0x80+fileid, 0x00]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if sw1 == 0x61:
|
||||
response = self.cmd_get_response(sw2)
|
||||
elif not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
return response
|
||||
|
||||
def cmd_write_binary(self, fileid, data, is_update):
|
||||
count = 0
|
||||
data_len = len(data)
|
||||
if is_update:
|
||||
ins = 0xd6
|
||||
else:
|
||||
ins = 0xd0
|
||||
while count*256 < data_len:
|
||||
if count == 0:
|
||||
d = data[:256]
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, len(d)] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, 0x80+fileid, 0x00, 255] + s2l(d[:255])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu0)
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 1 ] + s2l(d[255:])
|
||||
else:
|
||||
d = data[256*count:256*(count+1)]
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, count, 0x00, len(d)] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, count, 0x00, 255] + s2l(d[:255])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu0)
|
||||
apdu = [0x00, ins, count, 0x00, 1] + s2l(d[255:])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
if is_update:
|
||||
raise ValueError, ("update failure: %02x%02x" % (sw1, sw2))
|
||||
else:
|
||||
raise ValueError, ("write failure: %02x%02x" % (sw1, sw2))
|
||||
count += 1
|
||||
|
||||
def cmd_select_openpgp(self):
|
||||
apdu = [0x00, 0xa4, 0x04, 0x0c, 6, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if sw1 == 0x61:
|
||||
response = self.cmd_get_response(sw2)
|
||||
elif not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
|
||||
def cmd_get_data(self, tagh, tagl):
|
||||
apdu = [0x00, 0xca, tagh, tagl]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if sw1 == 0x61:
|
||||
response = self.cmd_get_response(sw2)
|
||||
elif not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
return response
|
||||
|
||||
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
|
||||
|
||||
DEFAULT_PW3 = "12345678"
|
||||
BY_ADMIN = 3
|
||||
|
||||
def main(fileid, is_update, data, passwd):
|
||||
gnuk = GnukToken()
|
||||
|
||||
gnuk.connection.connect()
|
||||
print "Token:", gnuk.connection.getReader()
|
||||
print "ATR:", toHexString( gnuk.connection.getATR() )
|
||||
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd)
|
||||
gnuk.cmd_write_binary(fileid, data, is_update)
|
||||
gnuk.cmd_select_openpgp()
|
||||
if fileid == 0:
|
||||
data_in_device = gnuk.cmd_get_data(0x00, 0x4f)
|
||||
for d in data_in_device:
|
||||
print "%02x" % d,
|
||||
print
|
||||
compare(data, data_in_device[8:])
|
||||
elif fileid >= 1 and fileid <= 4:
|
||||
data_in_device = gnuk.cmd_read_binary(fileid)
|
||||
compare(data, data_in_device)
|
||||
elif fileid == 5:
|
||||
data_in_device = gnuk.cmd_get_data(0x7f, 0x21)
|
||||
compare(data, data_in_device)
|
||||
|
||||
gnuk.connection.disconnect()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
passwd = DEFAULT_PW3
|
||||
if sys.argv[1] == '-p':
|
||||
from getpass import getpass
|
||||
passwd = getpass("Admin password: ")
|
||||
sys.argv.pop(1)
|
||||
if sys.argv[1] == '-u':
|
||||
is_update = True
|
||||
sys.argv.pop(1)
|
||||
else:
|
||||
is_update = False
|
||||
if sys.argv[1] == '-s':
|
||||
fileid = 0 # serial number
|
||||
filename = sys.argv[2]
|
||||
f = open(filename)
|
||||
email = os.environ['EMAIL']
|
||||
serial_data_hex = None
|
||||
for line in f.readlines():
|
||||
field = string.split(line)
|
||||
if field[0] == email:
|
||||
serial_data_hex = field[1].replace(':','')
|
||||
f.close()
|
||||
if not serial_data_hex:
|
||||
print "No serial number"
|
||||
exit(1)
|
||||
print "Writing serial number"
|
||||
data = binascii.unhexlify(serial_data_hex)
|
||||
elif sys.argv[1] == '-k': # firmware update key
|
||||
keyno = sys.argv[2]
|
||||
fileid = 1 + int(keyno)
|
||||
filename = sys.argv[3]
|
||||
f = open(filename)
|
||||
data = f.read()
|
||||
f.close()
|
||||
else:
|
||||
fileid = 5 # Card holder certificate
|
||||
filename = sys.argv[1]
|
||||
f = open(filename)
|
||||
data = f.read()
|
||||
f.close()
|
||||
print "%s: %d" % (filename, len(data))
|
||||
print "Updating card holder certificate"
|
||||
main(fileid, is_update, data, passwd)
|
||||
@@ -24,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from struct import *
|
||||
import sys, time, os, binascii, string
|
||||
import sys, time, os, binascii
|
||||
from gnuk_token import *
|
||||
|
||||
# INPUT: binary file
|
||||
@@ -39,25 +39,23 @@ def main(fileid, is_update, data, passwd):
|
||||
for (dev, config, intf) in gnuk_devices():
|
||||
try:
|
||||
gnuk = 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
|
||||
if gnuk.icc_get_status() == 2:
|
||||
raise ValueError, "No ICC present"
|
||||
raise ValueError("No ICC present")
|
||||
elif gnuk.icc_get_status() == 1:
|
||||
gnuk.icc_power_on()
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd)
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd.encode('UTF-8'))
|
||||
gnuk.cmd_write_binary(fileid, data, is_update)
|
||||
gnuk.cmd_select_openpgp()
|
||||
if fileid == 0:
|
||||
data_in_device = gnuk.cmd_get_data(0x00, 0x4f)
|
||||
for d in data_in_device:
|
||||
print "%02x" % ord(d),
|
||||
print
|
||||
compare(data + '\x00\x00', data_in_device[8:])
|
||||
print(' '.join([ "%02x" % d for d in data_in_device ]))
|
||||
compare(data + b'\x00\x00', data_in_device[8:].tostring())
|
||||
elif fileid >= 1 and fileid <= 4:
|
||||
data_in_device = gnuk.cmd_read_binary(fileid)
|
||||
compare(data, data_in_device)
|
||||
@@ -85,28 +83,28 @@ if __name__ == '__main__':
|
||||
email = os.environ['EMAIL']
|
||||
serial_data_hex = None
|
||||
for line in f.readlines():
|
||||
field = string.split(line)
|
||||
field = str.split(line)
|
||||
if field[0] == email:
|
||||
serial_data_hex = field[1].replace(':','')
|
||||
f.close()
|
||||
if not serial_data_hex:
|
||||
print "No serial number"
|
||||
print("No serial number")
|
||||
exit(1)
|
||||
print "Writing serial number"
|
||||
print("Writing serial number")
|
||||
data = binascii.unhexlify(serial_data_hex)
|
||||
elif sys.argv[1] == '-k': # firmware update key
|
||||
keyno = sys.argv[2]
|
||||
fileid = 1 + int(keyno)
|
||||
filename = sys.argv[3]
|
||||
f = open(filename)
|
||||
f = open(filename, "rb")
|
||||
data = f.read()
|
||||
f.close()
|
||||
else:
|
||||
fileid = 5 # Card holder certificate
|
||||
filename = sys.argv[1]
|
||||
f = open(filename)
|
||||
f = open(filename, "rb")
|
||||
data = f.read()
|
||||
f.close()
|
||||
print "%s: %d" % (filename, len(data))
|
||||
print "Updating card holder certificate"
|
||||
print("%s: %d" % (filename, len(data)))
|
||||
print("Updating card holder certificate")
|
||||
main(fileid, is_update, data, passwd)
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
#! /usr/bin/python
|
||||
|
||||
"""
|
||||
gnuk_remove_keys.py - a tool to remove keys in Gnuk Token
|
||||
|
||||
Copyright (C) 2012 Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
|
||||
Gnuk 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.
|
||||
|
||||
Gnuk 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/>.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
|
||||
# Assume only single CCID device is attached to computer and it's Gnuk Token
|
||||
|
||||
from smartcard.CardType import AnyCardType
|
||||
from smartcard.CardRequest import CardRequest
|
||||
from smartcard.util import toHexString
|
||||
|
||||
def s2l(s):
|
||||
return [ ord(c) for c in s ]
|
||||
|
||||
class GnukToken(object):
|
||||
def __init__(self):
|
||||
cardtype = AnyCardType()
|
||||
cardrequest = CardRequest(timeout=1, cardType=cardtype)
|
||||
cardservice = cardrequest.waitforcard()
|
||||
self.connection = cardservice.connection
|
||||
|
||||
def cmd_get_response(self, expected_len):
|
||||
apdu = [0x00, 0xc0, 0x00, 0x00, expected_len]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
return response
|
||||
|
||||
def cmd_verify(self, who, passwd):
|
||||
apdu = [0x00, 0x20, 0x00, 0x80+who, len(passwd)] + s2l(passwd)
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
|
||||
def cmd_select_openpgp(self):
|
||||
apdu = [0x00, 0xa4, 0x04, 0x0c, 6, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if sw1 == 0x61:
|
||||
response = self.cmd_get_response(sw2)
|
||||
elif not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
|
||||
def cmd_put_data_remove(self, tagh, tagl):
|
||||
apdu = [0x00, 0xda, tagh, tagl, 0]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
return response
|
||||
|
||||
def cmd_put_data_key_import_remove(self, keyno):
|
||||
if keyno == 1:
|
||||
keyspec = 0xb6 # SIG
|
||||
elif keyno == 2:
|
||||
keyspec = 0xb8 # DEC
|
||||
else:
|
||||
keyspec = 0xa4 # AUT
|
||||
apdu = [0x00, 0xdb, 0x3f, 0xff, 4, 0x4d, 0x02, keyspec, 0x00]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
return response
|
||||
|
||||
DEFAULT_PW3 = "12345678"
|
||||
BY_ADMIN = 3
|
||||
|
||||
def main(passwd):
|
||||
gnuk = GnukToken()
|
||||
|
||||
gnuk.connection.connect()
|
||||
print "Token:", gnuk.connection.getReader()
|
||||
print "ATR:", toHexString( gnuk.connection.getATR() )
|
||||
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd)
|
||||
gnuk.cmd_select_openpgp()
|
||||
gnuk.cmd_put_data_remove(0x00, 0xc7) # FP_SIG
|
||||
gnuk.cmd_put_data_remove(0x00, 0xce) # KGTIME_SIG
|
||||
gnuk.cmd_put_data_key_import_remove(1)
|
||||
gnuk.cmd_put_data_remove(0x00, 0xc8) # FP_DEC
|
||||
gnuk.cmd_put_data_remove(0x00, 0xcf) # KGTIME_DEC
|
||||
gnuk.cmd_put_data_key_import_remove(2)
|
||||
gnuk.cmd_put_data_remove(0x00, 0xc9) # FP_AUT
|
||||
gnuk.cmd_put_data_remove(0x00, 0xd0) # KGTIME_AUT
|
||||
gnuk.cmd_put_data_key_import_remove(3)
|
||||
|
||||
gnuk.connection.disconnect()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
passwd = DEFAULT_PW3
|
||||
if len(sys.argv) > 1 and sys.argv[1] == '-p':
|
||||
from getpass import getpass
|
||||
passwd = getpass("Admin password: ")
|
||||
sys.argv.pop(1)
|
||||
main(passwd)
|
||||
@@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import sys, os
|
||||
|
||||
from gnuk_token import *
|
||||
|
||||
@@ -36,17 +36,17 @@ def main(passwd):
|
||||
for (dev, config, intf) in gnuk_devices():
|
||||
try:
|
||||
gnuk = 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
|
||||
if gnuk.icc_get_status() == 2:
|
||||
raise ValueError, "No ICC present"
|
||||
raise ValueError("No ICC present")
|
||||
elif gnuk.icc_get_status() == 1:
|
||||
gnuk.icc_power_on()
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd)
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd.encode('UTF-8'))
|
||||
gnuk.cmd_select_openpgp()
|
||||
gnuk.cmd_put_data_remove(0x00, 0xc7) # FP_SIG
|
||||
gnuk.cmd_put_data_remove(0x00, 0xce) # KGTIME_SIG
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"""
|
||||
gnuk_token.py - a library for Gnuk Token
|
||||
|
||||
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 Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -21,8 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from struct import *
|
||||
import string, binascii
|
||||
import binascii
|
||||
import usb, time
|
||||
from array import array
|
||||
|
||||
# USB class, subclass, protocol
|
||||
CCID_CLASS = 0x0B
|
||||
@@ -50,9 +52,6 @@ def iso7816_compose(ins, p1, p2, data, cls=0x00, le=None):
|
||||
return pack('>BBBBB', cls, ins, p1, p2, data_len) \
|
||||
+ data + pack('>B', le)
|
||||
|
||||
def list_to_string(l):
|
||||
return string.join([chr(c) for c in l], '')
|
||||
|
||||
# This class only supports Gnuk (for now)
|
||||
class gnuk_token(object):
|
||||
def __init__(self, device, configuration, interface):
|
||||
@@ -68,10 +67,7 @@ class gnuk_token(object):
|
||||
if interface.interfaceSubClass != CCID_SUBCLASS:
|
||||
raise ValueError("Wrong interface sub class")
|
||||
self.__devhandle = device.open()
|
||||
try:
|
||||
self.__devhandle.setConfiguration(configuration)
|
||||
except:
|
||||
pass
|
||||
self.__devhandle.setConfiguration(configuration.value)
|
||||
self.__devhandle.claimInterface(interface)
|
||||
self.__devhandle.setAltInterface(0)
|
||||
|
||||
@@ -117,7 +113,7 @@ class gnuk_token(object):
|
||||
|
||||
def mem_info(self):
|
||||
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
|
||||
value = 0, index = 0, buffer = 8,
|
||||
buffer = 8, value = 0, index = 0,
|
||||
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]
|
||||
@@ -126,7 +122,7 @@ class gnuk_token(object):
|
||||
def download(self, start, data, verbose=False):
|
||||
addr = start
|
||||
addr_end = (start + len(data)) & 0xffffff00
|
||||
i = (addr - 0x20000000) / 0x100
|
||||
i = int((addr - 0x20000000) / 0x100)
|
||||
j = 0
|
||||
print("start %08x" % addr)
|
||||
print("end %08x" % addr_end)
|
||||
@@ -134,9 +130,8 @@ class gnuk_token(object):
|
||||
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],
|
||||
timeout = 10)
|
||||
value = i, index = 0, timeout = 10)
|
||||
i = i+1
|
||||
j = j+1
|
||||
addr = addr + 256
|
||||
@@ -145,22 +140,22 @@ class gnuk_token(object):
|
||||
if verbose:
|
||||
print("# %08x: %d : %d" % (addr, i, residue))
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
|
||||
value = i, index = 0,
|
||||
buffer = data[j*256:],
|
||||
timeout = 10)
|
||||
value = i, index = 0, timeout = 10)
|
||||
|
||||
def execute(self, last_addr):
|
||||
i = (last_addr - 0x20000000) / 0x100
|
||||
i = int((last_addr - 0x20000000) / 0x100)
|
||||
o = (last_addr - 0x20000000) % 0x100
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 2,
|
||||
value = i, index = o, buffer = None,
|
||||
buffer = None, value = i, index = o,
|
||||
timeout = 10)
|
||||
|
||||
def icc_get_result(self):
|
||||
msg = self.__devhandle.bulkRead(self.__bulkin, 1024, self.__timeout)
|
||||
if len(msg) < 10:
|
||||
print(msg)
|
||||
usbmsg = self.__devhandle.bulkRead(self.__bulkin, 1024, self.__timeout)
|
||||
if len(usbmsg) < 10:
|
||||
print(usbmsg)
|
||||
raise ValueError("icc_get_result")
|
||||
msg = array('B', usbmsg)
|
||||
msg_type = msg[0]
|
||||
data_len = msg[1] + (msg[2]<<8) + (msg[3]<<16) + (msg[4]<<24)
|
||||
slot = msg[5]
|
||||
@@ -173,7 +168,7 @@ class gnuk_token(object):
|
||||
return (status, chain, data)
|
||||
|
||||
def icc_get_status(self):
|
||||
msg = icc_compose(0x65, 0, 0, self.__seq, 0, "")
|
||||
msg = icc_compose(0x65, 0, 0, self.__seq, 0, b"")
|
||||
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||
self.increment_seq()
|
||||
status, chain, data = self.icc_get_result()
|
||||
@@ -181,16 +176,16 @@ class gnuk_token(object):
|
||||
return status
|
||||
|
||||
def icc_power_on(self):
|
||||
msg = icc_compose(0x62, 0, 0, self.__seq, 0, "")
|
||||
msg = icc_compose(0x62, 0, 0, self.__seq, 0, b"")
|
||||
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||
self.increment_seq()
|
||||
status, chain, data = self.icc_get_result()
|
||||
# XXX: check status, chain
|
||||
self.atr = list_to_string(data) # ATR
|
||||
self.atr = data
|
||||
return self.atr
|
||||
|
||||
def icc_power_off(self):
|
||||
msg = icc_compose(0x63, 0, 0, self.__seq, 0, "")
|
||||
msg = icc_compose(0x63, 0, 0, self.__seq, 0, b"")
|
||||
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||
self.increment_seq()
|
||||
status, chain, data = self.icc_get_result()
|
||||
@@ -212,7 +207,7 @@ class gnuk_token(object):
|
||||
elif chain == 1:
|
||||
d = data_rcv
|
||||
while True:
|
||||
msg = icc_compose(0x6f, 0, 0, self.__seq, 0x10, "")
|
||||
msg = icc_compose(0x6f, 0, 0, self.__seq, 0x10, b"")
|
||||
self.__devhandle.bulkWrite(self.__bulkout, msg, self.__timeout)
|
||||
self.increment_seq()
|
||||
status, chain, data_rcv = self.icc_get_result()
|
||||
@@ -229,14 +224,14 @@ class gnuk_token(object):
|
||||
raise ValueError("icc_send_cmd")
|
||||
|
||||
def cmd_get_response(self, expected_len):
|
||||
result = []
|
||||
result = array('B')
|
||||
while True:
|
||||
cmd_data = iso7816_compose(0xc0, 0x00, 0x00, '') + pack('>B', expected_len)
|
||||
cmd_data = iso7816_compose(0xc0, 0x00, 0x00, b'') + pack('>B', expected_len)
|
||||
response = self.icc_send_cmd(cmd_data)
|
||||
result += response[:-2]
|
||||
sw = response[-2:]
|
||||
if sw[0] == 0x90 and sw[1] == 0x00:
|
||||
return list_to_string(result)
|
||||
return result
|
||||
elif sw[0] != 0x61:
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
else:
|
||||
@@ -252,7 +247,7 @@ class gnuk_token(object):
|
||||
return True
|
||||
|
||||
def cmd_read_binary(self, fileid):
|
||||
cmd_data = iso7816_compose(0xb0, 0x80+fileid, 0x00, '')
|
||||
cmd_data = iso7816_compose(0xb0, 0x80+fileid, 0x00, b'')
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
raise ValueError(sw)
|
||||
@@ -296,21 +291,21 @@ class gnuk_token(object):
|
||||
count += 1
|
||||
|
||||
def cmd_select_openpgp(self):
|
||||
cmd_data = iso7816_compose(0xa4, 0x04, 0x0c, "\xD2\x76\x00\x01\x24\x01")
|
||||
cmd_data = iso7816_compose(0xa4, 0x04, 0x0c, b"\xD2\x76\x00\x01\x24\x01")
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
raise ValueError, sw
|
||||
raise ValueError(sw)
|
||||
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
return True
|
||||
|
||||
def cmd_get_data(self, tagh, tagl):
|
||||
cmd_data = iso7816_compose(0xca, tagh, tagl, "")
|
||||
cmd_data = iso7816_compose(0xca, tagh, tagl, b"")
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
raise ValueError, sw
|
||||
raise ValueError(sw)
|
||||
if sw[0] == 0x90 and sw[1] == 0x00:
|
||||
return ""
|
||||
return array('B')
|
||||
elif sw[0] != 0x61:
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
return self.cmd_get_response(sw[1])
|
||||
@@ -363,7 +358,7 @@ class gnuk_token(object):
|
||||
if len(sw) != 2:
|
||||
raise ValueError(sw)
|
||||
if sw[0] == 0x90 and sw[1] == 0x00:
|
||||
return ""
|
||||
return array('B')
|
||||
elif sw[0] != 0x61:
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
return self.cmd_get_response(sw[1])
|
||||
@@ -389,24 +384,24 @@ class gnuk_token(object):
|
||||
if len(sw) != 2:
|
||||
raise ValueError(sw)
|
||||
if sw[0] == 0x90 and sw[1] == 0x00:
|
||||
return ""
|
||||
return array('B')
|
||||
elif sw[0] != 0x61:
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
return self.cmd_get_response(sw[1])
|
||||
|
||||
def cmd_genkey(self, keyno):
|
||||
if keyno == 1:
|
||||
data = '\xb6\x00'
|
||||
data = b'\xb6\x00'
|
||||
elif keyno == 2:
|
||||
data = '\xb8\x00'
|
||||
data = b'\xb8\x00'
|
||||
else:
|
||||
data = '\xa4\x00'
|
||||
data = b'\xa4\x00'
|
||||
cmd_data = iso7816_compose(0x47, 0x80, 0, data)
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
raise ValueError(sw)
|
||||
if sw[0] == 0x90 and sw[1] == 0x00:
|
||||
return ""
|
||||
return array('B')
|
||||
elif sw[0] != 0x61:
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
pk = self.cmd_get_response(sw[1])
|
||||
@@ -414,11 +409,11 @@ class gnuk_token(object):
|
||||
|
||||
def cmd_get_public_key(self, keyno):
|
||||
if keyno == 1:
|
||||
data = '\xb6\x00'
|
||||
data = b'\xb6\x00'
|
||||
elif keyno == 2:
|
||||
data = '\xb8\x00'
|
||||
data = b'\xb8\x00'
|
||||
else:
|
||||
data = '\xa4\x00'
|
||||
data = b'\xa4\x00'
|
||||
cmd_data = iso7816_compose(0x47, 0x81, 0, data)
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
@@ -429,22 +424,22 @@ class gnuk_token(object):
|
||||
return (pk[9:9+256], pk[9+256+2:9+256+2+3])
|
||||
|
||||
def cmd_put_data_remove(self, tagh, tagl):
|
||||
cmd_data = iso7816_compose(0xda, tagh, tagl, "")
|
||||
cmd_data = iso7816_compose(0xda, tagh, tagl, b"")
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if sw[0] != 0x90 and sw[1] != 0x00:
|
||||
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
|
||||
def cmd_put_data_key_import_remove(self, keyno):
|
||||
if keyno == 1:
|
||||
keyspec = "\xb6\x00" # SIG
|
||||
keyspec = b"\xb6\x00" # SIG
|
||||
elif keyno == 2:
|
||||
keyspec = "\xb8\x00" # DEC
|
||||
keyspec = b"\xb8\x00" # DEC
|
||||
else:
|
||||
keyspec = "\xa4\x00" # AUT
|
||||
cmd_data = iso7816_compose(0xdb, 0x3f, 0xff, "\x4d\x02" + keyspec)
|
||||
keyspec = b"\xa4\x00" # AUT
|
||||
cmd_data = iso7816_compose(0xdb, 0x3f, 0xff, b"\x4d\x02" + keyspec)
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if sw[0] != 0x90 and sw[1] != 0x00:
|
||||
raise ValueError, ("%02x%02x" % (sw[0], sw[1]))
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
|
||||
def cmd_get_challenge(self):
|
||||
cmd_data = iso7816_compose(0x84, 0x00, 0x00, '')
|
||||
@@ -487,7 +482,7 @@ class regnual(object):
|
||||
|
||||
def mem_info(self):
|
||||
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
|
||||
value = 0, index = 0, buffer = 8,
|
||||
buffer = 8, value = 0, index = 0,
|
||||
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]
|
||||
@@ -496,7 +491,7 @@ class regnual(object):
|
||||
def download(self, start, data, verbose=False):
|
||||
addr = start
|
||||
addr_end = (start + len(data)) & 0xffffff00
|
||||
i = (addr - 0x08000000) / 0x100
|
||||
i = int((addr - 0x08000000) / 0x100)
|
||||
j = 0
|
||||
print("start %08x" % addr)
|
||||
print("end %08x" % addr_end)
|
||||
@@ -504,23 +499,21 @@ class regnual(object):
|
||||
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],
|
||||
timeout = 10000)
|
||||
value = 0, index = 0, timeout = 10000)
|
||||
crc32code = crc32(data[j*256:j*256+256])
|
||||
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
|
||||
value = 0, index = 0, buffer = 4,
|
||||
buffer = 4, value = 0, index = 0,
|
||||
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)
|
||||
value = i, index = 0, timeout = 10000)
|
||||
time.sleep(0.010)
|
||||
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
|
||||
value = 0, index = 0, buffer = 4,
|
||||
buffer = 4, value = 0, index = 0,
|
||||
timeout = 10000)
|
||||
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
|
||||
if r_value == 0:
|
||||
@@ -533,23 +526,21 @@ class regnual(object):
|
||||
if verbose:
|
||||
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)))
|
||||
value = 0, index = 0, timeout = 10000)
|
||||
crc32code = crc32(data[j*256:].ljust(256,b'\xff'))
|
||||
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
|
||||
value = 0, index = 0, buffer = 4,
|
||||
buffer = 4, value = 0, index = 0,
|
||||
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)
|
||||
value = i, index = 0, timeout = 10000)
|
||||
time.sleep(0.010)
|
||||
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
|
||||
value = 0, index = 0, buffer = 4,
|
||||
buffer = 4, value = 0, index = 0,
|
||||
timeout = 10000)
|
||||
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
|
||||
if r_value == 0:
|
||||
@@ -557,11 +548,11 @@ class regnual(object):
|
||||
|
||||
def protect(self):
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 4,
|
||||
value = 0, index = 0, buffer = None,
|
||||
buffer = None, value = 0, index = 0,
|
||||
timeout = 10000)
|
||||
time.sleep(0.100)
|
||||
res = self.__devhandle.controlMsg(requestType = 0xc0, request = 2,
|
||||
value = 0, index = 0, buffer = 4,
|
||||
buffer = 4, value = 0, index = 0,
|
||||
timeout = 10000)
|
||||
r_value = ((res[3]*256 + res[2])*256 + res[1])*256 + res[0]
|
||||
if r_value == 0:
|
||||
@@ -569,7 +560,7 @@ class regnual(object):
|
||||
|
||||
def finish(self):
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 5,
|
||||
value = 0, index = 0, buffer = None,
|
||||
buffer = None, value = 0, index = 0,
|
||||
timeout = 10000)
|
||||
|
||||
def reset_device(self):
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
gnuk_upgrade.py - a tool to upgrade firmware of Gnuk Token
|
||||
|
||||
Copyright (C) 2012, 2015 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.
|
||||
@@ -23,7 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from struct import *
|
||||
import sys, time, os, binascii, string
|
||||
import sys, time, os, binascii
|
||||
|
||||
# INPUT: binary files (regnual_image, upgrade_firmware_image)
|
||||
|
||||
@@ -33,12 +33,6 @@ import usb
|
||||
|
||||
from gnuk_token import *
|
||||
|
||||
def to_string(t):
|
||||
result = ""
|
||||
for c in t:
|
||||
result += chr(c)
|
||||
return result
|
||||
|
||||
from subprocess import check_output
|
||||
|
||||
SHA256_OID_PREFIX="3031300d060960864801650304020105000420"
|
||||
@@ -79,16 +73,16 @@ def gpg_sign(keygrip, hash):
|
||||
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))
|
||||
data_regnual = data_regnual.ljust(l + 4 - (l & 0x03), b'\x00')
|
||||
crc32code = crc32(data_regnual)
|
||||
print "CRC32: %04x\n" % crc32code
|
||||
print("CRC32: %04x\n" % crc32code)
|
||||
data_regnual += pack('<I', crc32code)
|
||||
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:
|
||||
icc = None
|
||||
@@ -97,15 +91,15 @@ def main(keyno,keygrip, data_regnual, data_upgrade):
|
||||
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)))
|
||||
challenge = icc.cmd_get_challenge().tostring()
|
||||
signed = gpg_sign(keygrip, binascii.hexlify(challenge))
|
||||
icc.cmd_external_authenticate(keyno, signed)
|
||||
icc.stop_gnuk()
|
||||
mem_info = icc.mem_info()
|
||||
print "%08x:%08x" % mem_info
|
||||
print "Downloading flash upgrade program..."
|
||||
print("%08x:%08x" % mem_info)
|
||||
print("Downloading flash upgrade program...")
|
||||
icc.download(mem_info[0], data_regnual)
|
||||
print "Run flash upgrade program..."
|
||||
print("Run flash upgrade program...")
|
||||
icc.execute(mem_info[0] + len(data_regnual) - 4)
|
||||
#
|
||||
time.sleep(3)
|
||||
@@ -113,20 +107,20 @@ def main(keyno,keygrip, data_regnual, data_upgrade):
|
||||
del icc
|
||||
icc = 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: %d" % 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()
|
||||
@@ -143,12 +137,12 @@ if __name__ == '__main__':
|
||||
sys.argv.pop(1)
|
||||
filename_regnual = sys.argv[1]
|
||||
filename_upgrade = sys.argv[2]
|
||||
f = open(filename_regnual)
|
||||
f = open(filename_regnual, "rb")
|
||||
data_regnual = f.read()
|
||||
f.close()
|
||||
print "%s: %d" % (filename_regnual, len(data_regnual))
|
||||
f = open(filename_upgrade)
|
||||
print("%s: %d" % (filename_regnual, len(data_regnual)))
|
||||
f = open(filename_upgrade, "rb")
|
||||
data_upgrade = f.read()
|
||||
f.close()
|
||||
print "%s: %d" % (filename_upgrade, len(data_upgrade))
|
||||
print("%s: %d" % (filename_upgrade, len(data_upgrade)))
|
||||
main(keyno, keygrip, data_regnual, data_upgrade[4096:])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
gpg_agent.py - a library to connect gpg-agent
|
||||
|
||||
Copyright (C) 2013 Free Software Initiative of Japan
|
||||
Copyright (C) 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.
|
||||
@@ -34,7 +34,7 @@ class gpg_agent(object):
|
||||
comm_port = os.path.join(home, "gnupg", "S.gpg-agent")
|
||||
#
|
||||
f = open(comm_port, "rb", 0)
|
||||
infostr = f.read()
|
||||
infostr = f.read().decode('UTF-8')
|
||||
f.close()
|
||||
#
|
||||
info = infostr.split('\n', 1)
|
||||
@@ -50,17 +50,17 @@ class gpg_agent(object):
|
||||
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
s.connect(path)
|
||||
self.sock = s
|
||||
self.buf_remained = ""
|
||||
self.buf_remained = b""
|
||||
self.response = None
|
||||
|
||||
def read_line(self):
|
||||
line = ""
|
||||
if self.buf_remained != "":
|
||||
line = b""
|
||||
if self.buf_remained != b"":
|
||||
chunk = self.buf_remained
|
||||
else:
|
||||
chunk = self.sock.recv(BUFLEN)
|
||||
while True:
|
||||
pos = chunk.find('\n')
|
||||
pos = chunk.find(b'\n')
|
||||
if pos >= 0:
|
||||
self.buf_remained = chunk[pos+1:]
|
||||
line = line + chunk[0:pos]
|
||||
@@ -71,37 +71,40 @@ class gpg_agent(object):
|
||||
|
||||
def get_response(self):
|
||||
r = self.response
|
||||
result = ""
|
||||
result = b""
|
||||
while True:
|
||||
i = r.find('%')
|
||||
i = r.find(b'%')
|
||||
if i < 0:
|
||||
result += r
|
||||
break
|
||||
hex_str = r[i+1:i+3]
|
||||
hex_str = r[i+1:i+3].decode('UTF-8')
|
||||
result += r[0:i]
|
||||
result += chr(int(hex_str,16))
|
||||
if bytes == str:
|
||||
result += chr(int(hex_str,16))
|
||||
else:
|
||||
result += bytes.fromhex(hex_str)
|
||||
r = r[i+3:]
|
||||
return result
|
||||
|
||||
def send_command(self, cmd):
|
||||
self.sock.send(cmd)
|
||||
self.response = ""
|
||||
self.sock.send(cmd.encode('UTF-8'))
|
||||
self.response = b""
|
||||
while True:
|
||||
while True:
|
||||
l = self.read_line()
|
||||
if l[0] != '#':
|
||||
if l[0] != b'#'[0]:
|
||||
break
|
||||
if l[0] == 'D':
|
||||
if l[0] == b'D'[0]:
|
||||
self.response += l[2:]
|
||||
elif l[0] == 'O' and l[1] == 'K':
|
||||
elif l[0:2] == b'OK':
|
||||
return True
|
||||
elif l[0] == 'E' and l[1] == 'R' and l[2] == 'R':
|
||||
elif l[0:3] == b'ERR':
|
||||
return False
|
||||
else: # XXX: S, INQUIRE, END
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.sock.send('BYE\n')
|
||||
self.sock.send(b'BYE\n')
|
||||
bye = self.read_line()
|
||||
self.sock.close()
|
||||
return bye # "OK closing connection"
|
||||
@@ -109,17 +112,17 @@ class gpg_agent(object):
|
||||
# Test
|
||||
if __name__ == '__main__':
|
||||
g = gpg_agent()
|
||||
print g.read_line()
|
||||
print g.send_command("KEYINFO --list --data\n")
|
||||
kl_str = g.get_response()
|
||||
print(g.read_line().decode('UTF-8'))
|
||||
print(g.send_command("KEYINFO --list --data\n"))
|
||||
kl_str = g.get_response().decode('UTF-8')
|
||||
kl_str = kl_str[0:-1]
|
||||
kl = kl_str.split('\n')
|
||||
import re
|
||||
kl_o3 = [kg for kg in kl if re.search("OPENPGP\\.3", kg)]
|
||||
print kl_o3
|
||||
print(kl_o3)
|
||||
kg = kl_o3[0].split(' ')[0]
|
||||
print g.send_command("READKEY %s\n" % kg)
|
||||
print(g.send_command("READKEY %s\n" % kg))
|
||||
r = g.get_response()
|
||||
import binascii
|
||||
print binascii.hexlify(r)
|
||||
print g.close()
|
||||
print(binascii.hexlify(r).decode('UTF-8'))
|
||||
print(g.close().decode('UTF-8'))
|
||||
|
||||
@@ -36,7 +36,7 @@ class intel_hex(object):
|
||||
memory[addr] = data
|
||||
prev_addr = addr
|
||||
prev_data_len = len(data)
|
||||
self.memory = memory
|
||||
self.memory = memory
|
||||
|
||||
def calc_checksum(self, byte_count, offset, type_code, data):
|
||||
s = byte_count
|
||||
@@ -57,19 +57,19 @@ class intel_hex(object):
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
raise ValueError, "data overwritten (%d)" % self.lineno
|
||||
raise ValueError("data overwritten (%d)" % self.lineno)
|
||||
self.memory[address] = data
|
||||
|
||||
def parse_line(self, line):
|
||||
if line[0] != ':':
|
||||
raise ValueError, "invalid line (%d)" % self.lineno
|
||||
raise ValueError("invalid line (%d)" % self.lineno)
|
||||
count = int(line[1:3], 16)
|
||||
offset = int(line[3:7], 16)
|
||||
type_code = int(line[7:9], 16)
|
||||
data = binascii.unhexlify(line[9:(9+count*2)])
|
||||
check_sum = int(line[(9+count*2):], 16)
|
||||
if check_sum != self.calc_checksum(count, offset, type_code, data):
|
||||
raise ValueError, "invalid checksum (%d)" % self.lineno
|
||||
raise ValueError("invalid checksum (%d)" % self.lineno)
|
||||
if type_code == 0x00:
|
||||
self.add_data(count, offset, data)
|
||||
return 0
|
||||
@@ -77,18 +77,18 @@ class intel_hex(object):
|
||||
return 1
|
||||
elif type_code == 0x04:
|
||||
if count != 2:
|
||||
raise ValueError, "invalid count (%d): (%d) Expected 2" \
|
||||
% (self.lineno, count)
|
||||
raise ValueError("invalid count (%d): (%d) Expected 2" \
|
||||
% (self.lineno, count))
|
||||
self.address = ((ord(data[0])&0xff)<<24) + ((ord(data[1])&0xff)<<16)
|
||||
return 0
|
||||
elif type_code == 0x05:
|
||||
if count != 4:
|
||||
raise ValueError, "invalid count (%d): (%d) Expected 4" \
|
||||
% (self.lineno, count)
|
||||
raise ValueError("invalid count (%d): (%d) Expected 4" \
|
||||
% (self.lineno, count))
|
||||
self.start_address \
|
||||
= ((ord(data[0])&0xff)<<24) + ((ord(data[1])&0xff)<<16) \
|
||||
+ ((ord(data[2])&0xff)<<8) + ((ord(data[3])&0xff))
|
||||
return 0
|
||||
else:
|
||||
raise ValueError, "invalid type code (%d): (%d)" \
|
||||
% (self.lineno, type_code)
|
||||
raise ValueError("invalid type code (%d): (%d)" \
|
||||
% (self.lineno, type_code))
|
||||
|
||||
@@ -434,3 +434,7 @@ if __name__ == '__main__':
|
||||
# 076b:3821 OmniKey AG CardMan 3821
|
||||
# OmniKey CardMan 3821 01 00
|
||||
# Works well with --pinmax 31 --pinmin 1
|
||||
|
||||
# 046a:003e Cherry GmbH SmartTerminal ST-2xxx
|
||||
# Cherry ST-2000
|
||||
# Needs --add to function properly
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from binascii import hexlify, unhexlify
|
||||
import string
|
||||
from os import urandom
|
||||
|
||||
def read_key_from_file(file):
|
||||
@@ -35,8 +34,9 @@ def modinv(a, m):
|
||||
return x % m
|
||||
|
||||
def pkcs1_pad_for_sign(digestinfo):
|
||||
byte_repr = '\x00' + '\x01' + string.ljust('', 256 - 19 - 32 - 3, '\xff') \
|
||||
+ '\x00' + digestinfo
|
||||
byte_repr = b'\x00' + b'\x01' \
|
||||
+ bytes.ljust(b'', 256 - 19 - 32 - 3, b'\xff') \
|
||||
+ b'\x00' + digestinfo
|
||||
return int(hexlify(byte_repr), 16)
|
||||
|
||||
def compute_signature(key, digestinfo):
|
||||
@@ -64,7 +64,7 @@ def integer_to_bytes_256(i):
|
||||
s = s.rstrip('L')
|
||||
if len(s) & 1:
|
||||
s = '0' + s
|
||||
return string.rjust(unhexlify(s), 256, '\x00')
|
||||
return bytes.rjust(unhexlify(s), 256, b'\x00')
|
||||
|
||||
def get_raw_pubkey(key):
|
||||
return key[0]
|
||||
|
||||
325
tool/stlinkv2.py
325
tool/stlinkv2.py
@@ -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.
|
||||
@@ -26,16 +26,25 @@ from struct import *
|
||||
import sys, time
|
||||
import usb
|
||||
from colorama import init as colorama_init, Fore, Back, Style
|
||||
from array import array
|
||||
|
||||
# INPUT: binary file
|
||||
|
||||
# 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 +71,36 @@ 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" + \
|
||||
"\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
|
||||
prog_flash_write_body = b"\x0D\x4A\x0B\x48\x0B\x49\x09\x4C\x01\x25\x14\x26\x00\x27\x25\x61" + \
|
||||
b"\xC3\x5B\xCB\x53\xE3\x68\x2B\x42\xFC\xD1\x33\x42\x02\xD1\x02\x37\x97\x42\xF5\xD1" + \
|
||||
b"\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 = b"\x0B\x48\x0A\x49\x08\x4A\x10\x23\x01\x24\x13\x61\x08\x80\xD0\x68" + \
|
||||
b"\x20\x42\xFC\xD1\x02\x31\xFF\x20\x08\x80\xD0\x68\x20\x42\xFC\xD1\x00\x20\x10\x61" + \
|
||||
b"\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"
|
||||
prog_blank_check_body = b"\x04\x49\x05\x4A\x08\x68\x01\x30\x02\xD1\x04\x31\x91\x42\xF9\xD1\x00\xBE\xC0\x46" + \
|
||||
b"\x00\x00\x00\x08"
|
||||
## HERE comes: end_addr in 4-byte
|
||||
# .END_ADDR
|
||||
|
||||
@@ -108,30 +109,34 @@ 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
|
||||
|
||||
|
||||
class TimeOutError(Exception):
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
def __str__(self):
|
||||
return repr(self.msg)
|
||||
def __repr__(self):
|
||||
return "TimeoutError(" + self.msg + ")"
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
def __str__(self):
|
||||
return repr(self.msg)
|
||||
def __repr__(self):
|
||||
return "TimeoutError(" + self.msg + ")"
|
||||
|
||||
class OperationFailure(Exception):
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
def __str__(self):
|
||||
return repr(self.msg)
|
||||
def __repr__(self):
|
||||
return "OperationFailure(" + self.msg + ")"
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
def __str__(self):
|
||||
return repr(self.msg)
|
||||
def __repr__(self):
|
||||
return "OperationFailure(" + self.msg + ")"
|
||||
|
||||
|
||||
class stlinkv2(object):
|
||||
def __init__(self, dev):
|
||||
self.__bulkout = 2
|
||||
if dev.idProduct == USB_VENDOR_STLINKV2:
|
||||
self.__bulkout = 2
|
||||
else:
|
||||
self.__bulkout = 1
|
||||
self.__bulkin = 0x81
|
||||
|
||||
self.__timeout = 1000 # 1 second
|
||||
@@ -141,11 +146,14 @@ class stlinkv2(object):
|
||||
if intf.interfaceClass != 0xff: # Vendor specific
|
||||
raise ValueError("Wrong interface class.", intf.interfaceClass)
|
||||
self.__devhandle = dev.open()
|
||||
# ST-Link/V2-1 has other interfaces
|
||||
# Some other processes or kernel would use it
|
||||
# So, write access to configuration causes error
|
||||
try:
|
||||
self.__devhandle.setConfiguration(conf)
|
||||
self.__devhandle.setConfiguration(conf.value)
|
||||
except:
|
||||
pass
|
||||
self.__devhandle.claimInterface(intf)
|
||||
self.__devhandle.claimInterface(intf.interfaceNumber)
|
||||
# self.__devhandle.setAltInterface(0) # This was not good for libusb-win32 with wrong arg intf, new correct value 0 would be OK
|
||||
|
||||
def shutdown(self):
|
||||
@@ -162,73 +170,76 @@ class stlinkv2(object):
|
||||
self.__devhandle.bulkWrite(self.__bulkout, data, self.__timeout)
|
||||
|
||||
def stl_mode(self):
|
||||
v = self.execute_get("\xf5\x00", 2)
|
||||
v = self.execute_get(b"\xf5\x00", 2)
|
||||
return (v[1] * 256 + v[0])
|
||||
|
||||
def exit_from_debug_swd(self):
|
||||
self.execute_put("\xf2\x21\x00")
|
||||
self.execute_put(b"\xf2\x21\x00")
|
||||
time.sleep(1)
|
||||
|
||||
def exit_from_dfu(self):
|
||||
self.execute_put("\xf3\x07\x00")
|
||||
self.execute_put(b"\xf3\x07\x00")
|
||||
time.sleep(1)
|
||||
|
||||
def exit_from_debug_swim(self):
|
||||
self.execute_put("\xf4\x01\x00")
|
||||
self.execute_put(b"\xf4\x01\x00")
|
||||
time.sleep(1)
|
||||
|
||||
def enter_swd(self):
|
||||
self.execute_put("\xf2\x20\xa3")
|
||||
self.execute_put(b"\xf2\x20\xa3")
|
||||
time.sleep(1)
|
||||
|
||||
def get_status(self):
|
||||
v = self.execute_get("\xf2\x01\x00", 2)
|
||||
v = self.execute_get(b"\xf2\x01\x00", 2)
|
||||
return (v[1] << 8) + v[0]
|
||||
# RUN:128, HALT:129
|
||||
|
||||
def enter_debug(self):
|
||||
v = self.execute_get("\xf2\x02\x00", 2)
|
||||
v = self.execute_get(b"\xf2\x02\x00", 2)
|
||||
return (v[1] << 8) + v[0]
|
||||
|
||||
def exit_debug(self):
|
||||
self.execute_put("\xf2\x21\x00")
|
||||
self.execute_put(b"\xf2\x21\x00")
|
||||
|
||||
def reset_sys(self):
|
||||
v = self.execute_get("\xf2\x03\x00", 2)
|
||||
v = self.execute_get(b"\xf2\x03\x00", 2)
|
||||
return (v[1] << 8) + v[0]
|
||||
|
||||
def read_memory(self, addr, length):
|
||||
return self.execute_get("\xf2\x07" + pack('<IH', addr, length), length)
|
||||
return self.execute_get(b"\xf2\x07" + pack('<IH', addr, length), length)
|
||||
|
||||
def read_memory_u32(self, addr):
|
||||
return uint32(self.execute_get("\xf2\x07" + pack('<IH', addr, 4), 4))
|
||||
return uint32(self.execute_get(b"\xf2\x07" + pack('<IH', addr, 4), 4))
|
||||
|
||||
def write_memory(self, addr, data):
|
||||
return self.execute_put("\xf2\x08" + pack('<IH', addr, len(data)), data)
|
||||
return self.execute_put(b"\xf2\x08" + pack('<IH', addr, len(data)), data)
|
||||
|
||||
def write_memory_u32(self, addr, data):
|
||||
return self.execute_put("\xf2\x08" + pack('<IH', addr, 4),
|
||||
return self.execute_put(b"\xf2\x08" + pack('<IH', addr, 4),
|
||||
pack('<I', data))
|
||||
|
||||
def read_reg(self, regno):
|
||||
return uint32(self.execute_get("\xf2\x05" + pack('<B', regno), 4))
|
||||
return uint32(self.execute_get(b"\xf2\x05" + pack('<B', regno), 4))
|
||||
|
||||
def write_reg(self, regno, value):
|
||||
return self.execute_get("\xf2\x06" + pack('<BI', regno, value), 2)
|
||||
return self.execute_get(b"\xf2\x06" + pack('<BI', regno, value), 2)
|
||||
|
||||
def write_debug_reg(self, addr, value):
|
||||
return self.execute_get("\xf2\x35" + pack('<II', addr, value), 2)
|
||||
return self.execute_get(b"\xf2\x35" + pack('<II', addr, value), 2)
|
||||
|
||||
def control_nrst(self, value):
|
||||
return self.execute_get(b"\xf2\x3c" + pack('<B', value), 2)
|
||||
|
||||
def run(self):
|
||||
v = self.execute_get("\xf2\x09\x00", 2)
|
||||
v = self.execute_get(b"\xf2\x09\x00", 2)
|
||||
return (v[1] << 8) + v[0]
|
||||
|
||||
def core_id(self):
|
||||
v = self.execute_get("\xf2\x22\x00", 4)
|
||||
def get_core_id(self):
|
||||
v = self.execute_get(b"\xf2\x22\x00", 4)
|
||||
return v[0] + (v[1]<<8) + (v[2]<<16) + (v[3]<<24)
|
||||
|
||||
def version(self):
|
||||
v = self.execute_get("\xf1", 6)
|
||||
v = self.execute_get(b"\xf1", 6)
|
||||
val = (v[0] << 8) + v[1]
|
||||
return ((val >> 12) & 0x0f, (val >> 6) & 0x3f, val & 0x3f)
|
||||
|
||||
@@ -309,7 +320,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()
|
||||
@@ -329,7 +340,7 @@ class stlinkv2(object):
|
||||
def option_bytes_write(self,addr,val):
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
|
||||
self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY1)
|
||||
self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY2)
|
||||
@@ -353,13 +364,13 @@ class stlinkv2(object):
|
||||
def option_bytes_erase(self):
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
|
||||
self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY1)
|
||||
self.write_memory_u32(FLASH_OPTKEYR, FLASH_KEY2)
|
||||
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_OPTER)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_OPTER)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_OPTER)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_OPTER)
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
@@ -371,7 +382,7 @@ class stlinkv2(object):
|
||||
break
|
||||
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
|
||||
if (status & FLASH_SR_EOP) == 0:
|
||||
if (status & FLASH_SR_EOP) == 0:
|
||||
raise OperationFailure("option bytes erase")
|
||||
|
||||
def flash_write_internal(self, addr, data, off, size):
|
||||
@@ -394,12 +405,12 @@ class stlinkv2(object):
|
||||
def flash_write(self, addr, data):
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
|
||||
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
|
||||
@@ -413,10 +424,10 @@ class stlinkv2(object):
|
||||
def flash_erase_all(self):
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_MER)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_MER)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER)
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
@@ -430,18 +441,18 @@ class stlinkv2(object):
|
||||
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
|
||||
|
||||
if (status & FLASH_SR_EOP) == 0:
|
||||
if (status & FLASH_SR_EOP) == 0:
|
||||
raise OperationFailure("flash erase all")
|
||||
|
||||
def flash_erase_page(self, addr):
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY1)
|
||||
self.write_memory_u32(FLASH_KEYR, FLASH_KEY2)
|
||||
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
self.write_memory_u32(FLASH_SR, FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR)
|
||||
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_PER)
|
||||
self.write_memory_u32(FLASH_AR, addr)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_PER)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_PER)
|
||||
self.write_memory_u32(FLASH_AR, addr)
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_STRT | FLASH_CR_PER)
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
@@ -454,7 +465,7 @@ class stlinkv2(object):
|
||||
|
||||
self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK)
|
||||
|
||||
if (status & FLASH_SR_EOP) == 0:
|
||||
if (status & FLASH_SR_EOP) == 0:
|
||||
raise OperationFailure("flash page erase")
|
||||
|
||||
def start(self):
|
||||
@@ -466,11 +477,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,9 +495,56 @@ 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
|
||||
USB_VENDOR_STLINKV2_1=0x374b # 0x374b ST-LINK/V2_1
|
||||
|
||||
def stlinkv2_devices():
|
||||
busses = usb.busses()
|
||||
@@ -494,14 +553,14 @@ def stlinkv2_devices():
|
||||
for dev in devices:
|
||||
if dev.idVendor != USB_VENDOR_ST:
|
||||
continue
|
||||
if dev.idProduct != USB_VENDOR_STLINKV2:
|
||||
if dev.idProduct != USB_VENDOR_STLINKV2 and dev.idProduct != USB_VENDOR_STLINKV2_1:
|
||||
continue
|
||||
yield dev
|
||||
|
||||
def compare(data_original, data_in_device):
|
||||
i = 0
|
||||
for d in data_original:
|
||||
if ord(d) != data_in_device[i]:
|
||||
if d != data_in_device[i]:
|
||||
raise ValueError("Verify failed at:", i)
|
||||
i += 1
|
||||
|
||||
@@ -515,15 +574,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 +596,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 +636,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 +645,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 +660,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,11 +687,11 @@ 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"
|
||||
data_received = ()
|
||||
print("VERIFY")
|
||||
data_received = array('B')
|
||||
size = len(data)
|
||||
off = 0
|
||||
while size > 0:
|
||||
@@ -641,17 +699,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 + array('B', stl.read_memory(0x08000000+off, blk_size))
|
||||
size = size - blk_size
|
||||
off = off + blk_size
|
||||
compare(data, data_received)
|
||||
compare(array('B', 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 +764,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 +775,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)
|
||||
|
||||
@@ -44,11 +44,11 @@ def main(keyno, passwd, data_regnual, data_upgrade):
|
||||
rsa_raw_pubkey = rsa.get_raw_pubkey(rsa_key)
|
||||
|
||||
gnuk = get_gnuk_device()
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd)
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd.encode('UTF-8'))
|
||||
gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
|
||||
|
||||
gnuk.cmd_select_openpgp()
|
||||
challenge = gnuk.cmd_get_challenge()
|
||||
challenge = gnuk.cmd_get_challenge().tostring()
|
||||
digestinfo = binascii.unhexlify(SHA256_OID_PREFIX) + challenge
|
||||
signed = rsa.compute_signature(rsa_key, digestinfo)
|
||||
signed_bytes = rsa.integer_to_bytes_256(signed)
|
||||
@@ -110,11 +110,11 @@ if __name__ == '__main__':
|
||||
passwd = getpass("Admin password: ")
|
||||
filename_regnual = sys.argv[1]
|
||||
filename_upgrade = sys.argv[2]
|
||||
f = open(filename_regnual)
|
||||
f = open(filename_regnual,"rb")
|
||||
data_regnual = f.read()
|
||||
f.close()
|
||||
print("%s: %d" % (filename_regnual, len(data_regnual)))
|
||||
f = open(filename_upgrade)
|
||||
f = open(filename_upgrade,"rb")
|
||||
data_upgrade = f.read()
|
||||
f.close()
|
||||
print("%s: %d" % (filename_upgrade, len(data_upgrade)))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
usb_strings.py - a tool to dump USB string
|
||||
|
||||
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.
|
||||
@@ -27,7 +27,7 @@ import usb, sys
|
||||
USB_VENDOR_FSIJ=0x234b
|
||||
USB_PRODUCT_GNUK=0x0000
|
||||
|
||||
def gnuk_devices():
|
||||
def gnuk_devices_by_vidpid():
|
||||
busses = usb.busses()
|
||||
for bus in busses:
|
||||
devices = bus.devices
|
||||
@@ -38,16 +38,16 @@ 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():
|
||||
for dev in gnuk_devices_by_vidpid():
|
||||
handle = dev.open()
|
||||
print "Device: ", dev.filename
|
||||
print("Device: %s" % dev.filename)
|
||||
try:
|
||||
for i in range(1,n):
|
||||
str = handle.getString(i, 512)
|
||||
print "%10s: %s" % (title[i], str)
|
||||
s = handle.getString(i, 512)
|
||||
print("%10s: %s" % (field[i], s.decode('UTF-8')))
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user