Compare commits
41 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
452c15c908 | ||
|
|
dc568422b1 | ||
|
|
5edcf32bb7 | ||
|
|
2647797348 | ||
|
|
9697694e45 | ||
|
|
f5cbc71a54 | ||
|
|
5099bfee88 | ||
|
|
691e16c605 | ||
|
|
eabcec107e | ||
|
|
73c698c67e | ||
|
|
d035c53b9c | ||
|
|
a96a3eefe6 | ||
|
|
fd08a853fd | ||
|
|
f882acc1b4 | ||
|
|
907d8c7a8e | ||
|
|
d636bf314c | ||
|
|
0212328a6a | ||
|
|
eb90074e11 | ||
|
|
38d164360c | ||
|
|
ff190a8053 | ||
|
|
f86f97cdbe | ||
|
|
1e004bec78 | ||
|
|
d68bee21e5 | ||
|
|
2903e88986 | ||
|
|
25fed157e1 | ||
|
|
d5c5571423 | ||
|
|
51d4b754e6 | ||
|
|
48905155c5 | ||
|
|
772071d1ba | ||
|
|
1fa45e3273 | ||
|
|
1a5eb0ec3b | ||
|
|
106b042e75 | ||
|
|
eebd40d946 | ||
|
|
5e37c7722a | ||
|
|
b1a582e87c | ||
|
|
3f1ee534fe | ||
|
|
522ec3299e | ||
|
|
34e2099b23 | ||
|
|
baf09ecac9 | ||
|
|
db23a1d051 | ||
|
|
3f8c4d1f17 |
251
ChangeLog
251
ChangeLog
@@ -1,3 +1,254 @@
|
|||||||
|
2016-07-11 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* VERSION: 1.2.1.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (ccid_power_on): Fix call of chopstx_create.
|
||||||
|
* src/usb-msc.c (msc_init): Ditto.
|
||||||
|
* src/pin-cir.c (cir_init): Ditto.
|
||||||
|
* src/neug.c (neug_init): Ditto.
|
||||||
|
* src/main.c (main): Ditto.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (struct ccid): Arrange for smaller footprint.
|
||||||
|
* src/gnuk.h (struct apdu): Likewise.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (ccid_card_change_signal): Don't touch ccid_state_p.
|
||||||
|
(ccid_state_p): This is constant.
|
||||||
|
|
||||||
|
* src/configure (output_vendor_product_serial_strings): Add const
|
||||||
|
qualifier.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (epo_init, epi_init): Simplify without notify method.
|
||||||
|
(EP1_IN_Callback, EP1_OUT_Callback): Call notify_tx and notify_icc
|
||||||
|
directly.
|
||||||
|
|
||||||
|
2016-07-09 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/openpgp.c (openpgp_card_thread): Don't need to get SELF.
|
||||||
|
|
||||||
|
2016-07-06 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/pin-cir.c (cir_getchar): Use chopstx_poll.
|
||||||
|
* src/usb-ccid.c (usb_tx_done): Fix ifdef condition.
|
||||||
|
* src/usb_ctrl.c (usb_ctrl_write_finish): Fix ifdef nesting.
|
||||||
|
|
||||||
|
2016-07-04 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* doc/conf.py: Remove 'sphinx.ext.pngmath' and 'sphinx.ext.mathjax'.
|
||||||
|
Reported by Kenji Rikitake.
|
||||||
|
|
||||||
|
2016-07-01 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* chopstx: Update to 1.1.
|
||||||
|
* src/usb-ccid.c (poll_event_intr, ccid_thread): Follow the
|
||||||
|
change.
|
||||||
|
|
||||||
|
2016-06-21 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* doc/index.rst: Update documentation by an example
|
||||||
|
Ed25519/cv25519.
|
||||||
|
|
||||||
|
2016-06-17 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* chopstx: Update to 1.0.
|
||||||
|
|
||||||
|
2016-06-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/gnuk.ld.in (__process2_stack_size__): Update
|
||||||
|
thread size for rng by examining NeuG.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (poll_event_intr): New.
|
||||||
|
|
||||||
|
2016-06-14 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* regnual/regnual.c (usb_device_reset): Rename from
|
||||||
|
usb_cb_device_reset.
|
||||||
|
(usb_ctrl_write_finish): Rename from usb_cb_ctrl_write_finish.
|
||||||
|
(usb_setup): Rename from usb_cb_setup.
|
||||||
|
(usb_get_descriptor): Rename from usb_cb_get_descriptor.
|
||||||
|
(usb_set_configuration): New.
|
||||||
|
(usb_interrupt_handler): New.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (usb_tx_done): Rename from usb_cb_tx_done.
|
||||||
|
(usb_rx_ready): Rename from usb_cb_rx_ready.
|
||||||
|
(usb_event_handle): New.
|
||||||
|
(ccid_thread): Use usb_event_handle.
|
||||||
|
|
||||||
|
* src/usb-msc.c (EP6_IN_Callback): Update to new USB API.
|
||||||
|
(EP6_OUT_Callback): Likewise.
|
||||||
|
|
||||||
|
* src/usb_ctrl.c (usb_device_reset): Rename from
|
||||||
|
usb_cb_device_reset.
|
||||||
|
(vcom_port_data_setup): Update to new USB API.
|
||||||
|
(usb_ctrl_write_finish): Rename from usb_cb_ctrl_write_finish.
|
||||||
|
(usb_setup): Rename from usb_cb_setup.
|
||||||
|
(usb_set_configuration): New, based on usb_cb_handle_event.
|
||||||
|
(usb_set_interface): Rename from usb_cb_interface.
|
||||||
|
(usb_get_interface): New.
|
||||||
|
(usb_get_status_interface): New.
|
||||||
|
|
||||||
|
* src/usb_desc.c (usb_get_descriptor): Rename from
|
||||||
|
usb_cb_get_descriptor.
|
||||||
|
|
||||||
|
2016-06-02 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* regnual/regnual.c (usb_cb_tx_done): Follow the change of USB
|
||||||
|
API.
|
||||||
|
|
||||||
|
* regnual/reset.c: Rename from sys.c.
|
||||||
|
|
||||||
|
2016-06-01 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* tool/stlinkv2.py (stlinkv2.__init__): Don't
|
||||||
|
call setConfiguration.
|
||||||
|
|
||||||
|
* tool/gnuk_token.py (gnuk_token, regnual): Don't
|
||||||
|
call setAltInterface, it's not needed.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (ccid_notify_slot_change): New.
|
||||||
|
(ccid_thread): Call ccid_notify_slot_change at
|
||||||
|
interface_reset and EV_CARD_CHANGE.
|
||||||
|
|
||||||
|
2016-05-31 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/usb_stm32f103.c, src/stm32f103.h: Remove.
|
||||||
|
* src/adc_stm32f103.c, src/sys.c: Remove.
|
||||||
|
|
||||||
|
* src/usb_ctrl.c (usb_cb_interface): call ccid_usb_reset.
|
||||||
|
(usb_cb_handle_event): Likewise.
|
||||||
|
|
||||||
|
* src/usb-ccid.c (ccid_thread): Handle RESET->CONFIGURE process
|
||||||
|
correctly.
|
||||||
|
(ccid_thread): Handle SET_INTERFACE correctly.
|
||||||
|
|
||||||
|
* polarssl/library/aes.c (FT0, FT1, FT2): Add "weak" flag.
|
||||||
|
|
||||||
|
* src/neug.c: Update from NeuG.
|
||||||
|
|
||||||
|
* src/usb_desc.c (usb_cb_get_descriptor): Only valid if USE_SYS3.
|
||||||
|
|
||||||
|
* src/Makefile.in (USE_SYS, USE_USB, USE_ADC): Enabled.
|
||||||
|
(CHIP): Add.
|
||||||
|
|
||||||
|
* src/sys.c, src/sys.h: Remove.
|
||||||
|
* src/usb_stm32f103.c, src/usb_lld.h: Remove.
|
||||||
|
* src/adc_stm32f103.c, src/adc.h: Remove.
|
||||||
|
|
||||||
|
* chopstx: Update to 0.12.
|
||||||
|
|
||||||
|
2016-05-21 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/main.c (led_blink, main): Fix LED blink protocol.
|
||||||
|
|
||||||
|
2016-05-20 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* VERSION: 1.2.0.
|
||||||
|
* src/usb-ccid.c (ccid_thread): Fix timeout.
|
||||||
|
(icc_handle_timeout, icc_send_status): Tweak.
|
||||||
|
|
||||||
|
2016-05-19 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/usb_ctrl.c (usb_cb_ctrl_write_finish): Set bDeviceState.
|
||||||
|
|
||||||
|
* src/usb-ccid.c: Rename from usb-icc.c.
|
||||||
|
(ccid_thread): Handle reGNUal upgrade.
|
||||||
|
|
||||||
|
* src/Makefile.in (CSRC): Follow the change.
|
||||||
|
|
||||||
|
* chopstx: Update to 0.11.
|
||||||
|
|
||||||
|
2016-05-18 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/gnuk.ld.in: Tweak thread size.
|
||||||
|
* src/main.c (main): Use chopstx_setpriority.
|
||||||
|
* src/usb-icc.c (ccid_init): Use new eventflag API.
|
||||||
|
|
||||||
|
* regnual/regnual.c (nvic_enable_intr): New.
|
||||||
|
(main): Call nvic_enable_intr.
|
||||||
|
|
||||||
|
* chopstx: Update.
|
||||||
|
|
||||||
|
2016-05-16 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* regnual/regnual.c (usb_cb_rx_ready, usb_cb_tx_done)
|
||||||
|
(usb_cb_device_reset): Follow the change of USB API.
|
||||||
|
|
||||||
|
* chopstx: Update.
|
||||||
|
* src/sys.c: Update from Chopstx.
|
||||||
|
|
||||||
|
2016-05-13 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/neug.c (rng): Call chopstx_claim_irq before adc_start.
|
||||||
|
Remove call of chopstx_release_irq.
|
||||||
|
|
||||||
|
2016-05-12 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* chopstx: Update.
|
||||||
|
* src/sys.c: Update from Chopstx.
|
||||||
|
* src/usb_lld.h: Likewise.
|
||||||
|
* src/usb_stm32f103.c: Likewise.
|
||||||
|
|
||||||
|
* src/usb_ctrl.c (usb_intr): Follow the change of USB API.
|
||||||
|
(usb_cb_rx_ready, usb_cb_tx_done): Likewise.
|
||||||
|
|
||||||
|
* src/adc.h: Remove unused declarations.
|
||||||
|
|
||||||
|
2016-03-08 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* tool/gnuk_token.py (gnuk_token.__init__, regnual.__init__):
|
||||||
|
Don't call setConfiguration method.
|
||||||
|
|
||||||
|
* src/usb_lld.h (usb_cb_ctrl_write_finish): Change the API of
|
||||||
|
callback, which possibly needs INDEX, VALUE, and LEN parameters.
|
||||||
|
(usb_lld_set_data_to_recv): Fix the type of P.
|
||||||
|
(USB_DEVICE_DESCRIPTOR_TYPE, USB_CONFIGURATION_DESCRIPTOR_TYPE)
|
||||||
|
(USB_STRING_DESCRIPTOR_TYPE, USB_INTERFACE_DESCRIPTOR_TYPE)
|
||||||
|
(USB_ENDPOINT_DESCRIPTOR_TYPE): Remove, as we have the enumeration
|
||||||
|
values for same things.
|
||||||
|
|
||||||
|
* src/usb_stm32f103.c (handle_in0): Follow the change.
|
||||||
|
* src/usb_ctrl.c (usb_cb_ctrl_write_finish): Likewise.
|
||||||
|
|
||||||
|
* src/usb_desc.c (usb_cb_get_descriptor): Use HID_INTERFACE.
|
||||||
|
(device_desc, config_desc, string_descriptors)
|
||||||
|
(usb_cb_get_descriptor): Use the enumeration types.
|
||||||
|
* src/configure: Use the enumeration types.
|
||||||
|
|
||||||
|
* regnual/regnual.c: Follow the change of usb_lld.h.
|
||||||
|
|
||||||
|
2016-02-09 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/openpgp.c (cmd_verify): Support VERIFY reset, which is
|
||||||
|
described in the specification V2.2 and V3.1.
|
||||||
|
|
||||||
|
* polarssl/library/bignum.c (mpi_exp_mod): Fix to our local
|
||||||
|
change. Thanks to Aidan Thornton for the failure test case.
|
||||||
|
|
||||||
|
Fix of mpi_div_mpi from upstream.
|
||||||
|
* polarssl/library/bignum.c (int_clz, int_div_int): New.
|
||||||
|
(mpi_div_mpi): Use int_div_int.
|
||||||
|
|
||||||
|
2016-02-09 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/openpgp.c (s2k): Include the unique ID of MCU into the
|
||||||
|
computation of S2K function.
|
||||||
|
|
||||||
|
2016-02-08 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/modp256r1.c (modp256r1_add, modp256r1_sub): Keep the result
|
||||||
|
less than P256R1.
|
||||||
|
(modp256r1_reduce): Fix wrong calculation.
|
||||||
|
* src/modp256k1.c (modp256k1_add, modp256k1_sub): Likewise.
|
||||||
|
Thanks to Aidan Thornton.
|
||||||
|
|
||||||
|
2016-02-05 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/configure: Add submodule check suggested by Elliott
|
||||||
|
Mitchell.
|
||||||
|
|
||||||
|
2015-11-30 perillamint <perillamint@gentoo.moe>
|
||||||
|
|
||||||
|
* src/openpgp.c (card_thread): Fix offset of bConfirmPIN.
|
||||||
|
|
||||||
2015-09-18 Niibe Yutaka <gniibe@fsij.org>
|
2015-09-18 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* VERSION: 1.1.9.
|
* VERSION: 1.1.9.
|
||||||
|
|||||||
31
NEWS
31
NEWS
@@ -1,5 +1,36 @@
|
|||||||
Gnuk NEWS - User visible changes
|
Gnuk NEWS - User visible changes
|
||||||
|
|
||||||
|
* Major changes in Gnuk 1.2.1
|
||||||
|
|
||||||
|
Released 2016-07-11, by NIIBE Yutaka
|
||||||
|
|
||||||
|
** Upgrade of Chopstx
|
||||||
|
We use Chopstx 1.1.
|
||||||
|
|
||||||
|
|
||||||
|
* Major changes in Gnuk 1.2.0
|
||||||
|
|
||||||
|
Released 2016-05-20, by NIIBE Yutaka
|
||||||
|
|
||||||
|
** Upgrade of Chopstx
|
||||||
|
We use Chopstx 0.11.
|
||||||
|
|
||||||
|
** Support authentication status reset by VERIFY command.
|
||||||
|
This feature is described in the OpenPGPcard specification V2.2 and
|
||||||
|
V3.1, which allow user to reset authentication status.
|
||||||
|
|
||||||
|
** S2K algorithm tweak to defeat "copycat" service of MCU.
|
||||||
|
Even if the existence of some services copying MCU, your private key
|
||||||
|
will not be controled by others, in some cases.
|
||||||
|
|
||||||
|
** Bug fix for secp256k1 and NIST P-256.
|
||||||
|
Bugs in basic computation were fixed.
|
||||||
|
|
||||||
|
** Bug fix for bignum routines.
|
||||||
|
Bignum routine update from upstream (failure doesn't occur for our RSA
|
||||||
|
computation, though). Another fix for mpi_exp_mod.
|
||||||
|
|
||||||
|
|
||||||
* Major changes in Gnuk 1.1.9
|
* Major changes in Gnuk 1.1.9
|
||||||
|
|
||||||
Released 2015-09-18, by NIIBE Yutaka
|
Released 2015-09-18, by NIIBE Yutaka
|
||||||
|
|||||||
88
README
88
README
@@ -1,28 +1,27 @@
|
|||||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||||
|
|
||||||
Version 1.1.9
|
Version 1.2.1
|
||||||
2015-09-18
|
2016-07-11
|
||||||
Niibe Yutaka
|
Niibe Yutaka
|
||||||
Free Software Initiative of Japan
|
Free Software Initiative of Japan
|
||||||
|
|
||||||
Warning
|
Release Notes
|
||||||
=======
|
=============
|
||||||
|
|
||||||
This is another experimental release of Gnuk, version 1.1.9, which has
|
This is the release of Gnuk, version 1.2.1, which has major
|
||||||
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
||||||
overriding key import, but importing keys (or generating keys) results
|
overriding key import, but importing keys (or generating keys) results
|
||||||
password reset. Please update your documentation for Gnuk Token, so
|
password reset. Please update your documentation for Gnuk Token, so
|
||||||
that the instruction of importing keys won't cause any confusion. It
|
that the instruction of importing keys won't cause any confusion.
|
||||||
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 modern GnuPG with
|
|
||||||
development version of libgcrypt.
|
|
||||||
|
|
||||||
It also supports RSA-4096 experimentally, but users should know that
|
It has supports of EdDSA, ECDSA (with NIST P256 and secp256k1), and
|
||||||
it takes more than 8 second to sign/decrypt.
|
ECDH (with X25519, NIST P256 and secp256k1), but this ECC feature is
|
||||||
|
somehow experimental, and it requires modern GnuPG 2.1 with libgcrypt
|
||||||
|
1.7.0 or later.
|
||||||
|
|
||||||
You will not able to keep using Curve25519 keys, as the key format is
|
It also supports RSA-4096, but users should know that it takes more
|
||||||
subject to change.
|
than 8 seconds to sign/decrypt. Key generation of RSA-4096 just fails,
|
||||||
|
because the device doesn't have enough memory.
|
||||||
|
|
||||||
|
|
||||||
What's Gnuk?
|
What's Gnuk?
|
||||||
@@ -63,11 +62,12 @@ A0: Good points of Gnuk are:
|
|||||||
|
|
||||||
Q1: What kind of key algorithm is supported?
|
Q1: What kind of key algorithm is supported?
|
||||||
A1: Gnuk version 1.0 only supports RSA-2048.
|
A1: Gnuk version 1.0 only supports RSA-2048.
|
||||||
Development version of Gnuk (1.1.x) supports 256-bit ECDSA and EdDSA,
|
Gnuk version 1.2.x supports 255-bit EdDSA, as well as RSA-4096.
|
||||||
as well as RSA 4096-bit. But it takes long time to sign with RSA-4096.
|
(Note that it takes long time to sign with RSA-4096.)
|
||||||
|
|
||||||
Q2: How long does it take for digital signing?
|
Q2: How long does it take for digital signing?
|
||||||
A2: It takes a second and a half or so for RSA-2048.
|
A2: It takes a second and a half or so for RSA-2048.
|
||||||
|
It takes more than 8 secondd for RSA-4096.
|
||||||
|
|
||||||
Q3: What's your recommendation for target board?
|
Q3: What's your recommendation for target board?
|
||||||
A3: Orthodox choice is Olimex STM32-H103.
|
A3: Orthodox choice is Olimex STM32-H103.
|
||||||
@@ -77,7 +77,7 @@ A3: Orthodox choice is Olimex STM32-H103.
|
|||||||
choice for experiment.
|
choice for experiment.
|
||||||
|
|
||||||
Q4: What's version of GnuPG are you using?
|
Q4: What's version of GnuPG are you using?
|
||||||
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.x in
|
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.13 in
|
||||||
experimental.
|
experimental.
|
||||||
|
|
||||||
Q5: What's version of pcscd and libccid are you using?
|
Q5: What's version of pcscd and libccid are you using?
|
||||||
@@ -139,22 +139,14 @@ Ac: That's because gnome-keyring-daemon interferes GnuPG. Please
|
|||||||
Qd: Do you know a good SWD debugger to connect FST-01 or something?
|
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
|
Ad: ST-Link/V2 is cheap one. We have a tool/stlinkv2.py as flash ROM
|
||||||
writer program. STM32 Nucleo F103 comes with the valiant of
|
writer program. STM32 Nucleo F103 comes with the valiant of
|
||||||
ST-Link/V2.
|
ST-Link/V2. However, the firmware of ST-Link/V2 is proprietary.
|
||||||
|
Now, I develop BBG-SWD, SWD debugger by BeagleBone Green.
|
||||||
|
|
||||||
|
|
||||||
Release notes
|
Tested features
|
||||||
=============
|
===============
|
||||||
|
|
||||||
This is ninth experimental release in version 1.1 series of Gnuk.
|
Gnuk is tested by test suite. Please see the test directory.
|
||||||
|
|
||||||
While it is daily use by its developer, some newly introduced features
|
|
||||||
(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:
|
|
||||||
|
|
||||||
* Personalization of the card
|
* Personalization of the card
|
||||||
* Changing Login name, URL, Name, Sex, Language, etc.
|
* Changing Login name, URL, Name, Sex, Language, etc.
|
||||||
@@ -171,10 +163,10 @@ Tested features are:
|
|||||||
* Modify with pin pad
|
* Modify with pin pad
|
||||||
* Card holder certificate (read)
|
* Card holder certificate (read)
|
||||||
* Removal of keys
|
* Removal of keys
|
||||||
* Key generation on device side
|
* Key generation on device side for RSA-2048
|
||||||
* Overriding key import
|
* Overriding key import
|
||||||
|
|
||||||
Original features of Gnuk, tested lightly:
|
Original features of Gnuk, tested manually lightly:
|
||||||
|
|
||||||
* OpenPGP card serial number setup
|
* OpenPGP card serial number setup
|
||||||
* Card holder certificate (write by UPDATE BINARY)
|
* Card holder certificate (write by UPDATE BINARY)
|
||||||
@@ -182,12 +174,12 @@ Original features of Gnuk, tested lightly:
|
|||||||
|
|
||||||
It is known not-working well:
|
It is known not-working well:
|
||||||
|
|
||||||
* It is known that the combination of libccid 1.4.1 (or newer)
|
* It is known that the specific combination of libccid 1.4.1
|
||||||
with libusb 1.0.8 (or older) has a minor problem. It is
|
(or newer) with libusb 1.0.8 (or older) had a minor problem.
|
||||||
rare but it is possible for USB communication to be failed,
|
It is rare but it is possible for USB communication to be
|
||||||
because of a bug in libusb implementation. Use libusbx
|
failed, because of a bug in libusb implementation. Use
|
||||||
1.0.9 or newer, or don't use PC/SC, but use internal CCID
|
libusbx 1.0.9 or newer, or don't use PC/SC, but use internal
|
||||||
driver of GnuPG.
|
CCID driver of GnuPG.
|
||||||
|
|
||||||
|
|
||||||
Targets
|
Targets
|
||||||
@@ -256,7 +248,7 @@ External source code
|
|||||||
|
|
||||||
Gnuk is distributed with external source code.
|
Gnuk is distributed with external source code.
|
||||||
|
|
||||||
* chopstx/ -- Chopstx 0.10
|
* chopstx/ -- Chopstx 1.1
|
||||||
|
|
||||||
We use Chopstx as the kernel for Gnuk.
|
We use Chopstx as the kernel for Gnuk.
|
||||||
|
|
||||||
@@ -369,9 +361,9 @@ You need GNU toolchain and newlib for 'arm-none-eabi' target.
|
|||||||
On Debian we can install the packages of gcc-arm-none-eabi,
|
On Debian we can install the packages of gcc-arm-none-eabi,
|
||||||
gdb-arm-none-eabi and its friends. I'm using:
|
gdb-arm-none-eabi and its friends. I'm using:
|
||||||
|
|
||||||
binutils-arm-none-eabi 2.25-5+5+b1
|
binutils-arm-none-eabi 2.26-4+8
|
||||||
gcc-arm-none-eabi 15:4.9.3+svn227297-1
|
gcc-arm-none-eabi 15:4.9.3+svn231177-1
|
||||||
gdb-arm-none-eabi 7.7.1+dfsg-5+8
|
gdb-arm-none-eabi 7.10-1+9
|
||||||
libnewlib-arm-none-eabi 2.2.0+git20150830.5a3d536-1
|
libnewlib-arm-none-eabi 2.2.0+git20150830.5a3d536-1
|
||||||
|
|
||||||
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
||||||
@@ -459,11 +451,13 @@ to access the contents. If you want to protect, killing DfuSe and
|
|||||||
accessing by JTAG debugger is recommended.
|
accessing by JTAG debugger is recommended.
|
||||||
|
|
||||||
|
|
||||||
How to configure
|
(Optional) Configure serial number and X.509 certificate
|
||||||
================
|
========================================================
|
||||||
|
|
||||||
You need python and pyscard (python-pyscard package in Debian) or
|
This is completely optional.
|
||||||
PyUSB 0.4.3 (python-usb package in Debian).
|
|
||||||
|
For this procedure, you need python and pyscard (python-pyscard
|
||||||
|
package in Debian) or PyUSB 0.4.3 (python-usb package in Debian).
|
||||||
|
|
||||||
(1) [pyscard] Stop scdaemon
|
(1) [pyscard] Stop scdaemon
|
||||||
[PyUSB] Stop the pcsc daemon.
|
[PyUSB] Stop the pcsc daemon.
|
||||||
@@ -616,7 +610,7 @@ Your Contributions
|
|||||||
==================
|
==================
|
||||||
|
|
||||||
FSIJ welcomes your contributions. Please assign your copyright
|
FSIJ welcomes your contributions. Please assign your copyright
|
||||||
to FSIJ (if possible).
|
to FSIJ (if possible), as I do.
|
||||||
|
|
||||||
|
|
||||||
Foot note
|
Foot note
|
||||||
|
|||||||
2
THANKS
2
THANKS
@@ -14,10 +14,12 @@ Andre Zepezauer andre.zepezauer@student.uni-halle.de
|
|||||||
Bertrand Jacquin bertrand@jacquin.bzh
|
Bertrand Jacquin bertrand@jacquin.bzh
|
||||||
Clint Adams clint@softwarefreedom.org
|
Clint Adams clint@softwarefreedom.org
|
||||||
Daniel Kahn Gillmor dkg@fifthhorseman.net
|
Daniel Kahn Gillmor dkg@fifthhorseman.net
|
||||||
|
Elliott Mitchell
|
||||||
Hironobu SUZUKI hironobu@h2np.net
|
Hironobu SUZUKI hironobu@h2np.net
|
||||||
Jan Suhr jan@suhr.info
|
Jan Suhr jan@suhr.info
|
||||||
Jonathan McDowell noodles@earth.li
|
Jonathan McDowell noodles@earth.li
|
||||||
Kaz Kojima kkojima@rr.iij4u.or.jp
|
Kaz Kojima kkojima@rr.iij4u.or.jp
|
||||||
|
Kenji Rikitake
|
||||||
Ludovic Rousseau ludovic.rousseau@free.fr
|
Ludovic Rousseau ludovic.rousseau@free.fr
|
||||||
Luis Felipe R. Murillo luisfelipe@ucla.edu
|
Luis Felipe R. Murillo luisfelipe@ucla.edu
|
||||||
Mateusz Zalega mateusz@nitrokey.com
|
Mateusz Zalega mateusz@nitrokey.com
|
||||||
|
|||||||
2
chopstx
2
chopstx
Submodule chopstx updated: a30a069ed8...09f27704f5
@@ -25,7 +25,7 @@ import sys, os
|
|||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.pngmath', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode']
|
extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode']
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
|||||||
@@ -22,24 +22,19 @@ tool/stlinkv2.py.
|
|||||||
OpenOCD
|
OpenOCD
|
||||||
-------
|
-------
|
||||||
|
|
||||||
For JTAG/SWD debugger, we can use OpenOCD somehow.
|
For JTAG/SWD debugger, we can use OpenOCD.
|
||||||
|
|
||||||
Note that ST-Link/V2 was *not* supported by OpenOCD 0.5.0.
|
|
||||||
|
|
||||||
It is supported by version 0.6 or later somehow, but still, you can't
|
|
||||||
enable protection of flash ROM with OpenOCD using ST-Link/V2.
|
|
||||||
|
|
||||||
|
|
||||||
GNU Toolchain
|
GNU Toolchain
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
You need GNU toolchain and newlib for 'arm-none-eabi' target.
|
You need GNU toolchain and newlib for 'arm-none-eabi' target.
|
||||||
|
In Debian, we can just apt-get packages of: gcc-arm-none-eabi, binutils-arm-none-eabi, gdb-arm-none-eabi and libnewlib-arm-none-eabi.
|
||||||
|
|
||||||
There is "gcc-arm-embedded" project. See:
|
For other distributiions, there is "gcc-arm-embedded" project. See:
|
||||||
https://launchpad.net/gcc-arm-embedded/
|
https://launchpad.net/gcc-arm-embedded/
|
||||||
|
|
||||||
It is based on GCC 4.8 (as of December, 2013). We are using "-O3 -Os"
|
We are using "-O3 -Os" for compiler option.
|
||||||
for compiler option.
|
|
||||||
|
|
||||||
|
|
||||||
Building Gnuk
|
Building Gnuk
|
||||||
|
|||||||
@@ -1,313 +0,0 @@
|
|||||||
============================
|
|
||||||
Generating 2048-bit RSA keys
|
|
||||||
============================
|
|
||||||
|
|
||||||
In this section, we describe how to generate 2048-bit RSA keys.
|
|
||||||
|
|
||||||
|
|
||||||
Key length of RSA
|
|
||||||
=================
|
|
||||||
|
|
||||||
In 2005, NIST (National Institute of Standards and Technology, USA)
|
|
||||||
has issued the first revision of NIST Special Publication 800-57,
|
|
||||||
"Recommendation for Key Management".
|
|
||||||
|
|
||||||
In 800-57, NIST advises that 1024-bit RSA keys will no longer be
|
|
||||||
viable after 2010 and advises moving to 2048-bit RSA keys. NIST
|
|
||||||
advises that 2048-bit keys should be viable until 2030.
|
|
||||||
|
|
||||||
As of 2010, GnuPG's default for generating RSA key is 2048-bit.
|
|
||||||
|
|
||||||
Some people have preference on RSA 4096-bit keys, considering
|
|
||||||
"longer is better".
|
|
||||||
|
|
||||||
However, "longer is better" is not always true. When it's long, it
|
|
||||||
requires more computational resource, memory and storage, and it
|
|
||||||
consumes more power for nomal usages. These days, many people has
|
|
||||||
enough computational resource, that would be true, but less is better
|
|
||||||
for power consumption.
|
|
||||||
|
|
||||||
For security, the key length is just a single factor. We had and will have
|
|
||||||
algorithm issues, too. It is true that it's difficult to update
|
|
||||||
our public keys, but this problem wouldn't be solved by just have
|
|
||||||
longer keys.
|
|
||||||
|
|
||||||
We deliberately support only RSA 2048-bit keys for Gnuk, considering
|
|
||||||
device computation power and host software constraints.
|
|
||||||
|
|
||||||
Thus, the key size is 2048-bit in the examples below.
|
|
||||||
|
|
||||||
|
|
||||||
Generating keys on host PC
|
|
||||||
==========================
|
|
||||||
|
|
||||||
Here is the example session to generate main key and a subkey for encryption.
|
|
||||||
|
|
||||||
I invoke GnuPG with ``--gen-key`` option. ::
|
|
||||||
|
|
||||||
$ gpg --gen-key
|
|
||||||
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
|
||||||
This is free software: you are free to change and redistribute it.
|
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
|
||||||
|
|
||||||
and GnuPG asks kind of key. Select ``RSA and RSA``. ::
|
|
||||||
|
|
||||||
Please select what kind of key you want:
|
|
||||||
(1) RSA and RSA (default)
|
|
||||||
(2) DSA and Elgamal
|
|
||||||
(3) DSA (sign only)
|
|
||||||
(4) RSA (sign only)
|
|
||||||
Your selection? 1
|
|
||||||
RSA keys may be between 1024 and 4096 bits long.
|
|
||||||
|
|
||||||
and select 2048-bit (as Gnuk Token only supports this). ::
|
|
||||||
|
|
||||||
What keysize do you want? (2048)
|
|
||||||
Requested keysize is 2048 bits
|
|
||||||
|
|
||||||
and select expiration of the key. ::
|
|
||||||
|
|
||||||
Please specify how long the key should be valid.
|
|
||||||
0 = key does not expire
|
|
||||||
<n> = key expires in n days
|
|
||||||
<n>w = key expires in n weeks
|
|
||||||
<n>m = key expires in n months
|
|
||||||
<n>y = key expires in n years
|
|
||||||
Key is valid for? (0) 0
|
|
||||||
Key does not expire at all
|
|
||||||
|
|
||||||
Confirm key types, bitsize and expiration. ::
|
|
||||||
|
|
||||||
Is this correct? (y/N) y
|
|
||||||
|
|
||||||
Then enter user ID. ::
|
|
||||||
|
|
||||||
You need a user ID to identify your key; the software constructs the user ID
|
|
||||||
from the Real Name, Comment and Email Address in this form:
|
|
||||||
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
|
|
||||||
|
|
||||||
Real name: Niibe Yutaka
|
|
||||||
Email address: gniibe@fsij.org
|
|
||||||
Comment:
|
|
||||||
You selected this USER-ID:
|
|
||||||
"Niibe Yutaka <gniibe@fsij.org>"
|
|
||||||
|
|
||||||
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
|
|
||||||
|
|
||||||
and enter passphrase for this **key on host PC**.
|
|
||||||
Note that this is a passphrase for the key on host PC.
|
|
||||||
It is different thing to the passphrase of Gnuk Token.
|
|
||||||
|
|
||||||
We enter two same inputs two times
|
|
||||||
(once for passphrase input, and another for confirmation). ::
|
|
||||||
|
|
||||||
You need a Passphrase to protect your secret key.
|
|
||||||
<PASSWORD-KEY-ON-PC>
|
|
||||||
|
|
||||||
Then, GnuPG generate keys. It takes some time. ::
|
|
||||||
|
|
||||||
We need to generate a lot of random bytes. It is a good idea to perform
|
|
||||||
some other action (type on the keyboard, move the mouse, utilize the
|
|
||||||
disks) during the prime generation; this gives the random number
|
|
||||||
generator a better chance to gain enough entropy.
|
|
||||||
...+++++
|
|
||||||
+++++
|
|
||||||
We need to generate a lot of random bytes. It is a good idea to perform
|
|
||||||
some other action (type on the keyboard, move the mouse, utilize the
|
|
||||||
disks) during the prime generation; this gives the random number
|
|
||||||
generator a better chance to gain enough entropy.
|
|
||||||
..+++++
|
|
||||||
|
|
||||||
Not enough random bytes available. Please do some other work to give
|
|
||||||
the OS a chance to collect more entropy! (Need 15 more bytes)
|
|
||||||
...+++++
|
|
||||||
gpg: key 4CA7BABE marked as ultimately trusted
|
|
||||||
public and secret key created and signed.
|
|
||||||
|
|
||||||
gpg: checking the trustdb
|
|
||||||
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
|
|
||||||
pub 2048R/4CA7BABE 2010-10-15
|
|
||||||
Key fingerprint = 1241 24BD 3B48 62AF 7A0A 42F1 00B4 5EBD 4CA7 BABE
|
|
||||||
uid Niibe Yutaka <gniibe@fsij.org>
|
|
||||||
sub 2048R/084239CF 2010-10-15
|
|
||||||
$
|
|
||||||
|
|
||||||
Done.
|
|
||||||
|
|
||||||
Then, we create authentication subkey.
|
|
||||||
Authentication subkey is not that common,
|
|
||||||
but very useful (for SSH authentication).
|
|
||||||
As it is not that common, we need ``--expert`` option for GnuPG. ::
|
|
||||||
|
|
||||||
$ gpg --expert --edit-key 4CA7BABE
|
|
||||||
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
|
||||||
This is free software: you are free to change and redistribute it.
|
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
|
||||||
|
|
||||||
Secret key is available.
|
|
||||||
|
|
||||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
|
||||||
trust: ultimate validity: ultimate
|
|
||||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
|
||||||
[ultimate] (1). Niibe Yutaka <gniibe@fsij.org>
|
|
||||||
|
|
||||||
gpg>
|
|
||||||
|
|
||||||
Here, it displays that there are main key and a subkey.
|
|
||||||
It prompts sub-command with ``gpg>`` .
|
|
||||||
|
|
||||||
Here, we enter ``addkey`` sub-command.
|
|
||||||
Then, we enter the passphrase of **key on host PC**.
|
|
||||||
It's the one we entered above as <PASSWORD-KEY-ON-PC>. ::
|
|
||||||
|
|
||||||
gpg> addkey
|
|
||||||
Key is protected.
|
|
||||||
|
|
||||||
You need a passphrase to unlock the secret key for
|
|
||||||
user: "Niibe Yutaka <gniibe@fsij.org>"
|
|
||||||
2048-bit RSA key, ID 4CA7BABE, created 2010-10-15
|
|
||||||
<PASSWORD-KEY-ON-PC>
|
|
||||||
gpg: gpg-agent is not available in this session
|
|
||||||
|
|
||||||
GnuPG asks kind of key. We select ``RSA (set your own capabilities)``. ::
|
|
||||||
|
|
||||||
Please select what kind of key you want:
|
|
||||||
(3) DSA (sign only)
|
|
||||||
(4) RSA (sign only)
|
|
||||||
(5) Elgamal (encrypt only)
|
|
||||||
(6) RSA (encrypt only)
|
|
||||||
(7) DSA (set your own capabilities)
|
|
||||||
(8) RSA (set your own capabilities)
|
|
||||||
Your selection? 8
|
|
||||||
|
|
||||||
And select ``Authenticate`` for the capabilities for this key.
|
|
||||||
Initially, it's ``Sign`` and ``Encrypt``.
|
|
||||||
I need to deselect ``Sign`` and ``Encrypt``, and select ``Authenticate``.
|
|
||||||
To do that, I enter ``s``, ``e``, and ``a``. ::
|
|
||||||
|
|
||||||
Possible actions for a RSA key: Sign Encrypt Authenticate
|
|
||||||
Current allowed actions: Sign Encrypt
|
|
||||||
|
|
||||||
(S) Toggle the sign capability
|
|
||||||
(E) Toggle the encrypt capability
|
|
||||||
(A) Toggle the authenticate capability
|
|
||||||
(Q) Finished
|
|
||||||
|
|
||||||
Your selection? s
|
|
||||||
|
|
||||||
Possible actions for a RSA key: Sign Encrypt Authenticate
|
|
||||||
Current allowed actions: Encrypt
|
|
||||||
|
|
||||||
(S) Toggle the sign capability
|
|
||||||
(E) Toggle the encrypt capability
|
|
||||||
(A) Toggle the authenticate capability
|
|
||||||
(Q) Finished
|
|
||||||
|
|
||||||
Your selection? e
|
|
||||||
|
|
||||||
Possible actions for a RSA key: Sign Encrypt Authenticate
|
|
||||||
Current allowed actions:
|
|
||||||
|
|
||||||
(S) Toggle the sign capability
|
|
||||||
(E) Toggle the encrypt capability
|
|
||||||
(A) Toggle the authenticate capability
|
|
||||||
(Q) Finished
|
|
||||||
|
|
||||||
Your selection? a
|
|
||||||
|
|
||||||
Possible actions for a RSA key: Sign Encrypt Authenticate
|
|
||||||
Current allowed actions: Authenticate
|
|
||||||
|
|
||||||
(S) Toggle the sign capability
|
|
||||||
(E) Toggle the encrypt capability
|
|
||||||
(A) Toggle the authenticate capability
|
|
||||||
(Q) Finished
|
|
||||||
|
|
||||||
OK, we set the capability of ``Authenticate``.
|
|
||||||
We enter ``q`` to finish setting capabilities. ::
|
|
||||||
|
|
||||||
Your selection? q
|
|
||||||
|
|
||||||
GnuPG asks bitsize and expiration, we enter 2048 for bitsize and no expiration.
|
|
||||||
Then, we confirm that we really create the key. ::
|
|
||||||
|
|
||||||
RSA keys may be between 1024 and 4096 bits long.
|
|
||||||
What keysize do you want? (2048)
|
|
||||||
Requested keysize is 2048 bits
|
|
||||||
Please specify how long the key should be valid.
|
|
||||||
0 = key does not expire
|
|
||||||
<n> = key expires in n days
|
|
||||||
<n>w = key expires in n weeks
|
|
||||||
<n>m = key expires in n months
|
|
||||||
<n>y = key expires in n years
|
|
||||||
Key is valid for? (0) 0
|
|
||||||
Key does not expire at all
|
|
||||||
Is this correct? (y/N) y
|
|
||||||
Really create? (y/N) y
|
|
||||||
|
|
||||||
Then, GnuPG generate the key. ::
|
|
||||||
|
|
||||||
We need to generate a lot of random bytes. It is a good idea to perform
|
|
||||||
some other action (type on the keyboard, move the mouse, utilize the
|
|
||||||
disks) during the prime generation; this gives the random number
|
|
||||||
generator a better chance to gain enough entropy.
|
|
||||||
.......+++++
|
|
||||||
+++++
|
|
||||||
|
|
||||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
|
||||||
trust: ultimate validity: ultimate
|
|
||||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
|
||||||
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
|
|
||||||
[ultimate] (1). Niibe Yutaka <gniibe@fsij.org>
|
|
||||||
|
|
||||||
gpg>
|
|
||||||
|
|
||||||
We save the key (to the storage of the host PC. ::
|
|
||||||
|
|
||||||
gpg> save
|
|
||||||
$
|
|
||||||
|
|
||||||
Now, we have three keys (one primary key for signature and certification,
|
|
||||||
subkey for encryption, and another subkey for authentication).
|
|
||||||
|
|
||||||
|
|
||||||
Publishing public key
|
|
||||||
=====================
|
|
||||||
|
|
||||||
We make a file for the public key by ``--export`` option of GnuPG. ::
|
|
||||||
|
|
||||||
$ gpg --armor --output <YOUR-KEY>.asc --export <YOUR-KEY-ID>
|
|
||||||
|
|
||||||
We can publish the file by web server. Or we can publish the key
|
|
||||||
to a keyserver, by invoking GnuPG with ``--send-keys`` option. ::
|
|
||||||
|
|
||||||
$ gpg --keyserver pool.sks-keyservers.net --send-keys <YOUR-KEY-ID>
|
|
||||||
|
|
||||||
Here, pool.sks-keyservers.net is a keyserver, which is widely used.
|
|
||||||
|
|
||||||
|
|
||||||
Backup the private key
|
|
||||||
======================
|
|
||||||
|
|
||||||
There are some ways to back up private key, such that backup .gnupg
|
|
||||||
directory entirely, or use of paperkey, etc.
|
|
||||||
Here, we describe backup by ASCII file.
|
|
||||||
ASCII file is good, because it has less risk on transfer.
|
|
||||||
Binary file has a risk to be modified on transfer.
|
|
||||||
|
|
||||||
Note that the key on host PC is protected by passphrase (which
|
|
||||||
is <PASSWORD-KEY-ON-PC> in the example above). Using the key
|
|
||||||
from the backup needs this passphrase. It is common that
|
|
||||||
people will forget passphrase for backup. Never forget it.
|
|
||||||
You have been warned.
|
|
||||||
|
|
||||||
To make ASCII backup for private key,
|
|
||||||
invokde GnuPG with ``--armor`` option and ``--export-secret-keys``
|
|
||||||
specifying the key identifier. ::
|
|
||||||
|
|
||||||
$ gpg --armor --output <YOUR-SECRET>.asc --export-secret-keys <YOUR-KEY-ID>
|
|
||||||
|
|
||||||
From the backup,
|
|
||||||
we can recover privet key by invoking GnuPG with ``--import`` option. ::
|
|
||||||
|
|
||||||
$ gpg --import <YOUR-SECRET>.asc
|
|
||||||
487
doc/generating-key.rst
Normal file
487
doc/generating-key.rst
Normal file
@@ -0,0 +1,487 @@
|
|||||||
|
====================
|
||||||
|
Generating key pairs
|
||||||
|
====================
|
||||||
|
|
||||||
|
In this section, we describe how to generate 2048-bit RSA keys.
|
||||||
|
|
||||||
|
You would like to use newer ECC keys instead of RSA keys. It is also described.
|
||||||
|
|
||||||
|
|
||||||
|
Key length of RSA
|
||||||
|
=================
|
||||||
|
|
||||||
|
In 2005, NIST (National Institute of Standards and Technology, USA)
|
||||||
|
issued the first revision of NIST Special Publication 800-57,
|
||||||
|
"Recommendation for Key Management".
|
||||||
|
|
||||||
|
In 800-57, NIST advises that 1024-bit RSA keys will no longer be
|
||||||
|
viable after 2010 and advises moving to 2048-bit RSA keys. NIST
|
||||||
|
advises that 2048-bit keys should be viable until 2030.
|
||||||
|
|
||||||
|
As of 2016, GnuPG's default for generating RSA key is 2048-bit.
|
||||||
|
|
||||||
|
Some people have preference on RSA 4096-bit keys, considering "longer is better".
|
||||||
|
|
||||||
|
However, "longer is better" is not always true. When it's long, it
|
||||||
|
requires more computational resource, memory, and storage. Further,
|
||||||
|
it consumes more power for nomal usages. These days, many people has
|
||||||
|
enough computational resource, that would be true, but less is better
|
||||||
|
for power consumption, isn't it?
|
||||||
|
|
||||||
|
For security, the key length is just a single factor. We had and will have
|
||||||
|
algorithm issues, too. It is true that it's difficult to update
|
||||||
|
our public keys, but this problem wouldn't be solved by just having
|
||||||
|
longer keys.
|
||||||
|
|
||||||
|
We deliberately recommend use of RSA 2048-bit keys for Gnuk,
|
||||||
|
considering device computation power and host software constraints.
|
||||||
|
|
||||||
|
Thus, the key size is 2048-bit in the examples below.
|
||||||
|
|
||||||
|
When/If your environment allows use of newer ECC keys, newer ECC keys are recommended.
|
||||||
|
|
||||||
|
|
||||||
|
Generating RSA keys on host PC
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Here is the example session to generate main key and a subkey for encryption.
|
||||||
|
|
||||||
|
I invoke GnuPG with ``--quick-gen-key`` option. ::
|
||||||
|
|
||||||
|
$ gpg --quick-gen-key "Niibe Yutaka <gniibe@fsij.org>"
|
||||||
|
About to create a key for:
|
||||||
|
"Niibe Yutaka <gniibe@fsij.org>"
|
||||||
|
|
||||||
|
Continue? (Y/n) y
|
||||||
|
|
||||||
|
It askes passphrase for this **key on host PC**.
|
||||||
|
Note that this is a passphrase for the key on host PC.
|
||||||
|
It is different thing to the passphrase of Gnuk Token.
|
||||||
|
We enter two same inputs two times
|
||||||
|
(once for passphrase input, and another for confirmation),
|
||||||
|
<PASSWORD-KEY-ON-PC>.
|
||||||
|
|
||||||
|
Then, GnuPG generate keys. It takes some time. ::
|
||||||
|
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
gpg: key 76A9392B02CD15D1 marked as ultimately trusted
|
||||||
|
gpg: revocation certificate stored as '/home/gniibe.gnupg/openpgp-revocs.d/36CE0B8408CFE5CD07F94ACF76A9392B02CD15D1.rev'
|
||||||
|
public and secret key created and signed.
|
||||||
|
|
||||||
|
gpg: checking the trustdb
|
||||||
|
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
|
||||||
|
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
|
||||||
|
pub rsa2048 2016-06-20 [S]
|
||||||
|
36CE0B8408CFE5CD07F94ACF76A9392B02CD15D1
|
||||||
|
uid [ultimate] Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
sub rsa2048 2016-06-20 []
|
||||||
|
|
||||||
|
Done.
|
||||||
|
|
||||||
|
Then, we create authentication subkey.
|
||||||
|
Authentication subkey is not that common,
|
||||||
|
but very useful (for SSH authentication).
|
||||||
|
As it is not that common, we need ``--expert`` option for GnuPG. ::
|
||||||
|
|
||||||
|
gpg (GnuPG) 2.1.13; Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
|
Secret key is available.
|
||||||
|
|
||||||
|
sec rsa2048/76A9392B02CD15D1
|
||||||
|
created: 2016-06-20 expires: never usage: SC
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb rsa2048/4BD1EB26F0E607E6
|
||||||
|
created: 2016-06-20 expires: never usage: E
|
||||||
|
[ultimate] (1). Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
gpg>
|
||||||
|
|
||||||
|
Here, it displays that there are main key and a subkey.
|
||||||
|
It prompts sub-command with ``gpg>`` .
|
||||||
|
|
||||||
|
Here, we enter ``addkey`` sub-command.
|
||||||
|
|
||||||
|
gpg> addkey
|
||||||
|
|
||||||
|
GnuPG asks kind of key. We select ``RSA (set your own capabilities)``. ::
|
||||||
|
|
||||||
|
Please select what kind of key you want:
|
||||||
|
(3) DSA (sign only)
|
||||||
|
(4) RSA (sign only)
|
||||||
|
(5) Elgamal (encrypt only)
|
||||||
|
(6) RSA (encrypt only)
|
||||||
|
(7) DSA (set your own capabilities)
|
||||||
|
(8) RSA (set your own capabilities)
|
||||||
|
(10) ECC (sign only)
|
||||||
|
(11) ECC (set your own capabilities)
|
||||||
|
(12) ECC (encrypt only)
|
||||||
|
(13) Existing key
|
||||||
|
Your selection? 8
|
||||||
|
|
||||||
|
And select ``Authenticate`` for the capabilities for this key.
|
||||||
|
Initially, it's ``Sign`` and ``Encrypt``.
|
||||||
|
I need to deselect ``Sign`` and ``Encrypt``, and select ``Authenticate``.
|
||||||
|
To do that, I enter ``s``, ``e``, and ``a``. ::
|
||||||
|
|
||||||
|
Possible actions for a RSA key: Sign Encrypt Authenticate
|
||||||
|
Current allowed actions: Sign Encrypt
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(E) Toggle the encrypt capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? s
|
||||||
|
|
||||||
|
Possible actions for a RSA key: Sign Encrypt Authenticate
|
||||||
|
Current allowed actions: Encrypt
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(E) Toggle the encrypt capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? e
|
||||||
|
|
||||||
|
Possible actions for a RSA key: Sign Encrypt Authenticate
|
||||||
|
Current allowed actions:
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(E) Toggle the encrypt capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? a
|
||||||
|
|
||||||
|
Possible actions for a RSA key: Sign Encrypt Authenticate
|
||||||
|
Current allowed actions: Authenticate
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(E) Toggle the encrypt capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
OK, we set the capability of ``Authenticate``.
|
||||||
|
We enter ``q`` to finish setting capabilities. ::
|
||||||
|
|
||||||
|
Your selection? q
|
||||||
|
|
||||||
|
GnuPG asks bitsize and expiration, we enter 2048 for bitsize and no expiration.
|
||||||
|
Then, we confirm that we really create the key. ::
|
||||||
|
|
||||||
|
RSA keys may be between 1024 and 4096 bits long.
|
||||||
|
What keysize do you want? (2048)
|
||||||
|
Requested keysize is 2048 bits
|
||||||
|
Please specify how long the key should be valid.
|
||||||
|
0 = key does not expire
|
||||||
|
<n> = key expires in n days
|
||||||
|
<n>w = key expires in n weeks
|
||||||
|
<n>m = key expires in n months
|
||||||
|
<n>y = key expires in n years
|
||||||
|
Key is valid for? (0) 0
|
||||||
|
Key does not expire at all
|
||||||
|
Is this correct? (y/N) y
|
||||||
|
Really create? (y/N) y
|
||||||
|
|
||||||
|
Then, it askes the passphrase, it is the passphrase of **key on host PC**.
|
||||||
|
It's the one we entered above as <PASSWORD-KEY-ON-PC>.
|
||||||
|
|
||||||
|
Then, GnuPG generate the key. ::
|
||||||
|
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
|
||||||
|
sec rsa2048/76A9392B02CD15D1
|
||||||
|
created: 2016-06-20 expires: never usage: SC
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb rsa2048/4BD1EB26F0E607E6
|
||||||
|
created: 2016-06-20 expires: never usage: E
|
||||||
|
ssb rsa2048/F3BA52C64012198D
|
||||||
|
created: 2016-06-20 expires: never usage: A
|
||||||
|
[ultimate] (1). Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
gpg>
|
||||||
|
|
||||||
|
We save the key (to the storage of the host PC). ::
|
||||||
|
|
||||||
|
gpg> save
|
||||||
|
$
|
||||||
|
|
||||||
|
Now, we have three keys (one primary key for signature and certification,
|
||||||
|
subkey for encryption, and another subkey for authentication).
|
||||||
|
|
||||||
|
|
||||||
|
Publishing public key
|
||||||
|
=====================
|
||||||
|
|
||||||
|
We make a file for the public key by ``--export`` option of GnuPG. ::
|
||||||
|
|
||||||
|
$ gpg --armor --output <YOUR-KEY>.asc --export <YOUR-KEY-ID>
|
||||||
|
|
||||||
|
We can publish the file by web server. Or we can publish the key
|
||||||
|
to a keyserver, by invoking GnuPG with ``--send-keys`` option. ::
|
||||||
|
|
||||||
|
$ gpg --keyserver pool.sks-keyservers.net --send-keys <YOUR-KEY-ID>
|
||||||
|
|
||||||
|
Here, pool.sks-keyservers.net is a keyserver, which is widely used.
|
||||||
|
|
||||||
|
|
||||||
|
Backup the private key
|
||||||
|
======================
|
||||||
|
|
||||||
|
There are some ways to back up private key, such that backup .gnupg
|
||||||
|
directory entirely, or use of paperkey, etc.
|
||||||
|
Here, we describe backup by ASCII file.
|
||||||
|
ASCII file is good, because it has less risk on transfer.
|
||||||
|
Binary file has a risk to be modified on transfer.
|
||||||
|
|
||||||
|
Note that the key on host PC is protected by passphrase (which
|
||||||
|
is <PASSWORD-KEY-ON-PC> in the example above). Using the key
|
||||||
|
from the backup needs this passphrase. It is common that
|
||||||
|
people will forget passphrase for backup. Never forget it.
|
||||||
|
You have been warned.
|
||||||
|
|
||||||
|
To make ASCII backup for private key,
|
||||||
|
invokde GnuPG with ``--armor`` option and ``--export-secret-keys``
|
||||||
|
specifying the key identifier. ::
|
||||||
|
|
||||||
|
$ gpg --armor --output <YOUR-SECRET>.asc --export-secret-keys <YOUR-KEY-ID>
|
||||||
|
|
||||||
|
From the backup,
|
||||||
|
we can recover privet key by invoking GnuPG with ``--import`` option. ::
|
||||||
|
|
||||||
|
$ gpg --import <YOUR-SECRET>.asc
|
||||||
|
|
||||||
|
|
||||||
|
Generating ECC keys on host PC
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Here is an example session log to create newer ECC keys. You need
|
||||||
|
libgcrypt 1.7 or newer and GnuPG 2.1.8 or newer.
|
||||||
|
|
||||||
|
Next, we invoke gpg frontend with ``--expert`` and ``--full-gen-key`` option. ::
|
||||||
|
|
||||||
|
$ gpg --expert --full-gen-key
|
||||||
|
gpg (GnuPG) 2.1.13; Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
|
Then, we input ``9`` to select ECC primary key and ECC encryption subkey. ::
|
||||||
|
|
||||||
|
Please select what kind of key you want:
|
||||||
|
(1) RSA and RSA (default)
|
||||||
|
(2) DSA and Elgamal
|
||||||
|
(3) DSA (sign only)
|
||||||
|
(4) RSA (sign only)
|
||||||
|
(7) DSA (set your own capabilities)
|
||||||
|
(8) RSA (set your own capabilities)
|
||||||
|
(9) ECC and ECC
|
||||||
|
(10) ECC (sign only)
|
||||||
|
(11) ECC (set your own capabilities)
|
||||||
|
Your selection? 9
|
||||||
|
|
||||||
|
Next is the important selection. We input ``1`` to select "Curve25519". ::
|
||||||
|
|
||||||
|
Please select which elliptic curve you want:
|
||||||
|
(1) Curve 25519
|
||||||
|
(2) NIST P-256
|
||||||
|
(3) NIST P-384
|
||||||
|
(4) NIST P-521
|
||||||
|
(5) Brainpool P-256
|
||||||
|
(6) Brainpool P-384
|
||||||
|
(7) Brainpool P-512
|
||||||
|
(8) secp256k1
|
||||||
|
Your selection? 1
|
||||||
|
|
||||||
|
You may see WARNING (it depends on version of GnuPG) and may been asked. Since it is what you want, please answer with 'y'. ::
|
||||||
|
|
||||||
|
gpg: WARNING: Curve25519 is not yet part of the OpenPGP standard.
|
||||||
|
Use this curve anyway? (y/N) y
|
||||||
|
|
||||||
|
It asks about expiration of key. ::
|
||||||
|
|
||||||
|
Please specify how long the key should be valid.
|
||||||
|
0 = key does not expire
|
||||||
|
<n> = key expires in n days
|
||||||
|
<n>w = key expires in n weeks
|
||||||
|
<n>m = key expires in n months
|
||||||
|
<n>y = key expires in n years
|
||||||
|
Key is valid for? (0)
|
||||||
|
Key does not expire at all
|
||||||
|
Is this correct? (y/N) y
|
||||||
|
|
||||||
|
Then, it asks about a user ID. ::
|
||||||
|
|
||||||
|
GnuPG needs to construct a user ID to identify your key.
|
||||||
|
|
||||||
|
Real name: Kunisada Chuji
|
||||||
|
Email address: chuji@gniibe.org
|
||||||
|
Comment:
|
||||||
|
You selected this USER-ID:
|
||||||
|
"Kunisada Chuji <chuji@gniibe.org>"
|
||||||
|
|
||||||
|
Lastly, it asks confirmation. ::
|
||||||
|
|
||||||
|
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
|
||||||
|
|
||||||
|
Then, it goes like this. ::
|
||||||
|
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
|
||||||
|
It asks the passphrase for keys by pop-up window, and then, finishes. ::
|
||||||
|
|
||||||
|
gpg: key 17174C1A7C406DB5 marked as ultimately trusted
|
||||||
|
gpg: revocation certificate stored as '/home/gniibe.gnupg/openpgp-revocs.d/1719874a4fe5a1d8c465277d5a1bb27e3000f4ff.rev'
|
||||||
|
public and secret key created and signed.
|
||||||
|
|
||||||
|
gpg: checking the trustdb
|
||||||
|
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
|
||||||
|
gpg: depth: 0 valid: 6 signed: 67 trust: 0-, 0q, 0n, 0m, 0f, 6u
|
||||||
|
gpg: depth: 1 valid: 67 signed: 40 trust: 67-, 0q, 0n, 0m, 0f, 0u
|
||||||
|
gpg: next trustdb check due at 2016-10-05
|
||||||
|
pub ed25519 2016-07-08
|
||||||
|
F478770235B60A230BE78005006A236C292C31D7
|
||||||
|
uid [ultimate] Kunisada Chuji <chuji@gniibe.org>
|
||||||
|
sub cv25519 2016-07-08
|
||||||
|
|
||||||
|
$
|
||||||
|
|
||||||
|
We have the primary key with ed25519, and encryption subkey with cv25519.
|
||||||
|
|
||||||
|
|
||||||
|
Next, we add authentication subkey which can be used with OpenSSH.
|
||||||
|
We invoke gpg frontend with ``--edit-key`` and the key ID. ::
|
||||||
|
|
||||||
|
$ gpg2 --expert --edit-key 17174C1A7C406DB5
|
||||||
|
gpg (GnuPG) 2.1.13; Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
|
Secret key is available.
|
||||||
|
|
||||||
|
sec ed25519/17174C1A7C406DB5
|
||||||
|
created: 2016-07-08 expires: never usage: SC
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb cv25519/37A03183DF7B31B1
|
||||||
|
created: 2016-07-08 expires: never usage: E
|
||||||
|
[ultimate] (1). Kunisada Chuji <chuji@gniibe.org>
|
||||||
|
|
||||||
|
We invoke ``addkey`` subcommand. ::
|
||||||
|
|
||||||
|
gpg> addkey
|
||||||
|
|
||||||
|
It asks a kind of key, we input ``11`` to select ECC for authentication. ::
|
||||||
|
|
||||||
|
Please select what kind of key you want:
|
||||||
|
(3) DSA (sign only)
|
||||||
|
(4) RSA (sign only)
|
||||||
|
(5) Elgamal (encrypt only)
|
||||||
|
(6) RSA (encrypt only)
|
||||||
|
(7) DSA (set your own capabilities)
|
||||||
|
(8) RSA (set your own capabilities)
|
||||||
|
(10) ECC (sign only)
|
||||||
|
(11) ECC (set your own capabilities)
|
||||||
|
(12) ECC (encrypt only)
|
||||||
|
(13) Existing key
|
||||||
|
Your selection? 11
|
||||||
|
|
||||||
|
and then, we specify "Authenticate" capability. ::
|
||||||
|
|
||||||
|
Possible actions for a ECDSA/EdDSA key: Sign Authenticate
|
||||||
|
Current allowed actions: Sign
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? a
|
||||||
|
|
||||||
|
Possible actions for a ECDSA/EdDSA key: Sign Authenticate
|
||||||
|
Current allowed actions: Sign Authenticate
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? s
|
||||||
|
|
||||||
|
Possible actions for a ECDSA/EdDSA key: Sign Authenticate
|
||||||
|
Current allowed actions: Authenticate
|
||||||
|
|
||||||
|
(S) Toggle the sign capability
|
||||||
|
(A) Toggle the authenticate capability
|
||||||
|
(Q) Finished
|
||||||
|
|
||||||
|
Your selection? q
|
||||||
|
|
||||||
|
Then, it asks which curve. We input ``1`` for "Curve25519". ::
|
||||||
|
|
||||||
|
Please select which elliptic curve you want:
|
||||||
|
(1) Curve 25519
|
||||||
|
(2) NIST P-256
|
||||||
|
(3) NIST P-384
|
||||||
|
(4) NIST P-521
|
||||||
|
(5) Brainpool P-256
|
||||||
|
(6) Brainpool P-384
|
||||||
|
(7) Brainpool P-512
|
||||||
|
(8) secp256k1
|
||||||
|
Your selection? 1
|
||||||
|
|
||||||
|
It may ask confirmation with WARNING (depends on version). We say ``y``. ::
|
||||||
|
|
||||||
|
gpg: WARNING: Curve25519 is not yet part of the OpenPGP standard.
|
||||||
|
Use this curve anyway? (y/N) y
|
||||||
|
|
||||||
|
It asks expiration of the key. ::
|
||||||
|
|
||||||
|
Please specify how long the key should be valid.
|
||||||
|
0 = key does not expire
|
||||||
|
<n> = key expires in n days
|
||||||
|
<n>w = key expires in n weeks
|
||||||
|
<n>m = key expires in n months
|
||||||
|
<n>y = key expires in n years
|
||||||
|
Key is valid for? (0)
|
||||||
|
Key does not expire at all
|
||||||
|
Is this correct? (y/N) y
|
||||||
|
|
||||||
|
And the confirmation. ::
|
||||||
|
|
||||||
|
Really create? (y/N) y
|
||||||
|
|
||||||
|
It goes. ::
|
||||||
|
|
||||||
|
We need to generate a lot of random bytes. It is a good idea to perform
|
||||||
|
some other action (type on the keyboard, move the mouse, utilize the
|
||||||
|
disks) during the prime generation; this gives the random number
|
||||||
|
generator a better chance to gain enough entropy.
|
||||||
|
|
||||||
|
It asks the passphrase. And done. ::
|
||||||
|
|
||||||
|
sec ed25519/17174C1A7C406DB5
|
||||||
|
created: 2016-09-08 expires: never usage: SC
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb cv25519/37A03183DF7B31B1
|
||||||
|
created: 2016-09-08 expires: never usage: E
|
||||||
|
ssb ed25519/4AD7D2428679DF5F
|
||||||
|
created: 2016-09-08 expires: never usage: A
|
||||||
|
[ultimate] (1). Kunisada Chuji <chuji@gniibe.org>
|
||||||
|
|
||||||
|
We type ``save`` to exit form gpg. ::
|
||||||
|
|
||||||
|
gpg> save
|
||||||
|
$
|
||||||
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
===========================================
|
|
||||||
GnuPG settings for GNOME 3.1x and GNOME 3.0
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
In the section `GnuPG settings`_, I wrote how I disable GNOME-keyrings for SSH.
|
|
||||||
|
|
||||||
It was for GNOME 2. The old days was good, we just disabled GNOME-keyrings
|
|
||||||
interference to SSH and customizing our desktop was easy for GNU and UNIX users.
|
|
||||||
|
|
||||||
.. _GnuPG settings: gpg-settings
|
|
||||||
|
|
||||||
|
|
||||||
GNOME keyrings in GNOME 3.1x
|
|
||||||
============================
|
|
||||||
|
|
||||||
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=
|
|
||||||
|
|
||||||
Then, no desktop environment invokes gnome-keyring for ssh and gpg. I think that it is The Right Thing.
|
|
||||||
|
|
||||||
|
|
||||||
GNOME keyrings in GNOME 3.0 by GNOME-SESSION-PROPERTIES
|
|
||||||
=======================================================
|
|
||||||
|
|
||||||
We can't use GNOME configuration tool (like GNOME 2) to disable interference by
|
|
||||||
GNOME keyrings in GNOME 3.0.
|
|
||||||
|
|
||||||
It is GNOME-SESSION-PROPERTIES to disable the interference. Invoking::
|
|
||||||
|
|
||||||
$ gnome-session-properties
|
|
||||||
|
|
||||||
and at the tab of "Startup Programs", I removed radio check buttons
|
|
||||||
for "GPG Password Agent" and "SSH Key Agent".
|
|
||||||
|
|
||||||
Then, I can use proper gpg-agent for GnuPG Agent Service and SSH Agent Service with Gnuk Token in GNOME 3.0.
|
|
||||||
@@ -10,7 +10,7 @@ I don't save changes on PC after keytocard.
|
|||||||
|
|
||||||
For the steps before the last step, please see `keytocard with removing keys on PC`_.
|
For the steps before the last step, please see `keytocard with removing keys on PC`_.
|
||||||
|
|
||||||
.. _keytocard removing keys: gnuk-keytocard
|
.. _keytocard with removing keys on PC: gnuk-keytocard
|
||||||
|
|
||||||
Here is the session log of the last step.
|
Here is the session log of the last step.
|
||||||
|
|
||||||
@@ -22,4 +22,4 @@ Lastly, I quit GnuPG. Note that I **don't** save changes. ::
|
|||||||
$
|
$
|
||||||
|
|
||||||
All keys are imported to Gnuk Token now.
|
All keys are imported to Gnuk Token now.
|
||||||
Still, secret keys are available on PC.
|
Still, secret keys are available on PC, too.
|
||||||
|
|||||||
@@ -24,31 +24,29 @@ After personalization, I put my keys into the Token.
|
|||||||
|
|
||||||
Here is the session log.
|
Here is the session log.
|
||||||
|
|
||||||
I invoke GnuPG with my key (4ca7babe). ::
|
I invoke GnuPG with my key (249CB3771750745D5CDD323CE267B052364F028D). ::
|
||||||
|
|
||||||
$ gpg --edit-key 4ca7babe
|
$ gpg --edit-key 249CB3771750745D5CDD323CE267B052364F028D
|
||||||
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
gpg (GnuPG) 2.1.13; Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
Secret key is available.
|
Secret key is available.
|
||||||
|
|
||||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
sec ed25519/E267B052364F028D
|
||||||
trust: ultimate validity: ultimate
|
created: 2015-08-12 expires: never usage: SC
|
||||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
trust: ultimate validity: ultimate
|
||||||
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
|
ssb cv25519/850AF040D619F240
|
||||||
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
created: 2015-08-12 expires: never usage: E
|
||||||
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
[ultimate] (1). NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
[ultimate] (2) NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
gpg>
|
||||||
|
|
||||||
|
|
||||||
Then, GnuPG enters its own command interaction mode. The prompt is ``gpg>``.
|
Then, GnuPG enters its own command interaction mode. The prompt is ``gpg>``.
|
||||||
To enable ``keytocard`` command, I type ``toggle`` command. ::
|
|
||||||
|
|
||||||
gpg> toggle
|
|
||||||
|
|
||||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
|
||||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
|
||||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
|
||||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
|
||||||
|
|
||||||
Firstly, I import my primary key into Gnuk Token.
|
Firstly, I import my primary key into Gnuk Token.
|
||||||
I type ``keytocard`` command, answer ``y`` to confirm keyimport,
|
I type ``keytocard`` command, answer ``y`` to confirm keyimport,
|
||||||
@@ -56,135 +54,129 @@ and type ``1`` to say it's signature key. ::
|
|||||||
|
|
||||||
gpg> keytocard
|
gpg> keytocard
|
||||||
Really move the primary key? (y/N) y
|
Really move the primary key? (y/N) y
|
||||||
Signature key ....: [none]
|
|
||||||
Encryption key....: [none]
|
|
||||||
Authentication key: [none]
|
|
||||||
|
|
||||||
Please select where to store the key:
|
Please select where to store the key:
|
||||||
(1) Signature key
|
(1) Signature key
|
||||||
(3) Authentication key
|
(3) Authentication key
|
||||||
Your selection? 1
|
Your selection? 1
|
||||||
|
|
||||||
Then, GnuPG asks two passwords. One is the passphrase of **keys on PC**
|
Then, GnuPG asks two kinds of passphrases. One is the passphrase of **keys on PC**
|
||||||
and another is the password of **Gnuk Token**. Note that the password of
|
and another is the passphrase of **Gnuk Token**. Note that the passphrase of
|
||||||
the token and the password of the keys on PC are different things,
|
the token and the passphrase of the keys on PC are different things,
|
||||||
although they can be same.
|
although they can be same.
|
||||||
|
|
||||||
Here, I assume that Gnuk Token's admin password of factory setting (12345678).
|
Here, I assume that Gnuk Token's admin passphrase of factory setting (12345678).
|
||||||
|
|
||||||
I enter these passwords. ::
|
I enter these passphrases. ::
|
||||||
|
|
||||||
You need a passphrase to unlock the secret key for
|
Please enter your passphrase, so that the secret key can be unlocked for this session
|
||||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
<PASSWORD-KEY-ON-PC>
|
||||||
2048-bit RSA key, ID 4CA7BABE, created 2010-10-15
|
|
||||||
<PASSWORD-KEY-4CA7BABE>
|
|
||||||
gpg: writing new key
|
|
||||||
gpg: 3 Admin PIN attempts remaining before card is permanently locked
|
|
||||||
|
|
||||||
Please enter the Admin PIN
|
Please enter the Admin PIN
|
||||||
Enter Admin PIN: 12345678
|
Enter Admin PIN: 12345678
|
||||||
|
|
||||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
sec ed25519/E267B052364F028D
|
||||||
card-no: F517 00000001
|
created: 2015-08-12 expires: never usage: SC
|
||||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
trust: ultimate validity: ultimate
|
||||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
ssb cv25519/850AF040D619F240
|
||||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
created: 2015-08-12 expires: never usage: E
|
||||||
|
ssb ed25519/5F910521FAA805B1
|
||||||
The primary key is now on the Token and GnuPG says its card-no (F517 00000001),
|
created: 2015-08-12 expires: never usage: A
|
||||||
where F517 is the vendor ID of FSIJ.
|
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
Secondly, I import my subkey of encryption. I select key number '1'. ::
|
Secondly, I import my subkey of encryption. I select key number '1'. ::
|
||||||
|
|
||||||
gpg> key 1
|
gpg> key 1
|
||||||
|
|
||||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
sec ed25519/E267B052364F028D
|
||||||
card-no: F517 00000001
|
created: 2015-08-12 expires: never usage: SC
|
||||||
ssb* 2048R/084239CF created: 2010-10-15 expires: never
|
trust: ultimate validity: ultimate
|
||||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
ssb* cv25519/850AF040D619F240
|
||||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
created: 2015-08-12 expires: never usage: E
|
||||||
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
You can see that the subkey is marked by '*'.
|
You can see that the subkey is marked by '*'.
|
||||||
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
||||||
I select ``2`` as it's encryption key. ::
|
I select ``2`` as it's encryption key. ::
|
||||||
|
|
||||||
gpg> keytocard
|
gpg> keytocard
|
||||||
Signature key ....: [none]
|
|
||||||
Encryption key....: [none]
|
|
||||||
Authentication key: [none]
|
|
||||||
|
|
||||||
Please select where to store the key:
|
Please select where to store the key:
|
||||||
(2) Encryption key
|
(2) Encryption key
|
||||||
Your selection? 2
|
Your selection? 2
|
||||||
|
|
||||||
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
||||||
|
|
||||||
You need a passphrase to unlock the secret key for
|
Please enter your passphrase, so that the secret key can be unlocked for this session
|
||||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
<PASSWORD-KEY-ON-PC>
|
||||||
2048-bit RSA key, ID 084239CF, created 2010-10-15
|
|
||||||
<PASSWORD-KEY-4CA7BABE>
|
|
||||||
gpg: writing new key
|
|
||||||
|
|
||||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
sec ed25519/E267B052364F028D
|
||||||
card-no: F517 00000001
|
created: 2015-08-12 expires: never usage: SC
|
||||||
ssb* 2048R/084239CF created: 2010-10-15 expires: never
|
trust: ultimate validity: ultimate
|
||||||
card-no: F517 00000001
|
ssb* cv25519/850AF040D619F240
|
||||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
created: 2015-08-12 expires: never usage: E
|
||||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
|
The sub key is now on the Token.
|
||||||
|
|
||||||
The sub key is now on the Token and GnuPG says its card-no for it.
|
|
||||||
|
|
||||||
I type ``key 1`` to deselect key number '1'. ::
|
I type ``key 1`` to deselect key number '1'. ::
|
||||||
|
|
||||||
gpg> key 1
|
gpg> key 1
|
||||||
|
|
||||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
sec ed25519/E267B052364F028D
|
||||||
card-no: F517 00000001
|
created: 2015-08-12 expires: never usage: SC
|
||||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
trust: ultimate validity: ultimate
|
||||||
card-no: F517 00000001
|
ssb cv25519/850AF040D619F240
|
||||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
created: 2015-08-12 expires: never usage: E
|
||||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
Thirdly, I select sub key of authentication which has key number '2'. ::
|
Thirdly, I select sub key of authentication which has key number '2'. ::
|
||||||
|
|
||||||
gpg> key 2
|
gpg> key 2
|
||||||
|
|
||||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
sec ed25519/E267B052364F028D
|
||||||
card-no: F517 00000001
|
created: 2015-08-12 expires: never usage: SC
|
||||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
trust: ultimate validity: ultimate
|
||||||
card-no: F517 00000001
|
ssb cv25519/850AF040D619F240
|
||||||
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
|
created: 2015-08-12 expires: never usage: E
|
||||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
ssb* ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
You can see that the subkey number '2' is marked by '*'.
|
You can see that the subkey number '2' is marked by '*'.
|
||||||
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
||||||
I select ``3`` as it's authentication key. ::
|
I select ``3`` as it's authentication key. ::
|
||||||
|
|
||||||
gpg> keytocard
|
gpg> keytocard
|
||||||
Signature key ....: [none]
|
|
||||||
Encryption key....: [none]
|
|
||||||
Authentication key: [none]
|
|
||||||
|
|
||||||
Please select where to store the key:
|
Please select where to store the key:
|
||||||
(3) Authentication key
|
(3) Authentication key
|
||||||
Your selection? 3
|
Your selection? 3
|
||||||
|
|
||||||
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
||||||
|
|
||||||
You need a passphrase to unlock the secret key for
|
Please enter your passphrase, so that the secret key can be unlocked for this session
|
||||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
<PASSWORD-KEY-ON-PC>
|
||||||
2048-bit RSA key, ID 5BB065DC, created 2010-10-22
|
|
||||||
<PASSWORD-KEY-4CA7BABE>
|
|
||||||
gpg: writing new key
|
|
||||||
|
|
||||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
sec ed25519/E267B052364F028D
|
||||||
card-no: F517 00000001
|
created: 2015-08-12 expires: never usage: SC
|
||||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
trust: ultimate validity: ultimate
|
||||||
card-no: F517 00000001
|
ssb cv25519/850AF040D619F240
|
||||||
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
|
created: 2015-08-12 expires: never usage: E
|
||||||
card-no: F517 00000001
|
ssb* ed25519/5F910521FAA805B1
|
||||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
The sub key is now on the Token and GnuPG says its card-no for it.
|
The sub key is now on the Token.
|
||||||
|
|
||||||
Lastly, I save changes of **keys on PC** and quit GnuPG. ::
|
Lastly, I save changes of **keys on PC** and quit GnuPG. ::
|
||||||
|
|
||||||
|
|||||||
@@ -22,41 +22,40 @@ Besides, some people sometimes prefer the word "passphrase" to
|
|||||||
same thing and it just refer user-password or admin-password.
|
same thing and it just refer user-password or admin-password.
|
||||||
|
|
||||||
|
|
||||||
Set up PW1, PW3 and reset code
|
Set up PW1 and PW3
|
||||||
==============================
|
==================
|
||||||
|
|
||||||
Invoke GnuPG with the option ``--card-edit``. ::
|
Invoke GnuPG with the option ``--card-edit``. ::
|
||||||
|
|
||||||
$ gpg --card-edit
|
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||||
Application ID ...: D276000124010200F517000000010000
|
Application ID ...: D276000124010200FFFE871930590000
|
||||||
Version ..........: 2.0
|
Version ..........: 2.0
|
||||||
Manufacturer .....: FSIJ
|
Manufacturer .....: unmanaged S/N range
|
||||||
Serial number ....: 00000001
|
Serial number ....: 87193059
|
||||||
Name of cardholder: Yutaka Niibe
|
Name of cardholder: Yutaka Niibe
|
||||||
Language prefs ...: ja
|
Language prefs ...: ja
|
||||||
Sex ..............: male
|
Sex ..............: male
|
||||||
URL of public key : http://www.gniibe.org/gniibe.asc
|
URL of public key : http://www.gniibe.org/gniibe-20150813.asc
|
||||||
Login data .......: gniibe
|
Login data .......: gniibe
|
||||||
Signature PIN ....: not forced
|
Signature PIN ....: not forced
|
||||||
Key attributes ...: 2048R 2048R 2048R
|
Key attributes ...: ed25519 cv25519 ed25519
|
||||||
Max. PIN lengths .: 127 127 127
|
Max. PIN lengths .: 127 127 127
|
||||||
PIN retry counter : 3 3 3
|
PIN retry counter : 3 3 3
|
||||||
Signature counter : 0
|
Signature counter : 0
|
||||||
Signature key ....: 1241 24BD 3B48 62AF 7A0A 42F1 00B4 5EBD 4CA7 BABE
|
Signature key ....: 249C B377 1750 745D 5CDD 323C E267 B052 364F 028D
|
||||||
created ....: 2010-10-15 06:46:33
|
created ....: 2015-08-12 07:10:48
|
||||||
Encryption key....: 42E1 E805 4E6F 1F30 26F2 DC79 79A7 9093 0842 39CF
|
Encryption key....: E228 AB42 0F73 3B1D 712D E50C 850A F040 D619 F240
|
||||||
created ....: 2010-10-15 06:46:33
|
created ....: 2015-08-12 07:10:48
|
||||||
Authentication key: B4D9 7142 C42D 6802 F5F7 4E70 9C33 B6BA 5BB0 65DC
|
Authentication key: E63F 31E6 F203 20B5 D796 D266 5F91 0521 FAA8 05B1
|
||||||
created ....: 2010-10-22 06:06:36
|
created ....: 2015-08-12 07:16:14
|
||||||
General key info..:
|
General key info..: pub ed25519/E267B052364F028D 2015-08-12 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
pub 2048R/4CA7BABE 2010-10-15 NIIBE Yutaka <gniibe@fsij.org>
|
sec> ed25519/E267B052364F028D created: 2015-08-12 expires: never
|
||||||
sec> 2048R/4CA7BABE created: 2010-10-15 expires: never
|
card-no: FFFE 87193059
|
||||||
card-no: F517 00000001
|
ssb> cv25519/850AF040D619F240 created: 2015-08-12 expires: never
|
||||||
ssb> 2048R/084239CF created: 2010-10-15 expires: never
|
card-no: FFFE 87193059
|
||||||
card-no: F517 00000001
|
ssb> ed25519/5F910521FAA805B1 created: 2015-08-12 expires: never
|
||||||
ssb> 2048R/5BB065DC created: 2010-10-22 expires: never
|
card-no: FFFE 87193059
|
||||||
card-no: F517 00000001
|
|
||||||
|
|
||||||
gpg/card>
|
gpg/card>
|
||||||
|
|
||||||
It shows the status of the card (as same as the output of ``gpg --card-status``).
|
It shows the status of the card (as same as the output of ``gpg --card-status``).
|
||||||
@@ -71,7 +70,7 @@ Note that *the length of PIN should be more than (or equals to) 8* for
|
|||||||
"admin less mode". ::
|
"admin less mode". ::
|
||||||
|
|
||||||
gpg/card> passwd
|
gpg/card> passwd
|
||||||
gpg: OpenPGP card no. D276000124010200F517000000010000 detected
|
gpg: OpenPGP card no. D276000124010200FFFE871930590000 detected
|
||||||
|
|
||||||
Please enter the PIN
|
Please enter the PIN
|
||||||
Enter PIN: 123456
|
Enter PIN: 123456
|
||||||
@@ -94,15 +93,24 @@ please change admin-password at first.
|
|||||||
Then, the token works as same as OpenPGPcard specification
|
Then, the token works as same as OpenPGPcard specification
|
||||||
with regards to PW1 and PW3.)
|
with regards to PW1 and PW3.)
|
||||||
|
|
||||||
Lastly, I setup reset code, entering admin mode.
|
|
||||||
Having reset code, you can unblock PIN when the token will be blocked
|
Set up of reset code (optional)
|
||||||
(by wrong attempt to entering PIN). This is optional step. ::
|
===============================
|
||||||
|
|
||||||
|
Lastly, we can setup reset code, entering admin mode.
|
||||||
|
|
||||||
|
Having reset code, we can unblock the token when the token will be blocked
|
||||||
|
(by wrong attempts to entering passphrase). Note that this is optional step.
|
||||||
|
|
||||||
|
When reset code is known to someone, that person can try to guess your passphrase of PW1 more times by unblocking the token. So, I don't use this feature by myself.
|
||||||
|
|
||||||
|
If we do, here is the interaction. ::
|
||||||
|
|
||||||
gpg/card> admin
|
gpg/card> admin
|
||||||
Admin commands are allowed
|
Admin commands are allowed
|
||||||
|
|
||||||
gpg/card> passwd
|
gpg/card> passwd
|
||||||
gpg: OpenPGP card no. D276000124010200F517000000010000 detected
|
gpg: OpenPGP card no. D276000124010200FFFE871930590000 detected
|
||||||
|
|
||||||
1 - change PIN
|
1 - change PIN
|
||||||
2 - unblock PIN
|
2 - unblock PIN
|
||||||
@@ -135,4 +143,4 @@ Then, I quit. ::
|
|||||||
|
|
||||||
gpg/card> quit
|
gpg/card> quit
|
||||||
|
|
||||||
That's all.
|
That's all in this step.
|
||||||
|
|||||||
@@ -9,17 +9,19 @@ Personalize your Gnuk Token
|
|||||||
Invoke GnuPG with the option ``--card-edit``. ::
|
Invoke GnuPG with the option ``--card-edit``. ::
|
||||||
|
|
||||||
$ gpg --card-edit
|
$ gpg --card-edit
|
||||||
Application ID ...: D276000124010200FFFE330069060000
|
|
||||||
|
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||||
|
Application ID ...: D276000124010200FFFE871930590000
|
||||||
Version ..........: 2.0
|
Version ..........: 2.0
|
||||||
Manufacturer .....: unmanaged S/N range
|
Manufacturer .....: unmanaged S/N range
|
||||||
Serial number ....: 33006906
|
Serial number ....: 87193059
|
||||||
Name of cardholder: [not set]
|
Name of cardholder: [not set]
|
||||||
Language prefs ...: [not set]
|
Language prefs ...: [not set]
|
||||||
Sex ..............: unspecified
|
Sex ..............: unspecified
|
||||||
URL of public key : [not set]
|
URL of public key : [not set]
|
||||||
Login data .......: [not set]
|
Login data .......: [not set]
|
||||||
Signature PIN ....: forced
|
Signature PIN ....: forced
|
||||||
Key attributes ...: 2048R 2048R 2048R
|
Key attributes ...: rsa2048 rsa2048 rsa2048
|
||||||
Max. PIN lengths .: 127 127 127
|
Max. PIN lengths .: 127 127 127
|
||||||
PIN retry counter : 3 3 3
|
PIN retry counter : 3 3 3
|
||||||
Signature counter : 0
|
Signature counter : 0
|
||||||
@@ -58,7 +60,7 @@ login, and URL. URL specifies the place where I put my public keys. ::
|
|||||||
Sex ((M)ale, (F)emale or space): m
|
Sex ((M)ale, (F)emale or space): m
|
||||||
|
|
||||||
gpg/card> url
|
gpg/card> url
|
||||||
URL to retrieve public key: http://www.gniibe.org/gniibe.asc
|
URL to retrieve public key: http://www.gniibe.org/gniibe-20150813.asc
|
||||||
|
|
||||||
gpg/card> login
|
gpg/card> login
|
||||||
Login data (account name): gniibe
|
Login data (account name): gniibe
|
||||||
@@ -72,4 +74,4 @@ Then, I quit. ::
|
|||||||
|
|
||||||
gpg/card> quit
|
gpg/card> quit
|
||||||
|
|
||||||
That's all.
|
That's all in this step.
|
||||||
|
|||||||
@@ -27,13 +27,15 @@ Make sure there is no ``scdaemon`` for configuring Gnuk Token. You can kill ``
|
|||||||
Serial Number (optional)
|
Serial Number (optional)
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
Note that this is completely optional step. I don't know anyone other than me, do this. Even for me, I only do that for a single device among multiple devices I use. I do that to test the feature.
|
||||||
|
|
||||||
In the file ``GNUK_SERIAL_NUMBER``, each line has email and 6-byte serial number. The first two bytes are organization number (F5:17 is for FSIJ). Last four bytes are number for tokens.
|
In the file ``GNUK_SERIAL_NUMBER``, each line has email and 6-byte serial number. The first two bytes are organization number (F5:17 is for FSIJ). Last four bytes are number for tokens.
|
||||||
|
|
||||||
The tool ``../tool/gnuk_put_binary_libusb.py`` examines environment variable of ``EMAIL``, and writes corresponding serial number to Gnuk Token. ::
|
The tool ``../tool/gnuk_put_binary_libusb.py`` examines environment variable of ``EMAIL``, and writes corresponding serial number to Gnuk Token. ::
|
||||||
|
|
||||||
$ ../tool/gnuk_put_binary_libusb.py -s ../GNUK_SERIAL_NUMBER
|
$ ../tool/gnuk_put_binary_libusb.py -s ../GNUK_SERIAL_NUMBER
|
||||||
Writing serial number
|
Writing serial number
|
||||||
Device: 006
|
Device:
|
||||||
Configuration: 1
|
Configuration: 1
|
||||||
Interface: 0
|
Interface: 0
|
||||||
d2 76 00 01 24 01 02 00 f5 17 00 00 00 01 00 00
|
d2 76 00 01 24 01 02 00 f5 17 00 00 00 01 00 00
|
||||||
|
|||||||
@@ -12,35 +12,38 @@ Here is my GnuPG settings.
|
|||||||
I create ``.gnupg/gpg.conf`` file with the following content. ::
|
I create ``.gnupg/gpg.conf`` file with the following content. ::
|
||||||
|
|
||||||
use-agent
|
use-agent
|
||||||
personal-digest-preferences SHA256
|
default-key 0xE267B052364F028D
|
||||||
cert-digest-algo SHA256
|
|
||||||
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
|
|
||||||
|
|
||||||
default-key 0x4ca7babe
|
In addition to the ``use-agent`` option, I specify my default key.
|
||||||
|
|
||||||
In addition to the ``use-agent`` option, set preferences on algorithms, and specify my default key.
|
|
||||||
|
|
||||||
The ``use-agent`` option is for GnuPG 1.4.x and it means using gpg-agent if available.
|
The ``use-agent`` option is for GnuPG 1.4.x and it means using gpg-agent if available.
|
||||||
If no option, GnuPG 1.4.x directly connects to Gnuk Token by itself, instead of through scdaemon. When GnuPG 1.4.x tries to access Gnuk Token and scdaemon is running, there are conflicts.
|
If no option, GnuPG 1.4.x directly connects to Gnuk Token by itself, instead of through scdaemon. When GnuPG 1.4.x tries to access Gnuk Token and scdaemon is running, there are conflicts.
|
||||||
|
|
||||||
We recommend to specify the ``use-agent`` option for GnuPG 1.4.x to access Gnuk Token through gpg-agent and scdaemon.
|
We recommend to specify the ``use-agent`` option for GnuPG 1.4.x to access Gnuk Token through gpg-agent and scdaemon.
|
||||||
|
|
||||||
For GnuPG 2.0.x, gpg-agent is always used, so there is no need to specify the ``use-agent`` option, but having this option is no harm, anyway.
|
For GnuPG 2.0 and 2.1, gpg-agent is always used, so, there is no need to specify the ``use-agent`` option, but having this option is no harm, anyway.
|
||||||
|
|
||||||
|
|
||||||
Let gpg-agent manage SSH key
|
Let gpg-agent manage SSH key
|
||||||
============================
|
============================
|
||||||
|
|
||||||
I deactivate seahorse-agent. Also, for GNOME 2, I deactivate gnome-keyring managing SSH key. ::
|
I create ``.gnupg/gpg-agent.conf`` file with the following content. ::
|
||||||
|
|
||||||
$ gconftool-2 --type bool --set /apps/gnome-keyring/daemon-components/ssh false
|
|
||||||
|
|
||||||
I edit the file /etc/X11/Xsession.options and comment out use-ssh-agent line.
|
|
||||||
|
|
||||||
Then, I create ``.gnupg/gpg-agent.conf`` file with the following content. ::
|
|
||||||
|
|
||||||
enable-ssh-support
|
enable-ssh-support
|
||||||
|
|
||||||
|
I edit the file /etc/X11/Xsession.options and comment out use-ssh-agent line,
|
||||||
|
so that Xsession doesn't invoke original ssh-agent. We use gpg-agent as ssh-agent.
|
||||||
|
|
||||||
|
In the files /etc/xdg/autostart/gnome-keyring-ssh.desktop,
|
||||||
|
I have a line something like: ::
|
||||||
|
|
||||||
|
OnlyShowIn=GNOME;Unity;MATE;
|
||||||
|
|
||||||
|
I edit this line to: ::
|
||||||
|
|
||||||
|
OnlyShowIn=
|
||||||
|
|
||||||
|
So that no desktop environment enables gnome-keyring for ssh.
|
||||||
|
|
||||||
References
|
References
|
||||||
==========
|
==========
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
sphinx-quickstart on Wed Jul 4 15:29:05 2012.
|
sphinx-quickstart on Wed Jul 4 15:29:05 2012.
|
||||||
You can adapt this file completely to your liking, but it should at least
|
You can adapt this file completely to your liking, but it should at least
|
||||||
contain the root `toctree` directive.
|
contain the root `toctree` directive.
|
||||||
Copyright (C) 2012, 2013 NIIBE Yutaka
|
Copyright (C) 2012, 2013, 2016 NIIBE Yutaka
|
||||||
Copyright (C) 2012, 2013 Free Software Initiative of Japan
|
Copyright (C) 2012, 2013, 2016 Free Software Initiative of Japan
|
||||||
This document is licensed under a CC-BY-SA 3.0 Unported License
|
This document is licensed under a CC-BY-SA 3.0 Unported License
|
||||||
|
|
||||||
Gnuk Documentation
|
Gnuk Documentation
|
||||||
@@ -20,12 +20,11 @@ Contents:
|
|||||||
udev-rules.rst
|
udev-rules.rst
|
||||||
gnuk-token-initial-configuration.rst
|
gnuk-token-initial-configuration.rst
|
||||||
gnuk-personalization.rst
|
gnuk-personalization.rst
|
||||||
generating-2048-RSA-key.rst
|
generating-key.rst
|
||||||
gnuk-keytocard.rst
|
gnuk-keytocard.rst
|
||||||
gnuk-keytocard-noremoval.rst
|
gnuk-keytocard-noremoval.rst
|
||||||
gnuk-passphrase-setting.rst
|
gnuk-passphrase-setting.rst
|
||||||
using-gnuk-token-with-another-computer.rst
|
using-gnuk-token-with-another-computer.rst
|
||||||
gnome3-gpg-settings.rst
|
|
||||||
development.rst
|
development.rst
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ Gnuk is an implementation of USB cryptographic token for GNU Privacy
|
|||||||
Guard. Gnuk supports OpenPGP card protocol version 2, and it runs on
|
Guard. Gnuk supports OpenPGP card protocol version 2, and it runs on
|
||||||
STM32F103 processor.
|
STM32F103 processor.
|
||||||
|
|
||||||
|
This document explains about Gnuk 1.2, which comes with ECC algorithm.
|
||||||
|
|
||||||
|
|
||||||
Cryptographic token and feature of Gnuk
|
Cryptographic token and feature of Gnuk
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
@@ -31,15 +33,15 @@ Target boards for running Gnuk
|
|||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
Hardware requirement for Gnuk is the micro controller STM32F103.
|
Hardware requirement for Gnuk is the micro controller STM32F103.
|
||||||
In version 1.1.x, Gnuk supports following boards.
|
In version 1.2, Gnuk supports following boards.
|
||||||
|
|
||||||
* FST-01 (Flying Stone Tiny ZERO-ONE)
|
* FST-01 (Flying Stone Tiny ZERO-ONE)
|
||||||
|
|
||||||
* Olimex STM32-H103
|
* Olimex STM32-H103
|
||||||
|
|
||||||
* STM32 part of STM8S Discovery Kit
|
* ST Nucleo F103
|
||||||
|
|
||||||
* STBee
|
* Nitrokey Start
|
||||||
|
|
||||||
|
|
||||||
Host prerequisites for using Gnuk Token
|
Host prerequisites for using Gnuk Token
|
||||||
@@ -49,11 +51,9 @@ Host prerequisites for using Gnuk Token
|
|||||||
|
|
||||||
* libusb
|
* libusb
|
||||||
|
|
||||||
* [Optional] PC/SC lite (pcscd, libccid)
|
|
||||||
|
|
||||||
* [Optional] SSH: openssh
|
* [Optional] SSH: openssh
|
||||||
|
|
||||||
* [optional] Web: scute, firefox
|
* [experimental] Web: scute, firefox
|
||||||
|
|
||||||
|
|
||||||
Usages
|
Usages
|
||||||
@@ -62,4 +62,4 @@ Usages
|
|||||||
* Sign with GnuPG
|
* Sign with GnuPG
|
||||||
* Decrypt with GnuPG
|
* Decrypt with GnuPG
|
||||||
* Use with OpenSSH through gpg-agent (as ssh-agent)
|
* Use with OpenSSH through gpg-agent (as ssh-agent)
|
||||||
* Use with Firefox through Scute for X.509 client certificate authentication
|
* [experimental] Use with Firefox through Scute for X.509 client certificate authentication
|
||||||
|
|||||||
@@ -28,10 +28,16 @@ To stop SCDAEMON and let it exit, type::
|
|||||||
Then, you can confirm that there is no SCDAEMON any more by ``ps``
|
Then, you can confirm that there is no SCDAEMON any more by ``ps``
|
||||||
command.
|
command.
|
||||||
|
|
||||||
|
Or, you can use ``gpgconf`` command. Type::
|
||||||
|
|
||||||
|
$ gpgconf --reload scdameon
|
||||||
|
|
||||||
|
will do the samething.
|
||||||
|
|
||||||
|
|
||||||
Let GPG-AGENT/SCDAEMON learn
|
Let GPG-AGENT/SCDAEMON learn
|
||||||
============================
|
============================
|
||||||
|
|
||||||
To let gpg-agent/scdaemon learn from Gnuk Token, type::
|
To let gpg-agent/scdaemon "learn" from Gnuk Token, type::
|
||||||
|
|
||||||
$ gpg-connect-agent learn /bye
|
$ gpg-connect-agent learn /bye
|
||||||
|
|||||||
@@ -10,10 +10,13 @@ PC/SC Lite, as it has its own device configuration.
|
|||||||
udev rules for Gnuk Token
|
udev rules for Gnuk Token
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
In case of Debian, there is a file /lib/udev/rules.d/60-gnupg.rules,
|
In case of Debian, there is a file /lib/udev/rules.d/60-gnupg.rules
|
||||||
when you install "gnupg" package. This is the place we need to
|
(or /lib/udev/rules.d/60-scdamon.rules for newer version),
|
||||||
change, if your installation is older (than jessie). Newer "gnupg"
|
when you install "gnupg" package (or "scdaemon" package).
|
||||||
package (1.4.15-1 or later) has already supported Gnuk Token.
|
This is the place we need to
|
||||||
|
change, if your installation is older than jessie. Newer "gnupg"
|
||||||
|
package (1.4.15-1 or later) or "scdaemon" package has already
|
||||||
|
supported Gnuk Token.
|
||||||
|
|
||||||
If needed, please add lines for Gnuk Token to give a desktop user the
|
If needed, please add lines for Gnuk Token to give a desktop user the
|
||||||
permission to use the device. We specify USB ID of Gnuk Token (by
|
permission to use the device. We specify USB ID of Gnuk Token (by
|
||||||
@@ -30,7 +33,7 @@ FSIJ)::
|
|||||||
+
|
+
|
||||||
LABEL="gnupg_rules_end"
|
LABEL="gnupg_rules_end"
|
||||||
|
|
||||||
When we install "gnupg2" package only (with no "gnupg" package),
|
When we only install "gnupg2" package for 2.0 (with no "gnupg" package),
|
||||||
there will be no udev rules (there is a bug report #543217 for this issue).
|
there will be no udev rules (there is a bug report #543217 for this issue).
|
||||||
In this case, we need something like this in /etc/udev/rules.d/60-gnuk.rules::
|
In this case, we need something like this in /etc/udev/rules.d/60-gnuk.rules::
|
||||||
|
|
||||||
|
|||||||
@@ -12,90 +12,90 @@ while ``.gnupg`` directory contains keyrings and trustdb, too.
|
|||||||
Fetch the public key and connect it to the Token
|
Fetch the public key and connect it to the Token
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
Using the Token, we need to put the public key and the secret
|
In order to use the Token, we need to put the public key and the secret
|
||||||
key reference (to the token) in ``.gnupg``.
|
key references (to the token) under ``.gnupg`` directory.
|
||||||
|
|
||||||
To do that, invoke GnuPG with ``--card-edit`` option. ::
|
To do that, invoke GnuPG with ``--card-edit`` option. ::
|
||||||
|
|
||||||
$ gpg --card-edit
|
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||||
Application ID ...: D276000124010200F517000000010000
|
Application ID ...: D276000124010200FFFE871930590000
|
||||||
Version ..........: 2.0
|
Version ..........: 2.0
|
||||||
Manufacturer .....: FSIJ
|
Manufacturer .....: unmanaged S/N range
|
||||||
Serial number ....: 00000001
|
Serial number ....: 87193059
|
||||||
Name of cardholder: Yutaka Niibe
|
Name of cardholder: Yutaka Niibe
|
||||||
Language prefs ...: ja
|
Language prefs ...: ja
|
||||||
Sex ..............: male
|
Sex ..............: male
|
||||||
URL of public key : http://www.gniibe.org/gniibe.asc
|
URL of public key : http://www.gniibe.org/gniibe-20150813.asc
|
||||||
Login data .......: gniibe
|
Login data .......: gniibe
|
||||||
Signature PIN ....: not forced
|
Signature PIN ....: not forced
|
||||||
Key attributes ...: 2048R 2048R 2048R
|
Key attributes ...: ed25519 cv25519 ed25519
|
||||||
Max. PIN lengths .: 127 127 127
|
Max. PIN lengths .: 127 127 127
|
||||||
PIN retry counter : 3 3 3
|
PIN retry counter : 3 3 3
|
||||||
Signature counter : 6
|
Signature counter : 0
|
||||||
Signature key ....: 1241 24BD 3B48 62AF 7A0A 42F1 00B4 5EBD 4CA7 BABE
|
Signature key ....: 249C B377 1750 745D 5CDD 323C E267 B052 364F 028D
|
||||||
created ....: 2010-10-15 06:46:33
|
created ....: 2015-08-12 07:10:48
|
||||||
Encryption key....: 42E1 E805 4E6F 1F30 26F2 DC79 79A7 9093 0842 39CF
|
Encryption key....: E228 AB42 0F73 3B1D 712D E50C 850A F040 D619 F240
|
||||||
created ....: 2010-10-15 06:46:33
|
created ....: 2015-08-12 07:10:48
|
||||||
Authentication key: B4D9 7142 C42D 6802 F5F7 4E70 9C33 B6BA 5BB0 65DC
|
Authentication key: E63F 31E6 F203 20B5 D796 D266 5F91 0521 FAA8 05B1
|
||||||
created ....: 2010-10-22 06:06:36
|
created ....: 2015-08-12 07:16:14
|
||||||
General key info..: [none]
|
General key info..: [none]
|
||||||
|
|
||||||
gpg/card>
|
gpg/card>
|
||||||
|
|
||||||
It says, there is no key info related to this token on your PC (``[none]``).
|
Here, the secret key references (to the token) are created under ``.gnupg/private-keys-v1.d`` directory. It can be also created when I do ``--card-status`` by GnuPG.
|
||||||
|
|
||||||
Fetch the public key from URL specified in the Token. ::
|
Still, it says that there is no key info related to this token on my PC (``[none]`` for General key info), because I don't have the public key on this PC yet.
|
||||||
|
|
||||||
|
So, I fetch the public key from URL specified in the Token. ::
|
||||||
|
|
||||||
gpg/card> fetch
|
gpg/card> fetch
|
||||||
gpg: requesting key 4CA7BABE from http server www.gniibe.org
|
gpg: requesting key E267B052364F028D from http server www.gniibe.org
|
||||||
gpg: key 4CA7BABE: public key "NIIBE Yutaka <gniibe@fsij.org>" imported
|
gpg: key E267B052364F028D: public key "NIIBE Yutaka <gniibe@fsij.org>" imported
|
||||||
gpg: no ultimately trusted keys found
|
|
||||||
gpg: Total number processed: 1
|
gpg: Total number processed: 1
|
||||||
gpg: imported: 1 (RSA: 1)
|
gpg: imported: 1
|
||||||
|
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
|
||||||
|
gpg: depth: 0 valid: 6 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 6u
|
||||||
|
|
||||||
gpg/card>
|
gpg/card>
|
||||||
|
|
||||||
Good. The public key is now in ``.gnupg``. We can examine by ``gpg --list-keys``.
|
Good. The public key is now under ``.gnupg`` directory. We can examine by ``gpg --list-keys``.
|
||||||
|
|
||||||
However, the secret key reference (to the token) is not in ``.gnupg`` yet.
|
When I type return at the ``gpg/card>`` prompt, now, I can see: ::
|
||||||
|
|
||||||
It will be generated when I do ``--card-status`` by GnuPG with
|
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||||
correspoinding public key in ``.gnupg``, or just type return
|
Application ID ...: D276000124010200FFFE871930590000
|
||||||
at the ``gpg/card>`` prompt. ::
|
|
||||||
|
|
||||||
gpg/card>
|
|
||||||
|
|
||||||
Application ID ...: D276000124010200F517000000010000
|
|
||||||
Version ..........: 2.0
|
Version ..........: 2.0
|
||||||
Manufacturer .....: FSIJ
|
Manufacturer .....: unmanaged S/N range
|
||||||
Serial number ....: 00000001
|
Serial number ....: 87193059
|
||||||
Name of cardholder: Yutaka Niibe
|
Name of cardholder: Yutaka Niibe
|
||||||
Language prefs ...: ja
|
Language prefs ...: ja
|
||||||
Sex ..............: male
|
Sex ..............: male
|
||||||
URL of public key : http://www.gniibe.org/gniibe.asc
|
URL of public key : http://www.gniibe.org/gniibe-20150813.asc
|
||||||
Login data .......: gniibe
|
Login data .......: gniibe
|
||||||
Signature PIN ....: not forced
|
Signature PIN ....: not forced
|
||||||
Key attributes ...: 2048R 2048R 2048R
|
Key attributes ...: ed25519 cv25519 ed25519
|
||||||
Max. PIN lengths .: 127 127 127
|
Max. PIN lengths .: 127 127 127
|
||||||
PIN retry counter : 3 3 3
|
PIN retry counter : 3 3 3
|
||||||
Signature counter : 6
|
Signature counter : 0
|
||||||
Signature key ....: 1241 24BD 3B48 62AF 7A0A 42F1 00B4 5EBD 4CA7 BABE
|
Signature key ....: 249C B377 1750 745D 5CDD 323C E267 B052 364F 028D
|
||||||
created ....: 2010-10-15 06:46:33
|
created ....: 2015-08-12 07:10:48
|
||||||
Encryption key....: 42E1 E805 4E6F 1F30 26F2 DC79 79A7 9093 0842 39CF
|
Encryption key....: E228 AB42 0F73 3B1D 712D E50C 850A F040 D619 F240
|
||||||
created ....: 2010-10-15 06:46:33
|
created ....: 2015-08-12 07:10:48
|
||||||
Authentication key: B4D9 7142 C42D 6802 F5F7 4E70 9C33 B6BA 5BB0 65DC
|
Authentication key: E63F 31E6 F203 20B5 D796 D266 5F91 0521 FAA8 05B1
|
||||||
created ....: 2010-10-22 06:06:36
|
created ....: 2015-08-12 07:16:14
|
||||||
General key info..:
|
General key info..: pub ed25519/E267B052364F028D 2015-08-12 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
pub 2048R/4CA7BABE 2010-10-15 NIIBE Yutaka <gniibe@fsij.org>
|
sec> ed25519/E267B052364F028D created: 2015-08-12 expires: never
|
||||||
sec> 2048R/4CA7BABE created: 2010-10-15 expires: never
|
card-no: FFFE 87193059
|
||||||
card-no: F517 00000001
|
ssb> cv25519/850AF040D619F240 created: 2015-08-12 expires: never
|
||||||
ssb> 2048R/084239CF created: 2010-10-15 expires: never
|
card-no: FFFE 87193059
|
||||||
card-no: F517 00000001
|
ssb> ed25519/5F910521FAA805B1 created: 2015-08-12 expires: never
|
||||||
ssb> 2048R/5BB065DC created: 2010-10-22 expires: never
|
card-no: FFFE 87193059
|
||||||
card-no: F517 00000001
|
|
||||||
|
|
||||||
gpg/card>
|
gpg/card>
|
||||||
|
|
||||||
|
Note that, it displays the information about "General key info".
|
||||||
|
|
||||||
OK, now I can use the Token on this computer.
|
OK, now I can use the Token on this computer.
|
||||||
|
|
||||||
|
|
||||||
@@ -103,33 +103,43 @@ Update trustdb for the key on Gnuk Token
|
|||||||
========================================
|
========================================
|
||||||
|
|
||||||
Yes, I can use the Token by the public key and the secret
|
Yes, I can use the Token by the public key and the secret
|
||||||
key reference to the card. More, I need to update the trustdb.
|
key references to the card. More, I need to update the trustdb.
|
||||||
|
|
||||||
To do that I do: ::
|
To do that, I do: ::
|
||||||
|
|
||||||
$ gpg --edit-key 4ca7babe
|
$ ./gpg --edit-key E267B052364F028D
|
||||||
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
gpg (GnuPG) 2.1.13; Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
Secret key is available.
|
Secret key is available.
|
||||||
|
|
||||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
sec ed25519/E267B052364F028D
|
||||||
trust: unknown validity: unknown
|
created: 2015-08-12 expires: never usage: SC
|
||||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
card-no: FFFE 87193059
|
||||||
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
|
trust: unknown validity: unknown
|
||||||
|
ssb cv25519/850AF040D619F240
|
||||||
|
created: 2015-08-12 expires: never usage: E
|
||||||
|
card-no: FFFE 87193059
|
||||||
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
card-no: FFFE 87193059
|
||||||
[ unknown] (1). NIIBE Yutaka <gniibe@fsij.org>
|
[ unknown] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
[ unknown] (2) NIIBE Yutaka <gniibe@debian.org>
|
[ unknown] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
gpg>
|
|
||||||
|
|
||||||
See, the key is ``unknown`` state. Add trust for that. ::
|
See, the key is ``unknown`` state. Add trust for that, because it's the key under my control. ::
|
||||||
|
|
||||||
gpg> trust
|
gpg> trust
|
||||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
sec ed25519/E267B052364F028D
|
||||||
trust: unknown validity: unknown
|
created: 2015-08-12 expires: never usage: SC
|
||||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
card-no: FFFE 87193059
|
||||||
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
|
trust: unknown validity: unknown
|
||||||
|
ssb cv25519/850AF040D619F240
|
||||||
|
created: 2015-08-12 expires: never usage: E
|
||||||
|
card-no: FFFE 87193059
|
||||||
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
card-no: FFFE 87193059
|
||||||
[ unknown] (1). NIIBE Yutaka <gniibe@fsij.org>
|
[ unknown] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
[ unknown] (2) NIIBE Yutaka <gniibe@debian.org>
|
[ unknown] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
@@ -146,32 +156,49 @@ See, the key is ``unknown`` state. Add trust for that. ::
|
|||||||
Your decision? 5
|
Your decision? 5
|
||||||
Do you really want to set this key to ultimate trust? (y/N) y
|
Do you really want to set this key to ultimate trust? (y/N) y
|
||||||
|
|
||||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
sec ed25519/E267B052364F028D
|
||||||
trust: ultimate validity: unknown
|
created: 2015-08-12 expires: never usage: SC
|
||||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
card-no: FFFE 87193059
|
||||||
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
|
trust: ultimate validity: unknown
|
||||||
|
ssb cv25519/850AF040D619F240
|
||||||
|
created: 2015-08-12 expires: never usage: E
|
||||||
|
card-no: FFFE 87193059
|
||||||
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
card-no: FFFE 87193059
|
||||||
[ unknown] (1). NIIBE Yutaka <gniibe@fsij.org>
|
[ unknown] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
[ unknown] (2) NIIBE Yutaka <gniibe@debian.org>
|
[ unknown] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
Please note that the shown key validity is not necessarily correct
|
Please note that the shown key validity is not necessarily correct
|
||||||
unless you restart the program.
|
unless you restart the program.
|
||||||
|
|
||||||
$
|
gpg>
|
||||||
|
|
||||||
Next time I invoke GnuPG, it will be ``ultimate`` key. Let's see: ::
|
And I quit from gpg. Then, when I invoke GnuPG, it will be ``ultimate`` key. Let's see: ::
|
||||||
|
|
||||||
$ gpg --edit-key 4ca7babe
|
$ ./gpg --edit-key E267B052364F028D
|
||||||
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
gpg (GnuPG) 2.1.13; Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
|
||||||
Secret key is available.
|
Secret key is available.
|
||||||
|
|
||||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
gpg: checking the trustdb
|
||||||
trust: ultimate validity: ultimate
|
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
|
||||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
gpg: depth: 0 valid: 7 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 7u
|
||||||
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
|
sec ed25519/E267B052364F028D
|
||||||
|
created: 2015-08-12 expires: never usage: SC
|
||||||
|
card-no: FFFE 87193059
|
||||||
|
trust: ultimate validity: ultimate
|
||||||
|
ssb cv25519/850AF040D619F240
|
||||||
|
created: 2015-08-12 expires: never usage: E
|
||||||
|
card-no: FFFE 87193059
|
||||||
|
ssb ed25519/5F910521FAA805B1
|
||||||
|
created: 2015-08-12 expires: never usage: A
|
||||||
|
card-no: FFFE 87193059
|
||||||
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||||
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
[ultimate] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||||
|
|
||||||
gpg> quit
|
gpg> quit
|
||||||
$
|
$
|
||||||
|
|
||||||
|
OK, all set. I'm ready to use my Gnuk Token on this PC.
|
||||||
|
|||||||
@@ -179,15 +179,15 @@ static const unsigned char FSb[256] =
|
|||||||
V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
|
V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
|
||||||
|
|
||||||
#define V(a,b,c,d) 0x##a##b##c##d
|
#define V(a,b,c,d) 0x##a##b##c##d
|
||||||
const uint32_t FT0[256] __attribute__((section(".sys.0"))) = { FT };
|
const uint32_t FT0[256] __attribute__((weak,section(".sys.0"))) = { FT };
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
#define V(a,b,c,d) 0x##b##c##d##a
|
#define V(a,b,c,d) 0x##b##c##d##a
|
||||||
const uint32_t FT1[256] __attribute__((section(".sys.1"))) = { FT };
|
const uint32_t FT1[256] __attribute__((weak,section(".sys.1"))) = { FT };
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
#define V(a,b,c,d) 0x##c##d##a##b
|
#define V(a,b,c,d) 0x##c##d##a##b
|
||||||
const uint32_t FT2[256] __attribute__((section(".sys.2"))) = { FT };
|
const uint32_t FT2[256] __attribute__((weak,section(".sys.2"))) = { FT };
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
#define V(a,b,c,d) 0x##d##a##b##c
|
#define V(a,b,c,d) 0x##d##a##b##c
|
||||||
|
|||||||
@@ -223,6 +223,24 @@ size_t mpi_lsb( const mpi *X )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count leading zero bits in a given integer
|
||||||
|
*/
|
||||||
|
static size_t int_clz( const t_uint x )
|
||||||
|
{
|
||||||
|
size_t j;
|
||||||
|
t_uint mask = (t_uint) 1 << (biL - 1);
|
||||||
|
|
||||||
|
for( j = 0; j < biL; j++ )
|
||||||
|
{
|
||||||
|
if( x & mask ) break;
|
||||||
|
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the number of most significant bits
|
* Return the number of most significant bits
|
||||||
*/
|
*/
|
||||||
@@ -1102,6 +1120,100 @@ int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
|
|||||||
return( mpi_mul_mpi( X, A, &_B ) );
|
return( mpi_mul_mpi( X, A, &_B ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unsigned integer divide - 64bit dividend and 32bit divisor
|
||||||
|
*/
|
||||||
|
static t_uint int_div_int(t_uint u1, t_uint u0, t_uint d, t_uint *r)
|
||||||
|
{
|
||||||
|
#if defined(POLARSSL_HAVE_UDBL)
|
||||||
|
t_udbl dividend, quotient;
|
||||||
|
#else
|
||||||
|
const t_uint radix = (t_uint) 1 << biH;
|
||||||
|
const t_uint uint_halfword_mask = ( (t_uint) 1 << biH ) - 1;
|
||||||
|
t_uint d0, d1, q0, q1, rAX, r0, quotient;
|
||||||
|
t_uint u0_msw, u0_lsw;
|
||||||
|
size_t s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for overflow
|
||||||
|
*/
|
||||||
|
if(( 0 == d ) || ( u1 >= d ))
|
||||||
|
{
|
||||||
|
if (r != NULL) *r = (~0);
|
||||||
|
|
||||||
|
return (~0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_HAVE_UDBL)
|
||||||
|
dividend = (t_udbl) u1 << biL;
|
||||||
|
dividend |= (t_udbl) u0;
|
||||||
|
quotient = dividend / d;
|
||||||
|
if( quotient > ( (t_udbl) 1 << biL ) - 1 )
|
||||||
|
quotient = ( (t_udbl) 1 << biL ) - 1;
|
||||||
|
|
||||||
|
if( r != NULL )
|
||||||
|
*r = (t_uint)( dividend - (quotient * d ) );
|
||||||
|
|
||||||
|
return (t_uint) quotient;
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Algorithm D, Section 4.3.1 - The Art of Computer Programming
|
||||||
|
* Vol. 2 - Seminumerical Algorithms, Knuth
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normalize the divisor, d, and dividend, u0, u1
|
||||||
|
*/
|
||||||
|
s = int_clz( d );
|
||||||
|
d = d << s;
|
||||||
|
|
||||||
|
u1 = u1 << s;
|
||||||
|
u1 |= ( u0 >> ( biL - s ) ) & ( -(t_sint)s >> ( biL - 1 ) );
|
||||||
|
u0 = u0 << s;
|
||||||
|
|
||||||
|
d1 = d >> biH;
|
||||||
|
d0 = d & uint_halfword_mask;
|
||||||
|
|
||||||
|
u0_msw = u0 >> biH;
|
||||||
|
u0_lsw = u0 & uint_halfword_mask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the first quotient and remainder
|
||||||
|
*/
|
||||||
|
q1 = u1 / d1;
|
||||||
|
r0 = u1 - d1 * q1;
|
||||||
|
|
||||||
|
while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
|
||||||
|
{
|
||||||
|
q1 -= 1;
|
||||||
|
r0 += d1;
|
||||||
|
|
||||||
|
if ( r0 >= radix ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rAX = (u1 * radix) + (u0_msw - q1 * d);
|
||||||
|
q0 = rAX / d1;
|
||||||
|
r0 = rAX - q0 * d1;
|
||||||
|
|
||||||
|
while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
|
||||||
|
{
|
||||||
|
q0 -= 1;
|
||||||
|
r0 += d1;
|
||||||
|
|
||||||
|
if ( r0 >= radix ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r != NULL)
|
||||||
|
*r = (rAX * radix + u0_lsw - q0 * d) >> s;
|
||||||
|
|
||||||
|
quotient = q1 * radix + q0;
|
||||||
|
|
||||||
|
return quotient;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Division by mpi: A = Q * B + R (HAC 14.20)
|
* Division by mpi: A = Q * B + R (HAC 14.20)
|
||||||
*/
|
*/
|
||||||
@@ -1159,57 +1271,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
|
|||||||
Z.p[i - t - 1] = ~0;
|
Z.p[i - t - 1] = ~0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(POLARSSL_HAVE_UDBL)
|
Z.p[i - t - 1] = int_div_int( X.p[i], X.p[i-1], Y.p[t], NULL);
|
||||||
t_udbl r;
|
|
||||||
|
|
||||||
r = (t_udbl) X.p[i] << biL;
|
|
||||||
r |= (t_udbl) X.p[i - 1];
|
|
||||||
r /= Y.p[t];
|
|
||||||
if( r > ((t_udbl) 1 << biL) - 1)
|
|
||||||
r = ((t_udbl) 1 << biL) - 1;
|
|
||||||
|
|
||||||
Z.p[i - t - 1] = (t_uint) r;
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* __udiv_qrnnd_c, from gmp/longlong.h
|
|
||||||
*/
|
|
||||||
t_uint q0, q1, r0, r1;
|
|
||||||
t_uint d0, d1, d, m;
|
|
||||||
|
|
||||||
d = Y.p[t];
|
|
||||||
d0 = ( d << biH ) >> biH;
|
|
||||||
d1 = ( d >> biH );
|
|
||||||
|
|
||||||
q1 = X.p[i] / d1;
|
|
||||||
r1 = X.p[i] - d1 * q1;
|
|
||||||
r1 <<= biH;
|
|
||||||
r1 |= ( X.p[i - 1] >> biH );
|
|
||||||
|
|
||||||
m = q1 * d0;
|
|
||||||
if( r1 < m )
|
|
||||||
{
|
|
||||||
q1--, r1 += d;
|
|
||||||
while( r1 >= d && r1 < m )
|
|
||||||
q1--, r1 += d;
|
|
||||||
}
|
|
||||||
r1 -= m;
|
|
||||||
|
|
||||||
q0 = r1 / d1;
|
|
||||||
r0 = r1 - d1 * q0;
|
|
||||||
r0 <<= biH;
|
|
||||||
r0 |= ( X.p[i - 1] << biH ) >> biH;
|
|
||||||
|
|
||||||
m = q0 * d0;
|
|
||||||
if( r0 < m )
|
|
||||||
{
|
|
||||||
q0--, r0 += d;
|
|
||||||
while( r0 >= d && r0 < m )
|
|
||||||
q0--, r0 += d;
|
|
||||||
}
|
|
||||||
r0 -= m;
|
|
||||||
|
|
||||||
Z.p[i - t - 1] = ( q1 << biH ) | q0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Z.p[i - t - 1]++;
|
Z.p[i - t - 1]++;
|
||||||
@@ -1584,6 +1646,7 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
|||||||
memset (d, 0, 2 * N->n * ciL); /* Set D zero. */
|
memset (d, 0, 2 * N->n * ciL); /* Set D zero. */
|
||||||
mpi_sub_hlp( N->n, N->p, d + N->n);
|
mpi_sub_hlp( N->n, N->p, d + N->n);
|
||||||
MPI_CHK( mpi_mod_mpi( &RR, &T, N ) );
|
MPI_CHK( mpi_mod_mpi( &RR, &T, N ) );
|
||||||
|
MPI_CHK( mpi_grow( &RR, N->n ) );
|
||||||
|
|
||||||
if( _RR != NULL )
|
if( _RR != NULL )
|
||||||
memcpy( _RR, &RR, sizeof( mpi ) );
|
memcpy( _RR, &RR, sizeof( mpi ) );
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
PROJECT = regnual
|
PROJECT = regnual
|
||||||
|
|
||||||
OBJS = regnual.o usb_stm32f103.o sys.o
|
OBJS = regnual.o usb-stm32f103.o reset.o
|
||||||
LDSCRIPT= regnual.ld
|
LDSCRIPT= regnual.ld
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
@@ -23,7 +23,7 @@ DEFS = -DFREE_STANDING
|
|||||||
|
|
||||||
CFLAGS = -O2 -g
|
CFLAGS = -O2 -g
|
||||||
CFLAGS += -Wa,-alms=$(notdir $(<:.c=.lst)) -fpie
|
CFLAGS += -Wa,-alms=$(notdir $(<:.c=.lst)) -fpie
|
||||||
CFLAGS += $(CWARN) -I . -I ../src -fno-common $(MCFLAGS) $(TOPT) $(DEFS)
|
CFLAGS += $(CWARN) -I . -I ../chopstx -fno-common $(MCFLAGS) $(TOPT) $(DEFS)
|
||||||
|
|
||||||
LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT)
|
LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT)
|
||||||
|
|
||||||
@@ -32,19 +32,19 @@ LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT)
|
|||||||
|
|
||||||
all: regnual.hex
|
all: regnual.hex
|
||||||
|
|
||||||
regnual.o: regnual.c ../src/sys.h ../src/usb_lld.h
|
regnual.o: regnual.c ../chopstx/sys.h ../chopstx/usb_lld.h
|
||||||
|
|
||||||
regnual.hex: regnual.elf
|
regnual.hex: regnual.elf
|
||||||
$(OBJCOPY) -Obinary regnual.elf regnual.bin
|
$(OBJCOPY) -Obinary regnual.elf regnual.bin
|
||||||
$(OBJCOPY) -Oihex regnual.elf regnual.hex
|
$(OBJCOPY) -Oihex regnual.elf regnual.hex
|
||||||
|
|
||||||
usb_stm32f103.o: ../src/usb_stm32f103.c
|
usb-stm32f103.o: ../chopstx/mcu/usb-stm32f103.c
|
||||||
$(CC) $(CFLAGS) -c -o usb_stm32f103.o ../src/usb_stm32f103.c
|
$(CC) $(CFLAGS) -c -o usb-stm32f103.o ../chopstx/mcu/usb-stm32f103.c
|
||||||
|
|
||||||
regnual.elf: $(OBJS) $(LDSCRIPT)
|
regnual.elf: $(OBJS) $(LDSCRIPT)
|
||||||
$(CC) $(LDFLAGS) -o regnual.elf $(OBJS)
|
$(CC) $(LDFLAGS) -o regnual.elf $(OBJS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f $(OBJS) regnual.elf regnual.hex regnual.bin
|
-rm -f $(OBJS) regnual.elf regnual.hex regnual.bin *.lst
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* regnual.c -- Firmware installation for STM32F103 Flash ROM
|
* regnual.c -- Firmware installation for STM32F103 Flash ROM
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012, 2013, 2015
|
* Copyright (C) 2012, 2013, 2015, 2016
|
||||||
* Free Software Initiative of Japan
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
@@ -51,7 +51,7 @@ static uint32_t flash_end;
|
|||||||
/* USB Standard Device Descriptor */
|
/* USB Standard Device Descriptor */
|
||||||
static const uint8_t regnual_device_desc[] = {
|
static const uint8_t regnual_device_desc[] = {
|
||||||
18, /* bLength */
|
18, /* bLength */
|
||||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||||
0xFF, /* bDeviceClass: VENDOR */
|
0xFF, /* bDeviceClass: VENDOR */
|
||||||
0x00, /* bDeviceSubClass */
|
0x00, /* bDeviceSubClass */
|
||||||
@@ -64,24 +64,26 @@ static const uint8_t regnual_device_desc[] = {
|
|||||||
0x01 /* bNumConfigurations */
|
0x01 /* bNumConfigurations */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(USB_SELF_POWERED)
|
||||||
|
#define REGNUAL_FEATURE_INIT 0xC0 /* self powered */
|
||||||
|
#else
|
||||||
|
#define REGNUAL_FEATURE_INIT 0x80 /* bus powered */
|
||||||
|
#endif
|
||||||
|
|
||||||
static const uint8_t regnual_config_desc[] = {
|
static const uint8_t regnual_config_desc[] = {
|
||||||
9,
|
9,
|
||||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
|
||||||
18, 0, /* wTotalLength: no of returned bytes */
|
18, 0, /* wTotalLength: no of returned bytes */
|
||||||
1, /* bNumInterfaces: single vendor interface */
|
1, /* bNumInterfaces: single vendor interface */
|
||||||
0x01, /* bConfigurationValue: Configuration value */
|
0x01, /* bConfigurationValue: Configuration value */
|
||||||
0x00, /* iConfiguration: None */
|
0x00, /* iConfiguration: None */
|
||||||
#if defined(USB_SELF_POWERED)
|
REGNUAL_FEATURE_INIT, /* bmAttributes: bus powered */
|
||||||
0xC0, /* bmAttributes: self powered */
|
50, /* MaxPower 100 mA */
|
||||||
#else
|
|
||||||
0x80, /* bmAttributes: bus powered */
|
|
||||||
#endif
|
|
||||||
50, /* MaxPower 100 mA */
|
|
||||||
|
|
||||||
/* Interface Descriptor */
|
/* Interface Descriptor */
|
||||||
9,
|
9,
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||||
0, /* bInterfaceNumber: Index of this interface */
|
0, /* bInterfaceNumber: Index of this interface */
|
||||||
0, /* Alternate setting for this interface */
|
0, /* Alternate setting for this interface */
|
||||||
0, /* bNumEndpoints: None */
|
0, /* bNumEndpoints: None */
|
||||||
0xFF,
|
0xFF,
|
||||||
@@ -92,7 +94,7 @@ static const uint8_t regnual_config_desc[] = {
|
|||||||
|
|
||||||
static const uint8_t regnual_string_lang_id[] = {
|
static const uint8_t regnual_string_lang_id[] = {
|
||||||
4, /* bLength */
|
4, /* bLength */
|
||||||
USB_STRING_DESCRIPTOR_TYPE,
|
STRING_DESCRIPTOR,
|
||||||
0x09, 0x04 /* LangID = 0x0409: US-English */
|
0x09, 0x04 /* LangID = 0x0409: US-English */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,23 +102,17 @@ static const uint8_t regnual_string_lang_id[] = {
|
|||||||
|
|
||||||
static const uint8_t regnual_string_serial[] = {
|
static const uint8_t regnual_string_serial[] = {
|
||||||
8*2+2,
|
8*2+2,
|
||||||
USB_STRING_DESCRIPTOR_TYPE,
|
STRING_DESCRIPTOR,
|
||||||
/* FSIJ-0.0 */
|
/* FSIJ-0.0 */
|
||||||
'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0,
|
'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0,
|
||||||
'0', 0, '.', 0, '0', 0,
|
'0', 0, '.', 0, '0', 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
usb_cb_device_reset (void)
|
usb_device_reset (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
/* Set DEVICE as not configured */
|
usb_lld_reset (dev, REGNUAL_FEATURE_INIT);
|
||||||
usb_lld_set_configuration (0);
|
|
||||||
|
|
||||||
/* Current Feature initialization */
|
|
||||||
usb_lld_set_feature (regnual_config_desc[7]);
|
|
||||||
|
|
||||||
usb_lld_reset ();
|
|
||||||
|
|
||||||
/* Initialize Endpoint 0 */
|
/* Initialize Endpoint 0 */
|
||||||
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
||||||
@@ -173,94 +169,101 @@ static uint32_t calc_crc32 (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
static void
|
||||||
|
usb_ctrl_write_finish (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
struct device_req *arg = &dev->dev_req;
|
||||||
|
uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
|
||||||
|
|
||||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT) && USB_SETUP_SET (req))
|
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
|
||||||
|
&& USB_SETUP_SET (arg->type))
|
||||||
{
|
{
|
||||||
if (req_no == USB_REGNUAL_SEND && value == 0)
|
if (arg->request == USB_REGNUAL_SEND && arg->value == 0)
|
||||||
result = calc_crc32 ();
|
result = calc_crc32 ();
|
||||||
else if (req_no == USB_REGNUAL_FLASH)
|
else if (arg->request == USB_REGNUAL_FLASH)
|
||||||
{
|
{
|
||||||
uint32_t dst_addr = (0x08000000 + value * 0x100);
|
uint32_t dst_addr = (0x08000000 + arg->value * 0x100);
|
||||||
|
|
||||||
result = flash_write (dst_addr, (const uint8_t *)mem, 256);
|
result = flash_write (dst_addr, (const uint8_t *)mem, 256);
|
||||||
}
|
}
|
||||||
else if (req_no == USB_REGNUAL_PROTECT && value == 0)
|
else if (arg->request == USB_REGNUAL_PROTECT && arg->value == 0)
|
||||||
result = flash_protect ();
|
result = flash_protect ();
|
||||||
else if (req_no == USB_REGNUAL_FINISH && value == 0)
|
else if (arg->request == USB_REGNUAL_FINISH && arg->value == 0)
|
||||||
nvic_system_reset ();
|
nvic_system_reset ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
usb_setup (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
struct device_req *arg = &dev->dev_req;
|
||||||
|
uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
|
||||||
|
|
||||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
||||||
{
|
{
|
||||||
if (USB_SETUP_GET (req))
|
if (USB_SETUP_GET (arg->type))
|
||||||
{
|
{
|
||||||
if (req_no == USB_REGNUAL_MEMINFO)
|
if (arg->request == USB_REGNUAL_MEMINFO)
|
||||||
{
|
{
|
||||||
const uint8_t *mem_info[2];
|
const uint8_t *mem_info[2];
|
||||||
|
|
||||||
mem_info[0] = (const uint8_t *)FLASH_START;
|
mem_info[0] = (const uint8_t *)FLASH_START;
|
||||||
mem_info[1] = (const uint8_t *)flash_end;
|
mem_info[1] = (const uint8_t *)flash_end;
|
||||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), detail);
|
return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
|
||||||
}
|
}
|
||||||
else if (req_no == USB_REGNUAL_RESULT)
|
else if (arg->request == USB_REGNUAL_RESULT)
|
||||||
return usb_lld_reply_request (&result, sizeof (uint32_t), detail);
|
return usb_lld_ctrl_send (dev, &result, sizeof (uint32_t));
|
||||||
}
|
}
|
||||||
else /* SETUP_SET */
|
else /* SETUP_SET */
|
||||||
{
|
{
|
||||||
if (req_no == USB_REGNUAL_SEND)
|
if (arg->request == USB_REGNUAL_SEND)
|
||||||
{
|
{
|
||||||
if (detail->value != 0 || detail->index + detail->len > 256)
|
if (arg->value != 0 || arg->index + arg->len > 256)
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
if (detail->index + detail->len < 256)
|
if (arg->index + arg->len < 256)
|
||||||
memset ((uint8_t *)mem + detail->index + detail->len, 0xff,
|
memset ((uint8_t *)mem + arg->index + arg->len, 0xff,
|
||||||
256 - (detail->index + detail->len));
|
256 - (arg->index + arg->len));
|
||||||
|
|
||||||
usb_lld_set_data_to_recv (mem + detail->index, detail->len);
|
return usb_lld_ctrl_recv (dev, mem + arg->index, arg->len);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else if (req_no == USB_REGNUAL_FLASH && detail->len == 0
|
else if (arg->request == USB_REGNUAL_FLASH && arg->len == 0
|
||||||
&& detail->index == 0)
|
&& arg->index == 0)
|
||||||
{
|
{
|
||||||
uint32_t dst_addr = (0x08000000 + detail->value * 0x100);
|
uint32_t dst_addr = (0x08000000 + arg->value * 0x100);
|
||||||
|
|
||||||
if (dst_addr + 256 <= flash_end)
|
if (dst_addr + 256 <= flash_end)
|
||||||
return USB_SUCCESS;
|
return usb_lld_ctrl_ack (dev);
|
||||||
}
|
}
|
||||||
else if (req_no == USB_REGNUAL_PROTECT && detail->len == 0
|
else if (arg->request == USB_REGNUAL_PROTECT && arg->len == 0
|
||||||
&& detail->value == 0 && detail->index == 0)
|
&& arg->value == 0 && arg->index == 0)
|
||||||
return USB_SUCCESS;
|
return usb_lld_ctrl_ack (dev);
|
||||||
else if (req_no == USB_REGNUAL_FINISH && detail->len == 0
|
else if (arg->request == USB_REGNUAL_FINISH && arg->len == 0
|
||||||
&& detail->value == 0 && detail->index == 0)
|
&& arg->value == 0 && arg->index == 0)
|
||||||
return USB_SUCCESS;
|
return usb_lld_ctrl_ack (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
usb_get_descriptor (struct usb_dev *dev)
|
||||||
struct control_info *detail)
|
|
||||||
{
|
{
|
||||||
|
struct device_req *arg = &dev->dev_req;
|
||||||
|
uint8_t rcp = arg->type & RECIPIENT;
|
||||||
|
uint8_t desc_type = (arg->value >> 8);
|
||||||
|
uint8_t desc_index = (arg->value & 0xff);
|
||||||
|
|
||||||
if (rcp != DEVICE_RECIPIENT)
|
if (rcp != DEVICE_RECIPIENT)
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
if (desc_type == DEVICE_DESCRIPTOR)
|
if (desc_type == DEVICE_DESCRIPTOR)
|
||||||
return usb_lld_reply_request (regnual_device_desc,
|
return usb_lld_ctrl_send (dev, regnual_device_desc,
|
||||||
sizeof (regnual_device_desc), detail);
|
sizeof (regnual_device_desc));
|
||||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||||
return usb_lld_reply_request (regnual_config_desc,
|
return usb_lld_ctrl_send (dev, regnual_config_desc,
|
||||||
sizeof (regnual_config_desc), detail);
|
sizeof (regnual_config_desc));
|
||||||
else if (desc_type == STRING_DESCRIPTOR)
|
else if (desc_type == STRING_DESCRIPTOR)
|
||||||
{
|
{
|
||||||
const uint8_t *str;
|
const uint8_t *str;
|
||||||
@@ -285,35 +288,38 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
|||||||
size = sizeof (regnual_string_serial);
|
size = sizeof (regnual_string_serial);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return usb_lld_reply_request (str, size, detail);
|
return usb_lld_ctrl_send (dev, str, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
static int
|
||||||
|
usb_set_configuration (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
(void)value;
|
uint8_t current_conf;
|
||||||
|
|
||||||
switch (event_type)
|
current_conf = usb_lld_current_configuration (dev);
|
||||||
|
if (current_conf == 0)
|
||||||
{
|
{
|
||||||
case USB_EVENT_ADDRESS:
|
if (dev->dev_req.value != 1)
|
||||||
case USB_EVENT_CONFIG:
|
return -1;
|
||||||
return USB_SUCCESS;
|
|
||||||
default:
|
usb_lld_set_configuration (dev, 1);
|
||||||
break;
|
}
|
||||||
|
else if (current_conf != dev->dev_req.value)
|
||||||
|
{
|
||||||
|
if (dev->dev_req.value != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
usb_lld_set_configuration (dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
/* Do nothing when current_conf == value */
|
||||||
}
|
return usb_lld_ctrl_ack (dev);
|
||||||
|
|
||||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
|
||||||
{
|
|
||||||
(void)cmd; (void)detail;
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -327,6 +333,31 @@ static void wait (int count)
|
|||||||
|
|
||||||
#define WAIT 2400000
|
#define WAIT 2400000
|
||||||
|
|
||||||
|
/* NVIC: Nested Vectored Interrupt Controller. */
|
||||||
|
struct NVIC {
|
||||||
|
volatile uint32_t ISER[8];
|
||||||
|
uint32_t unused1[24];
|
||||||
|
volatile uint32_t ICER[8];
|
||||||
|
uint32_t unused2[24];
|
||||||
|
volatile uint32_t ISPR[8];
|
||||||
|
uint32_t unused3[24];
|
||||||
|
volatile uint32_t ICPR[8];
|
||||||
|
uint32_t unused4[24];
|
||||||
|
volatile uint32_t IABR[8];
|
||||||
|
uint32_t unused5[56];
|
||||||
|
volatile uint32_t IPR[60];
|
||||||
|
};
|
||||||
|
static struct NVIC *const NVIC = (struct NVIC *const)0xE000E100;
|
||||||
|
#define NVIC_ISER(n) (NVIC->ISER[n >> 5])
|
||||||
|
|
||||||
|
static void nvic_enable_intr (uint8_t irq_num)
|
||||||
|
{
|
||||||
|
NVIC_ISER (irq_num) = 1 << (irq_num & 0x1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define USB_LP_CAN1_RX0_IRQn 20
|
||||||
|
static struct usb_dev dev;
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -335,7 +366,14 @@ main (int argc, char *argv[])
|
|||||||
set_led (0);
|
set_led (0);
|
||||||
|
|
||||||
flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
|
flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
|
||||||
usb_lld_init (regnual_config_desc[7]);
|
|
||||||
|
/*
|
||||||
|
* NVIC interrupt priority was set by Gnuk.
|
||||||
|
* USB interrupt is disabled by NVIC setting.
|
||||||
|
* We enable the interrupt again by nvic_enable_intr.
|
||||||
|
*/
|
||||||
|
usb_lld_init (&dev, REGNUAL_FEATURE_INIT);
|
||||||
|
nvic_enable_intr (USB_LP_CAN1_RX0_IRQn);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -345,3 +383,69 @@ main (int argc, char *argv[])
|
|||||||
wait (WAIT);
|
wait (WAIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
usb_interrupt_handler (void)
|
||||||
|
{
|
||||||
|
uint8_t ep_num;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
e = usb_lld_event_handler (&dev);
|
||||||
|
ep_num = USB_EVENT_ENDP (e);
|
||||||
|
|
||||||
|
if (ep_num == 0)
|
||||||
|
switch (USB_EVENT_ID (e))
|
||||||
|
{
|
||||||
|
case USB_EVENT_DEVICE_RESET:
|
||||||
|
usb_device_reset (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_DEVICE_ADDRESSED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_GET_DESCRIPTOR:
|
||||||
|
if (usb_get_descriptor (&dev) < 0)
|
||||||
|
usb_lld_ctrl_error (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_SET_CONFIGURATION:
|
||||||
|
if (usb_set_configuration (&dev) < 0)
|
||||||
|
usb_lld_ctrl_error (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_SET_INTERFACE:
|
||||||
|
usb_lld_ctrl_error (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_CTRL_REQUEST:
|
||||||
|
/* Device specific device request. */
|
||||||
|
if (usb_setup (&dev) < 0)
|
||||||
|
usb_lld_ctrl_error (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_GET_STATUS_INTERFACE:
|
||||||
|
usb_lld_ctrl_error (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_GET_INTERFACE:
|
||||||
|
usb_lld_ctrl_error (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_SET_FEATURE_DEVICE:
|
||||||
|
case USB_EVENT_SET_FEATURE_ENDPOINT:
|
||||||
|
case USB_EVENT_CLEAR_FEATURE_DEVICE:
|
||||||
|
case USB_EVENT_CLEAR_FEATURE_ENDPOINT:
|
||||||
|
usb_lld_ctrl_ack (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_CTRL_WRITE_FINISH:
|
||||||
|
/* Control WRITE transfer finished. */
|
||||||
|
usb_ctrl_write_finish (&dev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_EVENT_OK:
|
||||||
|
case USB_EVENT_DEVICE_SUSPEND:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,15 +8,14 @@ CHOPSTX = ../chopstx
|
|||||||
# Define linker script file here
|
# Define linker script file here
|
||||||
LDSCRIPT= gnuk.ld
|
LDSCRIPT= gnuk.ld
|
||||||
|
|
||||||
CSRC = main.c usb_stm32f103.c adc_stm32f103.c \
|
CSRC = main.c usb_desc.c usb_ctrl.c \
|
||||||
usb_desc.c usb_ctrl.c \
|
|
||||||
call-rsa.c \
|
call-rsa.c \
|
||||||
usb-icc.c openpgp.c ac.c openpgp-do.c flash.c \
|
usb-ccid.c openpgp.c ac.c openpgp-do.c flash.c \
|
||||||
bn.c mod.c \
|
bn.c mod.c \
|
||||||
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.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 \
|
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||||
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
|
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
|
||||||
random.c neug.c sha256.c sys.c
|
random.c neug.c sha256.c
|
||||||
|
|
||||||
INCDIR =
|
INCDIR =
|
||||||
|
|
||||||
@@ -46,6 +45,11 @@ ifeq ($(ENABLE_PINPAD),dnd)
|
|||||||
CSRC += usb-msc.c
|
CSRC += usb-msc.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CHIP=stm32f103
|
||||||
|
USE_SYS = yes
|
||||||
|
USE_USB = yes
|
||||||
|
USE_ADC = yes
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
CROSS = arm-none-eabi-
|
CROSS = arm-none-eabi-
|
||||||
CC = $(CROSS)gcc
|
CC = $(CROSS)gcc
|
||||||
@@ -55,7 +59,7 @@ OBJCOPY = $(CROSS)objcopy
|
|||||||
MCU = cortex-m3
|
MCU = cortex-m3
|
||||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||||
# DEFS: Add
|
# DEFS: Add
|
||||||
DEFS = @HAVE_SYS_H@
|
DEFS = @USE_SYS3@
|
||||||
OPT = -O3 -Os -g
|
OPT = -O3 -Os -g
|
||||||
LIBS =
|
LIBS =
|
||||||
|
|
||||||
|
|||||||
16
src/adc.h
16
src/adc.h
@@ -1,16 +0,0 @@
|
|||||||
extern chopstx_mutex_t adc_mtx;
|
|
||||||
extern chopstx_cond_t adc_cond;
|
|
||||||
extern int adc_waiting;
|
|
||||||
extern int adc_data_available;
|
|
||||||
|
|
||||||
void adc_init (void);
|
|
||||||
void adc_start (void);
|
|
||||||
void adc_stop (void);
|
|
||||||
|
|
||||||
#define ADC_SAMPLE_MODE 0
|
|
||||||
#define ADC_CRC32_MODE 1
|
|
||||||
|
|
||||||
extern uint32_t adc_buf[64];
|
|
||||||
|
|
||||||
void adc_start_conversion (int offset, int count);
|
|
||||||
int adc_wait_completion (chopstx_intr_t *intr);
|
|
||||||
@@ -1,319 +0,0 @@
|
|||||||
/*
|
|
||||||
* adc_stm32f103.c - ADC driver for STM32F103
|
|
||||||
* 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, 2015
|
|
||||||
* Free Software Initiative of Japan
|
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
|
||||||
*
|
|
||||||
* This file is a part of NeuG, a True Random Number Generator
|
|
||||||
* implementation based on quantization error of ADC (for STM32F103).
|
|
||||||
*
|
|
||||||
* NeuG 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.
|
|
||||||
*
|
|
||||||
* NeuG 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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <chopstx.h>
|
|
||||||
|
|
||||||
#include "neug.h"
|
|
||||||
#include "stm32f103.h"
|
|
||||||
#include "adc.h"
|
|
||||||
|
|
||||||
#define NEUG_CRC32_COUNTS 4
|
|
||||||
|
|
||||||
#define STM32_ADC_ADC1_DMA_PRIORITY 2
|
|
||||||
|
|
||||||
#define ADC_SMPR1_SMP_VREF(n) ((n) << 21)
|
|
||||||
#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18)
|
|
||||||
|
|
||||||
#define ADC_SMPR1_SMP_AN10(n) ((n) << 0)
|
|
||||||
#define ADC_SMPR1_SMP_AN11(n) ((n) << 3)
|
|
||||||
|
|
||||||
#define ADC_SMPR2_SMP_AN0(n) ((n) << 0)
|
|
||||||
#define ADC_SMPR2_SMP_AN1(n) ((n) << 3)
|
|
||||||
#define ADC_SMPR2_SMP_AN2(n) ((n) << 6)
|
|
||||||
#define ADC_SMPR2_SMP_AN9(n) ((n) << 27)
|
|
||||||
|
|
||||||
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
|
|
||||||
|
|
||||||
#define ADC_SQR3_SQ1_N(n) ((n) << 0)
|
|
||||||
#define ADC_SQR3_SQ2_N(n) ((n) << 5)
|
|
||||||
#define ADC_SQR3_SQ3_N(n) ((n) << 10)
|
|
||||||
#define ADC_SQR3_SQ4_N(n) ((n) << 15)
|
|
||||||
|
|
||||||
#define ADC_SAMPLE_1P5 0
|
|
||||||
|
|
||||||
#define ADC_CHANNEL_IN0 0
|
|
||||||
#define ADC_CHANNEL_IN1 1
|
|
||||||
#define ADC_CHANNEL_IN2 2
|
|
||||||
#define ADC_CHANNEL_IN9 9
|
|
||||||
#define ADC_CHANNEL_IN10 10
|
|
||||||
#define ADC_CHANNEL_IN11 11
|
|
||||||
#define ADC_CHANNEL_SENSOR 16
|
|
||||||
#define ADC_CHANNEL_VREFINT 17
|
|
||||||
|
|
||||||
#define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
|
|
||||||
#define DELIBARATELY_DO_IT_WRONG_START_STOP
|
|
||||||
|
|
||||||
#ifdef DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
|
|
||||||
#define ADC_SAMPLE_VREF ADC_SAMPLE_1P5
|
|
||||||
#define ADC_SAMPLE_SENSOR ADC_SAMPLE_1P5
|
|
||||||
#else
|
|
||||||
#define ADC_SAMPLE_VREF ADC_SAMPLE_239P5
|
|
||||||
#define ADC_SAMPLE_SENSOR ADC_SAMPLE_239P5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
|
|
||||||
#define NEUG_DMA_MODE \
|
|
||||||
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
|
|
||||||
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
|
|
||||||
| STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE \
|
|
||||||
| STM32_DMA_CR_TEIE )
|
|
||||||
|
|
||||||
#define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
|
|
||||||
| ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
|
|
||||||
#define NEUG_ADC_SETTING1_SMPR2 0
|
|
||||||
#define NEUG_ADC_SETTING1_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT) \
|
|
||||||
| ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR) \
|
|
||||||
| ADC_SQR3_SQ3_N(ADC_CHANNEL_SENSOR) \
|
|
||||||
| ADC_SQR3_SQ4_N(ADC_CHANNEL_VREFINT)
|
|
||||||
#define NEUG_ADC_SETTING1_NUM_CHANNELS 4
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do calibration for both of ADCs.
|
|
||||||
*/
|
|
||||||
void adc_init (void)
|
|
||||||
{
|
|
||||||
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
|
||||||
RCC->APB2RSTR = (RCC_APB2RSTR_ADC1RST | RCC_APB2RSTR_ADC2RST);
|
|
||||||
RCC->APB2RSTR = 0;
|
|
||||||
|
|
||||||
ADC1->CR1 = 0;
|
|
||||||
ADC1->CR2 = ADC_CR2_ADON;
|
|
||||||
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
|
||||||
while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
|
|
||||||
;
|
|
||||||
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
|
|
||||||
while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
|
|
||||||
;
|
|
||||||
ADC1->CR2 = 0;
|
|
||||||
|
|
||||||
ADC2->CR1 = 0;
|
|
||||||
ADC2->CR2 = ADC_CR2_ADON;
|
|
||||||
ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
|
||||||
while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0)
|
|
||||||
;
|
|
||||||
ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
|
|
||||||
while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
|
|
||||||
;
|
|
||||||
ADC2->CR2 = 0;
|
|
||||||
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:
|
|
||||||
case BOARD_ID_NITROKEY_START:
|
|
||||||
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;
|
|
||||||
DMA1->IFCR = 0xffffffff;
|
|
||||||
|
|
||||||
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
|
||||||
|
|
||||||
ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
|
|
||||||
| ADC_CR1_SCAN);
|
|
||||||
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
|
||||||
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
|
||||||
ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
|
|
||||||
ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
|
|
||||||
ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
|
|
||||||
ADC1->SQR2 = 0;
|
|
||||||
ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;
|
|
||||||
|
|
||||||
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 = config[0];
|
|
||||||
ADC2->SMPR2 = config[1];
|
|
||||||
ADC2->SQR1 = config[2];
|
|
||||||
ADC2->SQR2 = 0;
|
|
||||||
ADC2->SQR3 = config[3];
|
|
||||||
|
|
||||||
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
|
|
||||||
/*
|
|
||||||
* We could just let ADC run continuously always and only enable DMA
|
|
||||||
* to receive stable data from ADC. But our purpose is not to get
|
|
||||||
* correct data but noise. In fact, we can get more noise when we
|
|
||||||
* start/stop ADC each time.
|
|
||||||
*/
|
|
||||||
ADC2->CR2 = 0;
|
|
||||||
ADC1->CR2 = 0;
|
|
||||||
#else
|
|
||||||
/* Start conversion. */
|
|
||||||
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
|
|
||||||
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
|
||||||
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t adc_buf[64];
|
|
||||||
|
|
||||||
void adc_start_conversion (int offset, int count)
|
|
||||||
{
|
|
||||||
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
|
|
||||||
DMA1_Channel1->CMAR = (uint32_t)&adc_buf[offset]; /* SetMemory0 */
|
|
||||||
DMA1_Channel1->CNDTR = count; /* Counter */
|
|
||||||
DMA1_Channel1->CCR = NEUG_DMA_MODE | DMA_CCR1_EN; /* Mode */
|
|
||||||
|
|
||||||
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
|
|
||||||
/* Power on */
|
|
||||||
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
|
|
||||||
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
|
||||||
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
|
||||||
/*
|
|
||||||
* Start conversion. tSTAB is 1uS, but we don't follow the spec, to
|
|
||||||
* get more noise.
|
|
||||||
*/
|
|
||||||
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
|
|
||||||
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
|
|
||||||
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void adc_stop_conversion (void)
|
|
||||||
{
|
|
||||||
DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
|
|
||||||
|
|
||||||
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
|
|
||||||
ADC2->CR2 = 0;
|
|
||||||
ADC1->CR2 = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void adc_stop (void)
|
|
||||||
{
|
|
||||||
ADC1->CR1 = 0;
|
|
||||||
ADC1->CR2 = 0;
|
|
||||||
|
|
||||||
ADC2->CR1 = 0;
|
|
||||||
ADC2->CR2 = 0;
|
|
||||||
|
|
||||||
RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
|
|
||||||
RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t adc_err;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return 0 on success.
|
|
||||||
* Return 1 on error.
|
|
||||||
*/
|
|
||||||
int adc_wait_completion (chopstx_intr_t *intr)
|
|
||||||
{
|
|
||||||
uint32_t flags;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
chopstx_intr_wait (intr);
|
|
||||||
flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */
|
|
||||||
/*
|
|
||||||
* Clear interrupt cause of channel 1.
|
|
||||||
*
|
|
||||||
* Note that CGIFx=0, as CGIFx=1 clears all of GIF, HTIF, TCIF
|
|
||||||
* and TEIF.
|
|
||||||
*/
|
|
||||||
DMA1->IFCR = (flags & ~1);
|
|
||||||
|
|
||||||
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
|
|
||||||
{
|
|
||||||
/* Should never happened. If any, it's coding error. */
|
|
||||||
/* Access an unmapped address space or alignment violation. */
|
|
||||||
adc_err++;
|
|
||||||
adc_stop_conversion ();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
|
|
||||||
{
|
|
||||||
adc_stop_conversion ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
48
src/configure
vendored
48
src/configure
vendored
@@ -6,7 +6,7 @@ nl=$'\n'
|
|||||||
#
|
#
|
||||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||||
#
|
#
|
||||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
|
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||||
# Free Software Initiative of Japan
|
# Free Software Initiative of Japan
|
||||||
#
|
#
|
||||||
# This file is a part of Gnuk, a GnuPG USB Token implementation.
|
# This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
@@ -23,6 +23,15 @@ nl=$'\n'
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Submodule check
|
||||||
|
#
|
||||||
|
if ! test -f ../chopstx/rules.mk; then
|
||||||
|
echo "Submodule 'chopstx' not found" >&2
|
||||||
|
echo "You might need: git submodule update --init" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Default settings
|
# Default settings
|
||||||
help=no
|
help=no
|
||||||
vidpid=none
|
vidpid=none
|
||||||
@@ -127,7 +136,7 @@ EOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$vidpid" = "none"; then
|
if test "$vidpid" = "none"; then
|
||||||
echo "Please specify Vendor ID and Product ID by --vidpid option."
|
echo "Please specify Vendor ID and Product ID by --vidpid option." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -181,7 +190,7 @@ fi
|
|||||||
# --with-dfu option
|
# --with-dfu option
|
||||||
if test "$with_dfu" = "yes"; then
|
if test "$with_dfu" = "yes"; then
|
||||||
if test "$target" = "FST_01" -o "$target" = "FST_01_00"; then
|
if test "$target" = "FST_01" -o "$target" = "FST_01_00"; then
|
||||||
echo "FST-01 doesn't have DFU loader, you should not use --with-dfu."
|
echo "FST-01 doesn't have DFU loader, you should not use --with-dfu." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "Configured for DFU"
|
echo "Configured for DFU"
|
||||||
@@ -247,7 +256,7 @@ if test "$sys1_compat" = "yes"; then
|
|||||||
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo"
|
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo"
|
||||||
else
|
else
|
||||||
if test "$with_dfu" = "yes"; then
|
if test "$with_dfu" = "yes"; then
|
||||||
echo "Common binary can't support DFU loader, don't use --with-dfu."
|
echo "Common binary can't support DFU loader, don't use --with-dfu." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# Override settings for common binary. Safer side.
|
# Override settings for common binary. Safer side.
|
||||||
@@ -267,23 +276,23 @@ output_vendor_product_serial_strings () {
|
|||||||
|
|
||||||
echo "static const uint8_t ${prefix}string_vendor[] = {"
|
echo "static const uint8_t ${prefix}string_vendor[] = {"
|
||||||
echo " ${#VENDOR}*2+2, /* bLength */"
|
echo " ${#VENDOR}*2+2, /* bLength */"
|
||||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||||
echo " /* Manufacturer: \"$VENDOR\" */"
|
echo " /* Manufacturer: \"$VENDOR\" */"
|
||||||
echo $VENDOR | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
echo $VENDOR | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||||
echo '};'
|
echo '};'
|
||||||
echo
|
echo
|
||||||
echo "static const uint8_t ${prefix}string_product[] = {"
|
echo "static const uint8_t ${prefix}string_product[] = {"
|
||||||
echo " ${#PRODUCT}*2+2, /* bLength */"
|
echo " ${#PRODUCT}*2+2, /* bLength */"
|
||||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||||
echo " /* Product name: \"$PRODUCT\" */"
|
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 $PRODUCT | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||||
echo '};'
|
echo '};'
|
||||||
|
|
||||||
if test -n "$prefix"; then
|
if test -n "$prefix"; then
|
||||||
echo
|
echo
|
||||||
echo "uint8_t ${prefix}string_serial[] = {"
|
echo "const uint8_t ${prefix}string_serial[] = {"
|
||||||
echo " ${#SERIALNO}*2+2+16, /* bLength */"
|
echo " ${#SERIALNO}*2+2+16, /* bLength */"
|
||||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||||
echo " /* Serial number: \"$SERIALNO\" */"
|
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 $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,"
|
||||||
@@ -293,14 +302,14 @@ output_vendor_product_serial_strings () {
|
|||||||
echo '#ifdef USB_STRINGS_FOR_GNUK'
|
echo '#ifdef USB_STRINGS_FOR_GNUK'
|
||||||
echo "static const uint8_t ${prefix}revision_detail[] = {"
|
echo "static const uint8_t ${prefix}revision_detail[] = {"
|
||||||
echo " ${#REVISION}*2+2, /* bLength */"
|
echo " ${#REVISION}*2+2, /* bLength */"
|
||||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||||
echo " /* revision detail: \"$REVISION\" */"
|
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 $REVISION | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||||
echo '};'
|
echo '};'
|
||||||
echo
|
echo
|
||||||
echo "static const uint8_t ${prefix}config_options[] = {"
|
echo "static const uint8_t ${prefix}config_options[] = {"
|
||||||
echo " ${#CONFIG}*2+2, /* bLength */"
|
echo " ${#CONFIG}*2+2, /* bLength */"
|
||||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||||
echo " /* configure options: \"$CONFIG\" */"
|
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 $CONFIG | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||||
echo '};'
|
echo '};'
|
||||||
@@ -317,23 +326,24 @@ if !(IFS=" "
|
|||||||
fi
|
fi
|
||||||
done; exit 1) < ../GNUK_USB_DEVICE_ID
|
done; exit 1) < ../GNUK_USB_DEVICE_ID
|
||||||
then
|
then
|
||||||
echo "Please specify valid Vendor ID and Product ID."
|
echo "Please specify valid Vendor ID and Product ID." >&2
|
||||||
echo "Check ../GNUK_USB_DEVICE_ID."
|
echo "Check ../GNUK_USB_DEVICE_ID." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$sys1_compat" = "no"; then
|
if test "$sys1_compat" = "no"; then
|
||||||
# Disable when you are sure that it's sys version 2.1.
|
# Disable when you are sure that it's sys version 3.0 or later.
|
||||||
# Note that Gnuk 1.0 and NeuG (until 0.06) uses sys version 1.0.
|
# Note that Gnuk 1.0 and NeuG (until 0.06) uses sys version 1.0.
|
||||||
# Disabling the compatibility, executable will be target independent,
|
# Disabling the compatibility, executable will be target independent,
|
||||||
# assuming the clock initialization will be done by SYS (before entry).
|
# assuming the clock initialization will be done by clock_init in
|
||||||
have_sys_h="-DHAVE_SYS_H"
|
# SYS.
|
||||||
|
use_sys3="-DUSE_SYS3"
|
||||||
else
|
else
|
||||||
have_sys_h=""
|
use_sys3=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
sed -e "s%@HAVE_SYS_H@%$have_sys_h%" \
|
sed -e "s%@USE_SYS3@%$use_sys3%" \
|
||||||
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
|
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
|
||||||
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
|
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
|
||||||
-e "s%@HEXOUTPUT_MAKE_OPTION@%$HEXOUTPUT_MAKE_OPTION%" \
|
-e "s%@HEXOUTPUT_MAKE_OPTION@%$HEXOUTPUT_MAKE_OPTION%" \
|
||||||
|
|||||||
43
src/gnuk.h
43
src/gnuk.h
@@ -12,8 +12,8 @@ struct apdu {
|
|||||||
|
|
||||||
/* response APDU */
|
/* response APDU */
|
||||||
uint16_t sw;
|
uint16_t sw;
|
||||||
uint8_t *res_apdu_data;
|
|
||||||
uint16_t res_apdu_data_len;
|
uint16_t res_apdu_data_len;
|
||||||
|
uint8_t *res_apdu_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct apdu apdu;
|
extern struct apdu apdu;
|
||||||
@@ -22,14 +22,15 @@ extern struct apdu apdu;
|
|||||||
#define CARD_CHANGE_REMOVE 1
|
#define CARD_CHANGE_REMOVE 1
|
||||||
#define CARD_CHANGE_TOGGLE 2
|
#define CARD_CHANGE_TOGGLE 2
|
||||||
void ccid_card_change_signal (int how);
|
void ccid_card_change_signal (int how);
|
||||||
void ccid_usb_reset (void);
|
void ccid_usb_reset (int);
|
||||||
|
|
||||||
/* CCID thread */
|
/* CCID thread */
|
||||||
#define EV_RX_DATA_READY 1 /* USB Rx data available */
|
#define EV_RX_DATA_READY 1 /* USB Rx data available */
|
||||||
#define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */
|
#define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */
|
||||||
#define EV_TX_FINISHED 4 /* CCID Tx finished */
|
#define EV_TX_FINISHED 4 /* CCID Tx finished */
|
||||||
#define EV_CARD_CHANGE 8
|
#define EV_CARD_CHANGE 8
|
||||||
#define EV_USB_RESET 16
|
#define EV_USB_SET_INTERFACE 16
|
||||||
|
#define EV_USB_DEVICE_RESET 32
|
||||||
|
|
||||||
/* OpenPGPcard thread */
|
/* OpenPGPcard thread */
|
||||||
#define EV_PINPAD_INPUT_DONE 1
|
#define EV_PINPAD_INPUT_DONE 1
|
||||||
@@ -43,7 +44,7 @@ void ccid_usb_reset (void);
|
|||||||
/* Maximum res apdu data is public key 5+9+512 (gpg_do_public_key) */
|
/* Maximum res apdu data is public key 5+9+512 (gpg_do_public_key) */
|
||||||
#define MAX_RES_APDU_DATA_SIZE (5+9+512) /* without trailer */
|
#define MAX_RES_APDU_DATA_SIZE (5+9+512) /* without trailer */
|
||||||
|
|
||||||
#define ICC_MSG_HEADER_SIZE 10
|
#define CCID_MSG_HEADER_SIZE 10
|
||||||
|
|
||||||
#define res_APDU apdu.res_apdu_data
|
#define res_APDU apdu.res_apdu_data
|
||||||
#define res_APDU_size apdu.res_apdu_data_len
|
#define res_APDU_size apdu.res_apdu_data_len
|
||||||
@@ -51,22 +52,21 @@ void ccid_usb_reset (void);
|
|||||||
/* USB buffer size of LL (Low-level): size of single Bulk transaction */
|
/* USB buffer size of LL (Low-level): size of single Bulk transaction */
|
||||||
#define USB_LL_BUF_SIZE 64
|
#define USB_LL_BUF_SIZE 64
|
||||||
|
|
||||||
enum icc_state {
|
enum ccid_state {
|
||||||
ICC_STATE_NOCARD, /* No card available */
|
CCID_STATE_NOCARD, /* No card available */
|
||||||
ICC_STATE_START, /* Initial */
|
CCID_STATE_START, /* Initial */
|
||||||
ICC_STATE_WAIT, /* Waiting APDU */
|
CCID_STATE_WAIT, /* Waiting APDU */
|
||||||
/* Busy1, Busy2, Busy3, Busy5 */
|
/* Busy1, Busy2, Busy3, Busy5 */
|
||||||
ICC_STATE_EXECUTE, /* Busy4 */
|
CCID_STATE_EXECUTE, /* Busy4 */
|
||||||
ICC_STATE_RECEIVE, /* APDU Received Partially */
|
CCID_STATE_RECEIVE, /* APDU Received Partially */
|
||||||
ICC_STATE_SEND, /* APDU Sent Partially */
|
CCID_STATE_SEND, /* APDU Sent Partially */
|
||||||
|
|
||||||
ICC_STATE_EXITED, /* ICC Thread Terminated */
|
CCID_STATE_EXITED, /* ICC Thread Terminated */
|
||||||
ICC_STATE_EXEC_REQUESTED, /* Exec requested */
|
CCID_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CCID_CARD_INIT CARD_CHANGE_INSERT
|
|
||||||
|
|
||||||
extern enum icc_state *icc_state_p;
|
extern enum ccid_state *const ccid_state_p;
|
||||||
|
|
||||||
extern volatile uint8_t auth_status;
|
extern volatile uint8_t auth_status;
|
||||||
#define AC_NONE_AUTHORIZED 0x00
|
#define AC_NONE_AUTHORIZED 0x00
|
||||||
@@ -233,6 +233,7 @@ int gpg_change_keystring (int who_old, const uint8_t *old_ks,
|
|||||||
extern struct key_data kd[3];
|
extern struct key_data kd[3];
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
void stdout_init (void);
|
||||||
#define DEBUG_MORE 1
|
#define DEBUG_MORE 1
|
||||||
/*
|
/*
|
||||||
* Debug functions in debug.c
|
* Debug functions in debug.c
|
||||||
@@ -421,11 +422,11 @@ extern const uint8_t gnuk_string_serial[];
|
|||||||
#define LED_ONESHOT 1
|
#define LED_ONESHOT 1
|
||||||
#define LED_TWOSHOTS 2
|
#define LED_TWOSHOTS 2
|
||||||
#define LED_SHOW_STATUS 4
|
#define LED_SHOW_STATUS 4
|
||||||
#define LED_START_COMMAND 8
|
#define LED_FATAL 8
|
||||||
#define LED_FINISH_COMMAND 16
|
#define LED_SYNC 16
|
||||||
#define LED_FATAL 32
|
#define LED_GNUK_EXEC 32
|
||||||
#define LED_USB_RESET 64
|
#define LED_START_COMMAND 64
|
||||||
#define LED_GNUK_EXEC 128
|
#define LED_FINISH_COMMAND 128
|
||||||
void led_blink (int spec);
|
void led_blink (int spec);
|
||||||
|
|
||||||
#if defined(PINPAD_SUPPORT)
|
#if defined(PINPAD_SUPPORT)
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
*/
|
*/
|
||||||
__main_stack_size__ = 0x0080; /* Exception handlers */
|
__main_stack_size__ = 0x0080; /* Exception handlers */
|
||||||
__process0_stack_size__ = 0x0100; /* main */
|
__process0_stack_size__ = 0x0100; /* main */
|
||||||
__process1_stack_size__ = 0x0120; /* ccid */
|
__process1_stack_size__ = 0x0180; /* ccid */
|
||||||
__process2_stack_size__ = 0x01a0; /* rng */
|
__process2_stack_size__ = 0x0180; /* rng */
|
||||||
__process3_stack_size__ = 0x1640; /* gpg */
|
__process3_stack_size__ = 0x1640; /* gpg */
|
||||||
__process4_stack_size__ = 0x0120; /* intr: usb */
|
__process4_stack_size__ = 0; /* --- */
|
||||||
__process5_stack_size__ = @MSC_SIZE@; /* msc */
|
__process5_stack_size__ = @MSC_SIZE@; /* msc */
|
||||||
__process6_stack_size__ = @TIM_SIZE@; /* intr: timer */
|
__process6_stack_size__ = @TIM_SIZE@; /* intr: timer */
|
||||||
__process7_stack_size__ = @EXT_SIZE@; /* intr: ext */
|
__process7_stack_size__ = @EXT_SIZE@; /* intr: ext */
|
||||||
@@ -34,10 +34,10 @@ SECTIONS
|
|||||||
KEEP(*(.sys.version))
|
KEEP(*(.sys.version))
|
||||||
KEEP(*(.sys.board_id))
|
KEEP(*(.sys.board_id))
|
||||||
KEEP(*(.sys.board_name))
|
KEEP(*(.sys.board_name))
|
||||||
build/sys.o(.text)
|
build/sys-*.o(.text)
|
||||||
build/sys.o(.text.*)
|
build/sys-*.o(.text.*)
|
||||||
build/sys.o(.rodata)
|
build/sys-*.o(.rodata)
|
||||||
build/sys.o(.rodata.*)
|
build/sys-*.o(.rodata.*)
|
||||||
. = ALIGN(1024);
|
. = ALIGN(1024);
|
||||||
*(.sys.0)
|
*(.sys.0)
|
||||||
*(.sys.1)
|
*(.sys.1)
|
||||||
|
|||||||
220
src/main.c
220
src/main.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* main.c - main routine of Gnuk
|
* main.c - main routine of Gnuk
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015
|
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
|
||||||
* Free Software Initiative of Japan
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
@@ -35,87 +35,12 @@
|
|||||||
#include "usb_lld.h"
|
#include "usb_lld.h"
|
||||||
#include "usb-cdc.h"
|
#include "usb-cdc.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "stm32f103.h"
|
#include "mcu/stm32f103.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
struct stdout stdout;
|
|
||||||
|
|
||||||
static void
|
|
||||||
stdout_init (void)
|
|
||||||
{
|
|
||||||
chopstx_mutex_init (&stdout.m);
|
|
||||||
chopstx_mutex_init (&stdout.m_dev);
|
|
||||||
chopstx_cond_init (&stdout.cond_dev);
|
|
||||||
stdout.connected = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_write (const char *s, int len)
|
|
||||||
{
|
|
||||||
int packet_len;
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
chopstx_mutex_lock (&stdout.m);
|
|
||||||
|
|
||||||
chopstx_mutex_lock (&stdout.m_dev);
|
|
||||||
if (!stdout.connected)
|
|
||||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
|
||||||
chopstx_mutex_unlock (&stdout.m_dev);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
packet_len =
|
|
||||||
(len < VIRTUAL_COM_PORT_DATA_SIZE) ? len : VIRTUAL_COM_PORT_DATA_SIZE;
|
|
||||||
|
|
||||||
chopstx_mutex_lock (&stdout.m_dev);
|
|
||||||
usb_lld_write (ENDP3, s, packet_len);
|
|
||||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
|
||||||
chopstx_mutex_unlock (&stdout.m_dev);
|
|
||||||
|
|
||||||
s += packet_len;
|
|
||||||
len -= packet_len;
|
|
||||||
}
|
|
||||||
/* Send a Zero-Length-Packet if the last packet is full size. */
|
|
||||||
while (len != 0 || packet_len == VIRTUAL_COM_PORT_DATA_SIZE);
|
|
||||||
|
|
||||||
chopstx_mutex_unlock (&stdout.m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
EP3_IN_Callback (void)
|
|
||||||
{
|
|
||||||
chopstx_mutex_lock (&stdout.m_dev);
|
|
||||||
chopstx_cond_signal (&stdout.cond_dev);
|
|
||||||
chopstx_mutex_unlock (&stdout.m_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
EP5_OUT_Callback (void)
|
|
||||||
{
|
|
||||||
chopstx_mutex_lock (&stdout.m_dev);
|
|
||||||
usb_lld_rx_enable (ENDP5);
|
|
||||||
chopstx_mutex_unlock (&stdout.m_dev);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
_write (const char *s, int size)
|
|
||||||
{
|
|
||||||
(void)s;
|
|
||||||
(void)size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void *USBthread (void *arg);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main thread does 1-bit LED display output
|
* main thread does 1-bit LED display output
|
||||||
*/
|
*/
|
||||||
#define MAIN_TIMEOUT_INTERVAL (5000*1000)
|
|
||||||
|
|
||||||
#define LED_TIMEOUT_INTERVAL (75*1000)
|
#define LED_TIMEOUT_INTERVAL (75*1000)
|
||||||
#define LED_TIMEOUT_ZERO (25*1000)
|
#define LED_TIMEOUT_ZERO (25*1000)
|
||||||
#define LED_TIMEOUT_ONE (100*1000)
|
#define LED_TIMEOUT_ONE (100*1000)
|
||||||
@@ -195,65 +120,50 @@ static void display_fatal_code (void)
|
|||||||
|
|
||||||
static uint8_t led_inverted;
|
static uint8_t led_inverted;
|
||||||
|
|
||||||
static eventmask_t emit_led (int on_time, int off_time)
|
static void emit_led (int on_time, int off_time)
|
||||||
{
|
{
|
||||||
eventmask_t m;
|
|
||||||
|
|
||||||
set_led (!led_inverted);
|
set_led (!led_inverted);
|
||||||
m = eventflag_wait_timeout (&led_event, on_time);
|
chopstx_usec_wait (on_time);
|
||||||
set_led (led_inverted);
|
set_led (led_inverted);
|
||||||
if (m) return m;
|
chopstx_usec_wait (off_time);
|
||||||
if ((m = eventflag_wait_timeout (&led_event, off_time)))
|
|
||||||
return m;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static eventmask_t display_status_code (void)
|
static void display_status_code (void)
|
||||||
{
|
{
|
||||||
eventmask_t m;
|
enum ccid_state ccid_state = *ccid_state_p;
|
||||||
enum icc_state icc_state = *icc_state_p;
|
|
||||||
|
|
||||||
if (icc_state == ICC_STATE_START)
|
if (ccid_state == CCID_STATE_START)
|
||||||
return emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
||||||
else
|
else
|
||||||
/* OpenPGP card thread running */
|
/* OpenPGP card thread is running */
|
||||||
{
|
{
|
||||||
if ((m = emit_led ((auth_status & AC_ADMIN_AUTHORIZED)?
|
emit_led ((auth_status & AC_ADMIN_AUTHORIZED)?
|
||||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||||
LED_TIMEOUT_INTERVAL)))
|
emit_led ((auth_status & AC_OTHER_AUTHORIZED)?
|
||||||
return m;
|
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||||
if ((m = emit_led ((auth_status & AC_OTHER_AUTHORIZED)?
|
emit_led ((auth_status & AC_PSO_CDS_AUTHORIZED)?
|
||||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||||
LED_TIMEOUT_INTERVAL)))
|
|
||||||
return m;
|
|
||||||
if ((m = emit_led ((auth_status & AC_PSO_CDS_AUTHORIZED)?
|
|
||||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
|
||||||
LED_TIMEOUT_INTERVAL)))
|
|
||||||
return m;
|
|
||||||
|
|
||||||
if (icc_state == ICC_STATE_WAIT)
|
if (ccid_state == CCID_STATE_WAIT)
|
||||||
{
|
chopstx_usec_wait (LED_TIMEOUT_STOP * 2);
|
||||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_STOP * 2)))
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_INTERVAL)))
|
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||||
return m;
|
emit_led (ccid_state == CCID_STATE_RECEIVE?
|
||||||
|
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||||
if ((m = emit_led (icc_state == ICC_STATE_RECEIVE?
|
|
||||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
|
||||||
LED_TIMEOUT_STOP)))
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
led_blink (int spec)
|
led_blink (int spec)
|
||||||
{
|
{
|
||||||
|
if (spec == LED_START_COMMAND || spec == LED_FINISH_COMMAND)
|
||||||
|
{
|
||||||
|
led_inverted = (spec == LED_START_COMMAND);
|
||||||
|
spec = LED_SYNC;
|
||||||
|
}
|
||||||
|
|
||||||
eventflag_signal (&led_event, spec);
|
eventflag_signal (&led_event, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,20 +184,14 @@ calculate_regnual_entry_address (const uint8_t *addr)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint8_t __process1_stack_base__, __process1_stack_size__;
|
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
|
||||||
extern uint8_t __process4_stack_base__, __process4_stack_size__;
|
#define STACK_ADDR_CCID ((uint32_t)__process1_stack_base__)
|
||||||
|
#define STACK_SIZE_CCID ((uint32_t)__process1_stack_size__)
|
||||||
const uint32_t __stackaddr_ccid = (uint32_t)&__process1_stack_base__;
|
|
||||||
const size_t __stacksize_ccid = (size_t)&__process1_stack_size__;
|
|
||||||
|
|
||||||
const uint32_t __stackaddr_usb = (uint32_t)&__process4_stack_base__;
|
|
||||||
const size_t __stacksize_usb = (size_t)&__process4_stack_size__;
|
|
||||||
|
|
||||||
#define PRIO_CCID 3
|
#define PRIO_CCID 3
|
||||||
#define PRIO_USB 4
|
|
||||||
#define PRIO_MAIN 5
|
#define PRIO_MAIN 5
|
||||||
|
|
||||||
extern void *usb_intr (void *arg);
|
extern void *ccid_thread (void *arg);
|
||||||
|
|
||||||
static void gnuk_malloc_init (void);
|
static void gnuk_malloc_init (void);
|
||||||
|
|
||||||
@@ -296,16 +200,11 @@ extern uint32_t bDeviceState;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point.
|
* Entry point.
|
||||||
*
|
|
||||||
* NOTE: the main function is already a thread in the system on entry.
|
|
||||||
* See the hwinit1_common function.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
|
||||||
uint32_t entry;
|
uint32_t entry;
|
||||||
chopstx_t usb_thd;
|
|
||||||
chopstx_t ccid_thd;
|
chopstx_t ccid_thd;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
@@ -318,7 +217,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
adc_init ();
|
adc_init ();
|
||||||
|
|
||||||
eventflag_init (&led_event, chopstx_main);
|
eventflag_init (&led_event);
|
||||||
|
|
||||||
random_init ();
|
random_init ();
|
||||||
|
|
||||||
@@ -326,8 +225,8 @@ main (int argc, char *argv[])
|
|||||||
stdout_init ();
|
stdout_init ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ccid_thd = chopstx_create (PRIO_CCID, __stackaddr_ccid, __stacksize_ccid,
|
ccid_thd = chopstx_create (PRIO_CCID, STACK_ADDR_CCID, STACK_SIZE_CCID,
|
||||||
USBthread, NULL);
|
ccid_thread, NULL);
|
||||||
|
|
||||||
#ifdef PINPAD_CIR_SUPPORT
|
#ifdef PINPAD_CIR_SUPPORT
|
||||||
cir_init ();
|
cir_init ();
|
||||||
@@ -336,10 +235,7 @@ main (int argc, char *argv[])
|
|||||||
msc_init ();
|
msc_init ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
usb_thd = chopstx_create (PRIO_USB, __stackaddr_usb, __stacksize_usb,
|
chopstx_setpriority (PRIO_MAIN);
|
||||||
usb_intr, NULL);
|
|
||||||
|
|
||||||
chopstx_main_init (PRIO_MAIN);
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -353,56 +249,31 @@ main (int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
eventmask_t m;
|
eventmask_t m;
|
||||||
|
|
||||||
m = eventflag_wait_timeout (&led_event, MAIN_TIMEOUT_INTERVAL);
|
m = eventflag_wait (&led_event);
|
||||||
got_it:
|
|
||||||
count++;
|
|
||||||
switch (m)
|
switch (m)
|
||||||
{
|
{
|
||||||
case LED_ONESHOT:
|
case LED_ONESHOT:
|
||||||
if ((m = emit_led (100*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
emit_led (100*1000, LED_TIMEOUT_STOP);
|
||||||
break;
|
break;
|
||||||
case LED_TWOSHOTS:
|
case LED_TWOSHOTS:
|
||||||
if ((m = emit_led (50*1000, 50*1000))) goto got_it;
|
emit_led (50*1000, 50*1000);
|
||||||
if ((m = emit_led (50*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
emit_led (50*1000, LED_TIMEOUT_STOP);
|
||||||
break;
|
break;
|
||||||
case LED_SHOW_STATUS:
|
case LED_SHOW_STATUS:
|
||||||
if ((count & 0x07) != 0) continue; /* Display once for eight times */
|
display_status_code ();
|
||||||
if ((m = display_status_code ())) goto got_it;
|
|
||||||
break;
|
|
||||||
case LED_START_COMMAND:
|
|
||||||
set_led (1);
|
|
||||||
led_inverted = 1;
|
|
||||||
break;
|
|
||||||
case LED_FINISH_COMMAND:
|
|
||||||
m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_STOP);
|
|
||||||
led_inverted = 0;
|
|
||||||
set_led (0);
|
|
||||||
if (m)
|
|
||||||
goto got_it;
|
|
||||||
break;
|
break;
|
||||||
case LED_FATAL:
|
case LED_FATAL:
|
||||||
display_fatal_code ();
|
display_fatal_code ();
|
||||||
break;
|
break;
|
||||||
case LED_USB_RESET:
|
case LED_SYNC:
|
||||||
ccid_usb_reset ();
|
set_led (led_inverted);
|
||||||
break;
|
break;
|
||||||
case LED_GNUK_EXEC:
|
case LED_GNUK_EXEC:
|
||||||
goto exec;
|
goto exec;
|
||||||
default:
|
default:
|
||||||
if ((m = emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP)))
|
emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||||
goto got_it;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_MORE
|
|
||||||
if (stdout.connected && (count % 10) == 0)
|
|
||||||
{
|
|
||||||
DEBUG_SHORT (count / 10);
|
|
||||||
_write ("\r\nThis is Gnuk on STM32F103.\r\n"
|
|
||||||
"Testing USB driver.\n\n"
|
|
||||||
"Hello world\r\n\r\n", 30+21+15);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exec:
|
exec:
|
||||||
@@ -414,9 +285,6 @@ main (int argc, char *argv[])
|
|||||||
/* Finish application. */
|
/* Finish application. */
|
||||||
chopstx_join (ccid_thd, NULL);
|
chopstx_join (ccid_thd, NULL);
|
||||||
|
|
||||||
chopstx_cancel (usb_thd);
|
|
||||||
chopstx_join (usb_thd, NULL);
|
|
||||||
|
|
||||||
/* Set vector */
|
/* Set vector */
|
||||||
SCB->VTOR = (uint32_t)&_regnual_start;
|
SCB->VTOR = (uint32_t)&_regnual_start;
|
||||||
entry = calculate_regnual_entry_address (&_regnual_start);
|
entry = calculate_regnual_entry_address (&_regnual_start);
|
||||||
@@ -458,6 +326,8 @@ main (int argc, char *argv[])
|
|||||||
void
|
void
|
||||||
fatal (uint8_t code)
|
fatal (uint8_t code)
|
||||||
{
|
{
|
||||||
|
extern void _write (const char *s, int len);
|
||||||
|
|
||||||
fatal_code = code;
|
fatal_code = code;
|
||||||
eventflag_signal (&led_event, LED_FATAL);
|
eventflag_signal (&led_event, LED_FATAL);
|
||||||
_write ("fatal\r\n", 7);
|
_write ("fatal\r\n", 7);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* modp256k1.c -- modulo arithmetic for p256k1
|
* modp256k1.c -- modulo arithmetic for p256k1
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
* Copyright (C) 2014, 2016 Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
@@ -55,12 +55,12 @@ const bn256 p256k1 = { {0xfffffc2f, 0xfffffffe, 0xffffffff, 0xffffffff,
|
|||||||
/*
|
/*
|
||||||
* Implementation Note.
|
* Implementation Note.
|
||||||
*
|
*
|
||||||
* It's not always modulo p256k1. The representation is redundant
|
* It's always modulo p256k1.
|
||||||
* during computation. For example, when we add the prime - 1 and 1,
|
*
|
||||||
* it won't overflow to 2^256, and the result is represented within
|
* Once, I tried redundant representation which caused wrong
|
||||||
* 256-bit.
|
* calculation. Implementation could be correct with redundant
|
||||||
|
* representation, but it found that it's more expensive.
|
||||||
*
|
*
|
||||||
* It is guaranteed that modp256k1_reduce reduces to modulo p256k1.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,14 +69,16 @@ const bn256 p256k1 = { {0xfffffc2f, 0xfffffffe, 0xffffffff, 0xffffffff,
|
|||||||
void
|
void
|
||||||
modp256k1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
modp256k1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||||
{
|
{
|
||||||
uint32_t carry;
|
uint32_t cond;
|
||||||
bn256 tmp[1];
|
bn256 tmp[1];
|
||||||
|
|
||||||
carry = bn256_add (X, A, B);
|
cond = (bn256_add (X, A, B) == 0);
|
||||||
if (carry)
|
cond &= bn256_sub (tmp, X, P256K1);
|
||||||
bn256_sub (X, X, P256K1);
|
if (cond)
|
||||||
|
/* No-carry AND borrow */
|
||||||
|
memcpy (tmp, tmp, sizeof (bn256));
|
||||||
else
|
else
|
||||||
bn256_sub (tmp, X, P256K1);
|
memcpy (X, tmp, sizeof (bn256));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,10 +91,11 @@ modp256k1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
|||||||
bn256 tmp[1];
|
bn256 tmp[1];
|
||||||
|
|
||||||
borrow = bn256_sub (X, A, B);
|
borrow = bn256_sub (X, A, B);
|
||||||
|
bn256_add (tmp, X, P256K1);
|
||||||
if (borrow)
|
if (borrow)
|
||||||
bn256_add (X, X, P256K1);
|
memcpy (X, tmp, sizeof (bn256));
|
||||||
else
|
else
|
||||||
bn256_add (tmp, X, P256K1);
|
memcpy (tmp, tmp, sizeof (bn256));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* modp256r1.c -- modulo arithmetic for p256r1
|
* modp256r1.c -- modulo arithmetic for p256r1
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011, 2013, 2014 Free Software Initiative of Japan
|
* Copyright (C) 2011, 2013, 2014, 2016
|
||||||
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
@@ -49,12 +50,12 @@ const bn256 p256r1 = { {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
|
|||||||
/*
|
/*
|
||||||
* Implementation Note.
|
* Implementation Note.
|
||||||
*
|
*
|
||||||
* It's not always modulo p256r1. The representation is redundant
|
* It's always modulo p256r1.
|
||||||
* during computation. For example, when we add the prime - 1 and 1,
|
*
|
||||||
* it won't overflow to 2^256, and the result is represented within
|
* Once, I tried redundant representation which caused wrong
|
||||||
* 256-bit.
|
* calculation. Implementation could be correct with redundant
|
||||||
|
* representation, but it found that it's more expensive.
|
||||||
*
|
*
|
||||||
* It is guaranteed that modp256r1_reduce reduces to modulo p256r1.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,14 +64,16 @@ const bn256 p256r1 = { {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
|
|||||||
void
|
void
|
||||||
modp256r1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
modp256r1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||||
{
|
{
|
||||||
uint32_t carry;
|
uint32_t cond;
|
||||||
bn256 tmp[1];
|
bn256 tmp[1];
|
||||||
|
|
||||||
carry = bn256_add (X, A, B);
|
cond = (bn256_add (X, A, B) == 0);
|
||||||
if (carry)
|
cond &= bn256_sub (tmp, X, P256R1);
|
||||||
bn256_sub (X, X, P256R1);
|
if (cond)
|
||||||
|
/* No-carry AND borrow */
|
||||||
|
memcpy (tmp, tmp, sizeof (bn256));
|
||||||
else
|
else
|
||||||
bn256_sub (tmp, X, P256R1);
|
memcpy (X, tmp, sizeof (bn256));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,10 +86,11 @@ modp256r1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
|||||||
bn256 tmp[1];
|
bn256 tmp[1];
|
||||||
|
|
||||||
borrow = bn256_sub (X, A, B);
|
borrow = bn256_sub (X, A, B);
|
||||||
|
bn256_add (tmp, X, P256R1);
|
||||||
if (borrow)
|
if (borrow)
|
||||||
bn256_add (X, X, P256R1);
|
memcpy (X, tmp, sizeof (bn256));
|
||||||
else
|
else
|
||||||
bn256_add (tmp, X, P256R1);
|
memcpy (tmp, tmp, sizeof (bn256));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,7 +99,7 @@ modp256r1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
|||||||
void
|
void
|
||||||
modp256r1_reduce (bn256 *X, const bn512 *A)
|
modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||||
{
|
{
|
||||||
bn256 tmp[1];
|
bn256 tmp[1], tmp0[1];
|
||||||
uint32_t borrow;
|
uint32_t borrow;
|
||||||
|
|
||||||
#define S1 X
|
#define S1 X
|
||||||
@@ -116,6 +120,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
|||||||
S1->word[2] = A->word[2];
|
S1->word[2] = A->word[2];
|
||||||
S1->word[1] = A->word[1];
|
S1->word[1] = A->word[1];
|
||||||
S1->word[0] = A->word[0];
|
S1->word[0] = A->word[0];
|
||||||
|
borrow = bn256_sub (tmp0, S1, P256R1);
|
||||||
|
if (borrow)
|
||||||
|
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||||
|
else
|
||||||
|
memcpy (S1, tmp0, sizeof (bn256));
|
||||||
/* X = S1 */
|
/* X = S1 */
|
||||||
|
|
||||||
S2->word[7] = A->word[15];
|
S2->word[7] = A->word[15];
|
||||||
@@ -155,6 +164,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
|||||||
S5->word[2] = A->word[11];
|
S5->word[2] = A->word[11];
|
||||||
S5->word[1] = A->word[10];
|
S5->word[1] = A->word[10];
|
||||||
S5->word[0] = A->word[9];
|
S5->word[0] = A->word[9];
|
||||||
|
borrow = bn256_sub (tmp0, S5, P256R1);
|
||||||
|
if (borrow)
|
||||||
|
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||||
|
else
|
||||||
|
memcpy (S5, tmp0, sizeof (bn256));
|
||||||
/* X += S5 */
|
/* X += S5 */
|
||||||
modp256r1_add (X, X, S5);
|
modp256r1_add (X, X, S5);
|
||||||
|
|
||||||
@@ -164,6 +178,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
|||||||
S6->word[2] = A->word[13];
|
S6->word[2] = A->word[13];
|
||||||
S6->word[1] = A->word[12];
|
S6->word[1] = A->word[12];
|
||||||
S6->word[0] = A->word[11];
|
S6->word[0] = A->word[11];
|
||||||
|
borrow = bn256_sub (tmp0, S6, P256R1);
|
||||||
|
if (borrow)
|
||||||
|
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||||
|
else
|
||||||
|
memcpy (S6, tmp0, sizeof (bn256));
|
||||||
/* X -= S6 */
|
/* X -= S6 */
|
||||||
modp256r1_sub (X, X, S6);
|
modp256r1_sub (X, X, S6);
|
||||||
|
|
||||||
@@ -174,6 +193,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
|||||||
S7->word[2] = A->word[14];
|
S7->word[2] = A->word[14];
|
||||||
S7->word[1] = A->word[13];
|
S7->word[1] = A->word[13];
|
||||||
S7->word[0] = A->word[12];
|
S7->word[0] = A->word[12];
|
||||||
|
borrow = bn256_sub (tmp0, S7, P256R1);
|
||||||
|
if (borrow)
|
||||||
|
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||||
|
else
|
||||||
|
memcpy (S7, tmp0, sizeof (bn256));
|
||||||
/* X -= S7 */
|
/* X -= S7 */
|
||||||
modp256r1_sub (X, X, S7);
|
modp256r1_sub (X, X, S7);
|
||||||
|
|
||||||
|
|||||||
24
src/neug.c
24
src/neug.c
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* neug.c - true random number generation
|
* neug.c - true random number generation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
|
* Copyright (C) 2011, 2012, 2013, 2016
|
||||||
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of NeuG, a True Random Number Generator
|
* This file is a part of NeuG, a True Random Number Generator
|
||||||
@@ -28,19 +29,13 @@
|
|||||||
|
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "neug.h"
|
#include "neug.h"
|
||||||
#include "stm32f103.h"
|
#include "mcu/stm32f103.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "sha256.h"
|
#include "sha256.h"
|
||||||
|
|
||||||
static chopstx_mutex_t mode_mtx;
|
static chopstx_mutex_t mode_mtx;
|
||||||
static chopstx_cond_t mode_cond;
|
static chopstx_cond_t mode_cond;
|
||||||
|
|
||||||
/*
|
|
||||||
* ADC finish interrupt
|
|
||||||
*/
|
|
||||||
#define INTR_REQ_DMA1_Channel1 11
|
|
||||||
|
|
||||||
|
|
||||||
static sha256_context sha256_ctx_data;
|
static sha256_context sha256_ctx_data;
|
||||||
static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
|
static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
|
||||||
|
|
||||||
@@ -574,7 +569,6 @@ static void *
|
|||||||
rng (void *arg)
|
rng (void *arg)
|
||||||
{
|
{
|
||||||
struct rng_rb *rb = (struct rng_rb *)arg;
|
struct rng_rb *rb = (struct rng_rb *)arg;
|
||||||
chopstx_intr_t adc_intr;
|
|
||||||
int mode = neug_mode;
|
int mode = neug_mode;
|
||||||
|
|
||||||
rng_should_terminate = 0;
|
rng_should_terminate = 0;
|
||||||
@@ -583,7 +577,6 @@ rng (void *arg)
|
|||||||
|
|
||||||
/* Enable ADCs */
|
/* Enable ADCs */
|
||||||
adc_start ();
|
adc_start ();
|
||||||
chopstx_claim_irq (&adc_intr, INTR_REQ_DMA1_Channel1);
|
|
||||||
|
|
||||||
ep_init (mode);
|
ep_init (mode);
|
||||||
while (!rng_should_terminate)
|
while (!rng_should_terminate)
|
||||||
@@ -591,7 +584,7 @@ rng (void *arg)
|
|||||||
int err;
|
int err;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
err = adc_wait_completion (&adc_intr);
|
err = adc_wait_completion ();
|
||||||
|
|
||||||
chopstx_mutex_lock (&mode_mtx);
|
chopstx_mutex_lock (&mode_mtx);
|
||||||
if (err || mode != neug_mode)
|
if (err || mode != neug_mode)
|
||||||
@@ -641,16 +634,15 @@ rng (void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
adc_stop ();
|
adc_stop ();
|
||||||
chopstx_release_irq (&adc_intr);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rng_rb the_ring_buffer;
|
static struct rng_rb the_ring_buffer;
|
||||||
|
|
||||||
extern uint8_t __process2_stack_base__, __process2_stack_size__;
|
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
|
||||||
const uint32_t __stackaddr_rng = (uint32_t)&__process2_stack_base__;
|
#define STACK_ADDR_RNG ((uint32_t)__process2_stack_base__)
|
||||||
const size_t __stacksize_rng = (size_t)&__process2_stack_size__;
|
#define STACK_SIZE_RNG ((uint32_t)__process2_stack_size__)
|
||||||
#define PRIO_RNG 2
|
#define PRIO_RNG 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -676,7 +668,7 @@ neug_init (uint32_t *buf, uint8_t size)
|
|||||||
neug_mode = NEUG_MODE_CONDITIONED;
|
neug_mode = NEUG_MODE_CONDITIONED;
|
||||||
rb_init (rb, buf, size);
|
rb_init (rb, buf, size);
|
||||||
|
|
||||||
rng_thread = chopstx_create (PRIO_RNG, __stackaddr_rng, __stacksize_rng,
|
rng_thread = chopstx_create (PRIO_RNG, STACK_ADDR_RNG, STACK_SIZE_RNG,
|
||||||
rng, rb);
|
rng, rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* openpgp.c -- OpenPGP card protocol support
|
* openpgp.c -- OpenPGP card protocol support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
|
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||||
* Free Software Initiative of Japan
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
@@ -138,6 +138,7 @@ static void
|
|||||||
cmd_verify (void)
|
cmd_verify (void)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
uint8_t p1 = P1 (apdu);
|
||||||
uint8_t p2 = P2 (apdu);
|
uint8_t p2 = P2 (apdu);
|
||||||
int r;
|
int r;
|
||||||
const uint8_t *pw;
|
const uint8_t *pw;
|
||||||
@@ -149,22 +150,36 @@ cmd_verify (void)
|
|||||||
pw = apdu.cmd_apdu_data;
|
pw = apdu.cmd_apdu_data;
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{ /* This is to examine status. */
|
{
|
||||||
if (p2 == 0x81)
|
if (p1 == 0)
|
||||||
r = ac_check_status (AC_PSO_CDS_AUTHORIZED);
|
{ /* This is to examine status. */
|
||||||
else if (p2 == 0x82)
|
if (p2 == 0x81)
|
||||||
r = ac_check_status (AC_OTHER_AUTHORIZED);
|
r = ac_check_status (AC_PSO_CDS_AUTHORIZED);
|
||||||
else
|
else if (p2 == 0x82)
|
||||||
r = ac_check_status (AC_ADMIN_AUTHORIZED);
|
r = ac_check_status (AC_OTHER_AUTHORIZED);
|
||||||
|
else
|
||||||
|
r = ac_check_status (AC_ADMIN_AUTHORIZED);
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
GPG_SUCCESS (); /* If authentication done already, return success. */
|
GPG_SUCCESS (); /* If authentication done already, return success. */
|
||||||
else
|
else
|
||||||
{ /* If not, return retry counter, encoded. */
|
{ /* If not, return retry counter, encoded. */
|
||||||
r = gpg_pw_get_retry_counter (p2);
|
r = gpg_pw_get_retry_counter (p2);
|
||||||
set_res_sw (0x63, 0xc0 | (r&0x0f));
|
set_res_sw (0x63, 0xc0 | (r&0x0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (p1 == 0xff)
|
||||||
|
{ /* Reset the status. */
|
||||||
|
if (p2 == 0x81)
|
||||||
|
ac_reset_pso_cds ();
|
||||||
|
else if (p2 == 0x82)
|
||||||
|
ac_reset_other ();
|
||||||
|
else
|
||||||
|
ac_reset_admin ();
|
||||||
|
GPG_SUCCESS ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
GPG_BAD_P1_P2 ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,9 +452,12 @@ s2k (const unsigned char *salt, size_t slen,
|
|||||||
{
|
{
|
||||||
sha256_context ctx;
|
sha256_context ctx;
|
||||||
size_t count = S2KCOUNT;
|
size_t count = S2KCOUNT;
|
||||||
|
const uint8_t *unique = unique_device_id ();
|
||||||
|
|
||||||
sha256_start (&ctx);
|
sha256_start (&ctx);
|
||||||
|
|
||||||
|
sha256_update (&ctx, unique, 12);
|
||||||
|
|
||||||
while (count > slen + ilen)
|
while (count > slen + ilen)
|
||||||
{
|
{
|
||||||
if (slen)
|
if (slen)
|
||||||
@@ -1351,23 +1369,10 @@ process_command_apdu (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * card_thread (chopstx_t thd, struct eventflag *ccid_comm);
|
void *
|
||||||
|
|
||||||
void * __attribute__ ((naked))
|
|
||||||
openpgp_card_thread (void *arg)
|
openpgp_card_thread (void *arg)
|
||||||
{
|
{
|
||||||
chopstx_t thd;
|
struct eventflag *ccid_comm = (struct eventflag *)arg;
|
||||||
|
|
||||||
asm ("mov %0, sp" : "=r" (thd));
|
|
||||||
return card_thread (thd, (struct eventflag *)arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
chopstx_t openpgp_card_thd;
|
|
||||||
|
|
||||||
static void * __attribute__ ((noinline))
|
|
||||||
card_thread (chopstx_t thd, struct eventflag *ccid_comm)
|
|
||||||
{
|
|
||||||
openpgp_card_thd = thd;
|
|
||||||
|
|
||||||
openpgp_comm = ccid_comm + 1;
|
openpgp_comm = ccid_comm + 1;
|
||||||
|
|
||||||
@@ -1407,7 +1412,7 @@ card_thread (chopstx_t thd, struct eventflag *ccid_comm)
|
|||||||
else if (m == EV_MODIFY_CMD_AVAILABLE)
|
else if (m == EV_MODIFY_CMD_AVAILABLE)
|
||||||
{
|
{
|
||||||
#if defined(PINPAD_SUPPORT)
|
#if defined(PINPAD_SUPPORT)
|
||||||
uint8_t bConfirmPIN = apdu.cmd_apdu_data[5];
|
uint8_t bConfirmPIN = apdu.cmd_apdu_data[0];
|
||||||
uint8_t *p = apdu.cmd_apdu_data;
|
uint8_t *p = apdu.cmd_apdu_data;
|
||||||
|
|
||||||
if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
|
if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "gnuk.h"
|
#include "gnuk.h"
|
||||||
#include "stm32f103.h"
|
#include "mcu/stm32f103.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define DEBUG_CIR 1
|
#define DEBUG_CIR 1
|
||||||
@@ -51,10 +51,9 @@ cir_ext_enable (void)
|
|||||||
EXTI->IMR |= EXTI_IMR;
|
EXTI->IMR |= EXTI_IMR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static chopstx_mutex_t cir_input_mtx;
|
||||||
static chopstx_t pin_thread;
|
static chopstx_cond_t cir_input_cnd;
|
||||||
static uint32_t wait_usec;
|
static int input_avail;
|
||||||
static uint8_t notification;
|
|
||||||
|
|
||||||
uint8_t pin_input_buffer[MAX_PIN_CHARS];
|
uint8_t pin_input_buffer[MAX_PIN_CHARS];
|
||||||
uint8_t pin_input_len;
|
uint8_t pin_input_len;
|
||||||
@@ -500,9 +499,18 @@ hex (int x)
|
|||||||
return (x - 10) + 'a';
|
return (x - 10) + 'a';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_input (void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
return input_avail;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cir_getchar (uint32_t timeout)
|
cir_getchar (uint32_t timeout)
|
||||||
{
|
{
|
||||||
|
chopstx_poll_cond_t poll_desc;
|
||||||
|
struct chx_poll_head *pd_array[1] = { (struct chx_poll_head *)&poll_desc };
|
||||||
uint16_t cir_addr;
|
uint16_t cir_addr;
|
||||||
#if defined(DEBUG_CIR)
|
#if defined(DEBUG_CIR)
|
||||||
uint16_t *p;
|
uint16_t *p;
|
||||||
@@ -514,10 +522,15 @@ cir_getchar (uint32_t timeout)
|
|||||||
|
|
||||||
cir_ll_init ();
|
cir_ll_init ();
|
||||||
|
|
||||||
notification = 0;
|
poll_desc.type = CHOPSTX_POLL_COND;
|
||||||
wait_usec = timeout;
|
poll_desc.ready = 0;
|
||||||
chopstx_usec_wait_var (&wait_usec);
|
poll_desc.cond = &cir_input_cnd;
|
||||||
if (notification == 0)
|
poll_desc.mutex = &cir_input_mtx;
|
||||||
|
poll_desc.check = check_input;
|
||||||
|
poll_desc.arg = NULL;
|
||||||
|
|
||||||
|
input_avail = 0;
|
||||||
|
if (chopstx_poll (&timeout, 1, pd_array) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Sleep 200ms to avoid detecting chatter inputs. */
|
/* Sleep 200ms to avoid detecting chatter inputs. */
|
||||||
@@ -631,13 +644,10 @@ cir_getchar (uint32_t timeout)
|
|||||||
int
|
int
|
||||||
pinpad_getline (int msg_code, uint32_t timeout)
|
pinpad_getline (int msg_code, uint32_t timeout)
|
||||||
{
|
{
|
||||||
extern chopstx_t openpgp_card_thd;
|
|
||||||
|
|
||||||
(void)msg_code;
|
(void)msg_code;
|
||||||
|
|
||||||
DEBUG_INFO (">>>\r\n");
|
DEBUG_INFO (">>>\r\n");
|
||||||
|
|
||||||
pin_thread = openpgp_card_thd;
|
|
||||||
pin_input_len = 0;
|
pin_input_len = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -663,7 +673,6 @@ pinpad_getline (int msg_code, uint32_t timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cir_ext_disable ();
|
cir_ext_disable ();
|
||||||
pin_thread = NULL;
|
|
||||||
|
|
||||||
return pin_input_len;
|
return pin_input_len;
|
||||||
}
|
}
|
||||||
@@ -932,13 +941,12 @@ cir_timer_interrupt (void)
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Notify the thread, when it's waiting the input.
|
* Notify the thread, when it's waiting the input.
|
||||||
* If else, throw away the input.
|
* If else, the input is thrown away.
|
||||||
*/
|
*/
|
||||||
if (pin_thread)
|
chopstx_mutex_lock (&cir_input_mtx);
|
||||||
{
|
input_avail = 1;
|
||||||
notification = 1;
|
chopstx_cond_signal (&cir_input_cnd);
|
||||||
chopstx_wakeup_usec_wait (pin_thread);
|
chopstx_mutex_unlock (&cir_input_mtx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_CIR)
|
#if defined(DEBUG_CIR)
|
||||||
@@ -956,9 +964,9 @@ cir_timer_interrupt (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern uint8_t __process6_stack_base__, __process6_stack_size__;
|
extern uint8_t __process6_stack_base__[], __process6_stack_size__[];
|
||||||
const uint32_t __stackaddr_tim = (uint32_t)&__process6_stack_base__;
|
#define STACK_ADDR_TIM ((uint32_t)__process6_stack_base__)
|
||||||
const size_t __stacksize_tim = (size_t)&__process6_stack_size__;
|
#define STACK_SIZE_TIM ((uint32_t)__process6_stack_size__)
|
||||||
#define PRIO_TIM 4
|
#define PRIO_TIM 4
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
@@ -1004,6 +1012,9 @@ ext_main (void *arg)
|
|||||||
void
|
void
|
||||||
cir_init (void)
|
cir_init (void)
|
||||||
{
|
{
|
||||||
|
chopstx_mutex_init (&cir_input_mtx);
|
||||||
|
chopstx_cond_init (&cir_input_cnd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use XOR function for three signals: TIMx_CH1, TIMx_CH2, and TIMx_CH3.
|
* We use XOR function for three signals: TIMx_CH1, TIMx_CH2, and TIMx_CH3.
|
||||||
*
|
*
|
||||||
@@ -1046,6 +1057,6 @@ cir_init (void)
|
|||||||
/* Generate UEV to upload PSC and ARR */
|
/* Generate UEV to upload PSC and ARR */
|
||||||
TIMx->EGR = TIM_EGR_UG;
|
TIMx->EGR = TIM_EGR_UG;
|
||||||
|
|
||||||
chopstx_create (PRIO_TIM, __stackaddr_tim, __stacksize_tim, tim_main, NULL);
|
chopstx_create (PRIO_TIM, STACK_ADDR_TIM, STACK_SIZE_TIM, tim_main, NULL);
|
||||||
chopstx_create (PRIO_EXT, __stackaddr_ext, __stacksize_ext, ext_main, NULL);
|
chopstx_create (PRIO_EXT, STACK_ADDR_EXT, STACK_SIZE_EXT, ext_main, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
700
src/stm32f103.h
700
src/stm32f103.h
@@ -1,700 +0,0 @@
|
|||||||
#define PERIPH_BASE 0x40000000
|
|
||||||
#define APB1PERIPH_BASE PERIPH_BASE
|
|
||||||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
|
|
||||||
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
|
|
||||||
|
|
||||||
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_AHBENR_DMA1EN 0x00000001
|
|
||||||
#define RCC_AHBENR_CRCEN 0x00000040
|
|
||||||
|
|
||||||
#define RCC_APB2ENR_ADC1EN 0x00000200
|
|
||||||
#define RCC_APB2ENR_ADC2EN 0x00000400
|
|
||||||
#define RCC_APB2ENR_TIM1EN 0x00000800
|
|
||||||
#define RCC_APB1ENR_TIM2EN 0x00000001
|
|
||||||
#define RCC_APB1ENR_TIM3EN 0x00000002
|
|
||||||
#define RCC_APB1ENR_TIM4EN 0x00000004
|
|
||||||
|
|
||||||
#define RCC_APB2RSTR_ADC1RST 0x00000200
|
|
||||||
#define RCC_APB2RSTR_ADC2RST 0x00000400
|
|
||||||
#define RCC_APB2RSTR_TIM1RST 0x00000800
|
|
||||||
#define RCC_APB1RSTR_TIM2RST 0x00000001
|
|
||||||
#define RCC_APB1RSTR_TIM3RST 0x00000002
|
|
||||||
#define RCC_APB1RSTR_TIM4RST 0x00000004
|
|
||||||
|
|
||||||
#define CRC_CR_RESET 0x00000001
|
|
||||||
|
|
||||||
struct CRC {
|
|
||||||
volatile uint32_t DR;
|
|
||||||
volatile uint8_t IDR;
|
|
||||||
uint8_t RESERVED0;
|
|
||||||
uint16_t RESERVED1;
|
|
||||||
volatile uint32_t CR;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CRC_BASE (AHBPERIPH_BASE + 0x3000)
|
|
||||||
static struct CRC *const CRC = ((struct CRC *const)CRC_BASE);
|
|
||||||
|
|
||||||
|
|
||||||
struct ADC {
|
|
||||||
volatile uint32_t SR;
|
|
||||||
volatile uint32_t CR1;
|
|
||||||
volatile uint32_t CR2;
|
|
||||||
volatile uint32_t SMPR1;
|
|
||||||
volatile uint32_t SMPR2;
|
|
||||||
volatile uint32_t JOFR1;
|
|
||||||
volatile uint32_t JOFR2;
|
|
||||||
volatile uint32_t JOFR3;
|
|
||||||
volatile uint32_t JOFR4;
|
|
||||||
volatile uint32_t HTR;
|
|
||||||
volatile uint32_t LTR;
|
|
||||||
volatile uint32_t SQR1;
|
|
||||||
volatile uint32_t SQR2;
|
|
||||||
volatile uint32_t SQR3;
|
|
||||||
volatile uint32_t JSQR;
|
|
||||||
volatile uint32_t JDR1;
|
|
||||||
volatile uint32_t JDR2;
|
|
||||||
volatile uint32_t JDR3;
|
|
||||||
volatile uint32_t JDR4;
|
|
||||||
volatile uint32_t DR;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ADC1_BASE (APB2PERIPH_BASE + 0x2400)
|
|
||||||
#define ADC2_BASE (APB2PERIPH_BASE + 0x2800)
|
|
||||||
|
|
||||||
static struct ADC *const ADC1 = (struct ADC *const)ADC1_BASE;
|
|
||||||
static struct ADC *const ADC2 = (struct ADC *const)ADC2_BASE;
|
|
||||||
|
|
||||||
#define ADC_CR1_DUALMOD_0 0x00010000
|
|
||||||
#define ADC_CR1_DUALMOD_1 0x00020000
|
|
||||||
#define ADC_CR1_DUALMOD_2 0x00040000
|
|
||||||
#define ADC_CR1_DUALMOD_3 0x00080000
|
|
||||||
|
|
||||||
#define ADC_CR1_SCAN 0x00000100
|
|
||||||
|
|
||||||
#define ADC_CR2_ADON 0x00000001
|
|
||||||
#define ADC_CR2_CONT 0x00000002
|
|
||||||
#define ADC_CR2_CAL 0x00000004
|
|
||||||
#define ADC_CR2_RSTCAL 0x00000008
|
|
||||||
#define ADC_CR2_DMA 0x00000100
|
|
||||||
#define ADC_CR2_ALIGN 0x00000800
|
|
||||||
#define ADC_CR2_EXTSEL 0x000E0000
|
|
||||||
#define ADC_CR2_EXTSEL_0 0x00020000
|
|
||||||
#define ADC_CR2_EXTSEL_1 0x00040000
|
|
||||||
#define ADC_CR2_EXTSEL_2 0x00080000
|
|
||||||
#define ADC_CR2_EXTTRIG 0x00100000
|
|
||||||
#define ADC_CR2_SWSTART 0x00400000
|
|
||||||
#define ADC_CR2_TSVREFE 0x00800000
|
|
||||||
|
|
||||||
struct DMA_Channel {
|
|
||||||
volatile uint32_t CCR;
|
|
||||||
volatile uint32_t CNDTR;
|
|
||||||
volatile uint32_t CPAR;
|
|
||||||
volatile uint32_t CMAR;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DMA {
|
|
||||||
volatile uint32_t ISR;
|
|
||||||
volatile uint32_t IFCR;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define STM32_DMA_CR_MINC DMA_CCR1_MINC
|
|
||||||
#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1
|
|
||||||
#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1
|
|
||||||
#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE
|
|
||||||
#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE
|
|
||||||
#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE
|
|
||||||
#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
|
|
||||||
#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
|
|
||||||
#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
|
|
||||||
|
|
||||||
#define STM32_DMA_ISR_MASK 0x0F
|
|
||||||
#define STM32_DMA_CCR_RESET_VALUE 0x00000000
|
|
||||||
#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL
|
|
||||||
#define STM32_DMA_CR_PL(n) ((n) << 12)
|
|
||||||
|
|
||||||
#define DMA_CCR1_EN 0x00000001
|
|
||||||
#define DMA_CCR1_TCIE 0x00000002
|
|
||||||
#define DMA_CCR1_HTIE 0x00000004
|
|
||||||
#define DMA_CCR1_TEIE 0x00000008
|
|
||||||
#define DMA_CCR1_DIR 0x00000010
|
|
||||||
#define DMA_CCR1_CIRC 0x00000020
|
|
||||||
#define DMA_CCR1_PINC 0x00000040
|
|
||||||
#define DMA_CCR1_MINC 0x00000080
|
|
||||||
#define DMA_CCR1_PSIZE 0x00000300
|
|
||||||
#define DMA_CCR1_PSIZE_0 0x00000100
|
|
||||||
#define DMA_CCR1_PSIZE_1 0x00000200
|
|
||||||
#define DMA_CCR1_MSIZE 0x00000C00
|
|
||||||
#define DMA_CCR1_MSIZE_0 0x00000400
|
|
||||||
#define DMA_CCR1_MSIZE_1 0x00000800
|
|
||||||
#define DMA_CCR1_PL 0x00003000
|
|
||||||
#define DMA_CCR1_PL_0 0x00001000
|
|
||||||
#define DMA_CCR1_PL_1 0x00002000
|
|
||||||
#define DMA_CCR1_MEM2MEM 0x00004000
|
|
||||||
|
|
||||||
#define DMA_ISR_GIF1 0x00000001
|
|
||||||
#define DMA_ISR_TCIF1 0x00000002
|
|
||||||
#define DMA_ISR_HTIF1 0x00000004
|
|
||||||
#define DMA_ISR_TEIF1 0x00000008
|
|
||||||
#define DMA_ISR_GIF2 0x00000010
|
|
||||||
#define DMA_ISR_TCIF2 0x00000020
|
|
||||||
#define DMA_ISR_HTIF2 0x00000040
|
|
||||||
#define DMA_ISR_TEIF2 0x00000080
|
|
||||||
#define DMA_ISR_GIF3 0x00000100
|
|
||||||
#define DMA_ISR_TCIF3 0x00000200
|
|
||||||
#define DMA_ISR_HTIF3 0x00000400
|
|
||||||
#define DMA_ISR_TEIF3 0x00000800
|
|
||||||
#define DMA_ISR_GIF4 0x00001000
|
|
||||||
#define DMA_ISR_TCIF4 0x00002000
|
|
||||||
#define DMA_ISR_HTIF4 0x00004000
|
|
||||||
#define DMA_ISR_TEIF4 0x00008000
|
|
||||||
#define DMA_ISR_GIF5 0x00010000
|
|
||||||
#define DMA_ISR_TCIF5 0x00020000
|
|
||||||
#define DMA_ISR_HTIF5 0x00040000
|
|
||||||
#define DMA_ISR_TEIF5 0x00080000
|
|
||||||
#define DMA_ISR_GIF6 0x00100000
|
|
||||||
#define DMA_ISR_TCIF6 0x00200000
|
|
||||||
#define DMA_ISR_HTIF6 0x00400000
|
|
||||||
#define DMA_ISR_TEIF6 0x00800000
|
|
||||||
#define DMA_ISR_GIF7 0x01000000
|
|
||||||
#define DMA_ISR_TCIF7 0x02000000
|
|
||||||
#define DMA_ISR_HTIF7 0x04000000
|
|
||||||
#define DMA_ISR_TEIF7 0x08000000
|
|
||||||
|
|
||||||
#define DMA1_BASE (AHBPERIPH_BASE + 0x0000)
|
|
||||||
static struct DMA *const DMA1 = (struct DMA *const)DMA1_BASE;
|
|
||||||
|
|
||||||
#define DMA1_Channel1_BASE (AHBPERIPH_BASE + 0x0008)
|
|
||||||
static struct DMA_Channel *const DMA1_Channel1 =
|
|
||||||
(struct DMA_Channel *const)DMA1_Channel1_BASE;
|
|
||||||
|
|
||||||
/* System Control Block */
|
|
||||||
struct SCB
|
|
||||||
{
|
|
||||||
volatile uint32_t CPUID;
|
|
||||||
volatile uint32_t ICSR;
|
|
||||||
volatile uint32_t VTOR;
|
|
||||||
volatile uint32_t AIRCR;
|
|
||||||
volatile uint32_t SCR;
|
|
||||||
volatile uint32_t CCR;
|
|
||||||
volatile uint8_t SHP[12];
|
|
||||||
volatile uint32_t SHCSR;
|
|
||||||
volatile uint32_t CFSR;
|
|
||||||
volatile uint32_t HFSR;
|
|
||||||
volatile uint32_t DFSR;
|
|
||||||
volatile uint32_t MMFAR;
|
|
||||||
volatile uint32_t BFAR;
|
|
||||||
volatile uint32_t AFSR;
|
|
||||||
volatile uint32_t PFR[2];
|
|
||||||
volatile uint32_t DFR;
|
|
||||||
volatile uint32_t ADR;
|
|
||||||
volatile uint32_t MMFR[4];
|
|
||||||
volatile uint32_t ISAR[5];
|
|
||||||
uint32_t RESERVED0[5];
|
|
||||||
volatile uint32_t CPACR;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SCS_BASE 0xE000E000
|
|
||||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
|
||||||
static struct SCB *const SCB = (struct SCB *const)SCB_BASE;
|
|
||||||
|
|
||||||
/* Timer */
|
|
||||||
struct TIM
|
|
||||||
{
|
|
||||||
volatile uint16_t CR1; uint16_t RESERVED0;
|
|
||||||
volatile uint16_t CR2; uint16_t RESERVED1;
|
|
||||||
volatile uint16_t SMCR; uint16_t RESERVED2;
|
|
||||||
volatile uint16_t DIER; uint16_t RESERVED3;
|
|
||||||
volatile uint16_t SR; uint16_t RESERVED4;
|
|
||||||
volatile uint16_t EGR; uint16_t RESERVED5;
|
|
||||||
volatile uint16_t CCMR1; uint16_t RESERVED6;
|
|
||||||
volatile uint16_t CCMR2; uint16_t RESERVED7;
|
|
||||||
volatile uint16_t CCER; uint16_t RESERVED8;
|
|
||||||
volatile uint16_t CNT; uint16_t RESERVED9;
|
|
||||||
volatile uint16_t PSC; uint16_t RESERVED10;
|
|
||||||
volatile uint16_t ARR; uint16_t RESERVED11;
|
|
||||||
volatile uint16_t RCR; uint16_t RESERVED12;
|
|
||||||
volatile uint16_t CCR1; uint16_t RESERVED13;
|
|
||||||
volatile uint16_t CCR2; uint16_t RESERVED14;
|
|
||||||
volatile uint16_t CCR3; uint16_t RESERVED15;
|
|
||||||
volatile uint16_t CCR4; uint16_t RESERVED16;
|
|
||||||
volatile uint16_t BDTR; uint16_t RESERVED17;
|
|
||||||
volatile uint16_t DCR; uint16_t RESERVED18;
|
|
||||||
volatile uint16_t DMAR; uint16_t RESERVED19;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TIM2_BASE 0x40000000
|
|
||||||
#define TIM3_BASE 0x40000400
|
|
||||||
#define TIM4_BASE 0x40000800
|
|
||||||
static struct TIM *const TIM2 = (struct TIM *const)TIM2_BASE;
|
|
||||||
static struct TIM *const TIM3 = (struct TIM *const)TIM3_BASE;
|
|
||||||
static struct TIM *const TIM4 = (struct TIM *const)TIM4_BASE;
|
|
||||||
|
|
||||||
#define TIM_CR1_CEN 0x0001
|
|
||||||
#define TIM_CR1_UDIS 0x0002
|
|
||||||
#define TIM_CR1_URS 0x0004
|
|
||||||
#define TIM_CR1_OPM 0x0008
|
|
||||||
#define TIM_CR1_DIR 0x0010
|
|
||||||
#define TIM_CR1_CMS 0x0060
|
|
||||||
#define TIM_CR1_CMS_0 0x0020
|
|
||||||
#define TIM_CR1_CMS_1 0x0040
|
|
||||||
#define TIM_CR1_ARPE 0x0080
|
|
||||||
#define TIM_CR1_CKD 0x0300
|
|
||||||
#define TIM_CR1_CKD_0 0x0100
|
|
||||||
#define TIM_CR1_CKD_1 0x0200
|
|
||||||
|
|
||||||
#define TIM_CR2_CCPC 0x0001
|
|
||||||
#define TIM_CR2_CCUS 0x0004
|
|
||||||
#define TIM_CR2_CCDS 0x0008
|
|
||||||
#define TIM_CR2_MMS 0x0070
|
|
||||||
#define TIM_CR2_MMS_0 0x0010
|
|
||||||
#define TIM_CR2_MMS_1 0x0020
|
|
||||||
#define TIM_CR2_MMS_2 0x0040
|
|
||||||
#define TIM_CR2_TI1S 0x0080
|
|
||||||
#define TIM_CR2_OIS1 0x0100
|
|
||||||
#define TIM_CR2_OIS1N 0x0200
|
|
||||||
#define TIM_CR2_OIS2 0x0400
|
|
||||||
#define TIM_CR2_OIS2N 0x0800
|
|
||||||
#define TIM_CR2_OIS3 0x1000
|
|
||||||
#define TIM_CR2_OIS3N 0x2000
|
|
||||||
#define TIM_CR2_OIS4 0x4000
|
|
||||||
|
|
||||||
#define TIM_SMCR_SMS 0x0007
|
|
||||||
#define TIM_SMCR_SMS_0 0x0001
|
|
||||||
#define TIM_SMCR_SMS_1 0x0002
|
|
||||||
#define TIM_SMCR_SMS_2 0x0004
|
|
||||||
#define TIM_SMCR_TS 0x0070
|
|
||||||
#define TIM_SMCR_TS_0 0x0010
|
|
||||||
#define TIM_SMCR_TS_1 0x0020
|
|
||||||
#define TIM_SMCR_TS_2 0x0040
|
|
||||||
#define TIM_SMCR_MSM 0x0080
|
|
||||||
|
|
||||||
#define TIM_SMCR_ETF 0x0F00
|
|
||||||
#define TIM_SMCR_ETF_0 0x0100
|
|
||||||
#define TIM_SMCR_ETF_1 0x0200
|
|
||||||
#define TIM_SMCR_ETF_2 0x0400
|
|
||||||
#define TIM_SMCR_ETF_3 0x0800
|
|
||||||
|
|
||||||
#define TIM_SMCR_ETPS 0x3000
|
|
||||||
#define TIM_SMCR_ETPS_0 0x1000
|
|
||||||
#define TIM_SMCR_ETPS_1 0x2000
|
|
||||||
|
|
||||||
#define TIM_SMCR_ECE 0x4000
|
|
||||||
#define TIM_SMCR_ETP 0x8000
|
|
||||||
|
|
||||||
#define TIM_DIER_UIE 0x0001
|
|
||||||
#define TIM_DIER_CC1IE 0x0002
|
|
||||||
#define TIM_DIER_CC2IE 0x0004
|
|
||||||
#define TIM_DIER_CC3IE 0x0008
|
|
||||||
#define TIM_DIER_CC4IE 0x0010
|
|
||||||
#define TIM_DIER_COMIE 0x0020
|
|
||||||
#define TIM_DIER_TIE 0x0040
|
|
||||||
#define TIM_DIER_BIE 0x0080
|
|
||||||
#define TIM_DIER_UDE 0x0100
|
|
||||||
#define TIM_DIER_CC1DE 0x0200
|
|
||||||
#define TIM_DIER_CC2DE 0x0400
|
|
||||||
#define TIM_DIER_CC3DE 0x0800
|
|
||||||
#define TIM_DIER_CC4DE 0x1000
|
|
||||||
#define TIM_DIER_COMDE 0x2000
|
|
||||||
#define TIM_DIER_TDE 0x4000
|
|
||||||
|
|
||||||
#define TIM_SR_UIF 0x0001
|
|
||||||
#define TIM_SR_CC1IF 0x0002
|
|
||||||
#define TIM_SR_CC2IF 0x0004
|
|
||||||
#define TIM_SR_CC3IF 0x0008
|
|
||||||
#define TIM_SR_CC4IF 0x0010
|
|
||||||
#define TIM_SR_COMIF 0x0020
|
|
||||||
#define TIM_SR_TIF 0x0040
|
|
||||||
#define TIM_SR_BIF 0x0080
|
|
||||||
#define TIM_SR_CC1OF 0x0200
|
|
||||||
#define TIM_SR_CC2OF 0x0400
|
|
||||||
#define TIM_SR_CC3OF 0x0800
|
|
||||||
#define TIM_SR_CC4OF 0x1000
|
|
||||||
|
|
||||||
#define TIM_EGR_UG 0x01
|
|
||||||
#define TIM_EGR_CC1G 0x02
|
|
||||||
#define TIM_EGR_CC2G 0x04
|
|
||||||
#define TIM_EGR_CC3G 0x08
|
|
||||||
#define TIM_EGR_CC4G 0x10
|
|
||||||
#define TIM_EGR_COMG 0x20
|
|
||||||
#define TIM_EGR_TG 0x40
|
|
||||||
#define TIM_EGR_BG 0x80
|
|
||||||
|
|
||||||
#define TIM_CCMR1_CC1S 0x0003
|
|
||||||
#define TIM_CCMR1_CC1S_0 0x0001
|
|
||||||
#define TIM_CCMR1_CC1S_1 0x0002
|
|
||||||
|
|
||||||
#define TIM_CCMR1_OC1FE 0x0004
|
|
||||||
#define TIM_CCMR1_OC1PE 0x0008
|
|
||||||
|
|
||||||
#define TIM_CCMR1_OC1M 0x0070
|
|
||||||
#define TIM_CCMR1_OC1M_0 0x0010
|
|
||||||
#define TIM_CCMR1_OC1M_1 0x0020
|
|
||||||
#define TIM_CCMR1_OC1M_2 0x0040
|
|
||||||
|
|
||||||
#define TIM_CCMR1_OC1CE 0x0080
|
|
||||||
|
|
||||||
#define TIM_CCMR1_CC2S 0x0300
|
|
||||||
#define TIM_CCMR1_CC2S_0 0x0100
|
|
||||||
#define TIM_CCMR1_CC2S_1 0x0200
|
|
||||||
|
|
||||||
#define TIM_CCMR1_OC2FE 0x0400
|
|
||||||
#define TIM_CCMR1_OC2PE 0x0800
|
|
||||||
|
|
||||||
#define TIM_CCMR1_OC2M 0x7000
|
|
||||||
#define TIM_CCMR1_OC2M_0 0x1000
|
|
||||||
#define TIM_CCMR1_OC2M_1 0x2000
|
|
||||||
#define TIM_CCMR1_OC2M_2 0x4000
|
|
||||||
|
|
||||||
#define TIM_CCMR1_OC2CE 0x8000
|
|
||||||
|
|
||||||
|
|
||||||
#define TIM_CCMR1_IC1PSC 0x000C
|
|
||||||
#define TIM_CCMR1_IC1PSC_0 0x0004
|
|
||||||
#define TIM_CCMR1_IC1PSC_1 0x0008
|
|
||||||
|
|
||||||
#define TIM_CCMR1_IC1F 0x00F0
|
|
||||||
#define TIM_CCMR1_IC1F_0 0x0010
|
|
||||||
#define TIM_CCMR1_IC1F_1 0x0020
|
|
||||||
#define TIM_CCMR1_IC1F_2 0x0040
|
|
||||||
#define TIM_CCMR1_IC1F_3 0x0080
|
|
||||||
|
|
||||||
#define TIM_CCMR1_IC2PSC 0x0C00
|
|
||||||
#define TIM_CCMR1_IC2PSC_0 0x0400
|
|
||||||
#define TIM_CCMR1_IC2PSC_1 0x0800
|
|
||||||
|
|
||||||
#define TIM_CCMR1_IC2F 0xF000
|
|
||||||
#define TIM_CCMR1_IC2F_0 0x1000
|
|
||||||
#define TIM_CCMR1_IC2F_1 0x2000
|
|
||||||
#define TIM_CCMR1_IC2F_2 0x4000
|
|
||||||
#define TIM_CCMR1_IC2F_3 0x8000
|
|
||||||
|
|
||||||
#define TIM_CCMR2_CC3S 0x0003
|
|
||||||
#define TIM_CCMR2_CC3S_0 0x0001
|
|
||||||
#define TIM_CCMR2_CC3S_1 0x0002
|
|
||||||
|
|
||||||
#define TIM_CCMR2_OC3FE 0x0004
|
|
||||||
#define TIM_CCMR2_OC3PE 0x0008
|
|
||||||
|
|
||||||
#define TIM_CCMR2_OC3M 0x0070
|
|
||||||
#define TIM_CCMR2_OC3M_0 0x0010
|
|
||||||
#define TIM_CCMR2_OC3M_1 0x0020
|
|
||||||
#define TIM_CCMR2_OC3M_2 0x0040
|
|
||||||
|
|
||||||
#define TIM_CCMR2_OC3CE 0x0080
|
|
||||||
|
|
||||||
#define TIM_CCMR2_CC4S 0x0300
|
|
||||||
#define TIM_CCMR2_CC4S_0 0x0100
|
|
||||||
#define TIM_CCMR2_CC4S_1 0x0200
|
|
||||||
|
|
||||||
#define TIM_CCMR2_OC4FE 0x0400
|
|
||||||
#define TIM_CCMR2_OC4PE 0x0800
|
|
||||||
|
|
||||||
#define TIM_CCMR2_OC4M 0x7000
|
|
||||||
#define TIM_CCMR2_OC4M_0 0x1000
|
|
||||||
#define TIM_CCMR2_OC4M_1 0x2000
|
|
||||||
#define TIM_CCMR2_OC4M_2 0x4000
|
|
||||||
|
|
||||||
#define TIM_CCMR2_OC4CE 0x8000
|
|
||||||
|
|
||||||
|
|
||||||
#define TIM_CCMR2_IC3PSC 0x000C
|
|
||||||
#define TIM_CCMR2_IC3PSC_0 0x0004
|
|
||||||
#define TIM_CCMR2_IC3PSC_1 0x0008
|
|
||||||
|
|
||||||
#define TIM_CCMR2_IC3F 0x00F0
|
|
||||||
#define TIM_CCMR2_IC3F_0 0x0010
|
|
||||||
#define TIM_CCMR2_IC3F_1 0x0020
|
|
||||||
#define TIM_CCMR2_IC3F_2 0x0040
|
|
||||||
#define TIM_CCMR2_IC3F_3 0x0080
|
|
||||||
|
|
||||||
#define TIM_CCMR2_IC4PSC 0x0C00
|
|
||||||
#define TIM_CCMR2_IC4PSC_0 0x0400
|
|
||||||
#define TIM_CCMR2_IC4PSC_1 0x0800
|
|
||||||
|
|
||||||
#define TIM_CCMR2_IC4F 0xF000
|
|
||||||
#define TIM_CCMR2_IC4F_0 0x1000
|
|
||||||
#define TIM_CCMR2_IC4F_1 0x2000
|
|
||||||
#define TIM_CCMR2_IC4F_2 0x4000
|
|
||||||
#define TIM_CCMR2_IC4F_3 0x8000
|
|
||||||
|
|
||||||
#define TIM_CCER_CC1E 0x0001
|
|
||||||
#define TIM_CCER_CC1P 0x0002
|
|
||||||
#define TIM_CCER_CC1NE 0x0004
|
|
||||||
#define TIM_CCER_CC1NP 0x0008
|
|
||||||
#define TIM_CCER_CC2E 0x0010
|
|
||||||
#define TIM_CCER_CC2P 0x0020
|
|
||||||
#define TIM_CCER_CC2NE 0x0040
|
|
||||||
#define TIM_CCER_CC2NP 0x0080
|
|
||||||
#define TIM_CCER_CC3E 0x0100
|
|
||||||
#define TIM_CCER_CC3P 0x0200
|
|
||||||
#define TIM_CCER_CC3NE 0x0400
|
|
||||||
#define TIM_CCER_CC3NP 0x0800
|
|
||||||
#define TIM_CCER_CC4E 0x1000
|
|
||||||
#define TIM_CCER_CC4P 0x2000
|
|
||||||
|
|
||||||
#define TIM_CNT_CNT 0xFFFF
|
|
||||||
|
|
||||||
#define TIM_PSC_PSC 0xFFFF
|
|
||||||
|
|
||||||
#define TIM_ARR_ARR 0xFFFF
|
|
||||||
|
|
||||||
#define TIM_RCR_REP 0xFF
|
|
||||||
|
|
||||||
#define TIM_CCR1_CCR1 0xFFFF
|
|
||||||
#define TIM_CCR2_CCR2 0xFFFF
|
|
||||||
#define TIM_CCR3_CCR3 0xFFFF
|
|
||||||
#define TIM_CCR4_CCR4 0xFFFF
|
|
||||||
|
|
||||||
#define TIM_BDTR_DTG 0x00FF
|
|
||||||
#define TIM_BDTR_DTG_0 0x0001
|
|
||||||
#define TIM_BDTR_DTG_1 0x0002
|
|
||||||
#define TIM_BDTR_DTG_2 0x0004
|
|
||||||
#define TIM_BDTR_DTG_3 0x0008
|
|
||||||
#define TIM_BDTR_DTG_4 0x0010
|
|
||||||
#define TIM_BDTR_DTG_5 0x0020
|
|
||||||
#define TIM_BDTR_DTG_6 0x0040
|
|
||||||
#define TIM_BDTR_DTG_7 0x0080
|
|
||||||
|
|
||||||
#define TIM_BDTR_LOCK 0x0300
|
|
||||||
#define TIM_BDTR_LOCK_0 0x0100
|
|
||||||
#define TIM_BDTR_LOCK_1 0x0200
|
|
||||||
|
|
||||||
#define TIM_BDTR_OSSI 0x0400
|
|
||||||
#define TIM_BDTR_OSSR 0x0800
|
|
||||||
#define TIM_BDTR_BKE 0x1000
|
|
||||||
#define TIM_BDTR_BKP 0x2000
|
|
||||||
#define TIM_BDTR_AOE 0x4000
|
|
||||||
#define TIM_BDTR_MOE 0x8000
|
|
||||||
|
|
||||||
#define TIM_DCR_DBA 0x001F
|
|
||||||
#define TIM_DCR_DBA_0 0x0001
|
|
||||||
#define TIM_DCR_DBA_1 0x0002
|
|
||||||
#define TIM_DCR_DBA_2 0x0004
|
|
||||||
#define TIM_DCR_DBA_3 0x0008
|
|
||||||
#define TIM_DCR_DBA_4 0x0010
|
|
||||||
|
|
||||||
#define TIM_DCR_DBL 0x1F00
|
|
||||||
#define TIM_DCR_DBL_0 0x0100
|
|
||||||
#define TIM_DCR_DBL_1 0x0200
|
|
||||||
#define TIM_DCR_DBL_2 0x0400
|
|
||||||
#define TIM_DCR_DBL_3 0x0800
|
|
||||||
#define TIM_DCR_DBL_4 0x1000
|
|
||||||
|
|
||||||
#define TIM_DMAR_DMAB 0xFFFF
|
|
||||||
|
|
||||||
struct EXTI
|
|
||||||
{
|
|
||||||
volatile uint32_t IMR;
|
|
||||||
volatile uint32_t EMR;
|
|
||||||
volatile uint32_t RTSR;
|
|
||||||
volatile uint32_t FTSR;
|
|
||||||
volatile uint32_t SWIER;
|
|
||||||
volatile uint32_t PR;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define EXTI_BASE 0x40010400
|
|
||||||
static struct EXTI *const EXTI = (struct EXTI *const)EXTI_BASE;
|
|
||||||
|
|
||||||
#define EXTI_IMR_MR0 0x00000001
|
|
||||||
#define EXTI_IMR_MR1 0x00000002
|
|
||||||
#define EXTI_IMR_MR2 0x00000004
|
|
||||||
#define EXTI_IMR_MR3 0x00000008
|
|
||||||
#define EXTI_IMR_MR4 0x00000010
|
|
||||||
#define EXTI_IMR_MR5 0x00000020
|
|
||||||
#define EXTI_IMR_MR6 0x00000040
|
|
||||||
#define EXTI_IMR_MR7 0x00000080
|
|
||||||
#define EXTI_IMR_MR8 0x00000100
|
|
||||||
#define EXTI_IMR_MR9 0x00000200
|
|
||||||
#define EXTI_IMR_MR10 0x00000400
|
|
||||||
#define EXTI_IMR_MR11 0x00000800
|
|
||||||
#define EXTI_IMR_MR12 0x00001000
|
|
||||||
#define EXTI_IMR_MR13 0x00002000
|
|
||||||
#define EXTI_IMR_MR14 0x00004000
|
|
||||||
#define EXTI_IMR_MR15 0x00008000
|
|
||||||
#define EXTI_IMR_MR16 0x00010000
|
|
||||||
#define EXTI_IMR_MR17 0x00020000
|
|
||||||
#define EXTI_IMR_MR18 0x00040000
|
|
||||||
#define EXTI_IMR_MR19 0x00080000
|
|
||||||
|
|
||||||
#define EXTI_EMR_MR0 0x00000001
|
|
||||||
#define EXTI_EMR_MR1 0x00000002
|
|
||||||
#define EXTI_EMR_MR2 0x00000004
|
|
||||||
#define EXTI_EMR_MR3 0x00000008
|
|
||||||
#define EXTI_EMR_MR4 0x00000010
|
|
||||||
#define EXTI_EMR_MR5 0x00000020
|
|
||||||
#define EXTI_EMR_MR6 0x00000040
|
|
||||||
#define EXTI_EMR_MR7 0x00000080
|
|
||||||
#define EXTI_EMR_MR8 0x00000100
|
|
||||||
#define EXTI_EMR_MR9 0x00000200
|
|
||||||
#define EXTI_EMR_MR10 0x00000400
|
|
||||||
#define EXTI_EMR_MR11 0x00000800
|
|
||||||
#define EXTI_EMR_MR12 0x00001000
|
|
||||||
#define EXTI_EMR_MR13 0x00002000
|
|
||||||
#define EXTI_EMR_MR14 0x00004000
|
|
||||||
#define EXTI_EMR_MR15 0x00008000
|
|
||||||
#define EXTI_EMR_MR16 0x00010000
|
|
||||||
#define EXTI_EMR_MR17 0x00020000
|
|
||||||
#define EXTI_EMR_MR18 0x00040000
|
|
||||||
#define EXTI_EMR_MR19 0x00080000
|
|
||||||
|
|
||||||
#define EXTI_RTSR_TR0 0x00000001
|
|
||||||
#define EXTI_RTSR_TR1 0x00000002
|
|
||||||
#define EXTI_RTSR_TR2 0x00000004
|
|
||||||
#define EXTI_RTSR_TR3 0x00000008
|
|
||||||
#define EXTI_RTSR_TR4 0x00000010
|
|
||||||
#define EXTI_RTSR_TR5 0x00000020
|
|
||||||
#define EXTI_RTSR_TR6 0x00000040
|
|
||||||
#define EXTI_RTSR_TR7 0x00000080
|
|
||||||
#define EXTI_RTSR_TR8 0x00000100
|
|
||||||
#define EXTI_RTSR_TR9 0x00000200
|
|
||||||
#define EXTI_RTSR_TR10 0x00000400
|
|
||||||
#define EXTI_RTSR_TR11 0x00000800
|
|
||||||
#define EXTI_RTSR_TR12 0x00001000
|
|
||||||
#define EXTI_RTSR_TR13 0x00002000
|
|
||||||
#define EXTI_RTSR_TR14 0x00004000
|
|
||||||
#define EXTI_RTSR_TR15 0x00008000
|
|
||||||
#define EXTI_RTSR_TR16 0x00010000
|
|
||||||
#define EXTI_RTSR_TR17 0x00020000
|
|
||||||
#define EXTI_RTSR_TR18 0x00040000
|
|
||||||
#define EXTI_RTSR_TR19 0x00080000
|
|
||||||
|
|
||||||
#define EXTI_FTSR_TR0 0x00000001
|
|
||||||
#define EXTI_FTSR_TR1 0x00000002
|
|
||||||
#define EXTI_FTSR_TR2 0x00000004
|
|
||||||
#define EXTI_FTSR_TR3 0x00000008
|
|
||||||
#define EXTI_FTSR_TR4 0x00000010
|
|
||||||
#define EXTI_FTSR_TR5 0x00000020
|
|
||||||
#define EXTI_FTSR_TR6 0x00000040
|
|
||||||
#define EXTI_FTSR_TR7 0x00000080
|
|
||||||
#define EXTI_FTSR_TR8 0x00000100
|
|
||||||
#define EXTI_FTSR_TR9 0x00000200
|
|
||||||
#define EXTI_FTSR_TR10 0x00000400
|
|
||||||
#define EXTI_FTSR_TR11 0x00000800
|
|
||||||
#define EXTI_FTSR_TR12 0x00001000
|
|
||||||
#define EXTI_FTSR_TR13 0x00002000
|
|
||||||
#define EXTI_FTSR_TR14 0x00004000
|
|
||||||
#define EXTI_FTSR_TR15 0x00008000
|
|
||||||
#define EXTI_FTSR_TR16 0x00010000
|
|
||||||
#define EXTI_FTSR_TR17 0x00020000
|
|
||||||
#define EXTI_FTSR_TR18 0x00040000
|
|
||||||
#define EXTI_FTSR_TR19 0x00080000
|
|
||||||
|
|
||||||
#define EXTI_SWIER_SWIER0 0x00000001
|
|
||||||
#define EXTI_SWIER_SWIER1 0x00000002
|
|
||||||
#define EXTI_SWIER_SWIER2 0x00000004
|
|
||||||
#define EXTI_SWIER_SWIER3 0x00000008
|
|
||||||
#define EXTI_SWIER_SWIER4 0x00000010
|
|
||||||
#define EXTI_SWIER_SWIER5 0x00000020
|
|
||||||
#define EXTI_SWIER_SWIER6 0x00000040
|
|
||||||
#define EXTI_SWIER_SWIER7 0x00000080
|
|
||||||
#define EXTI_SWIER_SWIER8 0x00000100
|
|
||||||
#define EXTI_SWIER_SWIER9 0x00000200
|
|
||||||
#define EXTI_SWIER_SWIER10 0x00000400
|
|
||||||
#define EXTI_SWIER_SWIER11 0x00000800
|
|
||||||
#define EXTI_SWIER_SWIER12 0x00001000
|
|
||||||
#define EXTI_SWIER_SWIER13 0x00002000
|
|
||||||
#define EXTI_SWIER_SWIER14 0x00004000
|
|
||||||
#define EXTI_SWIER_SWIER15 0x00008000
|
|
||||||
#define EXTI_SWIER_SWIER16 0x00010000
|
|
||||||
#define EXTI_SWIER_SWIER17 0x00020000
|
|
||||||
#define EXTI_SWIER_SWIER18 0x00040000
|
|
||||||
#define EXTI_SWIER_SWIER19 0x00080000
|
|
||||||
|
|
||||||
#define EXTI_PR_PR0 0x00000001
|
|
||||||
#define EXTI_PR_PR1 0x00000002
|
|
||||||
#define EXTI_PR_PR2 0x00000004
|
|
||||||
#define EXTI_PR_PR3 0x00000008
|
|
||||||
#define EXTI_PR_PR4 0x00000010
|
|
||||||
#define EXTI_PR_PR5 0x00000020
|
|
||||||
#define EXTI_PR_PR6 0x00000040
|
|
||||||
#define EXTI_PR_PR7 0x00000080
|
|
||||||
#define EXTI_PR_PR8 0x00000100
|
|
||||||
#define EXTI_PR_PR9 0x00000200
|
|
||||||
#define EXTI_PR_PR10 0x00000400
|
|
||||||
#define EXTI_PR_PR11 0x00000800
|
|
||||||
#define EXTI_PR_PR12 0x00001000
|
|
||||||
#define EXTI_PR_PR13 0x00002000
|
|
||||||
#define EXTI_PR_PR14 0x00004000
|
|
||||||
#define EXTI_PR_PR15 0x00008000
|
|
||||||
#define EXTI_PR_PR16 0x00010000
|
|
||||||
#define EXTI_PR_PR17 0x00020000
|
|
||||||
#define EXTI_PR_PR18 0x00040000
|
|
||||||
#define EXTI_PR_PR19 0x00080000
|
|
||||||
|
|
||||||
#define EXTI0_IRQ 6
|
|
||||||
#define EXTI1_IRQ 7
|
|
||||||
#define EXTI2_IRQ 8
|
|
||||||
#define EXTI9_5_IRQ 23
|
|
||||||
#define TIM2_IRQ 28
|
|
||||||
#define TIM3_IRQ 29
|
|
||||||
#define TIM4_IRQ 30
|
|
||||||
|
|
||||||
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_EXTICR1_EXTI0_PA 0x0000
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PB 0x0001
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PC 0x0002
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PD 0x0003
|
|
||||||
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PA 0x0000
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PB 0x0010
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PC 0x0020
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PD 0x0030
|
|
||||||
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PA 0x0000
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PB 0x0100
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PC 0x0200
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PD 0x0300
|
|
||||||
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PA 0x0000
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PB 0x1000
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PC 0x2000
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PD 0x3000
|
|
||||||
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PA 0x0000
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PB 0x0001
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PC 0x0002
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PD 0x0003
|
|
||||||
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PA 0x0000
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PB 0x0010
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PC 0x0020
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PD 0x0030
|
|
||||||
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PA 0x0000
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PB 0x0100
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PC 0x0200
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PD 0x0300
|
|
||||||
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PA 0x0000
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PB 0x1000
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PC 0x2000
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PD 0x3000
|
|
||||||
|
|
||||||
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
|
|
||||||
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
|
|
||||||
434
src/sys.c
434
src/sys.c
@@ -1,434 +0,0 @@
|
|||||||
/*
|
|
||||||
* sys.c - system routines for the initial page for STM32F103.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013, 2014, 2015 Flying Stone Technology
|
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
|
||||||
*
|
|
||||||
* Copying and distribution of this file, with or without modification,
|
|
||||||
* are permitted in any medium without royalty provided the copyright
|
|
||||||
* notice and this notice are preserved. This file is offered as-is,
|
|
||||||
* without any warranty.
|
|
||||||
*
|
|
||||||
* When the flash ROM is protected, we cannot modify the initial page.
|
|
||||||
* We put some system routines (which is useful for any program) here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#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
|
|
||||||
|
|
||||||
struct NVIC {
|
|
||||||
uint32_t ISER[8];
|
|
||||||
uint32_t unused1[24];
|
|
||||||
uint32_t ICER[8];
|
|
||||||
uint32_t unused2[24];
|
|
||||||
uint32_t ISPR[8];
|
|
||||||
uint32_t unused3[24];
|
|
||||||
uint32_t ICPR[8];
|
|
||||||
uint32_t unused4[24];
|
|
||||||
uint32_t IABR[8];
|
|
||||||
uint32_t unused5[56];
|
|
||||||
uint32_t IPR[60];
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct NVIC *const NVICBase = ((struct NVIC *const)0xE000E100);
|
|
||||||
#define NVIC_ISER(n) (NVICBase->ISER[n >> 5])
|
|
||||||
#define NVIC_ICPR(n) (NVICBase->ICPR[n >> 5])
|
|
||||||
#define NVIC_IPR(n) (NVICBase->IPR[n >> 2])
|
|
||||||
|
|
||||||
static void
|
|
||||||
nvic_enable_vector (uint32_t n, uint32_t prio)
|
|
||||||
{
|
|
||||||
unsigned int sh = (n & 3) << 3;
|
|
||||||
|
|
||||||
NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (prio << sh);
|
|
||||||
NVIC_ICPR (n) = 1 << (n & 0x1F);
|
|
||||||
NVIC_ISER (n) = 1 << (n & 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usb_cable_config (int enable)
|
|
||||||
{
|
|
||||||
#if defined(GPIO_USB_SET_TO_ENABLE)
|
|
||||||
if (enable)
|
|
||||||
GPIO_USB->BSRR = (1 << GPIO_USB_SET_TO_ENABLE);
|
|
||||||
else
|
|
||||||
GPIO_USB->BRR = (1 << GPIO_USB_SET_TO_ENABLE);
|
|
||||||
#elif defined(GPIO_USB_CLEAR_TO_ENABLE)
|
|
||||||
if (enable)
|
|
||||||
GPIO_USB->BRR = (1 << GPIO_USB_CLEAR_TO_ENABLE);
|
|
||||||
else
|
|
||||||
GPIO_USB->BSRR = (1 << GPIO_USB_CLEAR_TO_ENABLE);
|
|
||||||
#else
|
|
||||||
(void)enable;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
set_led (int on)
|
|
||||||
{
|
|
||||||
#if defined(GPIO_LED_CLEAR_TO_EMIT)
|
|
||||||
if (on)
|
|
||||||
GPIO_LED->BRR = (1 << GPIO_LED_CLEAR_TO_EMIT);
|
|
||||||
else
|
|
||||||
GPIO_LED->BSRR = (1 << GPIO_LED_CLEAR_TO_EMIT);
|
|
||||||
#else
|
|
||||||
if (on)
|
|
||||||
GPIO_LED->BSRR = (1 << GPIO_LED_SET_TO_EMIT);
|
|
||||||
else
|
|
||||||
GPIO_LED->BRR = (1 << GPIO_LED_SET_TO_EMIT);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wait (int count)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
asm volatile ("" : : "r" (i) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
usb_lld_sys_shutdown (void)
|
|
||||||
{
|
|
||||||
RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
|
|
||||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
|
||||||
usb_cable_config (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usb_lld_sys_init (void)
|
|
||||||
{
|
|
||||||
if ((RCC->APB1ENR & RCC_APB1ENR_USBEN)
|
|
||||||
&& (RCC->APB1RSTR & RCC_APB1RSTR_USBRST) == 0)
|
|
||||||
/* Make sure the device is disconnected, even after core reset. */
|
|
||||||
{
|
|
||||||
usb_lld_sys_shutdown ();
|
|
||||||
/* Disconnect requires SE0 (>= 2.5uS). */
|
|
||||||
wait (300);
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_cable_config (1);
|
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
|
||||||
nvic_enable_vector (USB_LP_CAN1_RX0_IRQn,
|
|
||||||
CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
|
|
||||||
/*
|
|
||||||
* Note that we also have other IRQ(s):
|
|
||||||
* USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
|
|
||||||
* USBWakeUp_IRQn (suspend/resume)
|
|
||||||
*/
|
|
||||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
|
||||||
RCC->APB1RSTR = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FLASH_KEY1 0x45670123UL
|
|
||||||
#define FLASH_KEY2 0xCDEF89ABUL
|
|
||||||
|
|
||||||
enum flash_status
|
|
||||||
{
|
|
||||||
FLASH_BUSY = 1,
|
|
||||||
FLASH_ERROR_PG,
|
|
||||||
FLASH_ERROR_WRP,
|
|
||||||
FLASH_COMPLETE,
|
|
||||||
FLASH_TIMEOUT
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __attribute__ ((used))
|
|
||||||
flash_unlock (void)
|
|
||||||
{
|
|
||||||
FLASH->KEYR = FLASH_KEY1;
|
|
||||||
FLASH->KEYR = FLASH_KEY2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define intr_disable() asm volatile ("cpsid i" : : : "memory")
|
|
||||||
#define intr_enable() asm volatile ("cpsie i" : : : "memory")
|
|
||||||
|
|
||||||
#define FLASH_SR_BSY 0x01
|
|
||||||
#define FLASH_SR_PGERR 0x04
|
|
||||||
#define FLASH_SR_WRPRTERR 0x10
|
|
||||||
#define FLASH_SR_EOP 0x20
|
|
||||||
|
|
||||||
#define FLASH_CR_PG 0x0001
|
|
||||||
#define FLASH_CR_PER 0x0002
|
|
||||||
#define FLASH_CR_MER 0x0004
|
|
||||||
#define FLASH_CR_OPTPG 0x0010
|
|
||||||
#define FLASH_CR_OPTER 0x0020
|
|
||||||
#define FLASH_CR_STRT 0x0040
|
|
||||||
#define FLASH_CR_LOCK 0x0080
|
|
||||||
#define FLASH_CR_OPTWRE 0x0200
|
|
||||||
#define FLASH_CR_ERRIE 0x0400
|
|
||||||
#define FLASH_CR_EOPIE 0x1000
|
|
||||||
|
|
||||||
static int
|
|
||||||
flash_wait_for_last_operation (uint32_t timeout)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
status = FLASH->SR;
|
|
||||||
if (--timeout == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while ((status & FLASH_SR_BSY) != 0);
|
|
||||||
|
|
||||||
return status & (FLASH_SR_BSY|FLASH_SR_PGERR|FLASH_SR_WRPRTERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FLASH_PROGRAM_TIMEOUT 0x00010000
|
|
||||||
#define FLASH_ERASE_TIMEOUT 0x01000000
|
|
||||||
|
|
||||||
static int
|
|
||||||
flash_program_halfword (uint32_t addr, uint16_t data)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
|
|
||||||
|
|
||||||
intr_disable ();
|
|
||||||
if (status == 0)
|
|
||||||
{
|
|
||||||
FLASH->CR |= FLASH_CR_PG;
|
|
||||||
|
|
||||||
*(volatile uint16_t *)addr = data;
|
|
||||||
|
|
||||||
status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
|
|
||||||
FLASH->CR &= ~FLASH_CR_PG;
|
|
||||||
}
|
|
||||||
intr_enable ();
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
flash_erase_page (uint32_t addr)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
|
||||||
|
|
||||||
intr_disable ();
|
|
||||||
if (status == 0)
|
|
||||||
{
|
|
||||||
FLASH->CR |= FLASH_CR_PER;
|
|
||||||
FLASH->AR = addr;
|
|
||||||
FLASH->CR |= FLASH_CR_STRT;
|
|
||||||
|
|
||||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
|
||||||
FLASH->CR &= ~FLASH_CR_PER;
|
|
||||||
}
|
|
||||||
intr_enable ();
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
flash_check_blank (const uint8_t *p_start, size_t size)
|
|
||||||
{
|
|
||||||
const uint8_t *p;
|
|
||||||
|
|
||||||
for (p = p_start; p < p_start + size; p++)
|
|
||||||
if (*p != 0xff)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
|
|
||||||
|
|
||||||
if (dst_addr < FLASH_START || dst_addr + len > flash_end)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (len)
|
|
||||||
{
|
|
||||||
uint16_t hw = *src++;
|
|
||||||
|
|
||||||
hw |= (*src++ << 8);
|
|
||||||
status = flash_program_halfword (dst_addr, hw);
|
|
||||||
if (status != 0)
|
|
||||||
return 0; /* error return */
|
|
||||||
|
|
||||||
dst_addr += 2;
|
|
||||||
len -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OPTION_BYTES_ADDR 0x1ffff800
|
|
||||||
|
|
||||||
static int
|
|
||||||
flash_protect (void)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
uint32_t option_bytes_value;
|
|
||||||
|
|
||||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
|
||||||
|
|
||||||
intr_disable ();
|
|
||||||
if (status == 0)
|
|
||||||
{
|
|
||||||
FLASH->OPTKEYR = FLASH_KEY1;
|
|
||||||
FLASH->OPTKEYR = FLASH_KEY2;
|
|
||||||
|
|
||||||
FLASH->CR |= FLASH_CR_OPTER;
|
|
||||||
FLASH->CR |= FLASH_CR_STRT;
|
|
||||||
|
|
||||||
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
|
||||||
FLASH->CR &= ~FLASH_CR_OPTER;
|
|
||||||
}
|
|
||||||
intr_enable ();
|
|
||||||
|
|
||||||
if (status != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
option_bytes_value = *(uint32_t *)OPTION_BYTES_ADDR;
|
|
||||||
return (option_bytes_value & 0xff) == 0xff ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((naked))
|
|
||||||
flash_erase_all_and_exec (void (*entry)(void))
|
|
||||||
{
|
|
||||||
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 += page_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr >= end)
|
|
||||||
(*entry) ();
|
|
||||||
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SCB
|
|
||||||
{
|
|
||||||
volatile uint32_t CPUID;
|
|
||||||
volatile uint32_t ICSR;
|
|
||||||
volatile uint32_t VTOR;
|
|
||||||
volatile uint32_t AIRCR;
|
|
||||||
volatile uint32_t SCR;
|
|
||||||
volatile uint32_t CCR;
|
|
||||||
volatile uint8_t SHP[12];
|
|
||||||
volatile uint32_t SHCSR;
|
|
||||||
volatile uint32_t CFSR;
|
|
||||||
volatile uint32_t HFSR;
|
|
||||||
volatile uint32_t DFSR;
|
|
||||||
volatile uint32_t MMFAR;
|
|
||||||
volatile uint32_t BFAR;
|
|
||||||
volatile uint32_t AFSR;
|
|
||||||
volatile uint32_t PFR[2];
|
|
||||||
volatile uint32_t DFR;
|
|
||||||
volatile uint32_t ADR;
|
|
||||||
volatile uint32_t MMFR[4];
|
|
||||||
volatile uint32_t ISAR[5];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SCS_BASE (0xE000E000)
|
|
||||||
#define SCB_BASE (SCS_BASE + 0x0D00)
|
|
||||||
static struct SCB *const SCB = ((struct SCB *const) SCB_BASE);
|
|
||||||
|
|
||||||
#define SYSRESETREQ 0x04
|
|
||||||
static void
|
|
||||||
nvic_system_reset (void)
|
|
||||||
{
|
|
||||||
SCB->AIRCR = (0x05FA0000 | (SCB->AIRCR & 0x70) | SYSRESETREQ);
|
|
||||||
asm volatile ("dsb");
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__ ((naked))
|
|
||||||
reset (void)
|
|
||||||
{
|
|
||||||
extern const unsigned long *FT0, *FT1, *FT2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This code may not be at the start of flash ROM, because of DFU.
|
|
||||||
* So, we take the address from PC.
|
|
||||||
*/
|
|
||||||
asm volatile ("cpsid i\n\t" /* Mask all interrupts. */
|
|
||||||
"ldr r0, 1f\n\t" /* r0 = SCR */
|
|
||||||
"mov r1, pc\n\t" /* r1 = (PC + 0x1000) & ~0x0fff */
|
|
||||||
"mov r2, #0x1000\n\t"
|
|
||||||
"add r1, r1, r2\n\t"
|
|
||||||
"sub r2, r2, #1\n\t"
|
|
||||||
"bic r1, r1, r2\n\t"
|
|
||||||
"str r1, [r0, #8]\n\t" /* Set SCR->VCR */
|
|
||||||
"ldr r0, [r1], #4\n\t"
|
|
||||||
"msr MSP, r0\n\t" /* Main (exception handler) stack. */
|
|
||||||
"ldr r0, [r1]\n\t" /* Reset handler. */
|
|
||||||
"bx r0\n\t"
|
|
||||||
".align 2\n"
|
|
||||||
"1: .word 0xe000ed00"
|
|
||||||
: /* no output */ : /* no input */ : "memory");
|
|
||||||
|
|
||||||
/* Never reach here. */
|
|
||||||
/* Artificial entry to refer FT0, FT1, and FT2. */
|
|
||||||
asm volatile (""
|
|
||||||
: : "r" (FT0), "r" (FT1), "r" (FT2));
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef void (*handler)(void);
|
|
||||||
extern uint8_t __ram_end__;
|
|
||||||
|
|
||||||
handler vector[] __attribute__ ((section(".vectors"))) = {
|
|
||||||
(handler)&__ram_end__,
|
|
||||||
reset,
|
|
||||||
(handler)set_led,
|
|
||||||
flash_unlock,
|
|
||||||
(handler)flash_program_halfword,
|
|
||||||
(handler)flash_erase_page,
|
|
||||||
(handler)flash_check_blank,
|
|
||||||
(handler)flash_write,
|
|
||||||
(handler)flash_protect,
|
|
||||||
(handler)flash_erase_all_and_exec,
|
|
||||||
usb_lld_sys_init,
|
|
||||||
usb_lld_sys_shutdown,
|
|
||||||
nvic_system_reset,
|
|
||||||
clock_init,
|
|
||||||
gpio_init,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
|
|
||||||
3*2+2, /* bLength */
|
|
||||||
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;
|
|
||||||
130
src/sys.h
130
src/sys.h
@@ -1,130 +0,0 @@
|
|||||||
#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
|
|
||||||
#define BOARD_ID_NITROKEY_START 0xad1e7ebd
|
|
||||||
|
|
||||||
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];
|
|
||||||
|
|
||||||
static inline const uint8_t *
|
|
||||||
unique_device_id (void)
|
|
||||||
{
|
|
||||||
/* STM32F103 has 96-bit unique device identifier */
|
|
||||||
const uint8_t *addr = (const uint8_t *)0x1ffff7e8;
|
|
||||||
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
set_led (int on)
|
|
||||||
{
|
|
||||||
void (*func) (int) = (void (*)(int))vector[2];
|
|
||||||
|
|
||||||
return (*func) (on);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
flash_unlock (void)
|
|
||||||
{
|
|
||||||
(*vector[3]) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
flash_program_halfword (uint32_t addr, uint16_t data)
|
|
||||||
{
|
|
||||||
int (*func) (uint32_t, uint16_t) = (int (*)(uint32_t, uint16_t))vector[4];
|
|
||||||
|
|
||||||
return (*func) (addr, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
flash_erase_page (uint32_t addr)
|
|
||||||
{
|
|
||||||
int (*func) (uint32_t) = (int (*)(uint32_t))vector[5];
|
|
||||||
|
|
||||||
return (*func) (addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
flash_check_blank (const uint8_t *p_start, size_t size)
|
|
||||||
{
|
|
||||||
int (*func) (const uint8_t *, int) = (int (*)(const uint8_t *, int))vector[6];
|
|
||||||
|
|
||||||
return (*func) (p_start, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
|
|
||||||
{
|
|
||||||
int (*func) (uint32_t, const uint8_t *, size_t)
|
|
||||||
= (int (*)(uint32_t, const uint8_t *, size_t))vector[7];
|
|
||||||
|
|
||||||
return (*func) (dst_addr, src, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
flash_protect (void)
|
|
||||||
{
|
|
||||||
int (*func) (void) = (int (*)(void))vector[8];
|
|
||||||
|
|
||||||
return (*func) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __attribute__((noreturn))
|
|
||||||
flash_erase_all_and_exec (void (*entry)(void))
|
|
||||||
{
|
|
||||||
void (*func) (void (*)(void)) = (void (*)(void (*)(void)))vector[9];
|
|
||||||
|
|
||||||
(*func) (entry);
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
usb_lld_sys_init (void)
|
|
||||||
{
|
|
||||||
(*vector[10]) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
usb_lld_sys_shutdown (void)
|
|
||||||
{
|
|
||||||
(*vector[11]) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
nvic_system_reset (void)
|
|
||||||
{
|
|
||||||
(*vector[12]) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Users can override INLINE by 'attribute((used))' to have an
|
|
||||||
* implementation defined.
|
|
||||||
*/
|
|
||||||
#if !defined(INLINE)
|
|
||||||
#define INLINE __inline__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
clock_init (void)
|
|
||||||
{
|
|
||||||
(*vector[13]) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void
|
|
||||||
gpio_init (void)
|
|
||||||
{
|
|
||||||
(*vector[14]) ();
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -31,9 +31,9 @@
|
|||||||
#include "usb_lld.h"
|
#include "usb_lld.h"
|
||||||
#include "usb-msc.h"
|
#include "usb-msc.h"
|
||||||
|
|
||||||
extern uint8_t __process5_stack_base__, __process5_stack_size__;
|
extern uint8_t __process5_stack_base__[], __process5_stack_size__[];
|
||||||
const uint32_t __stackaddr_msc = (uint32_t)&__process5_stack_base__;
|
#define STACK_ADDR_MSC ((uint32_t)__process5_stack_base__)
|
||||||
const size_t __stacksize_msc = (size_t)&__process5_stack_size__;
|
#define STACK_SIZE_MSC ((uint32_t)__process5_stack_size__)
|
||||||
#define PRIO_MSC 3
|
#define PRIO_MSC 3
|
||||||
|
|
||||||
static chopstx_mutex_t a_pinpad_mutex;
|
static chopstx_mutex_t a_pinpad_mutex;
|
||||||
@@ -86,13 +86,12 @@ static void usb_start_transmit (const uint8_t *p, size_t n)
|
|||||||
|
|
||||||
/* "Data Transmitted" callback */
|
/* "Data Transmitted" callback */
|
||||||
void
|
void
|
||||||
EP6_IN_Callback (void)
|
EP6_IN_Callback (uint16_t len)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n = len;
|
||||||
|
|
||||||
chopstx_mutex_lock (msc_mutex);
|
chopstx_mutex_lock (msc_mutex);
|
||||||
|
|
||||||
n = (size_t)usb_lld_tx_data_len (ENDP6);
|
|
||||||
ep6_in.txbuf += n;
|
ep6_in.txbuf += n;
|
||||||
ep6_in.txcnt += n;
|
ep6_in.txcnt += n;
|
||||||
ep6_in.txsize -= n;
|
ep6_in.txsize -= n;
|
||||||
@@ -132,14 +131,13 @@ static void usb_start_receive (uint8_t *p, size_t n)
|
|||||||
|
|
||||||
/* "Data Received" call back */
|
/* "Data Received" call back */
|
||||||
void
|
void
|
||||||
EP6_OUT_Callback (void)
|
EP6_OUT_Callback (uint16_t len)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n = len;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
chopstx_mutex_lock (msc_mutex);
|
chopstx_mutex_lock (msc_mutex);
|
||||||
|
|
||||||
n = (size_t)usb_lld_rx_data_len (ENDP6);
|
|
||||||
if (n > ep6_out.rxsize)
|
if (n > ep6_out.rxsize)
|
||||||
{ /* buffer overflow */
|
{ /* buffer overflow */
|
||||||
err = 1;
|
err = 1;
|
||||||
@@ -570,5 +568,5 @@ msc_main (void *arg)
|
|||||||
void
|
void
|
||||||
msc_init (void)
|
msc_init (void)
|
||||||
{
|
{
|
||||||
chopstx_create (PRIO_MSC, __stackaddr_msc, __stacksize_msc, msc_main, NULL);
|
chopstx_create (PRIO_MSC, STACK_ADDR_MSC, STACK_SIZE_MSC, msc_main, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
#define SCSI_WRITE10 0x2A
|
#define SCSI_WRITE10 0x2A
|
||||||
#define SCSI_VERIFY10 0x2F
|
#define SCSI_VERIFY10 0x2F
|
||||||
#define SCSI_READ_FORMAT_CAPACITIES 0x23
|
#define SCSI_READ_FORMAT_CAPACITIES 0x23
|
||||||
|
|
||||||
#define SCSI_SYNCHRONIZE_CACHE 0x35
|
#define SCSI_SYNCHRONIZE_CACHE 0x35
|
||||||
|
#define SCSI_REPORT_LUN 0xA0
|
||||||
|
|
||||||
#define MSC_IDLE 0
|
#define MSC_IDLE 0
|
||||||
#define MSC_DATA_OUT 1
|
#define MSC_DATA_OUT 1
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#ifndef __USB_CONF_H
|
#ifndef __USB_CONF_H
|
||||||
#define __USB_CONF_H
|
#define __USB_CONF_H
|
||||||
|
|
||||||
#define ICC_NUM_INTERFACES 1
|
#define CCID_NUM_INTERFACES 1
|
||||||
#define ICC_INTERFACE 0
|
#define CCID_INTERFACE 0
|
||||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||||
#define HID_NUM_INTERFACES 1
|
#define HID_NUM_INTERFACES 1
|
||||||
#define HID_INTERFACE 1
|
#define HID_INTERFACE 1
|
||||||
@@ -13,18 +13,18 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
#define VCOM_NUM_INTERFACES 2
|
#define VCOM_NUM_INTERFACES 2
|
||||||
#define VCOM_INTERFACE_0 (ICC_NUM_INTERFACES + HID_NUM_INTERFACES)
|
#define VCOM_INTERFACE_0 (CCID_NUM_INTERFACES + HID_NUM_INTERFACES)
|
||||||
#define VCOM_INTERFACE_1 (ICC_NUM_INTERFACES + HID_NUM_INTERFACES + 1)
|
#define VCOM_INTERFACE_1 (CCID_NUM_INTERFACES + HID_NUM_INTERFACES + 1)
|
||||||
#else
|
#else
|
||||||
#define VCOM_NUM_INTERFACES 0
|
#define VCOM_NUM_INTERFACES 0
|
||||||
#endif
|
#endif
|
||||||
#ifdef PINPAD_DND_SUPPORT
|
#ifdef PINPAD_DND_SUPPORT
|
||||||
#define MSC_NUM_INTERFACES 1
|
#define MSC_NUM_INTERFACES 1
|
||||||
#define MSC_INTERFACE (ICC_NUM_INTERFACES + HID_NUM_INTERFACES + VCOM_NUM_INTERFACES)
|
#define MSC_INTERFACE (CCID_NUM_INTERFACES + HID_NUM_INTERFACES + VCOM_NUM_INTERFACES)
|
||||||
#else
|
#else
|
||||||
#define MSC_NUM_INTERFACES 0
|
#define MSC_NUM_INTERFACES 0
|
||||||
#endif
|
#endif
|
||||||
#define NUM_INTERFACES (ICC_NUM_INTERFACES + HID_NUM_INTERFACES \
|
#define NUM_INTERFACES (CCID_NUM_INTERFACES + HID_NUM_INTERFACES \
|
||||||
+ VCOM_NUM_INTERFACES + MSC_NUM_INTERFACES)
|
+ VCOM_NUM_INTERFACES + MSC_NUM_INTERFACES)
|
||||||
|
|
||||||
#if defined(USB_SELF_POWERED)
|
#if defined(USB_SELF_POWERED)
|
||||||
|
|||||||
350
src/usb_ctrl.c
350
src/usb_ctrl.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* usb_ctrl.c - USB control pipe device specific code for Gnuk
|
* usb_ctrl.c - USB control pipe device specific code for Gnuk
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015
|
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
|
||||||
* Free Software Initiative of Japan
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#include "usb_lld.h"
|
#include "usb_lld.h"
|
||||||
#include "usb_conf.h"
|
#include "usb_conf.h"
|
||||||
#include "gnuk.h"
|
#include "gnuk.h"
|
||||||
#include "stm32f103.h"
|
#include "mcu/stm32f103.h"
|
||||||
|
|
||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
#include "usb-cdc.h"
|
#include "usb-cdc.h"
|
||||||
@@ -61,47 +61,25 @@ static struct line_coding line_coding = {
|
|||||||
#define CDC_CTRL_DTR 0x0001
|
#define CDC_CTRL_DTR 0x0001
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
vcom_port_data_setup (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
if (USB_SETUP_GET (req))
|
struct device_req *arg = &dev->dev_req;
|
||||||
|
|
||||||
|
if (USB_SETUP_GET (arg->type))
|
||||||
{
|
{
|
||||||
if (req_no == USB_CDC_REQ_GET_LINE_CODING)
|
if (arg->request == USB_CDC_REQ_GET_LINE_CODING)
|
||||||
return usb_lld_reply_request (&line_coding, sizeof(line_coding), detail);
|
return usb_lld_ctrl_send (dev, &line_coding, sizeof (line_coding));
|
||||||
}
|
}
|
||||||
else /* USB_SETUP_SET (req) */
|
else /* USB_SETUP_SET (req) */
|
||||||
{
|
{
|
||||||
if (req_no == USB_CDC_REQ_SET_LINE_CODING)
|
if (arg->request == USB_CDC_REQ_SET_LINE_CODING
|
||||||
{
|
&& arg->len == sizeof (line_coding))
|
||||||
usb_lld_set_data_to_recv (&line_coding, sizeof(line_coding));
|
return usb_lld_ctrl_recv (dev, &line_coding, sizeof (line_coding));
|
||||||
return USB_SUCCESS;
|
else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||||
}
|
return usb_lld_ctrl_ack (dev);
|
||||||
else if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
|
||||||
{
|
|
||||||
uint8_t connected_saved = stdout.connected;
|
|
||||||
|
|
||||||
if ((detail->value & CDC_CTRL_DTR) != 0)
|
|
||||||
{
|
|
||||||
if (stdout.connected == 0)
|
|
||||||
/* It's Open call */
|
|
||||||
stdout.connected++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (stdout.connected)
|
|
||||||
/* Close call */
|
|
||||||
stdout.connected = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
chopstx_mutex_lock (&stdout.m_dev);
|
|
||||||
if (stdout.connected != connected_saved)
|
|
||||||
chopstx_cond_signal (&stdout.cond_dev);
|
|
||||||
chopstx_mutex_unlock (&stdout.m_dev);
|
|
||||||
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -132,7 +110,7 @@ static uint16_t hid_report;
|
|||||||
static void
|
static void
|
||||||
gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||||
{
|
{
|
||||||
if (interface == ICC_INTERFACE)
|
if (interface == CCID_INTERFACE)
|
||||||
{
|
{
|
||||||
if (!stop)
|
if (!stop)
|
||||||
{
|
{
|
||||||
@@ -195,17 +173,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
usb_cb_device_reset (void)
|
usb_device_reset (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Set DEVICE as not configured */
|
usb_lld_reset (dev, USB_INITIAL_FEATURE);
|
||||||
usb_lld_set_configuration (0);
|
|
||||||
|
|
||||||
/* Current Feature initialization */
|
|
||||||
usb_lld_set_feature (USB_INITIAL_FEATURE);
|
|
||||||
|
|
||||||
usb_lld_reset ();
|
|
||||||
|
|
||||||
/* Initialize Endpoint 0 */
|
/* Initialize Endpoint 0 */
|
||||||
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
||||||
@@ -216,7 +188,7 @@ usb_cb_device_reset (void)
|
|||||||
gnuk_setup_endpoints_for_interface (i, 1);
|
gnuk_setup_endpoints_for_interface (i, 1);
|
||||||
|
|
||||||
bDeviceState = ATTACHED;
|
bDeviceState = ATTACHED;
|
||||||
led_blink (LED_USB_RESET); /* Notify the main. */
|
ccid_usb_reset (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define USB_CCID_REQ_ABORT 0x01
|
#define USB_CCID_REQ_ABORT 0x01
|
||||||
@@ -246,7 +218,7 @@ static uint32_t rbit (uint32_t v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* After calling this function, CRC module remain enabled. */
|
/* After calling this function, CRC module remain enabled. */
|
||||||
static int download_check_crc32 (const uint32_t *end_p)
|
static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
|
||||||
{
|
{
|
||||||
uint32_t crc32 = *end_p;
|
uint32_t crc32 = *end_p;
|
||||||
const uint32_t *p;
|
const uint32_t *p;
|
||||||
@@ -258,261 +230,271 @@ static int download_check_crc32 (const uint32_t *end_p)
|
|||||||
CRC->DR = rbit (*p);
|
CRC->DR = rbit (*p);
|
||||||
|
|
||||||
if ((rbit (CRC->DR) ^ crc32) == 0xffffffff)
|
if ((rbit (CRC->DR) ^ crc32) == 0xffffffff)
|
||||||
return USB_SUCCESS;
|
return usb_lld_ctrl_ack (dev);
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
usb_setup (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
struct device_req *arg = &dev->dev_req;
|
||||||
|
uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
|
||||||
|
|
||||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
||||||
{
|
{
|
||||||
if (USB_SETUP_GET (req))
|
if (USB_SETUP_GET (arg->type))
|
||||||
{
|
{
|
||||||
if (req_no == USB_FSIJ_GNUK_MEMINFO)
|
if (arg->request == USB_FSIJ_GNUK_MEMINFO)
|
||||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), detail);
|
return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
|
||||||
}
|
}
|
||||||
else /* SETUP_SET */
|
else /* SETUP_SET */
|
||||||
{
|
{
|
||||||
uint8_t *addr = (uint8_t *)(0x20000000 + detail->value * 0x100 + detail->index);
|
uint8_t *addr = (uint8_t *)(0x20000000 + arg->value * 0x100
|
||||||
|
+ arg->index);
|
||||||
|
|
||||||
if (req_no == USB_FSIJ_GNUK_DOWNLOAD)
|
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
||||||
{
|
{
|
||||||
if (*icc_state_p != ICC_STATE_EXITED)
|
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
if (addr < &_regnual_start || addr + detail->len > __heap_end__)
|
if (addr < &_regnual_start || addr + arg->len > __heap_end__)
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
if (detail->index + detail->len < 256)
|
if (arg->index + arg->len < 256)
|
||||||
memset (addr + detail->index + detail->len, 0, 256 - (detail->index + detail->len));
|
memset (addr + arg->index + arg->len, 0,
|
||||||
|
256 - (arg->index + arg->len));
|
||||||
|
|
||||||
usb_lld_set_data_to_recv (addr, detail->len);
|
return usb_lld_ctrl_recv (dev, addr, arg->len);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else if (req_no == USB_FSIJ_GNUK_EXEC && detail->len == 0)
|
else if (arg->request == USB_FSIJ_GNUK_EXEC && arg->len == 0)
|
||||||
{
|
{
|
||||||
if (*icc_state_p != ICC_STATE_EXITED)
|
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
if (((uint32_t)addr & 0x03))
|
if (((uint32_t)addr & 0x03))
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
return download_check_crc32 ((uint32_t *)addr);
|
return download_check_crc32 (dev, (uint32_t *)addr);
|
||||||
}
|
}
|
||||||
else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && detail->len == 0)
|
else if (arg->request == USB_FSIJ_GNUK_CARD_CHANGE && arg->len == 0)
|
||||||
{
|
{
|
||||||
if (detail->value != 0 && detail->value != 1 && detail->value != 2)
|
if (arg->value != 0 && arg->value != 1 && arg->value != 2)
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
ccid_card_change_signal (detail->value);
|
ccid_card_change_signal (arg->value);
|
||||||
return USB_SUCCESS;
|
return usb_lld_ctrl_ack (dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||||
{
|
{
|
||||||
if (detail->index == ICC_INTERFACE)
|
if (arg->index == CCID_INTERFACE)
|
||||||
{
|
{
|
||||||
if (USB_SETUP_GET (req))
|
if (USB_SETUP_GET (arg->type))
|
||||||
{
|
{
|
||||||
if (req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
if (arg->request == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
||||||
return usb_lld_reply_request (freq_table, sizeof (freq_table),
|
return usb_lld_ctrl_send (dev, freq_table, sizeof (freq_table));
|
||||||
detail);
|
else if (arg->request == USB_CCID_REQ_GET_DATA_RATES)
|
||||||
else if (req_no == USB_CCID_REQ_GET_DATA_RATES)
|
return usb_lld_ctrl_send (dev, data_rate_table,
|
||||||
return usb_lld_reply_request (data_rate_table,
|
sizeof (data_rate_table));
|
||||||
sizeof (data_rate_table), detail);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (req_no == USB_CCID_REQ_ABORT)
|
if (arg->request == USB_CCID_REQ_ABORT)
|
||||||
/* wValue: bSeq, bSlot */
|
/* wValue: bSeq, bSlot */
|
||||||
/* Abortion is not supported in Gnuk */
|
/* Abortion is not supported in Gnuk */
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||||
else if (index == HID_INTERFACE)
|
else if (arg->index == HID_INTERFACE)
|
||||||
{
|
{
|
||||||
switch (req_no)
|
switch (arg->request)
|
||||||
{
|
{
|
||||||
case USB_HID_REQ_GET_IDLE:
|
case USB_HID_REQ_GET_IDLE:
|
||||||
return usb_lld_reply_request (&hid_idle_rate, 1, detail);
|
return usb_lld_ctrl_send (dev, &hid_idle_rate, 1);
|
||||||
case USB_HID_REQ_SET_IDLE:
|
case USB_HID_REQ_SET_IDLE:
|
||||||
usb_lld_set_data_to_recv (&hid_idle_rate, 1, detail);
|
return usb_lld_ctrl_recv (dev, &hid_idle_rate, 1);
|
||||||
return USB_SUCCESS;
|
|
||||||
|
|
||||||
case USB_HID_REQ_GET_REPORT:
|
case USB_HID_REQ_GET_REPORT:
|
||||||
/* Request of LED status and key press */
|
/* Request of LED status and key press */
|
||||||
return usb_lld_reply_request (&hid_report, 2, detail);
|
return usb_lld_ctrl_send (dev, &hid_report, 2);
|
||||||
|
|
||||||
case USB_HID_REQ_SET_REPORT:
|
case USB_HID_REQ_SET_REPORT:
|
||||||
/* Received LED set request */
|
/* Received LED set request */
|
||||||
if (detail->len == 1)
|
if (arg->len == 1)
|
||||||
usb_lld_set_data_to_recv (&hid_report, detail->len);
|
return usb_lld_ctrl_recv (dev, &hid_report, arg->len);
|
||||||
return USB_SUCCESS;
|
else
|
||||||
|
return usb_lld_ctrl_ack (dev);
|
||||||
|
|
||||||
case USB_HID_REQ_GET_PROTOCOL:
|
case USB_HID_REQ_GET_PROTOCOL:
|
||||||
case USB_HID_REQ_SET_PROTOCOL:
|
case USB_HID_REQ_SET_PROTOCOL:
|
||||||
/* This driver doesn't support boot protocol. */
|
/* This driver doesn't support boot protocol. */
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
else if (index == VCOM_INTERFACE_0)
|
else if (arg->index == VCOM_INTERFACE_0)
|
||||||
return vcom_port_data_setup (req, req_no, detail);
|
return vcom_port_data_setup (dev);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PINPAD_DND_SUPPORT
|
#ifdef PINPAD_DND_SUPPORT
|
||||||
else if (index == MSC_INTERFACE)
|
else if (arg->index == MSC_INTERFACE)
|
||||||
{
|
{
|
||||||
if (USB_SETUP_GET (req))
|
if (USB_SETUP_GET (arg->type))
|
||||||
{
|
{
|
||||||
if (req_no == MSC_GET_MAX_LUN_COMMAND)
|
if (arg->request == MSC_GET_MAX_LUN_COMMAND)
|
||||||
return usb_lld_reply_request (lun_table, sizeof (lun_table),
|
return usb_lld_ctrl_send (dev, lun_table, sizeof (lun_table));
|
||||||
detail);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (req_no == MSC_MASS_STORAGE_RESET_COMMAND)
|
if (arg->request == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||||
/* Should call resetting MSC thread, something like msc_reset() */
|
return usb_lld_ctrl_ack (dev);
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
usb_ctrl_write_finish (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
struct device_req *arg = &dev->dev_req;
|
||||||
|
uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
|
||||||
|
|
||||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
||||||
{
|
{
|
||||||
if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC)
|
if (USB_SETUP_SET (arg->type) && arg->request == USB_FSIJ_GNUK_EXEC)
|
||||||
{
|
{
|
||||||
if (*icc_state_p != ICC_STATE_EXITED)
|
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(void)value; (void)index;
|
bDeviceState = UNCONNECTED;
|
||||||
usb_lld_prepare_shutdown (); /* No further USB communication */
|
usb_lld_prepare_shutdown (); /* No further USB communication */
|
||||||
led_blink (LED_GNUK_EXEC); /* Notify the main. */
|
led_blink (LED_GNUK_EXEC); /* Notify the main. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
#if defined(HID_CARD_CHANGE_SUPPORT) || defined (ENABLE_VIRTUAL_COM_PORT)
|
||||||
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||||
{
|
{
|
||||||
if (index == HID_INTERFACE && req_no == USB_HID_REQ_SET_REPORT)
|
# if defined(ENABLE_VIRTUAL_COM_PORT)
|
||||||
|
if (arg->index == VCOM_INTERFACE_0 && USB_SETUP_SET (arg->type)
|
||||||
|
&& arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||||
|
{
|
||||||
|
uint8_t connected_saved = stdout.connected;
|
||||||
|
|
||||||
|
if ((arg->value & CDC_CTRL_DTR) != 0)
|
||||||
|
{
|
||||||
|
if (stdout.connected == 0)
|
||||||
|
/* It's Open call */
|
||||||
|
stdout.connected++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (stdout.connected)
|
||||||
|
/* Close call */
|
||||||
|
stdout.connected = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
chopstx_mutex_lock (&stdout.m_dev);
|
||||||
|
if (stdout.connected != connected_saved)
|
||||||
|
chopstx_cond_signal (&stdout.cond_dev);
|
||||||
|
chopstx_mutex_unlock (&stdout.m_dev);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# if defined(HID_CARD_CHANGE_SUPPORT)
|
||||||
|
if (arg->index == HID_INTERFACE && arg->request == USB_HID_REQ_SET_REPORT)
|
||||||
{
|
{
|
||||||
if ((hid_report ^ hid_report_saved) & HID_LED_STATUS_CARDCHANGE)
|
if ((hid_report ^ hid_report_saved) & HID_LED_STATUS_CARDCHANGE)
|
||||||
ccid_card_change_signal (CARD_CHANGE_TOGGLE);
|
ccid_card_change_signal (CARD_CHANGE_TOGGLE);
|
||||||
|
|
||||||
hid_report_saved = hid_report;
|
hid_report_saved = hid_report;
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
int
|
||||||
|
usb_set_configuration (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t current_conf;
|
uint8_t current_conf;
|
||||||
|
|
||||||
switch (event_type)
|
current_conf = usb_lld_current_configuration (dev);
|
||||||
|
if (current_conf == 0)
|
||||||
{
|
{
|
||||||
case USB_EVENT_ADDRESS:
|
if (dev->dev_req.value != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
usb_lld_set_configuration (dev, 1);
|
||||||
|
for (i = 0; i < NUM_INTERFACES; i++)
|
||||||
|
gnuk_setup_endpoints_for_interface (i, 0);
|
||||||
|
bDeviceState = CONFIGURED;
|
||||||
|
}
|
||||||
|
else if (current_conf != dev->dev_req.value)
|
||||||
|
{
|
||||||
|
if (dev->dev_req.value != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
usb_lld_set_configuration (dev, 0);
|
||||||
|
for (i = 0; i < NUM_INTERFACES; i++)
|
||||||
|
gnuk_setup_endpoints_for_interface (i, 1);
|
||||||
bDeviceState = ADDRESSED;
|
bDeviceState = ADDRESSED;
|
||||||
return USB_SUCCESS;
|
ccid_usb_reset (1);
|
||||||
case USB_EVENT_CONFIG:
|
|
||||||
current_conf = usb_lld_current_configuration ();
|
|
||||||
if (current_conf == 0)
|
|
||||||
{
|
|
||||||
if (value != 1)
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
|
|
||||||
usb_lld_set_configuration (value);
|
|
||||||
for (i = 0; i < NUM_INTERFACES; i++)
|
|
||||||
gnuk_setup_endpoints_for_interface (i, 0);
|
|
||||||
ccid_card_change_signal (CCID_CARD_INIT);
|
|
||||||
bDeviceState = CONFIGURED;
|
|
||||||
}
|
|
||||||
else if (current_conf != value)
|
|
||||||
{
|
|
||||||
if (value != 0)
|
|
||||||
return USB_UNSUPPORT;
|
|
||||||
|
|
||||||
usb_lld_set_configuration (0);
|
|
||||||
for (i = 0; i < NUM_INTERFACES; i++)
|
|
||||||
gnuk_setup_endpoints_for_interface (i, 1);
|
|
||||||
bDeviceState = ADDRESSED;
|
|
||||||
}
|
|
||||||
/* Do nothing when current_conf == value */
|
|
||||||
return USB_SUCCESS;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
/* Do nothing when current_conf == value */
|
||||||
|
return usb_lld_ctrl_ack (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
|
||||||
|
int
|
||||||
|
usb_set_interface (struct usb_dev *dev)
|
||||||
{
|
{
|
||||||
const uint8_t zero = 0;
|
uint16_t interface = dev->dev_req.index;
|
||||||
uint16_t interface = detail->index;
|
uint16_t alt = dev->dev_req.value;
|
||||||
uint16_t alt = detail->value;
|
|
||||||
|
|
||||||
if (interface >= NUM_INTERFACES)
|
if (interface >= NUM_INTERFACES)
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
|
|
||||||
switch (cmd)
|
if (alt != 0)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case USB_SET_INTERFACE:
|
gnuk_setup_endpoints_for_interface (interface, 0);
|
||||||
if (alt != 0)
|
ccid_usb_reset (0);
|
||||||
return USB_UNSUPPORT;
|
return usb_lld_ctrl_ack (dev);
|
||||||
else
|
|
||||||
{
|
|
||||||
gnuk_setup_endpoints_for_interface (interface, 0);
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
case USB_GET_INTERFACE:
|
|
||||||
return usb_lld_reply_request (&zero, 1, detail);
|
|
||||||
|
|
||||||
case USB_QUERY_INTERFACE:
|
|
||||||
default:
|
|
||||||
return USB_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define INTR_REQ_USB 20
|
int
|
||||||
|
usb_get_interface (struct usb_dev *dev)
|
||||||
void *
|
|
||||||
usb_intr (void *arg)
|
|
||||||
{
|
{
|
||||||
chopstx_intr_t interrupt;
|
const uint8_t zero = 0;
|
||||||
|
uint16_t interface = dev->dev_req.index;
|
||||||
|
|
||||||
(void)arg;
|
if (interface >= NUM_INTERFACES)
|
||||||
usb_lld_init (USB_INITIAL_FEATURE);
|
return -1;
|
||||||
chopstx_claim_irq (&interrupt, INTR_REQ_USB);
|
|
||||||
usb_interrupt_handler ();
|
|
||||||
|
|
||||||
while (1)
|
return usb_lld_ctrl_send (dev, &zero, 1);
|
||||||
{
|
}
|
||||||
chopstx_intr_wait (&interrupt);
|
|
||||||
|
int
|
||||||
/* Process interrupt. */
|
usb_get_status_interface (struct usb_dev *dev)
|
||||||
usb_interrupt_handler ();
|
{
|
||||||
}
|
const uint16_t status_info = 0;
|
||||||
|
uint16_t interface = dev->dev_req.index;
|
||||||
return NULL;
|
|
||||||
|
if (interface >= NUM_INTERFACES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return usb_lld_ctrl_send (dev, &status_info, 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,15 +53,15 @@ static const uint8_t hid_report_desc[] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define USB_ICC_INTERFACE_CLASS 0x0B
|
#define USB_CCID_INTERFACE_CLASS 0x0B
|
||||||
#define USB_ICC_INTERFACE_SUBCLASS 0x00
|
#define USB_CCID_INTERFACE_SUBCLASS 0x00
|
||||||
#define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00
|
#define USB_CCID_INTERFACE_BULK_PROTOCOL 0x00
|
||||||
#define USB_ICC_DATA_SIZE 64
|
#define USB_CCID_DATA_SIZE 64
|
||||||
|
|
||||||
/* USB Standard Device Descriptor */
|
/* USB Standard Device Descriptor */
|
||||||
static const uint8_t device_desc[] = {
|
static const uint8_t device_desc[] = {
|
||||||
18, /* bLength */
|
18, /* bLength */
|
||||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||||
0x00, /* bDeviceClass: 0 means deferred to interface */
|
0x00, /* bDeviceClass: 0 means deferred to interface */
|
||||||
0x00, /* bDeviceSubClass */
|
0x00, /* bDeviceSubClass */
|
||||||
@@ -74,7 +74,7 @@ static const uint8_t device_desc[] = {
|
|||||||
0x01 /* bNumConfigurations */
|
0x01 /* bNumConfigurations */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ICC_TOTAL_LENGTH (9+9+54+7+7+7)
|
#define CCID_TOTAL_LENGTH (9+9+54+7+7+7)
|
||||||
|
|
||||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||||
#define HID_TOTAL_LENGTH (9+9+7)
|
#define HID_TOTAL_LENGTH (9+9+7)
|
||||||
@@ -94,16 +94,16 @@ static const uint8_t device_desc[] = {
|
|||||||
#define MSC_TOTAL_LENGTH 0
|
#define MSC_TOTAL_LENGTH 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define W_TOTAL_LENGTH (ICC_TOTAL_LENGTH + HID_TOTAL_LENGTH \
|
#define W_TOTAL_LENGTH (CCID_TOTAL_LENGTH + HID_TOTAL_LENGTH \
|
||||||
+ VCOM_TOTAL_LENGTH + MSC_TOTAL_LENGTH)
|
+ VCOM_TOTAL_LENGTH + MSC_TOTAL_LENGTH)
|
||||||
|
|
||||||
|
|
||||||
/* Configuation Descriptor */
|
/* Configuation Descriptor */
|
||||||
static const uint8_t config_desc[] = {
|
static const uint8_t config_desc[] = {
|
||||||
9, /* bLength: Configuation Descriptor size */
|
9, /* bLength: Configuation Descriptor size */
|
||||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
|
||||||
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
|
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
|
||||||
NUM_INTERFACES, /* bNumInterfaces: */
|
NUM_INTERFACES, /* bNumInterfaces: */
|
||||||
0x01, /* bConfigurationValue: Configuration value */
|
0x01, /* bConfigurationValue: Configuration value */
|
||||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||||
USB_INITIAL_FEATURE, /* bmAttributes*/
|
USB_INITIAL_FEATURE, /* bmAttributes*/
|
||||||
@@ -111,13 +111,13 @@ static const uint8_t config_desc[] = {
|
|||||||
|
|
||||||
/* Interface Descriptor */
|
/* Interface Descriptor */
|
||||||
9, /* bLength: Interface Descriptor size */
|
9, /* bLength: Interface Descriptor size */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||||
ICC_INTERFACE, /* bInterfaceNumber: Index of this interface */
|
CCID_INTERFACE, /* bInterfaceNumber: Index of this interface */
|
||||||
0, /* Alternate setting for this interface */
|
0, /* Alternate setting for this interface */
|
||||||
3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
|
3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
|
||||||
USB_ICC_INTERFACE_CLASS,
|
USB_CCID_INTERFACE_CLASS,
|
||||||
USB_ICC_INTERFACE_SUBCLASS,
|
USB_CCID_INTERFACE_SUBCLASS,
|
||||||
USB_ICC_INTERFACE_BULK_PROTOCOL,
|
USB_CCID_INTERFACE_BULK_PROTOCOL,
|
||||||
0, /* string index for interface */
|
0, /* string index for interface */
|
||||||
|
|
||||||
/* ICC Descriptor */
|
/* ICC Descriptor */
|
||||||
@@ -167,21 +167,21 @@ static const uint8_t config_desc[] = {
|
|||||||
1, /* bMaxCCIDBusySlots: 1 */
|
1, /* bMaxCCIDBusySlots: 1 */
|
||||||
/*Endpoint IN1 Descriptor*/
|
/*Endpoint IN1 Descriptor*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x81, /* bEndpointAddress: (IN1) */
|
0x81, /* bEndpointAddress: (IN1) */
|
||||||
0x02, /* bmAttributes: Bulk */
|
0x02, /* bmAttributes: Bulk */
|
||||||
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
USB_CCID_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||||
0x00, /* bInterval */
|
0x00, /* bInterval */
|
||||||
/*Endpoint OUT1 Descriptor*/
|
/*Endpoint OUT1 Descriptor*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x01, /* bEndpointAddress: (OUT1) */
|
0x01, /* bEndpointAddress: (OUT1) */
|
||||||
0x02, /* bmAttributes: Bulk */
|
0x02, /* bmAttributes: Bulk */
|
||||||
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
USB_CCID_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||||
0x00, /* bInterval */
|
0x00, /* bInterval */
|
||||||
/*Endpoint IN2 Descriptor*/
|
/*Endpoint IN2 Descriptor*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x82, /* bEndpointAddress: (IN2) */
|
0x82, /* bEndpointAddress: (IN2) */
|
||||||
0x03, /* bmAttributes: Interrupt */
|
0x03, /* bmAttributes: Interrupt */
|
||||||
0x04, 0x00, /* wMaxPacketSize: 4 */
|
0x04, 0x00, /* wMaxPacketSize: 4 */
|
||||||
@@ -190,7 +190,7 @@ static const uint8_t config_desc[] = {
|
|||||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||||
/* Interface Descriptor */
|
/* Interface Descriptor */
|
||||||
9, /* bLength: Interface Descriptor size */
|
9, /* bLength: Interface Descriptor size */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||||
HID_INTERFACE, /* bInterfaceNumber: Number of Interface */
|
HID_INTERFACE, /* bInterfaceNumber: Number of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x01, /* bNumEndpoints: One endpoint used */
|
0x01, /* bNumEndpoints: One endpoint used */
|
||||||
@@ -209,7 +209,7 @@ static const uint8_t config_desc[] = {
|
|||||||
|
|
||||||
/*Endpoint IN7 Descriptor*/
|
/*Endpoint IN7 Descriptor*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x87, /* bEndpointAddress: (IN7) */
|
0x87, /* bEndpointAddress: (IN7) */
|
||||||
0x03, /* bmAttributes: Interrupt */
|
0x03, /* bmAttributes: Interrupt */
|
||||||
0x02, 0x00, /* wMaxPacketSize: 2 */
|
0x02, 0x00, /* wMaxPacketSize: 2 */
|
||||||
@@ -219,7 +219,7 @@ static const uint8_t config_desc[] = {
|
|||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
/* Interface Descriptor */
|
/* Interface Descriptor */
|
||||||
9, /* bLength: Interface Descriptor size */
|
9, /* bLength: Interface Descriptor size */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||||
VCOM_INTERFACE_0, /* bInterfaceNumber: Index of Interface */
|
VCOM_INTERFACE_0, /* bInterfaceNumber: Index of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x01, /* bNumEndpoints: One endpoints used */
|
0x01, /* bNumEndpoints: One endpoints used */
|
||||||
@@ -251,7 +251,7 @@ static const uint8_t config_desc[] = {
|
|||||||
VCOM_INTERFACE_1, /* bSlaveInterface0: Data Class Interface */
|
VCOM_INTERFACE_1, /* bSlaveInterface0: Data Class Interface */
|
||||||
/*Endpoint 4 Descriptor*/
|
/*Endpoint 4 Descriptor*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x84, /* bEndpointAddress: (IN4) */
|
0x84, /* bEndpointAddress: (IN4) */
|
||||||
0x03, /* bmAttributes: Interrupt */
|
0x03, /* bmAttributes: Interrupt */
|
||||||
VIRTUAL_COM_PORT_INT_SIZE, 0x00, /* wMaxPacketSize: */
|
VIRTUAL_COM_PORT_INT_SIZE, 0x00, /* wMaxPacketSize: */
|
||||||
@@ -259,7 +259,7 @@ static const uint8_t config_desc[] = {
|
|||||||
|
|
||||||
/*Data class interface descriptor*/
|
/*Data class interface descriptor*/
|
||||||
9, /* bLength: Endpoint Descriptor size */
|
9, /* bLength: Endpoint Descriptor size */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
|
INTERFACE_DESCRIPTOR, /* bDescriptorType: */
|
||||||
VCOM_INTERFACE_1, /* bInterfaceNumber: Index of Interface */
|
VCOM_INTERFACE_1, /* bInterfaceNumber: Index of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x02, /* bNumEndpoints: Two endpoints used */
|
0x02, /* bNumEndpoints: Two endpoints used */
|
||||||
@@ -269,14 +269,14 @@ static const uint8_t config_desc[] = {
|
|||||||
0x00, /* iInterface: */
|
0x00, /* iInterface: */
|
||||||
/*Endpoint 5 Descriptor*/
|
/*Endpoint 5 Descriptor*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x05, /* bEndpointAddress: (OUT5) */
|
0x05, /* bEndpointAddress: (OUT5) */
|
||||||
0x02, /* bmAttributes: Bulk */
|
0x02, /* bmAttributes: Bulk */
|
||||||
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||||
0x00, /* bInterval: ignore for Bulk transfer */
|
0x00, /* bInterval: ignore for Bulk transfer */
|
||||||
/*Endpoint 3 Descriptor*/
|
/*Endpoint 3 Descriptor*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x83, /* bEndpointAddress: (IN3) */
|
0x83, /* bEndpointAddress: (IN3) */
|
||||||
0x02, /* bmAttributes: Bulk */
|
0x02, /* bmAttributes: Bulk */
|
||||||
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||||
@@ -285,7 +285,7 @@ static const uint8_t config_desc[] = {
|
|||||||
#ifdef PINPAD_DND_SUPPORT
|
#ifdef PINPAD_DND_SUPPORT
|
||||||
/* Interface Descriptor.*/
|
/* Interface Descriptor.*/
|
||||||
9, /* bLength: Interface Descriptor size */
|
9, /* bLength: Interface Descriptor size */
|
||||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||||
MSC_INTERFACE, /* bInterfaceNumber. */
|
MSC_INTERFACE, /* bInterfaceNumber. */
|
||||||
0x00, /* bAlternateSetting. */
|
0x00, /* bAlternateSetting. */
|
||||||
0x02, /* bNumEndpoints. */
|
0x02, /* bNumEndpoints. */
|
||||||
@@ -298,14 +298,14 @@ static const uint8_t config_desc[] = {
|
|||||||
0x00, /* iInterface. */
|
0x00, /* iInterface. */
|
||||||
/* Endpoint Descriptor.*/
|
/* Endpoint Descriptor.*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x86, /* bEndpointAddress: (IN6) */
|
0x86, /* bEndpointAddress: (IN6) */
|
||||||
0x02, /* bmAttributes (Bulk). */
|
0x02, /* bmAttributes (Bulk). */
|
||||||
0x40, 0x00, /* wMaxPacketSize. */
|
0x40, 0x00, /* wMaxPacketSize. */
|
||||||
0x00, /* bInterval (ignored for bulk). */
|
0x00, /* bInterval (ignored for bulk). */
|
||||||
/* Endpoint Descriptor.*/
|
/* Endpoint Descriptor.*/
|
||||||
7, /* bLength: Endpoint Descriptor size */
|
7, /* bLength: Endpoint Descriptor size */
|
||||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||||
0x06, /* bEndpointAddress: (OUT6) */
|
0x06, /* bEndpointAddress: (OUT6) */
|
||||||
0x02, /* bmAttributes (Bulk). */
|
0x02, /* bmAttributes (Bulk). */
|
||||||
0x40, 0x00, /* wMaxPacketSize. */
|
0x40, 0x00, /* wMaxPacketSize. */
|
||||||
@@ -317,7 +317,7 @@ static const uint8_t config_desc[] = {
|
|||||||
/* USB String Descriptors */
|
/* USB String Descriptors */
|
||||||
static const uint8_t gnuk_string_lang_id[] = {
|
static const uint8_t gnuk_string_lang_id[] = {
|
||||||
4, /* bLength */
|
4, /* bLength */
|
||||||
USB_STRING_DESCRIPTOR_TYPE,
|
STRING_DESCRIPTOR,
|
||||||
0x09, 0x04 /* LangID = 0x0409: US-English */
|
0x09, 0x04 /* LangID = 0x0409: US-English */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -345,21 +345,25 @@ static const struct desc string_descriptors[] = {
|
|||||||
#define USB_DT_REPORT 0x22
|
#define USB_DT_REPORT 0x22
|
||||||
|
|
||||||
int
|
int
|
||||||
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
usb_get_descriptor (struct usb_dev *dev)
|
||||||
struct control_info *detail)
|
|
||||||
{
|
{
|
||||||
|
struct device_req *arg = &dev->dev_req;
|
||||||
|
uint8_t rcp = arg->type & RECIPIENT;
|
||||||
|
uint8_t desc_type = (arg->value >> 8);
|
||||||
|
uint8_t desc_index = (arg->value & 0xff);
|
||||||
|
|
||||||
if (rcp == DEVICE_RECIPIENT)
|
if (rcp == DEVICE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (desc_type == DEVICE_DESCRIPTOR)
|
if (desc_type == DEVICE_DESCRIPTOR)
|
||||||
return usb_lld_reply_request (device_desc, sizeof (device_desc), detail);
|
return usb_lld_ctrl_send (dev, device_desc, sizeof (device_desc));
|
||||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||||
return usb_lld_reply_request (config_desc, sizeof (config_desc), detail);
|
return usb_lld_ctrl_send (dev, config_desc, sizeof (config_desc));
|
||||||
else if (desc_type == STRING_DESCRIPTOR)
|
else if (desc_type == STRING_DESCRIPTOR)
|
||||||
{
|
{
|
||||||
if (desc_index < NUM_STRING_DESC)
|
if (desc_index < NUM_STRING_DESC)
|
||||||
return usb_lld_reply_request (string_descriptors[desc_index].desc,
|
return usb_lld_ctrl_send (dev, string_descriptors[desc_index].desc,
|
||||||
string_descriptors[desc_index].size,
|
string_descriptors[desc_index].size);
|
||||||
detail);
|
#ifdef USE_SYS3
|
||||||
else if (desc_index == NUM_STRING_DESC)
|
else if (desc_index == NUM_STRING_DESC)
|
||||||
{
|
{
|
||||||
uint8_t usbbuf[64];
|
uint8_t usbbuf[64];
|
||||||
@@ -375,25 +379,25 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
|||||||
usbbuf[i*2+3] = 0;
|
usbbuf[i*2+3] = 0;
|
||||||
}
|
}
|
||||||
usbbuf[0] = len = i*2 + 2;
|
usbbuf[0] = len = i*2 + 2;
|
||||||
usbbuf[1] = USB_STRING_DESCRIPTOR_TYPE;
|
usbbuf[1] = STRING_DESCRIPTOR;
|
||||||
return usb_lld_reply_request (usbbuf, len, detail);
|
return usb_lld_ctrl_send (dev, usbbuf, len);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||||
else if (rcp == INTERFACE_RECIPIENT)
|
else if (rcp == INTERFACE_RECIPIENT)
|
||||||
{
|
{
|
||||||
if (detail->index == 1)
|
if (arg->index == HID_INTERFACE)
|
||||||
{
|
{
|
||||||
if (desc_type == USB_DT_HID)
|
if (desc_type == USB_DT_HID)
|
||||||
return usb_lld_reply_request (config_desc+ICC_TOTAL_LENGTH+9, 9,
|
return usb_lld_ctrl_send (dev, config_desc+CCID_TOTAL_LENGTH+9, 9);
|
||||||
detail);
|
|
||||||
else if (desc_type == USB_DT_REPORT)
|
else if (desc_type == USB_DT_REPORT)
|
||||||
return usb_lld_reply_request (hid_report_desc, HID_REPORT_DESC_SIZE,
|
return usb_lld_ctrl_send (dev, hid_report_desc,
|
||||||
detail);
|
HID_REPORT_DESC_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return USB_UNSUPPORT;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
122
src/usb_lld.h
122
src/usb_lld.h
@@ -1,122 +0,0 @@
|
|||||||
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
|
|
||||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
|
|
||||||
#define USB_STRING_DESCRIPTOR_TYPE 0x03
|
|
||||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
|
|
||||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
|
|
||||||
|
|
||||||
#define STANDARD_ENDPOINT_DESC_SIZE 0x09
|
|
||||||
|
|
||||||
/* endpoints enumeration */
|
|
||||||
#define ENDP0 ((uint8_t)0)
|
|
||||||
#define ENDP1 ((uint8_t)1)
|
|
||||||
#define ENDP2 ((uint8_t)2)
|
|
||||||
#define ENDP3 ((uint8_t)3)
|
|
||||||
#define ENDP4 ((uint8_t)4)
|
|
||||||
#define ENDP5 ((uint8_t)5)
|
|
||||||
#define ENDP6 ((uint8_t)6)
|
|
||||||
#define ENDP7 ((uint8_t)7)
|
|
||||||
|
|
||||||
/* EP_TYPE[1:0] EndPoint TYPE */
|
|
||||||
#define EP_BULK (0x0000) /* EndPoint BULK */
|
|
||||||
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
|
|
||||||
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
|
|
||||||
#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
|
|
||||||
|
|
||||||
enum RECIPIENT_TYPE
|
|
||||||
{
|
|
||||||
DEVICE_RECIPIENT, /* Recipient device */
|
|
||||||
INTERFACE_RECIPIENT, /* Recipient interface */
|
|
||||||
ENDPOINT_RECIPIENT, /* Recipient endpoint */
|
|
||||||
OTHER_RECIPIENT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DESCRIPTOR_TYPE
|
|
||||||
{
|
|
||||||
DEVICE_DESCRIPTOR = 1,
|
|
||||||
CONFIG_DESCRIPTOR,
|
|
||||||
STRING_DESCRIPTOR,
|
|
||||||
INTERFACE_DESCRIPTOR,
|
|
||||||
ENDPOINT_DESCRIPTOR
|
|
||||||
};
|
|
||||||
|
|
||||||
#define REQUEST_DIR 0x80 /* Mask to get request dir */
|
|
||||||
#define REQUEST_TYPE 0x60 /* Mask to get request type */
|
|
||||||
#define STANDARD_REQUEST 0x00 /* Standard request */
|
|
||||||
#define CLASS_REQUEST 0x20 /* Class request */
|
|
||||||
#define VENDOR_REQUEST 0x40 /* Vendor request */
|
|
||||||
#define RECIPIENT 0x1F /* Mask to get recipient */
|
|
||||||
|
|
||||||
#define USB_SETUP_SET(req) ((req & REQUEST_DIR) == 0)
|
|
||||||
#define USB_SETUP_GET(req) ((req & REQUEST_DIR) != 0)
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
USB_UNSUPPORT = 0,
|
|
||||||
USB_SUCCESS = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct control_info {
|
|
||||||
uint16_t value;
|
|
||||||
uint16_t index;
|
|
||||||
uint16_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
void usb_cb_device_reset (void);
|
|
||||||
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,
|
|
||||||
struct control_info *detail);
|
|
||||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
|
|
||||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
USB_EVENT_ADDRESS,
|
|
||||||
USB_EVENT_CONFIG,
|
|
||||||
USB_EVENT_SUSPEND,
|
|
||||||
USB_EVENT_WAKEUP,
|
|
||||||
USB_EVENT_STALL,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
USB_SET_INTERFACE,
|
|
||||||
USB_GET_INTERFACE,
|
|
||||||
USB_QUERY_INTERFACE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DEVICE_STATE
|
|
||||||
{
|
|
||||||
UNCONNECTED,
|
|
||||||
ATTACHED,
|
|
||||||
POWERED,
|
|
||||||
SUSPENDED,
|
|
||||||
ADDRESSED,
|
|
||||||
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);
|
|
||||||
void usb_lld_stall_tx (int ep_num);
|
|
||||||
void usb_lld_stall_rx (int ep_num);
|
|
||||||
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);
|
|
||||||
void usb_lld_reset (void);
|
|
||||||
void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
|
|
||||||
int ep_rx_addr, int ep_tx_addr,
|
|
||||||
int ep_rx_memory_size);
|
|
||||||
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_recv (const void *p, size_t len);
|
|
||||||
|
|
||||||
void usb_lld_prepare_shutdown (void);
|
|
||||||
void usb_lld_shutdown (void);
|
|
||||||
|
|
||||||
void usb_interrupt_handler (void);
|
|
||||||
1168
src/usb_stm32f103.c
1168
src/usb_stm32f103.c
File diff suppressed because it is too large
Load Diff
@@ -67,9 +67,7 @@ class gnuk_token(object):
|
|||||||
if interface.interfaceSubClass != CCID_SUBCLASS:
|
if interface.interfaceSubClass != CCID_SUBCLASS:
|
||||||
raise ValueError("Wrong interface sub class")
|
raise ValueError("Wrong interface sub class")
|
||||||
self.__devhandle = device.open()
|
self.__devhandle = device.open()
|
||||||
self.__devhandle.setConfiguration(configuration.value)
|
|
||||||
self.__devhandle.claimInterface(interface)
|
self.__devhandle.claimInterface(interface)
|
||||||
self.__devhandle.setAltInterface(0)
|
|
||||||
|
|
||||||
self.__intf = interface.interfaceNumber
|
self.__intf = interface.interfaceNumber
|
||||||
self.__alt = interface.alternateSetting
|
self.__alt = interface.alternateSetting
|
||||||
@@ -473,12 +471,7 @@ class regnual(object):
|
|||||||
if intf.interfaceClass != 0xff:
|
if intf.interfaceClass != 0xff:
|
||||||
raise ValueError("Wrong interface class")
|
raise ValueError("Wrong interface class")
|
||||||
self.__devhandle = dev.open()
|
self.__devhandle = dev.open()
|
||||||
try:
|
|
||||||
self.__devhandle.setConfiguration(conf)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.__devhandle.claimInterface(intf)
|
self.__devhandle.claimInterface(intf)
|
||||||
self.__devhandle.setAltInterface(0)
|
|
||||||
|
|
||||||
def mem_info(self):
|
def mem_info(self):
|
||||||
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
|
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
|
||||||
|
|||||||
@@ -146,15 +146,7 @@ class stlinkv2(object):
|
|||||||
if intf.interfaceClass != 0xff: # Vendor specific
|
if intf.interfaceClass != 0xff: # Vendor specific
|
||||||
raise ValueError("Wrong interface class.", intf.interfaceClass)
|
raise ValueError("Wrong interface class.", intf.interfaceClass)
|
||||||
self.__devhandle = dev.open()
|
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.value)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.__devhandle.claimInterface(intf.interfaceNumber)
|
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):
|
def shutdown(self):
|
||||||
self.__devhandle.releaseInterface()
|
self.__devhandle.releaseInterface()
|
||||||
|
|||||||
Reference in New Issue
Block a user