Compare commits
81 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 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,7 +2,7 @@
|
||||
*.o
|
||||
*.pyc
|
||||
src/.dep
|
||||
src/Makefile
|
||||
src/config.mk
|
||||
src/config.h
|
||||
src/gnuk.ld
|
||||
src/board.h
|
||||
|
||||
10
AUTHORS
10
AUTHORS
@@ -1,3 +1,13 @@
|
||||
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.
|
||||
|
||||
|
||||
324
ChangeLog
324
ChangeLog
@@ -1,3 +1,327 @@
|
||||
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.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# 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> #################
|
||||
|
||||
46
NEWS
46
NEWS
@@ -1,5 +1,51 @@
|
||||
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
|
||||
|
||||
103
README
103
README
@@ -1,28 +1,35 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 1.2.2
|
||||
2016-10-15
|
||||
Version 1.2.6
|
||||
2017-10-11
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
This is the release of Gnuk, version 1.2.2, which has major
|
||||
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
|
||||
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.1 with libgcrypt
|
||||
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?
|
||||
============
|
||||
@@ -47,7 +54,7 @@ FAQ
|
||||
|
||||
Q0: How Gnuk USB Token is superior than other solutions (OpenPGP
|
||||
card 2.0, YubiKey, etc.) ?
|
||||
http://www.g10code.de/p-card.html
|
||||
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
|
||||
@@ -77,12 +84,12 @@ A3: Orthodox choice is Olimex STM32-H103.
|
||||
choice for experiment.
|
||||
|
||||
Q4: What's version of GnuPG are you using?
|
||||
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.13 in
|
||||
experimental.
|
||||
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.
|
||||
|
||||
@@ -224,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
|
||||
@@ -248,7 +257,7 @@ External source code
|
||||
|
||||
Gnuk is distributed with external source code.
|
||||
|
||||
* chopstx/ -- Chopstx 1.1
|
||||
* chopstx/ -- Chopstx 1.5
|
||||
|
||||
We use Chopstx as the kernel for Gnuk.
|
||||
|
||||
@@ -361,10 +370,10 @@ You need GNU toolchain and newlib for 'arm-none-eabi' target.
|
||||
On Debian we can install the packages of gcc-arm-none-eabi,
|
||||
gdb-arm-none-eabi and its friends. I'm using:
|
||||
|
||||
binutils-arm-none-eabi 2.26-4+8
|
||||
gcc-arm-none-eabi 15:4.9.3+svn231177-1
|
||||
gdb-arm-none-eabi 7.10-1+9
|
||||
libnewlib-arm-none-eabi 2.2.0+git20150830.5a3d536-1
|
||||
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.
|
||||
@@ -395,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
|
||||
@@ -414,9 +419,10 @@ Flying Stone Tiny 01
|
||||
|
||||
If you are using Flying Stone Tiny 01, you need a SWD writer.
|
||||
|
||||
OpenOCD 0.9 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"
|
||||
|
||||
|
||||
|
||||
@@ -435,20 +441,24 @@ 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.
|
||||
|
||||
|
||||
(Optional) Configure serial number and X.509 certificate
|
||||
@@ -536,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
|
||||
@@ -551,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:
|
||||
|
||||
@@ -578,33 +592,28 @@ You can get it by:
|
||||
$ 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 in Gnuk 1.1. 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:
|
||||
|
||||
http://www.gniibe.org/category/fst-01.html
|
||||
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
|
||||
==================
|
||||
|
||||
5
THANKS
5
THANKS
@@ -11,12 +11,14 @@ 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
|
||||
@@ -29,9 +31,12 @@ 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
|
||||
|
||||
2
chopstx
2
chopstx
Submodule chopstx updated: d448d3c678...96d2a81331
@@ -50,39 +50,9 @@ With the script below, I extract public key of the keygrip
|
||||
|
||||
$ ./get_raw_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
|
||||
|
||||
Here is the script, get_raw_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::
|
||||
|
||||
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
|
||||
@@ -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,7 @@ size_t mpi_lsb( const mpi *X )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if !defined(POLARSSL_HAVE_UDBL)
|
||||
/*
|
||||
* Count leading zero bits in a given integer
|
||||
*/
|
||||
@@ -240,6 +241,7 @@ static size_t int_clz( const t_uint x )
|
||||
|
||||
return j;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the number of most significant bits
|
||||
@@ -1140,9 +1142,9 @@ static t_uint int_div_int(t_uint u1, t_uint u0, t_uint d, t_uint *r)
|
||||
*/
|
||||
if(( 0 == d ) || ( u1 >= d ))
|
||||
{
|
||||
if (r != NULL) *r = (~0);
|
||||
if (r != NULL) *r = (~0UL);
|
||||
|
||||
return (~0);
|
||||
return (~0UL);
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_HAVE_UDBL)
|
||||
@@ -1268,7 +1270,7 @@ 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
|
||||
{
|
||||
Z.p[i - t - 1] = int_div_int( X.p[i], X.p[i-1], Y.p[t], NULL);
|
||||
@@ -1295,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) ) );
|
||||
@@ -1512,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;
|
||||
|
||||
@@ -1526,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; */
|
||||
@@ -1598,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
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1632,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
|
||||
@@ -1658,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
|
||||
*/
|
||||
@@ -2051,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;
|
||||
@@ -2202,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,
|
||||
@@ -2214,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 }};
|
||||
@@ -2221,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 }};
|
||||
@@ -2274,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>
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
PROJECT = regnual
|
||||
|
||||
OBJS = regnual.o usb-stm32f103.o reset.o
|
||||
|
||||
include ../src/config.mk
|
||||
|
||||
LDSCRIPT= regnual.ld
|
||||
|
||||
###################################
|
||||
@@ -19,7 +22,7 @@ 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* regnual.c -- Firmware installation for STM32F103 Flash ROM
|
||||
*
|
||||
* Copyright (C) 2012, 2013, 2015, 2016
|
||||
* Copyright (C) 2012, 2013, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -365,7 +365,11 @@ main (int argc, char *argv[])
|
||||
|
||||
set_led (0);
|
||||
|
||||
#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.
|
||||
|
||||
@@ -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,11 +5,8 @@ PROJECT = gnuk
|
||||
|
||||
CHOPSTX = ../chopstx
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= gnuk.ld
|
||||
|
||||
CSRC = main.c usb_desc.c usb_ctrl.c \
|
||||
call-rsa.c \
|
||||
CSRC = main.c call-rsa.c \
|
||||
usb_desc.c usb_ctrl.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 \
|
||||
@@ -27,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
|
||||
@@ -45,23 +49,17 @@ ifeq ($(ENABLE_PINPAD),dnd)
|
||||
CSRC += usb-msc.c
|
||||
endif
|
||||
|
||||
CHIP=stm32f103
|
||||
USE_SYS = yes
|
||||
USE_USB = yes
|
||||
USE_ADC = yes
|
||||
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 = @USE_SYS3@
|
||||
OPT = -O3 -Os -g
|
||||
LIBS =
|
||||
|
||||
#######################
|
||||
include $(CHOPSTX)/rules.mk
|
||||
@@ -75,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
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
#include "config.h"
|
||||
@@ -41,7 +40,7 @@ static struct chx_cleanup clp;
|
||||
static void
|
||||
rsa_cleanup (void *arg)
|
||||
{
|
||||
free (arg);
|
||||
(void)arg;
|
||||
rsa_free (&rsa_ctx);
|
||||
}
|
||||
|
||||
@@ -111,28 +110,23 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,6 +136,9 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
{
|
||||
mpi P1, Q1, H;
|
||||
int ret;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
size_t output_len;
|
||||
#endif
|
||||
|
||||
DEBUG_INFO ("RSA decrypt:");
|
||||
DEBUG_WORD ((uint32_t)&ret);
|
||||
@@ -177,9 +174,16 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
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);
|
||||
}
|
||||
@@ -232,54 +236,39 @@ rsa_verify (const uint8_t *pubkey, int pubkey_len,
|
||||
|
||||
#define RSA_EXPONENT 0x10001
|
||||
|
||||
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 = (void *)p_q_modulus;
|
||||
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)
|
||||
{
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (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:
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
rsa_free (&rsa_ctx);
|
||||
chopstx_cleanup_pop (1);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
return -1;
|
||||
else
|
||||
return p_q_modulus;
|
||||
return 0;
|
||||
}
|
||||
|
||||
204
src/configure
vendored
204
src/configure
vendored
@@ -6,10 +6,11 @@ nl=$'\n'
|
||||
#
|
||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||
#
|
||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||
# 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
|
||||
@@ -36,7 +37,6 @@ fi
|
||||
help=no
|
||||
vidpid=none
|
||||
target=FST_01
|
||||
verbose=no
|
||||
with_dfu=default
|
||||
debug=no
|
||||
sys1_compat=yes
|
||||
@@ -44,26 +44,35 @@ pinpad=no
|
||||
certdo=no
|
||||
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
|
||||
REVISION=`git describe --dirty="-modified"`
|
||||
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`
|
||||
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=*)
|
||||
@@ -96,6 +105,15 @@ for option; do
|
||||
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
|
||||
@@ -118,15 +136,19 @@ Configuration:
|
||||
FST_01
|
||||
FST_01G
|
||||
OLIMEX_STM32_H103
|
||||
STM32_PRIMER2
|
||||
STBEE
|
||||
STBEE_MINI
|
||||
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]
|
||||
@@ -136,21 +158,14 @@ Configuration:
|
||||
--disable-sys1-compat disable SYS 1.0 compatibility [no]
|
||||
executable is target independent
|
||||
but requires SYS 2.0 or newer
|
||||
--enable-factory-reset
|
||||
support life cycle management [no]
|
||||
--with-dfu build image for DFU [<target specific>]
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test "$vidpid" = "none"; then
|
||||
echo "Please specify Vendor ID and Product ID by --vidpid option." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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
|
||||
@@ -161,6 +176,10 @@ 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;
|
||||
@@ -177,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"
|
||||
@@ -204,21 +255,16 @@ if test "$with_dfu" = "yes"; then
|
||||
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"
|
||||
@@ -229,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
|
||||
@@ -265,13 +305,13 @@ else
|
||||
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}"
|
||||
|
||||
|
||||
if test "$sys1_compat" = "yes"; then
|
||||
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo"
|
||||
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo: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
|
||||
@@ -281,53 +321,58 @@ else
|
||||
FLASH_PAGE_SIZE=2048
|
||||
FLASH_SIZE=128
|
||||
MEMORY_SIZE=20
|
||||
CONFIG="common:debug=$debug:pinpad=$pinpad:certdo=$certdo"
|
||||
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"
|
||||
echo "$VIDPID" | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\\${nl} 0x\4, 0x\3, /* idProduct */%p"
|
||||
echo "$VERSION" | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
|
||||
}
|
||||
|
||||
output_vendor_product_serial_strings () {
|
||||
prefix=$1
|
||||
name=$1
|
||||
|
||||
echo "static const uint8_t ${prefix}string_vendor[] = {"
|
||||
echo " ${#VENDOR}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
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 "$VENDOR" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
echo '};'
|
||||
echo
|
||||
echo "static const uint8_t ${prefix}string_product[] = {"
|
||||
echo " ${#PRODUCT}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
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 "$PRODUCT" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
echo '};'
|
||||
|
||||
if test -n "$prefix"; then
|
||||
if test -n "$name"; then
|
||||
echo
|
||||
echo "const uint8_t ${prefix}string_serial[] = {"
|
||||
echo " ${#SERIALNO}*2+2+16, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
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"
|
||||
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
|
||||
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
|
||||
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 ${prefix}revision_detail[] = {"
|
||||
echo " ${#REVISION}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
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 "$REVISION" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
|
||||
echo '};'
|
||||
echo
|
||||
echo "static const uint8_t ${prefix}config_options[] = {"
|
||||
echo " ${#CONFIG}*2+2, /* bLength */"
|
||||
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
|
||||
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 '};'
|
||||
@@ -336,7 +381,7 @@ output_vendor_product_serial_strings () {
|
||||
}
|
||||
|
||||
if !(IFS=" "
|
||||
while read VIDPID VERSION PRODUCT VENDOR; do
|
||||
while read -r VIDPID VERSION PRODUCT VENDOR; do
|
||||
if test "$vidpid" = "$VIDPID"; then
|
||||
output_vid_pid_version > usb-vid-pid-ver.c.inc
|
||||
output_vendor_product_serial_strings gnuk_ >usb-strings.c.inc
|
||||
@@ -344,7 +389,7 @@ if !(IFS=" "
|
||||
fi
|
||||
done; exit 1) < ../GNUK_USB_DEVICE_ID
|
||||
then
|
||||
echo "Please specify valid Vendor ID and Product ID." >&2
|
||||
echo "Please specify valid Vendor ID and Product ID." >&2
|
||||
echo "Check ../GNUK_USB_DEVICE_ID." >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -361,28 +406,35 @@ else
|
||||
fi
|
||||
|
||||
|
||||
sed -e "s%@USE_SYS3@%$use_sys3%" \
|
||||
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
|
||||
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
|
||||
-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/" \
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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"
|
||||
@@ -708,7 +707,7 @@ eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
eddsa_public_key_25519 (bn256 *pk, const bn256 *a)
|
||||
{
|
||||
ac R[1];
|
||||
@@ -730,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, 2015 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.
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "bn.h"
|
||||
#include "mod25638.h"
|
||||
#include "mod.h"
|
||||
@@ -198,22 +197,17 @@ compute_nQ (bn256 *res, const bn256 *n, const bn256 *q_x)
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
ecdh_compute_public_25519 (const uint8_t *key_data)
|
||||
void
|
||||
ecdh_compute_public_25519 (const uint8_t *key_data, uint8_t *pubkey)
|
||||
{
|
||||
uint8_t *p;
|
||||
bn256 gx[1];
|
||||
bn256 k[1];
|
||||
|
||||
memset (gx, 0, sizeof (bn256));
|
||||
gx[0].word[0] = 9; /* Gx = 9 */
|
||||
memcpy (k, key_data, sizeof (bn256));
|
||||
p = (uint8_t *)malloc (sizeof (bn256));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
compute_nQ ((bn256 *)p, k, gx);
|
||||
return p;
|
||||
compute_nQ ((bn256 *)pubkey, k, gx);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -384,7 +384,7 @@ FUNC(check_secret) (const bn256 *d0, bn256 *d1)
|
||||
{
|
||||
ac Q0[1], Q1[1];
|
||||
|
||||
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) <= 0)
|
||||
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) != 0)
|
||||
/* == 0 or >= N, it's not valid. */
|
||||
return 0;
|
||||
|
||||
|
||||
151
src/flash.c
151
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, 2015, 2016
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -53,24 +53,21 @@
|
||||
* <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)
|
||||
|
||||
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) */
|
||||
@@ -78,8 +75,18 @@ const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
||||
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)
|
||||
{
|
||||
@@ -102,39 +109,45 @@ static int key_available_at (const uint8_t *k, int key_size)
|
||||
|
||||
|
||||
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
|
||||
const uint8_t *
|
||||
flash_init (void)
|
||||
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 *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 *)(&_data_pool + flash_page_size);
|
||||
data_pool = &_data_pool;
|
||||
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 && gen1 == 0xffff)
|
||||
/* It's terminated. */
|
||||
return NULL;
|
||||
{
|
||||
/* It's terminated. */
|
||||
*p_do_start = *p_do_end = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gen0 == 0xffff)
|
||||
/* Use another page if a page is erased. */
|
||||
data_pool = &_data_pool + flash_page_size;
|
||||
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 = &_data_pool;
|
||||
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 = &_data_pool + flash_page_size;
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
|
||||
return data_pool + FLASH_DATA_POOL_HEADER_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);
|
||||
@@ -145,28 +158,33 @@ flash_terminate (void)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
flash_erase_page ((uint32_t)flash_key_getpage (i));
|
||||
flash_erase_page ((uint32_t)&_data_pool);
|
||||
flash_erase_page ((uint32_t)(&_data_pool + flash_page_size));
|
||||
data_pool = &_data_pool;
|
||||
last_p = &_data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
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_activate (void)
|
||||
{
|
||||
flash_program_halfword ((uint32_t)&_data_pool, 0);
|
||||
flash_program_halfword ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flash_init_keys (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;
|
||||
@@ -224,15 +242,15 @@ 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;
|
||||
@@ -242,8 +260,8 @@ flash_copying_gc (void)
|
||||
generation = 0;
|
||||
else
|
||||
generation++;
|
||||
flash_program_halfword ((uint32_t)dst, generation);
|
||||
flash_erase_page ((uint32_t)src);
|
||||
flash_program_halfword ((uintptr_t)dst, generation);
|
||||
flash_erase_page ((uintptr_t)src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -273,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");
|
||||
@@ -329,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;
|
||||
@@ -364,7 +383,7 @@ static uint8_t *
|
||||
flash_key_getpage (enum kind_of_key kk)
|
||||
{
|
||||
/* There is a page for each KK. */
|
||||
return &_keystore_pool + (flash_page_size * kk);
|
||||
return FLASH_ADDR_KEY_STORAGE_START + (flash_page_size * kk);
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
@@ -398,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);
|
||||
@@ -424,7 +443,7 @@ 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))
|
||||
@@ -443,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);
|
||||
@@ -453,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);
|
||||
}
|
||||
@@ -461,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);
|
||||
}
|
||||
@@ -475,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
|
||||
@@ -489,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -501,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 *
|
||||
@@ -524,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;
|
||||
}
|
||||
|
||||
@@ -540,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 *
|
||||
@@ -556,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;
|
||||
}
|
||||
|
||||
@@ -592,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
|
||||
@@ -617,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
|
||||
@@ -632,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,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;
|
||||
}
|
||||
|
||||
@@ -660,9 +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);
|
||||
flash_erase_page ((uintptr_t)p);
|
||||
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
|
||||
flash_erase_page ((uint32_t)p + flash_page_size);
|
||||
flash_erase_page ((uintptr_t)p + flash_page_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -685,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)
|
||||
{
|
||||
@@ -711,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 *);
|
||||
25
src/gnuk.h
25
src/gnuk.h
@@ -106,13 +106,13 @@ 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);
|
||||
|
||||
@@ -139,10 +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_do_storage_init (const uint8_t **, const uint8_t **);
|
||||
void flash_terminate (void);
|
||||
void flash_activate (void);
|
||||
void flash_init_keys (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);
|
||||
@@ -152,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);
|
||||
|
||||
@@ -265,22 +265,22 @@ 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 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);
|
||||
@@ -288,8 +288,8 @@ int ecdh_decrypt_p256k1 (const uint8_t *input, uint8_t *output,
|
||||
int eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *output,
|
||||
const uint8_t *sk_a, const uint8_t *seed,
|
||||
const uint8_t *pk);
|
||||
uint8_t *eddsa_compute_public_25519 (const uint8_t *a);
|
||||
uint8_t *ecdh_compute_public_25519 (const uint8_t *a);
|
||||
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);
|
||||
|
||||
@@ -301,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;
|
||||
@@ -459,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__ = 0x0080; /* Exception handlers */
|
||||
__process0_stack_size__ = 0x0100; /* main */
|
||||
__process1_stack_size__ = 0x0180; /* ccid */
|
||||
__process2_stack_size__ = 0x0180; /* rng */
|
||||
__process3_stack_size__ = 0x1640; /* gpg */
|
||||
__process4_stack_size__ = 0; /* --- */
|
||||
__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
|
||||
@@ -82,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
|
||||
|
||||
@@ -171,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@);
|
||||
@@ -185,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
|
||||
}
|
||||
|
||||
|
||||
164
src/main.c
164
src/main.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* main.c - main routine of Gnuk
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -35,8 +35,13 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb-cdc.h"
|
||||
#include "random.h"
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define main emulated_main
|
||||
#else
|
||||
#include "mcu/stm32f103.h"
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main thread does 1-bit LED display output
|
||||
@@ -47,6 +52,10 @@
|
||||
#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)
|
||||
@@ -76,6 +85,7 @@ device_initialize_once (void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static volatile uint8_t fatal_code;
|
||||
@@ -167,26 +177,30 @@ led_blink (int spec)
|
||||
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__[];
|
||||
#define STACK_ADDR_CCID ((uint32_t)__process1_stack_base__)
|
||||
#define STACK_SIZE_CCID ((uint32_t)__process1_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_MAIN 5
|
||||
@@ -202,18 +216,94 @@ extern uint32_t bDeviceState;
|
||||
* Entry point.
|
||||
*/
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
uint32_t entry;
|
||||
#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 ();
|
||||
|
||||
@@ -285,8 +375,9 @@ main (int argc, char *argv[])
|
||||
/* Finish application. */
|
||||
chopstx_join (ccid_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
|
||||
@@ -294,12 +385,12 @@ main (int argc, char *argv[])
|
||||
#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_ADDR)&0x07 == 0x04) /* High dencity device. */
|
||||
if ((*CHIP_ID_REG)&0x07 == 0x04) /* High dencity device. */
|
||||
flash_page_size = 2048; /* It's 2KiB. */
|
||||
|
||||
/* Kill DFU */
|
||||
@@ -318,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;
|
||||
@@ -348,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;
|
||||
}
|
||||
|
||||
@@ -405,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: ");
|
||||
@@ -421,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);
|
||||
@@ -445,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,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)
|
||||
@@ -481,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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
183
src/neug.c
183
src/neug.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* neug.c - true random number generation
|
||||
*
|
||||
* Copyright (C) 2011, 2012, 2013, 2016
|
||||
* Copyright (C) 2011, 2012, 2013, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -29,10 +29,122 @@
|
||||
|
||||
#include "sys.h"
|
||||
#include "neug.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;
|
||||
|
||||
@@ -94,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;
|
||||
@@ -164,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);
|
||||
}
|
||||
|
||||
@@ -181,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);
|
||||
}
|
||||
|
||||
@@ -198,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; /* First byte of CRC->DR is used here. */
|
||||
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);
|
||||
@@ -226,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);
|
||||
}
|
||||
|
||||
@@ -640,9 +752,11 @@ rng (void *arg)
|
||||
|
||||
static struct rng_rb the_ring_buffer;
|
||||
|
||||
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
|
||||
#define STACK_ADDR_RNG ((uint32_t)__process2_stack_base__)
|
||||
#define STACK_SIZE_RNG ((uint32_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
|
||||
|
||||
/**
|
||||
@@ -655,15 +769,14 @@ 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
252
src/openpgp-do.c
252
src/openpgp-do.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.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];
|
||||
@@ -250,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)
|
||||
{
|
||||
@@ -336,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;
|
||||
@@ -749,47 +770,15 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
||||
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 (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);
|
||||
}
|
||||
if (*algo_attr_pp != NULL)
|
||||
return 0;
|
||||
}
|
||||
else if ((algo != ALGO_RSA2K && *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);
|
||||
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);
|
||||
}
|
||||
gpg_reset_algo_attr (kk);
|
||||
*algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo);
|
||||
if (*algo_attr_pp == NULL)
|
||||
return 0;
|
||||
@@ -858,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);
|
||||
@@ -877,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);
|
||||
@@ -1093,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;
|
||||
@@ -1108,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;
|
||||
@@ -1139,38 +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 if (attr == ALGO_CURVE25519)
|
||||
pubkey_allocated_here = ecdh_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++;
|
||||
@@ -1206,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;
|
||||
}
|
||||
|
||||
@@ -1240,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;
|
||||
|
||||
@@ -1272,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
|
||||
@@ -1314,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1380,6 +1327,7 @@ proc_key_import (const uint8_t *data, int len)
|
||||
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;
|
||||
@@ -1419,13 +1367,35 @@ 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);
|
||||
{
|
||||
/* 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];
|
||||
@@ -1437,7 +1407,8 @@ proc_key_import (const uint8_t *data, int len)
|
||||
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)
|
||||
{
|
||||
@@ -1449,7 +1420,8 @@ proc_key_import (const uint8_t *data, int len)
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
priv[31-i] = data[12+i];
|
||||
r = gpg_do_write_prvkey (kk, priv, 32, keystring_admin, NULL);
|
||||
ecdh_compute_public_25519 (priv, pubkey);
|
||||
r = gpg_do_write_prvkey (kk, priv, 32, keystring_admin, pubkey);
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
@@ -1543,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;
|
||||
@@ -1556,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 && *p != NR_EMPTY)
|
||||
p = do_start;
|
||||
while (p < do_end && *p != NR_EMPTY)
|
||||
{
|
||||
uint8_t nr = *p++;
|
||||
uint8_t second_byte = *p;
|
||||
@@ -1571,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)
|
||||
@@ -2079,42 +2058,35 @@ gpg_do_write_simple (uint8_t nr, const uint8_t *data, int size)
|
||||
}
|
||||
|
||||
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 attr = gpg_get_algo_attr (kk);;
|
||||
int prvkey_len = gpg_get_algo_attr_key_size (kk, GPG_KEY_PRIVATE);
|
||||
const uint8_t *keystring_admin;
|
||||
uint8_t *p_q_modulus = NULL;
|
||||
uint8_t d[64];
|
||||
const uint8_t *rnd;
|
||||
const uint8_t *prv;
|
||||
const uint8_t *pubkey;
|
||||
int r;
|
||||
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;
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
p_q_modulus = rsa_genkey (prvkey_len);
|
||||
if (p_q_modulus == NULL)
|
||||
if (rsa_genkey (prvkey_len, pubkey, p_q) < 0)
|
||||
{
|
||||
GPG_MEMORY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
|
||||
prv = p_q_modulus;
|
||||
pubkey = p_q_modulus + prvkey_len;
|
||||
prv = p_q;
|
||||
}
|
||||
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
|
||||
{
|
||||
uint8_t d1[32];
|
||||
const uint8_t *p;
|
||||
int i, r;
|
||||
|
||||
@@ -2143,7 +2115,10 @@ gpg_do_keygen (uint8_t kk_byte)
|
||||
random_bytes_free (rnd);
|
||||
|
||||
prv = d;
|
||||
pubkey = NULL;
|
||||
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)
|
||||
{
|
||||
@@ -2154,7 +2129,7 @@ gpg_do_keygen (uint8_t kk_byte)
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
prv = d;
|
||||
pubkey = NULL;
|
||||
eddsa_compute_public_25519 (d, pubkey);
|
||||
}
|
||||
else if (attr == ALGO_CURVE25519)
|
||||
{
|
||||
@@ -2165,7 +2140,7 @@ gpg_do_keygen (uint8_t kk_byte)
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
prv = d;
|
||||
pubkey = NULL;
|
||||
ecdh_compute_public_25519 (prv, pubkey);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2173,12 +2148,21 @@ gpg_do_keygen (uint8_t kk_byte)
|
||||
return;
|
||||
}
|
||||
|
||||
r = gpg_do_write_prvkey (kk, prv, prvkey_len, keystring_admin, pubkey);
|
||||
if (p_q_modulus)
|
||||
if (r >= 0)
|
||||
{
|
||||
memset (p_q_modulus, 0, prvkey_len * 2);
|
||||
free (p_q_modulus);
|
||||
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);
|
||||
|
||||
if (r < 0)
|
||||
{
|
||||
GPG_ERROR ();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* openpgp.c -- OpenPGP card protocol support
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -98,7 +98,6 @@ 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_OPENPGP 254
|
||||
#define FILE_CARD_TERMINATED 255
|
||||
|
||||
uint8_t file_selection;
|
||||
@@ -106,17 +105,18 @@ 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;
|
||||
|
||||
flash_data_start = flash_init ();
|
||||
flash_do_storage_init (&flash_do_start, &flash_do_end);
|
||||
|
||||
if (flash_data_start == NULL)
|
||||
if (flash_do_start == NULL)
|
||||
file_selection = FILE_CARD_TERMINATED;
|
||||
else
|
||||
file_selection = FILE_NONE;
|
||||
|
||||
gpg_data_scan (flash_data_start);
|
||||
flash_init_keys ();
|
||||
gpg_data_scan (flash_do_start, flash_do_end);
|
||||
flash_key_storage_init ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -644,10 +644,11 @@ cmd_pgp_gakp (void)
|
||||
{
|
||||
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
|
||||
GPG_SECURITY_FAILURE ();
|
||||
gpg_do_keygen (apdu.cmd_apdu_data[0]);
|
||||
gpg_do_keygen (&apdu.cmd_apdu_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
const uint8_t *
|
||||
gpg_get_firmware_update_key (uint8_t keyno)
|
||||
{
|
||||
@@ -657,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
|
||||
@@ -669,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");
|
||||
@@ -679,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;
|
||||
@@ -705,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;
|
||||
@@ -737,6 +735,11 @@ cmd_read_binary (void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
GPG_NO_FILE ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -759,8 +762,7 @@ cmd_select_file (void)
|
||||
|
||||
if (file_selection == FILE_CARD_TERMINATED)
|
||||
{
|
||||
file_selection = FILE_CARD_TERMINATED_OPENPGP;
|
||||
GPG_APPLICATION_TERMINATED();
|
||||
GPG_APPLICATION_TERMINATED ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1201,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)
|
||||
{
|
||||
@@ -1217,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 ();
|
||||
}
|
||||
@@ -1249,6 +1253,7 @@ cmd_write_binary (void)
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
static void
|
||||
cmd_external_authenticate (void)
|
||||
{
|
||||
@@ -1290,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)
|
||||
@@ -1322,9 +1328,9 @@ cmd_get_challenge (void)
|
||||
static void
|
||||
cmd_activate_file (void)
|
||||
{
|
||||
if (file_selection != FILE_CARD_TERMINATED_OPENPGP)
|
||||
if (file_selection != FILE_CARD_TERMINATED)
|
||||
{
|
||||
GPG_NO_RECORD();
|
||||
GPG_NO_RECORD ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1336,12 +1342,14 @@ cmd_activate_file (void)
|
||||
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();
|
||||
GPG_NO_RECORD ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1357,8 +1365,11 @@ cmd_terminate_df (void)
|
||||
return;
|
||||
}
|
||||
|
||||
ks_pw3 = gpg_do_read_simple (NR_DO_KEYSTRING_PW3);
|
||||
|
||||
if (!ac_check_status (AC_ADMIN_AUTHORIZED) && !gpg_pw_locked (PW_ERR_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();
|
||||
@@ -1391,8 +1402,10 @@ const struct command cmds[] = {
|
||||
{ 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 },
|
||||
@@ -1425,13 +1438,13 @@ process_command_apdu (void)
|
||||
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();
|
||||
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();
|
||||
GPG_NO_RECORD ();
|
||||
else
|
||||
{
|
||||
chopstx_setcancelstate (1);
|
||||
|
||||
@@ -964,9 +964,14 @@ cir_timer_interrupt (void)
|
||||
}
|
||||
|
||||
|
||||
extern uint8_t __process6_stack_base__[], __process6_stack_size__[];
|
||||
#define STACK_ADDR_TIM ((uint32_t)__process6_stack_base__)
|
||||
#define STACK_SIZE_TIM ((uint32_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 *
|
||||
@@ -986,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 *
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "sha256.h"
|
||||
|
||||
#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
|
||||
|
||||
@@ -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
|
||||
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 *);
|
||||
212
src/usb-ccid.c
212
src/usb-ccid.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* usb-ccid.c -- USB CCID protocol handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "usb-cdc.h"
|
||||
#include "debug.h"
|
||||
struct stdout stdout;
|
||||
#endif
|
||||
@@ -345,13 +346,21 @@ static void get_sw1sw2 (struct ep_in *epi, size_t len)
|
||||
epi->next_buf = no_buf;
|
||||
}
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
static uint8_t endp1_tx_buf[64]; /* Only support single CCID interface. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tx done callback
|
||||
*/
|
||||
static void
|
||||
EP1_IN_Callback (uint16_t len)
|
||||
ccid_tx_done (uint8_t ep_num, uint16_t len)
|
||||
{
|
||||
/*
|
||||
* If we support multiple CCID interfaces, we select endpoint object
|
||||
* by EP_NUM. Because it has only single CCID interface now, it's
|
||||
* hard-coded, here.
|
||||
*/
|
||||
struct ep_in *epi = &endpoint_in;
|
||||
|
||||
(void)len;
|
||||
@@ -361,7 +370,12 @@ EP1_IN_Callback (uint16_t len)
|
||||
else
|
||||
{
|
||||
epi->tx_done = 1;
|
||||
usb_lld_tx_enable (epi->ep_num, 0); /* send ZLP */
|
||||
/* send ZLP */
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (ep_num, endp1_tx_buf, 0);
|
||||
#else
|
||||
usb_lld_tx_enable (ep_num, 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -372,7 +386,11 @@ EP1_IN_Callback (uint16_t len)
|
||||
while (epi->buf)
|
||||
if (epi->buf_len < remain)
|
||||
{
|
||||
usb_lld_txcpy (epi->buf, epi->ep_num, offset, epi->buf_len);
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+offset, epi->buf, epi->buf_len);
|
||||
#else
|
||||
usb_lld_txcpy (epi->buf, ep_num, offset, epi->buf_len);
|
||||
#endif
|
||||
offset += epi->buf_len;
|
||||
remain -= epi->buf_len;
|
||||
tx_size += epi->buf_len;
|
||||
@@ -380,7 +398,11 @@ EP1_IN_Callback (uint16_t len)
|
||||
}
|
||||
else
|
||||
{
|
||||
usb_lld_txcpy (epi->buf, epi->ep_num, offset, remain);
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+offset, epi->buf, remain);
|
||||
#else
|
||||
usb_lld_txcpy (epi->buf, ep_num, offset, remain);
|
||||
#endif
|
||||
epi->buf += remain;
|
||||
epi->cnt += remain;
|
||||
epi->buf_len -= remain;
|
||||
@@ -390,7 +412,12 @@ EP1_IN_Callback (uint16_t len)
|
||||
|
||||
if (tx_size < USB_LL_BUF_SIZE)
|
||||
epi->tx_done = 1;
|
||||
usb_lld_tx_enable (epi->ep_num, tx_size);
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (ep_num, endp1_tx_buf, tx_size);
|
||||
#else
|
||||
usb_lld_tx_enable (ep_num, tx_size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,6 +636,9 @@ static void ccid_abdata (struct ep_out *epo, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
static uint8_t endp1_rx_buf[64]; /* Only support single CCID interface. */
|
||||
#endif
|
||||
|
||||
static void
|
||||
ccid_prepare_receive (struct ccid *c)
|
||||
@@ -619,17 +649,25 @@ ccid_prepare_receive (struct ccid *c)
|
||||
c->epo->cnt = 0;
|
||||
c->epo->next_buf = ccid_abdata;
|
||||
c->epo->end_rx = end_ccid_rx;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_rx_enable_buf (c->epo->ep_num, endp1_rx_buf, 64);
|
||||
#else
|
||||
usb_lld_rx_enable (c->epo->ep_num);
|
||||
#endif
|
||||
DEBUG_INFO ("Rx ready\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Rx ready callback
|
||||
*/
|
||||
|
||||
static void
|
||||
EP1_OUT_Callback (uint16_t len)
|
||||
ccid_rx_ready (uint8_t ep_num, uint16_t len)
|
||||
{
|
||||
/*
|
||||
* If we support multiple CCID interfaces, we select endpoint object
|
||||
* by EP_NUM. Because it has only single CCID interface now, it's
|
||||
* hard-coded, here.
|
||||
*/
|
||||
struct ep_out *epo = &endpoint_out;
|
||||
int offset = 0;
|
||||
int cont;
|
||||
@@ -640,7 +678,11 @@ EP1_OUT_Callback (uint16_t len)
|
||||
break;
|
||||
else if (len <= epo->buf_len)
|
||||
{
|
||||
usb_lld_rxcpy (epo->buf, epo->ep_num, offset, len);
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (epo->buf, endp1_rx_buf + offset, len);
|
||||
#else
|
||||
usb_lld_rxcpy (epo->buf, ep_num, offset, len);
|
||||
#endif
|
||||
epo->buf += len;
|
||||
epo->cnt += len;
|
||||
epo->buf_len -= len;
|
||||
@@ -648,7 +690,11 @@ EP1_OUT_Callback (uint16_t len)
|
||||
}
|
||||
else /* len > buf_len */
|
||||
{
|
||||
usb_lld_rxcpy (epo->buf, epo->ep_num, offset, epo->buf_len);
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (epo->buf, endp1_rx_buf + offset, epo->buf_len);
|
||||
#else
|
||||
usb_lld_rxcpy (epo->buf, ep_num, offset, epo->buf_len);
|
||||
#endif
|
||||
len -= epo->buf_len;
|
||||
offset += epo->buf_len;
|
||||
epo->next_buf (epo, len); /* Update epo->buf, cnt, buf_len */
|
||||
@@ -661,7 +707,11 @@ EP1_OUT_Callback (uint16_t len)
|
||||
cont = epo->end_rx (epo, orig_len);
|
||||
|
||||
if (cont)
|
||||
usb_lld_rx_enable (epo->ep_num);
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_rx_enable_buf (ep_num, endp1_rx_buf, 64);
|
||||
#else
|
||||
usb_lld_rx_enable (ep_num);
|
||||
#endif
|
||||
else
|
||||
notify_icc (epo);
|
||||
}
|
||||
@@ -669,16 +719,24 @@ EP1_OUT_Callback (uint16_t len)
|
||||
|
||||
extern void EP6_IN_Callback (uint16_t len);
|
||||
|
||||
#if defined(DEBUG) && defined(GNU_LINUX_EMULATION)
|
||||
static uint8_t endp5_buf[VIRTUAL_COM_PORT_DATA_SIZE];
|
||||
#endif
|
||||
|
||||
static void
|
||||
usb_rx_ready (uint8_t ep_num, uint16_t len)
|
||||
{
|
||||
if (ep_num == ENDP1)
|
||||
EP1_OUT_Callback (len);
|
||||
ccid_rx_ready (ep_num, len);
|
||||
#ifdef DEBUG
|
||||
else if (ep_num == ENDP5)
|
||||
{
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_rx_enable (ep_num, endp5_buf, VIRTUAL_COM_PORT_DATA_SIZE);
|
||||
#else
|
||||
usb_lld_rx_enable (ep_num);
|
||||
#endif
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
}
|
||||
#endif
|
||||
@@ -688,7 +746,7 @@ static void
|
||||
usb_tx_done (uint8_t ep_num, uint16_t len)
|
||||
{
|
||||
if (ep_num == ENDP1)
|
||||
EP1_IN_Callback (len);
|
||||
ccid_tx_done (ep_num, len);
|
||||
else if (ep_num == ENDP2)
|
||||
{
|
||||
/* INTERRUPT Transfer done */
|
||||
@@ -756,14 +814,21 @@ static void ccid_error (struct ccid *c, int offset)
|
||||
/* This is a single packet Bulk-IN transaction */
|
||||
c->epi->buf = NULL;
|
||||
c->epi->tx_done = 1;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf, ccid_reply, CCID_MSG_HEADER_SIZE);
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, CCID_MSG_HEADER_SIZE);
|
||||
#else
|
||||
usb_lld_write (c->epi->ep_num, ccid_reply, CCID_MSG_HEADER_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void *openpgp_card_thread (void *arg);
|
||||
|
||||
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
|
||||
#define STACK_ADDR_GPG ((uint32_t)__process3_stack_base__)
|
||||
#define STACK_SIZE_GPG ((uint32_t)__process3_stack_size__)
|
||||
#define STACK_PROCESS_3
|
||||
#include "stack-def.h"
|
||||
#define STACK_ADDR_GPG ((uintptr_t)process3_base)
|
||||
#define STACK_SIZE_GPG (sizeof process3_base)
|
||||
|
||||
#define PRIO_GPG 1
|
||||
|
||||
|
||||
@@ -793,9 +858,14 @@ ccid_power_on (struct ccid *c)
|
||||
p[CCID_MSG_ERROR_OFFSET] = 0x00;
|
||||
p[CCID_MSG_CHAIN_OFFSET] = 0x00;
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head));
|
||||
#else
|
||||
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
|
||||
usb_lld_txcpy (ATR_head, c->epi->ep_num, CCID_MSG_HEADER_SIZE,
|
||||
sizeof (ATR_head));
|
||||
#endif
|
||||
for (i = 1; i < (int)sizeof (ATR_head); i++)
|
||||
xor_check ^= ATR_head[i];
|
||||
memcpy (p, historical_bytes + 1, hist_len);
|
||||
@@ -806,13 +876,22 @@ ccid_power_on (struct ccid *c)
|
||||
for (i = 0; i < hist_len; i++)
|
||||
xor_check ^= p[i];
|
||||
p[i] = xor_check;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+sizeof (ATR_head), p, hist_len+1);
|
||||
#else
|
||||
usb_lld_txcpy (p, c->epi->ep_num, CCID_MSG_HEADER_SIZE + sizeof (ATR_head),
|
||||
hist_len+1);
|
||||
#endif
|
||||
|
||||
/* This is a single packet Bulk-IN transaction */
|
||||
c->epi->buf = NULL;
|
||||
c->epi->tx_done = 1;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
|
||||
CCID_MSG_HEADER_SIZE + size_atr);
|
||||
#else
|
||||
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + size_atr);
|
||||
#endif
|
||||
DEBUG_INFO ("ON\r\n");
|
||||
|
||||
return CCID_STATE_WAIT;
|
||||
@@ -843,7 +922,13 @@ ccid_send_status (struct ccid *c)
|
||||
/* This is a single packet Bulk-IN transaction */
|
||||
c->epi->buf = NULL;
|
||||
c->epi->tx_done = 1;
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf, ccid_reply, CCID_MSG_HEADER_SIZE);
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, CCID_MSG_HEADER_SIZE);
|
||||
#else
|
||||
usb_lld_write (c->epi->ep_num, ccid_reply, CCID_MSG_HEADER_SIZE);
|
||||
#endif
|
||||
|
||||
led_blink (LED_SHOW_STATUS);
|
||||
#ifdef DEBUG_MORE
|
||||
@@ -890,19 +975,35 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
|
||||
p[CCID_MSG_ERROR_OFFSET] = error;
|
||||
p[CCID_MSG_CHAIN_OFFSET] = 0;
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
|
||||
#else
|
||||
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
|
||||
#endif
|
||||
if (len == 0)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
|
||||
CCID_MSG_HEADER_SIZE);
|
||||
#else
|
||||
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (CCID_MSG_HEADER_SIZE + len <= USB_LL_BUF_SIZE)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
|
||||
c->a->res_apdu_data, c->a->res_apdu_data_len);
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+c->a->res_apdu_data_len,
|
||||
c->sw1sw2, 2);
|
||||
#else
|
||||
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num,
|
||||
CCID_MSG_HEADER_SIZE, c->a->res_apdu_data_len);
|
||||
usb_lld_txcpy (c->sw1sw2, c->epi->ep_num,
|
||||
CCID_MSG_HEADER_SIZE + c->a->res_apdu_data_len, 2);
|
||||
#endif
|
||||
c->epi->buf = NULL;
|
||||
if (CCID_MSG_HEADER_SIZE + len < USB_LL_BUF_SIZE)
|
||||
c->epi->tx_done = 1;
|
||||
@@ -910,10 +1011,17 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
|
||||
}
|
||||
else if (CCID_MSG_HEADER_SIZE + len - 1 == USB_LL_BUF_SIZE)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
|
||||
c->a->res_apdu_data, c->a->res_apdu_data_len);
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+c->a->res_apdu_data_len,
|
||||
c->sw1sw2, 1);
|
||||
#else
|
||||
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num,
|
||||
CCID_MSG_HEADER_SIZE, c->a->res_apdu_data_len);
|
||||
usb_lld_txcpy (c->sw1sw2, c->epi->ep_num,
|
||||
CCID_MSG_HEADER_SIZE + c->a->res_apdu_data_len, 1);
|
||||
#endif
|
||||
c->epi->buf = &c->sw1sw2[1];
|
||||
c->epi->cnt = 1;
|
||||
c->epi->buf_len = 1;
|
||||
@@ -921,8 +1029,13 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
|
||||
}
|
||||
else if (CCID_MSG_HEADER_SIZE + len - 2 == USB_LL_BUF_SIZE)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
|
||||
c->a->res_apdu_data, c->a->res_apdu_data_len);
|
||||
#else
|
||||
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num,
|
||||
CCID_MSG_HEADER_SIZE, c->a->res_apdu_data_len);
|
||||
#endif
|
||||
c->epi->buf = &c->sw1sw2[0];
|
||||
c->epi->cnt = 0;
|
||||
c->epi->buf_len = 2;
|
||||
@@ -930,8 +1043,13 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
|
||||
c->a->res_apdu_data, USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
|
||||
#else
|
||||
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num, CCID_MSG_HEADER_SIZE,
|
||||
USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
|
||||
#endif
|
||||
c->epi->buf = c->a->res_apdu_data + USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE;
|
||||
c->epi->cnt = USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE;
|
||||
c->epi->buf_len = c->a->res_apdu_data_len
|
||||
@@ -939,7 +1057,11 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
|
||||
c->epi->next_buf = get_sw1sw2;
|
||||
}
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, tx_size);
|
||||
#else
|
||||
usb_lld_tx_enable (c->epi->ep_num, tx_size);
|
||||
#endif
|
||||
#ifdef DEBUG_MORE
|
||||
DEBUG_INFO ("DATA\r\n");
|
||||
#endif
|
||||
@@ -976,11 +1098,20 @@ ccid_send_data_block_0x9000 (struct ccid *c)
|
||||
p[CCID_MSG_CHAIN_OFFSET+1] = 0x90;
|
||||
p[CCID_MSG_CHAIN_OFFSET+2] = 0x00;
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE + len);
|
||||
#else
|
||||
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE + len);
|
||||
#endif
|
||||
c->epi->buf = NULL;
|
||||
c->epi->tx_done = 1;
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
|
||||
CCID_MSG_HEADER_SIZE + len);
|
||||
#else
|
||||
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + len);
|
||||
#endif
|
||||
#ifdef DEBUG_MORE
|
||||
DEBUG_INFO ("DATA\r\n");
|
||||
#endif
|
||||
@@ -1007,7 +1138,11 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
|
||||
p[CCID_MSG_ERROR_OFFSET] = 0;
|
||||
p[CCID_MSG_CHAIN_OFFSET] = 0;
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
|
||||
#else
|
||||
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
|
||||
#endif
|
||||
|
||||
set_sw1sw2 (c, chunk_len);
|
||||
|
||||
@@ -1022,10 +1157,19 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
|
||||
else
|
||||
size_for_sw = 0;
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, c->p, chunk_len);
|
||||
#else
|
||||
usb_lld_txcpy (c->p, c->epi->ep_num, CCID_MSG_HEADER_SIZE, chunk_len);
|
||||
#endif
|
||||
if (size_for_sw)
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+chunk_len,
|
||||
c->sw1sw2, size_for_sw);
|
||||
#else
|
||||
usb_lld_txcpy (c->sw1sw2, c->epi->ep_num,
|
||||
CCID_MSG_HEADER_SIZE + chunk_len, size_for_sw);
|
||||
#endif
|
||||
tx_size = CCID_MSG_HEADER_SIZE + chunk_len + size_for_sw;
|
||||
if (size_for_sw == 2)
|
||||
{
|
||||
@@ -1044,8 +1188,13 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
|
||||
c->p, USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
|
||||
#else
|
||||
usb_lld_txcpy (c->p, c->epi->ep_num, CCID_MSG_HEADER_SIZE,
|
||||
USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
|
||||
#endif
|
||||
c->epi->buf = c->p + USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE;
|
||||
c->epi->cnt = 0;
|
||||
c->epi->buf_len = chunk_len - (USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
|
||||
@@ -1054,7 +1203,11 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
|
||||
|
||||
c->p += chunk_len;
|
||||
c->len -= chunk_len;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, tx_size);
|
||||
#else
|
||||
usb_lld_tx_enable (c->epi->ep_num, tx_size);
|
||||
#endif
|
||||
#ifdef DEBUG_MORE
|
||||
DEBUG_INFO ("DATA\r\n");
|
||||
#endif
|
||||
@@ -1086,13 +1239,23 @@ ccid_send_params (struct ccid *c)
|
||||
p[CCID_MSG_ERROR_OFFSET] = 0;
|
||||
p[CCID_MSG_CHAIN_OFFSET] = 0x01; /* ProtocolNum: T=1 */
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
|
||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, params, sizeof params);
|
||||
#else
|
||||
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
|
||||
usb_lld_txcpy (params, c->epi->ep_num, CCID_MSG_HEADER_SIZE, sizeof params);
|
||||
#endif
|
||||
|
||||
/* This is a single packet Bulk-IN transaction */
|
||||
c->epi->buf = NULL;
|
||||
c->epi->tx_done = 1;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
|
||||
CCID_MSG_HEADER_SIZE + sizeof params);
|
||||
#else
|
||||
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + sizeof params);
|
||||
#endif
|
||||
#ifdef DEBUG_MORE
|
||||
DEBUG_INFO ("PARAMS\r\n");
|
||||
#endif
|
||||
@@ -1359,6 +1522,9 @@ ccid_usb_reset (int full)
|
||||
full ? EV_USB_DEVICE_RESET : EV_USB_SET_INTERFACE);
|
||||
}
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
static uint8_t endp2_tx_buf[2];
|
||||
#endif
|
||||
|
||||
#define NOTIFY_SLOT_CHANGE 0x50
|
||||
static void
|
||||
@@ -1374,7 +1540,12 @@ ccid_notify_slot_change (struct ccid *c)
|
||||
|
||||
notification[0] = NOTIFY_SLOT_CHANGE;
|
||||
notification[1] = msg;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
memcpy (endp2_tx_buf, notification, sizeof notification);
|
||||
usb_lld_tx_enable_buf (ENDP2, endp2_tx_buf, sizeof notification);
|
||||
#else
|
||||
usb_lld_write (ENDP2, notification, sizeof notification);
|
||||
#endif
|
||||
led_blink (LED_TWOSHOTS);
|
||||
}
|
||||
|
||||
@@ -1384,7 +1555,12 @@ ccid_notify_slot_change (struct ccid *c)
|
||||
#define GPG_THREAD_TERMINATED 0xffff
|
||||
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#include <signal.h>
|
||||
#define INTR_REQ_USB SIGUSR1
|
||||
#else
|
||||
#define INTR_REQ_USB 20
|
||||
#endif
|
||||
|
||||
extern uint32_t bDeviceState;
|
||||
extern void usb_device_reset (struct usb_dev *dev);
|
||||
@@ -1687,7 +1863,11 @@ _write (const char *s, int len)
|
||||
(len < VIRTUAL_COM_PORT_DATA_SIZE) ? len : VIRTUAL_COM_PORT_DATA_SIZE;
|
||||
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_tx_enable_buf (ENDP3, s, packet_len);
|
||||
#else
|
||||
usb_lld_write (ENDP3, s, packet_len);
|
||||
#endif
|
||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb-msc.h"
|
||||
|
||||
extern uint8_t __process5_stack_base__[], __process5_stack_size__[];
|
||||
#define STACK_ADDR_MSC ((uint32_t)__process5_stack_base__)
|
||||
#define STACK_SIZE_MSC ((uint32_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;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* usb_ctrl.c - USB control pipe device specific code for Gnuk
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb_conf.h"
|
||||
#include "gnuk.h"
|
||||
#include "mcu/stm32f103.h"
|
||||
#include "neug.h"
|
||||
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
#include "usb-cdc.h"
|
||||
@@ -108,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 !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
|
||||
{
|
||||
@@ -129,7 +139,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
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);
|
||||
}
|
||||
@@ -138,7 +152,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
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);
|
||||
}
|
||||
@@ -146,9 +164,14 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -161,8 +184,12 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
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);
|
||||
@@ -180,12 +207,16 @@ usb_device_reset (struct usb_dev *dev)
|
||||
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, 1);
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 1);
|
||||
|
||||
bDeviceState = ATTACHED;
|
||||
ccid_usb_reset (1);
|
||||
@@ -202,38 +233,34 @@ static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
|
||||
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 (struct usb_dev *dev, 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)
|
||||
if ((rbit (crc32_rv_get ()) ^ crc32) == 0xffffffff)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
usb_setup (struct usb_dev *dev)
|
||||
@@ -245,16 +272,22 @@ usb_setup (struct usb_dev *dev)
|
||||
{
|
||||
if (USB_SETUP_GET (arg->type))
|
||||
{
|
||||
#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 + arg->value * 0x100
|
||||
+ arg->index);
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
uint8_t *addr = sram_address ((arg->value * 0x100) + arg->index);
|
||||
#endif
|
||||
|
||||
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
||||
{
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
return -1;
|
||||
|
||||
@@ -266,16 +299,23 @@ usb_setup (struct usb_dev *dev)
|
||||
256 - (arg->index + arg->len));
|
||||
|
||||
return usb_lld_ctrl_recv (dev, addr, arg->len);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else if (arg->request == USB_FSIJ_GNUK_EXEC && arg->len == 0)
|
||||
{
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
return -1;
|
||||
|
||||
if (((uint32_t)addr & 0x03))
|
||||
if (((uintptr_t)addr & 0x03))
|
||||
return -1;
|
||||
|
||||
return download_check_crc32 (dev, (uint32_t *)addr);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else if (arg->request == USB_FSIJ_GNUK_CARD_CHANGE && arg->len == 0)
|
||||
{
|
||||
@@ -435,7 +475,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
|
||||
usb_lld_set_configuration (dev, 1);
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
gnuk_setup_endpoints_for_interface (i, 0);
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 0);
|
||||
bDeviceState = CONFIGURED;
|
||||
}
|
||||
else if (current_conf != dev->dev_req.value)
|
||||
@@ -445,7 +485,7 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
|
||||
usb_lld_set_configuration (dev, 0);
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
gnuk_setup_endpoints_for_interface (i, 1);
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 1);
|
||||
bDeviceState = ADDRESSED;
|
||||
ccid_usb_reset (1);
|
||||
}
|
||||
@@ -468,7 +508,7 @@ usb_set_interface (struct usb_dev *dev)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
gnuk_setup_endpoints_for_interface (interface, 0);
|
||||
gnuk_setup_endpoints_for_interface (dev, interface, 0);
|
||||
ccid_usb_reset (0);
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,10 @@ static const uint8_t hid_report_desc[] = {
|
||||
#define USB_CCID_DATA_SIZE 64
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t device_desc[] = {
|
||||
#if !defined(GNU_LINUX_EMULATION)
|
||||
static const
|
||||
#endif
|
||||
uint8_t device_desc[] = {
|
||||
18, /* bLength */
|
||||
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||
|
||||
@@ -24,4 +24,4 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object AID
|
||||
When requesting AID: 4f
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00......\x00\x00
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00[\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff]\x00\x00
|
||||
|
||||
@@ -24,4 +24,4 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object AID
|
||||
When requesting AID: 4f
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00......\x00\x00
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00[\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff]\x00\x00
|
||||
|
||||
@@ -24,4 +24,4 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object AID
|
||||
When requesting AID: 4f
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00......\x00\x00
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00[\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff]\x00\x00
|
||||
|
||||
48
tool/gnuk-emulation-setup
Executable file
48
tool/gnuk-emulation-setup
Executable file
@@ -0,0 +1,48 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# gnuk-emulation-setup - Generate flash image for Gnuk
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
if test "$1" = "--help"; then
|
||||
echo "Usage:"
|
||||
echo " $0 [output-file]"
|
||||
echo " Generate Gnuk flash image"
|
||||
echo " $0 --help"
|
||||
echo " Show this message"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
OUTPUT_FILE=${1:-$HOME/.gnuk-flash-image}
|
||||
|
||||
# Generate 8192-byte flash data into OUTPUT_FILE
|
||||
|
||||
exec > $OUTPUT_FILE
|
||||
|
||||
for i in $(seq 512); do
|
||||
/bin/echo -n -e '\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
done
|
||||
|
||||
/bin/echo -n -e '\x00\x00\xff\xff\xff\xff\xff\xff'
|
||||
|
||||
for i in $(seq 511); do
|
||||
/bin/echo -n -e '\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
done
|
||||
|
||||
chmod og-rw $OUTPUT_FILE
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
gnuk_token.py - a library for Gnuk Token
|
||||
|
||||
Copyright (C) 2011, 2012, 2013, 2015
|
||||
Copyright (C) 2011, 2012, 2013, 2015, 2017
|
||||
Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
@@ -26,6 +26,12 @@ import binascii
|
||||
import usb, time
|
||||
from array import array
|
||||
|
||||
# Possible Gnuk Token products
|
||||
USB_PRODUCT_LIST=[
|
||||
{ 'vendor' : 0x234b, 'product' : 0x0000 }, # FSIJ Gnuk Token
|
||||
{ 'vendor' : 0x20a0, 'product' : 0x4211 }, # Nitrokey Start
|
||||
]
|
||||
|
||||
# USB class, subclass, protocol
|
||||
CCID_CLASS = 0x0B
|
||||
CCID_SUBCLASS = 0x00
|
||||
@@ -586,19 +592,18 @@ def gnuk_devices():
|
||||
alt.interfaceProtocol == CCID_PROTOCOL_0:
|
||||
yield dev, config, alt
|
||||
|
||||
USB_VENDOR_FSIJ=0x234b
|
||||
USB_PRODUCT_GNUK=0x0000
|
||||
|
||||
def gnuk_devices_by_vidpid():
|
||||
busses = usb.busses()
|
||||
for bus in busses:
|
||||
devices = bus.devices
|
||||
for dev in devices:
|
||||
if dev.idVendor != USB_VENDOR_FSIJ:
|
||||
continue
|
||||
if dev.idProduct != USB_PRODUCT_GNUK:
|
||||
continue
|
||||
yield dev
|
||||
for cand in USB_PRODUCT_LIST:
|
||||
if dev.idVendor != cand['vendor']:
|
||||
continue
|
||||
if dev.idProduct != cand['product']:
|
||||
continue
|
||||
yield dev
|
||||
break
|
||||
|
||||
def get_gnuk_device():
|
||||
icc = None
|
||||
|
||||
@@ -69,8 +69,9 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
|
||||
gnuk = None
|
||||
#
|
||||
reg = None
|
||||
print("Waiting for device to appear:")
|
||||
while reg == None:
|
||||
print("Wait %d seconds..." % wait_e)
|
||||
print(" Wait %d seconds..." % wait_e)
|
||||
time.sleep(wait_e)
|
||||
for dev in gnuk_devices_by_vidpid():
|
||||
try:
|
||||
@@ -84,9 +85,13 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
|
||||
print("%08x:%08x" % mem_info)
|
||||
print("Downloading the program")
|
||||
reg.download(mem_info[0], data_upgrade)
|
||||
print("Protecting device")
|
||||
reg.protect()
|
||||
print("Finish flashing")
|
||||
reg.finish()
|
||||
print("Resetting device")
|
||||
reg.reset_device()
|
||||
print("Update procedure finished")
|
||||
return 0
|
||||
|
||||
from getpass import getpass
|
||||
@@ -119,6 +124,9 @@ if __name__ == '__main__':
|
||||
passwd = getpass("Admin password: ")
|
||||
filename_regnual = sys.argv[1]
|
||||
filename_upgrade = sys.argv[2]
|
||||
if not filename_regnual.endswith('bin') or not filename_upgrade.endswith('bin'):
|
||||
print("Both input files must be in binary format (*.bin)!")
|
||||
exit(1)
|
||||
f = open(filename_regnual,"rb")
|
||||
data_regnual = f.read()
|
||||
f.close()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
usb_strings.py - a tool to dump USB string
|
||||
|
||||
Copyright (C) 2012, 2015 Free Software Initiative of Japan
|
||||
Copyright (C) 2012, 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.
|
||||
@@ -22,28 +22,14 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from gnuk_token import *
|
||||
import usb, sys
|
||||
|
||||
USB_VENDOR_FSIJ=0x234b
|
||||
USB_PRODUCT_GNUK=0x0000
|
||||
|
||||
def gnuk_devices_by_vidpid():
|
||||
busses = usb.busses()
|
||||
for bus in busses:
|
||||
devices = bus.devices
|
||||
for dev in devices:
|
||||
if dev.idVendor != USB_VENDOR_FSIJ:
|
||||
continue
|
||||
if dev.idProduct != USB_PRODUCT_GNUK:
|
||||
continue
|
||||
yield dev
|
||||
|
||||
field = ['', 'Vendor', 'Product', 'Serial', 'Revision', 'Config', 'Sys', 'Board']
|
||||
|
||||
def main(n):
|
||||
for dev in gnuk_devices_by_vidpid():
|
||||
handle = dev.open()
|
||||
print("Device: %s" % dev.filename)
|
||||
try:
|
||||
for i in range(1,n):
|
||||
s = handle.getString(i, 512)
|
||||
|
||||
Reference in New Issue
Block a user