Compare commits
228 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad704edc4e | ||
|
|
97a1870e6e | ||
|
|
f72e132967 | ||
|
|
a22b695f96 | ||
|
|
0c901d8052 | ||
|
|
a1b8e7f40c | ||
|
|
dccda32b93 | ||
|
|
75049ce949 | ||
|
|
be80a3ef2f | ||
|
|
94424e85c3 | ||
|
|
43980d1c81 | ||
|
|
183cec8a04 | ||
|
|
7bae61f300 | ||
|
|
7e4ee2b361 | ||
|
|
30fde2a0f0 | ||
|
|
eee8d046a9 | ||
|
|
550010f25f | ||
|
|
3adbe30c4d | ||
|
|
d9ec8778fc | ||
|
|
eff0c7077d | ||
|
|
289d3db8c4 | ||
|
|
7c5eb7efd2 | ||
|
|
6f1fbdd82d | ||
|
|
cbedf98a52 | ||
|
|
15689b5b86 | ||
|
|
8170b60ee2 | ||
|
|
ca7f4c8758 | ||
|
|
0b4099d6d1 | ||
|
|
65fee7eb2a | ||
|
|
0c229f5712 | ||
|
|
5948f6ec50 | ||
|
|
7b1ea00307 | ||
|
|
277be86958 | ||
|
|
a6b90ad648 | ||
|
|
547e263d6b | ||
|
|
7004453669 | ||
|
|
81b18f2db4 | ||
|
|
86715dd4fe | ||
|
|
62f27f319c | ||
|
|
7345f3c241 | ||
|
|
f4b9073b11 | ||
|
|
6678ac28c2 | ||
|
|
83414a747a | ||
|
|
8a615d087b | ||
|
|
967b949967 | ||
|
|
11afbdde14 | ||
|
|
328766af12 | ||
|
|
2b340ee1c5 | ||
|
|
86e6adf47e | ||
|
|
eea011fe70 | ||
|
|
e736227de7 | ||
|
|
22156ea7f9 | ||
|
|
db45e62ebe | ||
|
|
3270740631 | ||
|
|
e4e72a29ae | ||
|
|
25d3f021c1 | ||
|
|
ae76d66d53 | ||
|
|
10c5010141 | ||
|
|
d12483c3c9 | ||
|
|
67acb670d1 | ||
|
|
a44244b27e | ||
|
|
2622840e27 | ||
|
|
a51ac8593b | ||
|
|
de81caba3e | ||
|
|
fa69a85826 | ||
|
|
5c3c3e3001 | ||
|
|
6dcb4dd027 | ||
|
|
fa08f44cac | ||
|
|
4c2294ea6c | ||
|
|
86eaa26d32 | ||
|
|
9e52789203 | ||
|
|
702bc8cbde | ||
|
|
2cfce76d91 | ||
|
|
207652246a | ||
|
|
32779b6f96 | ||
|
|
55c1015faa | ||
|
|
0932465f0b | ||
|
|
4417799a51 | ||
|
|
b424cecf1e | ||
|
|
7ef417ae36 | ||
|
|
d4469c24ec | ||
|
|
e4333c6580 | ||
|
|
d2261d53e3 | ||
|
|
27bd37781a | ||
|
|
bed43d4049 | ||
|
|
f7d857b527 | ||
|
|
350528e1f4 | ||
|
|
4de605ed63 | ||
|
|
ffa9bf1f94 | ||
|
|
34d0b34144 | ||
|
|
5795dc9877 | ||
|
|
c8b17a8759 | ||
|
|
38d70e277b | ||
|
|
b00bab8dbf | ||
|
|
3c91dce8b7 | ||
|
|
f1773c146b | ||
|
|
979992c046 | ||
|
|
50700e3887 | ||
|
|
b0ee8b4452 | ||
|
|
a73f8cf4fd | ||
|
|
c1cc75f5b0 | ||
|
|
47150b5c98 | ||
|
|
f46880d2a8 | ||
|
|
23bbc9c755 | ||
|
|
2b784cb3b9 | ||
|
|
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 | ||
|
|
1648a538df | ||
|
|
3ffac57509 | ||
|
|
1654a83366 | ||
|
|
022bb44f12 | ||
|
|
03c024f8f6 | ||
|
|
9b7d400550 | ||
|
|
c53bd96eb8 | ||
|
|
1f9e8ca77f | ||
|
|
deeb8aad1c | ||
|
|
f02d7d8565 | ||
|
|
a5f7072a64 | ||
|
|
2c79280441 | ||
|
|
d4d36bebab | ||
|
|
d423678f59 | ||
|
|
4b7cfd04af | ||
|
|
115a7ba67a | ||
|
|
d0e7aad11e | ||
|
|
645f42a890 | ||
|
|
f505dea314 | ||
|
|
748c3cac6c | ||
|
|
fa8bc533a3 | ||
|
|
00062a0ac7 | ||
|
|
c9f88bb9f1 | ||
|
|
482742394d | ||
|
|
05867d84f6 | ||
|
|
92cbb5364a | ||
|
|
61e4551b76 | ||
|
|
254742bc6d | ||
|
|
a6fd40d4fd | ||
|
|
9a11e954d8 | ||
|
|
b2ca03dc19 | ||
|
|
0fb6853fc7 | ||
|
|
94d6208542 | ||
|
|
eb62609c86 | ||
|
|
d596493831 | ||
|
|
70463566bf | ||
|
|
99c55fce60 | ||
|
|
ec2a2e049f | ||
|
|
43331cbeaf | ||
|
|
fbdac6a96a | ||
|
|
9e3af06141 | ||
|
|
1de2f33d23 | ||
|
|
06b364b1ac | ||
|
|
9786da7009 | ||
|
|
55ee1cd30f | ||
|
|
5f21a44058 | ||
|
|
edf1a0cdd7 | ||
|
|
be5c052531 | ||
|
|
e041a2aa7d | ||
|
|
31c7a42c73 | ||
|
|
8ddcc1e896 | ||
|
|
6a8f8dffcb | ||
|
|
f2744bec30 | ||
|
|
074f479962 | ||
|
|
a60fe371a4 | ||
|
|
3ea5e54eb9 | ||
|
|
ed8c41a0ca | ||
|
|
9ed3bb5353 | ||
|
|
9bbca07033 | ||
|
|
9ba59de212 | ||
|
|
35c880fc0c | ||
|
|
7b116d614e | ||
|
|
a73d04cf82 | ||
|
|
2471616f74 | ||
|
|
3926f42647 | ||
|
|
ce070f85ff | ||
|
|
bd02cbfdb0 | ||
|
|
16149ff960 | ||
|
|
c4a5681f35 | ||
|
|
3d5a776ab1 | ||
|
|
9f4671eaf6 | ||
|
|
5af5d18310 | ||
|
|
3765c9233b | ||
|
|
0bd0af1fe1 | ||
|
|
92189e2d12 | ||
|
|
6dcd5aa00c | ||
|
|
09d3068222 | ||
|
|
0f11d320e6 | ||
|
|
365308f374 | ||
|
|
0e510b32c1 | ||
|
|
a9244d9b13 | ||
|
|
c268e59813 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,7 +2,7 @@
|
||||
*.o
|
||||
*.pyc
|
||||
src/.dep
|
||||
src/Makefile
|
||||
src/config.mk
|
||||
src/config.h
|
||||
src/gnuk.ld
|
||||
src/board.h
|
||||
@@ -12,3 +12,5 @@ regnual/regnual.bin
|
||||
regnual/regnual.hex
|
||||
regnual/regnual.elf
|
||||
doc/_build
|
||||
tests/.cache
|
||||
tests/__pycache__
|
||||
|
||||
41
AUTHORS
41
AUTHORS
@@ -1,35 +1,20 @@
|
||||
Anthony Romano:
|
||||
Modified:
|
||||
src/call-rsa.c
|
||||
src/main.c
|
||||
src/mod.c
|
||||
|
||||
Jeremy Drake:
|
||||
Modified:
|
||||
regnual/regnual.c
|
||||
|
||||
Kaz Kojima:
|
||||
Added STM32 Primer2 support:
|
||||
boards/STM32_PRIMER2/board.c
|
||||
boards/STM32_PRIMER2/board.h
|
||||
boards/STM32_PRIMER2/mcuconf.h
|
||||
Added STM32 Primer2 support.
|
||||
|
||||
NIIBE Yutaka:
|
||||
Founder of the project.
|
||||
Added FST_01 support:
|
||||
boards/FST_01/board.c
|
||||
boards/FST_01/board.h
|
||||
boards/FST_01/mcuconf.h
|
||||
Added FST_01_00 support:
|
||||
boards/FST_01_00/board.c
|
||||
boards/FST_01_00/board.h
|
||||
boards/FST_01_00/mcuconf.h
|
||||
Added STBee support:
|
||||
boards/STBEE/board.c
|
||||
boards/STBEE/board.h
|
||||
boards/STBEE/mcuconf.h
|
||||
Added STM8S Discovery Kit support:
|
||||
boards/STM8S_DISCOVERY/board.c
|
||||
boards/STM8S_DISCOVERY/board.h
|
||||
boards/STM8S_DISCOVERY/mcuconf.h
|
||||
Added STBee Mini support:
|
||||
boards/STBEE_MINI/board.c
|
||||
boards/STBEE_MINI/board.h
|
||||
boards/STBEE_MINI/mcuconf.h
|
||||
Added CQ STARM support:
|
||||
boards/CQ_STARM/board.c
|
||||
boards/CQ_STARM/board.h
|
||||
boards/CQ_STARM/mcuconf.h
|
||||
Wrote tools for STLink/V2:
|
||||
tool/stlinkv2.py
|
||||
Wrote tools for DfuSe:
|
||||
tool/dfuse.py
|
||||
tool/dump_mem.py
|
||||
|
||||
975
ChangeLog
975
ChangeLog
@@ -1,3 +1,978 @@
|
||||
2017-10-11 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.2.6.
|
||||
|
||||
* regnual/Makefile (LDSCRIPT): Move after include.
|
||||
* regnual/types.h: Add uintptr_t.
|
||||
|
||||
* test/features/002_get_data_static.feature (data object AID): Fix
|
||||
for any binary value.
|
||||
* 402_get_data_static.feature: Likewise.
|
||||
* 802_get_data_static.feature: Likewise.
|
||||
|
||||
2017-10-10 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/main.c (main): Support --debug option.
|
||||
* chopstx: Update to 1.5.
|
||||
|
||||
2017-10-06 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (flash_override): Fix suggested by Jeremy Drake.
|
||||
(help): STM8S_DISCOVERY is supported again.
|
||||
|
||||
2017-10-06 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.ld.in (.stacks): Specify NOLOAD type.
|
||||
|
||||
* src/configure: Allow not specifying VIDPID.
|
||||
|
||||
* src/main.c [GNU_LINUX_EMULATION] (main): Handle "--vidpid"
|
||||
option to assign vendor ID and product ID of USB.
|
||||
|
||||
* src/usb_desc.c [GNU_LINUX_EMULATION] (device_desc): Export.
|
||||
|
||||
* GNUK_USB_DEVICE_ID (0000:0000): New.
|
||||
|
||||
2017-10-05 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/stack-def.h (SIZE_1, SIZE_3): Tweak the size.
|
||||
|
||||
* src/call-rsa.c (rsa_genkey): Single step.
|
||||
* src/openpgp-do.c (gpg_do_keygen): Do RSA key generation in single
|
||||
step, using APDU buffer.
|
||||
* src/openpgp.c (cmd_pgp_gakp): Supply the APDU as a buffer.
|
||||
|
||||
* src/Makefile (install): New target.
|
||||
|
||||
* src/configure (prefix. exec_prefix, libexecdir): Add.
|
||||
|
||||
* src/main.c [GNU_LINUX_EMULATION] (main): Option handling.
|
||||
|
||||
* tool/gnuk-emulation-setup: New.
|
||||
|
||||
* polarssl/library/bignum.c (M_LIMBS, limbs_M, MAX_A_LIMBS)
|
||||
(limbs_MAX_A, mpi_gen_prime): Fix for 64-bit machine.
|
||||
|
||||
2017-10-04 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (output_vendor_product_serial_strings): Support
|
||||
GNU/Linux emulation.
|
||||
|
||||
* polarssl/library/bignum.c (mpi_div_mpi): Fix for 64-bit machine.
|
||||
|
||||
* src/main.c (gnuk_malloc, gnuk_free): Fix for 64-bit machine.
|
||||
|
||||
* src/stack-def.h (SIZE_3): Tweak the size.
|
||||
|
||||
* src/openpgp-do.c (gpg_do_keygen): Do RSA key generation in two
|
||||
steps.
|
||||
|
||||
* src/call-rsa.c (rsa_genkey_start, rsa_genkey_finish): New.
|
||||
(rsa_genkey): Remove.
|
||||
|
||||
2017-10-03 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/call-ec.c (ecc_compute_public): No use of malloc.
|
||||
* src/call-rsa.c (modulus_calc, rsa_genkey): Likewise.
|
||||
* src/ecc-edwards.c (eddsa_compute_public_25519): Likewise.
|
||||
* src/ecc-mont.c (ecdh_compute_public_25519): Likewise.
|
||||
* src/openpgp-do.c (gpg_do_write_prvkey, gpg_do_chks_prvkey)
|
||||
(proc_key_import, gpg_do_keygen): Likewise.
|
||||
|
||||
* polarssl/library/rsa.c: Don't include stdlib.h.
|
||||
* src/gnuk-malloc.h: Rename from stdlib.h.
|
||||
* polarssl/library/bignum.c: Include gnuk-malloc.h.
|
||||
|
||||
* src/Makefile (build/flash.data): Generate.
|
||||
|
||||
* src/main.c (flash_addr_key_storage_start)
|
||||
(flash_addr_data_storage_start): New.
|
||||
(main): Determine flash address.
|
||||
|
||||
* src/flash.c (FLASH_ADDR_KEY_STORAGE_START)
|
||||
(FLASH_ADDR_DATA_STORAGE_START): New.
|
||||
(flash_do_storage_init, flash_terminate, flash_activate)
|
||||
(flash_key_storage_init, flash_copying_gc, flash_do_release)
|
||||
(flash_key_getpage): Use new macros.
|
||||
|
||||
2017-10-02 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/main.c (device_initialize_once): Not for GNU/Linux.
|
||||
|
||||
* src/openpgp.c, src/flash.c: Distinguish FLASH_UPGRADE_SUPPORT.
|
||||
|
||||
* src/main.c [GNU_LINUX_EMULATION]: Use emulated_main.
|
||||
(MEMORY_SIZE, MEMORY_END): Fix for GNU/Linux.
|
||||
|
||||
* src/usb-ccid.c (INTR_REQ_USB): Fix for GNU/Linux.
|
||||
|
||||
* polarssl/library/bignum.c (mpi_montsqr): Easy C implementation.
|
||||
|
||||
2017-09-30 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/flash.c (flash_terminate, flash_activate)
|
||||
(flash_copying_gc, flash_do_write_internal, flash_do_release)
|
||||
(flash_key_write, flash_check_all_other_keys_released)
|
||||
(flash_key_fill_zero_as_released, flash_key_release)
|
||||
(flash_key_release_page, flash_clear_halfword)
|
||||
(flash_put_data_internal, flash_put_data, flash_bool_clear)
|
||||
(flash_bool_write_internal, flash_bool_write)
|
||||
(flash_enum_write_internal, flash_enum_write)
|
||||
(flash_cnt123_write_internal, flash_cnt123_increment)
|
||||
(flash_cnt123_clear, flash_erase_binary, flash_write_binary): Fix
|
||||
for GNU/Linux.
|
||||
|
||||
* src/usb-ccid.c (ccid_tx_done): Rename from EP1_IN_Callback.
|
||||
(ccid_rx_ready): Rename from EP1_OUT_Callback.
|
||||
|
||||
2017-09-29 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb-ccid.c (epo_init, epi_init, ccid_thread): Simplify.
|
||||
(EP1_IN_Callback, ccid_prepare_receive, EP1_OUT_Callback)
|
||||
(usb_rx_ready, ccid_error, ccid_power_on, ccid_send_status)
|
||||
(ccid_send_data_block_internal, ccid_send_data_block_0x9000)
|
||||
(ccid_send_data_block_gr, ccid_send_params)
|
||||
(ccid_notify_slot_change, _write) [GNU_LINUX_EMULATION]: Use
|
||||
different usb driver API.
|
||||
|
||||
* src/usb_ctrl.c (usb_device_reset): Fix control endpoint init.
|
||||
(gnuk_setup_endpoints_for_interface): Add DEV
|
||||
argument.
|
||||
(usb_device_reset) [GNU_LINUX_EMULATION]: Use usb_lld_setup_endp.
|
||||
|
||||
2017-09-29 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/main.c [FLASH_UPGRADE_SUPPORT] (main): Factor out flash ROM
|
||||
upgrade support.
|
||||
(calculate_regnual_entry_address): Likewise.
|
||||
* src/usb_ctrl.c (usb_setup, download_check_crc32): Likewise.
|
||||
|
||||
* src/openpgp.c (modify_binary): Fix for 64-bit machine.
|
||||
* src/openpgp-do.c (encrypt, decrypt): Likewise.
|
||||
(gpg_data_scan): Likewise.
|
||||
(gpg_do_chks_prvkey): Fix error return path.
|
||||
|
||||
* src/stack-def.h: New.
|
||||
|
||||
* src/gnuk.ld.in: Remove stack definitions.
|
||||
* src/configure: Remove stack size modifications.
|
||||
|
||||
* src/main.c (STACK_MAIN, STACK_PROCESS_1): Use stack-def.h.
|
||||
* src/usb-ccid.c (STACK_PROCESS_3): Likewise.
|
||||
* src/usb-msc.c (STACK_PROCESS_5): Likewise.
|
||||
* src/pin-cir.c (STACK_PROCESS_6, STACK_PROCESS_7): Likewise.
|
||||
|
||||
* src/usb_ctrl.c (download_check_crc32): Use chrc32_rv_ functions.
|
||||
|
||||
* src/mcu-stm32f103.c (rbit, check_crc32): Remove.
|
||||
|
||||
* src/neug.c: Update from NeuG.
|
||||
* src/neug.h: Ditto.
|
||||
|
||||
2017-09-28 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/ec_p256k1.c (coefficient_a): Remove.
|
||||
|
||||
* polarssl/library/bignum.c (mpi_fill_pseudo_random): Fix for
|
||||
64-bit machine.
|
||||
|
||||
* src/call-rsa.c (rsa_decrypt): Fix for 64-bit machine.
|
||||
|
||||
* src/flash.c (flash_do_storage_init): Rename from flash_init.
|
||||
(flash_key_storage_init): Rename from flash_init_keys.
|
||||
* src/openpgp.c (gpg_init): Use new function names.
|
||||
|
||||
* src/stdlib.h: Update for GNU/Linux emulation.
|
||||
|
||||
* src/Makefile: Support GNU/Linux emulation.
|
||||
* src/configure: Support GNU/Linux emulation.
|
||||
* emulation: Remove.
|
||||
|
||||
2017-08-11 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.2.5.
|
||||
* chopstx: Update to 1.4.
|
||||
|
||||
* src/gnuk.ld.in (__process3_stack_size__): Tweak the size.
|
||||
|
||||
* src/configure: Define STM32F103_OVERRIDE_FLASH_SIZE_KB for
|
||||
BULE_PILL.
|
||||
|
||||
* src/configure: Let generate src/config.mk.
|
||||
* src/Makefile: Rename from src/Makefile.in.
|
||||
* regnual/Makefile: Use src/config.mk.
|
||||
|
||||
2017-08-03 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (cmd_terminate_df): Fix for admin-less mode.
|
||||
|
||||
2017-08-03 Jeremy Drake <jeremydrake+gnuk@eacceleration.com>
|
||||
|
||||
* regnual/regnual.c (main): Allow compile time
|
||||
flash size definition by STM32F103_OVERRIDE_FLASH_SIZE_KB.
|
||||
|
||||
2017-08-02 Jeremy Drake <jeremydrake+gnuk@eacceleration.com>
|
||||
|
||||
* src/flash.c (flash_terminate): Erase Certificate DO, too.
|
||||
|
||||
2017-08-01 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (FILE_CARD_TERMINATED_OPENPGP): Remove.
|
||||
(cmd_select_file): Don't change file_selection.
|
||||
|
||||
2017-07-19 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/mod.c (mod_inv): Clear TMP.
|
||||
|
||||
* src/configure (REVISION): Generate even when no git.
|
||||
|
||||
* polarssl/library/bignum.c (mpi_exp_mod): Call mpi_grow for X
|
||||
after the initialization of RR.
|
||||
|
||||
2017-07-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure: Bark when no git available.
|
||||
|
||||
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
|
||||
|
||||
* docker: New.
|
||||
|
||||
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
|
||||
|
||||
* src/main.c (MEMORY_SIZE, MEM_HEAD_IS_CORRUPT, MEM_HEAD_CHECK):
|
||||
New.
|
||||
(gnuk_malloc, gnuk_free): Add calls to MEM_HEAD_CHECK.
|
||||
|
||||
* src/gnuk.h (FATAL_HEAP): New.
|
||||
|
||||
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
|
||||
|
||||
* src/openpgp-do.c (gpg_reset_algo_attr): New.
|
||||
(rw_algorithm_attr): Use gpg_reset_algo_attr.
|
||||
Fix null dereference.
|
||||
|
||||
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
|
||||
|
||||
* src/mod.c (mod_reduce): Clean up unused code.
|
||||
|
||||
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
|
||||
|
||||
* src/call-rsa.c (modulus_calc): Free modulus on error.
|
||||
(rsa_genkey): Remove bogus check, and call chopstx_cleanup_pop
|
||||
with 1 to release p_q_modulus on error. Assign NULL to clp.arg
|
||||
when it's goes with no error.
|
||||
|
||||
* src/main.c (gnuk_free): Allow NULL.
|
||||
|
||||
2017-07-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* Update chopstx (with USBIP emulation).
|
||||
|
||||
2017-05-12 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.2.4.
|
||||
|
||||
2017-04-28 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/mcu-stm32f103.c: New.
|
||||
(check_crc32, sram_address): New.
|
||||
|
||||
* src/usb_ctrl.c (download_check_crc32): Use check_crc32 and
|
||||
sram_address.
|
||||
|
||||
* src/openpgp-do.c (gpg_write_digital_signature_counter): Fix
|
||||
writing lower 10-bit.
|
||||
|
||||
2017-04-27 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.ld.in (_data_pool): Move to the end.
|
||||
|
||||
* src/flash.c (flash_init): Return address of end of data object.
|
||||
* src/openpgp.c (gpg_init): Get address of end of data object.
|
||||
* src/openpgp-do.c (gpg_data_scan): Check the end address.
|
||||
|
||||
2017-02-02 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.2.3.
|
||||
|
||||
* src/gnuk.ld.in (__process1_stack_size__): Increase by 0x20.
|
||||
* chopstx: Update to 1.3.
|
||||
* src/configure: Add BLUE_PILL in the help message.
|
||||
|
||||
2017-02-01 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* README: Update README. Thanks to Paul Fertser.
|
||||
|
||||
2017-01-02 Szczepan Zalega <szczepan@nitrokey.com>
|
||||
|
||||
* tool/upgrade_by_passwd.py: Add file extention check.
|
||||
|
||||
2017-02-01 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/upgrade_by_passwd.py (main): More verbose messages
|
||||
suggested by Szczepan Zalega <szczepan@nitrokey.com>.
|
||||
|
||||
* tool/gnuk_token.py (USB_PRODUCT_LIST): New.
|
||||
(gnuk_devices_by_vidpid): Support searching by USB_PRODUCT_LIST.
|
||||
Thanks to Szczepan Zalega <szczepan@nitrokey.com>.
|
||||
|
||||
* tool/usb_strings.py: Use gnuk_token.py.
|
||||
|
||||
2016-10-21 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/ecc.c (check_secret): Fix condition.
|
||||
|
||||
2016-10-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.2.2.
|
||||
|
||||
* tool/gnuk_put_binary_libusb.py (main): Likewise.
|
||||
* tool/upgrade_by_passwd.py (main): Add call of cmd_select_openpgp
|
||||
method.
|
||||
|
||||
* src/openpgp.c (gpg_init): flash_init_keys shoule be after
|
||||
gpg_data_scan since flash_init_keys accesses Data Object for
|
||||
key attributes.
|
||||
|
||||
* src/usb-ccid.c (ccid_power_on): Don't waste stack.
|
||||
|
||||
2016-10-14 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb-ccid.c (ccid_power_on) [LIFE_CYCLE_MANAGEMENT_SUPPORT]:
|
||||
Change LCS value in ATR at run time.
|
||||
|
||||
* src/openpgp.c (gpg_init): Handle FILE_CARD_TERMINATED.
|
||||
(cmd_select_file): Don't return AID.
|
||||
(cmd_activate_file, cmd_terminate_df): New.
|
||||
(process_command_apdu): Let return GPG_NO_RECORD() when
|
||||
not selected.
|
||||
|
||||
* src/openpgp-do.c (gpg_do_terminate): New.
|
||||
(gpg_data_scan): Handle p_start is NULL.
|
||||
(do_hist_bytes): Remove.
|
||||
|
||||
* src/flash.c (flash_data): Change the value from 0x0000.
|
||||
(flash_init): Support termination state. Fix handling
|
||||
of the boundary case where gen0 is 0xfffe.
|
||||
(flash_terminate, flash_activate): New.
|
||||
(flash_copying_gc): Skip 0xffff for generation number.
|
||||
|
||||
2016-10-13 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/status-code.h: Rename from openpgp.h.
|
||||
|
||||
* chopstx: Update to 1.2.
|
||||
|
||||
* tests: New test suite for OpenPGP card with PyTest.
|
||||
|
||||
* src/configure (factory_reset): New.
|
||||
|
||||
* src/usb-ccid.c (ccid_power_on): Use ATR_head and historical
|
||||
bytes.
|
||||
|
||||
* src/openpgp-do.c (rw_algorithm_attr): Clear fingerprint, timestamp,
|
||||
and possibly ds_counter.
|
||||
|
||||
2016-10-12 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* test/features/steps.py (cmd_reset_retry_counter): Fix.
|
||||
* tool/gnuk_token.py (gnuk_token.cmd_reset_retry_counter): Fix.
|
||||
(gnuk_token.cmd_select_openpgp): Fix P2.
|
||||
|
||||
2016-09-02 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (REVISION): Fix the detection of .git.
|
||||
It may be a regular file (if it's created by worktree).
|
||||
|
||||
2016-08-24 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* test/features/steps.py (ini): Use GLC (the global context),
|
||||
instead of FTC (the feature context), so that token only is
|
||||
opened once.
|
||||
|
||||
2016-08-03 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/hub_ctrl.py: Port to Python 3.
|
||||
|
||||
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>
|
||||
|
||||
* VERSION: 1.1.9.
|
||||
|
||||
* src/openpgp-do.c (proc_key_import): Fix error return.
|
||||
(rw_algorithm_attr): Check it's not ALGO_RSA2K.
|
||||
|
||||
2015-09-17 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.1.8.
|
||||
|
||||
2015-09-15 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx: Update to 0.10.
|
||||
|
||||
* src/main.c (main): Don't join after calling ccid_usb_reset.
|
||||
* src/usb-icc.c (ccid_thread): Don't finish on reset, but
|
||||
keep running.
|
||||
|
||||
* src/usb_ctrl.c (usb_cb_device_reset): Stop the interface.
|
||||
|
||||
* src/usb_stm32f103.c (std_set_interface): Bug fix for conf.
|
||||
|
||||
* src/gnuk.ld.in (__process3_stack_size__): Increase stack size of
|
||||
GPG thread.
|
||||
(__process2_stack_size__): Increase stack size of RNG.
|
||||
(__process4_stack_size__): Increase stack size of USB.
|
||||
(__main_stack_size__): Decrease stack size of exception handlers.
|
||||
(__process1_stack_size__): Decrease stack size of CCID.
|
||||
|
||||
2015-09-14 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.h (LED_GNUK_EXEC): New.
|
||||
* src/main.c, src/usb-icc.c, src/usb_ctrl.c: icc_state_p access
|
||||
clean up.
|
||||
|
||||
2015-09-11 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/upgrade_by_passwd.py (main): Loop until finding reGNUal
|
||||
device.
|
||||
|
||||
2015-09-10 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/call-rsa.c (rsa_cleanup): New.
|
||||
(rsa_sign, rsa_decrypt, rsa_genkey): Allow cancellation.
|
||||
* src/openpgp.c (cmd_pso, cmd_internal_authenticate): Cancellation
|
||||
is handled by each functions in case of RSA.
|
||||
|
||||
2015-09-09 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/sys.h: Update from Chopstx.
|
||||
* src/adc_stm32f103.c: Update from NeuG.
|
||||
|
||||
* src/openpgp.c (process_command_apdu): Protect command execution
|
||||
against cancelling the execution thread.
|
||||
(cmd_pso, cmd_internal_authenticate): Allow cancellation.
|
||||
|
||||
* src/main.c (main): Handle LED_USB_RESET.
|
||||
|
||||
* src/usb-icc.c (ccid_usb_reset): New.
|
||||
(ccid_thread): Upon receival of EV_USB_RESET, finish
|
||||
the thread, canceling the card thread.
|
||||
|
||||
2015-09-08 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.h (EV_USB_RESET, LED_USB_RESET): New.
|
||||
|
||||
* src/usb_ctrl.c (CDC_CTRL_DTR): New.
|
||||
(vcom_port_data_setup): Distinguish detail->value for DTR.
|
||||
|
||||
* src/configure (help): Add ST_DONGLE and ST_NUCLEO_F103.
|
||||
|
||||
2015-09-04 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (do_openpgpcard_aid): Use upper bytes of unique
|
||||
ID of MCU; same as USB serial number.
|
||||
|
||||
* src/configure (help): Add NITROKEY_START.
|
||||
|
||||
2015-08-26 Mateusz Zalega <mateusz@nitrokey.com>
|
||||
|
||||
* GNUK_USB_DEVICE_ID: Add Nitrokey Start.
|
||||
|
||||
2015-08-05 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.1.7.
|
||||
|
||||
2015-08-04 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/adc_stm32f103.c: Update from NeuG 1.0.3.
|
||||
|
||||
* chopstx: Update to 0.08.
|
||||
* src/sys.h: Update.
|
||||
|
||||
2015-08-03 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* test/features/steps.py (set_msg): Python3 fix.
|
||||
* test/generate_keys.py: Likewise.
|
||||
* test/rsa_keys.py: Likewise.
|
||||
|
||||
* tool/gnuk_token.py (gnuk_token.download, gnuk_token.execute)
|
||||
(regnual.download): Python3 fix.
|
||||
(list_to_string): Remove.
|
||||
|
||||
* tool/upgrade_by_passwd.py (maian): Python3 fix.
|
||||
* tool/usb_strings.py (main): Python3 fix.
|
||||
|
||||
2015-07-31 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (output_vendor_product_serial_strings): Fix sed
|
||||
script when string is short. Remove empty line.
|
||||
|
||||
* regnual/regnual.c (usb_cb_ctrl_write_finish, usb_cb_setup)
|
||||
(usb_cb_get_descriptor, usb_cb_interface): Follow the change
|
||||
of USB API.
|
||||
|
||||
* tool/stlinkv2.py: Support ST-Link/V2-1.
|
||||
|
||||
2015-07-28 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/stlinkv2.py: Fix for Python3. Thanks to Bertrand Jacquin.
|
||||
|
||||
* tool/gpg_agent.py: Fix for Python3.
|
||||
|
||||
* src/usb-msc.c: Update from Fraucheky.
|
||||
|
||||
* src/usb_stm32f103.c (struct DATA_INFO): Remove offset.
|
||||
(struct DEVICE_INFO): Integrate CONTROL_INFO.
|
||||
|
||||
2015-07-27 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb_stm32f103.c (usb_lld_reply_request): New.
|
||||
(usb_lld_set_data_to_send): Remove.
|
||||
(usb_lld_set_data_to_recv): Not a macro but a function.
|
||||
(std_get_status): Don't use statically allocated memory.
|
||||
(std_get_configuration): Use usb_lld_reply_request.
|
||||
(handle_setup0): Follow the change.
|
||||
* src/usb_ctrl.c (vcom_port_data_setup, usb_cb_setup)
|
||||
(usb_cb_interface): Use usb_lld_reply_request.
|
||||
* src/usb_desc.c (usb_cb_get_descriptor): Likewise.
|
||||
|
||||
2015-07-24 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/gnuk_put_binary.py: Remove.
|
||||
* tool/gnuk_remove_keys.py: Remove.
|
||||
|
||||
2015-07-23 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (nl): New. Follow the change of NeuG.
|
||||
|
||||
2015-07-21 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.1.6.
|
||||
|
||||
2015-07-20 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (gpg_do_keygen): Support ECC.
|
||||
* src/call-ec.c (ecc_check_secret): New.
|
||||
* src/ecc.c (check_secret): New.
|
||||
|
||||
2015-07-18 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (keygen): It's always enabled.
|
||||
* src/openpgp-do.c (gpg_do_keygen): Support key generation.
|
||||
* src/openpgp.c (cmd_pgp_gakp): Likewise.
|
||||
* src/call-rsa.c (rsa_genkey): Likewise.
|
||||
* src/random.c (random_gen): Likewise.
|
||||
* src/Makefile.in (KEYGEN_SUPPORT): Remove.
|
||||
* polarssl/include/polarssl/config.h (POLARSSL_GENPRIME): Define.
|
||||
|
||||
2015-07-16 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (FLASH_PAGE_SIZE, FLASH_SIZE, MEMORY_SIZE)
|
||||
[sys1_compat]: Use safe values for common binary.
|
||||
(TARGET_DEFINE): Remove.
|
||||
|
||||
2015-07-15 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/usb_strings.py (field): Add 'Board'.
|
||||
|
||||
* regnual/regnual.c (usb_cb_get_descriptor): Update.
|
||||
* src/usb_ctrl.c (usb_cb_interface): Call usb_lld_write.
|
||||
* src/usb_desc.c (usb_cb_get_descriptor): Support sys_board_name,
|
||||
using usb_lld_write.
|
||||
* src/usb_lld.h (usb_cb_get_descriptor): Add last argument length
|
||||
for asked length.
|
||||
* src/usb_stm32f103.c (handle_setup0): Allow setup callback to
|
||||
call usb_lld_write with ENDP0.
|
||||
* src/usb_conf.h (NUM_STRING_DESC): Remove.
|
||||
|
||||
* src/configure [!sys1_compat] (CONFIG): Don't include target
|
||||
board name.
|
||||
|
||||
* src/flash.c: Detect flash_page_size at runtime.
|
||||
|
||||
* src/main.c: Remove dependency to board.h.
|
||||
|
||||
* src/neug.c: Update from NeuG 1.0.2.
|
||||
* src/adc_stm32f103.c: Update.
|
||||
|
||||
* chopstx: Update to 0.07.
|
||||
* src/sys.c: Update.
|
||||
* src/sys.h: Update.
|
||||
* src/gnuk.ld.in: Update.
|
||||
|
||||
* tool/stlinkv2.py (stlinkv2.get_chip_id): New. Detect flash
|
||||
size, too.
|
||||
(main): Call stlinkv2.get_chip_id after MCU reset and stop.
|
||||
Verify read out fix.
|
||||
|
||||
2015-07-11 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure (help): Add STM32_PRIMER2 and CQ_STARM.
|
||||
|
||||
* chopstx: Update to 0.06.
|
||||
|
||||
* tool/stlinkv2.py: Support 512kB version of STM32F103.
|
||||
The size of executable file should be even.
|
||||
|
||||
2015-07-07 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/Makefile.in (CSRC): Add ecc-mont.c.
|
||||
|
||||
* src/ecc-mont.c (mod25638_mul_121665): Fix.
|
||||
(ecdh_compute_public_25519, ecdh_decrypt_curve25519): New.
|
||||
|
||||
* src/openpgp.c (cmd_pso): Support ALGO_CURVE25519.
|
||||
|
||||
* src/openpgp-do.c (algorithm_attr_cv25519): New.
|
||||
(rw_algorithm_attr, get_algo_attr_data_object)
|
||||
(gpg_get_algo_attr_key_size, gpg_do_write_prvkey)
|
||||
(proc_key_import, gpg_do_public_key): Support ALGO_CURVE25519.
|
||||
|
||||
* src/gnuk.h (ALGO_CURVE25519): New.
|
||||
|
||||
2015-07-06 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
Enhancement for FSM-55.
|
||||
* tool/stlinkv2.py (stlinkv2.control_nrst): New.
|
||||
(stlinkv2.get_rdp_key,has_spi_flash,has_protection): New.
|
||||
(stlinkv2.get_core_id): Rename.
|
||||
(stlinkv2.blank_check): Use self.flash_size.
|
||||
(stlinkv2.start): Call control_nrst. Call get_core_id.
|
||||
Distinguishing chip, and set rdp_key, flash_size and require_nrst.
|
||||
(stlinkv2.flash_write): Use self.flash_block_size.
|
||||
(main): Call control_nrst.
|
||||
(prog_flash_write_body, prog_option_bytes_write_body)
|
||||
(prog_blank_check_body): Support Cortex-M0.
|
||||
(main): Call API V2 halt twice.
|
||||
* tool/asm-thumb/*.S: Updated for Cortex-M0.
|
||||
|
||||
2015-06-30 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/sys.c: Update from chopstx/example-cdc/sys.c.
|
||||
|
||||
* src/main.c (device_initialize_once): Apply change of NeuG.
|
||||
|
||||
2015-06-03 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.1.5.
|
||||
|
||||
* test/ecc_nistp256_keys.py: New.
|
||||
|
||||
* tool/upgrade_by_passwd.py: Remove -p option and add -f option.
|
||||
|
||||
* tool/gnuk_token.py (gnuk_token.download): Add verbose flag.
|
||||
(regnual.download): Ditto.
|
||||
|
||||
* tool/gnuk_upgrade.py: Use gnuk_token module.
|
||||
|
||||
2015-06-02 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (cmd_pso): Support OpenPGPcard spec v3.0.
|
||||
|
||||
2015-04-20 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx: Upgrade to 0.05.
|
||||
|
||||
2015-04-19 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.h (CCID_CARD_INIT): New.
|
||||
* src/usb_desc.c (gnukConfigDescriptor): Update dwDefaultClock,
|
||||
dwMaximumClock, dwFeatures, and bClassEnvelope.
|
||||
* src/usb_ctrl.c (freq_table): Change the value to 4000MHz.
|
||||
(usb_cb_handle_event): Call ccid_card_change_signal after configure.
|
||||
* src/usb-icc.c (ccid_thread): Change EV_CARD_CHANGE handling.
|
||||
|
||||
2015-04-18 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/main.c (main): Call chopstx_main_init.
|
||||
* src/Makefile.in (DEFS): Remove CHX_PRIO_MAIN.
|
||||
|
||||
2015-04-17 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure: Fix shell syntax.
|
||||
|
||||
2015-03-31 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb_conf.h (ICC_NUM_INTERFACES, HID_NUM_INTERFACES)
|
||||
(HID_NUM_INTERFACES, VCOM_NUM_INTERFACES, MSC_NUM_INTERFACES)
|
||||
(NUM_INTERFACES): Define here (moved from usb_desc.c).
|
||||
(ICC_INTERFACE, HID_INTERFACE, VCOM_INTERFACE_0, VCOM_INTERFACE_1)
|
||||
(MSC_INTERFACE): New.
|
||||
* src/usb_ctrl.c (gnuk_setup_endpoints_for_interface)
|
||||
(usb_cb_setup, usb_cb_ctrl_write_finish): Use *_INTERFACE.
|
||||
* src/usb_desc.c (gnukConfigDescriptor): Likewise.
|
||||
|
||||
2015-03-06 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/ecc-edwards.c (eddsa_sign_25519): Return 0.
|
||||
|
||||
2015-02-25 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (cmd_internal_authenticate): Fix storing to
|
||||
res_APDU_size.
|
||||
|
||||
2015-02-10 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (cmd_pso): Fix counter update for EdDSA. Thanks
|
||||
to Jonathan Schleifer.
|
||||
|
||||
* src/call-rsa.c (rsa_sign): Don't set res_APDU_len.
|
||||
(rsa_decrypt): Likewise, but get OUTPUT_LEN_P as an argument.
|
||||
|
||||
2015-02-09 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (cmd_pso): Fix EdDSA. Use GPG_KEY_FOR_SIGNING.
|
||||
|
||||
2014-12-15 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.1.4.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# VID:PID bcdDev Product_STRING Vender_STRING
|
||||
# VID:PID bcdDev Product_STRING Vendor_STRING
|
||||
0000:0000 0200 Gnuk Emulation Free Software Initiative of Japan
|
||||
234b:0000 0200 Gnuk Token Free Software Initiative of Japan
|
||||
20a0:4211 0200 Nitrokey Start Nitrokey
|
||||
##########<TAB> ##<TAB> ##########<TAB> #################
|
||||
|
||||
173
NEWS
173
NEWS
@@ -1,5 +1,178 @@
|
||||
Gnuk NEWS - User visible changes
|
||||
|
||||
* Major changes in Gnuk 1.2.6
|
||||
|
||||
Released 2017-10-11, by NIIBE Yutaka
|
||||
|
||||
** Port to GNU/Linux emulation
|
||||
We can "run" Gnuk Token on GNU/Linux by emulation through USBIP.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.5.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.5
|
||||
|
||||
Released 2017-08-11, by NIIBE Yutaka
|
||||
|
||||
** "factory-reset" fix
|
||||
Gnuk's behavior was implemented by referring the gpg implementation.
|
||||
It found that gpg implementation was not good from the viewpoint of
|
||||
the OpenPGP card specification. GnuPG was fixed to match the OpenPGP
|
||||
card specification already. Thus, Gnuk is now fixed.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.4.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.4
|
||||
|
||||
Released 2017-05-12, by NIIBE Yutaka
|
||||
|
||||
** Flash ROM security fix
|
||||
The partial content of flash ROM might be exposed when scanning of
|
||||
data object had a problem. Added boundary check and changed layout of
|
||||
flash ROM.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.3
|
||||
|
||||
Released 2017-02-02, by NIIBE Yutaka
|
||||
|
||||
** ECC key generation on the device
|
||||
Bug fixed.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.3.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.2
|
||||
|
||||
Released 2016-10-15, by NIIBE Yutaka
|
||||
|
||||
** Change of SELECT FILE behavior
|
||||
Gnuk used to reply AID upon SELECT FILE command. Now, to be compatible
|
||||
to original OpenPGP card, it returns nothing but status code of 9000.
|
||||
|
||||
** Added feature of Factory Reset as compile time option
|
||||
Original OpenPGP card has the feature, and Gnuk is now configurable to
|
||||
support the feature.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.2.
|
||||
|
||||
|
||||
* 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
|
||||
|
||||
Released 2015-09-18, by NIIBE Yutaka
|
||||
|
||||
** Bug fix for Ed25519 and Curve25519
|
||||
When registering key, wrong operations were not detected correctly.
|
||||
This is fixed.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.1.8
|
||||
|
||||
Released 2015-09-17, by NIIBE Yutaka
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 0.10, which supports Nitrokey-Start.
|
||||
|
||||
** Card serial number
|
||||
The way to determine a serial number of Gnuk Token for card has been
|
||||
changed. It uses the 96-bit unique bits of MCU, but the portion for
|
||||
use is changed.
|
||||
|
||||
** USB Reset handling
|
||||
USB reset lets Gnuk Token restart. It would not be perfect, when it's
|
||||
during computation of some function, but most parts are protected by
|
||||
Chopstx's feature of cancellation.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.1.7
|
||||
|
||||
Released 2015-08-05, by NIIBE Yutaka
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 0.08, which supports STM32 Nucleo and ST Dongle.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.1.6
|
||||
|
||||
Released 2015-07-21, by NIIBE Yutaka
|
||||
|
||||
** USB SerialNumber String
|
||||
The way to determine a serial number of Gnuk Token has been changed.
|
||||
It uses the 96-bit unique bits of MCU, but the portion for use is
|
||||
changed.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 0.07, which supports STM32 Primer2 and CQ STARM, too.
|
||||
|
||||
** Experimental Curve25519 support.
|
||||
|
||||
Gnuk can support Curve25519 (for decryption). Note that this is
|
||||
pretty much experimental, and subjects to change. The low level code
|
||||
is somehow stable, but there are no consensus in higer level.
|
||||
Especially, OID in the key attribute would be changed in future.
|
||||
|
||||
** No --enable-keygen option
|
||||
It is now standard feature included always. Note that it doesn't mean
|
||||
this feature is stable now. It is becoming stable, hopefully.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.1.5
|
||||
|
||||
Released 2015-06-03, by NIIBE Yutaka
|
||||
|
||||
** upgrade_by_passwd.py is not so noisy any more.
|
||||
Since it's getting stable, no debug output any more.
|
||||
|
||||
** Maple mini support.
|
||||
Although its random number generation is not tested, Maple mini
|
||||
support is added.
|
||||
|
||||
** Windows interoperability fix.
|
||||
1.1.x (0 to 4) didn't work with Windows because of INTERRUPT transfer.
|
||||
It's fixed and it works now.
|
||||
|
||||
** OpenPGPcard specification v3.0 compatibility.
|
||||
OpenPGPcard specification v3.0 now include NIST curves (and other
|
||||
curves) and ECDSA and ECDH operations are defined. Gnuk follows
|
||||
this specification.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.1.4
|
||||
|
||||
Released 2014-12-15, by NIIBE Yutaka
|
||||
|
||||
261
README
261
README
@@ -1,31 +1,41 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 1.1.4
|
||||
2014-12-15
|
||||
Version 1.2.6
|
||||
2017-10-11
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
Warning
|
||||
=======
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
This is another experimental release of Gnuk, version 1.1.4, which has
|
||||
This is the release of Gnuk, version 1.2.6, which has major
|
||||
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
||||
overriding key import, but importing keys (or generating keys) results
|
||||
password reset. Please update your documentation for Gnuk Token, so
|
||||
that the instruction of importing keys won't cause any confusion. It
|
||||
has supports of ECDSA (with NIST P256 and secp256k1) and EdDSA with
|
||||
EdDSA, but this feature is pretty much experimental, and it requires
|
||||
development version of GnuPG with newest version of libgcrypt. You
|
||||
will not able to keep using EdDSA keys, as the key format is subject
|
||||
to change. It also support RSA-4096 experimentally, but users should
|
||||
know that it takes more than 8 second to sign/decrypt.
|
||||
password reset. Also, you need to import private keys before changing
|
||||
your password. Please update your documentation for Gnuk Token, so
|
||||
that the instruction of importing keys won't cause any confusion.
|
||||
|
||||
It has supports of EdDSA, ECDSA (with NIST P256 and secp256k1), and
|
||||
ECDH (with X25519, NIST P256 and secp256k1), but this ECC feature is
|
||||
somehow experimental, and it requires modern GnuPG 2.2 with libgcrypt
|
||||
1.7.0 or later.
|
||||
|
||||
It also supports RSA-4096, but users should know that it takes more
|
||||
than 8 seconds to sign/decrypt. Key generation of RSA-4096 just fails,
|
||||
because the device doesn't have enough memory.
|
||||
|
||||
With this release, you can test how Gnuk Token works on GNU/Linux,
|
||||
without real hardware, by USBIP emulation (--target=GNU_LINUX).
|
||||
Please note that this emulation is intended only for testing. When
|
||||
Gnuk does crypto computation on host, it is vulnerable by side channel
|
||||
attacks.
|
||||
|
||||
|
||||
What's Gnuk?
|
||||
============
|
||||
|
||||
Gnuk is an implementation of USB cryptographic token for GNU Privacy
|
||||
Guard. Gnuk supports OpenPGP card protocol version 2, and it runs on
|
||||
Guard. Gnuk supports OpenPGP card protocol version 3, and it runs on
|
||||
STM32F103 processor.
|
||||
|
||||
I wish that Gnuk will be a developer's soother who uses GnuPG. I have
|
||||
@@ -43,9 +53,9 @@ FAQ
|
||||
===
|
||||
|
||||
Q0: How Gnuk USB Token is superior than other solutions (OpenPGP
|
||||
card 2.0, GPF Crypto Stick, etc.) ?
|
||||
http://www.g10code.de/p-card.html
|
||||
http://www.privacyfoundation.de/crypto_stick/
|
||||
card 2.0, YubiKey, etc.) ?
|
||||
https://www.g10code.de/p-card.html
|
||||
https://www.yubico.com/
|
||||
A0: Good points of Gnuk are:
|
||||
* If you have skill of electronics and like DIY, you can build
|
||||
Gnuk Token cheaper (see Q8-A8).
|
||||
@@ -58,25 +68,28 @@ A0: Good points of Gnuk are:
|
||||
"for Free Software"; Gnuk supports GnuPG.
|
||||
|
||||
Q1: What kind of key algorithm is supported?
|
||||
A1: Gnuk version 1.0 only supports RSA 2048.
|
||||
Development version of Gnuk (1.1.x) supports 256-bit ECDSA and EdDSA,
|
||||
as well as RSA 4096-bit. But it takes long time to sign with RSA 4096.
|
||||
A1: Gnuk version 1.0 only supports RSA-2048.
|
||||
Gnuk version 1.2.x supports 255-bit EdDSA, as well as RSA-4096.
|
||||
(Note that it takes long time to sign with RSA-4096.)
|
||||
|
||||
Q2: How long does it take for digital signing?
|
||||
A2: It takes a second and a half or so.
|
||||
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?
|
||||
A3: Orthodox choice is Olimex STM32-H103.
|
||||
FST-01 (Flying Stone Tiny 01) is available for sale, and it is a
|
||||
kind of the best choice, hopefully.
|
||||
If you have a skill of electronics, STM32 Nucleo F103 is the best
|
||||
choice for experiment.
|
||||
|
||||
Q4: What's version of GnuPG are you using?
|
||||
A4: In Debian GNU/Linux system, I use gnupg 1.4.12-7 and gnupg-agent
|
||||
2.0.20-1.
|
||||
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.18 in
|
||||
unstable.
|
||||
|
||||
Q5: What's version of pcscd and libccid are you using?
|
||||
A5: I don't use them, pcscd and libccid are optional, you can use Gnuk
|
||||
without them.
|
||||
Token without them.
|
||||
I tested pcscd 1.5.5-4 and libccid 1.3.11-2 which were in Debian
|
||||
squeeze.
|
||||
|
||||
@@ -89,8 +102,11 @@ A6: You need a target board plus a JTAG/SWD debugger. If you just
|
||||
Q7: How much does it cost?
|
||||
A7: Olimex STM32-H103 plus ARM-USB-TINY-H cost 70 Euro or so.
|
||||
|
||||
Q8: How much does it cost for DIY version?
|
||||
A8: STM32 Nucleo F103 costs about $10 USD.
|
||||
|
||||
Q9: I got an error like "gpg: selecting openpgp failed: ec=6.108", what's up?
|
||||
A9: GnuPG's SCDaemon has problems for handling insertion/removal of
|
||||
A9: Older GnuPG's SCDaemon has problems for handling insertion/removal of
|
||||
card/reader. When your newly inserted token is not found by
|
||||
GnuPG, try killing scdaemon and let it to be invoked again. I do:
|
||||
|
||||
@@ -114,33 +130,30 @@ Ab: That's because gnome-keyring-daemon interferes GnuPG. Type:
|
||||
and at the tab of "Startup Programs", disable check buttons for
|
||||
"GPG Password Agent" and "SSH Key Agent".
|
||||
|
||||
Qc: Do you know a good SWD debugger to connect FST-01 or something?
|
||||
Ac: ST-Link/V2 is cheap one. We have a tool/stlinkv2.py as flash ROM
|
||||
writer program.
|
||||
Qc: With GNOME 3.x (x >= 8?), I can't use Gnuk Token at all. Why?
|
||||
Ac: That's because gnome-keyring-daemon interferes GnuPG. Please
|
||||
disable the invocation of gnome-keyring-daemon. In Debian
|
||||
wheezy, it's in the files /etc/xdg/autostart/gnome-keyring-ssh.desktop
|
||||
and /etc/xdg/autostart/gnome-keyring-gpg.desktop.
|
||||
We have a line something like:
|
||||
|
||||
Qd: With GNOME 3.x (x >= 8?), I can't use Gnuk Token at all. Why?
|
||||
Ad: Please set the configration variable OnlyShowIn as none. Like:
|
||||
OnlyShowIn=GNOME;Unity;MATE;
|
||||
|
||||
OnlyShowIn=
|
||||
Please edit this line to:
|
||||
|
||||
In the files of /etc/xdg/autostart/gnome-keyring-gpg.desktop and
|
||||
/etc/xdg/autostart/gnome-keyring-ssh.desktop
|
||||
OnlyShowIn=
|
||||
|
||||
Qd: Do you know a good SWD debugger to connect FST-01 or something?
|
||||
Ad: ST-Link/V2 is cheap one. We have a tool/stlinkv2.py as flash ROM
|
||||
writer program. STM32 Nucleo F103 comes with the valiant of
|
||||
ST-Link/V2. However, the firmware of ST-Link/V2 is proprietary.
|
||||
Now, I develop BBG-SWD, SWD debugger by BeagleBone Green.
|
||||
|
||||
|
||||
Tested features
|
||||
===============
|
||||
|
||||
|
||||
Release notes
|
||||
=============
|
||||
|
||||
This is third experimental release in version 1.1 series of Gnuk.
|
||||
|
||||
While it is daily use by its developer, some newly introduced features
|
||||
(including ECDSA/EdDSA, key generation and firmware upgrade) should be
|
||||
considered experimental. ECDSA/EdDSA is really experimental.
|
||||
Further, EdDSA is much experimental. You won't be able to keep using
|
||||
the EdDSA key, as the key format of GnuPG is subject to change.
|
||||
|
||||
Tested features are:
|
||||
Gnuk is tested by test suite. Please see the test directory.
|
||||
|
||||
* Personalization of the card
|
||||
* Changing Login name, URL, Name, Sex, Language, etc.
|
||||
@@ -157,10 +170,10 @@ Tested features are:
|
||||
* Modify with pin pad
|
||||
* Card holder certificate (read)
|
||||
* Removal of keys
|
||||
* Key generation on device side
|
||||
* Key generation on device side for RSA-2048
|
||||
* Overriding key import
|
||||
|
||||
Original features of Gnuk, tested lightly:
|
||||
Original features of Gnuk, tested manually lightly:
|
||||
|
||||
* OpenPGP card serial number setup
|
||||
* Card holder certificate (write by UPDATE BINARY)
|
||||
@@ -168,12 +181,12 @@ Original features of Gnuk, tested lightly:
|
||||
|
||||
It is known not-working well:
|
||||
|
||||
* It is known that the combination of libccid 1.4.1 (or newer)
|
||||
with libusb 1.0.8 (or older) has a minor problem. It is
|
||||
rare but it is possible for USB communication to be failed,
|
||||
because of a bug in libusb implementation. Use libusbx
|
||||
1.0.9 or newer, or don't use PC/SC, but use internal CCID
|
||||
driver of GnuPG.
|
||||
* It is known that the specific combination of libccid 1.4.1
|
||||
(or newer) with libusb 1.0.8 (or older) had a minor problem.
|
||||
It is rare but it is possible for USB communication to be
|
||||
failed, because of a bug in libusb implementation. Use
|
||||
libusbx 1.0.9 or newer, or don't use PC/SC, but use internal
|
||||
CCID driver of GnuPG.
|
||||
|
||||
|
||||
Targets
|
||||
@@ -186,17 +199,30 @@ DfuSe is for experiment only, because it is impossible for DfuSe to
|
||||
disable read from flash. For real use, please consider killing DfuSe
|
||||
and enabling read protection using JTAG debugger.
|
||||
|
||||
For PIN-pad support, I connect a consumer IR receive module to FST-01,
|
||||
and use controller for TV. PIN verification is supported by this
|
||||
configuration. Yes, it is not secure at all, since it is very easy to
|
||||
monitor IR output of the controllers. It is just an experiment. Note
|
||||
that hardware needed for this experiment is only a consumer IR receive
|
||||
module which is as cheap as 50 JPY.
|
||||
For experimental PIN-pad support, I connect a consumer IR receive
|
||||
module to FST-01, and use controller for TV. PIN verification is
|
||||
supported by this configuration. Yes, it is not secure at all, since
|
||||
it is very easy to monitor IR output of the controllers. It is just
|
||||
an experiment. Note that hardware needed for this experiment is only
|
||||
a consumer IR receive module which is as cheap as 50 JPY.
|
||||
|
||||
Note that you need pinpad support for GnuPG to use PIN-pad enabled
|
||||
Gnuk. The pinpad support for GnuPG is only available in version 2.
|
||||
|
||||
|
||||
Build system and Host system
|
||||
============================
|
||||
|
||||
Makefile is written for GNU make. You need Bash 4.x for configure.
|
||||
|
||||
If your bash is not installed as /bin/bash, you need to run configure
|
||||
script prepending 'bash' before './configure'.
|
||||
|
||||
Some tools are written in Python. If your Python is not installed as
|
||||
/usr/bin/python, please prepend 'python' for your command invocation.
|
||||
Python 2.7 and PyUSB 0.4.3 is assumed.
|
||||
|
||||
|
||||
Souce code
|
||||
==========
|
||||
|
||||
@@ -205,7 +231,9 @@ Gnuk source code is under src/ directory.
|
||||
Note that SHA-2 hash function implementation, src/sha256.c, is based
|
||||
on the original implementation by Dr. Brian Gladman. See:
|
||||
|
||||
http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php
|
||||
http://brg.a2hosted.com//oldsite/cryptography_technology/sha/index.php
|
||||
(was at:
|
||||
http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php)
|
||||
|
||||
|
||||
License
|
||||
@@ -229,14 +257,14 @@ External source code
|
||||
|
||||
Gnuk is distributed with external source code.
|
||||
|
||||
* chopstx/ -- Chopstx 0.04
|
||||
* chopstx/ -- Chopstx 1.5
|
||||
|
||||
We use Chopstx as the kernel for Gnuk.
|
||||
|
||||
Chopstx is distributed under GPLv3+ (with a special exception).
|
||||
|
||||
|
||||
* polarssl/ -- PolarSSL 1.2.10
|
||||
* polarssl/ -- based on PolarSSL 1.2.10 (now mbedTLS)
|
||||
|
||||
Souce code taken from: http://polarssl.org/
|
||||
|
||||
@@ -282,7 +310,7 @@ Gnuk is distributed with external source code.
|
||||
USB vendor ID and product ID (USB device ID)
|
||||
============================================
|
||||
|
||||
When you have a vender ID and assign a product ID for Gnuk, edit the
|
||||
When you have a vendor ID and assign a product ID for Gnuk, edit the
|
||||
file GNUK_USB_DEVICE_ID and add an entry for yours. In this case,
|
||||
please contact Niibe, so that it is listed to the file in the official
|
||||
release of the source code.
|
||||
@@ -339,10 +367,16 @@ How to compile
|
||||
|
||||
You need GNU toolchain and newlib for 'arm-none-eabi' target.
|
||||
|
||||
There is "gcc-arm-embedded" project. See:
|
||||
On Debian we can install the packages of gcc-arm-none-eabi,
|
||||
gdb-arm-none-eabi and its friends. I'm using:
|
||||
|
||||
https://launchpad.net/gcc-arm-embedded/
|
||||
binutils-arm-none-eabi 2.28-4+9+b3
|
||||
gcc-arm-none-eabi 15:5.4.1+svn241155-1
|
||||
gdb-arm-none-eabi 7.12-6+9+b2
|
||||
libnewlib-arm-none-eabi 2.4.0.20160527-2
|
||||
|
||||
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
||||
GNU Toolchain for 'arm-none-eabi' target.
|
||||
|
||||
Change directory to `src':
|
||||
|
||||
@@ -356,7 +390,8 @@ Here, you need to specify USB vendor ID and product ID. For FSIJ's,
|
||||
it's: --vidpid=234b:0000 . Please read section 'USB vendor ID and
|
||||
product ID' above.
|
||||
|
||||
Type:
|
||||
|
||||
Then, type:
|
||||
|
||||
$ make
|
||||
|
||||
@@ -369,18 +404,14 @@ How to install
|
||||
Olimex STM32-H103 board
|
||||
-----------------------
|
||||
|
||||
If you are using Olimex JTAG-Tiny, type following to invoke OpenOCD:
|
||||
If you are using Olimex JTAG-Tiny, type following to invoke OpenOCD
|
||||
and write "gnuk.elf" to Flash ROM:
|
||||
|
||||
$ openocd -f interface/ftdi/olimex-jtag-tiny.cfg -f board/olimex_stm32_h103.cfg
|
||||
$ openocd -f interface/ftdi/olimex-jtag-tiny.cfg \
|
||||
-f board/olimex_stm32_h103.cfg \
|
||||
-c "program build/gnuk.elf verify reset exit"
|
||||
|
||||
Then, with another terminal, type following to write "gnuk.elf" to Flash ROM:
|
||||
|
||||
$ telnet localhost 4444
|
||||
> reset halt
|
||||
> flash write_image erase gnuk.elf
|
||||
> reset
|
||||
> exit
|
||||
$
|
||||
Command invocation is assumed in src/ directory.
|
||||
|
||||
|
||||
Flying Stone Tiny 01
|
||||
@@ -388,11 +419,11 @@ Flying Stone Tiny 01
|
||||
|
||||
If you are using Flying Stone Tiny 01, you need a SWD writer.
|
||||
|
||||
OpenOCD 0.6.1 now supports ST-Link/V2. We can use it:
|
||||
OpenOCD 0.9.0 now supports ST-Link/V2. We can use it like:
|
||||
|
||||
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x_stlink.cfg
|
||||
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
|
||||
-c "program build/gnuk.elf verify reset exit"
|
||||
|
||||
But it doesn't support option bytes handling (protection) yet.
|
||||
|
||||
|
||||
STBee
|
||||
@@ -410,27 +441,33 @@ Then, reset the board.
|
||||
How to protect flash ROM
|
||||
========================
|
||||
|
||||
Invoke your OpenOCD and type:
|
||||
To protect, invoke OpenOCD like (for FST-01):
|
||||
|
||||
$ telnet localhost 4444
|
||||
> reset halt
|
||||
> stm32f1x lock 0
|
||||
> reset
|
||||
> shutdown
|
||||
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
|
||||
-c init -c "reset halt" -c "stm32f1x lock 0" -c reset -c exit
|
||||
|
||||
After power-off / power-on sequence, the contents of flash ROM cannot
|
||||
be accessible from JTAG debugger.
|
||||
|
||||
Unprotecting is:
|
||||
|
||||
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
|
||||
-c init -c "reset halt" -c "stm32f1x unlock 0" -c reset -c exit
|
||||
|
||||
Upon unprotection, flash is erased.
|
||||
|
||||
Note that it would be still possible for some implementation of DfuSe
|
||||
to access the contents. If you want to protect, killing DfuSe and
|
||||
accessing by JTAG debugger is recommended.
|
||||
to access the contents, even if it's protected. If you really want to
|
||||
protect, killing DfuSe and 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
|
||||
PyUSB 0.4.3 (python-usb package in Debian).
|
||||
This is completely optional.
|
||||
|
||||
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
|
||||
[PyUSB] Stop the pcsc daemon.
|
||||
@@ -449,7 +486,7 @@ In case of PyUSB tool, you need to stop pcscd.
|
||||
|
||||
If you use fixed serial number in the file 'GNUK_SERIAL_NUMBER', you can do:
|
||||
|
||||
$ EMAIL=<YOUR-EMAIL-ADDRESS> ../tool/gnuk_put_binary.py -s ../GNUK_SERIAL_NUMBER
|
||||
$ EMAIL=<YOUR-EMAIL-ADDRESS> ../tool/gnuk_put_binary_usb.py -s ../GNUK_SERIAL_NUMBER
|
||||
Writing serial number
|
||||
...
|
||||
|
||||
@@ -457,7 +494,7 @@ If you use fixed serial number in the file 'GNUK_SERIAL_NUMBER', you can do:
|
||||
|
||||
If you have card holder certificate binary file, you can do:
|
||||
|
||||
$ ../tool/gnuk_put_binary.py ../../<YOUR-CERTIFICATE>.bin
|
||||
$ ../tool/gnuk_put_binary_usb.py ../../<YOUR-CERTIFICATE>.bin
|
||||
../../<YOUR-CERTIFICATE>.bin: <LENGTH-OF-YOUR-CERTIFICATE>
|
||||
Updating card holder certificate
|
||||
...
|
||||
@@ -509,7 +546,7 @@ Gnuk supports key generation, but this feature is young and should be
|
||||
considered experimental.
|
||||
|
||||
For detail, please see documentation under doc/. You can see the HTML
|
||||
version at: http://www.fsij.org/doc-gnuk/
|
||||
version at: https://www.fsij.org/doc-gnuk/
|
||||
|
||||
|
||||
How to debug
|
||||
@@ -524,6 +561,10 @@ Inside GDB, we can connect OpenOCD by:
|
||||
|
||||
(gdb) target remote localhost:3333
|
||||
|
||||
or
|
||||
|
||||
(gdb) target extended-remote localhost:3333
|
||||
|
||||
|
||||
You can see the output of PCSCD:
|
||||
|
||||
@@ -544,41 +585,45 @@ See doc/note/firmware-update.
|
||||
Git Repositories
|
||||
================
|
||||
|
||||
Please use: http://gitorious.org/gnuk
|
||||
Please use: https://anonscm.debian.org/cgit/gnuk/gnuk/
|
||||
|
||||
You can get it by:
|
||||
|
||||
$ git clone git://gitorious.org/gnuk/gnuk.git
|
||||
$ git clone git://anonscm.debian.org/gnuk/gnuk/gnuk.git
|
||||
|
||||
It's also available at: www.gniibe.org
|
||||
You can browse at: http://git.gniibe.org/gitweb?p=gnuk/gnuk.git;a=summary
|
||||
You can browse at: https://git.gniibe.org/gitweb?p=gnuk/gnuk.git;a=summary
|
||||
|
||||
I put Chopstx as a submodule of Git. Please do this:
|
||||
|
||||
$ git submodule init
|
||||
$ git submodule update
|
||||
|
||||
We have migrated from ChibiOS/RT to Chopstx. If you have old code of
|
||||
ChibiOS/RT, you need:
|
||||
|
||||
Edit .git/config to remove chibios reference
|
||||
git rm --cached chibios
|
||||
$ git submodule update --init
|
||||
|
||||
|
||||
Information on the Web
|
||||
======================
|
||||
|
||||
Please visit: http://www.fsij.org/gnuk/
|
||||
For more information, please visit: https://www.fsij.org/gnuk/
|
||||
|
||||
Please see the FST-01 support pages:
|
||||
|
||||
https://www.gniibe.org/category/fst-01.html
|
||||
|
||||
Please consider to join Gnuk-users mailing list:
|
||||
|
||||
https://lists.alioth.debian.org/mailman/listinfo/gnuk-users
|
||||
|
||||
The mailing list will be moved to lists.debian.org.
|
||||
|
||||
|
||||
Your Contributions
|
||||
==================
|
||||
|
||||
FSIJ welcomes your contributions. Please assign your copyright
|
||||
to FSIJ (if possible).
|
||||
to FSIJ (if possible), as I do.
|
||||
|
||||
|
||||
Foot note
|
||||
==========
|
||||
|
||||
* NUK(R) is a registered trademark owend by MAPA GmbH, Germany.
|
||||
--
|
||||
|
||||
19
THANKS
19
THANKS
@@ -8,16 +8,35 @@ encouraging the development, testing the implementation, suggesting
|
||||
improvements, or fixing bugs. Here is a list of those people.
|
||||
|
||||
Achim Pietig achim@pietig.com
|
||||
Aidan Thornton
|
||||
Anibal Monsalve Salazar anibal@debian.org
|
||||
Andre Zepezauer andre.zepezauer@student.uni-halle.de
|
||||
Anthony Romano anthony.romano@coreos.com
|
||||
Bertrand Jacquin bertrand@jacquin.bzh
|
||||
Clint Adams clint@softwarefreedom.org
|
||||
Daniel Kahn Gillmor dkg@fifthhorseman.net
|
||||
Elliott Mitchell
|
||||
Hironobu SUZUKI hironobu@h2np.net
|
||||
Jan Suhr jan@suhr.info
|
||||
Jeremy Drake jeremydrake+gnuk@eacceleration.com
|
||||
Jonathan McDowell noodles@earth.li
|
||||
Kaz Kojima kkojima@rr.iij4u.or.jp
|
||||
Kenji Rikitake
|
||||
Ludovic Rousseau ludovic.rousseau@free.fr
|
||||
Luis Felipe R. Murillo luisfelipe@ucla.edu
|
||||
Mateusz Zalega mateusz@nitrokey.com
|
||||
MATSUU Takuto matsuu@gentoo.org
|
||||
Micah Anderson micah@debian.org
|
||||
NAGAMI Takeshi nagami-takeshi@aist.go.jp
|
||||
Nguyễn Hồng Quân quannguyen@mbm.vn
|
||||
Nico Rikken nico@nicorikken.eu
|
||||
NOKUBI Takatsugu knok@daionet.gr.jp
|
||||
Paul Fertser
|
||||
Paul Bakker polarssl_maintainer@polarssl.org
|
||||
Santiago Ruano Rincón santiago@debian.org
|
||||
Shane Coughlan scoughlan@openinventionnetwork.com
|
||||
Stanislas Bach sbach@0g.re
|
||||
Szczepan Zalega szczepan@nitrokey.com
|
||||
Vasily Evseenko
|
||||
Werner Koch wk@gnupg.org
|
||||
Yuji Imai ug@xcast.jp
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/*
|
||||
* Board-specific initialization code.
|
||||
*/
|
||||
void boardInit(void)
|
||||
{
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
/*
|
||||
* Setup for the CQ STARM board.
|
||||
*/
|
||||
#undef SET_USB_CONDITION /* No functionality to disconnect USB */
|
||||
#define SET_LED_CONDITION(on) on /* To emit light, call palSetPad */
|
||||
#define GPIO_LED GPIOC_LED
|
||||
#define IOPORT_LED GPIOC
|
||||
|
||||
/*
|
||||
* Board identifier.
|
||||
*/
|
||||
#define BOARD_CQ_STARM
|
||||
#define BOARD_NAME "CQ STARM"
|
||||
|
||||
/*
|
||||
* Board frequencies.
|
||||
*/
|
||||
#define STM32_LSECLK 32768
|
||||
#define STM32_HSECLK 8000000
|
||||
|
||||
/*
|
||||
* MCU type, this macro is used by both the ST library and the ChibiOS/RT
|
||||
* native STM32 HAL.
|
||||
*/
|
||||
#define STM32F10X_MD
|
||||
|
||||
/*
|
||||
* IO pins assignments.
|
||||
*/
|
||||
#define GPIOC_LED 6
|
||||
|
||||
#if 0
|
||||
#define GPIOA_BUTTON 0
|
||||
#define GPIOA_SPI1NSS 4
|
||||
|
||||
#define GPIOB_SPI2NSS 12
|
||||
#define GPIOC_MMCWP 6
|
||||
#define GPIOC_MMCCP 7
|
||||
#define GPIOC_CANCNTL 10
|
||||
#define GPIOC_DISC 11
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O ports initial setup, this configuration is established soon after reset
|
||||
* in the initialization code.
|
||||
*
|
||||
* The digits have the following meaning:
|
||||
* 0 - Analog input.
|
||||
* 1 - Push Pull output 10MHz.
|
||||
* 2 - Push Pull output 2MHz.
|
||||
* 3 - Push Pull output 50MHz.
|
||||
* 4 - Digital input.
|
||||
* 5 - Open Drain output 10MHz.
|
||||
* 6 - Open Drain output 2MHz.
|
||||
* 7 - Open Drain output 50MHz.
|
||||
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
|
||||
* 9 - Alternate Push Pull output 10MHz.
|
||||
* A - Alternate Push Pull output 2MHz.
|
||||
* B - Alternate Push Pull output 50MHz.
|
||||
* C - Reserved.
|
||||
* D - Alternate Open Drain output 10MHz.
|
||||
* E - Alternate Open Drain output 2MHz.
|
||||
* F - Alternate Open Drain output 50MHz.
|
||||
* Please refer to the STM32 Reference Manual for details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Port A setup.
|
||||
* Everything input with pull-up except:
|
||||
* PA4 - Normal input (ADC_IN4 : VoutX of LIS344ALH).
|
||||
* PA5 - Alternate output (MMC SPI1 SCK).
|
||||
* PA6 - Normal input (MMC SPI1 MISO).
|
||||
* PA7 - Alternate output (MMC SPI1 MOSI).
|
||||
* PA11 - (USBDM)
|
||||
* PA12 - (USBDP)
|
||||
*/
|
||||
#define VAL_GPIOACRL 0xB4B48888 /* PA7...PA0 */
|
||||
#define VAL_GPIOACRH 0x88888888 /* PA15...PA8 */
|
||||
#define VAL_GPIOAODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port B setup.
|
||||
* Everything input with pull-up except:
|
||||
* PB13 - Alternate output (MMC SPI2 SCK).
|
||||
* PB14 - Normal input (MMC SPI2 MISO).
|
||||
* PB15 - Alternate output (MMC SPI2 MOSI).
|
||||
*/
|
||||
#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
|
||||
#define VAL_GPIOBCRH 0xB4B88888 /* PB15...PB8 */
|
||||
#define VAL_GPIOBODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port C setup.
|
||||
* Everything input with pull-up except:
|
||||
* PC4 - Normal input (ADC_IN14 : VoutY of LIS344ALH).
|
||||
* PC5 - Normal input (ADC_IN15 : VoutZ of LIS344ALH).
|
||||
* PC6 - Push Pull output (LED).
|
||||
* (PC9 - SDCard CD)
|
||||
* (PC12 - SDCard CS)
|
||||
* PC14 - Normal input (XTAL).
|
||||
* PC15 - Normal input (XTAL).
|
||||
*/
|
||||
#define VAL_GPIOCCRL 0x83448888 /* PC7...PC0 */
|
||||
#define VAL_GPIOCCRH 0x44888888 /* PC15...PC8 */
|
||||
#define VAL_GPIOCODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port D setup.
|
||||
* Everything input with pull-up except:
|
||||
* (PD9 - USB_DC)
|
||||
*/
|
||||
#define VAL_GPIODCRL 0x88888888 /* PD7...PD0 */
|
||||
#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
|
||||
#define VAL_GPIODODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port E setup.
|
||||
* Everything input with pull-up except:
|
||||
*/
|
||||
#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */
|
||||
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
|
||||
#define VAL_GPIOEODR 0xFFFFFFFF
|
||||
|
||||
#if !defined(_FROM_ASM_)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void boardInit(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FROM_ASM_ */
|
||||
|
||||
#endif /* _BOARD_H_ */
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
#define STM32_SW STM32_SW_PLL
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSE
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
|
||||
#define STM32_PLLMUL_VALUE 9
|
||||
#define STM32_HPRE STM32_HPRE_DIV1
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV2
|
||||
#define STM32_PPRE2 STM32_PPRE2_DIV1
|
||||
#define STM32_ADCPRE STM32_ADCPRE_DIV6
|
||||
#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK
|
||||
|
||||
#include "mcuconf-common.h"
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "config.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/*
|
||||
* Board-specific initialization code.
|
||||
*/
|
||||
void boardInit(void)
|
||||
{
|
||||
/*
|
||||
* Clear LED and SHUTDOWN output.
|
||||
*/
|
||||
palClearPad (IOPORT5, GPIOE_LED);
|
||||
palClearPad (IOPORT3, GPIOC_SHUTDOWN);
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
/*
|
||||
* Setup for the STM32 Primer2.
|
||||
*/
|
||||
#define SET_USB_CONDITION(en) (!en) /* To connect USB, call palClearPad */
|
||||
#define SET_LED_CONDITION(on) (!on) /* To emit light, call palClearPad */
|
||||
#define GPIO_USB GPIOD_DISC
|
||||
#define IOPORT_USB GPIOD
|
||||
#define GPIO_LED GPIOE_LEDR
|
||||
#define IOPORT_LED GPIOE
|
||||
|
||||
/* NeuG settings for ADC2. */
|
||||
|
||||
/*
|
||||
* Board identifier.
|
||||
*/
|
||||
#define BOARD_STM32_PRIMER2
|
||||
#define BOARD_NAME "STM32 Primer2"
|
||||
|
||||
/*
|
||||
* Board frequencies.
|
||||
*/
|
||||
#define STM32_LSECLK 32768
|
||||
#define STM32_HSECLK 12000000
|
||||
|
||||
/*
|
||||
* MCU type, this macro is used by both the ST library and the ChibiOS/RT
|
||||
* native STM32 HAL.
|
||||
*/
|
||||
#define STM32F10X_MD
|
||||
|
||||
/*
|
||||
* IO pins assignments.
|
||||
*/
|
||||
#define GPIOA_BUTTON 8
|
||||
#define GPIOC_SHUTDOWN 13
|
||||
#define GPIOD_DISC 3
|
||||
#define GPIOE_LED 0
|
||||
#define GPIOE_LEDR 1
|
||||
|
||||
/*
|
||||
* I/O ports initial setup, this configuration is established soon after reset
|
||||
* in the initialization code.
|
||||
*
|
||||
* The digits have the following meaning:
|
||||
* 0 - Analog input.
|
||||
* 1 - Push Pull output 10MHz.
|
||||
* 2 - Push Pull output 2MHz.
|
||||
* 3 - Push Pull output 50MHz.
|
||||
* 4 - Digital input.
|
||||
* 5 - Open Drain output 10MHz.
|
||||
* 6 - Open Drain output 2MHz.
|
||||
* 7 - Open Drain output 50MHz.
|
||||
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
|
||||
* 9 - Alternate Push Pull output 10MHz.
|
||||
* A - Alternate Push Pull output 2MHz.
|
||||
* B - Alternate Push Pull output 50MHz.
|
||||
* C - Reserved.
|
||||
* D - Alternate Open Drain output 10MHz.
|
||||
* E - Alternate Open Drain output 2MHz.
|
||||
* F - Alternate Open Drain output 50MHz.
|
||||
* Please refer to the STM32 Reference Manual for details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Port A setup.
|
||||
* Everything input with pull-up except:
|
||||
* PA0 - Digital input with PullUp. AN0
|
||||
* PA1 - Digital input with PullUp. AN1
|
||||
* PA2 - Alternate output (USART2 TX).
|
||||
* PA3 - Normal input (USART2 RX).
|
||||
* PA8 - Input with pull-down (PBUTTON).
|
||||
*/
|
||||
#define VAL_GPIOACRL 0x88884B88 /* PA7...PA0 */
|
||||
#define VAL_GPIOACRH 0x88888888 /* PA15...PA8 */
|
||||
#define VAL_GPIOAODR 0xFFFFFEFF
|
||||
|
||||
/*
|
||||
* Port B setup.
|
||||
* Everything input with pull-up except:
|
||||
* PB13 - Alternate output (AUDIO SPI2 SCK).
|
||||
* PB14 - Normal input (AUDIO SPI2 MISO).
|
||||
* PB15 - Alternate output (AUDIO SPI2 MOSI).
|
||||
*/
|
||||
#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
|
||||
#define VAL_GPIOBCRH 0xB4B88888 /* PB15...PB8 */
|
||||
#define VAL_GPIOBODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port C setup.
|
||||
* Everything input with pull-up except:
|
||||
* PC6 - Normal input because there is an external resistor.
|
||||
* PC7 - Normal input because there is an external resistor.
|
||||
* PC13 - Push Pull output (SHUTDOWN)
|
||||
*/
|
||||
#define VAL_GPIOCCRL 0x44888888 /* PC7...PC0 */
|
||||
#define VAL_GPIOCCRH 0x88388888 /* PC15...PC8 */
|
||||
#define VAL_GPIOCODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port D setup.
|
||||
* Everything input with pull-up except:
|
||||
* PD3 - Push Pull output (USB_DISCONNECT)
|
||||
*/
|
||||
#define VAL_GPIODCRL 0x88883888 /* PD7...PD0 */
|
||||
#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
|
||||
#define VAL_GPIODODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port E setup.
|
||||
* Everything input with pull-up except:
|
||||
* PE0 - Push Pull output (LED0).
|
||||
* PD1 - Push Pull output (LED1).
|
||||
*/
|
||||
#define VAL_GPIOECRL 0x88888833 /* PE7...PE0 */
|
||||
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
|
||||
#define VAL_GPIOEODR 0xFFFFFFFF
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Port F setup.
|
||||
* Everything input with pull-up except:
|
||||
*/
|
||||
#define VAL_GPIOFCRL 0x88888888 /* PF7...PF0 */
|
||||
#define VAL_GPIOFCRH 0x88888888 /* PF15...PF8 */
|
||||
#define VAL_GPIOFODR 0xFFFFFFFF
|
||||
|
||||
/*
|
||||
* Port G setup.
|
||||
* Everything input with pull-up except:
|
||||
*/
|
||||
#define VAL_GPIOGCRL 0x88888888 /* PG7...PG0 */
|
||||
#define VAL_GPIOGCRH 0x88888888 /* PG15...PG8 */
|
||||
#define VAL_GPIOGODR 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#if !defined(_FROM_ASM_)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void boardInit(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _FROM_ASM_ */
|
||||
|
||||
#endif /* _BOARD_H_ */
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
#define STM32_SW STM32_SW_PLL
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSE
|
||||
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV2
|
||||
#define STM32_PLLMUL_VALUE 12
|
||||
#define STM32_HPRE STM32_HPRE_DIV1
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV2
|
||||
#define STM32_PPRE2 STM32_PPRE2_DIV1
|
||||
#define STM32_ADCPRE STM32_ADCPRE_DIV6
|
||||
#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK
|
||||
|
||||
#include "mcuconf-common.h"
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* @brief PAL setup.
|
||||
* @details Digital I/O ports static configuration as defined in @p board.h.
|
||||
* This variable is used by the HAL when initializing the PAL driver.
|
||||
*/
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
const PALConfig pal_default_config =
|
||||
{
|
||||
{VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
|
||||
{VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
|
||||
{VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH},
|
||||
{VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH},
|
||||
{VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH},
|
||||
#if defined(STM32F10X_HD)
|
||||
{VAL_GPIOFODR, VAL_GPIOFCRL, VAL_GPIOFCRH},
|
||||
{VAL_GPIOGODR, VAL_GPIOGCRL, VAL_GPIOGCRH},
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Early initialization code.
|
||||
* This initialization must be performed just after stack setup and before
|
||||
* any other initialization.
|
||||
*/
|
||||
void
|
||||
__early_init(void)
|
||||
{
|
||||
stm32_clock_init();
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
unique_device_id (void)
|
||||
{
|
||||
/* STM32F103 has 96-bit unique device identifier */
|
||||
const uint8_t *addr = (const uint8_t *)0x1ffff7e8;
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes ChibiOS/RT, without being obliged to provide
|
||||
the source code for any proprietary components. See the file exception.txt
|
||||
for full details of how and when the exception can be applied.
|
||||
*/
|
||||
|
||||
/*
|
||||
* STM32 drivers configuration.
|
||||
* The following settings override the default settings present in
|
||||
* the various device driver implementation headers.
|
||||
* Note that the settings for each driver only have effect if the driver
|
||||
* is enabled in halconf.h.
|
||||
*
|
||||
* IRQ priorities:
|
||||
* 15...0 Lowest...Highest.
|
||||
*
|
||||
* DMA priorities:
|
||||
* 0...3 Lowest...Highest.
|
||||
*/
|
||||
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
#define STM32_NO_INIT FALSE
|
||||
#define STM32_HSI_ENABLED TRUE
|
||||
#define STM32_LSI_ENABLED FALSE
|
||||
#define STM32_HSE_ENABLED TRUE
|
||||
#define STM32_LSE_ENABLED FALSE
|
||||
#define STM32_USB_CLOCK_REQUIRED TRUE
|
||||
#define STM32_USBPRE STM32_USBPRE_DIV1P5
|
||||
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
|
||||
#define STM32_PVD_ENABLE FALSE
|
||||
#define STM32_PLS STM32_PLS_LEV0
|
||||
|
||||
/*
|
||||
* ADC driver system settings.
|
||||
*/
|
||||
#define USE_STM32_ADC1 TRUE
|
||||
#define STM32_ADC1_DMA_PRIORITY 3
|
||||
#define STM32_ADC1_IRQ_PRIORITY 5
|
||||
#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
*/
|
||||
#define USE_STM32_CAN1 FALSE
|
||||
#define STM32_CAN1_IRQ_PRIORITY 11
|
||||
|
||||
/*
|
||||
* PWM driver system settings.
|
||||
*/
|
||||
#define USE_STM32_PWM1 FALSE
|
||||
#define USE_STM32_PWM2 FALSE
|
||||
#define USE_STM32_PWM3 FALSE
|
||||
#define USE_STM32_PWM4 FALSE
|
||||
#define STM32_PWM1_IRQ_PRIORITY 7
|
||||
#define STM32_PWM2_IRQ_PRIORITY 7
|
||||
#define STM32_PWM3_IRQ_PRIORITY 7
|
||||
#define STM32_PWM4_IRQ_PRIORITY 7
|
||||
|
||||
/*
|
||||
* SERIAL driver system settings.
|
||||
*/
|
||||
#define USE_STM32_USART1 FALSE
|
||||
#define USE_STM32_USART2 FALSE
|
||||
#define USE_STM32_USART3 FALSE
|
||||
#if defined(STM32F10X_HD) || defined(STM32F10X_CL)
|
||||
#define USE_STM32_UART4 FALSE
|
||||
#define USE_STM32_UART5 FALSE
|
||||
#endif
|
||||
#define STM32_USART1_PRIORITY 12
|
||||
#define STM32_USART2_PRIORITY 12
|
||||
#define STM32_USART3_PRIORITY 12
|
||||
#if defined(STM32F10X_HD) || defined(STM32F10X_CL)
|
||||
#define STM32_UART4_PRIORITY 12
|
||||
#define STM32_UART5_PRIORITY 12
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SPI driver system settings.
|
||||
*/
|
||||
#define USE_STM32_SPI1 FALSE
|
||||
#define USE_STM32_SPI2 FALSE
|
||||
#define STM32_SPI1_DMA_PRIORITY 2
|
||||
#define STM32_SPI2_DMA_PRIORITY 2
|
||||
#define STM32_SPI1_IRQ_PRIORITY 10
|
||||
#define STM32_SPI2_IRQ_PRIORITY 10
|
||||
#define STM32_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
|
||||
/*
|
||||
* USB driver system settings.
|
||||
*/
|
||||
#define STM32_USB_USE_USB1 TRUE
|
||||
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
|
||||
#define STM32_USB_USB1_HP_IRQ_PRIORITY 6
|
||||
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
|
||||
2
chopstx
2
chopstx
Submodule chopstx updated: 23893d9b73...96d2a81331
@@ -25,7 +25,7 @@ import sys, os
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# 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.
|
||||
templates_path = ['_templates']
|
||||
|
||||
@@ -22,24 +22,19 @@ tool/stlinkv2.py.
|
||||
OpenOCD
|
||||
-------
|
||||
|
||||
For JTAG/SWD debugger, we can use OpenOCD somehow.
|
||||
|
||||
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.
|
||||
For JTAG/SWD debugger, we can use OpenOCD.
|
||||
|
||||
|
||||
GNU Toolchain
|
||||
-------------
|
||||
|
||||
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/
|
||||
|
||||
It is based on GCC 4.8 (as of December, 2013). We are using "-O3 -Os"
|
||||
for compiler option.
|
||||
We are using "-O3 -Os" for compiler option.
|
||||
|
||||
|
||||
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,38 +0,0 @@
|
||||
==========================
|
||||
GnuPG settings for GNOME 3
|
||||
==========================
|
||||
|
||||
In the article `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
|
||||
=========================
|
||||
|
||||
It seems that it is more integrated into the desktop.
|
||||
It is difficult to kill it. It would be possible to kill it simply,
|
||||
but then, I can't use, say, wi-fi access (which needs to access "secrets")
|
||||
any more.
|
||||
|
||||
We can't use GNOME configuration tool to disable interference by
|
||||
GNOME keyrings any more. It seems that desktop should not have
|
||||
customization these days.
|
||||
|
||||
|
||||
GNOME-SESSION-PROPERTIES
|
||||
========================
|
||||
|
||||
After struggling some hours, I figured out it is GNOME-SESSION-PROPERTIES
|
||||
to disable the interference. Invoking::
|
||||
|
||||
$ gnome-session-properties
|
||||
|
||||
and at the tab of "Startup Programs", I removed radio check buttons
|
||||
for "GPG Password Agent" and "SSH Key Agent".
|
||||
|
||||
|
||||
Now, I use gpg-agent for GnuPG Agent and SSH agent with Gnuk Token.
|
||||
@@ -5,174 +5,14 @@ Key import from PC to Gnuk Token (no removal)
|
||||
This document describes how I put my **keys on PC** to the Token
|
||||
without removing keys from PC.
|
||||
|
||||
The difference is just not-to-save changes after key imports.
|
||||
The difference is only the last step.
|
||||
I don't save changes on PC after keytocard.
|
||||
|
||||
After personalization, I put my keys into the Token.
|
||||
For the steps before the last step, please see `keytocard with removing keys on PC`_.
|
||||
|
||||
Here is the log.
|
||||
.. _keytocard with removing keys on PC: gnuk-keytocard
|
||||
|
||||
I invoke GnuPG with my key (4ca7babe) and with ``--homedir`` option
|
||||
to specify the directory which contains my secret keys. ::
|
||||
|
||||
$ gpg --homedir=/home/gniibe/tmp/gnuk-testing-dir --edit-key 4ca7babe
|
||||
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
Secret key is available.
|
||||
|
||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
||||
sub 2048R/5BB065DC created: 2010-10-22 expires: never usage: A
|
||||
[ultimate] (1). NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
|
||||
Then, GnuPG enters its own command interaction mode. The prompt is ``gpg>``.
|
||||
To enable ``keytocard`` command, I type ``toggle`` command. ::
|
||||
|
||||
gpg> toggle
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
Firstly, I import my primary key into Gnuk Token.
|
||||
I type ``keytocard`` command, answer ``y`` to confirm keyimport,
|
||||
and type ``1`` to say it's signature key. ::
|
||||
|
||||
gpg> keytocard
|
||||
Really move the primary key? (y/N) y
|
||||
Signature key ....: [none]
|
||||
Encryption key....: [none]
|
||||
Authentication key: [none]
|
||||
|
||||
Please select where to store the key:
|
||||
(1) Signature key
|
||||
(3) Authentication key
|
||||
Your selection? 1
|
||||
|
||||
Then, GnuPG asks two passwords. One is the passphrase of **keys on PC**
|
||||
and another is the password of **Gnuk Token**. Note that the password of
|
||||
the token and the password of the keys on PC are different things,
|
||||
although they can be same.
|
||||
|
||||
Here, I assume that Gnuk Token's admin password of factory setting (12345678).
|
||||
|
||||
I enter these passwords. ::
|
||||
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
||||
2048-bit RSA key, ID 4CA7BABE, created 2010-10-15
|
||||
<PASSWORD-KEY-4CA7BABE>
|
||||
gpg: writing new key
|
||||
gpg: 3 Admin PIN attempts remaining before card is permanently locked
|
||||
|
||||
Please enter the Admin PIN
|
||||
Enter Admin PIN: 12345678
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
The primary key is now on the Token and GnuPG says its card-no (F517 00000001),
|
||||
where F517 is the vendor ID of FSIJ.
|
||||
|
||||
Secondly, I import my subkey of encryption. I select key number '1'. ::
|
||||
|
||||
gpg> key 1
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/084239CF created: 2010-10-15 expires: never
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
You can see that the subkey is marked by '*'.
|
||||
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
||||
I select ``2`` as it's encryption key. ::
|
||||
|
||||
gpg> keytocard
|
||||
Signature key ....: [none]
|
||||
Encryption key....: [none]
|
||||
Authentication key: [none]
|
||||
|
||||
Please select where to store the key:
|
||||
(2) Encryption key
|
||||
Your selection? 2
|
||||
|
||||
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
||||
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
||||
2048-bit RSA key, ID 084239CF, created 2010-10-15
|
||||
<PASSWORD-KEY-4CA7BABE>
|
||||
gpg: writing new key
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
The sub key is now on the Token and GnuPG says its card-no for it.
|
||||
|
||||
I type ``key 1`` to deselect key number '1'. ::
|
||||
|
||||
gpg> key 1
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
Thirdly, I select sub key of authentication which has key number '2'. ::
|
||||
|
||||
gpg> key 2
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
You can see that the subkey number '2' is marked by '*'.
|
||||
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
||||
I select ``3`` as it's authentication key. ::
|
||||
|
||||
gpg> keytocard
|
||||
Signature key ....: [none]
|
||||
Encryption key....: [none]
|
||||
Authentication key: [none]
|
||||
|
||||
Please select where to store the key:
|
||||
(3) Authentication key
|
||||
Your selection? 3
|
||||
|
||||
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
||||
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
||||
2048-bit RSA key, ID 5BB065DC, created 2010-10-22
|
||||
<PASSWORD-KEY-4CA7BABE>
|
||||
gpg: writing new key
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
card-no: F517 00000001
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
The sub key is now on the Token and GnuPG says its card-no for it.
|
||||
Here is the session log of the last step.
|
||||
|
||||
Lastly, I quit GnuPG. Note that I **don't** save changes. ::
|
||||
|
||||
@@ -182,4 +22,4 @@ Lastly, I quit GnuPG. Note that I **don't** save changes. ::
|
||||
$
|
||||
|
||||
All keys are imported to Gnuk Token now.
|
||||
Still, secret keys are available on PC.
|
||||
Still, secret keys are available on PC, too.
|
||||
|
||||
@@ -22,33 +22,31 @@ See `another document`_ to import keys to the Token from copied directory.
|
||||
|
||||
After personalization, I put my keys into the Token.
|
||||
|
||||
Here is the log.
|
||||
Here is the session log.
|
||||
|
||||
I invoke GnuPG with my key (4ca7babe). ::
|
||||
I invoke GnuPG with my key (249CB3771750745D5CDD323CE267B052364F028D). ::
|
||||
|
||||
$ gpg --edit-key 4ca7babe
|
||||
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
$ gpg --edit-key 249CB3771750745D5CDD323CE267B052364F028D
|
||||
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.
|
||||
|
||||
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>
|
||||
|
||||
sec ed25519/E267B052364F028D
|
||||
created: 2015-08-12 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/850AF040D619F240
|
||||
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>``.
|
||||
To enable ``keytocard`` command, I type ``toggle`` command. ::
|
||||
|
||||
gpg> toggle
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
Firstly, I import my primary key into Gnuk Token.
|
||||
I type ``keytocard`` command, answer ``y`` to confirm keyimport,
|
||||
@@ -56,135 +54,129 @@ and type ``1`` to say it's signature key. ::
|
||||
|
||||
gpg> keytocard
|
||||
Really move the primary key? (y/N) y
|
||||
Signature key ....: [none]
|
||||
Encryption key....: [none]
|
||||
Authentication key: [none]
|
||||
|
||||
Please select where to store the key:
|
||||
(1) Signature key
|
||||
(3) Authentication key
|
||||
Your selection? 1
|
||||
|
||||
Then, GnuPG asks two passwords. One is the passphrase of **keys on PC**
|
||||
and another is the password of **Gnuk Token**. Note that the password of
|
||||
the token and the password of the keys on PC are different things,
|
||||
Then, GnuPG asks two kinds of passphrases. One is the passphrase of **keys on PC**
|
||||
and another is the passphrase of **Gnuk Token**. Note that the passphrase of
|
||||
the token and the passphrase of the keys on PC are different things,
|
||||
although they can be same.
|
||||
|
||||
Here, I assume that Gnuk Token's admin password of factory setting (12345678).
|
||||
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
|
||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
||||
2048-bit RSA key, ID 4CA7BABE, created 2010-10-15
|
||||
<PASSWORD-KEY-4CA7BABE>
|
||||
gpg: writing new key
|
||||
gpg: 3 Admin PIN attempts remaining before card is permanently locked
|
||||
Please enter your passphrase, so that the secret key can be unlocked for this session
|
||||
<PASSWORD-KEY-ON-PC>
|
||||
|
||||
Please enter the Admin PIN
|
||||
Enter Admin PIN: 12345678
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
The primary key is now on the Token and GnuPG says its card-no (F517 00000001),
|
||||
where F517 is the vendor ID of FSIJ.
|
||||
sec ed25519/E267B052364F028D
|
||||
created: 2015-08-12 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/850AF040D619F240
|
||||
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>
|
||||
|
||||
Secondly, I import my subkey of encryption. I select key number '1'. ::
|
||||
|
||||
gpg> key 1
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/084239CF created: 2010-10-15 expires: never
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec ed25519/E267B052364F028D
|
||||
created: 2015-08-12 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb* cv25519/850AF040D619F240
|
||||
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 '*'.
|
||||
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
||||
I select ``2`` as it's encryption key. ::
|
||||
|
||||
gpg> keytocard
|
||||
Signature key ....: [none]
|
||||
Encryption key....: [none]
|
||||
Authentication key: [none]
|
||||
|
||||
Please select where to store the key:
|
||||
(2) Encryption key
|
||||
Your selection? 2
|
||||
|
||||
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
||||
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
||||
2048-bit RSA key, ID 084239CF, created 2010-10-15
|
||||
<PASSWORD-KEY-4CA7BABE>
|
||||
gpg: writing new key
|
||||
Please enter your passphrase, so that the secret key can be unlocked for this session
|
||||
<PASSWORD-KEY-ON-PC>
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec ed25519/E267B052364F028D
|
||||
created: 2015-08-12 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb* cv25519/850AF040D619F240
|
||||
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>
|
||||
|
||||
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'. ::
|
||||
|
||||
gpg> key 1
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec ed25519/E267B052364F028D
|
||||
created: 2015-08-12 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/850AF040D619F240
|
||||
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>
|
||||
|
||||
Thirdly, I select sub key of authentication which has key number '2'. ::
|
||||
|
||||
gpg> key 2
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec ed25519/E267B052364F028D
|
||||
created: 2015-08-12 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/850AF040D619F240
|
||||
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 number '2' is marked by '*'.
|
||||
I type ``keytocard`` command to import this subkey to Gnuk Token.
|
||||
I select ``3`` as it's authentication key. ::
|
||||
|
||||
gpg> keytocard
|
||||
Signature key ....: [none]
|
||||
Encryption key....: [none]
|
||||
Authentication key: [none]
|
||||
|
||||
Please select where to store the key:
|
||||
(3) Authentication key
|
||||
Your selection? 3
|
||||
|
||||
Then, GnuPG asks the passphrase of **keys on PC** again. I enter. ::
|
||||
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "NIIBE Yutaka <gniibe@fsij.org>"
|
||||
2048-bit RSA key, ID 5BB065DC, created 2010-10-22
|
||||
<PASSWORD-KEY-4CA7BABE>
|
||||
gpg: writing new key
|
||||
Please enter your passphrase, so that the secret key can be unlocked for this session
|
||||
<PASSWORD-KEY-ON-PC>
|
||||
|
||||
sec 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb* 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
card-no: F517 00000001
|
||||
(1) NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec ed25519/E267B052364F028D
|
||||
created: 2015-08-12 expires: never usage: SC
|
||||
trust: ultimate validity: ultimate
|
||||
ssb cv25519/850AF040D619F240
|
||||
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>
|
||||
|
||||
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. ::
|
||||
|
||||
|
||||
@@ -22,41 +22,40 @@ Besides, some people sometimes prefer the word "passphrase" to
|
||||
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``. ::
|
||||
|
||||
$ gpg --card-edit
|
||||
Application ID ...: D276000124010200F517000000010000
|
||||
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||
Application ID ...: D276000124010200FFFE871930590000
|
||||
Version ..........: 2.0
|
||||
Manufacturer .....: FSIJ
|
||||
Serial number ....: 00000001
|
||||
Manufacturer .....: unmanaged S/N range
|
||||
Serial number ....: 87193059
|
||||
Name of cardholder: Yutaka Niibe
|
||||
Language prefs ...: ja
|
||||
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
|
||||
Signature PIN ....: not forced
|
||||
Key attributes ...: 2048R 2048R 2048R
|
||||
Key attributes ...: ed25519 cv25519 ed25519
|
||||
Max. PIN lengths .: 127 127 127
|
||||
PIN retry counter : 3 3 3
|
||||
Signature counter : 0
|
||||
Signature key ....: 1241 24BD 3B48 62AF 7A0A 42F1 00B4 5EBD 4CA7 BABE
|
||||
created ....: 2010-10-15 06:46:33
|
||||
Encryption key....: 42E1 E805 4E6F 1F30 26F2 DC79 79A7 9093 0842 39CF
|
||||
created ....: 2010-10-15 06:46:33
|
||||
Authentication key: B4D9 7142 C42D 6802 F5F7 4E70 9C33 B6BA 5BB0 65DC
|
||||
created ....: 2010-10-22 06:06:36
|
||||
General key info..:
|
||||
pub 2048R/4CA7BABE 2010-10-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec> 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb> 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb> 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
card-no: F517 00000001
|
||||
|
||||
Signature key ....: 249C B377 1750 745D 5CDD 323C E267 B052 364F 028D
|
||||
created ....: 2015-08-12 07:10:48
|
||||
Encryption key....: E228 AB42 0F73 3B1D 712D E50C 850A F040 D619 F240
|
||||
created ....: 2015-08-12 07:10:48
|
||||
Authentication key: E63F 31E6 F203 20B5 D796 D266 5F91 0521 FAA8 05B1
|
||||
created ....: 2015-08-12 07:16:14
|
||||
General key info..: pub ed25519/E267B052364F028D 2015-08-12 NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec> ed25519/E267B052364F028D created: 2015-08-12 expires: never
|
||||
card-no: FFFE 87193059
|
||||
ssb> cv25519/850AF040D619F240 created: 2015-08-12 expires: never
|
||||
card-no: FFFE 87193059
|
||||
ssb> ed25519/5F910521FAA805B1 created: 2015-08-12 expires: never
|
||||
card-no: FFFE 87193059
|
||||
|
||||
gpg/card>
|
||||
|
||||
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". ::
|
||||
|
||||
gpg/card> passwd
|
||||
gpg: OpenPGP card no. D276000124010200F517000000010000 detected
|
||||
gpg: OpenPGP card no. D276000124010200FFFE871930590000 detected
|
||||
|
||||
Please enter the PIN
|
||||
Enter PIN: 123456
|
||||
@@ -94,15 +93,24 @@ please change admin-password at first.
|
||||
Then, the token works as same as OpenPGPcard specification
|
||||
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
|
||||
(by wrong attempt to entering PIN). This is optional step. ::
|
||||
|
||||
Set up of reset code (optional)
|
||||
===============================
|
||||
|
||||
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
|
||||
Admin commands are allowed
|
||||
|
||||
gpg/card> passwd
|
||||
gpg: OpenPGP card no. D276000124010200F517000000010000 detected
|
||||
gpg: OpenPGP card no. D276000124010200FFFE871930590000 detected
|
||||
|
||||
1 - change PIN
|
||||
2 - unblock PIN
|
||||
@@ -135,4 +143,4 @@ Then, I 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``. ::
|
||||
|
||||
$ gpg --card-edit
|
||||
Application ID ...: D276000124010200FFFE330069060000
|
||||
|
||||
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||
Application ID ...: D276000124010200FFFE871930590000
|
||||
Version ..........: 2.0
|
||||
Manufacturer .....: unmanaged S/N range
|
||||
Serial number ....: 33006906
|
||||
Serial number ....: 87193059
|
||||
Name of cardholder: [not set]
|
||||
Language prefs ...: [not set]
|
||||
Sex ..............: unspecified
|
||||
URL of public key : [not set]
|
||||
Login data .......: [not set]
|
||||
Signature PIN ....: forced
|
||||
Key attributes ...: 2048R 2048R 2048R
|
||||
Key attributes ...: rsa2048 rsa2048 rsa2048
|
||||
Max. PIN lengths .: 127 127 127
|
||||
PIN retry counter : 3 3 3
|
||||
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
|
||||
|
||||
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
|
||||
Login data (account name): gniibe
|
||||
@@ -72,4 +74,4 @@ Then, I quit. ::
|
||||
|
||||
gpg/card> quit
|
||||
|
||||
That's all.
|
||||
That's all in this step.
|
||||
|
||||
@@ -27,19 +27,15 @@ Make sure there is no ``scdaemon`` for configuring Gnuk Token. You can kill ``
|
||||
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.
|
||||
|
||||
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
|
||||
Writing serial number
|
||||
Device: 006
|
||||
Device:
|
||||
Configuration: 1
|
||||
Interface: 0
|
||||
d2 76 00 01 24 01 02 00 f5 17 00 00 00 01 00 00
|
||||
|
||||
|
||||
The example above is the case of libusb version.
|
||||
|
||||
Use the tool ``../tool/gnuk_put_binary.py`` instead , for PC/SC Lite.
|
||||
You need PyScard for this.
|
||||
|
||||
@@ -12,35 +12,38 @@ Here is my GnuPG settings.
|
||||
I create ``.gnupg/gpg.conf`` file with the following content. ::
|
||||
|
||||
use-agent
|
||||
personal-digest-preferences SHA256
|
||||
cert-digest-algo SHA256
|
||||
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
|
||||
default-key 0xE267B052364F028D
|
||||
|
||||
default-key 0x4ca7babe
|
||||
|
||||
In addition to the ``use-agent`` option, set preferences on algorithms, and specify my default key.
|
||||
In addition to the ``use-agent`` option, I specify my default key.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
============================
|
||||
|
||||
I deactivate seahose-agent. Also, for GNOME 2, I deactivate gnome-keyring managing SSH key. ::
|
||||
|
||||
$ 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. ::
|
||||
I create ``.gnupg/gpg-agent.conf`` file with the following content. ::
|
||||
|
||||
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
|
||||
==========
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
sphinx-quickstart on Wed Jul 4 15:29:05 2012.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
Copyright (C) 2012, 2013 NIIBE Yutaka
|
||||
Copyright (C) 2012, 2013 Free Software Initiative of Japan
|
||||
Copyright (C) 2012, 2013, 2016 NIIBE Yutaka
|
||||
Copyright (C) 2012, 2013, 2016 Free Software Initiative of Japan
|
||||
This document is licensed under a CC-BY-SA 3.0 Unported License
|
||||
|
||||
Gnuk Documentation
|
||||
@@ -20,12 +20,11 @@ Contents:
|
||||
udev-rules.rst
|
||||
gnuk-token-initial-configuration.rst
|
||||
gnuk-personalization.rst
|
||||
generating-2048-RSA-key.rst
|
||||
generating-key.rst
|
||||
gnuk-keytocard.rst
|
||||
gnuk-keytocard-noremoval.rst
|
||||
gnuk-passphrase-setting.rst
|
||||
using-gnuk-token-with-another-computer.rst
|
||||
gnome3-gpg-settings.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
|
||||
STM32F103 processor.
|
||||
|
||||
This document explains about Gnuk 1.2, which comes with ECC algorithm.
|
||||
|
||||
|
||||
Cryptographic token and feature of Gnuk
|
||||
---------------------------------------
|
||||
@@ -31,15 +33,15 @@ Target boards for running Gnuk
|
||||
------------------------------
|
||||
|
||||
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)
|
||||
|
||||
* Olimex STM32-H103
|
||||
|
||||
* STM32 part of STM8S Discovery Kit
|
||||
* ST Nucleo F103
|
||||
|
||||
* STBee
|
||||
* Nitrokey Start
|
||||
|
||||
|
||||
Host prerequisites for using Gnuk Token
|
||||
@@ -49,11 +51,9 @@ Host prerequisites for using Gnuk Token
|
||||
|
||||
* libusb
|
||||
|
||||
* [Optional] PC/SC lite (pcscd, libccid)
|
||||
|
||||
* [Optional] SSH: openssh
|
||||
|
||||
* [optional] Web: scute, firefox
|
||||
* [experimental] Web: scute, firefox
|
||||
|
||||
|
||||
Usages
|
||||
@@ -62,4 +62,4 @@ Usages
|
||||
* Sign with GnuPG
|
||||
* Decrypt with GnuPG
|
||||
* 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
|
||||
|
||||
@@ -48,41 +48,11 @@ I have three keys in my token.
|
||||
With the script below, I extract public key of the keygrip
|
||||
5D6C89682D07CCFC034AF508420BF2276D8018ED into the file: 5D6C8968.bin::
|
||||
|
||||
$ ./get_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
|
||||
$ ./get_raw_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
|
||||
|
||||
Here is the script, get_public_key.py::
|
||||
|
||||
#! /usr/bin/python
|
||||
|
||||
import sys, binascii
|
||||
from subprocess import check_output
|
||||
|
||||
def get_gpg_public_key(keygrip):
|
||||
result = check_output(["gpg-connect-agent", "READKEY %s" % keygrip, "/bye"])
|
||||
key = ""
|
||||
while True:
|
||||
i = result.find('%')
|
||||
if i < 0:
|
||||
key += result
|
||||
break
|
||||
hex_str = result[i+1:i+3]
|
||||
key += result[0:i]
|
||||
key += chr(int(hex_str,16))
|
||||
result = result[i+3:]
|
||||
|
||||
pos = key.index("D (10:public-key(3:rsa(1:n257:") + 31 # skip NUL too
|
||||
key = key[pos:-17] # )(1:e3:XYZ)))\nOK\n
|
||||
if len(key) != 256:
|
||||
raise ValueError, binascii.hexlify(key)
|
||||
return key
|
||||
|
||||
if __name__ == '__main__':
|
||||
keygrip = sys.argv[1]
|
||||
k = get_gpg_public_key(keygrip)
|
||||
shorthand = keygrip[0:8] + ".bin"
|
||||
f = open(shorthand,"w")
|
||||
f.write(k)
|
||||
f.close()
|
||||
(The script is available in the directory gnuk/tool. Please note that
|
||||
it was written in the early stage of the development. The quality of
|
||||
the code is somewhat questionable.)
|
||||
|
||||
|
||||
Then, we can put the data of public key into token by::
|
||||
|
||||
131
doc/note/firmware-update-2
Normal file
131
doc/note/firmware-update-2
Normal file
@@ -0,0 +1,131 @@
|
||||
Please refer:
|
||||
|
||||
How can I reflash FST-01 with SWD port?:
|
||||
http://www.gniibe.org/FST-01/q_and_a/swd-debugger.html
|
||||
|
||||
|
||||
Installing newer version of Gnuk onto FST-01 with Gnuk 1.0.1
|
||||
============================================================
|
||||
|
||||
Please note that the feature of firmware upgrade is somewhat
|
||||
experimental. I haven't got any success reports yet, but it's only
|
||||
used by me, so far. When you will get some failure during your
|
||||
firmware installation, you will need SWD debugger. YOU HAVE BEEN
|
||||
WARNED. It is best to try firmware upgrade after you get a SWD
|
||||
debugger.
|
||||
|
||||
|
||||
The firmare upgrade feature of Gnuk
|
||||
------------------------------------
|
||||
|
||||
Gnuk supports firmware upgrade by reGNUal. It works in the following
|
||||
steps.
|
||||
|
||||
1. User registers RSA public key to Gnuk Token for firmware upgrade
|
||||
|
||||
2. When User wants firmware upgrade, user sends
|
||||
the GET_CHALLENGE command then the EXTERNAL_AUTHENTICATE command
|
||||
to Gnuk Token from host PC to authenticate.
|
||||
The EXTERNAL_AUTHENTICATE command message consists of
|
||||
signature (of challenge) by corresponding RSA private key.
|
||||
|
||||
3. When Gnuk Token receives the EXTERNAL_AUTHENTICATE command message
|
||||
and validates signature successfully, Gnuk finishes its normal
|
||||
operation and goes to enter mode of loading special program onto RAM.
|
||||
|
||||
4. Host PC sends reflashing program (reGNUal) to Gnuk Token.
|
||||
|
||||
5. Gnuk clears up all content of flash ROM (but first 4KiB of system)
|
||||
at the end of receiving special program and transfers its control
|
||||
to reGNUal.
|
||||
|
||||
6. reGNUal on Gnuk Token receives new firmware image from host PC and writes
|
||||
to each page.
|
||||
|
||||
7. Done.
|
||||
|
||||
|
||||
Host PC setting for Gnuk
|
||||
------------------------
|
||||
|
||||
You need proper configuration for permission of Gnuk Token (udev
|
||||
setting). It should have lines something like: ::
|
||||
|
||||
# Gnuk Token by FSIJ
|
||||
|
||||
SUBSYSTEMS=="usb", ACTION=="add", \
|
||||
ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0000", \
|
||||
ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
|
||||
|
||||
I have those lines in /etc/udev/rules.d/69-gnuk.rules.
|
||||
|
||||
|
||||
Building another version (newer) of Gnuk
|
||||
----------------------------------------
|
||||
|
||||
Please see README of Gnuk for detail, but it's like configure
|
||||
and make: ::
|
||||
|
||||
$ pwd
|
||||
/home/user/src/gnuk
|
||||
$ cd src
|
||||
$ ./configure --vidpid=234b:0000
|
||||
$ make
|
||||
|
||||
Please take care of configure options. The default target in 1.0.x
|
||||
series is Olimex STM32 H103 (not FST-01). The default target in 1.1.8
|
||||
is FST-01.
|
||||
|
||||
|
||||
Then you get build/gnuk.elf and build/gnuk.bin.
|
||||
|
||||
Invoking configure with FSIJ's USB ID (234b:0000) means that you are
|
||||
using FSIJ's USB ID (for reGNUal in this case). Please note that FSIJ
|
||||
only allows use of its USB ID for specific situations. Please read
|
||||
README of Gnuk about that.
|
||||
|
||||
|
||||
Bulding reGNUal
|
||||
---------------
|
||||
|
||||
You need to compile reGNUal. ::
|
||||
|
||||
$ cd ../regnual
|
||||
$ make
|
||||
|
||||
Then, you should have regnual.bin. Note that 'configure' of Gnuk
|
||||
itself is needed before compiling reGNUal.
|
||||
|
||||
|
||||
upgrade_by_passwd.py
|
||||
--------------------
|
||||
|
||||
In the source code distribution of 1.0.4 (or current development
|
||||
version) of Gnuk, there is a tool named 'upgrade_by_passwd.py'.
|
||||
|
||||
This is an easy tool to hide lengthy steps from user and to allow user
|
||||
firmware upgrade only by password of Gnuk Token.
|
||||
|
||||
Before running the script, you need to kill scdaemon: ::
|
||||
|
||||
$ gpg-connect-agent "SCD KILLSCD" "SCD BYE" /bye
|
||||
|
||||
The command line invokation above assumes that you properly configure
|
||||
your environment for Gnuk Token.
|
||||
|
||||
|
||||
How to run the script: ::
|
||||
|
||||
$ cd tool
|
||||
$ ./upgrade_by_passwd.py ../regnual/regnual.bin ../src/build/gnuk.bin
|
||||
|
||||
Then, the script on your host PC invoke the steps described above, and
|
||||
you will get new version of Gnuk installed.
|
||||
|
||||
You can also specify -p option to enter your password (other than
|
||||
factory setting).
|
||||
|
||||
If you already have configured another upgrade key installed, you can
|
||||
specify different slot by -k ``<slot_no>`` option. SLOT_NO can be 0
|
||||
to 3.
|
||||
--
|
||||
@@ -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``
|
||||
command.
|
||||
|
||||
Or, you can use ``gpgconf`` command. Type::
|
||||
|
||||
$ gpgconf --reload scdameon
|
||||
|
||||
will do the samething.
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -10,10 +10,13 @@ PC/SC Lite, as it has its own device configuration.
|
||||
udev rules for Gnuk Token
|
||||
=========================
|
||||
|
||||
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
|
||||
change, if your installation is older (than jessie). Newer "gnupg"
|
||||
package (1.4.15-1 or later) has already supported Gnuk Token.
|
||||
In case of Debian, there is a file /lib/udev/rules.d/60-gnupg.rules
|
||||
(or /lib/udev/rules.d/60-scdamon.rules for newer version),
|
||||
when you install "gnupg" package (or "scdaemon" package).
|
||||
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
|
||||
permission to use the device. We specify USB ID of Gnuk Token (by
|
||||
@@ -30,7 +33,7 @@ FSIJ)::
|
||||
+
|
||||
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).
|
||||
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
|
||||
================================================
|
||||
|
||||
Using the Token, we need to put the public key and the secret
|
||||
key reference (to the token) in ``.gnupg``.
|
||||
In order to use the Token, we need to put the public key and the secret
|
||||
key references (to the token) under ``.gnupg`` directory.
|
||||
|
||||
To do that, invoke GnuPG with ``--card-edit`` option. ::
|
||||
|
||||
$ gpg --card-edit
|
||||
Application ID ...: D276000124010200F517000000010000
|
||||
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||
Application ID ...: D276000124010200FFFE871930590000
|
||||
Version ..........: 2.0
|
||||
Manufacturer .....: FSIJ
|
||||
Serial number ....: 00000001
|
||||
Manufacturer .....: unmanaged S/N range
|
||||
Serial number ....: 87193059
|
||||
Name of cardholder: Yutaka Niibe
|
||||
Language prefs ...: ja
|
||||
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
|
||||
Signature PIN ....: not forced
|
||||
Key attributes ...: 2048R 2048R 2048R
|
||||
Key attributes ...: ed25519 cv25519 ed25519
|
||||
Max. PIN lengths .: 127 127 127
|
||||
PIN retry counter : 3 3 3
|
||||
Signature counter : 6
|
||||
Signature key ....: 1241 24BD 3B48 62AF 7A0A 42F1 00B4 5EBD 4CA7 BABE
|
||||
created ....: 2010-10-15 06:46:33
|
||||
Encryption key....: 42E1 E805 4E6F 1F30 26F2 DC79 79A7 9093 0842 39CF
|
||||
created ....: 2010-10-15 06:46:33
|
||||
Authentication key: B4D9 7142 C42D 6802 F5F7 4E70 9C33 B6BA 5BB0 65DC
|
||||
created ....: 2010-10-22 06:06:36
|
||||
Signature counter : 0
|
||||
Signature key ....: 249C B377 1750 745D 5CDD 323C E267 B052 364F 028D
|
||||
created ....: 2015-08-12 07:10:48
|
||||
Encryption key....: E228 AB42 0F73 3B1D 712D E50C 850A F040 D619 F240
|
||||
created ....: 2015-08-12 07:10:48
|
||||
Authentication key: E63F 31E6 F203 20B5 D796 D266 5F91 0521 FAA8 05B1
|
||||
created ....: 2015-08-12 07:16:14
|
||||
General key info..: [none]
|
||||
|
||||
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: requesting key 4CA7BABE from http server www.gniibe.org
|
||||
gpg: key 4CA7BABE: public key "NIIBE Yutaka <gniibe@fsij.org>" imported
|
||||
gpg: no ultimately trusted keys found
|
||||
gpg: requesting key E267B052364F028D from http server www.gniibe.org
|
||||
gpg: key E267B052364F028D: public key "NIIBE Yutaka <gniibe@fsij.org>" imported
|
||||
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>
|
||||
|
||||
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
|
||||
correspoinding public key in ``.gnupg``, or just type return
|
||||
at the ``gpg/card>`` prompt. ::
|
||||
|
||||
gpg/card>
|
||||
|
||||
Application ID ...: D276000124010200F517000000010000
|
||||
Reader ...........: 234B:0000:FSIJ-1.2.0-87193059:0
|
||||
Application ID ...: D276000124010200FFFE871930590000
|
||||
Version ..........: 2.0
|
||||
Manufacturer .....: FSIJ
|
||||
Serial number ....: 00000001
|
||||
Manufacturer .....: unmanaged S/N range
|
||||
Serial number ....: 87193059
|
||||
Name of cardholder: Yutaka Niibe
|
||||
Language prefs ...: ja
|
||||
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
|
||||
Signature PIN ....: not forced
|
||||
Key attributes ...: 2048R 2048R 2048R
|
||||
Key attributes ...: ed25519 cv25519 ed25519
|
||||
Max. PIN lengths .: 127 127 127
|
||||
PIN retry counter : 3 3 3
|
||||
Signature counter : 6
|
||||
Signature key ....: 1241 24BD 3B48 62AF 7A0A 42F1 00B4 5EBD 4CA7 BABE
|
||||
created ....: 2010-10-15 06:46:33
|
||||
Encryption key....: 42E1 E805 4E6F 1F30 26F2 DC79 79A7 9093 0842 39CF
|
||||
created ....: 2010-10-15 06:46:33
|
||||
Authentication key: B4D9 7142 C42D 6802 F5F7 4E70 9C33 B6BA 5BB0 65DC
|
||||
created ....: 2010-10-22 06:06:36
|
||||
General key info..:
|
||||
pub 2048R/4CA7BABE 2010-10-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec> 2048R/4CA7BABE created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb> 2048R/084239CF created: 2010-10-15 expires: never
|
||||
card-no: F517 00000001
|
||||
ssb> 2048R/5BB065DC created: 2010-10-22 expires: never
|
||||
card-no: F517 00000001
|
||||
|
||||
Signature counter : 0
|
||||
Signature key ....: 249C B377 1750 745D 5CDD 323C E267 B052 364F 028D
|
||||
created ....: 2015-08-12 07:10:48
|
||||
Encryption key....: E228 AB42 0F73 3B1D 712D E50C 850A F040 D619 F240
|
||||
created ....: 2015-08-12 07:10:48
|
||||
Authentication key: E63F 31E6 F203 20B5 D796 D266 5F91 0521 FAA8 05B1
|
||||
created ....: 2015-08-12 07:16:14
|
||||
General key info..: pub ed25519/E267B052364F028D 2015-08-12 NIIBE Yutaka <gniibe@fsij.org>
|
||||
sec> ed25519/E267B052364F028D created: 2015-08-12 expires: never
|
||||
card-no: FFFE 87193059
|
||||
ssb> cv25519/850AF040D619F240 created: 2015-08-12 expires: never
|
||||
card-no: FFFE 87193059
|
||||
ssb> ed25519/5F910521FAA805B1 created: 2015-08-12 expires: never
|
||||
card-no: FFFE 87193059
|
||||
|
||||
|
||||
gpg/card>
|
||||
|
||||
Note that, it displays the information about "General key info".
|
||||
|
||||
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
|
||||
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 (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
$ ./gpg --edit-key E267B052364F028D
|
||||
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.
|
||||
|
||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
||||
trust: unknown validity: unknown
|
||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
||||
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: 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] (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
|
||||
pub 2048R/4CA7BABE created: 2010-10-15 expires: never usage: SC
|
||||
trust: unknown validity: unknown
|
||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
||||
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: 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] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||
|
||||
@@ -146,32 +156,49 @@ See, the key is ``unknown`` state. Add trust for that. ::
|
||||
Your decision? 5
|
||||
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
|
||||
trust: ultimate validity: unknown
|
||||
sub 2048R/084239CF created: 2010-10-15 expires: never usage: E
|
||||
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: 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] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||
Please note that the shown key validity is not necessarily correct
|
||||
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 (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
$ ./gpg --edit-key E267B052364F028D
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
gpg: checking the trustdb
|
||||
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
|
||||
gpg: depth: 0 valid: 7 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 7u
|
||||
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] (2) NIIBE Yutaka <gniibe@debian.org>
|
||||
|
||||
|
||||
gpg> quit
|
||||
$
|
||||
$
|
||||
|
||||
OK, all set. I'm ready to use my Gnuk Token on this PC.
|
||||
|
||||
7
docker/Dockerfile.check
Normal file
7
docker/Dockerfile.check
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM gnuk:latest
|
||||
|
||||
LABEL Description="Image for checking gnuK"
|
||||
|
||||
RUN apt install -y shellcheck
|
||||
RUN apt install -y clang libfindbin-libs-perl
|
||||
RUN apt clean
|
||||
4
docker/Dockerfile.debug
Normal file
4
docker/Dockerfile.debug
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM gnuk:latest
|
||||
LABEL Description="Image for building gnuK with debugging"
|
||||
|
||||
RUN apt install -y gdb-arm-none-eabi && apt clean
|
||||
6
docker/Dockerfile.release
Normal file
6
docker/Dockerfile.release
Normal file
@@ -0,0 +1,6 @@
|
||||
FROM debian:latest
|
||||
LABEL Description="Image for building gnuK"
|
||||
|
||||
RUN apt update -y && apt install -y make gcc-arm-none-eabi && apt clean
|
||||
|
||||
CMD ["/bin/sh", "-c", "cd /gnuk/src && make clean && ./configure $GNUK_CONFIG && make"]
|
||||
36
docker/Makefile
Normal file
36
docker/Makefile
Normal file
@@ -0,0 +1,36 @@
|
||||
ifndef GNUK_CONFIG
|
||||
$(warning configuration flags not set in GNUK_CONFIG)
|
||||
endif
|
||||
|
||||
all: ../chopstx docker-build-release
|
||||
docker run --user=`id -u` --env GNUK_CONFIG --rm -v `pwd`/..:/gnuk/ -t gnuk:latest
|
||||
|
||||
clean: docker-build-release
|
||||
docker run --user=`id -u` --env GNUK_CONFIG --rm -v `pwd`/..:/gnuk/ -w /gnuk/src -t gnuk:latest make clean
|
||||
|
||||
gdb: docker-build-debug
|
||||
docker run --net host --rm -i -v `pwd`/..:/gnuk/ -t gnuk:latest-debug arm-none-eabi-gdb /gnuk/src/build/gnuk.elf
|
||||
|
||||
shellcheck: docker-build-check
|
||||
docker run --rm -v `pwd`/..:/gnuk/ -t gnuk:latest-check shellcheck /gnuk/src/configure
|
||||
|
||||
CHECKERS=security optin nullability core deadcode alpha.core alpha.security
|
||||
scan-build: clean docker-build-check
|
||||
docker run --user=`id -u` --rm -v `pwd`/..:/gnuk/ -w /gnuk/src -t gnuk:latest-check scan-build -o scan-build \
|
||||
-analyze-headers -stats $(addprefix -enable-checker ,$(CHECKERS)) -k \
|
||||
--use-cc=arm-none-eabi-gcc \
|
||||
make
|
||||
../chopstx:
|
||||
git submodule update --init
|
||||
|
||||
docker-build-release:
|
||||
docker build -t gnuk:latest -f `pwd`/Dockerfile.release ..
|
||||
|
||||
docker-build-debug: docker-build-release
|
||||
docker build -t gnuk:latest-debug -f `pwd`/Dockerfile.debug ..
|
||||
|
||||
docker-build-check: docker-build-release
|
||||
docker build -t gnuk:latest-check -f `pwd`/Dockerfile.check ..
|
||||
|
||||
.PHONY: all clean gdb shellcheck scan-build \
|
||||
docker-build-release docker-build-debug docker-build-check
|
||||
220
misc/debug-bn.c
Normal file
220
misc/debug-bn.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* debug-bn.c - Debug Bignum
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "bn.h"
|
||||
|
||||
void
|
||||
print_le_bn256 (const bn256 *X)
|
||||
{
|
||||
int i;
|
||||
const uint8_t *p = (const uint8_t *)X;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
printf ("%02x", p[i]);
|
||||
puts ("");
|
||||
}
|
||||
|
||||
void
|
||||
print_be_bn256 (const bn256 *X)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 7; i >= 0; i--)
|
||||
printf ("%08x", X->word[i]);
|
||||
puts ("");
|
||||
}
|
||||
|
||||
#define MAXLINE 4096
|
||||
|
||||
static int lineno;
|
||||
static int test_no;
|
||||
static bn256 sk[1];
|
||||
static bn256 pk[1];
|
||||
static unsigned char msg[MAXLINE];
|
||||
static size_t msglen;
|
||||
static bn512 sig[1];
|
||||
|
||||
const char *
|
||||
skip_white_space (const char *l)
|
||||
{
|
||||
while (*l != '\n' && isspace (*l))
|
||||
l++;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_hex_4bit (char c)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
r = c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
r = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
r = c - 'A' + 10;
|
||||
else
|
||||
r = -1;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
read_hex_8bit (const char **l_p)
|
||||
{
|
||||
const char *l = *l_p;
|
||||
int r, v;
|
||||
|
||||
r = read_hex_4bit (*l++);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
v = r*16;
|
||||
r = read_hex_4bit (*l++);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
v += r;
|
||||
|
||||
*l_p = l;
|
||||
return v;
|
||||
}
|
||||
|
||||
static int
|
||||
read_msg (unsigned char *msg, const char *l, int len)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
r = read_hex_8bit (&l);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
msg[i] = r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_le_bn256 (bn256 *sk, const char *l)
|
||||
{
|
||||
int i;
|
||||
uint8_t *p = (uint8_t *)sk;
|
||||
|
||||
for (i = 0; i < sizeof (bn256); i++)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (*l == '\n')
|
||||
{
|
||||
/* should support small input??? */
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = read_hex_8bit (&l);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
|
||||
p[i] = r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
read_be_bn256 (bn256 *sk, const char *l)
|
||||
{
|
||||
int i;
|
||||
uint8_t *p = (uint8_t *)sk;
|
||||
|
||||
for (i = 0; i < sizeof (bn256); i++)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (*l == '\n')
|
||||
{
|
||||
/* should support small input??? */
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = read_hex_8bit (&l);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
|
||||
p[31 - i] = r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_pk (bn256 *pk, const char *l, int len)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (len == 64) /* 64 chars == 32-byte */
|
||||
{ /* compressed form */
|
||||
r = read_le_bn256 (pk, l);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bn256 x[1];
|
||||
|
||||
r = read_hex_8bit (&l);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
if (r != 4)
|
||||
return -1;
|
||||
|
||||
r = read_be_bn256 (x, l);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
r = read_be_bn256 (pk, l+64);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
|
||||
pk->word[7] ^= (x->word[0] & 1) * 0x80000000;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
read_le_bn512 (bn512 *sig, const char *l)
|
||||
{
|
||||
int i;
|
||||
uint8_t *p = (uint8_t *)sig;
|
||||
|
||||
for (i = 0; i < sizeof (bn512); i++)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (*l == '\n')
|
||||
{
|
||||
/* should support small input??? */
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = read_hex_8bit (&l);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
|
||||
p[i] = r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
92
misc/t-mont.c
Normal file
92
misc/t-mont.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* t-eddsa.c - testing EdDSA
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* Run following commands. The file t-ed25519.inp is available in GNU
|
||||
* libgcrypt source code under 'tests' directory.
|
||||
|
||||
gcc -Wall -c -DBN256_C_IMPLEMENTATION ecc-mont.c
|
||||
gcc -Wall -c -DBN256_NO_RANDOM -DBN256_C_IMPLEMENTATION bn.c
|
||||
gcc -Wall -c mod.c
|
||||
gcc -Wall -c -DBN256_C_IMPLEMENTATION mod25638.c
|
||||
gcc -Wall -c t-mont.c
|
||||
gcc -Wall -c debug-bn.c
|
||||
gcc -o t-mont t-mont.o ecc-mont.o bn.o mod.o mod25638.o debug-bn.o
|
||||
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "bn.h"
|
||||
|
||||
const uint8_t k[32] = {
|
||||
0x30, 0x01, 0x33, 0xE7, 0xDC, 0x52, 0xAD, 0x9F,
|
||||
0x89, 0xFE, 0xC0, 0x59, 0x4A, 0x6D, 0x65, 0xE5,
|
||||
0xF8, 0x7A, 0xD6, 0xA9, 0xA4, 0x89, 0x00, 0xB1,
|
||||
0x93, 0x7E, 0xD3, 0x6F, 0x09, 0x1E, 0xB7, 0x76,
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int all_good = 1;
|
||||
int r;
|
||||
bn256 *pk;
|
||||
bn256 a[1];
|
||||
uint8_t out[32];
|
||||
|
||||
extern void ecdh_decrypt_curve25519 (const uint8_t *input,
|
||||
uint8_t *output,
|
||||
const bn256 *k);
|
||||
extern uint8_t *ecdh_compute_public_25519 (const uint8_t*k);
|
||||
extern void print_le_bn256 (const bn256 *X);
|
||||
|
||||
while (1)
|
||||
{
|
||||
#if 0
|
||||
hash[0] &= 248;
|
||||
hash[31] &= 127;
|
||||
hash[31] |= 64;
|
||||
memcpy (a, hash, sizeof (bn256)); /* Lower half of hash */
|
||||
#endif
|
||||
|
||||
pk = ecdh_compute_public_25519 (k);
|
||||
print_le_bn256 (pk);
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
if (memcmp (pk, pk_calculated, sizeof (bn256)) != 0)
|
||||
{
|
||||
printf ("ERR PK: %d\n", test_no);
|
||||
print_be_bn256 (sk);
|
||||
print_be_bn256 (pk);
|
||||
print_be_bn256 (pk_calculated);
|
||||
all_good = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
ecdh_decrypt_25519 (msg, out, a);
|
||||
if (memcmp (sig, R, sizeof (bn256)) != 0
|
||||
|| memcmp (((const uint8_t *)sig)+32, S, sizeof (bn256)) != 0)
|
||||
{
|
||||
printf ("ERR SIG: %d\n", test_no);
|
||||
print_le_bn256 (R);
|
||||
print_le_bn256 (S);
|
||||
print_le_bn256 ((const bn256 *)sig);
|
||||
print_le_bn256 ((const bn256 *)(((const uint8_t *)sig)+32));
|
||||
all_good = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf ("%d\n", test_no);
|
||||
#endif
|
||||
}
|
||||
return all_good == 1?0:1;
|
||||
}
|
||||
@@ -209,9 +209,7 @@
|
||||
*
|
||||
* Enable the RSA prime-number generation code.
|
||||
*/
|
||||
#ifdef KEYGEN_SUPPORT
|
||||
#define POLARSSL_GENPRIME
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def POLARSSL_FS_IO
|
||||
|
||||
@@ -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)
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#define V(a,b,c,d) 0x##d##a##b##c
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "polarssl/bignum.h"
|
||||
#include "polarssl/bn_mul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gnuk-malloc.h>
|
||||
|
||||
#define ciL (sizeof(t_uint)) /* chars in limb */
|
||||
#define biL (ciL << 3) /* bits in limb */
|
||||
@@ -223,6 +223,26 @@ size_t mpi_lsb( const mpi *X )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if !defined(POLARSSL_HAVE_UDBL)
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the number of most significant bits
|
||||
*/
|
||||
@@ -1102,6 +1122,100 @@ int mpi_mul_int( mpi *X, const mpi *A, t_sint 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 = (~0UL);
|
||||
|
||||
return (~0UL);
|
||||
}
|
||||
|
||||
#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)
|
||||
*/
|
||||
@@ -1156,60 +1270,10 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
|
||||
for( i = n; i > t ; i-- )
|
||||
{
|
||||
if( X.p[i] >= Y.p[t] )
|
||||
Z.p[i - t - 1] = ~0;
|
||||
Z.p[i - t - 1] = ~0UL;
|
||||
else
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_UDBL)
|
||||
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] = int_div_int( X.p[i], X.p[i-1], Y.p[t], NULL);
|
||||
}
|
||||
|
||||
Z.p[i - t - 1]++;
|
||||
@@ -1233,7 +1297,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
|
||||
MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
|
||||
MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
|
||||
|
||||
if( mpi_cmp_int( &X, 0 ) < 0 )
|
||||
while( mpi_cmp_int( &X, 0 ) < 0 )
|
||||
{
|
||||
MPI_CHK( mpi_copy( &T1, &Y ) );
|
||||
MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
|
||||
@@ -1450,9 +1514,22 @@ static void mpi_montred( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
/*
|
||||
* Montgomery square: A = A * A * R^-1 mod N
|
||||
* A is placed at the upper half of D.
|
||||
*
|
||||
* n : number of limbs of N
|
||||
* np: pointer to limbs of bignum N
|
||||
* mm: m' = -N^(-1) mod b where b = 2^number-of-bit-in-limb
|
||||
* d (destination): the result [<-- temp -->][<--- A ---->]
|
||||
* lower part upper part
|
||||
* n-limb n-limb
|
||||
*/
|
||||
static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
{
|
||||
#ifdef BIGNUM_C_IMPLEMENTATION
|
||||
t_uint a_input[n];
|
||||
|
||||
memcpy (a_input, &d[n], sizeof (a_input));
|
||||
mpi_montmul (n, np, mm, d, a_input);
|
||||
#else
|
||||
size_t i;
|
||||
register t_uint c = 0;
|
||||
|
||||
@@ -1464,6 +1541,7 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
|
||||
x_i = *xj;
|
||||
*xj++ = c;
|
||||
|
||||
asm (/* (C,R4,R5) := w_i_i + x_i*x_i; w_i_i := R5; */
|
||||
"mov %[c], #0\n\t"
|
||||
"ldr r5, [%[wij]]\n\t" /* R5 := w_i_i; */
|
||||
@@ -1536,6 +1614,7 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
mpi_sub_hlp( n, np, d );
|
||||
else
|
||||
mpi_sub_hlp( n, d - n, d - n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1570,7 +1649,6 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
||||
* Init temps and window size
|
||||
*/
|
||||
mpi_montg_init( &mm, N );
|
||||
MPI_CHK( mpi_grow( X, N->n ) );
|
||||
|
||||
/*
|
||||
* If 1st call, pre-compute R^2 mod N
|
||||
@@ -1584,6 +1662,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. */
|
||||
mpi_sub_hlp( N->n, N->p, d + N->n);
|
||||
MPI_CHK( mpi_mod_mpi( &RR, &T, N ) );
|
||||
MPI_CHK( mpi_grow( &RR, N->n ) );
|
||||
|
||||
if( _RR != NULL )
|
||||
memcpy( _RR, &RR, sizeof( mpi ) );
|
||||
@@ -1595,6 +1674,8 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
||||
memset (d, 0, N->n * ciL); /* Set lower half of D zero. */
|
||||
}
|
||||
|
||||
MPI_CHK( mpi_grow( X, N->n ) );
|
||||
|
||||
/*
|
||||
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
|
||||
*/
|
||||
@@ -1988,17 +2069,19 @@ jkiss (struct jkiss_state *s)
|
||||
static int mpi_fill_pseudo_random ( mpi *X, size_t size)
|
||||
{
|
||||
int ret;
|
||||
uint32_t *p;
|
||||
uint32_t *p, *p_end;
|
||||
|
||||
MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
|
||||
MPI_CHK( mpi_lset( X, 0 ) );
|
||||
|
||||
/* Assume little endian. */
|
||||
p = X->p;
|
||||
while (p < X->p + (size/ciL))
|
||||
p = (uint32_t *)X->p;
|
||||
p_end = (uint32_t *)(X->p + (size/sizeof (uint32_t)));
|
||||
while (p < p_end)
|
||||
*p++ = jkiss (&jkiss_state_v);
|
||||
if ((size % ciL))
|
||||
*p = jkiss (&jkiss_state_v) & ((1 << (8*(size % ciL))) - 1);
|
||||
|
||||
if ((size%sizeof (uint32_t)))
|
||||
*p = jkiss (&jkiss_state_v) & ((1 << (8*(size % sizeof (uint32_t)))) - 1);
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
@@ -2139,10 +2222,24 @@ cleanup:
|
||||
* Value M: multiply all primes up to 701 (except 97) and 797
|
||||
* (so that MAX_A will be convenient value)
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
#define M_LIMBS 16
|
||||
#else
|
||||
#define M_LIMBS 31
|
||||
#endif
|
||||
#define M_SIZE 122
|
||||
|
||||
static const t_uint limbs_M[] = { /* Little endian */
|
||||
#ifdef __LP64__
|
||||
0x9344A6AB84EEB59EUL, 0xEC855CDAFF21529FUL,
|
||||
0x477E991E009BAB38UL, 0x2EEA23579F5B86F3UL,
|
||||
0xAC17D30441D6502FUL, 0x38FF52B90A468A6DUL,
|
||||
0x63630419FD42E5EFUL, 0x48CE17D091DB2572UL,
|
||||
0x708AB00AE3B57D0EUL, 0xF8A9DE08CD723598UL,
|
||||
0x731411374432C93BUL, 0x554DF2612779FAB3UL,
|
||||
0xDEEBDA58953D2BA5UL, 0xD1D66F2F5F57D007UL,
|
||||
0xB85C9607E84E9F2BUL, 0x000000000000401DUL
|
||||
#else
|
||||
0x84EEB59E, 0x9344A6AB, 0xFF21529F, 0xEC855CDA,
|
||||
0x009BAB38, 0x477E991E, 0x9F5B86F3, 0x2EEA2357,
|
||||
0x41D6502F, 0xAC17D304, 0x0A468A6D, 0x38FF52B9,
|
||||
@@ -2151,6 +2248,7 @@ static const t_uint limbs_M[] = { /* Little endian */
|
||||
0x4432C93B, 0x73141137, 0x2779FAB3, 0x554DF261,
|
||||
0x953D2BA5, 0xDEEBDA58, 0x5F57D007, 0xD1D66F2F,
|
||||
0xE84E9F2B, 0xB85C9607, 0x0000401D
|
||||
#endif
|
||||
};
|
||||
|
||||
static const mpi M[1] = {{ 1, M_LIMBS, (t_uint *)limbs_M }};
|
||||
@@ -2158,10 +2256,18 @@ static const mpi M[1] = {{ 1, M_LIMBS, (t_uint *)limbs_M }};
|
||||
/*
|
||||
* MAX_A : 2^1024 / M - 1
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
#define MAX_A_LIMBS 1
|
||||
#else
|
||||
#define MAX_A_LIMBS 2
|
||||
#endif
|
||||
#define MAX_A_FILL_SIZE 6
|
||||
static const t_uint limbs_MAX_A[] = { /* Little endian */
|
||||
#ifdef __LP64__
|
||||
0x0003FE2556A2B35FUL
|
||||
#else
|
||||
0x56A2B35F, 0x0003FE25
|
||||
#endif
|
||||
};
|
||||
|
||||
static const mpi MAX_A[1] = {{ 1, MAX_A_LIMBS, (t_uint *)limbs_MAX_A }};
|
||||
@@ -2211,9 +2317,8 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
|
||||
|
||||
MPI_CHK ( mpi_mul_mpi ( X, X, M ) );
|
||||
MPI_CHK ( mpi_add_abs ( X, X, B ) );
|
||||
if (X->n <= 31 || (X->p[31] & 0xc0000000) == 0)
|
||||
if (X->n <= M_LIMBS || (X->p[M_LIMBS-1] & 0xc0000000) == 0)
|
||||
continue;
|
||||
|
||||
ret = mpi_is_prime ( X );
|
||||
if (ret == 0 || ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE)
|
||||
break;
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "polarssl/md.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
PROJECT = regnual
|
||||
|
||||
OBJS = regnual.o usb_stm32f103.o sys.o
|
||||
OBJS = regnual.o usb-stm32f103.o reset.o
|
||||
|
||||
include ../src/config.mk
|
||||
|
||||
LDSCRIPT= regnual.ld
|
||||
|
||||
###################################
|
||||
@@ -19,11 +22,11 @@ TOPT = -mthumb -DTHUMB -mno-thumb-interwork
|
||||
# Define C warning options here
|
||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||
MCFLAGS= -mcpu=$(MCU)
|
||||
DEFS = -DFREE_STANDING
|
||||
DEFS += -DFREE_STANDING
|
||||
|
||||
CFLAGS = -O2 -g
|
||||
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)
|
||||
|
||||
@@ -32,19 +35,19 @@ LDFLAGS = -T$(LDSCRIPT) -nostartfiles $(MCFLAGS) $(TOPT)
|
||||
|
||||
all: regnual.hex
|
||||
|
||||
regnual.o: regnual.c ../src/sys.h
|
||||
regnual.o: regnual.c ../chopstx/sys.h ../chopstx/usb_lld.h
|
||||
|
||||
regnual.hex: regnual.elf
|
||||
$(OBJCOPY) -Obinary regnual.elf regnual.bin
|
||||
$(OBJCOPY) -Oihex regnual.elf regnual.hex
|
||||
|
||||
usb_stm32f103.o: ../src/usb_stm32f103.c
|
||||
$(CC) $(CFLAGS) -c -o usb_stm32f103.o ../src/usb_stm32f103.c
|
||||
usb-stm32f103.o: ../chopstx/mcu/usb-stm32f103.c
|
||||
$(CC) $(CFLAGS) -c -o usb-stm32f103.o ../chopstx/mcu/usb-stm32f103.c
|
||||
|
||||
regnual.elf: $(OBJS) $(LDSCRIPT)
|
||||
$(CC) $(LDFLAGS) -o regnual.elf $(OBJS)
|
||||
|
||||
clean:
|
||||
-rm -f $(OBJS) regnual.elf regnual.hex regnual.bin
|
||||
-rm -f $(OBJS) regnual.elf regnual.hex regnual.bin *.lst
|
||||
|
||||
distclean: clean
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* regnual.c -- Firmware installation for STM32F103 Flash ROM
|
||||
*
|
||||
* Copyright (C) 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2012, 2013, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -32,19 +33,25 @@
|
||||
extern void *memset (void *s, int c, size_t n);
|
||||
|
||||
extern void set_led (int);
|
||||
extern uint8_t _flash_start, _flash_end;
|
||||
extern int flash_write (uint32_t dst_addr, const uint8_t *src, size_t len);
|
||||
extern int flash_protect (void);
|
||||
extern void nvic_system_reset (void);
|
||||
|
||||
|
||||
#define FLASH_START_ADDR 0x08000000 /* Fixed for all STM32F1. */
|
||||
#define FLASH_OFFSET 0x1000 /* First pages are not-writable. */
|
||||
#define FLASH_START (FLASH_START_ADDR+FLASH_OFFSET)
|
||||
#define FLASH_SIZE_REG ((uint16_t *)0x1ffff7e0)
|
||||
static uint32_t flash_end;
|
||||
|
||||
|
||||
#define ENDP0_RXADDR (0x40)
|
||||
#define ENDP0_TXADDR (0x80)
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t regnual_device_desc[] = {
|
||||
18, /* bLength */
|
||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||
0xFF, /* bDeviceClass: VENDOR */
|
||||
0x00, /* bDeviceSubClass */
|
||||
@@ -57,24 +64,26 @@ static const uint8_t regnual_device_desc[] = {
|
||||
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[] = {
|
||||
9,
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
||||
18, 0, /* wTotalLength: no of returned bytes */
|
||||
1, /* bNumInterfaces: single vender interface */
|
||||
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
|
||||
18, 0, /* wTotalLength: no of returned bytes */
|
||||
1, /* bNumInterfaces: single vendor interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: None */
|
||||
#if defined(USB_SELF_POWERED)
|
||||
0xC0, /* bmAttributes: self powered */
|
||||
#else
|
||||
0x80, /* bmAttributes: bus powered */
|
||||
#endif
|
||||
50, /* MaxPower 100 mA */
|
||||
REGNUAL_FEATURE_INIT, /* bmAttributes: bus powered */
|
||||
50, /* MaxPower 100 mA */
|
||||
|
||||
/* Interface Descriptor */
|
||||
9,
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
0, /* bInterfaceNumber: Index of this interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
0, /* bInterfaceNumber: Index of this interface */
|
||||
0, /* Alternate setting for this interface */
|
||||
0, /* bNumEndpoints: None */
|
||||
0xFF,
|
||||
@@ -85,7 +94,7 @@ static const uint8_t regnual_config_desc[] = {
|
||||
|
||||
static const uint8_t regnual_string_lang_id[] = {
|
||||
4, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
STRING_DESCRIPTOR,
|
||||
0x09, 0x04 /* LangID = 0x0409: US-English */
|
||||
};
|
||||
|
||||
@@ -93,23 +102,17 @@ static const uint8_t regnual_string_lang_id[] = {
|
||||
|
||||
static const uint8_t regnual_string_serial[] = {
|
||||
8*2+2,
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
STRING_DESCRIPTOR,
|
||||
/* FSIJ-0.0 */
|
||||
'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0,
|
||||
'0', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
usb_cb_device_reset (void)
|
||||
static void
|
||||
usb_device_reset (struct usb_dev *dev)
|
||||
{
|
||||
/* Set DEVICE as not configured */
|
||||
usb_lld_set_configuration (0);
|
||||
|
||||
/* Current Feature initialization */
|
||||
usb_lld_set_feature (regnual_config_desc[7]);
|
||||
|
||||
usb_lld_reset ();
|
||||
usb_lld_reset (dev, REGNUAL_FEATURE_INIT);
|
||||
|
||||
/* Initialize Endpoint 0 */
|
||||
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
||||
@@ -166,108 +169,101 @@ static uint32_t calc_crc32 (void)
|
||||
}
|
||||
|
||||
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len)
|
||||
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 ();
|
||||
else if (req_no == USB_REGNUAL_FLASH && len == 0 && index == 0)
|
||||
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);
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_PROTECT && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
else if (arg->request == USB_REGNUAL_PROTECT && arg->value == 0)
|
||||
result = flash_protect ();
|
||||
else if (req_no == USB_REGNUAL_FINISH && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
else if (arg->request == USB_REGNUAL_FINISH && arg->value == 0)
|
||||
nvic_system_reset ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
static int
|
||||
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 (USB_SETUP_GET (req))
|
||||
if (USB_SETUP_GET (arg->type))
|
||||
{
|
||||
if (req_no == USB_REGNUAL_MEMINFO)
|
||||
if (arg->request == USB_REGNUAL_MEMINFO)
|
||||
{
|
||||
static const uint8_t *mem_info[2];
|
||||
const uint8_t *mem_info[2];
|
||||
|
||||
mem_info[0] = &_flash_start;
|
||||
mem_info[1] = &_flash_end;
|
||||
usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_RESULT)
|
||||
{
|
||||
usb_lld_set_data_to_send (&result, sizeof (uint32_t));
|
||||
return USB_SUCCESS;
|
||||
mem_info[0] = (const uint8_t *)FLASH_START;
|
||||
mem_info[1] = (const uint8_t *)flash_end;
|
||||
return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
|
||||
}
|
||||
else if (arg->request == USB_REGNUAL_RESULT)
|
||||
return usb_lld_ctrl_send (dev, &result, sizeof (uint32_t));
|
||||
}
|
||||
else /* SETUP_SET */
|
||||
{
|
||||
if (req_no == USB_REGNUAL_SEND)
|
||||
if (arg->request == USB_REGNUAL_SEND)
|
||||
{
|
||||
if (value != 0 || index + len > 256)
|
||||
return USB_UNSUPPORT;
|
||||
if (arg->value != 0 || arg->index + arg->len > 256)
|
||||
return -1;
|
||||
|
||||
if (index + len < 256)
|
||||
memset ((uint8_t *)mem + index + len, 0xff,
|
||||
256 - (index + len));
|
||||
if (arg->index + arg->len < 256)
|
||||
memset ((uint8_t *)mem + arg->index + arg->len, 0xff,
|
||||
256 - (arg->index + arg->len));
|
||||
|
||||
usb_lld_set_data_to_recv (mem + index, len);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_ctrl_recv (dev, mem + arg->index, arg->len);
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_FLASH && len == 0 && index == 0)
|
||||
else if (arg->request == USB_REGNUAL_FLASH && arg->len == 0
|
||||
&& arg->index == 0)
|
||||
{
|
||||
uint32_t dst_addr = (0x08000000 + value * 0x100);
|
||||
uint32_t dst_addr = (0x08000000 + arg->value * 0x100);
|
||||
|
||||
if (dst_addr + 256 <= (uint32_t)&_flash_end)
|
||||
return USB_SUCCESS;
|
||||
if (dst_addr + 256 <= flash_end)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_PROTECT && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
return USB_SUCCESS;
|
||||
else if (req_no == USB_REGNUAL_FINISH && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
return USB_SUCCESS;
|
||||
else if (arg->request == USB_REGNUAL_PROTECT && arg->len == 0
|
||||
&& arg->value == 0 && arg->index == 0)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
else if (arg->request == USB_REGNUAL_FINISH && arg->len == 0
|
||||
&& arg->value == 0 && arg->index == 0)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
uint16_t index)
|
||||
static int
|
||||
usb_get_descriptor (struct usb_dev *dev)
|
||||
{
|
||||
(void)index;
|
||||
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)
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
|
||||
if (desc_type == DEVICE_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (regnual_device_desc,
|
||||
sizeof (regnual_device_desc));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_ctrl_send (dev, regnual_device_desc,
|
||||
sizeof (regnual_device_desc));
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (regnual_config_desc,
|
||||
sizeof (regnual_config_desc));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_ctrl_send (dev, regnual_config_desc,
|
||||
sizeof (regnual_config_desc));
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
const uint8_t *str;
|
||||
@@ -280,48 +276,50 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
size = sizeof (regnual_string_lang_id);
|
||||
break;
|
||||
case 1:
|
||||
str = gnukStringVendor;
|
||||
size = sizeof (gnukStringVendor);
|
||||
str = gnuk_string_vendor;
|
||||
size = sizeof (gnuk_string_vendor);
|
||||
break;
|
||||
case 2:
|
||||
str = gnukStringProduct;
|
||||
size = sizeof (gnukStringProduct);
|
||||
str = gnuk_string_product;
|
||||
size = sizeof (gnuk_string_product);
|
||||
break;
|
||||
case 3:
|
||||
str = regnual_string_serial;
|
||||
size = sizeof (regnual_string_serial);
|
||||
break;
|
||||
default:
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
usb_lld_set_data_to_send (str, size);
|
||||
return USB_SUCCESS;
|
||||
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:
|
||||
case USB_EVENT_CONFIG:
|
||||
return USB_SUCCESS;
|
||||
default:
|
||||
break;
|
||||
if (dev->dev_req.value != 1)
|
||||
return -1;
|
||||
|
||||
usb_lld_set_configuration (dev, 1);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
|
||||
{
|
||||
(void)cmd; (void)interface; (void)alt;
|
||||
return USB_UNSUPPORT;
|
||||
/* Do nothing when current_conf == value */
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -335,6 +333,31 @@ static void wait (int count)
|
||||
|
||||
#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
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -342,7 +365,19 @@ main (int argc, char *argv[])
|
||||
|
||||
set_led (0);
|
||||
|
||||
usb_lld_init (regnual_config_desc[7]);
|
||||
#if defined(STM32F103_OVERRIDE_FLASH_SIZE_KB)
|
||||
flash_end = FLASH_START_ADDR + STM32F103_OVERRIDE_FLASH_SIZE_KB*1024;
|
||||
#else
|
||||
flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
@@ -352,3 +387,69 @@ main (int argc, char *argv[])
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ MEMORY
|
||||
}
|
||||
|
||||
vector = 0x08000000;
|
||||
_flash_start = 0x08001000;
|
||||
_flash_end = 0x08020000;
|
||||
|
||||
__ram_start__ = ORIGIN(ram0);
|
||||
__ram_size__ = 20k;
|
||||
|
||||
@@ -3,6 +3,7 @@ typedef unsigned long size_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
@@ -5,18 +5,14 @@ PROJECT = gnuk
|
||||
|
||||
CHOPSTX = ../chopstx
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= gnuk.ld
|
||||
|
||||
CSRC = main.c usb_stm32f103.c adc_stm32f103.c \
|
||||
CSRC = main.c call-rsa.c \
|
||||
usb_desc.c usb_ctrl.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 \
|
||||
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
mod25638.c ecc-edwards.c sha512.c \
|
||||
random.c neug.c sha256.c sys.c
|
||||
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
|
||||
random.c neug.c sha256.c
|
||||
|
||||
INCDIR =
|
||||
|
||||
@@ -28,12 +24,19 @@ CRYPTSRC = $(CRYPTSRCDIR)/bignum.c $(CRYPTSRCDIR)/rsa.c $(CRYPTSRCDIR)/aes.c
|
||||
CSRC += $(CRYPTSRC)
|
||||
INCDIR += $(CRYPTINCDIR)
|
||||
|
||||
@PINPAD_MAKE_OPTION@
|
||||
@DEBUG_MAKE_OPTION@
|
||||
@HEXOUTPUT_MAKE_OPTION@
|
||||
include config.mk
|
||||
|
||||
USE_SYS = yes
|
||||
USE_USB = yes
|
||||
USE_ADC = yes
|
||||
USE_EVENTFLAG = yes
|
||||
|
||||
ifeq ($(EMULATION),)
|
||||
DEFS += -DFLASH_UPGRADE_SUPPORT
|
||||
else
|
||||
DEFS += -DBN256_C_IMPLEMENTATION -DBIGNUM_C_IMPLEMENTATION
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_DEBUG),)
|
||||
CSRC += debug.c
|
||||
endif
|
||||
@@ -46,18 +49,17 @@ ifeq ($(ENABLE_PINPAD),dnd)
|
||||
CSRC += usb-msc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CHIP),stm32f103)
|
||||
CSRC += mcu-stm32f103.c
|
||||
endif
|
||||
|
||||
###################################
|
||||
CROSS = arm-none-eabi-
|
||||
CC = $(CROSS)gcc
|
||||
LD = $(CROSS)gcc
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
|
||||
MCU = cortex-m3
|
||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||
# DEFS: Add
|
||||
DEFS = -DCHX_PRIO_MAIN=5 @KEYGEN_SUPPORT@ @HAVE_SYS_H@
|
||||
OPT = -O3 -Os -g
|
||||
LIBS =
|
||||
|
||||
#######################
|
||||
include $(CHOPSTX)/rules.mk
|
||||
@@ -71,5 +73,18 @@ sys.c: board.h
|
||||
build/bignum.o: OPT = -O3 -g
|
||||
|
||||
distclean: clean
|
||||
-rm -f gnuk.ld config.h board.h Makefile \
|
||||
-rm -f gnuk.ld config.h board.h config.mk \
|
||||
usb-strings.c.inc usb-vid-pid-ver.c.inc
|
||||
|
||||
ifneq ($(EMULATION),)
|
||||
# By specifying DESTDIR on invocation of "make", you can install
|
||||
# program to different ROOT.
|
||||
|
||||
# The variables prefix, exec_prefix, libexecdir are defined in
|
||||
# config.mk.
|
||||
|
||||
install: build/gnuk
|
||||
test -d "$(DESTDIR)$(libexecdir)" || mkdir -p "$(DESTDIR)$(libexecdir)"
|
||||
install -c build/gnuk "$(DESTDIR)$(libexecdir)"
|
||||
|
||||
endif
|
||||
2
src/ac.c
2
src/ac.c
@@ -169,7 +169,7 @@ verify_admin_00 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
pw_len = ks[0] & PW_LEN_MASK;
|
||||
salt = KS_GET_SALT (ks);
|
||||
salt_len = SALT_SIZE;
|
||||
|
||||
|
||||
if ((pw_len_known >= 0 && pw_len_known != pw_len) || buf_len < pw_len)
|
||||
return -1;
|
||||
|
||||
|
||||
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,266 +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 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
|
||||
|
||||
#if !defined(NEUG_ADC_SETTING2_SMPR1)
|
||||
#define NEUG_ADC_SETTING2_SMPR1 0
|
||||
#define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) \
|
||||
| ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
|
||||
#define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) \
|
||||
| ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
|
||||
#define NEUG_ADC_SETTING2_NUM_CHANNELS 2
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Do calibration for both of ADCs.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void adc_start (void)
|
||||
{
|
||||
/* 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 = NEUG_ADC_SETTING2_SMPR1;
|
||||
ADC2->SMPR2 = NEUG_ADC_SETTING2_SMPR2;
|
||||
ADC2->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING2_NUM_CHANNELS);
|
||||
ADC2->SQR2 = 0;
|
||||
ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* call-ec.c - interface between Gnuk and Elliptic curve over GF(prime)
|
||||
*
|
||||
* Copyright (C) 2013, 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2013, 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -54,28 +54,21 @@ FUNC(ecdsa_sign) (const uint8_t *hash, uint8_t *output,
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
FUNC(ecc_compute_public) (const uint8_t *key_data)
|
||||
int
|
||||
FUNC(ecc_compute_public) (const uint8_t *key_data, uint8_t *pubkey)
|
||||
{
|
||||
uint8_t *p0, *p, *p1;
|
||||
uint8_t *p, *p1;
|
||||
ac q[1];
|
||||
bn256 k[1];
|
||||
int i;
|
||||
|
||||
p0 = (uint8_t *)malloc (ECDSA_BYTE_SIZE * 2);
|
||||
if (p0 == NULL)
|
||||
return NULL;
|
||||
|
||||
p = (uint8_t *)k;
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
p[ECDSA_BYTE_SIZE - i - 1] = key_data[i];
|
||||
if (FUNC(compute_kG) (q, k) < 0)
|
||||
{
|
||||
free (p0);
|
||||
return NULL;
|
||||
}
|
||||
return -1;
|
||||
|
||||
p = p0;
|
||||
p = pubkey;
|
||||
p1 = (uint8_t *)q->x;
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
*p++ = p1[ECDSA_BYTE_SIZE - i - 1];
|
||||
@@ -83,7 +76,7 @@ FUNC(ecc_compute_public) (const uint8_t *key_data)
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
*p++ = p1[ECDSA_BYTE_SIZE - i - 1];
|
||||
|
||||
return p0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -124,3 +117,20 @@ FUNC(ecdh_decrypt) (const uint8_t *input, uint8_t *output,
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check if a secret d0 is valid or not
|
||||
*
|
||||
* @param D0 scalar D0: secret
|
||||
* @param D1 scalar D1: secret candidate N-D0
|
||||
*
|
||||
* Return 0 on error.
|
||||
* Return -1 when D1 should be used as the secret
|
||||
* Return 1 when D0 should be used as the secret
|
||||
*/
|
||||
int
|
||||
FUNC(ecc_check_secret) (const uint8_t *d0, uint8_t *d1)
|
||||
{
|
||||
return FUNC(check_secret) ((const bn256 *)d0, (bn256 *)d1);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* call-ec_p256k1.c - interface between Gnuk and Elliptic curve over
|
||||
* GF(p256k1)
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bn.h"
|
||||
#include "affine.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* call-ec_p256r1.c - interface between Gnuk and Elliptic curve over
|
||||
* GF(p256r1)
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bn.h"
|
||||
#include "affine.h"
|
||||
|
||||
109
src/call-rsa.c
109
src/call-rsa.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -24,16 +24,26 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "openpgp.h"
|
||||
#include "status-code.h"
|
||||
#include "random.h"
|
||||
#include "polarssl/config.h"
|
||||
#include "polarssl/rsa.h"
|
||||
|
||||
static rsa_context rsa_ctx;
|
||||
static struct chx_cleanup clp;
|
||||
|
||||
static void
|
||||
rsa_cleanup (void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
rsa_free (&rsa_ctx);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
|
||||
@@ -66,12 +76,20 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
|
||||
mpi_free (&P1); mpi_free (&Q1); mpi_free (&H);
|
||||
if (ret == 0)
|
||||
{
|
||||
DEBUG_INFO ("RSA sign...");
|
||||
int cs;
|
||||
|
||||
DEBUG_INFO ("RSA sign...");
|
||||
clp.next = NULL;
|
||||
clp.routine = rsa_cleanup;
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
ret = rsa_rsassa_pkcs1_v15_sign (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, SIG_RSA_RAW,
|
||||
msg_len, raw_message, temp);
|
||||
memcpy (output, temp, pubkey_len);
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
}
|
||||
|
||||
rsa_free (&rsa_ctx);
|
||||
@@ -83,7 +101,6 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
|
||||
}
|
||||
else
|
||||
{
|
||||
res_APDU_size = pubkey_len;
|
||||
DEBUG_INFO ("done.\r\n");
|
||||
GPG_SUCCESS ();
|
||||
return 0;
|
||||
@@ -93,41 +110,38 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
|
||||
/*
|
||||
* LEN: length in byte
|
||||
*/
|
||||
uint8_t *
|
||||
modulus_calc (const uint8_t *p, int len)
|
||||
int
|
||||
modulus_calc (const uint8_t *p, int len, uint8_t *pubkey)
|
||||
{
|
||||
mpi P, Q, N;
|
||||
uint8_t *modulus;
|
||||
int ret;
|
||||
|
||||
modulus = malloc (len);
|
||||
if (modulus == NULL)
|
||||
return NULL;
|
||||
|
||||
mpi_init (&P); mpi_init (&Q); mpi_init (&N);
|
||||
MPI_CHK( mpi_read_binary (&P, p, len / 2) );
|
||||
MPI_CHK( mpi_read_binary (&Q, p + len / 2, len / 2) );
|
||||
MPI_CHK( mpi_mul_mpi (&N, &P, &Q) );
|
||||
MPI_CHK( mpi_write_binary (&N, modulus, len) );
|
||||
MPI_CHK( mpi_write_binary (&N, pubkey, len) );
|
||||
cleanup:
|
||||
mpi_free (&P); mpi_free (&Q); mpi_free (&N);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
else
|
||||
return modulus;
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
struct key_data *kd)
|
||||
struct key_data *kd, unsigned int *output_len_p)
|
||||
{
|
||||
mpi P1, Q1, H;
|
||||
int ret;
|
||||
unsigned int output_len;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
size_t output_len;
|
||||
#endif
|
||||
|
||||
DEBUG_INFO ("RSA decrypt:");
|
||||
DEBUG_WORD ((uint32_t)&output_len);
|
||||
DEBUG_WORD ((uint32_t)&ret);
|
||||
|
||||
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
|
||||
mpi_init (&P1); mpi_init (&Q1); mpi_init (&H);
|
||||
@@ -152,10 +166,26 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
mpi_free (&P1); mpi_free (&Q1); mpi_free (&H);
|
||||
if (ret == 0)
|
||||
{
|
||||
int cs;
|
||||
|
||||
DEBUG_INFO ("RSA decrypt ...");
|
||||
clp.next = NULL;
|
||||
clp.routine = rsa_cleanup;
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, &output_len, input,
|
||||
output, MAX_RES_APDU_DATA_SIZE);
|
||||
*output_len_p = (unsigned int)output_len;
|
||||
#else
|
||||
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, output_len_p, input,
|
||||
output, MAX_RES_APDU_DATA_SIZE);
|
||||
#endif
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
}
|
||||
|
||||
rsa_free (&rsa_ctx);
|
||||
@@ -167,7 +197,6 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
}
|
||||
else
|
||||
{
|
||||
res_APDU_size = output_len;
|
||||
DEBUG_INFO ("done.\r\n");
|
||||
GPG_SUCCESS ();
|
||||
return 0;
|
||||
@@ -207,45 +236,39 @@ rsa_verify (const uint8_t *pubkey, int pubkey_len,
|
||||
|
||||
#define RSA_EXPONENT 0x10001
|
||||
|
||||
#ifdef KEYGEN_SUPPORT
|
||||
uint8_t *
|
||||
rsa_genkey (int pubkey_len)
|
||||
int
|
||||
rsa_genkey (int pubkey_len, uint8_t *pubkey, uint8_t *p_q)
|
||||
{
|
||||
int ret;
|
||||
uint8_t index = 0;
|
||||
uint8_t *p_q_modulus = (uint8_t *)malloc (pubkey_len * 2);
|
||||
uint8_t *p = p_q_modulus;
|
||||
uint8_t *q = p_q_modulus + pubkey_len / 2;
|
||||
uint8_t *modulus = p_q_modulus + pubkey_len;
|
||||
uint8_t *p = p_q;
|
||||
uint8_t *q = p_q + pubkey_len / 2;
|
||||
int cs;
|
||||
|
||||
extern int prng_seed (int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
extern void neug_flush (void);
|
||||
|
||||
if (p_q_modulus == NULL)
|
||||
return NULL;
|
||||
|
||||
neug_flush ();
|
||||
prng_seed (random_gen, &index);
|
||||
|
||||
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
|
||||
|
||||
clp.next = NULL;
|
||||
clp.routine = rsa_cleanup;
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
MPI_CHK( rsa_gen_key (&rsa_ctx, random_gen, &index, pubkey_len * 8,
|
||||
RSA_EXPONENT) );
|
||||
if (ret != 0)
|
||||
{
|
||||
free (p_q_modulus);
|
||||
rsa_free (&rsa_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.P, p, pubkey_len / 2) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.Q, q, pubkey_len / 2) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.N, modulus, pubkey_len) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.N, pubkey, pubkey_len) );
|
||||
|
||||
cleanup:
|
||||
rsa_free (&rsa_ctx);
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (1);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
return -1;
|
||||
else
|
||||
return p_q_modulus;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
@PINPAD_MORE_DEFINE@
|
||||
@CERTDO_DEFINE@
|
||||
@HID_CARD_CHANGE_DEFINE@
|
||||
@SERIALNO_STR_LEN@
|
||||
@SERIALNO_STR_LEN_DEFINE@
|
||||
@LIFE_CYCLE_MANAGEMENT_DEFINE@
|
||||
|
||||
344
src/configure
vendored
344
src/configure
vendored
@@ -1,12 +1,16 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This is bash which supports ANSI-C Quoting
|
||||
nl=$'\n'
|
||||
|
||||
#
|
||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||
#
|
||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014
|
||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
# Free Software Initiative of Japan
|
||||
#
|
||||
# This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
#
|
||||
# Gnuk is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -20,31 +24,55 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# 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
|
||||
help=no
|
||||
vidpid=none
|
||||
target=FST_01
|
||||
verbose=no
|
||||
with_dfu=default
|
||||
debug=no
|
||||
sys1_compat=yes
|
||||
pinpad=no
|
||||
certdo=no
|
||||
keygen=no
|
||||
sys1_compat=yes
|
||||
hid_card_change=no
|
||||
factory_reset=no
|
||||
flash_override=""
|
||||
# For emulation
|
||||
prefix=/usr/local
|
||||
exec_prefix='${prefix}'
|
||||
libexecdir='${exec_prefix}/libexec'
|
||||
|
||||
# Revision number
|
||||
if test -e ../.git; then
|
||||
if type git >/dev/null 2>&1; then
|
||||
REVISION=$(git describe --dirty="-modified")
|
||||
else
|
||||
# echo 'No git available, please install git'
|
||||
GIT_REVISION=$(sed -e 's/^\(.......\).*$/g\1/' "../.git/$(sed -e 's/^ref: //' ../.git/HEAD)")
|
||||
REVISION=$(cat ../VERSION)-$GIT_REVISION
|
||||
fi
|
||||
else
|
||||
REVISION=$(cat ../VERSION)
|
||||
fi
|
||||
|
||||
# Process each option
|
||||
for option; do
|
||||
case $option in
|
||||
*=*) optarg=`expr "X$option" : '[^=]*=\(.*\)'` ;;
|
||||
*=*) optarg=$(expr "X$option" : '[^=]*=\(.*\)') ;;
|
||||
*) optarg=yes ;;
|
||||
esac
|
||||
|
||||
case $option in
|
||||
-h | --help)
|
||||
help=yes ;;
|
||||
-v | --verbose)
|
||||
verbose=yes ;;
|
||||
--vidpid=*)
|
||||
vidpid=$optarg ;;
|
||||
--target=*)
|
||||
@@ -61,22 +89,31 @@ for option; do
|
||||
certdo=yes ;;
|
||||
--disable-certdo)
|
||||
certdo=no ;;
|
||||
--enable-keygen)
|
||||
keygen=yes ;;
|
||||
--disable-keygen)
|
||||
keygen=no ;;
|
||||
--enable-sys1-compat)
|
||||
sys1_compat = yes ;;
|
||||
--disable-sys1-compat)
|
||||
sys1_compat = no ;;
|
||||
--enable-hid-card-change)
|
||||
hid_card_change = yes ;;
|
||||
hid_card_change=yes ;;
|
||||
--disable-hid-card-change)
|
||||
hid_card_change = no ;;
|
||||
hid_card_change=no ;;
|
||||
--enable-sys1-compat)
|
||||
sys1_compat=yes ;;
|
||||
--disable-sys1-compat)
|
||||
sys1_compat=no ;;
|
||||
--enable-factory-reset)
|
||||
factory_reset=yes ;;
|
||||
--disable-factory-reset)
|
||||
factory_reset=no ;;
|
||||
--with-dfu)
|
||||
with_dfu=yes ;;
|
||||
--without-dfu)
|
||||
with_dfu=no ;;
|
||||
#
|
||||
# For emulation
|
||||
#
|
||||
--prefix=*)
|
||||
prefix=optarg ;;
|
||||
--exec-prefix=*)
|
||||
exec_prefix=optarg ;;
|
||||
--libexecdir=*)
|
||||
libexecdir=optarg ;;
|
||||
*)
|
||||
echo "Unrecognized option \`$option'" >&2
|
||||
echo "Try \`$0 --help' for more information." >&2
|
||||
@@ -97,15 +134,25 @@ Configuration:
|
||||
--target=TARGET specify target [FST_01]
|
||||
supported targets are:
|
||||
FST_01
|
||||
FST_01G
|
||||
OLIMEX_STM32_H103
|
||||
MAPLE_MINI
|
||||
ST_DONGLE
|
||||
ST_NUCLEO_F103
|
||||
NITROKEY_START
|
||||
BLUE_PILL
|
||||
STM8S_DISCOVERY
|
||||
CQ_STARM
|
||||
STM32_PRIMER2
|
||||
STBEE
|
||||
STBEE_MINI
|
||||
FST_01_00 (unreleased version with 8MHz XTAL)
|
||||
--enable-factory-reset
|
||||
support life cycle management [no]
|
||||
--enable-debug debug with virtual COM port [no]
|
||||
--enable-pinpad=cir
|
||||
PIN entry support [no]
|
||||
--enable-certdo support CERT.3 data object [no]
|
||||
--enable-keygen support key generation [no]
|
||||
--enable-sys1-compat enable SYS 1.0 compatibility [yes]
|
||||
executable is target dependent
|
||||
--disable-sys1-compat disable SYS 1.0 compatibility [no]
|
||||
@@ -116,25 +163,23 @@ EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test "$vidpid" = "none"; then
|
||||
echo "Please specify Vendor ID and Product ID by --vidpid option."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_DEFINE="#define BOARD_$target 1"
|
||||
BOARD_HEADER_FILE=board-`echo $target | tr '_[:upper:]' '-[:lower:]'`.h
|
||||
echo Header file is: $BOARD_HEADER_FILE
|
||||
ln -sf ../chopstx/board/$BOARD_HEADER_FILE board.h
|
||||
BOARD_HEADER_FILE=board-$(echo $target | tr '_[:upper:]' '-[:lower:]').h
|
||||
echo "Header file is: $BOARD_HEADER_FILE"
|
||||
ln -sf "../chopstx/board/$BOARD_HEADER_FILE" board.h
|
||||
|
||||
# Flash page size in byte
|
||||
FLASH_PAGE_SIZE=1024
|
||||
# Flash memory size in KB
|
||||
# Flash memory size in KiB
|
||||
FLASH_SIZE=128
|
||||
# Memory size in KiB
|
||||
MEMORY_SIZE=20
|
||||
|
||||
# Settings for TARGET
|
||||
case $target in
|
||||
BLUE_PILL|STM8S_DISCOVERY)
|
||||
# It's 64KB version of STM32F103, but actually has 128KB
|
||||
flash_override="-DSTM32F103_OVERRIDE_FLASH_SIZE_KB=128"
|
||||
;;
|
||||
CQ_STARM|STBEE_MINI)
|
||||
if test "$with_dfu" = "default"; then
|
||||
with_dfu=yes;
|
||||
@@ -151,13 +196,45 @@ STBEE)
|
||||
if test "$with_dfu" = "default"; then
|
||||
with_dfu=yes;
|
||||
fi ;;
|
||||
STM8S_DISCOVERY)
|
||||
FLASH_SIZE=64
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$target" = "GNU_LINUX"; then
|
||||
ldscript=""
|
||||
chip="gnu-linux"
|
||||
emulation="yes"
|
||||
cross=""
|
||||
mcu="none"
|
||||
def_emulation="-DGNU_LINUX_EMULATION"
|
||||
enable_hexoutput=""
|
||||
libs="-lpthread"
|
||||
else
|
||||
ldscript="gnuk.ld"
|
||||
chip="stm32f103"
|
||||
emulation=""
|
||||
cross="arm-none-eabi-"
|
||||
mcu="cortex-m3"
|
||||
def_emulation=""
|
||||
enable_hexoutput=yes
|
||||
libs=""
|
||||
fi
|
||||
|
||||
if test "$emulation" = "yes"; then
|
||||
if test "$vidpid" = "none"; then
|
||||
vidpid=0000:0000
|
||||
else
|
||||
echo "Please don't specify VID:PID for emulation at compile time;"
|
||||
echo "It is a user who should specify VID:PID at run time."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if test "$vidpid" = "none"; then
|
||||
echo "Please specify Vendor ID and Product ID by --vidpid option." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# --enable-debug option
|
||||
if test "$debug" = "yes"; then
|
||||
DEBUG_MAKE_OPTION="ENABLE_DEBUG=1"
|
||||
@@ -171,27 +248,23 @@ fi
|
||||
|
||||
# --with-dfu option
|
||||
if test "$with_dfu" = "yes"; then
|
||||
if test "$target" = "FST_01" -o "$target" = "FST_01_00"; then
|
||||
echo "FST-01 doesn't have DFU loader, you should not enable this."
|
||||
if test "$target" = "FST_01" -o "$target" = "FST_01G" \
|
||||
-o "$target" = "FST_01_00"; then
|
||||
echo "FST-01 doesn't have DFU loader, you should not use --with-dfu." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Configured for DFU"
|
||||
ORIGIN=0x08003000
|
||||
FLASH_SIZE=`expr $FLASH_SIZE - 12`
|
||||
FLASH_SIZE=$((FLASH_SIZE - 12))
|
||||
DFU_DEFINE="#define DFU_SUPPORT 1"
|
||||
HEXOUTPUT_MAKE_OPTION="ENABLE_OUTPUT_HEX=yes"
|
||||
else
|
||||
with_dfu=no
|
||||
echo "Configured for bare system (no-DFU)"
|
||||
ORIGIN=0x08000000
|
||||
DFU_DEFINE="#undef DFU_SUPPORT"
|
||||
HEXOUTPUT_MAKE_OPTION=""
|
||||
fi
|
||||
|
||||
# --enable-pinpad option
|
||||
MSC_SIZE="0"
|
||||
TIM_SIZE="0"
|
||||
EXT_SIZE="0"
|
||||
if test "$pinpad" = "no"; then
|
||||
PINPAD_MAKE_OPTION="# ENABLE_PINPAD="
|
||||
PINPAD_DEFINE="#undef PINPAD_SUPPORT"
|
||||
@@ -202,12 +275,6 @@ else
|
||||
PINPAD_DEFINE="#define PINPAD_SUPPORT 1"
|
||||
PINPAD_MORE_DEFINE="#define PINPAD_${pinpad^^[a-z]}_SUPPORT 1"
|
||||
echo "PIN pad option enabled ($pinpad)"
|
||||
if test "$pinpad" = "dnd"; then
|
||||
MSC_SIZE="0x0200"
|
||||
elif test "$pinpad" = "cir"; then
|
||||
TIM_SIZE="0x00c0"
|
||||
EXT_SIZE="0x00c0"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --enable-certdo option
|
||||
@@ -219,15 +286,6 @@ else
|
||||
echo "CERT.3 Data Object is NOT supported"
|
||||
fi
|
||||
|
||||
# --enable-keygen option
|
||||
if test "$keygen" = "yes"; then
|
||||
KEYGEN_SUPPORT="-DKEYGEN_SUPPORT"
|
||||
echo "Key generation on device is supported"
|
||||
else
|
||||
KEYGEN_SUPPORT=""
|
||||
echo "Key generation on device is NOT supported"
|
||||
fi
|
||||
|
||||
# --enable-hid-card-change option
|
||||
if test "$hid_card_change" = "yes"; then
|
||||
HID_CARD_CHANGE_DEFINE="#define HID_CARD_CHANGE_SUPPORT 1"
|
||||
@@ -237,107 +295,146 @@ else
|
||||
echo "Card insert/removal by HID device is NOT supported"
|
||||
fi
|
||||
|
||||
if test -d ../.git; then
|
||||
REVISION=`git describe --dirty="-modified"`
|
||||
# --enable-factory-reset option
|
||||
if test "$factory_reset" = "yes"; then
|
||||
LIFE_CYCLE_MANAGEMENT_DEFINE="#define LIFE_CYCLE_MANAGEMENT_SUPPORT 1"
|
||||
echo "Life cycle management is supported"
|
||||
else
|
||||
REVISION=`cat ../VERSION`
|
||||
LIFE_CYCLE_MANAGEMENT_DEFINE="#undef LIFE_CYCLE_MANAGEMENT_SUPPORT"
|
||||
echo "Life cycle management is NOT supported"
|
||||
fi
|
||||
|
||||
### !!! Replace following string of "FSIJ" to yours !!! ####
|
||||
SERIALNO="FSIJ-`cat ../VERSION | sed -e 's%^[^/]*/%%'`-"
|
||||
SERIALNO="FSIJ-$(sed -e 's%^[^/]*/%%' <../VERSION)-"
|
||||
|
||||
SERIALNO_STR_LEN_DEFINE="#define SERIALNO_STR_LEN ${#SERIALNO}"
|
||||
|
||||
|
||||
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo:keygen=$keygen"
|
||||
if test "$sys1_compat" = "yes"; then
|
||||
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset"
|
||||
else
|
||||
if test "$with_dfu" = "yes"; then
|
||||
echo "Common binary can't support DFU loader, don't use --with-dfu." >&2
|
||||
exit 1
|
||||
fi
|
||||
# Override settings for common binary. Safer side.
|
||||
FLASH_PAGE_SIZE=2048
|
||||
FLASH_SIZE=128
|
||||
MEMORY_SIZE=20
|
||||
CONFIG="common:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset"
|
||||
fi
|
||||
|
||||
output_vid_pid_version () {
|
||||
echo "$VIDPID" | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\\${nl} 0x\4, 0x\3, /* idProduct */%p"
|
||||
echo "$VERSION" | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
|
||||
}
|
||||
|
||||
output_vendor_product_serial_strings () {
|
||||
name=$1
|
||||
|
||||
echo "static const uint8_t ${name}string_vendor[] = {"
|
||||
echo " ${#VENDOR}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
echo " /* Manufacturer: \"$VENDOR\" */"
|
||||
echo "$VENDOR" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
echo '};'
|
||||
echo
|
||||
echo "static const uint8_t ${name}string_product[] = {"
|
||||
echo " ${#PRODUCT}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
echo " /* Product name: \"$PRODUCT\" */"
|
||||
echo "$PRODUCT" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
echo '};'
|
||||
|
||||
if test -n "$name"; then
|
||||
echo
|
||||
echo "const uint8_t ${name}string_serial[] = {"
|
||||
echo " ${#SERIALNO}*2+2+16, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
echo " /* Serial number: \"$SERIALNO\" */"
|
||||
echo "$SERIALNO" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
if test "$emulation" = "yes"; then
|
||||
echo " 'E', 0, 'M', 0, 'U', 0, 'L', 0,"
|
||||
echo " 'A', 0, 'T', 0, 'E', 0, 'D', 0,"
|
||||
else
|
||||
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
|
||||
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
|
||||
fi
|
||||
echo '};'
|
||||
echo
|
||||
echo '#ifdef USB_STRINGS_FOR_GNUK'
|
||||
echo "static const uint8_t ${name}revision_detail[] = {"
|
||||
echo " ${#REVISION}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
echo " /* revision detail: \"$REVISION\" */"
|
||||
echo "$REVISION" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
echo '};'
|
||||
echo
|
||||
echo "static const uint8_t ${name}config_options[] = {"
|
||||
echo " ${#CONFIG}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
echo " /* configure options: \"$CONFIG\" */"
|
||||
echo $CONFIG | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
echo '};'
|
||||
echo '#endif'
|
||||
fi
|
||||
}
|
||||
|
||||
if !(IFS=" "
|
||||
while read VIDPID VERSION PRODUCT VENDOR; do
|
||||
while read -r VIDPID VERSION PRODUCT VENDOR; do
|
||||
if test "$vidpid" = "$VIDPID"; then
|
||||
(echo $VIDPID | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\n 0x\4, 0x\3, /* idProduct */%p"
|
||||
echo $VERSION | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
|
||||
) > usb-vid-pid-ver.c.inc
|
||||
(echo 'static const uint8_t gnukStringVendor[] = {'
|
||||
echo " ${#VENDOR}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
echo " /* Manufacturer: \"$VENDOR\" */"
|
||||
echo $VENDOR | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
|
||||
echo '};'
|
||||
echo
|
||||
echo 'static const uint8_t gnukStringProduct[] = {'
|
||||
echo " ${#PRODUCT}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
echo " /* Product name: \"$PRODUCT\" */"
|
||||
echo $PRODUCT | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
|
||||
echo '};'
|
||||
echo
|
||||
echo 'const uint8_t gnukStringSerial[] = {'
|
||||
echo " ${#SERIALNO}*2+2+16, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
echo " /* Serial number: \"$SERIALNO\" */"
|
||||
echo $SERIALNO | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
|
||||
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
|
||||
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
|
||||
echo '};'
|
||||
echo
|
||||
echo '#ifdef USB_STRINGS_FOR_GNUK'
|
||||
echo 'static const uint8_t gnuk_revision_detail[] = {'
|
||||
echo " ${#REVISION}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
echo " /* revision detail: \"$REVISION\" */"
|
||||
echo $REVISION | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
|
||||
echo '};'
|
||||
echo
|
||||
echo 'static const uint8_t gnuk_config_options[] = {'
|
||||
echo " ${#CONFIG}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
echo " /* configure options: \"$CONFIG\" */"
|
||||
echo $CONFIG | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
|
||||
echo '};'
|
||||
echo '#endif'
|
||||
) >usb-strings.c.inc
|
||||
output_vid_pid_version > usb-vid-pid-ver.c.inc
|
||||
output_vendor_product_serial_strings gnuk_ >usb-strings.c.inc
|
||||
exit 0
|
||||
fi
|
||||
done; exit 1) < ../GNUK_USB_DEVICE_ID
|
||||
then
|
||||
echo "Please specify valid Vendor ID and Product ID."
|
||||
echo "Check ../GNUK_USB_DEVICE_ID."
|
||||
echo "Please specify valid Vendor ID and Product ID." >&2
|
||||
echo "Check ../GNUK_USB_DEVICE_ID." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$sys1_compat" = "no"; then
|
||||
# Disable when you are sure that it's sys version 2.0.
|
||||
# Note that Gnuk 1.0 and Neug (until 0.06) uses sys version 1.0.
|
||||
# Disabling the compatibility, executable will be target independent,
|
||||
# assuming the clock initialization will be done by SYS (before entry).
|
||||
have_sys_h="-DHAVE_SYS_H"
|
||||
# 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.
|
||||
# Disabling the compatibility, executable will be target independent,
|
||||
# assuming the clock initialization will be done by clock_init in
|
||||
# SYS.
|
||||
use_sys3="-DUSE_SYS3"
|
||||
else
|
||||
have_sys_h=""
|
||||
use_sys3=""
|
||||
fi
|
||||
|
||||
sed -e "s%@HAVE_SYS_H@%$have_sys_h%" \
|
||||
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
|
||||
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
|
||||
-e "s%@KEYGEN_SUPPORT@%$KEYGEN_SUPPORT%" \
|
||||
-e "s%@HEXOUTPUT_MAKE_OPTION@%$HEXOUTPUT_MAKE_OPTION%" \
|
||||
< Makefile.in > Makefile
|
||||
|
||||
(echo "CHIP=$chip";
|
||||
echo "EMULATION=$emulation";
|
||||
echo "CROSS=$cross";
|
||||
echo "MCU=$mcu";
|
||||
echo "DEFS=$use_sys3 $flash_override $def_emulation";
|
||||
echo "LDSCRIPT=$ldscript";
|
||||
echo "LIBS=$libs";
|
||||
echo "$DEBUG_MAKE_OPTION";
|
||||
echo "$PINPAD_MAKE_OPTION";
|
||||
echo "ENABLE_FRAUCHEKY=$enable_fraucheky";
|
||||
echo "ENABLE_OUTPUT_HEX=$enable_hexoutput"
|
||||
if test "$emulation" = "yes"; then
|
||||
echo "prefix=$prefix"
|
||||
echo "exec_prefix=$exec_prefix"
|
||||
echo "libexecdir=$libexecdir"
|
||||
fi
|
||||
) > config.mk
|
||||
|
||||
if test "$certdo" = "yes"; then
|
||||
sed -e "/^@CERTDO_SUPPORT_START@$/ d" -e "/^@CERTDO_SUPPORT_END@$/ d" \
|
||||
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
|
||||
-e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
|
||||
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
|
||||
-e "s/@MSC_SIZE@/$MSC_SIZE/" \
|
||||
-e "s/@TIM_SIZE@/$TIM_SIZE/" \
|
||||
-e "s/@EXT_SIZE@/$EXT_SIZE/" \
|
||||
< gnuk.ld.in > gnuk.ld
|
||||
else
|
||||
sed -e "/^@CERTDO_SUPPORT_START@$/,/^@CERTDO_SUPPORT_END@$/ d" \
|
||||
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
|
||||
-e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
|
||||
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
|
||||
-e "s/@MSC_SIZE@/$MSC_SIZE/" \
|
||||
-e "s/@TIM_SIZE@/$TIM_SIZE/" \
|
||||
-e "s/@EXT_SIZE@/$EXT_SIZE/" \
|
||||
< gnuk.ld.in > gnuk.ld
|
||||
fi
|
||||
sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
|
||||
@@ -346,6 +443,7 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
|
||||
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
|
||||
-e "s/@CERTDO_DEFINE@/$CERTDO_DEFINE/" \
|
||||
-e "s/@HID_CARD_CHANGE_DEFINE@/$HID_CARD_CHANGE_DEFINE/" \
|
||||
-e "s/@SERIALNO_STR_LEN@/$SERIALNO_STR_LEN_DEFINE/" \
|
||||
-e "s/@LIFE_CYCLE_MANAGEMENT_DEFINE@/$LIFE_CYCLE_MANAGEMENT_DEFINE/" \
|
||||
-e "s/@SERIALNO_STR_LEN_DEFINE@/$SERIALNO_STR_LEN_DEFINE/" \
|
||||
< config.h.in > config.h
|
||||
exit 0
|
||||
|
||||
@@ -42,9 +42,11 @@
|
||||
/*
|
||||
* a = 0, b = 7
|
||||
*/
|
||||
#if 0
|
||||
static const bn256 coefficient_a[1] = {
|
||||
{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}
|
||||
};
|
||||
#endif
|
||||
|
||||
static const bn256 coefficient_b[1] = {
|
||||
{{ 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
int compute_kP_p256k1 (ac *X, const bn256 *K, const ac *P);
|
||||
|
||||
int compute_kG_p256k1 (ac *X, const bn256 *K);
|
||||
void ecdsa_p256k1 (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d);
|
||||
int check_secret_p256k1 (const bn256 *q, bn256 *d1);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
int compute_kP_p256r1 (ac *X, const bn256 *K, const ac *P);
|
||||
|
||||
int compute_kG_p256r1 (ac *X, const bn256 *K);
|
||||
void ecdsa_p256r1 (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d);
|
||||
|
||||
int check_secret_p256r1 (const bn256 *q, bn256 *d1);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* ecc-edwards.c - Elliptic curve computation for
|
||||
* the twisted Edwards curve: -x^2 + y^2 = 1 + d*x^2*y^2
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bn.h"
|
||||
@@ -50,7 +49,7 @@
|
||||
* IMPLEMENTATION NOTE
|
||||
*
|
||||
* (0) We assume that the processor has no cache, nor branch target
|
||||
* prediction. Thus, we don't avoid indexing by secret value.
|
||||
* prediction. Thus, we don't avoid indexing by secret value.
|
||||
* We don't avoid conditional jump if both cases have same timing,
|
||||
* either.
|
||||
*
|
||||
@@ -235,7 +234,7 @@ point_add (ptc *X, const ptc *A, const ac *B)
|
||||
* @param X Destination AC
|
||||
* @param A PTC
|
||||
*
|
||||
* (X1:Y1:Z1) represents the affine point (x=X1/Z1, y=Y1/Z1)
|
||||
* (X1:Y1:Z1) represents the affine point (x=X1/Z1, y=Y1/Z1)
|
||||
*/
|
||||
static void
|
||||
point_ptc_to_ac (ac *X, const ptc *A)
|
||||
@@ -258,195 +257,195 @@ point_ptc_to_ac (ac *X, const ptc *A)
|
||||
static const ac precomputed_KG[16] = {
|
||||
{ {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}},
|
||||
{{{ 1, 0, 0, 0, 0, 0, 0, 0 }}} },
|
||||
{ {{{ 0x8f25d51a, 0xc9562d60, 0x9525a7b2, 0x692cc760,
|
||||
{ {{{ 0x8f25d51a, 0xc9562d60, 0x9525a7b2, 0x692cc760,
|
||||
0xfdd6dc5c, 0xc0a4e231, 0xcd6e53fe, 0x216936d3 }}},
|
||||
{{{ 0x66666658, 0x66666666, 0x66666666, 0x66666666,
|
||||
{{{ 0x66666658, 0x66666666, 0x66666666, 0x66666666,
|
||||
0x66666666, 0x66666666, 0x66666666, 0x66666666 }}} },
|
||||
{ {{{ 0x3713af22, 0xac7137bd, 0xac634604, 0x25ed77a4,
|
||||
{ {{{ 0x3713af22, 0xac7137bd, 0xac634604, 0x25ed77a4,
|
||||
0xa815e038, 0xce0d0064, 0xbca90151, 0x041c030f }}},
|
||||
{{{ 0x0780f989, 0xe9b33fcf, 0x3d4445e7, 0xe4e97c2a,
|
||||
{{{ 0x0780f989, 0xe9b33fcf, 0x3d4445e7, 0xe4e97c2a,
|
||||
0x655e5c16, 0xc67dc71c, 0xee43fb7a, 0x72467625 }}} },
|
||||
{ {{{ 0x3ee99893, 0x76a19171, 0x7ba9b065, 0xe647edd9,
|
||||
{ {{{ 0x3ee99893, 0x76a19171, 0x7ba9b065, 0xe647edd9,
|
||||
0x6aeae260, 0x31f39299, 0x5f4a9bb2, 0x6d9e4545 }}},
|
||||
{{{ 0x94cae280, 0xc41433da, 0x79061211, 0x8e842de8,
|
||||
{{{ 0x94cae280, 0xc41433da, 0x79061211, 0x8e842de8,
|
||||
0xa259dc8a, 0xaab95e0b, 0x99013cd0, 0x28bd5fc3 }}} },
|
||||
{ {{{ 0x7d23ea24, 0x59e22c56, 0x0460850e, 0x1e745a88,
|
||||
{ {{{ 0x7d23ea24, 0x59e22c56, 0x0460850e, 0x1e745a88,
|
||||
0xda13ef4b, 0x4583ff4c, 0x95083f85, 0x1f13202c }}},
|
||||
{{{ 0x90275f48, 0xad42025c, 0xb55c4778, 0x0085087e,
|
||||
{{{ 0x90275f48, 0xad42025c, 0xb55c4778, 0x0085087e,
|
||||
0xfdfd7ffa, 0xf21109e7, 0x6c381b7e, 0x66336d35 }}} },
|
||||
{ {{{ 0xd00851f2, 0xaa9476ab, 0x4a61600b, 0xe7838534,
|
||||
{ {{{ 0xd00851f2, 0xaa9476ab, 0x4a61600b, 0xe7838534,
|
||||
0x1a52df87, 0x0de65625, 0xbd675870, 0x5f0dd494 }}},
|
||||
{{{ 0xe23493ba, 0xf20aec1b, 0x3414b0a8, 0x8f7f2741,
|
||||
{{{ 0xe23493ba, 0xf20aec1b, 0x3414b0a8, 0x8f7f2741,
|
||||
0xa80e1eb6, 0x497e74bd, 0xe9365b15, 0x1648eaac }}} },
|
||||
{ {{{ 0x04ac2b69, 0x5b78dcec, 0x32001a73, 0xecdb66ce,
|
||||
{ {{{ 0x04ac2b69, 0x5b78dcec, 0x32001a73, 0xecdb66ce,
|
||||
0xb34cf697, 0xb75832f4, 0x3a2bce94, 0x7aaf57c5 }}},
|
||||
{{{ 0x60fdfc6f, 0xb32ed2ce, 0x757924c6, 0x77bf20be,
|
||||
{{{ 0x60fdfc6f, 0xb32ed2ce, 0x757924c6, 0x77bf20be,
|
||||
0x48742dd1, 0xaebd15dd, 0x55d38439, 0x6311bb16 }}} },
|
||||
{ {{{ 0x42ff5c97, 0x139cdd73, 0xdbd82964, 0xee4c359e,
|
||||
{ {{{ 0x42ff5c97, 0x139cdd73, 0xdbd82964, 0xee4c359e,
|
||||
0x70611a3f, 0x91c1cd94, 0x8075dbcb, 0x1d0c34f6 }}},
|
||||
{{{ 0x5f931219, 0x43eaa549, 0xa23d35a6, 0x3737aba7,
|
||||
{{{ 0x5f931219, 0x43eaa549, 0xa23d35a6, 0x3737aba7,
|
||||
0x46f167bb, 0x54b1992f, 0xb74a9944, 0x01a11f3c }}} },
|
||||
{ {{{ 0xba46b161, 0x67a5310e, 0xd9d67f6c, 0x790f8527,
|
||||
{ {{{ 0xba46b161, 0x67a5310e, 0xd9d67f6c, 0x790f8527,
|
||||
0x2f6cc814, 0x359c5b5f, 0x7786383d, 0x7b6a5565 }}},
|
||||
{{{ 0x663ab0d3, 0xf1431b60, 0x09995826, 0x14a32d8f,
|
||||
{{{ 0x663ab0d3, 0xf1431b60, 0x09995826, 0x14a32d8f,
|
||||
0xeddb8571, 0x61d526f6, 0x0eac739a, 0x0cb7acea }}} },
|
||||
{ {{{ 0x4a2d009f, 0x5eb1a697, 0xd8df987a, 0xdacb43b4,
|
||||
{ {{{ 0x4a2d009f, 0x5eb1a697, 0xd8df987a, 0xdacb43b4,
|
||||
0x8397f958, 0x4870f214, 0x8a175fbb, 0x5aa0c67c }}},
|
||||
{{{ 0x78887db3, 0x27dbbd4c, 0x64e322ab, 0xe327b707,
|
||||
{{{ 0x78887db3, 0x27dbbd4c, 0x64e322ab, 0xe327b707,
|
||||
0x7cbe4e3b, 0x87e293fa, 0xbda72395, 0x17040799 }}} },
|
||||
{ {{{ 0x99d1e696, 0xc833a5a2, 0x2d9d5877, 0x969bff8e,
|
||||
{ {{{ 0x99d1e696, 0xc833a5a2, 0x2d9d5877, 0x969bff8e,
|
||||
0x2216fa67, 0x383a533a, 0x684d3925, 0x338bbe0a }}},
|
||||
{{{ 0xd6cfb491, 0x35b5aae8, 0xaa12f3f8, 0x4a588279,
|
||||
{{{ 0xd6cfb491, 0x35b5aae8, 0xaa12f3f8, 0x4a588279,
|
||||
0x2e30380e, 0xa7c2e708, 0x9e4b3d62, 0x69f13e09 }}} },
|
||||
{ {{{ 0x27f1cd56, 0xec0dc2ef, 0xdb11cc97, 0x1af11548,
|
||||
{ {{{ 0x27f1cd56, 0xec0dc2ef, 0xdb11cc97, 0x1af11548,
|
||||
0x9ebc7613, 0xb642f86a, 0xcb77c3b9, 0x5ce45e73 }}},
|
||||
{{{ 0x3eddd6de, 0x5d128786, 0x4859eab7, 0x16f9a6b4,
|
||||
{{{ 0x3eddd6de, 0x5d128786, 0x4859eab7, 0x16f9a6b4,
|
||||
0xd8782345, 0x55c53916, 0xdb7b202a, 0x6b1dfa87 }}} },
|
||||
{ {{{ 0x19e30528, 0x2461a8ed, 0x665cfb1c, 0xaf756bf9,
|
||||
{ {{{ 0x19e30528, 0x2461a8ed, 0x665cfb1c, 0xaf756bf9,
|
||||
0x3a6e8673, 0x0fcafd1d, 0x45d10f48, 0x0d264435 }}},
|
||||
{{{ 0x5431db67, 0x543fd4c6, 0x60932432, 0xc153a5b3,
|
||||
{{{ 0x5431db67, 0x543fd4c6, 0x60932432, 0xc153a5b3,
|
||||
0xd2119aa4, 0x41d5b8eb, 0x8b09b6a5, 0x36bd9ab4 }}} },
|
||||
{ {{{ 0x21e06738, 0x6d39f935, 0x3765dd86, 0x4e6a7c59,
|
||||
{ {{{ 0x21e06738, 0x6d39f935, 0x3765dd86, 0x4e6a7c59,
|
||||
0xa4730880, 0xefc0dd80, 0x4079fe2f, 0x40617e56 }}},
|
||||
{{{ 0x921439b9, 0xbc83cdff, 0x98833c09, 0xd5cccc06,
|
||||
{{{ 0x921439b9, 0xbc83cdff, 0x98833c09, 0xd5cccc06,
|
||||
0xda13cdcb, 0xe315c425, 0x67ff5370, 0x37bc6e84 }}} },
|
||||
{ {{{ 0xf643b5f5, 0x65e7f028, 0x0ffbf5a8, 0x5b0d4831,
|
||||
{ {{{ 0xf643b5f5, 0x65e7f028, 0x0ffbf5a8, 0x5b0d4831,
|
||||
0xf4085f62, 0x0f540498, 0x0db7bd1b, 0x6f0bb035 }}},
|
||||
{{{ 0x9733742c, 0x51f65571, 0xf513409f, 0x2fc047a0,
|
||||
{{{ 0x9733742c, 0x51f65571, 0xf513409f, 0x2fc047a0,
|
||||
0x355facf6, 0x07f45010, 0x3a989a9c, 0x5cd416a9 }}} },
|
||||
{ {{{ 0x748f2a67, 0x0bdd7208, 0x415b7f7f, 0x0cf0b80b,
|
||||
{ {{{ 0x748f2a67, 0x0bdd7208, 0x415b7f7f, 0x0cf0b80b,
|
||||
0x57aa0119, 0x44afdd5f, 0x430dc946, 0x05d68802 }}},
|
||||
{{{ 0x1a60eeb2, 0x420c46e5, 0x665024f5, 0xc60a9b33,
|
||||
{{{ 0x1a60eeb2, 0x420c46e5, 0x665024f5, 0xc60a9b33,
|
||||
0x48c51347, 0x37520265, 0x00a21bfb, 0x6f4be0af }}} }
|
||||
};
|
||||
|
||||
static const ac precomputed_2E_KG[16] = {
|
||||
{ {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}},
|
||||
{{{ 1, 0, 0, 0, 0, 0, 0, 0 }}} },
|
||||
{ {{{ 0x199c4f7d, 0xec314ac0, 0xb2ebaaf9, 0x66a39c16,
|
||||
{ {{{ 0x199c4f7d, 0xec314ac0, 0xb2ebaaf9, 0x66a39c16,
|
||||
0xedd4d15f, 0xab1c92b8, 0x57d9eada, 0x482a4cdf }}},
|
||||
{{{ 0x6e4eb04b, 0xbd513b11, 0x25e4fd6a, 0x3f115fa5,
|
||||
{{{ 0x6e4eb04b, 0xbd513b11, 0x25e4fd6a, 0x3f115fa5,
|
||||
0x14519298, 0x0b3c5fc6, 0x81c2f7a8, 0x7391de43 }}} },
|
||||
{ {{{ 0x1254fe02, 0xa57dca18, 0x6da34368, 0xa56a2a14,
|
||||
{ {{{ 0x1254fe02, 0xa57dca18, 0x6da34368, 0xa56a2a14,
|
||||
0x63e7328e, 0x44c6e34f, 0xca63ab3e, 0x3f748617 }}},
|
||||
{{{ 0x7dc1641e, 0x5a13dc52, 0xee4e9ca1, 0x4cbb2899,
|
||||
{{{ 0x7dc1641e, 0x5a13dc52, 0xee4e9ca1, 0x4cbb2899,
|
||||
0x1ba9acee, 0x3938a289, 0x420fc47b, 0x0fed89e6 }}} },
|
||||
{ {{{ 0x49cbad08, 0x3c193f32, 0x15e80ef5, 0xdda71ef1,
|
||||
{ {{{ 0x49cbad08, 0x3c193f32, 0x15e80ef5, 0xdda71ef1,
|
||||
0x9d128c33, 0xda44186c, 0xbf98c24f, 0x54183ede }}},
|
||||
{{{ 0x93d165c1, 0x2cb483f7, 0x177f44aa, 0x51762ace,
|
||||
{{{ 0x93d165c1, 0x2cb483f7, 0x177f44aa, 0x51762ace,
|
||||
0xb4ab035d, 0xb3fe651b, 0xa0b0d4e5, 0x426c99c3 }}} },
|
||||
{ {{{ 0xef3f3fb1, 0xb3fcf4d8, 0x065060a0, 0x7052292b,
|
||||
{ {{{ 0xef3f3fb1, 0xb3fcf4d8, 0x065060a0, 0x7052292b,
|
||||
0x24240b15, 0x18795ff8, 0x9989ffcc, 0x13aea184 }}},
|
||||
{{{ 0xc2b81f44, 0x1930c101, 0x10600555, 0x672d6ca4,
|
||||
{{{ 0xc2b81f44, 0x1930c101, 0x10600555, 0x672d6ca4,
|
||||
0x1b25e570, 0xfbddbff2, 0x8ca12b70, 0x0884949c }}} },
|
||||
{ {{{ 0x00564bbf, 0x9983a033, 0xde61b72d, 0x95587d25,
|
||||
{ {{{ 0x00564bbf, 0x9983a033, 0xde61b72d, 0x95587d25,
|
||||
0xeb17ad71, 0xb6719dfb, 0xc0bc3517, 0x46871ad0 }}},
|
||||
{{{ 0xe95a6693, 0xb034fb61, 0x76eabad9, 0x5b0d8d18,
|
||||
{{{ 0xe95a6693, 0xb034fb61, 0x76eabad9, 0x5b0d8d18,
|
||||
0x884785dc, 0xad295dd0, 0x74a1276a, 0x359debad }}} },
|
||||
{ {{{ 0xe89fb5ca, 0x2e5a2686, 0x5656c6c5, 0xd3d200ba,
|
||||
{ {{{ 0xe89fb5ca, 0x2e5a2686, 0x5656c6c5, 0xd3d200ba,
|
||||
0x9c969001, 0xef4c051e, 0x02cb45f4, 0x0d4ea946 }}},
|
||||
{{{ 0x76d6e506, 0xa6f8a422, 0x63209e23, 0x454c768f,
|
||||
{{{ 0x76d6e506, 0xa6f8a422, 0x63209e23, 0x454c768f,
|
||||
0x2b372386, 0x5c12fd04, 0xdbfee11f, 0x1aedbd3e }}} },
|
||||
{ {{{ 0x00dbf569, 0x700ab50f, 0xd335b313, 0x9553643c,
|
||||
{ {{{ 0x00dbf569, 0x700ab50f, 0xd335b313, 0x9553643c,
|
||||
0xa17dc97e, 0xeea9bddf, 0x3350a2bd, 0x0d12fe3d }}},
|
||||
{{{ 0xa16a3dee, 0xe5ac35fe, 0xf81950c3, 0x4ae4664a,
|
||||
{{{ 0xa16a3dee, 0xe5ac35fe, 0xf81950c3, 0x4ae4664a,
|
||||
0x3dbbf921, 0x75c63df4, 0x2958a5a6, 0x545b109c }}} },
|
||||
{ {{{ 0x0a61b29c, 0xd7a52a98, 0x65aca9ee, 0xe21e0acb,
|
||||
{ {{{ 0x0a61b29c, 0xd7a52a98, 0x65aca9ee, 0xe21e0acb,
|
||||
0x5985dcbe, 0x57a69c0f, 0xeb87a534, 0x3c0c1e7b }}},
|
||||
{{{ 0x6384bd2f, 0xf0a0b50d, 0xc6939e4b, 0xff349a34,
|
||||
{{{ 0x6384bd2f, 0xf0a0b50d, 0xc6939e4b, 0xff349a34,
|
||||
0x6e2f1973, 0x922c4554, 0xf1347631, 0x74e826b2 }}} },
|
||||
{ {{{ 0xa655803c, 0xd7eaa066, 0x38292c5c, 0x09504e76,
|
||||
{ {{{ 0xa655803c, 0xd7eaa066, 0x38292c5c, 0x09504e76,
|
||||
0x2c874953, 0xe298a02e, 0x8932b73f, 0x225093ed }}},
|
||||
{{{ 0xe69c3efd, 0xf93e2b4d, 0x8a87c799, 0xa2cbd5fc,
|
||||
{{{ 0xe69c3efd, 0xf93e2b4d, 0x8a87c799, 0xa2cbd5fc,
|
||||
0x85dba986, 0xdf41da94, 0xccee8edc, 0x36fe85e7 }}} },
|
||||
{ {{{ 0x7d742813, 0x78df7dc5, 0x4a193e64, 0x333bcc6d,
|
||||
{ {{{ 0x7d742813, 0x78df7dc5, 0x4a193e64, 0x333bcc6d,
|
||||
0x6a966d2d, 0x8242aa25, 0x4cd36d32, 0x03500a94 }}},
|
||||
{{{ 0x580505d7, 0xd5d110fc, 0xfa11e1e9, 0xb2f47e16,
|
||||
{{{ 0x580505d7, 0xd5d110fc, 0xfa11e1e9, 0xb2f47e16,
|
||||
0x06eab6b4, 0xd0030f92, 0x62c91d46, 0x2dc80d5f }}} },
|
||||
{ {{{ 0x2a75e492, 0x5788b01a, 0xbae31352, 0x992acf54,
|
||||
{ {{{ 0x2a75e492, 0x5788b01a, 0xbae31352, 0x992acf54,
|
||||
0x8159db27, 0x4591b980, 0xd3d84740, 0x36c6533c }}},
|
||||
{{{ 0x103883b5, 0xc44c7c00, 0x515d0820, 0x10329423,
|
||||
{{{ 0x103883b5, 0xc44c7c00, 0x515d0820, 0x10329423,
|
||||
0x71b9dc16, 0xbd306903, 0xf88f8d32, 0x7edd5a95 }}} },
|
||||
{ {{{ 0x005523d7, 0xfd63b1ac, 0xad70dd21, 0x74482e0d,
|
||||
{ {{{ 0x005523d7, 0xfd63b1ac, 0xad70dd21, 0x74482e0d,
|
||||
0x02b56105, 0x67c9d9d0, 0x5971b456, 0x4d318012 }}},
|
||||
{{{ 0x841106df, 0xdc9a6f6d, 0xa326987f, 0x7c52ed9d,
|
||||
{{{ 0x841106df, 0xdc9a6f6d, 0xa326987f, 0x7c52ed9d,
|
||||
0x00607ea0, 0x4dbeaa6f, 0x6959e688, 0x115c221d }}} },
|
||||
{ {{{ 0xc80f7c16, 0xf8718464, 0xe9930634, 0x05dc8f40,
|
||||
{ {{{ 0xc80f7c16, 0xf8718464, 0xe9930634, 0x05dc8f40,
|
||||
0xc2e9d5f4, 0xefa699bb, 0x021da209, 0x2469e813 }}},
|
||||
{{{ 0xc602a3c4, 0x75c02845, 0x0a200f9d, 0x49d1b2ce,
|
||||
{{{ 0xc602a3c4, 0x75c02845, 0x0a200f9d, 0x49d1b2ce,
|
||||
0x2fb3ec8f, 0xd21b75e4, 0xd72a7545, 0x10dd726a }}} },
|
||||
{ {{{ 0x63ef1a6c, 0xeda58527, 0x051705e0, 0xb3fc0e72,
|
||||
{ {{{ 0x63ef1a6c, 0xeda58527, 0x051705e0, 0xb3fc0e72,
|
||||
0x44f1161f, 0xbda6f3ee, 0xf339efe5, 0x7680aebf }}},
|
||||
{{{ 0xb1b070a7, 0xe8d3fd01, 0xdbfbaaa0, 0xc3ff7dbf,
|
||||
{{{ 0xb1b070a7, 0xe8d3fd01, 0xdbfbaaa0, 0xc3ff7dbf,
|
||||
0xa320c916, 0xd81ef6f2, 0x62a3b54d, 0x3e22a1fb }}} },
|
||||
{ {{{ 0xb1fa18c8, 0xcdbb9187, 0xcb483a17, 0x8ddb5f6b,
|
||||
{ {{{ 0xb1fa18c8, 0xcdbb9187, 0xcb483a17, 0x8ddb5f6b,
|
||||
0xea49af98, 0xc0a880b9, 0xf2dfddd0, 0x53bf600b }}},
|
||||
{{{ 0x9e25b164, 0x4217404c, 0xafb74aa7, 0xfabf06ee,
|
||||
{{{ 0x9e25b164, 0x4217404c, 0xafb74aa7, 0xfabf06ee,
|
||||
0x2b9f233c, 0xb17712ae, 0xd0eb909e, 0x71f0b344 }}} }
|
||||
};
|
||||
|
||||
static const ac precomputed_4E_KG[16] = {
|
||||
{ {{{ 0, 0, 0, 0, 0, 0, 0, 0 }}},
|
||||
{{{ 1, 0, 0, 0, 0, 0, 0, 0 }}} },
|
||||
{ {{{ 0xe388a820, 0xbb6ec091, 0x5182278a, 0xa928b283,
|
||||
{ {{{ 0xe388a820, 0xbb6ec091, 0x5182278a, 0xa928b283,
|
||||
0xa9a6eb83, 0x2259174d, 0x45500054, 0x184b48cb }}},
|
||||
{{{ 0x26e77c33, 0xfe324dba, 0x83faf453, 0x6679a5e3,
|
||||
{{{ 0x26e77c33, 0xfe324dba, 0x83faf453, 0x6679a5e3,
|
||||
0x2380ef73, 0xdd60c268, 0x03dc33a9, 0x3ee0e07a }}} },
|
||||
{ {{{ 0xce974493, 0x403aff28, 0x9bf6f5c4, 0x84076bf4,
|
||||
{ {{{ 0xce974493, 0x403aff28, 0x9bf6f5c4, 0x84076bf4,
|
||||
0xecd898fb, 0xec57038c, 0xb663ed49, 0x2898ffaa }}},
|
||||
{{{ 0xf335163d, 0xf4b3bc46, 0xfa4fb6c6, 0xe613a0f4,
|
||||
{{{ 0xf335163d, 0xf4b3bc46, 0xfa4fb6c6, 0xe613a0f4,
|
||||
0xb9934557, 0xe759d6bc, 0xab6c9477, 0x094f3b96 }}} },
|
||||
{ {{{ 0x6afffe9e, 0x168bb5a0, 0xee748c29, 0x950f7ad7,
|
||||
{ {{{ 0x6afffe9e, 0x168bb5a0, 0xee748c29, 0x950f7ad7,
|
||||
0xda17203d, 0xa4850a2b, 0x77289e0f, 0x0062f7a7 }}},
|
||||
{{{ 0x4b3829fa, 0x6265d4e9, 0xbdfcd386, 0x4f155ada,
|
||||
{{{ 0x4b3829fa, 0x6265d4e9, 0xbdfcd386, 0x4f155ada,
|
||||
0x475795f6, 0x9f38bda4, 0xdece4a4c, 0x560ed4b3 }}} },
|
||||
{ {{{ 0x141e648a, 0xdad4570a, 0x019b965c, 0x8bbf674c,
|
||||
{ {{{ 0x141e648a, 0xdad4570a, 0x019b965c, 0x8bbf674c,
|
||||
0xdb08fe30, 0xd7a8d50d, 0xa2851109, 0x7efb45d3 }}},
|
||||
{{{ 0xd0c28cda, 0x52e818ac, 0xa321d436, 0x792257dd,
|
||||
{{{ 0xd0c28cda, 0x52e818ac, 0xa321d436, 0x792257dd,
|
||||
0x9d71f8b7, 0x867091c6, 0x11a1bf56, 0x0fe1198b }}} },
|
||||
{ {{{ 0x06137ab1, 0x4e848339, 0x3e6674cc, 0x5673e864,
|
||||
{ {{{ 0x06137ab1, 0x4e848339, 0x3e6674cc, 0x5673e864,
|
||||
0x0140502b, 0xad882043, 0x6ea1e46a, 0x34b5c0cb }}},
|
||||
{{{ 0x1d70aa7c, 0x29786814, 0x8cdbb8aa, 0x840ae3f9,
|
||||
{{{ 0x1d70aa7c, 0x29786814, 0x8cdbb8aa, 0x840ae3f9,
|
||||
0xbd4801fb, 0x78b4d622, 0xcf18ae9a, 0x6cf4e146 }}} },
|
||||
{ {{{ 0x36297168, 0x95c270ad, 0x942e7812, 0x2303ce80,
|
||||
{ {{{ 0x36297168, 0x95c270ad, 0x942e7812, 0x2303ce80,
|
||||
0x0205cf0e, 0x71908cc2, 0x32bcd754, 0x0cc15edd }}},
|
||||
{{{ 0x2c7ded86, 0x1db94364, 0xf141b22c, 0xc694e39b,
|
||||
{{{ 0x2c7ded86, 0x1db94364, 0xf141b22c, 0xc694e39b,
|
||||
0x5e5a9312, 0xf22f64ef, 0x3c5e6155, 0x649b8859 }}} },
|
||||
{ {{{ 0xb6417945, 0x0d5611c6, 0xac306c97, 0x9643fdbf,
|
||||
{ {{{ 0xb6417945, 0x0d5611c6, 0xac306c97, 0x9643fdbf,
|
||||
0x0df500ff, 0xe81faaa4, 0x6f50e615, 0x0792c79b }}},
|
||||
{{{ 0xd2af8c8d, 0xb45bbc49, 0x84f51bfe, 0x16c615ab,
|
||||
{{{ 0xd2af8c8d, 0xb45bbc49, 0x84f51bfe, 0x16c615ab,
|
||||
0xc1d02d32, 0xdc57c526, 0x3c8aaa55, 0x5fb9a9a6 }}} },
|
||||
{ {{{ 0xdee40b98, 0x82faa8db, 0x6d520674, 0xff8a5208,
|
||||
{ {{{ 0xdee40b98, 0x82faa8db, 0x6d520674, 0xff8a5208,
|
||||
0x446ac562, 0x1f8c510f, 0x2cc6b66e, 0x4676d381 }}},
|
||||
{{{ 0x2e7429f4, 0x8f1aa780, 0x8ed6bdf6, 0x2a95c1bf,
|
||||
{{{ 0x2e7429f4, 0x8f1aa780, 0x8ed6bdf6, 0x2a95c1bf,
|
||||
0x457fa0eb, 0x051450a0, 0x744c57b1, 0x7d89e2b7 }}} },
|
||||
{ {{{ 0x3f95ea15, 0xb6bdacd2, 0x2f1a5d69, 0xc9a9d1b1,
|
||||
{ {{{ 0x3f95ea15, 0xb6bdacd2, 0x2f1a5d69, 0xc9a9d1b1,
|
||||
0xf4d22d72, 0xd4c2f1a9, 0x4dc516b5, 0x73ecfdf1 }}},
|
||||
{{{ 0x05391e08, 0xa1ce93cd, 0x7b8aac17, 0x98f1e99e,
|
||||
{{{ 0x05391e08, 0xa1ce93cd, 0x7b8aac17, 0x98f1e99e,
|
||||
0xa098cbb3, 0x9ba84f2e, 0xf9bdd37a, 0x1425aa8b }}} },
|
||||
{ {{{ 0x966abfc0, 0x8a385bf4, 0xf081a640, 0x55e5e8bc,
|
||||
{ {{{ 0x966abfc0, 0x8a385bf4, 0xf081a640, 0x55e5e8bc,
|
||||
0xee26f5ff, 0x835dff85, 0xe509e1ea, 0x4927e622 }}},
|
||||
{{{ 0x352334b0, 0x164c8dbc, 0xa3fea31f, 0xcac1ad63,
|
||||
{{{ 0x352334b0, 0x164c8dbc, 0xa3fea31f, 0xcac1ad63,
|
||||
0x682fd457, 0x9b87a676, 0x1a53145f, 0x75f382ff }}} },
|
||||
{ {{{ 0xc3efcb46, 0x16b944f5, 0x68cb184c, 0x1fb55714,
|
||||
{ {{{ 0xc3efcb46, 0x16b944f5, 0x68cb184c, 0x1fb55714,
|
||||
0x9ccf2dc8, 0xf1c2b116, 0x808283d8, 0x7417e00f }}},
|
||||
{{{ 0x930199ba, 0x1ea67a22, 0x718990d8, 0x9fbaf765,
|
||||
{{{ 0x930199ba, 0x1ea67a22, 0x718990d8, 0x9fbaf765,
|
||||
0x8f3d5d57, 0x231fc664, 0xe5853194, 0x38141a19 }}} },
|
||||
{ {{{ 0x2f81290d, 0xb9f00390, 0x04a9ca6c, 0x44877827,
|
||||
{ {{{ 0x2f81290d, 0xb9f00390, 0x04a9ca6c, 0x44877827,
|
||||
0xe1dbdd65, 0x65d7f9b9, 0xf7c6698a, 0x7133424c }}},
|
||||
{{{ 0xa7cd250f, 0x604cfb3c, 0x5acc18f3, 0x460c3c4b,
|
||||
{{{ 0xa7cd250f, 0x604cfb3c, 0x5acc18f3, 0x460c3c4b,
|
||||
0xb518e3eb, 0xa53e50e0, 0x98a40196, 0x2b4b9267 }}} },
|
||||
{ {{{ 0xc5dbd06c, 0x591b0672, 0xaa1eeb65, 0x10d43dca,
|
||||
{ {{{ 0xc5dbd06c, 0x591b0672, 0xaa1eeb65, 0x10d43dca,
|
||||
0xcd2517af, 0x420cdef8, 0x0b695a8a, 0x513a307e }}},
|
||||
{{{ 0x66503215, 0xee9d6a7b, 0x088fd9a4, 0xdea58720,
|
||||
{{{ 0x66503215, 0xee9d6a7b, 0x088fd9a4, 0xdea58720,
|
||||
0x973afe12, 0x8f3cbbea, 0x872f2538, 0x005c2350 }}} },
|
||||
{ {{{ 0x35af3291, 0xe5024b70, 0x4f5e669a, 0x1d3eec2d,
|
||||
{ {{{ 0x35af3291, 0xe5024b70, 0x4f5e669a, 0x1d3eec2d,
|
||||
0x6e79d539, 0xc1f6d766, 0x795b5248, 0x34ec043f }}},
|
||||
{{{ 0x400960b6, 0xb2763511, 0x29e57df0, 0xff7a3d84,
|
||||
{{{ 0x400960b6, 0xb2763511, 0x29e57df0, 0xff7a3d84,
|
||||
0x1666c1f1, 0xaeac7792, 0x66084bc0, 0x72426e97 }}} },
|
||||
{ {{{ 0x44f826ca, 0x5b1c3199, 0x790aa408, 0x68b00b73,
|
||||
{ {{{ 0x44f826ca, 0x5b1c3199, 0x790aa408, 0x68b00b73,
|
||||
0x69e9b92b, 0xaf0984b4, 0x3ffe9093, 0x5fe6736f }}},
|
||||
{{{ 0xffd49312, 0xd67f2889, 0x5cb9ed21, 0x3520d747,
|
||||
{{{ 0xffd49312, 0xd67f2889, 0x5cb9ed21, 0x3520d747,
|
||||
0x3c65a606, 0x94f893b1, 0x2d65496f, 0x2fee5e8c }}} }
|
||||
};
|
||||
|
||||
@@ -586,7 +585,7 @@ bnX_mul_C (uint32_t *r, const uint32_t *q, int q_size)
|
||||
|
||||
/**
|
||||
* @brief R = A mod M (using M=2^252+C) (Barret reduction)
|
||||
*
|
||||
*
|
||||
* See HAC 14.47.
|
||||
*/
|
||||
static void
|
||||
@@ -660,7 +659,7 @@ mod_reduce_M (bn256 *R, const bn512 *A)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
int
|
||||
eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *out,
|
||||
const bn256 *a, const uint8_t *seed, const bn256 *pk)
|
||||
{
|
||||
@@ -704,9 +703,11 @@ eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *out,
|
||||
bn256_add (s, s, M);
|
||||
else
|
||||
bn256_add (tmp, s, M);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
eddsa_public_key_25519 (bn256 *pk, const bn256 *a)
|
||||
{
|
||||
ac R[1];
|
||||
@@ -728,18 +729,10 @@ eddsa_public_key_25519 (bn256 *pk, const bn256 *a)
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
eddsa_compute_public_25519 (const uint8_t *kd)
|
||||
void
|
||||
eddsa_compute_public_25519 (const uint8_t *kd, uint8_t *pubkey)
|
||||
{
|
||||
uint8_t *p0;
|
||||
const bn256 *a = (const bn256 *)kd;
|
||||
|
||||
p0 = (uint8_t *)malloc (sizeof (bn256));
|
||||
if (p0 == NULL)
|
||||
return NULL;
|
||||
|
||||
eddsa_public_key_25519 ((bn256 *)p0, a);
|
||||
return p0;
|
||||
eddsa_public_key_25519 ((bn256 *)pubkey, (const bn256 *)kd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* ecc-mont.c - Elliptic curve computation for
|
||||
* the Montgomery curve: y^2 = x^3 + 486662*x^2 + x.
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2015, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -32,7 +32,7 @@
|
||||
* References:
|
||||
*
|
||||
* [1] D. J. Bernstein. Curve25519: new Diffie-Hellman speed records.
|
||||
* Proceedings of PKC 2006, to appear.
|
||||
* Proceedings of PKC 2006, to appear.
|
||||
* http://cr.yp.to/papers.html#curve25519. Date: 2006.02.09.
|
||||
*
|
||||
* [2] D. J. Bernstein. Can we avoid tests for zero in fast
|
||||
@@ -45,7 +45,7 @@
|
||||
* IMPLEMENTATION NOTE
|
||||
*
|
||||
* (0) We assume that the processor has no cache, nor branch target
|
||||
* prediction. Thus, we don't avoid indexing by secret value.
|
||||
* prediction. Thus, we don't avoid indexing by secret value.
|
||||
* We don't avoid conditional jump if both cases have same timing,
|
||||
* either.
|
||||
*
|
||||
@@ -78,6 +78,7 @@ mod25638_mul_121665 (bn256 *x, const bn256 *a)
|
||||
|
||||
s = a->word;
|
||||
d = x->word;
|
||||
memset (d, 0, sizeof (bn256));
|
||||
w = 121665;
|
||||
MULADD_256_ASM (s, d, w, c);
|
||||
#else
|
||||
@@ -143,7 +144,7 @@ mont_d_and_a (pt *prd, pt *sum, pt *q0, pt *q1, const bn256 *dif_x)
|
||||
* @param Q_X x-coordinate of Q
|
||||
*
|
||||
*/
|
||||
void
|
||||
static void
|
||||
compute_nQ (bn256 *res, const bn256 *n, const bn256 *q_x)
|
||||
{
|
||||
int i, j;
|
||||
@@ -194,3 +195,32 @@ compute_nQ (bn256 *res, const bn256 *n, const bn256 *q_x)
|
||||
mod25638_mul (res, res, p0->x);
|
||||
mod25519_reduce (res);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ecdh_compute_public_25519 (const uint8_t *key_data, uint8_t *pubkey)
|
||||
{
|
||||
bn256 gx[1];
|
||||
bn256 k[1];
|
||||
|
||||
memset (gx, 0, sizeof (bn256));
|
||||
gx[0].word[0] = 9; /* Gx = 9 */
|
||||
memcpy (k, key_data, sizeof (bn256));
|
||||
|
||||
compute_nQ ((bn256 *)pubkey, k, gx);
|
||||
}
|
||||
|
||||
int
|
||||
ecdh_decrypt_curve25519 (const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key_data)
|
||||
{
|
||||
bn256 q_x[1];
|
||||
bn256 k[1];
|
||||
bn256 shared[1];
|
||||
|
||||
memcpy (q_x, input, sizeof (bn256));
|
||||
memcpy (k, key_data, sizeof (bn256));
|
||||
compute_nQ (shared, k, q_x);
|
||||
memcpy (output, shared, sizeof (bn256));
|
||||
return 0;
|
||||
}
|
||||
|
||||
34
src/ecc.c
34
src/ecc.c
@@ -1,7 +1,8 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ecc.c - Elliptic curve over GF(prime)
|
||||
*
|
||||
* Copyright (C) 2011, 2013, 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2013, 2014, 2015
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -33,7 +34,7 @@
|
||||
* Pages 250-265, Springer-Verlag London, UK, 2001
|
||||
* ISBN:3-540-41898-9
|
||||
*
|
||||
* [3] Mustapha Hedabou, Pierre Pinel, Lucien Bénéteau,
|
||||
* [3] Mustapha Hedabou, Pierre Pinel, Lucien Bénéteau,
|
||||
* A comb method to render ECC resistant against Side Channel Attacks,
|
||||
* 2004
|
||||
*/
|
||||
@@ -366,3 +367,32 @@ FUNC(ecdsa) (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d)
|
||||
#undef tmp_k
|
||||
#undef borrow
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check if a secret d0 is valid or not
|
||||
*
|
||||
* @param D0 scalar D0: secret
|
||||
* @param D1 scalar D1: secret candidate N-D0
|
||||
*
|
||||
* Return 0 on error.
|
||||
* Return -1 when D1 should be used as the secret
|
||||
* Return 1 when D0 should be used as the secret
|
||||
*/
|
||||
int
|
||||
FUNC(check_secret) (const bn256 *d0, bn256 *d1)
|
||||
{
|
||||
ac Q0[1], Q1[1];
|
||||
|
||||
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) != 0)
|
||||
/* == 0 or >= N, it's not valid. */
|
||||
return 0;
|
||||
|
||||
FUNC(compute_kG) (Q0, d0);
|
||||
FUNC(compute_kG) (Q1, d1);
|
||||
|
||||
/*
|
||||
* Jivsov compliant key check
|
||||
*/
|
||||
return bn256_cmp (Q1[0].y, Q0[0].y);
|
||||
}
|
||||
|
||||
204
src/flash.c
204
src/flash.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "sys.h"
|
||||
#include "gnuk.h"
|
||||
|
||||
@@ -54,31 +53,40 @@
|
||||
* <alignment to page>
|
||||
* ch_certificate_startp
|
||||
* <2048 bytes>
|
||||
* _data_pool
|
||||
* <two pages>
|
||||
* _keystore_pool
|
||||
* Three flash pages for keystore
|
||||
* a page contains a key data of:
|
||||
* For RSA-2048: 512-byte (p, q and N)
|
||||
* For RSA-4096: 1024-byte (p, q and N)
|
||||
* For ECDSA/ECDH and EdDSA, there are padding after public key
|
||||
* _data_pool
|
||||
* <two pages>
|
||||
*/
|
||||
|
||||
#define FLASH_DATA_POOL_HEADER_SIZE 2
|
||||
#define FLASH_DATA_POOL_SIZE (FLASH_PAGE_SIZE*2)
|
||||
#define FLASH_DATA_POOL_SIZE (flash_page_size*2)
|
||||
|
||||
static uint16_t flash_page_size;
|
||||
static const uint8_t *data_pool;
|
||||
extern uint8_t _keystore_pool;
|
||||
|
||||
static uint8_t *last_p;
|
||||
|
||||
/* The first halfword is generation for the data page (little endian) */
|
||||
const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
||||
0x01, 0x00, 0xff, 0xff
|
||||
0x00, 0x00, 0xff, 0xff
|
||||
};
|
||||
|
||||
/* Linker set this symbol */
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
extern uint8_t *flash_addr_key_storage_start;
|
||||
extern uint8_t *flash_addr_data_storage_start;
|
||||
#define FLASH_ADDR_KEY_STORAGE_START flash_addr_key_storage_start
|
||||
#define FLASH_ADDR_DATA_STORAGE_START flash_addr_data_storage_start
|
||||
#else
|
||||
/* Linker sets these symbols */
|
||||
extern uint8_t _keystore_pool;
|
||||
extern uint8_t _data_pool;
|
||||
#define FLASH_ADDR_KEY_STORAGE_START ((&_keystore_pool))
|
||||
#define FLASH_ADDR_DATA_STORAGE_START ((&_data_pool))
|
||||
#endif
|
||||
|
||||
static int key_available_at (const uint8_t *k, int key_size)
|
||||
{
|
||||
@@ -99,43 +107,91 @@ static int key_available_at (const uint8_t *k, int key_size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
flash_init (void)
|
||||
|
||||
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
|
||||
void
|
||||
flash_do_storage_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
|
||||
{
|
||||
uint16_t gen0, gen1;
|
||||
uint16_t *gen0_p = (uint16_t *)&_data_pool;
|
||||
uint16_t *gen1_p = (uint16_t *)(&_data_pool + FLASH_PAGE_SIZE);
|
||||
uint16_t *gen0_p = (uint16_t *)FLASH_ADDR_DATA_STORAGE_START;
|
||||
uint16_t *gen1_p;
|
||||
|
||||
flash_page_size = 1024;
|
||||
#if !defined (GNU_LINUX_EMULATION)
|
||||
if (((*CHIP_ID_REG) & 0xfff) == 0x0414)
|
||||
flash_page_size = 2048;
|
||||
#endif
|
||||
|
||||
gen1_p = (uint16_t *)(FLASH_ADDR_DATA_STORAGE_START + flash_page_size);
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START;
|
||||
|
||||
/* Check data pool generation and choose the page */
|
||||
gen0 = *gen0_p;
|
||||
gen1 = *gen1_p;
|
||||
if (gen0 == 0xffff)
|
||||
data_pool = &_data_pool + FLASH_PAGE_SIZE;
|
||||
else if (gen1 == 0xffff)
|
||||
data_pool = &_data_pool;
|
||||
else if (gen1 > gen0)
|
||||
data_pool = &_data_pool + FLASH_PAGE_SIZE;
|
||||
else
|
||||
data_pool = &_data_pool;
|
||||
|
||||
return data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
if (gen0 == 0xffff && gen1 == 0xffff)
|
||||
{
|
||||
/* It's terminated. */
|
||||
*p_do_start = *p_do_end = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gen0 == 0xffff)
|
||||
/* Use another page if a page is erased. */
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
else if (gen1 == 0xffff)
|
||||
/* Or use different page if another page is erased. */
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START;
|
||||
else if ((gen0 == 0xfffe && gen1 == 0) || gen1 > gen0)
|
||||
/* When both pages have valid header, use newer page. */
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
|
||||
*p_do_start = data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
*p_do_end = data_pool + flash_page_size;
|
||||
}
|
||||
|
||||
static uint8_t *flash_key_getpage (enum kind_of_key kk);
|
||||
|
||||
void
|
||||
flash_terminate (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
flash_erase_page ((uintptr_t)flash_key_getpage (i));
|
||||
flash_erase_page ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START);
|
||||
flash_erase_page ((uintptr_t)(FLASH_ADDR_DATA_STORAGE_START + flash_page_size));
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START;
|
||||
last_p = FLASH_ADDR_DATA_STORAGE_START + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
flash_erase_page ((uintptr_t)&ch_certificate_start);
|
||||
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
|
||||
flash_erase_page ((uintptr_t)(&ch_certificate_start + flash_page_size));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
flash_init_keys (void)
|
||||
flash_activate (void)
|
||||
{
|
||||
flash_program_halfword ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flash_key_storage_init (void)
|
||||
{
|
||||
const uint8_t *p;
|
||||
int i;
|
||||
|
||||
/* For each key, find its address. */
|
||||
p = &_keystore_pool;
|
||||
p = FLASH_ADDR_KEY_STORAGE_START;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
const uint8_t *k;
|
||||
int key_size = gpg_get_algo_attr_key_size (i, GPG_KEY_STORAGE);
|
||||
|
||||
kd[i].pubkey = NULL;
|
||||
for (k = p; k < p + FLASH_PAGE_SIZE; k += key_size)
|
||||
for (k = p; k < p + flash_page_size; k += key_size)
|
||||
if (key_available_at (k, key_size))
|
||||
{
|
||||
int prv_len = gpg_get_algo_attr_key_size (i, GPG_KEY_PRIVATE);
|
||||
@@ -144,7 +200,7 @@ flash_init_keys (void)
|
||||
break;
|
||||
}
|
||||
|
||||
p += FLASH_PAGE_SIZE;
|
||||
p += flash_page_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,29 +242,33 @@ flash_copying_gc (void)
|
||||
uint8_t *src, *dst;
|
||||
uint16_t generation;
|
||||
|
||||
if (data_pool == &_data_pool)
|
||||
if (data_pool == FLASH_ADDR_DATA_STORAGE_START)
|
||||
{
|
||||
src = &_data_pool;
|
||||
dst = &_data_pool + FLASH_PAGE_SIZE;
|
||||
src = FLASH_ADDR_DATA_STORAGE_START;
|
||||
dst = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
src = &_data_pool + FLASH_PAGE_SIZE;
|
||||
dst = &_data_pool;
|
||||
src = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
dst = FLASH_ADDR_DATA_STORAGE_START;
|
||||
}
|
||||
|
||||
generation = *(uint16_t *)src;
|
||||
data_pool = dst;
|
||||
gpg_data_copy (data_pool + FLASH_DATA_POOL_HEADER_SIZE);
|
||||
flash_erase_page ((uint32_t)src);
|
||||
flash_program_halfword ((uint32_t)dst, generation+1);
|
||||
if (generation == 0xfffe)
|
||||
generation = 0;
|
||||
else
|
||||
generation++;
|
||||
flash_program_halfword ((uintptr_t)dst, generation);
|
||||
flash_erase_page ((uintptr_t)src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
is_data_pool_full (size_t size)
|
||||
{
|
||||
return last_p + size > data_pool + FLASH_PAGE_SIZE;
|
||||
return last_p + size > data_pool + flash_page_size;
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
@@ -231,10 +291,10 @@ void
|
||||
flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len)
|
||||
{
|
||||
uint16_t hw;
|
||||
uint32_t addr;
|
||||
uintptr_t addr;
|
||||
int i;
|
||||
|
||||
addr = (uint32_t)p;
|
||||
addr = (uintptr_t)p;
|
||||
hw = nr | (len << 8);
|
||||
if (flash_program_halfword (addr, hw) != 0)
|
||||
flash_warning ("DO WRITE ERROR");
|
||||
@@ -287,13 +347,14 @@ flash_warning (const char *msg)
|
||||
void
|
||||
flash_do_release (const uint8_t *do_data)
|
||||
{
|
||||
uint32_t addr = (uint32_t)do_data - 1;
|
||||
uint32_t addr_tag = addr;
|
||||
uintptr_t addr = (uintptr_t)do_data - 1;
|
||||
uintptr_t addr_tag = addr;
|
||||
int i;
|
||||
int len = do_data[0];
|
||||
|
||||
/* Don't filling zero for data in code (such as ds_count_initial_value) */
|
||||
if (do_data < &_data_pool || do_data > &_data_pool + FLASH_DATA_POOL_SIZE)
|
||||
if (do_data < FLASH_ADDR_DATA_STORAGE_START
|
||||
|| do_data > FLASH_ADDR_DATA_STORAGE_START + FLASH_DATA_POOL_SIZE)
|
||||
return;
|
||||
|
||||
addr += 2;
|
||||
@@ -322,18 +383,18 @@ static uint8_t *
|
||||
flash_key_getpage (enum kind_of_key kk)
|
||||
{
|
||||
/* There is a page for each KK. */
|
||||
return &_keystore_pool + (FLASH_PAGE_SIZE * kk);
|
||||
return FLASH_ADDR_KEY_STORAGE_START + (flash_page_size * kk);
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
flash_key_alloc (enum kind_of_key kk)
|
||||
{
|
||||
uint8_t *k, *k0 = flash_key_getpage (kk);
|
||||
int i;
|
||||
int i;
|
||||
int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
|
||||
|
||||
/* Seek free space in the page. */
|
||||
for (k = k0; k < k0 + FLASH_PAGE_SIZE; k += key_size)
|
||||
for (k = k0; k < k0 + flash_page_size; k += key_size)
|
||||
{
|
||||
const uint32_t *p = (const uint32_t *)k;
|
||||
|
||||
@@ -356,10 +417,10 @@ flash_key_write (uint8_t *key_addr,
|
||||
const uint8_t *pubkey, int pubkey_len)
|
||||
{
|
||||
uint16_t hw;
|
||||
uint32_t addr;
|
||||
uintptr_t addr;
|
||||
int i;
|
||||
|
||||
addr = (uint32_t)key_addr;
|
||||
addr = (uintptr_t)key_addr;
|
||||
for (i = 0; i < key_data_len/2; i ++)
|
||||
{
|
||||
hw = key_data[i*2] | (key_data[i*2+1]<<8);
|
||||
@@ -382,10 +443,10 @@ flash_key_write (uint8_t *key_addr,
|
||||
static int
|
||||
flash_check_all_other_keys_released (const uint8_t *key_addr, int key_size)
|
||||
{
|
||||
uint32_t start = (uint32_t)key_addr & ~(FLASH_PAGE_SIZE - 1);
|
||||
uintptr_t start = (uintptr_t)key_addr & ~(flash_page_size - 1);
|
||||
const uint32_t *p = (const uint32_t *)start;
|
||||
|
||||
while (p < (const uint32_t *)(start + FLASH_PAGE_SIZE))
|
||||
while (p < (const uint32_t *)(start + flash_page_size))
|
||||
if (p == (const uint32_t *)key_addr)
|
||||
p += key_size/4;
|
||||
else
|
||||
@@ -401,7 +462,7 @@ static void
|
||||
flash_key_fill_zero_as_released (uint8_t *key_addr, int key_size)
|
||||
{
|
||||
int i;
|
||||
uint32_t addr = (uint32_t)key_addr;
|
||||
uintptr_t addr = (uintptr_t)key_addr;
|
||||
|
||||
for (i = 0; i < key_size/2; i++)
|
||||
flash_program_halfword (addr + i*2, 0);
|
||||
@@ -411,7 +472,7 @@ void
|
||||
flash_key_release (uint8_t *key_addr, int key_size)
|
||||
{
|
||||
if (flash_check_all_other_keys_released (key_addr, key_size))
|
||||
flash_erase_page (((uint32_t)key_addr & ~(FLASH_PAGE_SIZE - 1)));
|
||||
flash_erase_page (((uintptr_t)key_addr & ~(flash_page_size - 1)));
|
||||
else
|
||||
flash_key_fill_zero_as_released (key_addr, key_size);
|
||||
}
|
||||
@@ -419,12 +480,12 @@ flash_key_release (uint8_t *key_addr, int key_size)
|
||||
void
|
||||
flash_key_release_page (enum kind_of_key kk)
|
||||
{
|
||||
flash_erase_page ((uint32_t)flash_key_getpage (kk));
|
||||
flash_erase_page ((uintptr_t)flash_key_getpage (kk));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flash_clear_halfword (uint32_t addr)
|
||||
flash_clear_halfword (uintptr_t addr)
|
||||
{
|
||||
flash_program_halfword (addr, 0);
|
||||
}
|
||||
@@ -433,7 +494,7 @@ flash_clear_halfword (uint32_t addr)
|
||||
void
|
||||
flash_put_data_internal (const uint8_t *p, uint16_t hw)
|
||||
{
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -447,7 +508,7 @@ flash_put_data (uint16_t hw)
|
||||
DEBUG_INFO ("data allocation failure.\r\n");
|
||||
}
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
|
||||
|
||||
@@ -459,14 +520,14 @@ flash_bool_clear (const uint8_t **addr_p)
|
||||
if ((p = *addr_p) == NULL)
|
||||
return;
|
||||
|
||||
flash_program_halfword ((uint32_t)p, 0);
|
||||
flash_program_halfword ((uintptr_t)p, 0);
|
||||
*addr_p = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
flash_bool_write_internal (const uint8_t *p, int nr)
|
||||
{
|
||||
flash_program_halfword ((uint32_t)p, nr);
|
||||
flash_program_halfword ((uintptr_t)p, nr);
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
@@ -482,7 +543,7 @@ flash_bool_write (uint8_t nr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -498,7 +559,7 @@ flash_enum_write_internal (const uint8_t *p, int nr, uint8_t v)
|
||||
{
|
||||
uint16_t hw = nr | (v << 8);
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
@@ -514,7 +575,7 @@ flash_enum_write (uint8_t nr, uint8_t v)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -550,14 +611,14 @@ flash_cnt123_write_internal (const uint8_t *p, int which, int v)
|
||||
uint16_t hw;
|
||||
|
||||
hw = NR_COUNTER_123 | (which << 8);
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
|
||||
if (v == 1)
|
||||
return;
|
||||
else if (v == 2)
|
||||
flash_program_halfword ((uint32_t)p+2, 0xc3c3);
|
||||
flash_program_halfword ((uintptr_t)p+2, 0xc3c3);
|
||||
else /* v == 3 */
|
||||
flash_program_halfword ((uint32_t)p+2, 0);
|
||||
flash_program_halfword ((uintptr_t)p+2, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -575,7 +636,7 @@ flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
|
||||
return;
|
||||
}
|
||||
hw = NR_COUNTER_123 | (which << 8);
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
*addr_p = p + 2;
|
||||
}
|
||||
else
|
||||
@@ -590,7 +651,7 @@ flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
|
||||
else
|
||||
hw = 0;
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,9 +663,9 @@ flash_cnt123_clear (const uint8_t **addr_p)
|
||||
if ((p = *addr_p) == NULL)
|
||||
return;
|
||||
|
||||
flash_program_halfword ((uint32_t)p, 0);
|
||||
flash_program_halfword ((uintptr_t)p, 0);
|
||||
p -= 2;
|
||||
flash_program_halfword ((uint32_t)p, 0);
|
||||
flash_program_halfword ((uintptr_t)p, 0);
|
||||
*addr_p = NULL;
|
||||
}
|
||||
|
||||
@@ -618,10 +679,9 @@ flash_erase_binary (uint8_t file_id)
|
||||
const uint8_t *p = &ch_certificate_start;
|
||||
if (flash_check_blank (p, FLASH_CH_CERTIFICATE_SIZE) == 0)
|
||||
{
|
||||
flash_erase_page ((uint32_t)p);
|
||||
#if FLASH_CH_CERTIFICATE_SIZE > FLASH_PAGE_SIZE
|
||||
flash_erase_page ((uint32_t)p + FLASH_PAGE_SIZE);
|
||||
#endif
|
||||
flash_erase_page ((uintptr_t)p);
|
||||
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
|
||||
flash_erase_page ((uintptr_t)p + flash_page_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -644,17 +704,19 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
maxsize = 6;
|
||||
p = &openpgpcard_aid[8];
|
||||
}
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
{
|
||||
maxsize = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
|
||||
if (len == 0 && offset == 0)
|
||||
{ /* This means removal of update key. */
|
||||
if (flash_program_halfword ((uint32_t)p, 0) != 0)
|
||||
if (flash_program_halfword ((uintptr_t)p, 0) != 0)
|
||||
flash_warning ("DO WRITE ERROR");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
else if (file_id == FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
@@ -670,13 +732,13 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
else
|
||||
{
|
||||
uint16_t hw;
|
||||
uint32_t addr;
|
||||
uintptr_t addr;
|
||||
int i;
|
||||
|
||||
if (flash_check_blank (p + offset, len) == 0)
|
||||
return -1;
|
||||
|
||||
addr = (uint32_t)p + offset;
|
||||
addr = (uintptr_t)p + offset;
|
||||
for (i = 0; i < len/2; i++)
|
||||
{
|
||||
hw = data[i*2] | (data[i*2+1]<<8);
|
||||
|
||||
16
src/gnuk-malloc.h
Normal file
16
src/gnuk-malloc.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Gnuk uses its own malloc functions.
|
||||
*
|
||||
* The intention is no-dependency to C library. But, we provide
|
||||
* malloc and free here, since RSA routines uses malloc/free
|
||||
* internally.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h> /* NULL and size_t */
|
||||
|
||||
#define malloc(size) gnuk_malloc (size)
|
||||
#define free(p) gnuk_free (p)
|
||||
|
||||
void *gnuk_malloc (size_t);
|
||||
void gnuk_free (void *);
|
||||
101
src/gnuk.h
101
src/gnuk.h
@@ -12,8 +12,8 @@ struct apdu {
|
||||
|
||||
/* response APDU */
|
||||
uint16_t sw;
|
||||
uint8_t *res_apdu_data;
|
||||
uint16_t res_apdu_data_len;
|
||||
uint8_t *res_apdu_data;
|
||||
};
|
||||
|
||||
extern struct apdu apdu;
|
||||
@@ -22,26 +22,29 @@ extern struct apdu apdu;
|
||||
#define CARD_CHANGE_REMOVE 1
|
||||
#define CARD_CHANGE_TOGGLE 2
|
||||
void ccid_card_change_signal (int how);
|
||||
void ccid_usb_reset (int);
|
||||
|
||||
/* CCID thread */
|
||||
#define EV_RX_DATA_READY (1) /* USB Rx data available */
|
||||
#define EV_EXEC_FINISHED (2) /* OpenPGP Execution finished */
|
||||
#define EV_TX_FINISHED (4) /* CCID Tx finished */
|
||||
#define EV_CARD_CHANGE (8)
|
||||
#define EV_RX_DATA_READY 1 /* USB Rx data available */
|
||||
#define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */
|
||||
#define EV_TX_FINISHED 4 /* CCID Tx finished */
|
||||
#define EV_CARD_CHANGE 8
|
||||
#define EV_USB_SET_INTERFACE 16
|
||||
#define EV_USB_DEVICE_RESET 32
|
||||
|
||||
/* OpenPGPcard thread */
|
||||
#define EV_PINPAD_INPUT_DONE (1)
|
||||
#define EV_EXIT (2)
|
||||
#define EV_CMD_AVAILABLE (4)
|
||||
#define EV_VERIFY_CMD_AVAILABLE (8)
|
||||
#define EV_MODIFY_CMD_AVAILABLE (16)
|
||||
#define EV_PINPAD_INPUT_DONE 1
|
||||
#define EV_EXIT 2
|
||||
#define EV_CMD_AVAILABLE 4
|
||||
#define EV_VERIFY_CMD_AVAILABLE 8
|
||||
#define EV_MODIFY_CMD_AVAILABLE 16
|
||||
|
||||
/* Maximum cmd apdu data is key import 24+4+256+256 (proc_key_import) */
|
||||
#define MAX_CMD_APDU_DATA_SIZE (24+4+256+256) /* without header */
|
||||
/* 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 ICC_MSG_HEADER_SIZE 10
|
||||
#define CCID_MSG_HEADER_SIZE 10
|
||||
|
||||
#define res_APDU apdu.res_apdu_data
|
||||
#define res_APDU_size apdu.res_apdu_data_len
|
||||
@@ -49,20 +52,21 @@ void ccid_card_change_signal (int how);
|
||||
/* USB buffer size of LL (Low-level): size of single Bulk transaction */
|
||||
#define USB_LL_BUF_SIZE 64
|
||||
|
||||
enum icc_state {
|
||||
ICC_STATE_NOCARD, /* No card available */
|
||||
ICC_STATE_START, /* Initial */
|
||||
ICC_STATE_WAIT, /* Waiting APDU */
|
||||
enum ccid_state {
|
||||
CCID_STATE_NOCARD, /* No card available */
|
||||
CCID_STATE_START, /* Initial */
|
||||
CCID_STATE_WAIT, /* Waiting APDU */
|
||||
/* Busy1, Busy2, Busy3, Busy5 */
|
||||
ICC_STATE_EXECUTE, /* Busy4 */
|
||||
ICC_STATE_RECEIVE, /* APDU Received Partially */
|
||||
ICC_STATE_SEND, /* APDU Sent Partially */
|
||||
CCID_STATE_EXECUTE, /* Busy4 */
|
||||
CCID_STATE_RECEIVE, /* APDU Received Partially */
|
||||
CCID_STATE_SEND, /* APDU Sent Partially */
|
||||
|
||||
ICC_STATE_EXITED, /* ICC Thread Terminated */
|
||||
ICC_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||
CCID_STATE_EXITED, /* ICC Thread Terminated */
|
||||
CCID_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||
};
|
||||
|
||||
extern enum icc_state *icc_state_p;
|
||||
|
||||
extern enum ccid_state *const ccid_state_p;
|
||||
|
||||
extern volatile uint8_t auth_status;
|
||||
#define AC_NONE_AUTHORIZED 0x00
|
||||
@@ -96,16 +100,19 @@ void ac_fini (void);
|
||||
|
||||
|
||||
void set_res_sw (uint8_t sw1, uint8_t sw2);
|
||||
extern uint8_t file_selection;
|
||||
extern const uint8_t historical_bytes[];
|
||||
extern uint16_t data_objects_number_of_bytes;
|
||||
|
||||
#define CHALLENGE_LEN 32
|
||||
|
||||
void gpg_data_scan (const uint8_t *p);
|
||||
void gpg_data_scan (const uint8_t *start, const uint8_t *end);
|
||||
void gpg_data_copy (const uint8_t *p);
|
||||
void gpg_do_terminate (void);
|
||||
void gpg_do_get_data (uint16_t tag, int with_tag);
|
||||
void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
|
||||
void gpg_do_public_key (uint8_t kk_byte);
|
||||
void gpg_do_keygen (uint8_t kk_byte);
|
||||
void gpg_do_keygen (uint8_t *buf);
|
||||
|
||||
const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
|
||||
|
||||
@@ -114,6 +121,7 @@ const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
|
||||
#define ALGO_NISTP256R1 1
|
||||
#define ALGO_SECP256K1 2
|
||||
#define ALGO_ED25519 3
|
||||
#define ALGO_CURVE25519 4
|
||||
#define ALGO_RSA2K 255
|
||||
|
||||
enum kind_of_key {
|
||||
@@ -131,8 +139,10 @@ enum size_of_key {
|
||||
int gpg_get_algo_attr (enum kind_of_key kk);
|
||||
int gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s);
|
||||
|
||||
const uint8_t *flash_init (void);
|
||||
void flash_init_keys (void);
|
||||
void flash_do_storage_init (const uint8_t **, const uint8_t **);
|
||||
void flash_terminate (void);
|
||||
void flash_activate (void);
|
||||
void flash_key_storage_init (void);
|
||||
void flash_do_release (const uint8_t *);
|
||||
const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
|
||||
uint8_t *flash_key_alloc (enum kind_of_key);
|
||||
@@ -142,7 +152,7 @@ int flash_key_write (uint8_t *key_addr,
|
||||
const uint8_t *key_data, int key_data_len,
|
||||
const uint8_t *pubkey, int pubkey_len);
|
||||
void flash_set_data_pool_last (const uint8_t *p);
|
||||
void flash_clear_halfword (uint32_t addr);
|
||||
void flash_clear_halfword (uintptr_t addr);
|
||||
void flash_increment_counter (uint8_t counter_tag_nr);
|
||||
void flash_reset_counter (uint8_t counter_tag_nr);
|
||||
|
||||
@@ -160,7 +170,6 @@ int flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
|
||||
/* Linker set these two symbols */
|
||||
extern uint8_t ch_certificate_start;
|
||||
extern uint8_t random_bits_start;
|
||||
|
||||
#define FIRMWARE_UPDATE_KEY_CONTENT_LEN 256 /* RSA-2048 (p and q) */
|
||||
|
||||
@@ -229,6 +238,7 @@ int gpg_change_keystring (int who_old, const uint8_t *old_ks,
|
||||
extern struct key_data kd[3];
|
||||
|
||||
#ifdef DEBUG
|
||||
void stdout_init (void);
|
||||
#define DEBUG_MORE 1
|
||||
/*
|
||||
* Debug functions in debug.c
|
||||
@@ -255,27 +265,33 @@ void put_binary (const char *s, int len);
|
||||
#endif
|
||||
|
||||
int rsa_sign (const uint8_t *, uint8_t *, int, struct key_data *, int);
|
||||
uint8_t *modulus_calc (const uint8_t *, int);
|
||||
int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *);
|
||||
int modulus_calc (const uint8_t *, int, uint8_t *);
|
||||
int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *,
|
||||
unsigned int *);
|
||||
int rsa_verify (const uint8_t *, int, const uint8_t *, const uint8_t *);
|
||||
uint8_t *rsa_genkey (int);
|
||||
int rsa_genkey (int, uint8_t *, uint8_t *);
|
||||
|
||||
int ecdsa_sign_p256r1 (const uint8_t *hash, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
uint8_t *ecc_compute_public_p256r1 (const uint8_t *key_data);
|
||||
int ecc_compute_public_p256r1 (const uint8_t *key_data, uint8_t *);
|
||||
int ecc_check_secret_p256r1 (const uint8_t *d0, uint8_t *d1);
|
||||
int ecdh_decrypt_p256r1 (const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
|
||||
int ecdsa_sign_p256k1 (const uint8_t *hash, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
uint8_t *ecc_compute_public_p256k1 (const uint8_t *key_data);
|
||||
int ecc_compute_public_p256k1 (const uint8_t *key_data, uint8_t *);
|
||||
int ecc_check_secret_p256k1 (const uint8_t *d0, uint8_t *d1);
|
||||
int ecdh_decrypt_p256k1 (const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
|
||||
int eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *output,
|
||||
const uint8_t *sk_a, const uint8_t *seed,
|
||||
const uint8_t *pk);
|
||||
uint8_t *eddsa_compute_public_25519 (const uint8_t *a);
|
||||
void eddsa_compute_public_25519 (const uint8_t *a, uint8_t *);
|
||||
void ecdh_compute_public_25519 (const uint8_t *a, uint8_t *);
|
||||
int ecdh_decrypt_curve25519 (const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
|
||||
const uint8_t *gpg_do_read_simple (uint8_t);
|
||||
void gpg_do_write_simple (uint8_t, const uint8_t *, int);
|
||||
@@ -285,6 +301,7 @@ void gpg_increment_digital_signature_counter (void);
|
||||
void fatal (uint8_t code) __attribute__ ((noreturn));
|
||||
#define FATAL_FLASH 1
|
||||
#define FATAL_RANDOM 2
|
||||
#define FATAL_HEAP 3
|
||||
|
||||
extern uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
|
||||
extern uint8_t admin_authorized;
|
||||
@@ -406,14 +423,16 @@ void flash_cnt123_write_internal (const uint8_t *p, int which, int v);
|
||||
void flash_do_write_internal (const uint8_t *p, int nr,
|
||||
const uint8_t *data, int len);
|
||||
|
||||
extern const uint8_t gnukStringSerial[];
|
||||
extern const uint8_t gnuk_string_serial[];
|
||||
|
||||
#define LED_ONESHOT (1)
|
||||
#define LED_TWOSHOTS (2)
|
||||
#define LED_SHOW_STATUS (4)
|
||||
#define LED_START_COMMAND (8)
|
||||
#define LED_FINISH_COMMAND (16)
|
||||
#define LED_FATAL (32)
|
||||
#define LED_ONESHOT 1
|
||||
#define LED_TWOSHOTS 2
|
||||
#define LED_SHOW_STATUS 4
|
||||
#define LED_FATAL 8
|
||||
#define LED_SYNC 16
|
||||
#define LED_GNUK_EXEC 32
|
||||
#define LED_START_COMMAND 64
|
||||
#define LED_FINISH_COMMAND 128
|
||||
void led_blink (int spec);
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
@@ -441,3 +460,5 @@ int pinpad_getline (int msg_code, uint32_t timeout_usec);
|
||||
#endif
|
||||
|
||||
extern uint8_t _regnual_start, __heap_end__[];
|
||||
|
||||
uint8_t * sram_address (uint32_t offset);
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
/*
|
||||
* ST32F103 memory setup.
|
||||
*/
|
||||
__main_stack_size__ = 0x0100; /* Exception handlers */
|
||||
__process0_stack_size__ = 0x0100; /* main */
|
||||
__process1_stack_size__ = 0x0140; /* ccid */
|
||||
__process2_stack_size__ = 0x0180; /* rng */
|
||||
__process3_stack_size__ = 0x1600; /* gpg */
|
||||
__process4_stack_size__ = 0x0100; /* intr: usb */
|
||||
__process5_stack_size__ = @MSC_SIZE@; /* msc */
|
||||
__process6_stack_size__ = @TIM_SIZE@; /* intr: timer */
|
||||
__process7_stack_size__ = @EXT_SIZE@; /* intr: ext */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash0 : org = @ORIGIN@, len = 4k
|
||||
@@ -18,10 +8,6 @@ MEMORY
|
||||
ram : org = 0x20000000, len = @MEMORY_SIZE@k
|
||||
}
|
||||
|
||||
/* __flash_start__: flash ROM start address regardless of DFU_SUPPORT */
|
||||
__flash_start__ = 0x08001000;
|
||||
__flash_end__ = ORIGIN(flash) + LENGTH(flash);
|
||||
|
||||
__ram_start__ = ORIGIN(ram);
|
||||
__ram_size__ = LENGTH(ram);
|
||||
__ram_end__ = __ram_start__ + __ram_size__;
|
||||
@@ -32,18 +18,20 @@ SECTIONS
|
||||
|
||||
.sys : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
_sys = .;
|
||||
KEEP(*(.vectors))
|
||||
. = ALIGN(16);
|
||||
*(.sys.version)
|
||||
build/sys.o(.text)
|
||||
build/sys.o(.text.*)
|
||||
build/sys.o(.rodata)
|
||||
build/sys.o(.rodata.*)
|
||||
. = ALIGN(1024);
|
||||
*(.sys.0)
|
||||
*(.sys.1)
|
||||
*(.sys.2)
|
||||
_sys = .;
|
||||
KEEP(*(.vectors))
|
||||
. = ALIGN(16);
|
||||
KEEP(*(.sys.version))
|
||||
KEEP(*(.sys.board_id))
|
||||
KEEP(*(.sys.board_name))
|
||||
build/sys-*.o(.text)
|
||||
build/sys-*.o(.text.*)
|
||||
build/sys-*.o(.rodata)
|
||||
build/sys-*.o(.rodata.*)
|
||||
. = ALIGN(1024);
|
||||
*(.sys.0)
|
||||
*(.sys.1)
|
||||
*(.sys.2)
|
||||
} > flash0
|
||||
|
||||
_text = .;
|
||||
@@ -64,6 +52,7 @@ SECTIONS
|
||||
*(.glue_7t)
|
||||
*(.glue_7)
|
||||
*(.gcc*)
|
||||
. = ALIGN(8);
|
||||
} > flash
|
||||
|
||||
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)} > flash
|
||||
@@ -83,45 +72,18 @@ SECTIONS
|
||||
_etext = .;
|
||||
_textdata = _etext;
|
||||
|
||||
.stacks :
|
||||
.stacks (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__main_stack_base__ = .;
|
||||
. += __main_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__main_stack_end__ = .;
|
||||
__process0_stack_base__ = .;
|
||||
. += __process0_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process0_stack_end__ = .;
|
||||
__process1_stack_base__ = .;
|
||||
. += __process1_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process1_stack_end__ = .;
|
||||
__process2_stack_base__ = .;
|
||||
. += __process2_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process2_stack_end__ = .;
|
||||
__process3_stack_base__ = .;
|
||||
. += __process3_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process3_stack_end__ = .;
|
||||
__process4_stack_base__ = .;
|
||||
. += __process4_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process4_stack_end__ = .;
|
||||
__process5_stack_base__ = .;
|
||||
. += __process5_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process5_stack_end__ = .;
|
||||
__process6_stack_base__ = .;
|
||||
. += __process6_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process6_stack_end__ = .;
|
||||
__process7_stack_base__ = .;
|
||||
. += __process7_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process7_stack_end__ = .;
|
||||
*(.main_stack)
|
||||
*(.process_stack.0)
|
||||
*(.process_stack.1)
|
||||
*(.process_stack.2)
|
||||
*(.process_stack.3)
|
||||
*(.process_stack.4)
|
||||
*(.process_stack.5)
|
||||
*(.process_stack.6)
|
||||
*(.process_stack.7)
|
||||
. = ALIGN(8);
|
||||
} > ram
|
||||
|
||||
@@ -172,10 +134,6 @@ SECTIONS
|
||||
.gnuk_flash :
|
||||
{
|
||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||
_data_pool = .;
|
||||
KEEP(*(.gnuk_data))
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += @FLASH_PAGE_SIZE@;
|
||||
_keystore_pool = .;
|
||||
. += 512;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
@@ -186,6 +144,10 @@ SECTIONS
|
||||
_updatekey_store = .;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_data_pool = .;
|
||||
KEEP(*(.gnuk_data))
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += @FLASH_PAGE_SIZE@;
|
||||
} > flash =0xffffffff
|
||||
}
|
||||
|
||||
|
||||
394
src/main.c
394
src/main.c
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* main.c - main routine of Gnuk
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -27,7 +28,6 @@
|
||||
#include <eventflag.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "adc.h"
|
||||
@@ -35,98 +35,32 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb-cdc.h"
|
||||
#include "random.h"
|
||||
#include "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);
|
||||
}
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define main emulated_main
|
||||
#else
|
||||
void
|
||||
_write (const char *s, int size)
|
||||
{
|
||||
(void)s;
|
||||
(void)size;
|
||||
}
|
||||
#include "mcu/stm32f103.h"
|
||||
#endif
|
||||
|
||||
extern void *USBthread (void *arg);
|
||||
|
||||
/*
|
||||
* main thread does 1-bit LED display output
|
||||
*/
|
||||
#define MAIN_TIMEOUT_INTERVAL (5000*1000)
|
||||
|
||||
#define LED_TIMEOUT_INTERVAL (75*1000)
|
||||
#define LED_TIMEOUT_ZERO (25*1000)
|
||||
#define LED_TIMEOUT_ONE (100*1000)
|
||||
#define LED_TIMEOUT_STOP (200*1000)
|
||||
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
uint8_t *flash_addr_key_storage_start;
|
||||
uint8_t *flash_addr_data_storage_start;
|
||||
#else
|
||||
#define ID_OFFSET (2+SERIALNO_STR_LEN*2)
|
||||
static void
|
||||
device_initialize_once (void)
|
||||
{
|
||||
const uint8_t *p = &gnukStringSerial[ID_OFFSET];
|
||||
const uint8_t *p = &gnuk_string_serial[ID_OFFSET];
|
||||
|
||||
if (p[0] == 0xff && p[1] == 0xff && p[2] == 0xff && p[3] == 0xff)
|
||||
{
|
||||
@@ -134,12 +68,12 @@ device_initialize_once (void)
|
||||
* This is the first time invocation.
|
||||
* Setup serial number by unique device ID.
|
||||
*/
|
||||
const uint8_t *u = unique_device_id ();
|
||||
const uint8_t *u = unique_device_id () + 8;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
uint8_t b = u[i];
|
||||
uint8_t b = u[3-i];
|
||||
uint8_t nibble;
|
||||
|
||||
nibble = (b >> 4);
|
||||
@@ -151,6 +85,7 @@ device_initialize_once (void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static volatile uint8_t fatal_code;
|
||||
@@ -195,103 +130,82 @@ static void display_fatal_code (void)
|
||||
|
||||
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);
|
||||
m = eventflag_wait_timeout (&led_event, on_time);
|
||||
chopstx_usec_wait (on_time);
|
||||
set_led (led_inverted);
|
||||
if (m) return m;
|
||||
if ((m = eventflag_wait_timeout (&led_event, off_time)))
|
||||
return m;
|
||||
return 0;
|
||||
chopstx_usec_wait (off_time);
|
||||
}
|
||||
|
||||
static eventmask_t display_status_code (void)
|
||||
static void display_status_code (void)
|
||||
{
|
||||
enum icc_state icc_state;
|
||||
eventmask_t m;
|
||||
enum ccid_state ccid_state = *ccid_state_p;
|
||||
|
||||
if (icc_state_p == NULL)
|
||||
icc_state = ICC_STATE_START;
|
||||
if (ccid_state == CCID_STATE_START)
|
||||
emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
||||
else
|
||||
icc_state = *icc_state_p;
|
||||
|
||||
if (icc_state == ICC_STATE_START)
|
||||
return emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
||||
else
|
||||
/* OpenPGP card thread running */
|
||||
/* OpenPGP card thread is running */
|
||||
{
|
||||
if ((m = emit_led ((auth_status & AC_ADMIN_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
||||
LED_TIMEOUT_INTERVAL)))
|
||||
return m;
|
||||
if ((m = emit_led ((auth_status & AC_OTHER_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
||||
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;
|
||||
emit_led ((auth_status & AC_ADMIN_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
emit_led ((auth_status & AC_OTHER_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
emit_led ((auth_status & AC_PSO_CDS_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
|
||||
if (icc_state == ICC_STATE_WAIT)
|
||||
{
|
||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_STOP * 2)))
|
||||
return m;
|
||||
}
|
||||
if (ccid_state == CCID_STATE_WAIT)
|
||||
chopstx_usec_wait (LED_TIMEOUT_STOP * 2);
|
||||
else
|
||||
{
|
||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_INTERVAL)))
|
||||
return m;
|
||||
|
||||
if ((m = emit_led (icc_state == ICC_STATE_RECEIVE?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
||||
LED_TIMEOUT_STOP)))
|
||||
return m;
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
emit_led (ccid_state == CCID_STATE_RECEIVE?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
/*
|
||||
* In Gnuk 1.0.[12], reGNUal was not relocatable.
|
||||
* Now, it's relocatable, but we need to calculate its entry address
|
||||
* based on it's pre-defined address.
|
||||
*/
|
||||
#define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
|
||||
static uint32_t
|
||||
static uintptr_t
|
||||
calculate_regnual_entry_address (const uint8_t *addr)
|
||||
{
|
||||
const uint8_t *p = addr + 4;
|
||||
uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
|
||||
uintptr_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
|
||||
|
||||
v -= REGNUAL_START_ADDRESS_COMPATIBLE;
|
||||
v += (uint32_t)addr;
|
||||
v += (uintptr_t)addr;
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern uint8_t __process1_stack_base__, __process1_stack_size__;
|
||||
extern uint8_t __process4_stack_base__, __process4_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 STACK_MAIN
|
||||
#define STACK_PROCESS_1
|
||||
#include "stack-def.h"
|
||||
#define STACK_ADDR_CCID ((uintptr_t)process1_base)
|
||||
#define STACK_SIZE_CCID (sizeof process1_base)
|
||||
|
||||
#define PRIO_CCID 3
|
||||
#define PRIO_USB 4
|
||||
#define PRIO_MAIN 5
|
||||
|
||||
extern void *usb_intr (void *arg);
|
||||
extern void *ccid_thread (void *arg);
|
||||
|
||||
static void gnuk_malloc_init (void);
|
||||
|
||||
@@ -300,29 +214,100 @@ extern uint32_t bDeviceState;
|
||||
|
||||
/*
|
||||
* Entry point.
|
||||
*
|
||||
* NOTE: the main function is already a thread in the system on entry.
|
||||
* See the hwinit1_common function.
|
||||
*/
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
unsigned int count = 0;
|
||||
uint32_t entry;
|
||||
chopstx_t usb_thd;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
uintptr_t flash_addr;
|
||||
const char *flash_image_path;
|
||||
char *path_string = NULL;
|
||||
#endif
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
uintptr_t entry;
|
||||
#endif
|
||||
chopstx_t ccid_thd;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
gnuk_malloc_init ();
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define FLASH_IMAGE_NAME ".gnuk-flash-image"
|
||||
|
||||
if (argc >= 4 || (argc == 2 && !strcmp (argv[1], "--help")))
|
||||
{
|
||||
fprintf (stdout, "Usage: %s [--vidpid=Vxxx:Pxxx] [flash-image-file]",
|
||||
argv[0]);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (argc >= 2 && !strncmp (argv[1], "--debug=", 8))
|
||||
{
|
||||
debug = strtol (&argv[1][8], NULL, 10);
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc >= 2 && !strncmp (argv[1], "--vidpid=", 9))
|
||||
{
|
||||
extern uint8_t device_desc[];
|
||||
uint32_t id;
|
||||
char *p;
|
||||
|
||||
id = (uint32_t)strtol (&argv[1][9], &p, 16);
|
||||
device_desc[8] = (id & 0xff);
|
||||
device_desc[9] = (id >> 8);
|
||||
|
||||
if (p && p[0] == ':')
|
||||
{
|
||||
id = (uint32_t)strtol (&p[1], NULL, 16);
|
||||
device_desc[10] = (id & 0xff);
|
||||
device_desc[11] = (id >> 8);
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
char *p = getenv ("HOME");
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
fprintf (stderr, "Can't find $HOME\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
path_string = malloc (strlen (p) + strlen (FLASH_IMAGE_NAME) + 2);
|
||||
|
||||
p = stpcpy (path_string, p);
|
||||
*p++ = '/';
|
||||
strcpy (p, FLASH_IMAGE_NAME);
|
||||
flash_image_path = path_string;
|
||||
}
|
||||
else
|
||||
flash_image_path = argv[1];
|
||||
|
||||
flash_addr = flash_init (flash_image_path);
|
||||
flash_addr_key_storage_start = (uint8_t *)flash_addr;
|
||||
flash_addr_data_storage_start = (uint8_t *)flash_addr + 4096;
|
||||
#else
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
#endif
|
||||
|
||||
flash_unlock ();
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
if (path_string)
|
||||
free (path_string);
|
||||
#else
|
||||
device_initialize_once ();
|
||||
#endif
|
||||
|
||||
adc_init ();
|
||||
|
||||
eventflag_init (&led_event, chopstx_main);
|
||||
eventflag_init (&led_event);
|
||||
|
||||
random_init ();
|
||||
|
||||
@@ -330,8 +315,8 @@ main (int argc, char *argv[])
|
||||
stdout_init ();
|
||||
#endif
|
||||
|
||||
ccid_thd = chopstx_create (PRIO_CCID, __stackaddr_ccid,
|
||||
__stacksize_ccid, USBthread, NULL);
|
||||
ccid_thd = chopstx_create (PRIO_CCID, STACK_ADDR_CCID, STACK_SIZE_CCID,
|
||||
ccid_thread, NULL);
|
||||
|
||||
#ifdef PINPAD_CIR_SUPPORT
|
||||
cir_init ();
|
||||
@@ -340,8 +325,7 @@ main (int argc, char *argv[])
|
||||
msc_init ();
|
||||
#endif
|
||||
|
||||
usb_thd = chopstx_create (PRIO_USB, __stackaddr_usb, __stacksize_usb,
|
||||
usb_intr, NULL);
|
||||
chopstx_setpriority (PRIO_MAIN);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -355,56 +339,34 @@ main (int argc, char *argv[])
|
||||
{
|
||||
eventmask_t m;
|
||||
|
||||
if (icc_state_p != NULL && *icc_state_p == ICC_STATE_EXEC_REQUESTED)
|
||||
break;
|
||||
|
||||
m = eventflag_wait_timeout (&led_event, MAIN_TIMEOUT_INTERVAL);
|
||||
got_it:
|
||||
count++;
|
||||
m = eventflag_wait (&led_event);
|
||||
switch (m)
|
||||
{
|
||||
case LED_ONESHOT:
|
||||
if ((m = emit_led (100*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
emit_led (100*1000, LED_TIMEOUT_STOP);
|
||||
break;
|
||||
case LED_TWOSHOTS:
|
||||
if ((m = emit_led (50*1000, 50*1000))) goto got_it;
|
||||
if ((m = emit_led (50*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
emit_led (50*1000, 50*1000);
|
||||
emit_led (50*1000, LED_TIMEOUT_STOP);
|
||||
break;
|
||||
case LED_SHOW_STATUS:
|
||||
if ((count & 0x07) != 0) continue; /* Display once for eight times */
|
||||
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;
|
||||
display_status_code ();
|
||||
break;
|
||||
case LED_FATAL:
|
||||
display_fatal_code ();
|
||||
break;
|
||||
case LED_SYNC:
|
||||
set_led (led_inverted);
|
||||
break;
|
||||
case LED_GNUK_EXEC:
|
||||
goto exec;
|
||||
default:
|
||||
if ((m = emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP)))
|
||||
goto got_it;
|
||||
emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
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:
|
||||
random_fini ();
|
||||
|
||||
set_led (1);
|
||||
@@ -413,24 +375,27 @@ main (int argc, char *argv[])
|
||||
/* Finish application. */
|
||||
chopstx_join (ccid_thd, NULL);
|
||||
|
||||
chopstx_cancel (usb_thd);
|
||||
chopstx_join (usb_thd, NULL);
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
/* Set vector */
|
||||
SCB->VTOR = (uint32_t)&_regnual_start;
|
||||
SCB->VTOR = (uintptr_t)&_regnual_start;
|
||||
entry = calculate_regnual_entry_address (&_regnual_start);
|
||||
#ifdef DFU_SUPPORT
|
||||
#define FLASH_SYS_START_ADDR 0x08000000
|
||||
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
|
||||
#define CHIP_ID_REG ((uint32_t *)0xE0042000)
|
||||
{
|
||||
extern uint8_t _sys;
|
||||
uint32_t addr;
|
||||
uintptr_t addr;
|
||||
handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
|
||||
void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
|
||||
uint32_t flash_page_size = 1024; /* 1KiB default */
|
||||
|
||||
if ((*CHIP_ID_REG)&0x07 == 0x04) /* High dencity device. */
|
||||
flash_page_size = 2048; /* It's 2KiB. */
|
||||
|
||||
/* Kill DFU */
|
||||
for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
|
||||
addr += FLASH_PAGE_SIZE)
|
||||
addr += flash_page_size)
|
||||
flash_erase_page (addr);
|
||||
|
||||
/* copy system service routines */
|
||||
@@ -444,6 +409,9 @@ main (int argc, char *argv[])
|
||||
/* Leave Gnuk to exec reGNUal */
|
||||
flash_erase_all_and_exec ((void (*)(void))entry);
|
||||
#endif
|
||||
#else
|
||||
exit (0);
|
||||
#endif
|
||||
|
||||
/* Never reached */
|
||||
return 0;
|
||||
@@ -452,6 +420,8 @@ main (int argc, char *argv[])
|
||||
void
|
||||
fatal (uint8_t code)
|
||||
{
|
||||
extern void _write (const char *s, int len);
|
||||
|
||||
fatal_code = code;
|
||||
eventflag_signal (&led_event, LED_FATAL);
|
||||
_write ("fatal\r\n", 7);
|
||||
@@ -472,30 +442,46 @@ fatal (uint8_t code)
|
||||
* reclaimed to system.
|
||||
*/
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define MEMORY_SIZE (32*1024)
|
||||
uint8_t __heap_base__[MEMORY_SIZE];
|
||||
|
||||
#define HEAP_START __heap_base__
|
||||
#define MEMORY_END (__heap_base__ + MEMORY_SIZE)
|
||||
#define MEMORY_ALIGNMENT 32
|
||||
#else
|
||||
extern uint8_t __heap_base__[];
|
||||
extern uint8_t __heap_end__[];
|
||||
|
||||
#define HEAP_START __heap_base__
|
||||
#define MEMORY_END (__heap_end__)
|
||||
#define MEMORY_ALIGNMENT 16
|
||||
#define MEMORY_SIZE ((uintptr_t)__heap_end__ - (uintptr_t)__heap_base__)
|
||||
#endif
|
||||
|
||||
#define MEMORY_ALIGN(n) (((n) + MEMORY_ALIGNMENT - 1) & ~(MEMORY_ALIGNMENT - 1))
|
||||
|
||||
static uint8_t *heap_p;
|
||||
static chopstx_mutex_t malloc_mtx;
|
||||
|
||||
struct mem_head {
|
||||
uint32_t size;
|
||||
uintptr_t size;
|
||||
/**/
|
||||
struct mem_head *next, *prev; /* free list chain */
|
||||
struct mem_head *neighbor; /* backlink to neighbor */
|
||||
};
|
||||
|
||||
#define MEM_HEAD_IS_CORRUPT(x) \
|
||||
((x)->size != MEMORY_ALIGN((x)->size) || (x)->size > MEMORY_SIZE)
|
||||
#define MEM_HEAD_CHECK(x) if (MEM_HEAD_IS_CORRUPT(x)) fatal (FATAL_HEAP)
|
||||
|
||||
static struct mem_head *free_list;
|
||||
|
||||
static void
|
||||
gnuk_malloc_init (void)
|
||||
{
|
||||
chopstx_mutex_init (&malloc_mtx);
|
||||
heap_p = __heap_base__;
|
||||
heap_p = HEAP_START;
|
||||
free_list = NULL;
|
||||
}
|
||||
|
||||
@@ -529,7 +515,7 @@ gnuk_malloc (size_t size)
|
||||
struct mem_head *m;
|
||||
struct mem_head *m0;
|
||||
|
||||
size = MEMORY_ALIGN (size + sizeof (uint32_t));
|
||||
size = MEMORY_ALIGN (size + sizeof (uintptr_t));
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
DEBUG_INFO ("malloc: ");
|
||||
@@ -545,7 +531,7 @@ gnuk_malloc (size_t size)
|
||||
m->size = size;
|
||||
break;
|
||||
}
|
||||
|
||||
MEM_HEAD_CHECK (m);
|
||||
if (m->size == size)
|
||||
{
|
||||
remove_from_free_list (m);
|
||||
@@ -569,8 +555,8 @@ gnuk_malloc (size_t size)
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WORD ((uint32_t)m + sizeof (uint32_t));
|
||||
return (void *)m + sizeof (uint32_t);
|
||||
DEBUG_WORD ((uintptr_t)m + sizeof (uintptr_t));
|
||||
return (void *)m + sizeof (uintptr_t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,18 +564,23 @@ gnuk_malloc (size_t size)
|
||||
void
|
||||
gnuk_free (void *p)
|
||||
{
|
||||
struct mem_head *m = (struct mem_head *)((void *)p - sizeof (uint32_t));
|
||||
struct mem_head *m = (struct mem_head *)((void *)p - sizeof (uintptr_t));
|
||||
struct mem_head *m0;
|
||||
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
m0 = free_list;
|
||||
DEBUG_INFO ("free: ");
|
||||
DEBUG_SHORT (m->size);
|
||||
DEBUG_WORD ((uint32_t)p);
|
||||
DEBUG_WORD ((uintptr_t)p);
|
||||
|
||||
MEM_HEAD_CHECK (m);
|
||||
m->neighbor = NULL;
|
||||
while (m0)
|
||||
{
|
||||
MEM_HEAD_CHECK (m0);
|
||||
if ((void *)m + m->size == (void *)m0)
|
||||
m0->neighbor = m;
|
||||
else if ((void *)m0 + m0->size == (void *)m)
|
||||
@@ -605,6 +596,7 @@ gnuk_free (void *p)
|
||||
heap_p -= m->size;
|
||||
while (mn)
|
||||
{
|
||||
MEM_HEAD_CHECK (mn);
|
||||
heap_p -= mn->size;
|
||||
remove_from_free_list (mn);
|
||||
mn = mn->neighbor;
|
||||
|
||||
32
src/mcu-stm32f103.c
Normal file
32
src/mcu-stm32f103.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* mcu-stm32f103.c - STM32F103 specific routines
|
||||
*
|
||||
* Copyright (C) 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
*
|
||||
* Gnuk is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mcu/stm32f103.h"
|
||||
|
||||
uint8_t *
|
||||
sram_address (uint32_t offset)
|
||||
{
|
||||
return ((uint8_t *)0x20000000) + offset;
|
||||
}
|
||||
10
src/mod.c
10
src/mod.c
@@ -27,7 +27,7 @@
|
||||
|
||||
/**
|
||||
* @brief X = A mod B (using MU=(1<<(256)+MU_lower)) (Barret reduction)
|
||||
*
|
||||
*
|
||||
*/
|
||||
void
|
||||
mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
@@ -36,7 +36,6 @@ mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
bn512 q_big[1], tmp[1];
|
||||
uint32_t carry;
|
||||
#define borrow carry
|
||||
uint32_t borrow_next;
|
||||
|
||||
memset (q, 0, sizeof (bn256));
|
||||
q->word[0] = A->word[15];
|
||||
@@ -110,9 +109,7 @@ mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
= tmp->word[11] = tmp->word[10] = tmp->word[9] = 0;
|
||||
|
||||
borrow = bn256_sub (X, (bn256 *)&q_big->word[0], (bn256 *)&tmp->word[0]);
|
||||
borrow_next = (q_big->word[8] < borrow);
|
||||
q_big->word[8] -= borrow;
|
||||
borrow_next += (q_big->word[8] < tmp->word[8]);
|
||||
q_big->word[8] -= tmp->word[8];
|
||||
|
||||
carry = q_big->word[8];
|
||||
@@ -122,7 +119,7 @@ mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
bn256_sub (q, X, B);
|
||||
|
||||
if (carry)
|
||||
carry -= bn256_sub (X, X, B);
|
||||
bn256_sub (X, X, B);
|
||||
else
|
||||
bn256_sub (q, X, B);
|
||||
|
||||
@@ -145,7 +142,7 @@ mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
|
||||
/**
|
||||
* @brief C = X^(-1) mod N
|
||||
*
|
||||
*
|
||||
* Assume X and N are co-prime (or N is prime).
|
||||
* NOTE: If X==0, it return 0.
|
||||
*
|
||||
@@ -159,6 +156,7 @@ mod_inv (bn256 *C, const bn256 *X, const bn256 *N)
|
||||
#define borrow carry
|
||||
int n = MAX_GCD_STEPS_BN256;
|
||||
|
||||
memset (tmp, 0, sizeof (bn256));
|
||||
memset (C, 0, sizeof (bn256));
|
||||
memcpy (u, X, sizeof (bn256));
|
||||
memcpy (v, N, sizeof (bn256));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* It's not always modulo p256k1. The representation is redundant
|
||||
* 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
|
||||
* 256-bit.
|
||||
* It's always modulo p256k1.
|
||||
*
|
||||
* Once, I tried redundant representation which caused wrong
|
||||
* 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
|
||||
modp256k1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t carry;
|
||||
uint32_t cond;
|
||||
bn256 tmp[1];
|
||||
|
||||
carry = bn256_add (X, A, B);
|
||||
if (carry)
|
||||
bn256_sub (X, X, P256K1);
|
||||
cond = (bn256_add (X, A, B) == 0);
|
||||
cond &= bn256_sub (tmp, X, P256K1);
|
||||
if (cond)
|
||||
/* No-carry AND borrow */
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
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];
|
||||
|
||||
borrow = bn256_sub (X, A, B);
|
||||
bn256_add (tmp, X, P256K1);
|
||||
if (borrow)
|
||||
bn256_add (X, X, P256K1);
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
else
|
||||
bn256_add (tmp, X, P256K1);
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,12 +184,12 @@ modp256k1_reduce (bn256 *X, const bn512 *A)
|
||||
*/
|
||||
S->word[7] = S->word[6] = S->word[5] = S->word[4] = S->word[3] = 0;
|
||||
|
||||
/* (S02, S01, S00) = (S1, S0) + (S1, S0)*2^32 */
|
||||
/* (S02, S01, S00) = (S1, S0) + (S1, S0)*2^32 */
|
||||
s00 = s0;
|
||||
s01 = s0 + s1;
|
||||
s02 = s1 + ((s01 < s0)? 1 : 0);
|
||||
|
||||
/* (S02, S01, S00) += (S1, S0)*2^9 */
|
||||
/* (S02, S01, S00) += (S1, S0)*2^9 */
|
||||
carry = (s0 >> 23) + s01;
|
||||
s02 += (s1 >> 23) + ((carry < s01)? 1 : 0);
|
||||
s01 = (s1 << 9) + carry;
|
||||
@@ -196,7 +199,7 @@ modp256k1_reduce (bn256 *X, const bn512 *A)
|
||||
s01 += carry;
|
||||
s02 += ((s01 < carry)? 1 : 0);
|
||||
|
||||
/* (S02, S01, S00) += (S1, S0)*2^8 */
|
||||
/* (S02, S01, S00) += (S1, S0)*2^8 */
|
||||
carry = (s0 >> 24) + s01;
|
||||
s02 += (s1 >> 24) + ((carry < s01)? 1 : 0);
|
||||
s01 = (s1 << 8) + carry;
|
||||
@@ -206,7 +209,7 @@ modp256k1_reduce (bn256 *X, const bn512 *A)
|
||||
s01 += carry;
|
||||
s02 += ((s01 < carry)? 1 : 0);
|
||||
|
||||
/* (S02, S01, S00) += (S1, S0)*2^7 */
|
||||
/* (S02, S01, S00) += (S1, S0)*2^7 */
|
||||
carry = (s0 >> 25) + s01;
|
||||
s02 += (s1 >> 25) + ((carry < s01)? 1 : 0);
|
||||
s01 = (s1 << 7) + carry;
|
||||
@@ -216,7 +219,7 @@ modp256k1_reduce (bn256 *X, const bn512 *A)
|
||||
s01 += carry;
|
||||
s02 += ((s01 < carry)? 1 : 0);
|
||||
|
||||
/* (S02, S01, S00) += (S1, S0)*2^6 */
|
||||
/* (S02, S01, S00) += (S1, S0)*2^6 */
|
||||
carry = (s0 >> 26) + s01;
|
||||
s02 += (s1 >> 26) + ((carry < s01)? 1 : 0);
|
||||
s01 = (s1 << 6) + carry;
|
||||
@@ -226,7 +229,7 @@ modp256k1_reduce (bn256 *X, const bn512 *A)
|
||||
s01 += carry;
|
||||
s02 += ((s01 < carry)? 1 : 0);
|
||||
|
||||
/* (S02, S01, S00) += (S1, S0)*2^4 */
|
||||
/* (S02, S01, S00) += (S1, S0)*2^4 */
|
||||
carry = (s0 >> 28) + s01;
|
||||
s02 += (s1 >> 28) + ((carry < s01)? 1 : 0);
|
||||
s01 = (s1 << 4) + carry;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* 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>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* It's not always modulo p256r1. The representation is redundant
|
||||
* 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
|
||||
* 256-bit.
|
||||
* It's always modulo p256r1.
|
||||
*
|
||||
* Once, I tried redundant representation which caused wrong
|
||||
* 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
|
||||
modp256r1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t carry;
|
||||
uint32_t cond;
|
||||
bn256 tmp[1];
|
||||
|
||||
carry = bn256_add (X, A, B);
|
||||
if (carry)
|
||||
bn256_sub (X, X, P256R1);
|
||||
cond = (bn256_add (X, A, B) == 0);
|
||||
cond &= bn256_sub (tmp, X, P256R1);
|
||||
if (cond)
|
||||
/* No-carry AND borrow */
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
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];
|
||||
|
||||
borrow = bn256_sub (X, A, B);
|
||||
bn256_add (tmp, X, P256R1);
|
||||
if (borrow)
|
||||
bn256_add (X, X, P256R1);
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
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
|
||||
modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
{
|
||||
bn256 tmp[1];
|
||||
bn256 tmp[1], tmp0[1];
|
||||
uint32_t borrow;
|
||||
|
||||
#define S1 X
|
||||
@@ -116,6 +120,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S1->word[2] = A->word[2];
|
||||
S1->word[1] = A->word[1];
|
||||
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 */
|
||||
|
||||
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[1] = A->word[10];
|
||||
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 */
|
||||
modp256r1_add (X, X, S5);
|
||||
|
||||
@@ -164,6 +178,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S6->word[2] = A->word[13];
|
||||
S6->word[1] = A->word[12];
|
||||
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 */
|
||||
modp256r1_sub (X, X, S6);
|
||||
|
||||
@@ -174,6 +193,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S7->word[2] = A->word[14];
|
||||
S7->word[1] = A->word[13];
|
||||
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 */
|
||||
modp256r1_sub (X, X, S7);
|
||||
|
||||
|
||||
201
src/neug.c
201
src/neug.c
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* neug.c - true random number generation
|
||||
*
|
||||
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2012, 2013, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of NeuG, a True Random Number Generator
|
||||
@@ -28,19 +29,125 @@
|
||||
|
||||
#include "sys.h"
|
||||
#include "neug.h"
|
||||
#include "stm32f103.h"
|
||||
#ifndef GNU_LINUX_EMULATION
|
||||
#include "mcu/stm32f103.h"
|
||||
#endif
|
||||
#include "adc.h"
|
||||
#include "sha256.h"
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
static const uint32_t crc32_rv_table[256] = {
|
||||
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
||||
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
|
||||
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
|
||||
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
|
||||
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
|
||||
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
||||
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
|
||||
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
||||
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
|
||||
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
|
||||
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
||||
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
|
||||
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
||||
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
|
||||
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
|
||||
0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
|
||||
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
|
||||
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
||||
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
|
||||
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
||||
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
|
||||
0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
|
||||
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
||||
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
|
||||
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
static uint32_t crc;
|
||||
|
||||
void
|
||||
crc32_rv_reset (void)
|
||||
{
|
||||
crc = 0xffffffff;
|
||||
}
|
||||
|
||||
void
|
||||
crc32_rv_step (uint32_t v)
|
||||
{
|
||||
crc = crc32_rv_table[(crc ^ (v << 0)) >> 24] ^ (crc << 8);
|
||||
crc = crc32_rv_table[(crc ^ (v << 8)) >> 24] ^ (crc << 8);
|
||||
crc = crc32_rv_table[(crc ^ (v << 16)) >> 24] ^ (crc << 8);
|
||||
crc = crc32_rv_table[(crc ^ (v << 24)) >> 24] ^ (crc << 8);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
crc32_rv_get (void)
|
||||
{
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rbit (uint32_t v)
|
||||
{
|
||||
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
|
||||
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
|
||||
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
|
||||
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
|
||||
v = ( v >> 16 ) | ( v << 16);
|
||||
return v;
|
||||
}
|
||||
#else
|
||||
void
|
||||
crc32_rv_reset (void)
|
||||
{
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
}
|
||||
|
||||
void
|
||||
crc32_rv_step (uint32_t v)
|
||||
{
|
||||
CRC->DR = v;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
crc32_rv_get (void)
|
||||
{
|
||||
return CRC->DR;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rbit (uint32_t v)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
static chopstx_mutex_t mode_mtx;
|
||||
static chopstx_cond_t mode_cond;
|
||||
|
||||
/*
|
||||
* ADC finish interrupt
|
||||
*/
|
||||
#define INTR_REQ_DMA1_Channel1 11
|
||||
|
||||
|
||||
static sha256_context sha256_ctx_data;
|
||||
static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
|
||||
|
||||
@@ -99,11 +206,11 @@ static void noise_source_continuous_test_word (uint8_t b0, uint8_t b1,
|
||||
* Then, three-byte from noise source follows.
|
||||
*
|
||||
* One-byte was used in the previous turn, and we have three bytes in
|
||||
* CRC->DR.
|
||||
* CRC32.
|
||||
*/
|
||||
static void ep_fill_initial_string (void)
|
||||
{
|
||||
uint32_t v = CRC->DR;
|
||||
uint32_t v = crc32_rv_get ();
|
||||
uint8_t b1, b2, b3;
|
||||
|
||||
b3 = v >> 24;
|
||||
@@ -169,11 +276,11 @@ static int ep_process (int mode)
|
||||
sha256_ctx_data.wbuf[1] = adc_buf[1];
|
||||
for (i = 0; i < EP_ROUND_0_INPUTS / 4; i++)
|
||||
{
|
||||
CRC->DR = adc_buf[i*4 + 2];
|
||||
CRC->DR = adc_buf[i*4 + 3];
|
||||
CRC->DR = adc_buf[i*4 + 4];
|
||||
CRC->DR = adc_buf[i*4 + 5];
|
||||
v = CRC->DR;
|
||||
crc32_rv_step (adc_buf[i*4 + 2]);
|
||||
crc32_rv_step (adc_buf[i*4 + 3]);
|
||||
crc32_rv_step (adc_buf[i*4 + 4]);
|
||||
crc32_rv_step (adc_buf[i*4 + 5]);
|
||||
v = crc32_rv_get ();
|
||||
ep_fill_wbuf_v (i+2, 1, v);
|
||||
}
|
||||
|
||||
@@ -186,11 +293,11 @@ static int ep_process (int mode)
|
||||
{
|
||||
for (i = 0; i < EP_ROUND_1_INPUTS / 4; i++)
|
||||
{
|
||||
CRC->DR = adc_buf[i*4];
|
||||
CRC->DR = adc_buf[i*4 + 1];
|
||||
CRC->DR = adc_buf[i*4 + 2];
|
||||
CRC->DR = adc_buf[i*4 + 3];
|
||||
v = CRC->DR;
|
||||
crc32_rv_step (adc_buf[i*4]);
|
||||
crc32_rv_step (adc_buf[i*4 + 1]);
|
||||
crc32_rv_step (adc_buf[i*4 + 2]);
|
||||
crc32_rv_step (adc_buf[i*4 + 3]);
|
||||
v = crc32_rv_get ();
|
||||
ep_fill_wbuf_v (i, 1, v);
|
||||
}
|
||||
|
||||
@@ -203,23 +310,23 @@ static int ep_process (int mode)
|
||||
{
|
||||
for (i = 0; i < EP_ROUND_2_INPUTS / 4; i++)
|
||||
{
|
||||
CRC->DR = adc_buf[i*4];
|
||||
CRC->DR = adc_buf[i*4 + 1];
|
||||
CRC->DR = adc_buf[i*4 + 2];
|
||||
CRC->DR = adc_buf[i*4 + 3];
|
||||
v = CRC->DR;
|
||||
crc32_rv_step (adc_buf[i*4]);
|
||||
crc32_rv_step (adc_buf[i*4 + 1]);
|
||||
crc32_rv_step (adc_buf[i*4 + 2]);
|
||||
crc32_rv_step (adc_buf[i*4 + 3]);
|
||||
v = crc32_rv_get ();
|
||||
ep_fill_wbuf_v (i, 1, v);
|
||||
}
|
||||
|
||||
CRC->DR = adc_buf[i*4];
|
||||
CRC->DR = adc_buf[i*4 + 1];
|
||||
CRC->DR = adc_buf[i*4 + 2];
|
||||
CRC->DR = adc_buf[i*4 + 3];
|
||||
v = CRC->DR & 0xff;
|
||||
crc32_rv_step (adc_buf[i*4]);
|
||||
crc32_rv_step (adc_buf[i*4 + 1]);
|
||||
crc32_rv_step (adc_buf[i*4 + 2]);
|
||||
crc32_rv_step (adc_buf[i*4 + 3]);
|
||||
v = crc32_rv_get () & 0xff; /* First byte of CRC32 is used here. */
|
||||
noise_source_continuous_test (v);
|
||||
sha256_ctx_data.wbuf[i] = v;
|
||||
ep_init (NEUG_MODE_CONDITIONED); /* The rest three-byte of
|
||||
CRC->DR is used here. */
|
||||
CRC32 is used here. */
|
||||
n = SHA256_DIGEST_SIZE / 2;
|
||||
memcpy (((uint8_t *)sha256_ctx_data.wbuf) + EP_ROUND_2_INPUTS,
|
||||
sha256_output, n);
|
||||
@@ -231,11 +338,11 @@ static int ep_process (int mode)
|
||||
{
|
||||
for (i = 0; i < EP_ROUND_RAW_INPUTS / 4; i++)
|
||||
{
|
||||
CRC->DR = adc_buf[i*4];
|
||||
CRC->DR = adc_buf[i*4 + 1];
|
||||
CRC->DR = adc_buf[i*4 + 2];
|
||||
CRC->DR = adc_buf[i*4 + 3];
|
||||
v = CRC->DR;
|
||||
crc32_rv_step (adc_buf[i*4]);
|
||||
crc32_rv_step (adc_buf[i*4 + 1]);
|
||||
crc32_rv_step (adc_buf[i*4 + 2]);
|
||||
crc32_rv_step (adc_buf[i*4 + 3]);
|
||||
v = crc32_rv_get ();
|
||||
ep_fill_wbuf_v (i, 1, v);
|
||||
}
|
||||
|
||||
@@ -280,8 +387,6 @@ uint16_t neug_rc_max;
|
||||
uint16_t neug_p64_max;
|
||||
uint16_t neug_p4k_max;
|
||||
|
||||
#include "board.h"
|
||||
|
||||
static void noise_source_cnt_max_reset (void)
|
||||
{
|
||||
neug_err_cnt = neug_err_cnt_rc = neug_err_cnt_p64 = neug_err_cnt_p4k = 0;
|
||||
@@ -576,7 +681,6 @@ static void *
|
||||
rng (void *arg)
|
||||
{
|
||||
struct rng_rb *rb = (struct rng_rb *)arg;
|
||||
chopstx_intr_t adc_intr;
|
||||
int mode = neug_mode;
|
||||
|
||||
rng_should_terminate = 0;
|
||||
@@ -585,7 +689,6 @@ rng (void *arg)
|
||||
|
||||
/* Enable ADCs */
|
||||
adc_start ();
|
||||
chopstx_claim_irq (&adc_intr, INTR_REQ_DMA1_Channel1);
|
||||
|
||||
ep_init (mode);
|
||||
while (!rng_should_terminate)
|
||||
@@ -593,7 +696,7 @@ rng (void *arg)
|
||||
int err;
|
||||
int n;
|
||||
|
||||
err = adc_wait_completion (&adc_intr);
|
||||
err = adc_wait_completion ();
|
||||
|
||||
chopstx_mutex_lock (&mode_mtx);
|
||||
if (err || mode != neug_mode)
|
||||
@@ -643,16 +746,17 @@ rng (void *arg)
|
||||
}
|
||||
|
||||
adc_stop ();
|
||||
chopstx_release_irq (&adc_intr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct rng_rb the_ring_buffer;
|
||||
|
||||
extern uint8_t __process2_stack_base__, __process2_stack_size__;
|
||||
const uint32_t __stackaddr_rng = (uint32_t)&__process2_stack_base__;
|
||||
const size_t __stacksize_rng = (size_t)&__process2_stack_size__;
|
||||
#define STACK_PROCESS_2
|
||||
#include "stack-def.h"
|
||||
#define STACK_ADDR_RNG ((uintptr_t)process2_base)
|
||||
#define STACK_SIZE_RNG (sizeof process2_base)
|
||||
|
||||
#define PRIO_RNG 2
|
||||
|
||||
/**
|
||||
@@ -665,20 +769,19 @@ neug_init (uint32_t *buf, uint8_t size)
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
int i;
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
crc32_rv_reset ();
|
||||
|
||||
/*
|
||||
* This initialization ensures that it generates different sequence
|
||||
* even if all physical conditions are same.
|
||||
*/
|
||||
for (i = 0; i < 3; i++)
|
||||
CRC->DR = *u++;
|
||||
crc32_rv_step (*u++);
|
||||
|
||||
neug_mode = NEUG_MODE_CONDITIONED;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
11
src/neug.h
11
src/neug.h
@@ -3,9 +3,9 @@
|
||||
|
||||
#define NEUG_PRE_LOOP 32
|
||||
|
||||
#define NEUG_MODE_CONDITIONED 0
|
||||
#define NEUG_MODE_RAW 1
|
||||
#define NEUG_MODE_RAW_DATA 2
|
||||
#define NEUG_MODE_CONDITIONED 0 /* Conditioned data. */
|
||||
#define NEUG_MODE_RAW 1 /* CRC-32 filtered sample data. */
|
||||
#define NEUG_MODE_RAW_DATA 2 /* Sample data directly. */
|
||||
|
||||
extern uint8_t neug_mode;
|
||||
extern uint16_t neug_err_cnt;
|
||||
@@ -26,3 +26,8 @@ void neug_fini (void);
|
||||
void neug_mode_select (uint8_t mode);
|
||||
|
||||
int neug_consume_random (void (*proc) (uint32_t, int));
|
||||
|
||||
void crc32_rv_reset (void);
|
||||
void crc32_rv_step (uint32_t v);
|
||||
uint32_t crc32_rv_get (void);
|
||||
uint32_t rbit (uint32_t v);
|
||||
|
||||
474
src/openpgp-do.c
474
src/openpgp-do.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -24,13 +24,12 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sys.h"
|
||||
#include "gnuk.h"
|
||||
#include "openpgp.h"
|
||||
#include "status-code.h"
|
||||
#include "random.h"
|
||||
#include "polarssl/config.h"
|
||||
#include "polarssl/aes.h"
|
||||
@@ -40,7 +39,7 @@
|
||||
#define CLEAN_PAGE_FULL 1
|
||||
#define CLEAN_SINGLE 0
|
||||
static void gpg_do_delete_prvkey (enum kind_of_key kk, int clean_page_full);
|
||||
|
||||
static void gpg_reset_digital_signature_counter (void);
|
||||
|
||||
#define PASSWORD_ERRORS_MAX 3 /* >= errors, it will be locked */
|
||||
static const uint8_t *pw_err_counter_p[3];
|
||||
@@ -90,11 +89,11 @@ uint16_t data_objects_number_of_bytes;
|
||||
|
||||
/*
|
||||
* Compile time vars:
|
||||
* Historical Bytes (template), Extended Capabilities.
|
||||
* Historical Bytes, Extended Capabilities.
|
||||
*/
|
||||
|
||||
/* Historical Bytes (template) */
|
||||
static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
/* Historical Bytes */
|
||||
const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
10,
|
||||
0x00,
|
||||
0x31, 0x84, /* Full DF name, GET DATA, MF */
|
||||
@@ -102,7 +101,12 @@ static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
0x80, 0x01, 0x80, /* Full DF name */
|
||||
/* 1-byte */
|
||||
/* Command chaining, No extended Lc and Le */
|
||||
0x00, 0x90, 0x00 /* Status info (no life cycle management) */
|
||||
#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
|
||||
0x05,
|
||||
#else
|
||||
0x00,
|
||||
#endif
|
||||
0x90, 0x00 /* Status info */
|
||||
};
|
||||
|
||||
/* Extended Capabilities */
|
||||
@@ -170,6 +174,13 @@ static const uint8_t algorithm_attr_ed25519[] __attribute__ ((aligned (1))) = {
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01
|
||||
};
|
||||
|
||||
static const uint8_t algorithm_attr_cv25519[] __attribute__ ((aligned (1))) = {
|
||||
11,
|
||||
OPENPGP_ALGO_ECDH,
|
||||
/* OID of the curve Curve25519 */
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Representation of PW1_LIFETIME:
|
||||
@@ -194,7 +205,7 @@ gpg_get_pw1_lifetime (void)
|
||||
/*
|
||||
* Representation of algorithm attributes:
|
||||
* 0: ALGO_ATTR_<>_P == NULL : RSA-2048
|
||||
* N: ALGO_ATTR_<>_P != NULL :
|
||||
* N: ALGO_ATTR_<>_P != NULL :
|
||||
*
|
||||
*/
|
||||
static const uint8_t *algo_attr_sig_p;
|
||||
@@ -238,6 +249,28 @@ gpg_get_algo_attr (enum kind_of_key kk)
|
||||
return algo_attr_p[1];
|
||||
}
|
||||
|
||||
static void
|
||||
gpg_reset_algo_attr (enum kind_of_key kk)
|
||||
{
|
||||
gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
|
||||
if (kk == GPG_KEY_FOR_SIGNING)
|
||||
{
|
||||
gpg_reset_digital_signature_counter ();
|
||||
gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0);
|
||||
gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0);
|
||||
}
|
||||
else if (kk == GPG_KEY_FOR_DECRYPTION)
|
||||
{
|
||||
gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0);
|
||||
gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0);
|
||||
gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static const uint8_t *
|
||||
get_algo_attr_data_object (enum kind_of_key kk)
|
||||
{
|
||||
@@ -246,16 +279,21 @@ get_algo_attr_data_object (enum kind_of_key kk)
|
||||
if (algo_attr_p == NULL)
|
||||
return algorithm_attr_rsa2k;
|
||||
|
||||
if (algo_attr_p[1] == ALGO_RSA4K)
|
||||
return algorithm_attr_rsa4k;
|
||||
else if (algo_attr_p[1] == ALGO_NISTP256R1)
|
||||
return algorithm_attr_p256r1;
|
||||
else if (algo_attr_p[1] == ALGO_SECP256K1)
|
||||
return algorithm_attr_p256k1;
|
||||
else if (algo_attr_p[1] == ALGO_ED25519)
|
||||
return algorithm_attr_ed25519;
|
||||
|
||||
return algorithm_attr_rsa2k;
|
||||
switch (algo_attr_p[1])
|
||||
{
|
||||
case ALGO_RSA4K:
|
||||
return algorithm_attr_rsa4k;
|
||||
case ALGO_NISTP256R1:
|
||||
return algorithm_attr_p256r1;
|
||||
case ALGO_SECP256K1:
|
||||
return algorithm_attr_p256k1;
|
||||
case ALGO_ED25519:
|
||||
return algorithm_attr_ed25519;
|
||||
case ALGO_CURVE25519:
|
||||
return algorithm_attr_cv25519;
|
||||
default:
|
||||
return algorithm_attr_rsa2k;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -263,30 +301,43 @@ gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s)
|
||||
{
|
||||
const uint8_t *algo_attr_p = *get_algo_attr_pointer (kk);
|
||||
|
||||
if (algo_attr_p == NULL)
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 512;
|
||||
else
|
||||
return 256;
|
||||
else if (algo_attr_p[1] == ALGO_RSA4K)
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 1024;
|
||||
else
|
||||
return 512;
|
||||
else if (algo_attr_p[1] == ALGO_NISTP256R1 || algo_attr_p[1] == ALGO_SECP256K1)
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 128;
|
||||
else if (s == GPG_KEY_PUBLIC)
|
||||
return 64;
|
||||
else
|
||||
return 32;
|
||||
else /* ED25519 */
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 128;
|
||||
else if (s == GPG_KEY_PUBLIC)
|
||||
return 32;
|
||||
else
|
||||
return 64;
|
||||
if (algo_attr_p == NULL) /* RSA-2048 */
|
||||
goto rsa2k;
|
||||
|
||||
switch (algo_attr_p[1])
|
||||
{
|
||||
case ALGO_RSA4K:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 1024;
|
||||
else
|
||||
return 512;
|
||||
case ALGO_NISTP256R1:
|
||||
case ALGO_SECP256K1:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 128;
|
||||
else if (s == GPG_KEY_PUBLIC)
|
||||
return 64;
|
||||
else
|
||||
return 32;
|
||||
case ALGO_ED25519:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 128;
|
||||
else if (s == GPG_KEY_PUBLIC)
|
||||
return 32;
|
||||
else
|
||||
return 64;
|
||||
case ALGO_CURVE25519:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 64;
|
||||
else
|
||||
return 32;
|
||||
default:
|
||||
rsa2k:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 512;
|
||||
else
|
||||
return 256;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +357,7 @@ gpg_write_digital_signature_counter (const uint8_t *p, uint32_t dsc)
|
||||
else
|
||||
{
|
||||
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
|
||||
hw1 = NR_COUNTER_DS_LSB;
|
||||
hw1 = NR_COUNTER_DS_LSB | ((dsc & 0x0300) >> 8) | ((dsc & 0x00ff) << 8);
|
||||
flash_put_data_internal (p, hw0);
|
||||
flash_put_data_internal (p+2, hw1);
|
||||
return p+4;
|
||||
@@ -460,21 +511,6 @@ copy_tag (uint16_t tag)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
do_hist_bytes (uint16_t tag, int with_tag)
|
||||
{
|
||||
/*
|
||||
* Currently, we support no life cycle management.
|
||||
* In case of Gnuk, user could flash the MCU, instead.
|
||||
* Thus, just return the template as is.
|
||||
*
|
||||
* In future (when Gnuk will be onn the real smartcard),
|
||||
* we can support life cycle management by implementing
|
||||
* TERMINATE DF / ACTIVATE FILE and fix code around here.
|
||||
*/
|
||||
copy_do_1 (tag, historical_bytes, with_tag);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SIZE_FP 20
|
||||
#define SIZE_KGTIME 4
|
||||
@@ -604,16 +640,19 @@ do_openpgpcard_aid (uint16_t tag, int with_tag)
|
||||
|
||||
if (vid == 0xffff || vid == 0x0000)
|
||||
{
|
||||
const uint8_t *u = unique_device_id ();
|
||||
const uint8_t *u = unique_device_id () + 8;
|
||||
|
||||
memcpy (res_p, openpgpcard_aid, 8);
|
||||
res_p += 8;
|
||||
|
||||
/* vid == 0xfffe: serial number is random byte */
|
||||
/* vid == 0xfffe: serial number is four random bytes */
|
||||
*res_p++ = 0xff;
|
||||
*res_p++ = 0xfe;
|
||||
memcpy (res_p, u, 4);
|
||||
res_p += 4;
|
||||
|
||||
*res_p++ = u[3];
|
||||
*res_p++ = u[2];
|
||||
*res_p++ = u[1];
|
||||
*res_p++ = u[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -724,19 +763,22 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
||||
algo = ALGO_NISTP256R1;
|
||||
else if (len == 10 && memcmp (data, algorithm_attr_ed25519+1, 10) == 0)
|
||||
algo = ALGO_ED25519;
|
||||
else if (len == 11 && memcmp (data, algorithm_attr_cv25519+1, 11) == 0)
|
||||
algo = ALGO_CURVE25519;
|
||||
|
||||
if (algo < 0)
|
||||
return 0; /* Error */
|
||||
return 0; /* Error. */
|
||||
else if (algo == ALGO_RSA2K && *algo_attr_pp != NULL)
|
||||
{
|
||||
gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
|
||||
gpg_reset_algo_attr (kk);
|
||||
flash_enum_clear (algo_attr_pp);
|
||||
if (*algo_attr_pp != NULL)
|
||||
return 0;
|
||||
}
|
||||
else if (*algo_attr_pp == NULL || (*algo_attr_pp)[1] != algo)
|
||||
else if ((algo != ALGO_RSA2K && *algo_attr_pp == NULL) ||
|
||||
(*algo_attr_pp != NULL && (*algo_attr_pp)[1] != algo))
|
||||
{
|
||||
gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
|
||||
gpg_reset_algo_attr (kk);
|
||||
*algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo);
|
||||
if (*algo_attr_pp == NULL)
|
||||
return 0;
|
||||
@@ -805,7 +847,7 @@ encrypt (const uint8_t *key, const uint8_t *iv, uint8_t *data, int len)
|
||||
{
|
||||
aes_context aes;
|
||||
uint8_t iv0[INITIAL_VECTOR_SIZE];
|
||||
unsigned int iv_offset;
|
||||
size_t iv_offset;
|
||||
|
||||
DEBUG_INFO ("ENC\r\n");
|
||||
DEBUG_BINARY (data, len);
|
||||
@@ -824,7 +866,7 @@ decrypt (const uint8_t *key, const uint8_t *iv, uint8_t *data, int len)
|
||||
{
|
||||
aes_context aes;
|
||||
uint8_t iv0[INITIAL_VECTOR_SIZE];
|
||||
unsigned int iv_offset;
|
||||
size_t iv_offset;
|
||||
|
||||
aes_setkey_enc (&aes, key, 128); /* This is setkey_enc, because of CFB. */
|
||||
memcpy (iv0, iv, INITIAL_VECTOR_SIZE);
|
||||
@@ -1009,6 +1051,28 @@ gpg_do_delete_prvkey (enum kind_of_key kk, int clean_page_full)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gpg_do_terminate (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
kd[i].pubkey = NULL;
|
||||
|
||||
for (i = 0; i < NR_DO__LAST__; i++)
|
||||
do_ptr[i] = NULL;
|
||||
|
||||
num_prv_keys = 0;
|
||||
data_objects_number_of_bytes = 0;
|
||||
digital_signature_counter = 0;
|
||||
|
||||
pw1_lifetime_p = NULL;
|
||||
pw_err_counter_p[PW_ERR_PW1] = NULL;
|
||||
pw_err_counter_p[PW_ERR_RC] = NULL;
|
||||
pw_err_counter_p[PW_ERR_PW3] = NULL;
|
||||
algo_attr_sig_p = algo_attr_dec_p = algo_attr_aut_p = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
int prvkey_len, const uint8_t *keystring_admin,
|
||||
@@ -1018,11 +1082,11 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
int attr = gpg_get_algo_attr (kk);;
|
||||
const uint8_t *p;
|
||||
int r;
|
||||
struct prvkey_data *pd;
|
||||
struct prvkey_data prv;
|
||||
struct prvkey_data *pd = &prv;
|
||||
uint8_t *key_addr;
|
||||
const uint8_t *dek, *iv;
|
||||
struct key_data_internal kdi;
|
||||
uint8_t *pubkey_allocated_here = NULL;
|
||||
int pubkey_len;
|
||||
uint8_t ks[KEYSTRING_MD_SIZE];
|
||||
enum kind_of_key kk0;
|
||||
@@ -1033,10 +1097,6 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
/* Delete it first, if any. */
|
||||
gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
|
||||
|
||||
pd = (struct prvkey_data *)malloc (sizeof (struct prvkey_data));
|
||||
if (pd == NULL)
|
||||
return -1;
|
||||
|
||||
if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
|
||||
{
|
||||
pubkey_len = prvkey_len * 2;
|
||||
@@ -1049,6 +1109,12 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
if (prvkey_len != 64)
|
||||
return -1;
|
||||
}
|
||||
else if (attr == ALGO_CURVE25519)
|
||||
{
|
||||
pubkey_len = prvkey_len;
|
||||
if (prvkey_len != 32)
|
||||
return -1;
|
||||
}
|
||||
else /* RSA */
|
||||
{
|
||||
int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
|
||||
@@ -1058,36 +1124,11 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pubkey == NULL)
|
||||
{
|
||||
if (attr == ALGO_SECP256K1)
|
||||
pubkey_allocated_here = ecc_compute_public_p256k1 (key_data);
|
||||
else if (attr == ALGO_NISTP256R1)
|
||||
pubkey_allocated_here = ecc_compute_public_p256r1 (key_data);
|
||||
else if (attr == ALGO_ED25519)
|
||||
pubkey_allocated_here = eddsa_compute_public_25519 (key_data);
|
||||
else /* RSA */
|
||||
pubkey_allocated_here = modulus_calc (key_data, prvkey_len);
|
||||
|
||||
if (pubkey_allocated_here == NULL)
|
||||
{
|
||||
free (pd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_INFO ("Getting keystore address...\r\n");
|
||||
key_addr = flash_key_alloc (kk);
|
||||
if (key_addr == NULL)
|
||||
{
|
||||
if (pubkey_allocated_here)
|
||||
{
|
||||
memset (pubkey_allocated_here, 0, pubkey_len);
|
||||
free (pubkey_allocated_here);
|
||||
}
|
||||
free (pd);
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
|
||||
kd[kk].pubkey = key_addr + prvkey_len;
|
||||
|
||||
num_prv_keys++;
|
||||
@@ -1123,19 +1164,11 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
encrypt (dek, iv, (uint8_t *)&kdi, kdi_len (prvkey_len));
|
||||
|
||||
r = flash_key_write (key_addr, (const uint8_t *)kdi.data, prvkey_len,
|
||||
pubkey_allocated_here? pubkey_allocated_here: pubkey,
|
||||
pubkey_len);
|
||||
if (pubkey_allocated_here)
|
||||
{
|
||||
memset (pubkey_allocated_here, 0, pubkey_len);
|
||||
free (pubkey_allocated_here);
|
||||
}
|
||||
|
||||
pubkey, pubkey_len);
|
||||
if (r < 0)
|
||||
{
|
||||
random_bytes_free (dek);
|
||||
memset (pd, 0, sizeof (struct prvkey_data));
|
||||
free (pd);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1157,7 +1190,6 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
|
||||
random_bytes_free (dek);
|
||||
memset (pd, 0, sizeof (struct prvkey_data));
|
||||
free (pd);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
|
||||
@@ -1189,18 +1221,15 @@ gpg_do_chks_prvkey (enum kind_of_key kk,
|
||||
uint8_t nr = get_do_ptr_nr_for_kk (kk);
|
||||
const uint8_t *do_data = do_ptr[nr];
|
||||
uint8_t dek[DATA_ENCRYPTION_KEY_SIZE];
|
||||
struct prvkey_data *pd;
|
||||
const uint8_t *p;
|
||||
struct prvkey_data prv;
|
||||
struct prvkey_data *pd = &prv;
|
||||
uint8_t *dek_p;
|
||||
int update_needed = 0;
|
||||
int r = 1; /* Success */
|
||||
|
||||
if (do_data == NULL)
|
||||
return 0; /* No private key */
|
||||
|
||||
pd = (struct prvkey_data *)malloc (sizeof (struct prvkey_data));
|
||||
if (pd == NULL)
|
||||
return -1;
|
||||
|
||||
memcpy (pd, &do_data[1], sizeof (struct prvkey_data));
|
||||
|
||||
dek_p = ((uint8_t *)pd) + INITIAL_VECTOR_SIZE
|
||||
@@ -1231,18 +1260,19 @@ gpg_do_chks_prvkey (enum kind_of_key kk,
|
||||
|
||||
if (update_needed)
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
flash_do_release (do_data);
|
||||
do_ptr[nr] = NULL;
|
||||
p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data));
|
||||
do_ptr[nr] = p;
|
||||
if (p == NULL)
|
||||
r = -1;
|
||||
}
|
||||
|
||||
memset (pd, 0, sizeof (struct prvkey_data));
|
||||
free (pd);
|
||||
if (update_needed && p == NULL)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -1292,11 +1322,12 @@ kkb_to_kk (uint8_t kk_byte)
|
||||
static int
|
||||
proc_key_import (const uint8_t *data, int len)
|
||||
{
|
||||
int r;
|
||||
int r = -1;
|
||||
enum kind_of_key kk;
|
||||
const uint8_t *keystring_admin;
|
||||
int attr;
|
||||
const uint8_t *p = data;
|
||||
uint8_t pubkey[512];
|
||||
|
||||
if (admin_authorized == BY_ADMIN)
|
||||
keystring_admin = keystring_md_pw3;
|
||||
@@ -1328,7 +1359,7 @@ proc_key_import (const uint8_t *data, int len)
|
||||
attr = gpg_get_algo_attr (kk);
|
||||
|
||||
if ((len <= 12 && (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1
|
||||
|| attr == ALGO_ED25519))
|
||||
|| attr == ALGO_ED25519 || attr == ALGO_CURVE25519))
|
||||
|| (len <= 22 && attr == ALGO_RSA2K) || (len <= 24 && attr == ALGO_RSA4K))
|
||||
{ /* Deletion of the key */
|
||||
gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
|
||||
@@ -1336,25 +1367,61 @@ proc_key_import (const uint8_t *data, int len)
|
||||
}
|
||||
|
||||
if (attr == ALGO_RSA2K)
|
||||
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
|
||||
r = gpg_do_write_prvkey (kk, &data[26], len - 26, keystring_admin, NULL);
|
||||
{
|
||||
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
|
||||
r = modulus_calc (&data[26], len - 26, pubkey);
|
||||
if (r >= 0)
|
||||
r = gpg_do_write_prvkey (kk, &data[26], len - 26, keystring_admin,
|
||||
pubkey);
|
||||
}
|
||||
else if (attr == ALGO_RSA4K)
|
||||
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
|
||||
r = gpg_do_write_prvkey (kk, &data[28], len - 28, keystring_admin, NULL);
|
||||
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
|
||||
r = gpg_do_write_prvkey (kk, &data[12], len - 12, keystring_admin, NULL);
|
||||
else /* if (attr == ALGO_ED25519) */
|
||||
{
|
||||
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
|
||||
r = modulus_calc (&data[28], len - 28, pubkey);
|
||||
if (r >= 0)
|
||||
r = gpg_do_write_prvkey (kk, &data[28], len - 28, keystring_admin,
|
||||
pubkey);
|
||||
}
|
||||
else if (attr == ALGO_NISTP256R1)
|
||||
{
|
||||
r = ecc_compute_public_p256r1 (&data[12], pubkey);
|
||||
if (r >= 0)
|
||||
r = gpg_do_write_prvkey (kk, &data[12], len - 12, keystring_admin,
|
||||
pubkey);
|
||||
}
|
||||
else if (attr == ALGO_SECP256K1)
|
||||
{
|
||||
r = ecc_compute_public_p256k1 (&data[12], pubkey);
|
||||
if (r >= 0)
|
||||
r = gpg_do_write_prvkey (kk, &data[12], len - 12, keystring_admin,
|
||||
pubkey);
|
||||
}
|
||||
else if (attr == ALGO_ED25519)
|
||||
{
|
||||
uint8_t hash[64];
|
||||
|
||||
if (len - 12 != 32)
|
||||
return 1; /* Error. */
|
||||
return 0; /* Error. */
|
||||
|
||||
sha512 (&data[12], 32, hash);
|
||||
hash[0] &= 248;
|
||||
hash[31] &= 127;
|
||||
hash[31] |= 64;
|
||||
r = gpg_do_write_prvkey (kk, hash, 64, keystring_admin, NULL);
|
||||
eddsa_compute_public_25519 (hash, pubkey);
|
||||
r = gpg_do_write_prvkey (kk, hash, 64, keystring_admin, pubkey);
|
||||
}
|
||||
else if (attr == ALGO_CURVE25519)
|
||||
{
|
||||
uint8_t priv[32];
|
||||
int i;
|
||||
|
||||
if (len - 12 != 32)
|
||||
return 0; /* Error. */
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
priv[31-i] = data[12+i];
|
||||
ecdh_compute_public_25519 (priv, pubkey);
|
||||
r = gpg_do_write_prvkey (kk, priv, 32, keystring_admin, pubkey);
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
@@ -1406,7 +1473,6 @@ gpg_do_table[] = {
|
||||
{ GPG_DO_NAME, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[12] },
|
||||
{ GPG_DO_LANGUAGE, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[13] },
|
||||
/* Pseudo DO READ: calculated */
|
||||
{ GPG_DO_HIST_BYTES, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_hist_bytes },
|
||||
{ GPG_DO_FP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_fp_all },
|
||||
{ GPG_DO_CAFP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_cafp_all },
|
||||
{ GPG_DO_KGTIME_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_kgtime_all },
|
||||
@@ -1423,6 +1489,7 @@ gpg_do_table[] = {
|
||||
{ GPG_DO_ALG_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
|
||||
rw_algorithm_attr },
|
||||
/* Fixed data */
|
||||
{ GPG_DO_HIST_BYTES, DO_FIXED, AC_ALWAYS, AC_NEVER, historical_bytes },
|
||||
{ GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
|
||||
/* Compound data: Read access only */
|
||||
{ GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data },
|
||||
@@ -1448,7 +1515,7 @@ gpg_do_table[] = {
|
||||
* Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc.
|
||||
*/
|
||||
void
|
||||
gpg_data_scan (const uint8_t *p_start)
|
||||
gpg_data_scan (const uint8_t *do_start, const uint8_t *do_end)
|
||||
{
|
||||
const uint8_t *p;
|
||||
int i;
|
||||
@@ -1461,10 +1528,15 @@ gpg_data_scan (const uint8_t *p_start)
|
||||
pw_err_counter_p[PW_ERR_RC] = NULL;
|
||||
pw_err_counter_p[PW_ERR_PW3] = NULL;
|
||||
algo_attr_sig_p = algo_attr_dec_p = algo_attr_aut_p = NULL;
|
||||
digital_signature_counter = 0;
|
||||
|
||||
/* When the card is terminated no data objects are valid. */
|
||||
if (do_start == NULL)
|
||||
return;
|
||||
|
||||
/* Traverse DO, counters, etc. in DATA pool */
|
||||
p = p_start;
|
||||
while (*p != NR_EMPTY)
|
||||
p = do_start;
|
||||
while (p < do_end && *p != NR_EMPTY)
|
||||
{
|
||||
uint8_t nr = *p++;
|
||||
uint8_t second_byte = *p;
|
||||
@@ -1476,10 +1548,12 @@ gpg_data_scan (const uint8_t *p_start)
|
||||
if (nr < 0x80)
|
||||
{
|
||||
/* It's Data Object */
|
||||
do_ptr[nr] = p;
|
||||
if (nr < NR_DO__LAST__)
|
||||
do_ptr[nr] = p;
|
||||
|
||||
p += second_byte + 1; /* second_byte has length */
|
||||
|
||||
if (((uint32_t)p & 1))
|
||||
if (((uintptr_t)p & 1))
|
||||
p++;
|
||||
}
|
||||
else if (nr >= 0x80 && nr <= 0xbf)
|
||||
@@ -1910,14 +1984,14 @@ gpg_do_public_key (uint8_t kk_byte)
|
||||
res_p += 64;
|
||||
}
|
||||
}
|
||||
else if (attr == ALGO_ED25519)
|
||||
{ /* EdDSA */
|
||||
else if (attr == ALGO_ED25519 || attr == ALGO_CURVE25519)
|
||||
{ /* EdDSA or ECDH on curve25519 */
|
||||
/* LEN */
|
||||
*res_p++ = 2 + 32;
|
||||
{
|
||||
/*TAG*/ /* LEN = 32 */
|
||||
*res_p++ = 0x86; *res_p++ = 0x20;
|
||||
/* 32-byte binary (little endian): Y with parity */
|
||||
/* 32-byte binary (little endian): Y with parity or X*/
|
||||
memcpy (res_p, pubkey, 32);
|
||||
res_p += 32;
|
||||
}
|
||||
@@ -1983,39 +2057,112 @@ gpg_do_write_simple (uint8_t nr, const uint8_t *data, int size)
|
||||
*do_data_p = NULL;
|
||||
}
|
||||
|
||||
#ifdef KEYGEN_SUPPORT
|
||||
void
|
||||
gpg_do_keygen (uint8_t kk_byte)
|
||||
gpg_do_keygen (uint8_t *buf)
|
||||
{
|
||||
uint8_t kk_byte = buf[0];
|
||||
enum kind_of_key kk = kkb_to_kk (kk_byte);
|
||||
int pubkey_len = gpg_get_algo_attr_key_size (kk, GPG_KEY_PUBLIC);
|
||||
const uint8_t *keystring_admin;
|
||||
uint8_t *p_q_modulus;
|
||||
const uint8_t *p_q;
|
||||
const uint8_t *modulus;
|
||||
int r;
|
||||
int attr = gpg_get_algo_attr (kk);;
|
||||
int prvkey_len = gpg_get_algo_attr_key_size (kk, GPG_KEY_PRIVATE);
|
||||
const uint8_t *prv;
|
||||
const uint8_t *rnd;
|
||||
int r = 0;
|
||||
#define p_q buf
|
||||
#define d buf
|
||||
#define d1 (&buf[64])
|
||||
#define pubkey (&buf[256])
|
||||
|
||||
DEBUG_INFO ("Keygen\r\n");
|
||||
DEBUG_BYTE (kk_byte);
|
||||
|
||||
if (admin_authorized == BY_ADMIN)
|
||||
keystring_admin = keystring_md_pw3;
|
||||
else
|
||||
keystring_admin = NULL;
|
||||
|
||||
p_q_modulus = rsa_genkey (pubkey_len);
|
||||
if (p_q_modulus == NULL)
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
GPG_MEMORY_FAILURE ();
|
||||
if (rsa_genkey (prvkey_len, pubkey, p_q) < 0)
|
||||
{
|
||||
GPG_MEMORY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
|
||||
prv = p_q;
|
||||
}
|
||||
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
|
||||
{
|
||||
const uint8_t *p;
|
||||
int i, r;
|
||||
|
||||
rnd = NULL;
|
||||
do
|
||||
{
|
||||
if (rnd)
|
||||
random_bytes_free (rnd);
|
||||
rnd = random_bytes_get ();
|
||||
if (attr == ALGO_NISTP256R1)
|
||||
r = ecc_check_secret_p256r1 (rnd, d1);
|
||||
else
|
||||
r = ecc_check_secret_p256k1 (rnd, d1);
|
||||
}
|
||||
while (r == 0);
|
||||
|
||||
/* Convert it to big endian */
|
||||
|
||||
if (r < 0)
|
||||
p = (const uint8_t *)d1;
|
||||
else
|
||||
p = rnd;
|
||||
for (i = 0; i < 32; i++)
|
||||
d[32 - i - 1] = p[i];
|
||||
|
||||
random_bytes_free (rnd);
|
||||
|
||||
prv = d;
|
||||
if (attr == ALGO_SECP256K1)
|
||||
r = ecc_compute_public_p256k1 (prv, pubkey);
|
||||
else if (attr == ALGO_NISTP256R1)
|
||||
r = ecc_compute_public_p256r1 (prv, pubkey);
|
||||
}
|
||||
else if (attr == ALGO_ED25519)
|
||||
{
|
||||
rnd = random_bytes_get ();
|
||||
sha512 (rnd, 32, d);
|
||||
random_bytes_free (rnd);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
prv = d;
|
||||
eddsa_compute_public_25519 (d, pubkey);
|
||||
}
|
||||
else if (attr == ALGO_CURVE25519)
|
||||
{
|
||||
rnd = random_bytes_get ();
|
||||
memcpy (d, rnd, 32);
|
||||
random_bytes_free (rnd);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
prv = d;
|
||||
ecdh_compute_public_25519 (prv, pubkey);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
p_q = p_q_modulus;
|
||||
modulus = p_q_modulus + pubkey_len;
|
||||
if (r >= 0)
|
||||
{
|
||||
const uint8_t *keystring_admin;
|
||||
|
||||
if (admin_authorized == BY_ADMIN)
|
||||
keystring_admin = keystring_md_pw3;
|
||||
else
|
||||
keystring_admin = NULL;
|
||||
|
||||
r = gpg_do_write_prvkey (kk, prv, prvkey_len, keystring_admin, pubkey);
|
||||
}
|
||||
|
||||
/* Clear private key data in the buffer. */
|
||||
memset (buf, 0, 256);
|
||||
|
||||
r = gpg_do_write_prvkey (kk, p_q, pubkey_len, keystring_admin, modulus);
|
||||
memset (p_q_modulus, 0, pubkey_len * 2);
|
||||
free (p_q_modulus);
|
||||
if (r < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
@@ -2041,4 +2188,3 @@ gpg_do_keygen (uint8_t kk_byte)
|
||||
|
||||
gpg_do_public_key (kk_byte);
|
||||
}
|
||||
#endif
|
||||
|
||||
354
src/openpgp.c
354
src/openpgp.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* openpgp.c -- OpenPGP card protocol support
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "sys.h"
|
||||
#include "openpgp.h"
|
||||
#include "status-code.h"
|
||||
#include "sha256.h"
|
||||
#include "random.h"
|
||||
|
||||
@@ -48,6 +48,7 @@ static struct eventflag *openpgp_comm;
|
||||
#define INS_CHANGE_REFERENCE_DATA 0x24
|
||||
#define INS_PSO 0x2a
|
||||
#define INS_RESET_RETRY_COUNTER 0x2c
|
||||
#define INS_ACTIVATE_FILE 0x44
|
||||
#define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR 0x47
|
||||
#define INS_EXTERNAL_AUTHENTICATE 0x82
|
||||
#define INS_GET_CHALLENGE 0x84
|
||||
@@ -59,6 +60,7 @@ static struct eventflag *openpgp_comm;
|
||||
#define INS_UPDATE_BINARY 0xd6
|
||||
#define INS_PUT_DATA 0xda
|
||||
#define INS_PUT_DATA_ODD 0xdb /* For key import */
|
||||
#define INS_TERMINATE_DF 0xe6
|
||||
|
||||
static const uint8_t *challenge; /* Random bytes */
|
||||
|
||||
@@ -96,18 +98,25 @@ set_res_sw (uint8_t sw1, uint8_t sw2)
|
||||
#define FILE_EF_UPDATE_KEY_2 7
|
||||
#define FILE_EF_UPDATE_KEY_3 8
|
||||
#define FILE_EF_CH_CERTIFICATE 9
|
||||
#define FILE_CARD_TERMINATED 255
|
||||
|
||||
static uint8_t file_selection;
|
||||
uint8_t file_selection;
|
||||
|
||||
static void
|
||||
gpg_init (void)
|
||||
{
|
||||
const uint8_t *flash_data_start;
|
||||
const uint8_t *flash_do_start;
|
||||
const uint8_t *flash_do_end;
|
||||
|
||||
file_selection = FILE_NONE;
|
||||
flash_data_start = flash_init ();
|
||||
gpg_data_scan (flash_data_start);
|
||||
flash_init_keys ();
|
||||
flash_do_storage_init (&flash_do_start, &flash_do_end);
|
||||
|
||||
if (flash_do_start == NULL)
|
||||
file_selection = FILE_CARD_TERMINATED;
|
||||
else
|
||||
file_selection = FILE_NONE;
|
||||
|
||||
gpg_data_scan (flash_do_start, flash_do_end);
|
||||
flash_key_storage_init ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -138,6 +147,7 @@ static void
|
||||
cmd_verify (void)
|
||||
{
|
||||
int len;
|
||||
uint8_t p1 = P1 (apdu);
|
||||
uint8_t p2 = P2 (apdu);
|
||||
int r;
|
||||
const uint8_t *pw;
|
||||
@@ -149,22 +159,36 @@ cmd_verify (void)
|
||||
pw = apdu.cmd_apdu_data;
|
||||
|
||||
if (len == 0)
|
||||
{ /* This is to examine status. */
|
||||
if (p2 == 0x81)
|
||||
r = ac_check_status (AC_PSO_CDS_AUTHORIZED);
|
||||
else if (p2 == 0x82)
|
||||
r = ac_check_status (AC_OTHER_AUTHORIZED);
|
||||
else
|
||||
r = ac_check_status (AC_ADMIN_AUTHORIZED);
|
||||
{
|
||||
if (p1 == 0)
|
||||
{ /* This is to examine status. */
|
||||
if (p2 == 0x81)
|
||||
r = ac_check_status (AC_PSO_CDS_AUTHORIZED);
|
||||
else if (p2 == 0x82)
|
||||
r = ac_check_status (AC_OTHER_AUTHORIZED);
|
||||
else
|
||||
r = ac_check_status (AC_ADMIN_AUTHORIZED);
|
||||
|
||||
if (r)
|
||||
GPG_SUCCESS (); /* If authentication done already, return success. */
|
||||
else
|
||||
{ /* If not, return retry counter, encoded. */
|
||||
r = gpg_pw_get_retry_counter (p2);
|
||||
set_res_sw (0x63, 0xc0 | (r&0x0f));
|
||||
if (r)
|
||||
GPG_SUCCESS (); /* If authentication done already, return success. */
|
||||
else
|
||||
{ /* If not, return retry counter, encoded. */
|
||||
r = gpg_pw_get_retry_counter (p2);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -437,9 +461,12 @@ s2k (const unsigned char *salt, size_t slen,
|
||||
{
|
||||
sha256_context ctx;
|
||||
size_t count = S2KCOUNT;
|
||||
const uint8_t *unique = unique_device_id ();
|
||||
|
||||
sha256_start (&ctx);
|
||||
|
||||
sha256_update (&ctx, unique, 12);
|
||||
|
||||
while (count > slen + ilen)
|
||||
{
|
||||
if (slen)
|
||||
@@ -598,9 +625,6 @@ cmd_put_data (void)
|
||||
|
||||
DEBUG_INFO (" - PUT DATA\r\n");
|
||||
|
||||
if (file_selection != FILE_DF_OPENPGP)
|
||||
GPG_NO_RECORD();
|
||||
|
||||
tag = ((P1 (apdu)<<8) | P2 (apdu));
|
||||
len = apdu.cmd_apdu_data_len;
|
||||
data = apdu.cmd_apdu_data;
|
||||
@@ -620,15 +644,11 @@ cmd_pgp_gakp (void)
|
||||
{
|
||||
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
|
||||
GPG_SECURITY_FAILURE ();
|
||||
#ifdef KEYGEN_SUPPORT
|
||||
/* Generate key pair */
|
||||
gpg_do_keygen (apdu.cmd_apdu_data[0]);
|
||||
#else
|
||||
GPG_FUNCTION_NOT_SUPPORTED ();
|
||||
#endif
|
||||
gpg_do_keygen (&apdu.cmd_apdu_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
const uint8_t *
|
||||
gpg_get_firmware_update_key (uint8_t keyno)
|
||||
{
|
||||
@@ -638,6 +658,7 @@ gpg_get_firmware_update_key (uint8_t keyno)
|
||||
p = &_updatekey_store + keyno * FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CERTDO_SUPPORT
|
||||
#define FILEID_CH_CERTIFICATE_IS_VALID 1
|
||||
@@ -650,7 +671,6 @@ cmd_read_binary (void)
|
||||
{
|
||||
int is_short_EF = (P1 (apdu) & 0x80) != 0;
|
||||
uint8_t file_id;
|
||||
const uint8_t *p;
|
||||
uint16_t offset;
|
||||
|
||||
DEBUG_INFO (" - Read binary\r\n");
|
||||
@@ -660,13 +680,6 @@ cmd_read_binary (void)
|
||||
else
|
||||
file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
|
||||
|
||||
if ((!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
|
||||
|| file_id > FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
GPG_NO_FILE ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_short_EF)
|
||||
{
|
||||
file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
|
||||
@@ -686,22 +699,26 @@ cmd_read_binary (void)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
{
|
||||
if (offset != 0)
|
||||
GPG_MEMORY_FAILURE ();
|
||||
else
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
|
||||
res_APDU_size = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
memcpy (res_APDU, p, FIRMWARE_UPDATE_KEY_CONTENT_LEN);
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
else /* file_id == FILEID_CH_CERTIFICATE */
|
||||
else if (file_id == FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
const uint8_t *p;
|
||||
uint16_t len = 256;
|
||||
|
||||
p = &ch_certificate_start;
|
||||
@@ -718,6 +735,11 @@ cmd_read_binary (void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
GPG_NO_FILE ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -738,19 +760,16 @@ cmd_select_file (void)
|
||||
return;
|
||||
}
|
||||
|
||||
file_selection = FILE_DF_OPENPGP;
|
||||
if ((P2 (apdu) & 0x0c) == 0x0c) /* No FCI */
|
||||
GPG_SUCCESS ();
|
||||
else
|
||||
if (file_selection == FILE_CARD_TERMINATED)
|
||||
{
|
||||
gpg_do_get_data (0x004f, 1); /* AID */
|
||||
memmove (res_APDU+2, res_APDU, res_APDU_size);
|
||||
res_APDU[0] = 0x6f;
|
||||
res_APDU[1] = 0x12;
|
||||
res_APDU[2] = 0x84; /* overwrite: DF name */
|
||||
res_APDU_size += 2;
|
||||
GPG_SUCCESS ();
|
||||
GPG_APPLICATION_TERMINATED ();
|
||||
return;
|
||||
}
|
||||
|
||||
file_selection = FILE_DF_OPENPGP;
|
||||
|
||||
/* Behave just like original OpenPGP card. */
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
else if (apdu.cmd_apdu_data_len == 2
|
||||
&& apdu.cmd_apdu_data[0] == 0x2f && apdu.cmd_apdu_data[1] == 0x02)
|
||||
@@ -800,9 +819,6 @@ cmd_get_data (void)
|
||||
|
||||
DEBUG_INFO (" - Get Data\r\n");
|
||||
|
||||
if (file_selection != FILE_DF_OPENPGP)
|
||||
GPG_NO_RECORD ();
|
||||
|
||||
gpg_do_get_data (tag, 0);
|
||||
}
|
||||
|
||||
@@ -812,6 +828,8 @@ cmd_get_data (void)
|
||||
#define EDDSA_HASH_LEN_MAX 256
|
||||
#define EDDSA_SIGNATURE_LENGTH 64
|
||||
|
||||
#define ECC_CIPHER_DO_HEADER_SIZE 7
|
||||
|
||||
static void
|
||||
cmd_pso (void)
|
||||
{
|
||||
@@ -819,6 +837,8 @@ cmd_pso (void)
|
||||
int r = -1;
|
||||
int attr;
|
||||
int pubkey_len;
|
||||
unsigned int result_len = 0;
|
||||
int cs;
|
||||
|
||||
DEBUG_INFO (" - PSO: ");
|
||||
DEBUG_WORD ((uint32_t)&r);
|
||||
@@ -855,13 +875,9 @@ cmd_pso (void)
|
||||
|
||||
DEBUG_BINARY (kd[GPG_KEY_FOR_SIGNING].data, pubkey_len);
|
||||
|
||||
result_len = pubkey_len;
|
||||
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
|
||||
&kd[GPG_KEY_FOR_SIGNING], pubkey_len);
|
||||
if (r < 0)
|
||||
ac_reset_pso_cds ();
|
||||
else
|
||||
/* Success */
|
||||
gpg_increment_digital_signature_counter ();
|
||||
}
|
||||
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
|
||||
{
|
||||
@@ -873,19 +889,15 @@ cmd_pso (void)
|
||||
return;
|
||||
}
|
||||
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = ECDSA_SIGNATURE_LENGTH;
|
||||
if (attr == ALGO_NISTP256R1)
|
||||
r = ecdsa_sign_p256r1 (apdu.cmd_apdu_data, res_APDU,
|
||||
kd[GPG_KEY_FOR_SIGNING].data);
|
||||
else /* ALGO_SECP256K1 */
|
||||
r = ecdsa_sign_p256k1 (apdu.cmd_apdu_data, res_APDU,
|
||||
kd[GPG_KEY_FOR_SIGNING].data);
|
||||
if (r < 0)
|
||||
ac_reset_pso_cds ();
|
||||
else
|
||||
{ /* Success */
|
||||
gpg_increment_digital_signature_counter ();
|
||||
res_APDU_size = ECDSA_SIGNATURE_LENGTH;
|
||||
}
|
||||
chopstx_setcancelstate (cs);
|
||||
}
|
||||
else if (attr == ALGO_ED25519)
|
||||
{
|
||||
@@ -898,13 +910,29 @@ cmd_pso (void)
|
||||
return;
|
||||
}
|
||||
|
||||
res_APDU_size = EDDSA_SIGNATURE_LENGTH;
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = EDDSA_SIGNATURE_LENGTH;
|
||||
r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].data,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].data+32,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].pubkey);
|
||||
kd[GPG_KEY_FOR_SIGNING].data,
|
||||
kd[GPG_KEY_FOR_SIGNING].data+32,
|
||||
kd[GPG_KEY_FOR_SIGNING].pubkey);
|
||||
chopstx_setcancelstate (cs);
|
||||
memcpy (res_APDU, output, EDDSA_SIGNATURE_LENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_INFO ("unknown algo.");
|
||||
GPG_FUNCTION_NOT_SUPPORTED ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
{
|
||||
res_APDU_size = result_len;
|
||||
gpg_increment_digital_signature_counter ();
|
||||
}
|
||||
else /* Failure */
|
||||
ac_reset_pso_cds ();
|
||||
}
|
||||
else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
|
||||
{
|
||||
@@ -931,27 +959,55 @@ cmd_pso (void)
|
||||
return;
|
||||
}
|
||||
r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
|
||||
&kd[GPG_KEY_FOR_DECRYPTION]);
|
||||
&kd[GPG_KEY_FOR_DECRYPTION], &result_len);
|
||||
}
|
||||
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
|
||||
{
|
||||
int header = ECC_CIPHER_DO_HEADER_SIZE;
|
||||
|
||||
/* Format is in big endian MPI: 04 || x || y */
|
||||
if (len != 65 || apdu.cmd_apdu_data[0] != 4)
|
||||
if (len != 65 + ECC_CIPHER_DO_HEADER_SIZE
|
||||
|| apdu.cmd_apdu_data[header] != 0x04)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = 65;
|
||||
if (attr == ALGO_NISTP256R1)
|
||||
r = ecdh_decrypt_p256r1 (apdu.cmd_apdu_data, res_APDU,
|
||||
r = ecdh_decrypt_p256r1 (apdu.cmd_apdu_data + header, res_APDU,
|
||||
kd[GPG_KEY_FOR_DECRYPTION].data);
|
||||
else
|
||||
r = ecdh_decrypt_p256k1 (apdu.cmd_apdu_data, res_APDU,
|
||||
r = ecdh_decrypt_p256k1 (apdu.cmd_apdu_data + header, res_APDU,
|
||||
kd[GPG_KEY_FOR_DECRYPTION].data);
|
||||
|
||||
if (r == 0)
|
||||
res_APDU_size = 65;
|
||||
chopstx_setcancelstate (cs);
|
||||
}
|
||||
else if (attr == ALGO_CURVE25519)
|
||||
{
|
||||
int header = ECC_CIPHER_DO_HEADER_SIZE;
|
||||
|
||||
if (len != 32 + ECC_CIPHER_DO_HEADER_SIZE)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = 32;
|
||||
r = ecdh_decrypt_curve25519 (apdu.cmd_apdu_data + header, res_APDU,
|
||||
kd[GPG_KEY_FOR_DECRYPTION].data);
|
||||
chopstx_setcancelstate (cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_INFO ("unknown algo.");
|
||||
GPG_FUNCTION_NOT_SUPPORTED ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
res_APDU_size = result_len;
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
@@ -976,6 +1032,8 @@ cmd_internal_authenticate (void)
|
||||
GPG_KEY_PUBLIC);
|
||||
int len = apdu.cmd_apdu_data_len;
|
||||
int r = -1;
|
||||
unsigned int result_len = 0;
|
||||
int cs;
|
||||
|
||||
DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n");
|
||||
|
||||
@@ -1006,9 +1064,10 @@ cmd_internal_authenticate (void)
|
||||
return;
|
||||
}
|
||||
|
||||
result_len = pubkey_len;
|
||||
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
|
||||
&kd[GPG_KEY_FOR_AUTHENTICATION], pubkey_len);
|
||||
}
|
||||
}
|
||||
else if (attr == ALGO_NISTP256R1)
|
||||
{
|
||||
if (len != ECDSA_HASH_LEN)
|
||||
@@ -1018,9 +1077,11 @@ cmd_internal_authenticate (void)
|
||||
return;
|
||||
}
|
||||
|
||||
res_APDU_size = ECDSA_SIGNATURE_LENGTH;
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = ECDSA_SIGNATURE_LENGTH;
|
||||
r = ecdsa_sign_p256r1 (apdu.cmd_apdu_data, res_APDU,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].data);
|
||||
chopstx_setcancelstate (cs);
|
||||
}
|
||||
else if (attr == ALGO_SECP256K1)
|
||||
{
|
||||
@@ -1031,9 +1092,11 @@ cmd_internal_authenticate (void)
|
||||
return;
|
||||
}
|
||||
|
||||
res_APDU_size = ECDSA_SIGNATURE_LENGTH;
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = ECDSA_SIGNATURE_LENGTH;
|
||||
r = ecdsa_sign_p256k1 (apdu.cmd_apdu_data, res_APDU,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].data);
|
||||
chopstx_setcancelstate (cs);
|
||||
}
|
||||
else if (attr == ALGO_ED25519)
|
||||
{
|
||||
@@ -1046,15 +1109,19 @@ cmd_internal_authenticate (void)
|
||||
return;
|
||||
}
|
||||
|
||||
res_APDU_size = EDDSA_SIGNATURE_LENGTH;
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = EDDSA_SIGNATURE_LENGTH;
|
||||
r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].data,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].data+32,
|
||||
kd[GPG_KEY_FOR_AUTHENTICATION].pubkey);
|
||||
chopstx_setcancelstate (cs);
|
||||
memcpy (res_APDU, output, EDDSA_SIGNATURE_LENGTH);
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
if (r == 0)
|
||||
res_APDU_size = result_len;
|
||||
else
|
||||
GPG_ERROR ();
|
||||
|
||||
DEBUG_INFO ("INTERNAL AUTHENTICATE done.\r\n");
|
||||
@@ -1136,6 +1203,7 @@ modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3
|
||||
&& len == 0 && offset == 0)
|
||||
{
|
||||
@@ -1152,9 +1220,10 @@ modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
|
||||
if (i == 4) /* all update keys are removed */
|
||||
{
|
||||
p = gpg_get_firmware_update_key (0);
|
||||
flash_erase_page ((uint32_t)p);
|
||||
flash_erase_page ((uintptr_t)p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
@@ -1184,6 +1253,7 @@ cmd_write_binary (void)
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
static void
|
||||
cmd_external_authenticate (void)
|
||||
{
|
||||
@@ -1225,6 +1295,7 @@ cmd_external_authenticate (void)
|
||||
set_res_sw (0xff, 0xff);
|
||||
DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cmd_get_challenge (void)
|
||||
@@ -1253,6 +1324,69 @@ cmd_get_challenge (void)
|
||||
}
|
||||
|
||||
|
||||
#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
|
||||
static void
|
||||
cmd_activate_file (void)
|
||||
{
|
||||
if (file_selection != FILE_CARD_TERMINATED)
|
||||
{
|
||||
GPG_NO_RECORD ();
|
||||
return;
|
||||
}
|
||||
|
||||
flash_activate ();
|
||||
file_selection = FILE_DF_OPENPGP;
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_terminate_df (void)
|
||||
{
|
||||
const uint8_t *ks_pw3;
|
||||
|
||||
uint8_t p1 = P1 (apdu);
|
||||
uint8_t p2 = P2 (apdu);
|
||||
|
||||
if (file_selection != FILE_DF_OPENPGP)
|
||||
{
|
||||
GPG_NO_RECORD ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (p1 != 0 || p2 != 0)
|
||||
{
|
||||
GPG_BAD_P1_P2();
|
||||
return;
|
||||
}
|
||||
|
||||
if (apdu.cmd_apdu_data_len != 0)
|
||||
{
|
||||
GPG_WRONG_LENGTH();
|
||||
return;
|
||||
}
|
||||
|
||||
ks_pw3 = gpg_do_read_simple (NR_DO_KEYSTRING_PW3);
|
||||
|
||||
if (!ac_check_status (AC_ADMIN_AUTHORIZED)
|
||||
&& !((ks_pw3 && gpg_pw_locked (PW_ERR_PW3))
|
||||
|| (ks_pw3 == NULL && gpg_pw_locked (PW_ERR_PW1))))
|
||||
{
|
||||
/* Only allow the case admin authorized, or, admin pass is locked. */
|
||||
GPG_SECURITY_FAILURE();
|
||||
return;
|
||||
}
|
||||
|
||||
ac_reset_admin ();
|
||||
ac_reset_pso_cds ();
|
||||
ac_reset_other ();
|
||||
gpg_do_terminate ();
|
||||
flash_terminate ();
|
||||
file_selection = FILE_CARD_TERMINATED;
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct command
|
||||
{
|
||||
uint8_t command;
|
||||
@@ -1264,13 +1398,18 @@ const struct command cmds[] = {
|
||||
{ INS_CHANGE_REFERENCE_DATA, cmd_change_password },
|
||||
{ INS_PSO, cmd_pso },
|
||||
{ INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
|
||||
#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
|
||||
{ INS_ACTIVATE_FILE, cmd_activate_file },
|
||||
#endif
|
||||
{ INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
{ INS_EXTERNAL_AUTHENTICATE, /* Not in OpenPGP card protocol */
|
||||
cmd_external_authenticate },
|
||||
#endif
|
||||
{ INS_GET_CHALLENGE, cmd_get_challenge }, /* Not in OpenPGP card protocol */
|
||||
{ INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
|
||||
{ INS_SELECT_FILE, cmd_select_file },
|
||||
{ INS_READ_BINARY, cmd_read_binary },
|
||||
{ INS_READ_BINARY, cmd_read_binary }, /* Not in OpenPGP card protocol */
|
||||
{ INS_GET_DATA, cmd_get_data },
|
||||
{ INS_WRITE_BINARY, cmd_write_binary}, /* Not in OpenPGP card protocol */
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
@@ -1278,6 +1417,9 @@ const struct command cmds[] = {
|
||||
#endif
|
||||
{ INS_PUT_DATA, cmd_put_data },
|
||||
{ INS_PUT_DATA_ODD, cmd_put_data },
|
||||
#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
|
||||
{ INS_TERMINATE_DF, cmd_terminate_df},
|
||||
#endif
|
||||
};
|
||||
#define NUM_CMDS ((int)(sizeof (cmds) / sizeof (struct command)))
|
||||
|
||||
@@ -1292,7 +1434,24 @@ process_command_apdu (void)
|
||||
break;
|
||||
|
||||
if (i < NUM_CMDS)
|
||||
cmds[i].cmd_handler ();
|
||||
{
|
||||
if (file_selection == FILE_CARD_TERMINATED
|
||||
&& cmd != INS_SELECT_FILE && cmd != INS_ACTIVATE_FILE
|
||||
&& cmd != INS_GET_CHALLENGE && cmd != INS_EXTERNAL_AUTHENTICATE)
|
||||
GPG_APPLICATION_TERMINATED ();
|
||||
else if (file_selection != FILE_DF_OPENPGP
|
||||
&& cmd != INS_SELECT_FILE && cmd != INS_ACTIVATE_FILE
|
||||
&& cmd != INS_GET_CHALLENGE && cmd != INS_EXTERNAL_AUTHENTICATE
|
||||
&& cmd != INS_WRITE_BINARY && cmd != INS_UPDATE_BINARY
|
||||
&& cmd != INS_READ_BINARY)
|
||||
GPG_NO_RECORD ();
|
||||
else
|
||||
{
|
||||
chopstx_setcancelstate (1);
|
||||
cmds[i].cmd_handler ();
|
||||
chopstx_setcancelstate (0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_INFO (" - ??");
|
||||
@@ -1301,23 +1460,10 @@ process_command_apdu (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void * card_thread (chopstx_t thd, struct eventflag *ccid_comm);
|
||||
|
||||
void * __attribute__ ((naked))
|
||||
void *
|
||||
openpgp_card_thread (void *arg)
|
||||
{
|
||||
chopstx_t thd;
|
||||
|
||||
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;
|
||||
struct eventflag *ccid_comm = (struct eventflag *)arg;
|
||||
|
||||
openpgp_comm = ccid_comm + 1;
|
||||
|
||||
@@ -1325,10 +1471,10 @@ card_thread (chopstx_t thd, struct eventflag *ccid_comm)
|
||||
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m = eventflag_wait (openpgp_comm);
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
int len, pw_len, newpw_len;
|
||||
#endif
|
||||
eventmask_t m = eventflag_wait (openpgp_comm);
|
||||
|
||||
DEBUG_INFO ("GPG!: ");
|
||||
|
||||
@@ -1357,7 +1503,7 @@ card_thread (chopstx_t thd, struct eventflag *ccid_comm)
|
||||
else if (m == EV_MODIFY_CMD_AVAILABLE)
|
||||
{
|
||||
#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;
|
||||
|
||||
if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "config.h"
|
||||
#include "board.h"
|
||||
#include "gnuk.h"
|
||||
#include "stm32f103.h"
|
||||
#include "mcu/stm32f103.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_CIR 1
|
||||
@@ -51,10 +51,9 @@ cir_ext_enable (void)
|
||||
EXTI->IMR |= EXTI_IMR;
|
||||
}
|
||||
|
||||
|
||||
static chopstx_t pin_thread;
|
||||
static uint32_t wait_usec;
|
||||
static uint8_t notification;
|
||||
static chopstx_mutex_t cir_input_mtx;
|
||||
static chopstx_cond_t cir_input_cnd;
|
||||
static int input_avail;
|
||||
|
||||
uint8_t pin_input_buffer[MAX_PIN_CHARS];
|
||||
uint8_t pin_input_len;
|
||||
@@ -500,9 +499,18 @@ hex (int x)
|
||||
return (x - 10) + 'a';
|
||||
}
|
||||
|
||||
static int
|
||||
check_input (void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
return input_avail;
|
||||
}
|
||||
|
||||
static int
|
||||
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;
|
||||
#if defined(DEBUG_CIR)
|
||||
uint16_t *p;
|
||||
@@ -514,10 +522,15 @@ cir_getchar (uint32_t timeout)
|
||||
|
||||
cir_ll_init ();
|
||||
|
||||
notification = 0;
|
||||
wait_usec = timeout;
|
||||
chopstx_usec_wait_var (&wait_usec);
|
||||
if (notification == 0)
|
||||
poll_desc.type = CHOPSTX_POLL_COND;
|
||||
poll_desc.ready = 0;
|
||||
poll_desc.cond = &cir_input_cnd;
|
||||
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;
|
||||
|
||||
/* Sleep 200ms to avoid detecting chatter inputs. */
|
||||
@@ -631,13 +644,10 @@ cir_getchar (uint32_t timeout)
|
||||
int
|
||||
pinpad_getline (int msg_code, uint32_t timeout)
|
||||
{
|
||||
extern chopstx_t openpgp_card_thd;
|
||||
|
||||
(void)msg_code;
|
||||
|
||||
DEBUG_INFO (">>>\r\n");
|
||||
|
||||
pin_thread = openpgp_card_thd;
|
||||
pin_input_len = 0;
|
||||
while (1)
|
||||
{
|
||||
@@ -663,7 +673,6 @@ pinpad_getline (int msg_code, uint32_t timeout)
|
||||
}
|
||||
|
||||
cir_ext_disable ();
|
||||
pin_thread = NULL;
|
||||
|
||||
return pin_input_len;
|
||||
}
|
||||
@@ -932,13 +941,12 @@ cir_timer_interrupt (void)
|
||||
{
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
notification = 1;
|
||||
chopstx_wakeup_usec_wait (pin_thread);
|
||||
}
|
||||
chopstx_mutex_lock (&cir_input_mtx);
|
||||
input_avail = 1;
|
||||
chopstx_cond_signal (&cir_input_cnd);
|
||||
chopstx_mutex_unlock (&cir_input_mtx);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_CIR)
|
||||
@@ -956,9 +964,14 @@ cir_timer_interrupt (void)
|
||||
}
|
||||
|
||||
|
||||
extern uint8_t __process6_stack_base__, __process6_stack_size__;
|
||||
const uint32_t __stackaddr_tim = (uint32_t)&__process6_stack_base__;
|
||||
const size_t __stacksize_tim = (size_t)&__process6_stack_size__;
|
||||
#define STACK_PROCESS_6
|
||||
#define STACK_PROCESS_7
|
||||
#include "stack-def.h"
|
||||
#define STACK_ADDR_TIM ((uintptr_t)process6_base)
|
||||
#define STACK_SIZE_TIM (sizeof process6_base)
|
||||
#define STACK_ADDR_EXT ((uintptr_t)process7_base)
|
||||
#define STACK_SIZE_EXT (sizeof process7_base)
|
||||
|
||||
#define PRIO_TIM 4
|
||||
|
||||
static void *
|
||||
@@ -978,9 +991,7 @@ tim_main (void *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern uint8_t __process7_stack_base__, __process7_stack_size__;
|
||||
const uint32_t __stackaddr_ext = (uint32_t)&__process7_stack_base__;
|
||||
const size_t __stacksize_ext = (size_t)&__process7_stack_size__;
|
||||
|
||||
#define PRIO_EXT 4
|
||||
|
||||
static void *
|
||||
@@ -1004,6 +1015,9 @@ ext_main (void *arg)
|
||||
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.
|
||||
*
|
||||
@@ -1044,8 +1058,8 @@ cir_init (void)
|
||||
TIMx->PSC = 72 - 1; /* 1 MHz */
|
||||
TIMx->ARR = 18000; /* 18 ms */
|
||||
/* 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_EXT, __stackaddr_ext, __stacksize_ext, ext_main, NULL);
|
||||
chopstx_create (PRIO_TIM, STACK_ADDR_TIM, STACK_SIZE_TIM, tim_main, NULL);
|
||||
chopstx_create (PRIO_EXT, STACK_ADDR_EXT, STACK_SIZE_EXT, ext_main, NULL);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* random.c -- get random bytes
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -24,8 +25,6 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "neug.h"
|
||||
|
||||
@@ -85,7 +84,6 @@ random_get_salt (uint8_t *p)
|
||||
}
|
||||
|
||||
|
||||
#ifdef KEYGEN_SUPPORT
|
||||
/*
|
||||
* Random byte iterator
|
||||
*/
|
||||
@@ -120,4 +118,3 @@ random_gen (void *arg, unsigned char *out, size_t out_len)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "sha256.h"
|
||||
|
||||
#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* sha512.c -- Compute SHA-512 hash (for little endian architecture).
|
||||
*
|
||||
* This module is written by gniibe, following the API of sha256.c.
|
||||
* This module is written by gniibe, following the API of sha256.c.
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "sha512.h"
|
||||
|
||||
#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
|
||||
|
||||
59
src/stack-def.h
Normal file
59
src/stack-def.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define SIZE_1 4096
|
||||
#define SIZE_2 4096
|
||||
#define SIZE_3 (4 * 4096)
|
||||
#else
|
||||
#define SIZE_0 0x0100 /* Main */
|
||||
#define SIZE_1 0x01a0 /* CCID */
|
||||
#define SIZE_2 0x0180 /* RNG */
|
||||
#define SIZE_3 0x1640 /* openpgp-card */
|
||||
#define SIZE_4 0x0000 /* --- */
|
||||
#define SIZE_5 0x0200 /* msc */
|
||||
#define SIZE_6 0x00c0 /* timer (cir) */
|
||||
#define SIZE_7 0x00c0 /* ext (cir) */
|
||||
#endif
|
||||
|
||||
#if defined(STACK_MAIN) && !defined(GNU_LINUX_EMULATION)
|
||||
/* Idle+Exception handlers */
|
||||
char __main_stack_end__[0] __attribute__ ((section(".main_stack")));
|
||||
char main_base[0x0080] __attribute__ ((section(".main_stack")));
|
||||
|
||||
/* Main program */
|
||||
char __process0_stack_end__[0] __attribute__ ((section(".process_stack.0")));
|
||||
char process0_base[SIZE_0] __attribute__ ((section(".process_stack.0")));
|
||||
#endif
|
||||
|
||||
/* First thread program */
|
||||
#if defined(STACK_PROCESS_1)
|
||||
char process1_base[SIZE_1] __attribute__ ((section(".process_stack.1")));
|
||||
#endif
|
||||
|
||||
/* Second thread program */
|
||||
#if defined(STACK_PROCESS_2)
|
||||
char process2_base[SIZE_2] __attribute__ ((section(".process_stack.2")));
|
||||
#endif
|
||||
|
||||
/* Third thread program */
|
||||
#if defined(STACK_PROCESS_3)
|
||||
char process3_base[SIZE_3] __attribute__ ((section(".process_stack.3")));
|
||||
#endif
|
||||
|
||||
/* Fourth thread program */
|
||||
#if defined(STACK_PROCESS_4)
|
||||
char process4_base[SIZE_4] __attribute__ ((section(".process_stack.4")));
|
||||
#endif
|
||||
|
||||
/* Fifth thread program */
|
||||
#if defined(STACK_PROCESS_5)
|
||||
char process5_base[SIZE_5] __attribute__ ((section(".process_stack.5")));
|
||||
#endif
|
||||
|
||||
/* Sixth thread program */
|
||||
#if defined(STACK_PROCESS_6)
|
||||
char process6_base[SIZE_6] __attribute__ ((section(".process_stack.6")));
|
||||
#endif
|
||||
|
||||
/* Seventh thread program */
|
||||
#if defined(STACK_PROCESS_7)
|
||||
char process7_base[SIZE_7] __attribute__ ((section(".process_stack.7")));
|
||||
#endif
|
||||
@@ -1,4 +1,6 @@
|
||||
#define GPG_APPLICATION_TERMINATED() set_res_sw (0x62, 0x85)
|
||||
#define GPG_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
|
||||
#define GPG_WRONG_LENGTH() set_res_sw (0x67, 0x00)
|
||||
#define GPG_SECURITY_FAILURE() set_res_sw (0x69, 0x82)
|
||||
#define GPG_SECURITY_AUTH_BLOCKED() set_res_sw (0x69, 0x83)
|
||||
#define GPG_CONDITION_NOT_SATISFIED() set_res_sw (0x69, 0x85)
|
||||
13
src/stdlib.h
13
src/stdlib.h
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* stdlib.h replacement to replace malloc functions
|
||||
*/
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#include <stddef.h> /* NULL */
|
||||
|
||||
#define malloc(size) gnuk_malloc (size)
|
||||
#define free(p) gnuk_free (p)
|
||||
|
||||
void *gnuk_malloc (size_t);
|
||||
void gnuk_free (void *);
|
||||
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
|
||||
646
src/sys.c
646
src/sys.c
@@ -1,646 +0,0 @@
|
||||
/*
|
||||
* sys.c - system routines for the initial page for STM32F103.
|
||||
*
|
||||
* Copyright (C) 2013, 2014 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"
|
||||
|
||||
|
||||
#define CORTEX_PRIORITY_BITS 4
|
||||
#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
|
||||
#define USB_LP_CAN1_RX0_IRQn 20
|
||||
#define STM32_USB_IRQ_PRIORITY 11
|
||||
|
||||
|
||||
#define STM32_SW_HSI (0 << 0)
|
||||
#define STM32_SW_PLL (2 << 0)
|
||||
#define STM32_PLLSRC_HSI (0 << 16)
|
||||
#define STM32_PLLSRC_HSE (1 << 16)
|
||||
|
||||
#define STM32_PLLXTPRE_DIV1 (0 << 17)
|
||||
#define STM32_PLLXTPRE_DIV2 (1 << 17)
|
||||
|
||||
#define STM32_HPRE_DIV1 (0 << 4)
|
||||
|
||||
#define STM32_PPRE1_DIV1 (0 << 8)
|
||||
#define STM32_PPRE1_DIV2 (4 << 8)
|
||||
|
||||
#define STM32_PPRE2_DIV1 (0 << 11)
|
||||
#define STM32_PPRE2_DIV2 (4 << 11)
|
||||
|
||||
#define STM32_ADCPRE_DIV4 (1 << 14)
|
||||
#define STM32_ADCPRE_DIV6 (2 << 14)
|
||||
|
||||
#define STM32_USBPRE_DIV1P5 (0 << 22)
|
||||
|
||||
#define STM32_MCO_NOCLOCK (0 << 24)
|
||||
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV2
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSE
|
||||
#define STM32_FLASHBITS 0x00000012
|
||||
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
|
||||
|
||||
#define STM32_SW STM32_SW_PLL
|
||||
#define STM32_HPRE STM32_HPRE_DIV1
|
||||
#define STM32_PPRE2 STM32_PPRE2_DIV1
|
||||
#define STM32_ADCPRE STM32_ADCPRE_DIV6
|
||||
#define STM32_MCOSEL STM32_MCO_NOCLOCK
|
||||
#define STM32_USBPRE STM32_USBPRE_DIV1P5
|
||||
|
||||
#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18)
|
||||
#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE)
|
||||
#define STM32_SYSCLK STM32_PLLCLKOUT
|
||||
#define STM32_HCLK (STM32_SYSCLK / 1)
|
||||
|
||||
struct NVIC {
|
||||
uint32_t ISER[8];
|
||||
uint32_t unused1[24];
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#define PERIPH_BASE 0x40000000
|
||||
#define APBPERIPH_BASE PERIPH_BASE
|
||||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
|
||||
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
|
||||
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
|
||||
|
||||
struct RCC {
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t CIR;
|
||||
volatile uint32_t APB2RSTR;
|
||||
volatile uint32_t APB1RSTR;
|
||||
volatile uint32_t AHBENR;
|
||||
volatile uint32_t APB2ENR;
|
||||
volatile uint32_t APB1ENR;
|
||||
volatile uint32_t BDCR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
|
||||
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
|
||||
static struct RCC *const RCC = ((struct RCC *const)RCC_BASE);
|
||||
|
||||
#define RCC_APB1ENR_USBEN 0x00800000
|
||||
#define RCC_APB1RSTR_USBRST 0x00800000
|
||||
|
||||
#define RCC_CR_HSION 0x00000001
|
||||
#define RCC_CR_HSIRDY 0x00000002
|
||||
#define RCC_CR_HSITRIM 0x000000F8
|
||||
#define RCC_CR_HSEON 0x00010000
|
||||
#define RCC_CR_HSERDY 0x00020000
|
||||
#define RCC_CR_PLLON 0x01000000
|
||||
#define RCC_CR_PLLRDY 0x02000000
|
||||
|
||||
#define RCC_CFGR_SWS 0x0000000C
|
||||
#define RCC_CFGR_SWS_HSI 0x00000000
|
||||
|
||||
#define RCC_AHBENR_CRCEN 0x0040
|
||||
|
||||
#define RCC_APB2RSTR_AFIORST 0x00000001
|
||||
#define RCC_APB2RSTR_IOPARST 0x00000004
|
||||
#define RCC_APB2RSTR_IOPBRST 0x00000008
|
||||
#define RCC_APB2RSTR_IOPCRST 0x00000010
|
||||
#define RCC_APB2RSTR_IOPDRST 0x00000020
|
||||
|
||||
#define RCC_APB2ENR_AFIOEN 0x00000001
|
||||
#define RCC_APB2ENR_IOPAEN 0x00000004
|
||||
#define RCC_APB2ENR_IOPBEN 0x00000008
|
||||
#define RCC_APB2ENR_IOPCEN 0x00000010
|
||||
#define RCC_APB2ENR_IOPDEN 0x00000020
|
||||
|
||||
struct FLASH {
|
||||
volatile uint32_t ACR;
|
||||
volatile uint32_t KEYR;
|
||||
volatile uint32_t OPTKEYR;
|
||||
volatile uint32_t SR;
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t AR;
|
||||
volatile uint32_t RESERVED;
|
||||
volatile uint32_t OBR;
|
||||
volatile uint32_t WRPR;
|
||||
};
|
||||
|
||||
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000)
|
||||
static struct FLASH *const FLASH = ((struct FLASH *const) FLASH_R_BASE);
|
||||
|
||||
static void
|
||||
clock_init (void)
|
||||
{
|
||||
/* HSI setup */
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
while (!(RCC->CR & RCC_CR_HSIRDY))
|
||||
;
|
||||
/* Reset HSEON, HSEBYP, CSSON, and PLLON, not touching RCC_CR_HSITRIM */
|
||||
RCC->CR &= (RCC_CR_HSITRIM | RCC_CR_HSION);
|
||||
RCC->CFGR = 0;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
|
||||
;
|
||||
|
||||
/* HSE setup */
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR & RCC_CR_HSERDY))
|
||||
;
|
||||
|
||||
/* PLL setup */
|
||||
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR & RCC_CR_PLLRDY))
|
||||
;
|
||||
|
||||
/* Clock settings */
|
||||
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE
|
||||
| STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
|
||||
|
||||
/*
|
||||
* We don't touch RCC->CR2, RCC->CFGR2, RCC->CFGR3, and RCC->CIR.
|
||||
*/
|
||||
|
||||
/* Flash setup */
|
||||
FLASH->ACR = STM32_FLASHBITS;
|
||||
|
||||
/* CRC */
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
|
||||
/* Switching on the configured clock source. */
|
||||
RCC->CFGR |= STM32_SW;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
struct AFIO
|
||||
{
|
||||
volatile uint32_t EVCR;
|
||||
volatile uint32_t MAPR;
|
||||
volatile uint32_t EXTICR[4];
|
||||
uint32_t RESERVED0;
|
||||
volatile uint32_t MAPR2;
|
||||
};
|
||||
|
||||
#define AFIO_BASE 0x40010000
|
||||
static struct AFIO *const AFIO = (struct AFIO *const)AFIO_BASE;
|
||||
|
||||
#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP 0x00000800
|
||||
#define AFIO_MAPR_SWJ_CFG_DISABLE 0x04000000
|
||||
|
||||
|
||||
struct GPIO {
|
||||
volatile uint32_t CRL;
|
||||
volatile uint32_t CRH;
|
||||
volatile uint32_t IDR;
|
||||
volatile uint32_t ODR;
|
||||
volatile uint32_t BSRR;
|
||||
volatile uint32_t BRR;
|
||||
volatile uint32_t LCKR;
|
||||
};
|
||||
|
||||
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
|
||||
#define GPIOA ((struct GPIO *) GPIOA_BASE)
|
||||
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
|
||||
#define GPIOB ((struct GPIO *) GPIOB_BASE)
|
||||
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
|
||||
#define GPIOC ((struct GPIO *) GPIOC_BASE)
|
||||
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
|
||||
#define GPIOD ((struct GPIO *) GPIOD_BASE)
|
||||
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
|
||||
#define GPIOE ((struct GPIO *) GPIOE_BASE)
|
||||
|
||||
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
|
||||
#ifdef GPIO_USB_BASE
|
||||
static struct GPIO *const GPIO_USB = ((struct GPIO *const) GPIO_USB_BASE);
|
||||
#endif
|
||||
#ifdef GPIO_OTHER_BASE
|
||||
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
|
||||
#endif
|
||||
|
||||
static void
|
||||
gpio_init (void)
|
||||
{
|
||||
/* Enable GPIO clock. */
|
||||
RCC->APB2ENR |= RCC_ENR_IOP_EN;
|
||||
RCC->APB2RSTR = RCC_RSTR_IOP_RST;
|
||||
RCC->APB2RSTR = 0;
|
||||
|
||||
#ifdef AFIO_MAPR_SOMETHING
|
||||
AFIO->MAPR |= AFIO_MAPR_SOMETHING;
|
||||
#endif
|
||||
|
||||
GPIO_USB->ODR = VAL_GPIO_ODR;
|
||||
GPIO_USB->CRH = VAL_GPIO_CRH;
|
||||
GPIO_USB->CRL = VAL_GPIO_CRL;
|
||||
|
||||
#if GPIO_USB_BASE != GPIO_LED_BASE
|
||||
GPIO_LED->ODR = VAL_GPIO_LED_ODR;
|
||||
GPIO_LED->CRH = VAL_GPIO_LED_CRH;
|
||||
GPIO_LED->CRL = VAL_GPIO_LED_CRL;
|
||||
#endif
|
||||
|
||||
#ifdef GPIO_OTHER_BASE
|
||||
GPIO_OTHER->ODR = VAL_GPIO_OTHER_ODR;
|
||||
GPIO_OTHER->CRH = VAL_GPIO_OTHER_CRH;
|
||||
GPIO_OTHER->CRL = VAL_GPIO_OTHER_CRL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
usb_cable_config (int enable)
|
||||
{
|
||||
#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;
|
||||
}
|
||||
|
||||
extern uint8_t __flash_start__, __flash_end__;
|
||||
|
||||
static int
|
||||
flash_write (uint32_t dst_addr, const uint8_t *src, size_t len)
|
||||
{
|
||||
int status;
|
||||
uint32_t flash_start = (uint32_t)&__flash_start__;
|
||||
uint32_t flash_end = (uint32_t)&__flash_end__;
|
||||
|
||||
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 = (uint32_t)&__flash_start__;
|
||||
uint32_t end = (uint32_t)&__flash_end__;
|
||||
int r;
|
||||
|
||||
while (addr < end)
|
||||
{
|
||||
r = flash_erase_page (addr);
|
||||
if (r != 0)
|
||||
break;
|
||||
|
||||
addr += FLASH_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.0" */
|
||||
'2', 0, '.', 0, '0', 0,
|
||||
};
|
||||
115
src/sys.h
115
src/sys.h
@@ -1,115 +0,0 @@
|
||||
extern const uint8_t sys_version[8];
|
||||
|
||||
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]) ();
|
||||
}
|
||||
1890
src/usb-ccid.c
Normal file
1890
src/usb-ccid.c
Normal file
File diff suppressed because it is too large
Load Diff
1460
src/usb-icc.c
1460
src/usb-icc.c
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* usb-msc.c -- USB Mass Storage Class protocol handling
|
||||
*
|
||||
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2012, 2013, 2015
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -30,9 +31,11 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb-msc.h"
|
||||
|
||||
extern uint8_t __process5_stack_base__, __process5_stack_size__;
|
||||
const uint32_t __stackaddr_msc = (uint32_t)&__process5_stack_base__;
|
||||
const size_t __stacksize_msc = (size_t)&__process5_stack_size__;
|
||||
#define STACK_PROCESS_5
|
||||
#include "stack-def.h"
|
||||
#define STACK_ADDR_MSC ((uintptr_t)process5_base)
|
||||
#define STACK_SIZE_MSC (sizeof process5_base)
|
||||
|
||||
#define PRIO_MSC 3
|
||||
|
||||
static chopstx_mutex_t a_pinpad_mutex;
|
||||
@@ -85,13 +88,12 @@ static void usb_start_transmit (const uint8_t *p, size_t n)
|
||||
|
||||
/* "Data Transmitted" callback */
|
||||
void
|
||||
EP6_IN_Callback (void)
|
||||
EP6_IN_Callback (uint16_t len)
|
||||
{
|
||||
size_t n;
|
||||
size_t n = len;
|
||||
|
||||
chopstx_mutex_lock (msc_mutex);
|
||||
|
||||
n = (size_t)usb_lld_tx_data_len (ENDP6);
|
||||
ep6_in.txbuf += n;
|
||||
ep6_in.txcnt += n;
|
||||
ep6_in.txsize -= n;
|
||||
@@ -131,14 +133,13 @@ static void usb_start_receive (uint8_t *p, size_t n)
|
||||
|
||||
/* "Data Received" call back */
|
||||
void
|
||||
EP6_OUT_Callback (void)
|
||||
EP6_OUT_Callback (uint16_t len)
|
||||
{
|
||||
size_t n;
|
||||
size_t n = len;
|
||||
int err = 0;
|
||||
|
||||
chopstx_mutex_lock (msc_mutex);
|
||||
|
||||
n = (size_t)usb_lld_rx_data_len (ENDP6);
|
||||
if (n > ep6_out.rxsize)
|
||||
{ /* buffer overflow */
|
||||
err = 1;
|
||||
@@ -170,11 +171,13 @@ EP6_OUT_Callback (void)
|
||||
}
|
||||
|
||||
static const uint8_t scsi_inquiry_data_00[] = { 0, 0, 0, 0, 0 };
|
||||
static const uint8_t scsi_inquiry_data_83[] = { 0, 0x83, 0, 0 };
|
||||
|
||||
|
||||
static const uint8_t scsi_inquiry_data[] = {
|
||||
0x00, /* Direct Access Device. */
|
||||
0x80, /* RMB = 1: Removable Medium. */
|
||||
0x05, /* Version: SPC-3. */
|
||||
0x00, /* Version: not claim conformance. */
|
||||
0x02, /* Response format: SPC-3. */
|
||||
36 - 4, /* Additional Length. */
|
||||
0x00,
|
||||
@@ -316,7 +319,7 @@ msc_handle_command (void)
|
||||
/* Error occured, ignore the request and go into error state */
|
||||
msc_state = MSC_ERROR;
|
||||
usb_lld_stall_rx (ENDP6);
|
||||
goto done;
|
||||
goto done;
|
||||
}
|
||||
|
||||
n = ep6_out.rxcnt;
|
||||
@@ -330,6 +333,11 @@ msc_handle_command (void)
|
||||
|
||||
CSW.dCSWTag = CBW.dCBWTag;
|
||||
switch (CBW.CBWCB[0]) {
|
||||
case SCSI_REPORT_LUN:
|
||||
buf[0] = buf[1] = buf[2] = buf[3] = 0;
|
||||
buf[4] = buf[5] = buf[6] = buf[7] = 0;
|
||||
msc_send_result (buf, 8);
|
||||
goto done;
|
||||
case SCSI_REQUEST_SENSE:
|
||||
if (CBW.CBWCB[1] & 0x01) /* DESC */
|
||||
msc_send_result ((uint8_t *)&scsi_sense_data_desc,
|
||||
@@ -345,10 +353,18 @@ msc_handle_command (void)
|
||||
}
|
||||
goto done;
|
||||
case SCSI_INQUIRY:
|
||||
if (CBW.CBWCB[1] & 0x01) /* EVPD */
|
||||
/* assume page 00 */
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data_00,
|
||||
sizeof scsi_inquiry_data_00);
|
||||
if (CBW.CBWCB[1] & 0x01)
|
||||
/* EVPD */
|
||||
{
|
||||
if (CBW.CBWCB[2] == 0x83)
|
||||
/* Handle the case Page Code 0x83 */
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data_83,
|
||||
sizeof scsi_inquiry_data_83);
|
||||
else
|
||||
/* Otherwise, assume page 00 */
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data_00,
|
||||
sizeof scsi_inquiry_data_00);
|
||||
}
|
||||
else
|
||||
msc_send_result ((uint8_t *)&scsi_inquiry_data,
|
||||
sizeof scsi_inquiry_data);
|
||||
@@ -462,6 +478,7 @@ msc_handle_command (void)
|
||||
if (CBW.CBWCB[8]-- == 0)
|
||||
CBW.CBWCB[7]--;
|
||||
CSW.dCSWDataResidue += 512;
|
||||
lba++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -507,6 +524,7 @@ msc_handle_command (void)
|
||||
if (CBW.CBWCB[8]-- == 0)
|
||||
CBW.CBWCB[7]--;
|
||||
CSW.dCSWDataResidue -= 512;
|
||||
lba++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -552,5 +570,5 @@ msc_main (void *arg)
|
||||
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_VERIFY10 0x2F
|
||||
#define SCSI_READ_FORMAT_CAPACITIES 0x23
|
||||
|
||||
#define SCSI_SYNCHRONIZE_CACHE 0x35
|
||||
#define SCSI_REPORT_LUN 0xA0
|
||||
|
||||
#define MSC_IDLE 0
|
||||
#define MSC_DATA_OUT 1
|
||||
|
||||
@@ -3,7 +3,29 @@
|
||||
#ifndef __USB_CONF_H
|
||||
#define __USB_CONF_H
|
||||
|
||||
#define NUM_STRING_DESC 7
|
||||
#define CCID_NUM_INTERFACES 1
|
||||
#define CCID_INTERFACE 0
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
#define HID_NUM_INTERFACES 1
|
||||
#define HID_INTERFACE 1
|
||||
#else
|
||||
#define HID_NUM_INTERFACES 0
|
||||
#endif
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
#define VCOM_NUM_INTERFACES 2
|
||||
#define VCOM_INTERFACE_0 (CCID_NUM_INTERFACES + HID_NUM_INTERFACES)
|
||||
#define VCOM_INTERFACE_1 (CCID_NUM_INTERFACES + HID_NUM_INTERFACES + 1)
|
||||
#else
|
||||
#define VCOM_NUM_INTERFACES 0
|
||||
#endif
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
#define MSC_NUM_INTERFACES 1
|
||||
#define MSC_INTERFACE (CCID_NUM_INTERFACES + HID_NUM_INTERFACES + VCOM_NUM_INTERFACES)
|
||||
#else
|
||||
#define MSC_NUM_INTERFACES 0
|
||||
#endif
|
||||
#define NUM_INTERFACES (CCID_NUM_INTERFACES + HID_NUM_INTERFACES \
|
||||
+ VCOM_NUM_INTERFACES + MSC_NUM_INTERFACES)
|
||||
|
||||
#if defined(USB_SELF_POWERED)
|
||||
#define USB_INITIAL_FEATURE 0xC0 /* bmAttributes: self powered */
|
||||
|
||||
463
src/usb_ctrl.c
463
src/usb_ctrl.c
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* usb_ctrl.c - USB control pipe device specific code for Gnuk
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -37,7 +38,7 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb_conf.h"
|
||||
#include "gnuk.h"
|
||||
#include "stm32f103.h"
|
||||
#include "neug.h"
|
||||
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
#include "usb-cdc.h"
|
||||
@@ -57,68 +58,35 @@ static struct line_coding line_coding = {
|
||||
0x08 /* bits: 8 */
|
||||
};
|
||||
|
||||
#define CDC_CTRL_DTR 0x0001
|
||||
|
||||
static int
|
||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
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)
|
||||
{
|
||||
usb_lld_set_data_to_send (&line_coding, sizeof(line_coding));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
if (arg->request == USB_CDC_REQ_GET_LINE_CODING)
|
||||
return usb_lld_ctrl_send (dev, &line_coding, sizeof (line_coding));
|
||||
}
|
||||
else /* USB_SETUP_SET (req) */
|
||||
{
|
||||
if (req_no == USB_CDC_REQ_SET_LINE_CODING)
|
||||
{
|
||||
usb_lld_set_data_to_recv (&line_coding, sizeof(line_coding));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||
{
|
||||
uint8_t connected_saved = stdout.connected;
|
||||
|
||||
if (value != 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;
|
||||
}
|
||||
if (arg->request == USB_CDC_REQ_SET_LINE_CODING
|
||||
&& arg->len == sizeof (line_coding))
|
||||
return usb_lld_ctrl_recv (dev, &line_coding, sizeof (line_coding));
|
||||
else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define VCOM_NUM_INTERFACES 2
|
||||
#else
|
||||
#define VCOM_NUM_INTERFACES 0
|
||||
#endif
|
||||
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
#include "usb-msc.h"
|
||||
#define MSC_NUM_INTERFACES 1
|
||||
#else
|
||||
#define MSC_NUM_INTERFACES 0
|
||||
#endif
|
||||
|
||||
#define NUM_INTERFACES (2+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES)
|
||||
#define MSC_INTERFACE_NO (2+VCOM_NUM_INTERFACES)
|
||||
|
||||
uint32_t bDeviceState = UNCONNECTED; /* USB device status */
|
||||
|
||||
#define USB_HID_REQ_GET_REPORT 1
|
||||
@@ -140,15 +108,25 @@ static uint16_t hid_report;
|
||||
#endif
|
||||
|
||||
static void
|
||||
gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
gnuk_setup_endpoints_for_interface (struct usb_dev *dev,
|
||||
uint16_t interface, int stop)
|
||||
{
|
||||
if (interface == 0)
|
||||
#if !defined(GNU_LINUX_EMULATION)
|
||||
(void)dev;
|
||||
#endif
|
||||
|
||||
if (interface == CCID_INTERFACE)
|
||||
{
|
||||
if (!stop)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP1, 1, 1);
|
||||
usb_lld_setup_endp (dev, ENDP2, 0, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, ENDP1_RXADDR,
|
||||
ENDP1_TXADDR, GNUK_MAX_PACKET_SIZE);
|
||||
usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -158,29 +136,42 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
}
|
||||
}
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
else if (interface == 1)
|
||||
else if (interface == HID_INTERFACE)
|
||||
{
|
||||
if (!stop)
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP7, 0, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP7, EP_INTERRUPT, 0, 0, ENDP7_TXADDR, 0);
|
||||
#endif
|
||||
else
|
||||
usb_lld_stall_tx (ENDP7);
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
else if (interface == 2)
|
||||
else if (interface == VCOM_INTERFACE_0)
|
||||
{
|
||||
if (!stop)
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP4, 0, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP4, EP_INTERRUPT, 0, 0, ENDP4_TXADDR, 0);
|
||||
#endif
|
||||
else
|
||||
usb_lld_stall_tx (ENDP4);
|
||||
}
|
||||
else if (interface == 3)
|
||||
else if (interface == VCOM_INTERFACE_1)
|
||||
{
|
||||
if (!stop)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP3, 0, 1);
|
||||
usb_lld_setup_endp (dev, ENDP5, 1, 0);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, 0, ENDP3_TXADDR, 0);
|
||||
usb_lld_setup_endpoint (ENDP5, EP_BULK, 0, ENDP5_RXADDR, 0,
|
||||
VIRTUAL_COM_PORT_DATA_SIZE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -190,11 +181,15 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
}
|
||||
#endif
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
else if (interface == MSC_INTERFACE_NO)
|
||||
else if (interface == MSC_INTERFACE)
|
||||
{
|
||||
if (!stop)
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP6, 1, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP6, EP_BULK, 0,
|
||||
ENDP6_RXADDR, ENDP6_TXADDR, 64);
|
||||
#endif
|
||||
else
|
||||
{
|
||||
usb_lld_stall_tx (ENDP6);
|
||||
@@ -205,335 +200,341 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
}
|
||||
|
||||
void
|
||||
usb_cb_device_reset (void)
|
||||
usb_device_reset (struct usb_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Set DEVICE as not configured */
|
||||
usb_lld_set_configuration (0);
|
||||
|
||||
/* Current Feature initialization */
|
||||
usb_lld_set_feature (USB_INITIAL_FEATURE);
|
||||
|
||||
usb_lld_reset ();
|
||||
usb_lld_reset (dev, USB_INITIAL_FEATURE);
|
||||
|
||||
/* Initialize Endpoint 0 */
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP0, 1, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
||||
GNUK_MAX_PACKET_SIZE);
|
||||
64);
|
||||
#endif
|
||||
|
||||
/* Stop the interface */
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
gnuk_setup_endpoints_for_interface (i, 0);
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 1);
|
||||
|
||||
bDeviceState = ATTACHED;
|
||||
ccid_usb_reset (1);
|
||||
}
|
||||
|
||||
#define USB_CCID_REQ_ABORT 0x01
|
||||
#define USB_CCID_REQ_GET_CLOCK_FREQUENCIES 0x02
|
||||
#define USB_CCID_REQ_GET_DATA_RATES 0x03
|
||||
|
||||
static const uint8_t freq_table[] = { 0xf3, 0x0d, 0, 0, }; /* dwDefaultClock */
|
||||
|
||||
static const uint8_t freq_table[] = { 0xa0, 0x0f, 0, 0, }; /* dwDefaultClock */
|
||||
static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
|
||||
|
||||
#if defined(PINPAD_DND_SUPPORT)
|
||||
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
|
||||
#endif
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
static const uint8_t *const mem_info[] = { &_regnual_start, __heap_end__, };
|
||||
#endif
|
||||
|
||||
#define USB_FSIJ_GNUK_MEMINFO 0
|
||||
#define USB_FSIJ_GNUK_DOWNLOAD 1
|
||||
#define USB_FSIJ_GNUK_EXEC 2
|
||||
#define USB_FSIJ_GNUK_CARD_CHANGE 3
|
||||
|
||||
static uint32_t rbit (uint32_t v)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
/* 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;
|
||||
const uint32_t *p;
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
crc32_rv_reset ();
|
||||
|
||||
for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
|
||||
CRC->DR = rbit (*p);
|
||||
crc32_rv_step (rbit (*p));
|
||||
|
||||
if ((rbit (CRC->DR) ^ crc32) == 0xffffffff)
|
||||
return USB_SUCCESS;
|
||||
if ((rbit (crc32_rv_get ()) ^ crc32) == 0xffffffff)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
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 (USB_SETUP_GET (req))
|
||||
if (USB_SETUP_GET (arg->type))
|
||||
{
|
||||
if (req_no == USB_FSIJ_GNUK_MEMINFO)
|
||||
{
|
||||
usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (arg->request == USB_FSIJ_GNUK_MEMINFO)
|
||||
return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else /* SETUP_SET */
|
||||
{
|
||||
uint8_t *addr = (uint8_t *)(0x20000000 + value * 0x100 + index);
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
uint8_t *addr = sram_address ((arg->value * 0x100) + arg->index);
|
||||
#endif
|
||||
|
||||
if (req_no == USB_FSIJ_GNUK_DOWNLOAD)
|
||||
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
||||
{
|
||||
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||
return USB_UNSUPPORT;
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
return -1;
|
||||
|
||||
if (addr < &_regnual_start || addr + len > __heap_end__)
|
||||
return USB_UNSUPPORT;
|
||||
if (addr < &_regnual_start || addr + arg->len > __heap_end__)
|
||||
return -1;
|
||||
|
||||
if (index + len < 256)
|
||||
memset (addr + index + len, 0, 256 - (index + len));
|
||||
if (arg->index + arg->len < 256)
|
||||
memset (addr + arg->index + arg->len, 0,
|
||||
256 - (arg->index + arg->len));
|
||||
|
||||
usb_lld_set_data_to_recv (addr, len);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_ctrl_recv (dev, addr, arg->len);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else if (req_no == USB_FSIJ_GNUK_EXEC && len == 0)
|
||||
else if (arg->request == USB_FSIJ_GNUK_EXEC && arg->len == 0)
|
||||
{
|
||||
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||
return USB_UNSUPPORT;
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
return -1;
|
||||
|
||||
if (((uint32_t)addr & 0x03))
|
||||
return USB_UNSUPPORT;
|
||||
if (((uintptr_t)addr & 0x03))
|
||||
return -1;
|
||||
|
||||
return download_check_crc32 ((uint32_t *)addr);
|
||||
return download_check_crc32 (dev, (uint32_t *)addr);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && len == 0)
|
||||
else if (arg->request == USB_FSIJ_GNUK_CARD_CHANGE && arg->len == 0)
|
||||
{
|
||||
if (value != 0 && value != 1 && value != 2)
|
||||
return USB_UNSUPPORT;
|
||||
if (arg->value != 0 && arg->value != 1 && arg->value != 2)
|
||||
return -1;
|
||||
|
||||
ccid_card_change_signal (value);
|
||||
return USB_SUCCESS;
|
||||
ccid_card_change_signal (arg->value);
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||
{
|
||||
if (index == 0)
|
||||
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)
|
||||
{
|
||||
usb_lld_set_data_to_send (freq_table, sizeof (freq_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_CCID_REQ_GET_DATA_RATES)
|
||||
{
|
||||
usb_lld_set_data_to_send (data_rate_table,
|
||||
sizeof (data_rate_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
if (arg->request == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
||||
return usb_lld_ctrl_send (dev, freq_table, sizeof (freq_table));
|
||||
else if (arg->request == USB_CCID_REQ_GET_DATA_RATES)
|
||||
return usb_lld_ctrl_send (dev, data_rate_table,
|
||||
sizeof (data_rate_table));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req_no == USB_CCID_REQ_ABORT)
|
||||
if (arg->request == USB_CCID_REQ_ABORT)
|
||||
/* wValue: bSeq, bSlot */
|
||||
/* Abortion is not supported in Gnuk */
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
else if (index == 1)
|
||||
else if (arg->index == HID_INTERFACE)
|
||||
{
|
||||
switch (req_no)
|
||||
switch (arg->request)
|
||||
{
|
||||
case USB_HID_REQ_GET_IDLE:
|
||||
usb_lld_set_data_to_send (&hid_idle_rate, 1);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_ctrl_send (dev, &hid_idle_rate, 1);
|
||||
case USB_HID_REQ_SET_IDLE:
|
||||
usb_lld_set_data_to_recv (&hid_idle_rate, 1);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_ctrl_recv (dev, &hid_idle_rate, 1);
|
||||
|
||||
case USB_HID_REQ_GET_REPORT:
|
||||
/* Request of LED status and key press */
|
||||
usb_lld_set_data_to_send (&hid_report, 2);
|
||||
return USB_SUCCESS;
|
||||
return usb_lld_ctrl_send (dev, &hid_report, 2);
|
||||
|
||||
case USB_HID_REQ_SET_REPORT:
|
||||
/* Received LED set request */
|
||||
if (len == 1)
|
||||
usb_lld_set_data_to_recv (&hid_report, len);
|
||||
return USB_SUCCESS;
|
||||
if (arg->len == 1)
|
||||
return usb_lld_ctrl_recv (dev, &hid_report, arg->len);
|
||||
else
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
|
||||
case USB_HID_REQ_GET_PROTOCOL:
|
||||
case USB_HID_REQ_SET_PROTOCOL:
|
||||
/* This driver doesn't support boot protocol. */
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
|
||||
default:
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
else if (index == 2)
|
||||
return vcom_port_data_setup (req, req_no, value);
|
||||
else if (arg->index == VCOM_INTERFACE_0)
|
||||
return vcom_port_data_setup (dev);
|
||||
#endif
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
else if (index == MSC_INTERFACE_NO)
|
||||
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)
|
||||
{
|
||||
usb_lld_set_data_to_send (lun_table, sizeof (lun_table));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
if (arg->request == MSC_GET_MAX_LUN_COMMAND)
|
||||
return usb_lld_ctrl_send (dev, lun_table, sizeof (lun_table));
|
||||
}
|
||||
else
|
||||
if (req_no == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||
/* Should call resetting MSC thread, something like msc_reset() */
|
||||
return USB_SUCCESS;
|
||||
if (arg->request == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len)
|
||||
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 (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC && len == 0)
|
||||
if (USB_SETUP_SET (arg->type) && arg->request == USB_FSIJ_GNUK_EXEC)
|
||||
{
|
||||
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
return;
|
||||
|
||||
(void)value; (void)index;
|
||||
bDeviceState = UNCONNECTED;
|
||||
usb_lld_prepare_shutdown (); /* No further USB communication */
|
||||
*icc_state_p = ICC_STATE_EXEC_REQUESTED;
|
||||
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))
|
||||
{
|
||||
if (index == 1 && 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)
|
||||
ccid_card_change_signal (CARD_CHANGE_TOGGLE);
|
||||
|
||||
hid_report_saved = hid_report;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
||||
int
|
||||
usb_set_configuration (struct usb_dev *dev)
|
||||
{
|
||||
int i;
|
||||
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 (dev, 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 (dev, i, 1);
|
||||
bDeviceState = ADDRESSED;
|
||||
return USB_SUCCESS;
|
||||
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);
|
||||
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;
|
||||
ccid_usb_reset (1);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
/* Do nothing when current_conf == value */
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
|
||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
|
||||
|
||||
int
|
||||
usb_set_interface (struct usb_dev *dev)
|
||||
{
|
||||
static const uint8_t zero = 0;
|
||||
uint16_t interface = dev->dev_req.index;
|
||||
uint16_t alt = dev->dev_req.value;
|
||||
|
||||
if (interface >= NUM_INTERFACES)
|
||||
return USB_UNSUPPORT;
|
||||
return -1;
|
||||
|
||||
switch (cmd)
|
||||
if (alt != 0)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
case USB_SET_INTERFACE:
|
||||
if (alt != 0)
|
||||
return USB_UNSUPPORT;
|
||||
else
|
||||
{
|
||||
gnuk_setup_endpoints_for_interface (interface, 0);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
||||
case USB_GET_INTERFACE:
|
||||
usb_lld_set_data_to_send (&zero, 1);
|
||||
return USB_SUCCESS;
|
||||
|
||||
default:
|
||||
case USB_QUERY_INTERFACE:
|
||||
return USB_SUCCESS;
|
||||
gnuk_setup_endpoints_for_interface (dev, interface, 0);
|
||||
ccid_usb_reset (0);
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define INTR_REQ_USB 20
|
||||
|
||||
void *
|
||||
usb_intr (void *arg)
|
||||
int
|
||||
usb_get_interface (struct usb_dev *dev)
|
||||
{
|
||||
chopstx_intr_t interrupt;
|
||||
const uint8_t zero = 0;
|
||||
uint16_t interface = dev->dev_req.index;
|
||||
|
||||
(void)arg;
|
||||
usb_lld_init (USB_INITIAL_FEATURE);
|
||||
chopstx_claim_irq (&interrupt, INTR_REQ_USB);
|
||||
usb_interrupt_handler ();
|
||||
if (interface >= NUM_INTERFACES)
|
||||
return -1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
chopstx_intr_wait (&interrupt);
|
||||
|
||||
/* Process interrupt. */
|
||||
usb_interrupt_handler ();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return usb_lld_ctrl_send (dev, &zero, 1);
|
||||
}
|
||||
|
||||
int
|
||||
usb_get_status_interface (struct usb_dev *dev)
|
||||
{
|
||||
const uint16_t status_info = 0;
|
||||
uint16_t interface = dev->dev_req.index;
|
||||
|
||||
if (interface >= NUM_INTERFACES)
|
||||
return -1;
|
||||
|
||||
return usb_lld_ctrl_send (dev, &status_info, 2);
|
||||
}
|
||||
|
||||
238
src/usb_desc.c
238
src/usb_desc.c
@@ -53,15 +53,18 @@ static const uint8_t hid_report_desc[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#define USB_ICC_INTERFACE_CLASS 0x0B
|
||||
#define USB_ICC_INTERFACE_SUBCLASS 0x00
|
||||
#define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00
|
||||
#define USB_ICC_DATA_SIZE 64
|
||||
#define USB_CCID_INTERFACE_CLASS 0x0B
|
||||
#define USB_CCID_INTERFACE_SUBCLASS 0x00
|
||||
#define USB_CCID_INTERFACE_BULK_PROTOCOL 0x00
|
||||
#define USB_CCID_DATA_SIZE 64
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t gnukDeviceDescriptor[] = {
|
||||
#if !defined(GNU_LINUX_EMULATION)
|
||||
static const
|
||||
#endif
|
||||
uint8_t device_desc[] = {
|
||||
18, /* bLength */
|
||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||
0x00, /* bDeviceClass: 0 means deferred to interface */
|
||||
0x00, /* bDeviceSubClass */
|
||||
@@ -74,46 +77,36 @@ static const uint8_t gnukDeviceDescriptor[] = {
|
||||
0x01 /* bNumConfigurations */
|
||||
};
|
||||
|
||||
#define ICC_TOTAL_LENGTH (9+9+54+7+7+7)
|
||||
#define ICC_NUM_INTERFACES 1
|
||||
#define CCID_TOTAL_LENGTH (9+9+54+7+7+7)
|
||||
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
#define HID_TOTAL_LENGTH (9+9+7)
|
||||
#define HID_NUM_INTERFACES 1
|
||||
#else
|
||||
#define HID_TOTAL_LENGTH 0
|
||||
#define HID_NUM_INTERFACES 0
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
#define VCOM_TOTAL_LENGTH (9+5+5+4+5+7+9+7+7)
|
||||
#define VCOM_NUM_INTERFACES 2
|
||||
#else
|
||||
#define VCOM_TOTAL_LENGTH 0
|
||||
#define VCOM_NUM_INTERFACES 0
|
||||
#endif
|
||||
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
#define MSC_TOTAL_LENGTH (9+7+7)
|
||||
#define MSC_NUM_INTERFACES 1
|
||||
#else
|
||||
#define MSC_TOTAL_LENGTH 0
|
||||
#define MSC_NUM_INTERFACES 0
|
||||
#endif
|
||||
|
||||
#define W_TOTAL_LENGTH (ICC_TOTAL_LENGTH + HID_TOTAL_LENGTH \
|
||||
#define W_TOTAL_LENGTH (CCID_TOTAL_LENGTH + HID_TOTAL_LENGTH \
|
||||
+ VCOM_TOTAL_LENGTH + MSC_TOTAL_LENGTH)
|
||||
#define NUM_INTERFACES (ICC_NUM_INTERFACES + HID_NUM_INTERFACES \
|
||||
+ VCOM_NUM_INTERFACES + MSC_NUM_INTERFACES)
|
||||
|
||||
|
||||
|
||||
/* Configuation Descriptor */
|
||||
static const uint8_t gnukConfigDescriptor[] = {
|
||||
static const uint8_t config_desc[] = {
|
||||
9, /* bLength: Configuation Descriptor size */
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
||||
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
|
||||
NUM_INTERFACES, /* bNumInterfaces: */
|
||||
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
|
||||
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
|
||||
NUM_INTERFACES, /* bNumInterfaces: */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
USB_INITIAL_FEATURE, /* bmAttributes*/
|
||||
@@ -121,13 +114,13 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
|
||||
/* Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
0, /* bInterfaceNumber: Index of this interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
CCID_INTERFACE, /* bInterfaceNumber: Index of this interface */
|
||||
0, /* Alternate setting for this interface */
|
||||
3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
|
||||
USB_ICC_INTERFACE_CLASS,
|
||||
USB_ICC_INTERFACE_SUBCLASS,
|
||||
USB_ICC_INTERFACE_BULK_PROTOCOL,
|
||||
USB_CCID_INTERFACE_CLASS,
|
||||
USB_CCID_INTERFACE_SUBCLASS,
|
||||
USB_CCID_INTERFACE_BULK_PROTOCOL,
|
||||
0, /* string index for interface */
|
||||
|
||||
/* ICC Descriptor */
|
||||
@@ -135,42 +128,36 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
0x21, /* bDescriptorType: USBDESCR_ICC */
|
||||
0x10, 0x01, /* bcdCCID: revision 1.1 (of CCID) */
|
||||
0, /* bMaxSlotIndex: */
|
||||
1, /* bVoltageSupport: FIXED VALUE */
|
||||
1, /* bVoltageSupport: 5V-only */
|
||||
0x02, 0, 0, 0, /* dwProtocols: T=1 */
|
||||
0xf3, 0x0d, 0, 0, /* dwDefaultClock: 3571 (non-ICCD): 3580 (ICCD) */
|
||||
0xf3, 0x0d, 0, 0, /* dwMaximumClock: 3571 (non-ICCD): 3580 (ICCD) */
|
||||
1, /* bNumClockSupported: FIXED VALUE */
|
||||
0x80, 0x25, 0, 0, /* dwDataRate: 9600: FIXED VALUE */
|
||||
0x80, 0x25, 0, 0, /* dwMaxDataRate: 9600: FIXED VALUE */
|
||||
1, /* bNumDataRateSupported: FIXED VALUE */
|
||||
0xa0, 0x0f, 0, 0, /* dwDefaultClock: 4000 */
|
||||
0xa0, 0x0f, 0, 0, /* dwMaximumClock: 4000 */
|
||||
0, /* bNumClockSupported: 0x00 */
|
||||
0x80, 0x25, 0, 0, /* dwDataRate: 9600 */
|
||||
0x80, 0x25, 0, 0, /* dwMaxDataRate: 9600 */
|
||||
0, /* bNumDataRateSupported: 0x00 */
|
||||
0xfe, 0, 0, 0, /* dwMaxIFSD: 254 */
|
||||
0, 0, 0, 0, /* dwSynchProtocols: FIXED VALUE */
|
||||
0, 0, 0, 0, /* dwMechanical: FIXED VALUE */
|
||||
/*
|
||||
* According to Specification for USB ICCD (revision 1.0),
|
||||
* dwFeatures should be 0x00040840.
|
||||
*
|
||||
* It is different now for better interaction to GPG's in-stock
|
||||
* ccid-driver.
|
||||
*/
|
||||
0x42, 0x08, 0x02, 0x00, /* dwFeatures (not ICCD):
|
||||
* Short APDU level : 0x20000 *
|
||||
* (what? means ICCD?) : 0x00800 *
|
||||
* Automatic IFSD : 0x00400
|
||||
0, 0, 0, 0, /* dwSynchProtocols: 0 */
|
||||
0, 0, 0, 0, /* dwMechanical: 0 */
|
||||
0x7a, 0x04, 0x02, 0x00, /* dwFeatures:
|
||||
* Short and extended APDU level: 0x40000 ----
|
||||
* Short APDU level : 0x20000 *
|
||||
* (ICCD?) : 0x00800 ----
|
||||
* Automatic IFSD : 0x00400 *
|
||||
* NAD value other than 0x00 : 0x00200
|
||||
* Can set ICC in clock stop : 0x00100
|
||||
* Automatic PPS CUR : 0x00080
|
||||
* Automatic PPS PROP : 0x00040 *
|
||||
* Auto baud rate change : 0x00020
|
||||
* Auto clock change : 0x00010
|
||||
* Auto voltage selection : 0x00008
|
||||
* Auto baud rate change : 0x00020 *
|
||||
* Auto clock change : 0x00010 *
|
||||
* Auto voltage selection : 0x00008 *
|
||||
* Auto activaction of ICC : 0x00004
|
||||
* Automatic conf. based on ATR : 0x00002 g
|
||||
* Automatic conf. based on ATR : 0x00002 *
|
||||
*/
|
||||
0x0f, 0x01, 0, 0, /* dwMaxCCIDMessageLength: 271 */
|
||||
0xff, /* bClassGetResponse: */
|
||||
0xff, /* bClassEnvelope: */
|
||||
0, 0, /* wLCDLayout: FIXED VALUE */
|
||||
0xff, /* bClassGetResponse: 0xff */
|
||||
0x00, /* bClassEnvelope: 0 */
|
||||
0, 0, /* wLCDLayout: 0 */
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DND_SUPPORT)
|
||||
1, /* bPinSupport: with PIN pad (verify) */
|
||||
@@ -183,31 +170,31 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
1, /* bMaxCCIDBusySlots: 1 */
|
||||
/*Endpoint IN1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x81, /* bEndpointAddress: (IN1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
USB_CCID_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint OUT1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x01, /* bEndpointAddress: (OUT1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
USB_CCID_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint IN2 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x82, /* bEndpointAddress: (IN2) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
4, 0x00, /* wMaxPacketSize: */
|
||||
0x04, 0x00, /* wMaxPacketSize: 4 */
|
||||
0xFF, /* bInterval (255ms) */
|
||||
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
/* Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
0x01, /* bInterfaceNumber: Number of Interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
HID_INTERFACE, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoint used */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
@@ -225,7 +212,7 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
|
||||
/*Endpoint IN7 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x87, /* bEndpointAddress: (IN7) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
0x02, 0x00, /* wMaxPacketSize: 2 */
|
||||
@@ -235,8 +222,8 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
/* Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
0x02, /* bInterfaceNumber: Number of Interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
VCOM_INTERFACE_0, /* bInterfaceNumber: Index of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoints used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
@@ -247,14 +234,13 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
5, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||
0x10, /* bcdCDC: spec release number */
|
||||
0x01,
|
||||
0x10, 0x01, /* bcdCDC: spec release number */
|
||||
/*Call Managment Functional Descriptor*/
|
||||
5, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x03, /* bmCapabilities: D0+D1 */
|
||||
0x02, /* bDataInterface: 2 */
|
||||
VCOM_INTERFACE_1, /* bDataInterface */
|
||||
/*ACM Functional Descriptor*/
|
||||
4, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
@@ -264,11 +250,11 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
5, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x06, /* bDescriptorSubtype: Union func desc */
|
||||
0x01, /* bMasterInterface: Communication class interface */
|
||||
0x02, /* bSlaveInterface0: Data Class Interface */
|
||||
VCOM_INTERFACE_0, /* bMasterInterface: Communication class interface */
|
||||
VCOM_INTERFACE_1, /* bSlaveInterface0: Data Class Interface */
|
||||
/*Endpoint 4 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x84, /* bEndpointAddress: (IN4) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
VIRTUAL_COM_PORT_INT_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
@@ -276,8 +262,8 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
|
||||
/*Data class interface descriptor*/
|
||||
9, /* bLength: Endpoint Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
|
||||
0x03, /* bInterfaceNumber: Number of Interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: */
|
||||
VCOM_INTERFACE_1, /* bInterfaceNumber: Index of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: Two endpoints used */
|
||||
0x0A, /* bInterfaceClass: CDC */
|
||||
@@ -286,14 +272,14 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
0x00, /* iInterface: */
|
||||
/*Endpoint 5 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x05, /* bEndpointAddress: (OUT5) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
/*Endpoint 3 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x83, /* bEndpointAddress: (IN3) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
@@ -302,12 +288,8 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
/* Interface Descriptor.*/
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
0x04, /* bInterfaceNumber. */
|
||||
#else
|
||||
0x02, /* bInterfaceNumber. */
|
||||
#endif
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
MSC_INTERFACE, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x02, /* bNumEndpoints. */
|
||||
0x08, /* bInterfaceClass (Mass Stprage). */
|
||||
@@ -319,14 +301,14 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
0x00, /* iInterface. */
|
||||
/* Endpoint Descriptor.*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x86, /* bEndpointAddress: (IN6) */
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x40, 0x00, /* wMaxPacketSize. */
|
||||
0x00, /* bInterval (ignored for bulk). */
|
||||
/* Endpoint Descriptor.*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x06, /* bEndpointAddress: (OUT6) */
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x40, 0x00, /* wMaxPacketSize. */
|
||||
@@ -336,9 +318,9 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
|
||||
|
||||
/* USB String Descriptors */
|
||||
static const uint8_t gnukStringLangID[] = {
|
||||
static const uint8_t gnuk_string_lang_id[] = {
|
||||
4, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
STRING_DESCRIPTOR,
|
||||
0x09, 0x04 /* LangID = 0x0409: US-English */
|
||||
};
|
||||
|
||||
@@ -351,78 +333,74 @@ struct desc
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
static const struct desc String_Descriptors[NUM_STRING_DESC] = {
|
||||
{gnukStringLangID, sizeof (gnukStringLangID)},
|
||||
{gnukStringVendor, sizeof (gnukStringVendor)},
|
||||
{gnukStringProduct, sizeof (gnukStringProduct)},
|
||||
{gnukStringSerial, sizeof (gnukStringSerial)},
|
||||
static const struct desc string_descriptors[] = {
|
||||
{gnuk_string_lang_id, sizeof (gnuk_string_lang_id)},
|
||||
{gnuk_string_vendor, sizeof (gnuk_string_vendor)},
|
||||
{gnuk_string_product, sizeof (gnuk_string_product)},
|
||||
{gnuk_string_serial, sizeof (gnuk_string_serial)},
|
||||
{gnuk_revision_detail, sizeof (gnuk_revision_detail)},
|
||||
{gnuk_config_options, sizeof (gnuk_config_options)},
|
||||
{sys_version, sizeof (sys_version)},
|
||||
};
|
||||
#define NUM_STRING_DESC (sizeof (string_descriptors) / sizeof (struct desc))
|
||||
|
||||
#define USB_DT_HID 0x21
|
||||
#define USB_DT_REPORT 0x22
|
||||
|
||||
int
|
||||
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
uint16_t index)
|
||||
usb_get_descriptor (struct usb_dev *dev)
|
||||
{
|
||||
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 (desc_type == DEVICE_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (gnukDeviceDescriptor,
|
||||
sizeof (gnukDeviceDescriptor));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_ctrl_send (dev, device_desc, sizeof (device_desc));
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (gnukConfigDescriptor,
|
||||
sizeof (gnukConfigDescriptor));
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_ctrl_send (dev, config_desc, sizeof (config_desc));
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
if (desc_index < NUM_STRING_DESC)
|
||||
return usb_lld_ctrl_send (dev, string_descriptors[desc_index].desc,
|
||||
string_descriptors[desc_index].size);
|
||||
#ifdef USE_SYS3
|
||||
else if (desc_index == NUM_STRING_DESC)
|
||||
{
|
||||
usb_lld_set_data_to_send (String_Descriptors[desc_index].desc,
|
||||
String_Descriptors[desc_index].size);
|
||||
return USB_SUCCESS;
|
||||
uint8_t usbbuf[64];
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
for (i = 0; i < (int)sizeof (usbbuf)/2 - 2; i++)
|
||||
{
|
||||
if (sys_board_name[i] == 0)
|
||||
break;
|
||||
|
||||
usbbuf[i*2+2] = sys_board_name[i];
|
||||
usbbuf[i*2+3] = 0;
|
||||
}
|
||||
usbbuf[0] = len = i*2 + 2;
|
||||
usbbuf[1] = STRING_DESCRIPTOR;
|
||||
return usb_lld_ctrl_send (dev, usbbuf, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
else if (rcp == INTERFACE_RECIPIENT)
|
||||
{
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
if (index == 1)
|
||||
if (arg->index == HID_INTERFACE)
|
||||
{
|
||||
if (desc_type == USB_DT_HID)
|
||||
{
|
||||
usb_lld_set_data_to_send (gnukConfigDescriptor+ICC_TOTAL_LENGTH+9,
|
||||
9);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_ctrl_send (dev, config_desc+CCID_TOTAL_LENGTH+9, 9);
|
||||
else if (desc_type == USB_DT_REPORT)
|
||||
{
|
||||
usb_lld_set_data_to_send (hid_report_desc, HID_REPORT_DESC_SIZE);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
(void)index;
|
||||
#endif
|
||||
if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
if (desc_index < NUM_STRING_DESC)
|
||||
{
|
||||
usb_lld_set_data_to_send (String_Descriptors[desc_index].desc,
|
||||
String_Descriptors[desc_index].size);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return usb_lld_ctrl_send (dev, hid_report_desc,
|
||||
HID_REPORT_DESC_SIZE);
|
||||
}
|
||||
}
|
||||
#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,
|
||||
};
|
||||
|
||||
void usb_cb_device_reset (void);
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len);
|
||||
int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
|
||||
uint16_t index, uint16_t len);
|
||||
int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
uint16_t index);
|
||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
|
||||
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value);
|
||||
|
||||
enum {
|
||||
USB_EVENT_ADDRESS,
|
||||
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);
|
||||
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_send (const void *p, size_t len);
|
||||
|
||||
extern inline void usb_lld_set_data_to_recv (void *p, size_t len)
|
||||
{
|
||||
usb_lld_set_data_to_send ((const void *)p, len);
|
||||
}
|
||||
|
||||
void usb_lld_prepare_shutdown (void);
|
||||
void usb_lld_shutdown (void);
|
||||
|
||||
void usb_interrupt_handler (void);
|
||||
1191
src/usb_stm32f103.c
1191
src/usb_stm32f103.c
File diff suppressed because it is too large
Load Diff
31
test/ecc_nistp256_keys.py
Normal file
31
test/ecc_nistp256_keys.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# Data taken from:
|
||||
# A. Jivsov, Sample Keys and Messages:
|
||||
# https://sites.google.com/site/brainhub/pgpecckeys
|
||||
|
||||
# uid ec_dsa_dh_256 <openpgp@brainhub.org>
|
||||
# sign key:
|
||||
# nistp256/BAA59D9C 2010-09-17
|
||||
# keygrip: 8E06A180EFFE4C65B812150CAF19BF30C0689A4C
|
||||
#
|
||||
# q=(x, y) and d
|
||||
key[0] = (0x0bc7a7baebd5f08c74c77b71ee44e7bb0b5a18317b996da5393e33acc52932c6,
|
||||
0xd2f60f4d1efe35a0b9fb8d3787ed4bee97ca012d07b8f5835be7093545d532e6,
|
||||
0xd8f28c530c99821faa5ee2ff4dd8d1df01995d4e98fb45f8768cb65abd4adaa9)
|
||||
|
||||
# decryption key:
|
||||
# sub nistp256/4089AB73 2010-09-17 nistp256
|
||||
# keygrip: E4403F3FD7A443FAC29FEF288FA0D20AC212851E
|
||||
#
|
||||
# q=(x, y) and d
|
||||
key[1] = (0x7f70c0a8184cdcaea5db20ba8fed17e47bdefb744d575ec449130af37edade65,
|
||||
0x8ae7ee35d20e8897911c9f564be33d9a94bc1e5c927b1aa07ff750d2d11c2971,
|
||||
0xa05cd14749bea3f3d14c92dc438e45e351efe860360c431705b7d42410581843)
|
||||
|
||||
# auth key from: uid ec_dsa_dh_256_no_pass <openpgp@brainhub.org>
|
||||
#
|
||||
# q=(x, y) and d
|
||||
key[2] = (0x81fbbc20eea9e8d1c3ceabb0a8185925b113d1ac42cd5c78403bd83da19235c6,
|
||||
0x5ed6db13d91db34507d0129bf88981878d29adbf8fcd1720afdb767bb3fcaaff,
|
||||
0xa355916f8665eb99c1af48d9560b5c6889e5287bc75aa693aaae9bdb15e8b3fd)
|
||||
|
||||
# This file is here to extend the test suite for ECC.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user