Compare commits
101 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad42010272 | ||
|
|
8ce91267be | ||
|
|
b5c2ace2ae | ||
|
|
4cbc661fb7 | ||
|
|
543f28574e | ||
|
|
fe94e1885b | ||
|
|
ce82b347f9 | ||
|
|
d54712c04c | ||
|
|
9c63c874d0 | ||
|
|
bb9b31166f | ||
|
|
e417846408 | ||
|
|
21a481060c | ||
|
|
d4c9d6653b | ||
|
|
f00306627b | ||
|
|
f4b36b7503 | ||
|
|
e85527d302 | ||
|
|
bd58997dc9 | ||
|
|
9d5834d47b | ||
|
|
36ecf67694 | ||
|
|
c9b1e511ba | ||
|
|
01b5aa5984 | ||
|
|
b735c02ec2 | ||
|
|
2ecb104ae4 | ||
|
|
6b4f3c9934 | ||
|
|
660aaeb04b | ||
|
|
1022534c02 | ||
|
|
46cc64cf03 | ||
|
|
effc65381a | ||
|
|
6cbf5a4822 | ||
|
|
8ff3865890 | ||
|
|
43009f39e8 | ||
|
|
56fb5002bf | ||
|
|
3bb5097031 | ||
|
|
8319f4a14b | ||
|
|
f7cf0a3461 | ||
|
|
5ac52d3f2f | ||
|
|
209d459d09 | ||
|
|
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 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,7 +2,7 @@
|
||||
*.o
|
||||
*.pyc
|
||||
src/.dep
|
||||
src/Makefile
|
||||
src/config.mk
|
||||
src/config.h
|
||||
src/gnuk.ld
|
||||
src/board.h
|
||||
@@ -14,4 +14,3 @@ regnual/regnual.elf
|
||||
doc/_build
|
||||
tests/.cache
|
||||
tests/__pycache__
|
||||
emulation/gnuk_emulation
|
||||
|
||||
17
AUTHORS
17
AUTHORS
@@ -1,3 +1,20 @@
|
||||
Aurelien Jarno:
|
||||
Modified:
|
||||
src/Makefile
|
||||
src/configure
|
||||
src/main.c
|
||||
src/stack-def.h
|
||||
|
||||
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.
|
||||
|
||||
|
||||
428
ChangeLog
428
ChangeLog
@@ -1,3 +1,431 @@
|
||||
2017-11-26 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.2.7.
|
||||
|
||||
2017-11-24 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* regnual/regnual.c (calc_crc32): Enable CRC module fix.
|
||||
|
||||
* chopstx: Update to 1.6.
|
||||
|
||||
2017-11-17 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/stack-def.h (SIZE_0): Decrease.
|
||||
|
||||
* src/main.c (emit_led, display_status_code, main): Use
|
||||
chopstx_poll instead of eventflag_wait_timeout.
|
||||
|
||||
2017-11-17 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/stack-def.h (SIZE_0): Increase.
|
||||
|
||||
* src/main.c (emit_led, display_status_code, main): Use
|
||||
eventflag_wait_timeout instead of chopstx_usec_wait.
|
||||
|
||||
2017-11-17 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* regnual/regnual.c (calc_crc32): Enable CRC module.
|
||||
|
||||
* src/neug.c (crc32_rv_stop): New.
|
||||
(neug_fini): Call crc32_rv_stop.
|
||||
|
||||
* src/main.c (main): Call chopstx_conf_idle.
|
||||
|
||||
* src/usb-ccid.c (usb_event_handle): Use 2 for call of
|
||||
chopstx_conf_idle on suspend. Call random_fini on suspend
|
||||
to stop ADC module. Call random_init on wakeup.
|
||||
Sleep a bit to switch main thread.
|
||||
|
||||
2017-11-16 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.h (LED_OFF): New.
|
||||
|
||||
* src/usb-ccid.c (usb_event_handle): LED off on sleep.
|
||||
(ccid_thread): Use constant pointer for chopstx_poll.
|
||||
(poll_event_intr): Remove.
|
||||
|
||||
2017-11-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb-ccid.c (usb_event_handle): Allow sleep on suspend.
|
||||
|
||||
* src/usb_ctrl.c (usb_device_reset): Fix device state.
|
||||
|
||||
2017-11-14 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb-ccid.c (ccid_usb_reset): Remove
|
||||
(usb_event_handle): Return value change to notify
|
||||
caller about needs for going out of the loop.
|
||||
Support USB suspend/resume.
|
||||
(ccid_thread): Supporting USB suspend, sleep forever with
|
||||
timeout_p = NULL.
|
||||
|
||||
* src/main.c (main): Add USB_DEVICE_STATE_ prefix.
|
||||
* src/usb_ctrl.c: Likewise.
|
||||
(usb_device_reset): Don't call ccid_usb_reset.
|
||||
(usb_set_configuration, usb_set_interface): Likewise.
|
||||
|
||||
* src/usb_desc.c (device_desc): bcdUSB = 2.0, supporting
|
||||
suspend/resume.
|
||||
|
||||
2017-11-13 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb_ctrl.c: Use new const USB_DEVICE_STATE_*
|
||||
* src/main.c (main): Likewise.
|
||||
* src/usb-ccid.c: Likewise.
|
||||
(INTR_REQ_USB): Remove. Use the definition
|
||||
in usb-lld.h.
|
||||
|
||||
2017-11-08 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (gpg_do_kdf_check): New.
|
||||
(proc_resetting_code): Use gpg_do_kdf_check.
|
||||
* src/openpgp.c (cmd_verify, cmd_change_password)
|
||||
(cmd_reset_user_password): Likewise.
|
||||
|
||||
2017-11-07 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (proc_resetting_code): Error when
|
||||
it's not pass-hash.
|
||||
|
||||
* src/openpgp.c (cmd_verify, cmd_change_password)
|
||||
(cmd_reset_user_password): Avoid authentication error
|
||||
by old GnuPG which doesn't support KDF.
|
||||
|
||||
2017-11-06 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tests/test_empty_card.py (test_extended_capabilities): Support
|
||||
KDF-DO.
|
||||
* test/features/802_get_data_static.feature: Likewise.
|
||||
* test/features/402_get_data_static.feature: Likewise.
|
||||
* test/features/002_get_data_static.feature: Likewise.
|
||||
|
||||
2017-11-02 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (rw_kdf): Only writable when no keys.
|
||||
(gpg_do_get_initial_pw_setting): New.
|
||||
(gpg_do_write_prvkey): Use gpg_do_get_initial_pw_setting.
|
||||
(gpg_do_keygen): Likewise.
|
||||
(extended_capabilities): Enable KDF-DO available bit.
|
||||
|
||||
* src/openpgp.c (cmd_change_password): Use
|
||||
gpg_do_get_initial_pw_setting.
|
||||
* src/ac.c (verify_user_0, verify_admin_0): Likewise.
|
||||
|
||||
2017-11-01 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (GPG_DO_KDF): New.
|
||||
(GPG_DO_FEATURE_MNGMNT): New.
|
||||
(do_tag_to_nr): Support GPG_DO_KDF.
|
||||
(GPG_DO_UIF_SIG, GPG_DO_UIF_DEC, GPG_DO_UIF_AUT): New.
|
||||
(rw_kdf): New.
|
||||
(gpg_do_table): Add an entry for GPG_DO_KDF.
|
||||
|
||||
* src/gnuk.h (NR_DO_KDF): New.
|
||||
|
||||
2017-10-31 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp-do.c (gpg_do_keygen): Bug fix for memory alignment.
|
||||
|
||||
2017-10-24 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tests/card_reader.py (CardReader.ccid_power_on): Setting
|
||||
PPS only for Gemalto GemPC reader.
|
||||
|
||||
2017-10-18 Aurelien Jarno <aurelien@aurel32.net>
|
||||
|
||||
* src/gnuk.ld.in: Fix keystore_pool size.
|
||||
|
||||
2017-10-12 Aurelien Jarno <aurelien@aurel32.net>
|
||||
|
||||
* polarssl/include/polarssl/bn_mul.h (MULADDC_HUIT_DEAD): Rename
|
||||
from MULADDC_HUIT.
|
||||
[__ARM_FEATURE_DSP] (MULADDC_1024_CORE, MULADDC_1024_LOOP)
|
||||
(MULADDC_INIT, MULADDC_CORE, MULADDC_HUIT, MULADDC_STOP): New.
|
||||
|
||||
* polarssl/library/bignum.c (mpi_montsqr): Check on
|
||||
POLARSSL_HAVE_ASM and __arm__.
|
||||
[__ARM_FEATURE_DSP] (mpi_montsqr): New.
|
||||
(MAX_WSIZE): New.
|
||||
(mpi_exp_mod): Use MAX_WSIZE.
|
||||
|
||||
* src/Makefile (DEFS): Remove BIGNUM_C_IMPLEMENTATION.
|
||||
|
||||
* src/main.c (HEAP_SIZE): Rename from MEMORY_SIZE.
|
||||
(HEAP_END, HEAP_ALIGNMENT, HEAP_ALIGN): Likewise.
|
||||
|
||||
* src/stack-def.h (SIZE_3): Depend on MEMORY_SIZE.
|
||||
* src/configure: Emit DEFS with MEMORY_SIZE.
|
||||
|
||||
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.
|
||||
|
||||
@@ -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.7
|
||||
|
||||
Released 2017-11-26, by NIIBE Yutaka
|
||||
|
||||
** reGNUal
|
||||
reGNUal enables CRC module by itself.
|
||||
|
||||
** Flash update change
|
||||
CRC module is disabled when Gnuk stops. It's reGNUal which needs to
|
||||
enable CRC module.
|
||||
|
||||
** Support of USB suspend
|
||||
USB suspend and wakeup event are now handled.
|
||||
|
||||
** KDF-DO support and KDF by host
|
||||
KDF-DO is now available. Host can use this feature.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.6.
|
||||
|
||||
|
||||
* 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
|
||||
|
||||
59
README
59
README
@@ -1,28 +1,37 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 1.2.4
|
||||
2017-05-12
|
||||
Version 1.2.7
|
||||
2017-11-26
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
This is the release of Gnuk, version 1.2.4, which has major
|
||||
This is the release of Gnuk, version 1.2.7, 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.
|
||||
|
||||
In this release, experimental KDF-DO support is added. To use the
|
||||
feature, you need to build/install experimental branch of GnuPG by
|
||||
yourself:
|
||||
|
||||
https://dev.gnupg.org/source/gnupg/history/gniibe%252Fscd-kdf-support/
|
||||
|
||||
And manually prepare the KDF-DO on your token.
|
||||
|
||||
|
||||
What's Gnuk?
|
||||
============
|
||||
@@ -216,15 +225,17 @@ Some tools are written in Python. If your Python is not installed as
|
||||
Python 2.7 and PyUSB 0.4.3 is assumed.
|
||||
|
||||
|
||||
Souce code
|
||||
==========
|
||||
Source code
|
||||
===========
|
||||
|
||||
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 +259,7 @@ External source code
|
||||
|
||||
Gnuk is distributed with external source code.
|
||||
|
||||
* chopstx/ -- Chopstx 1.3
|
||||
* chopstx/ -- Chopstx 1.5
|
||||
|
||||
We use Chopstx as the kernel for Gnuk.
|
||||
|
||||
@@ -297,6 +308,15 @@ Gnuk is distributed with external source code.
|
||||
POLARSSL_SELF_TEST, and POLARSSL_PADLOCK_C, and only define
|
||||
POLARSSL_GENPRIME when defined KEYGEN_SUPPORT.
|
||||
|
||||
And polarssl/library/bignum.c is modified to work on 64-bit machine.
|
||||
|
||||
Aurelien Jarno also modified:
|
||||
|
||||
polarssl/include/polarssl/bn_mul.h
|
||||
polarssl/library/bignum.c
|
||||
|
||||
See ChangeLog (and/or history of git) for detail.
|
||||
|
||||
|
||||
USB vendor ID and product ID (USB device ID)
|
||||
============================================
|
||||
@@ -361,10 +381,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.28-4+9+b2
|
||||
gcc-arm-none-eabi 15:5.4.1+svn241155-1
|
||||
binutils-arm-none-eabi 2.28-4+9+b3
|
||||
gcc-arm-none-eabi 15:6.3.1+svn253039-1
|
||||
gdb-arm-none-eabi 7.12-6+9+b2
|
||||
libnewlib-arm-none-eabi 2.4.0.20160527-2
|
||||
libnewlib-arm-none-eabi 2.4.0.20160527-3
|
||||
|
||||
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
||||
GNU Toolchain for 'arm-none-eabi' target.
|
||||
@@ -537,7 +557,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
|
||||
@@ -583,24 +603,17 @@ 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 update --init
|
||||
|
||||
Gnuk 1.0 uses ChibiOS/RT, and then, we have migrated from to Chopstx
|
||||
in the development phase of Gnuk 1.1. If you have old code of
|
||||
ChibiOS/RT, you need:
|
||||
|
||||
Edit .git/config to remove chibios reference and
|
||||
$ git rm --cached chibios
|
||||
|
||||
|
||||
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:
|
||||
|
||||
@@ -610,6 +623,8 @@ 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
|
||||
==================
|
||||
|
||||
4
THANKS
4
THANKS
@@ -7,16 +7,19 @@ Gnuk was originally written by NIIBE Yutaka. People contributed by
|
||||
encouraging the development, testing the implementation, suggesting
|
||||
improvements, or fixing bugs. Here is a list of those people.
|
||||
|
||||
Aurelien Jarno aurelien@aurel32.net
|
||||
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
|
||||
@@ -33,6 +36,7 @@ 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
|
||||
|
||||
2
chopstx
2
chopstx
Submodule chopstx updated: 89eb54929e...9e527b0532
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
|
||||
@@ -1,31 +0,0 @@
|
||||
SRCS = usbip-server.c usb-emu.c glue.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
TARGET=gnuk_emulation
|
||||
GNUKDIR=../src
|
||||
|
||||
GNUK_SRCS = main.c call-rsa.c \
|
||||
usb-ccid.c openpgp.c ac.c openpgp-do.c flash.c \
|
||||
bn.c mod.c \
|
||||
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
|
||||
random.c neug.c sha256.c
|
||||
USB_SRCS=usb_desc.c usb_ctrl.c
|
||||
|
||||
GNUK_CSRC = $(addprefix $(GNUKDIR)/, $(GNUK_SRCS))
|
||||
GNUK_OBJS = $(notdir $(GNUK_CSRC:.c=.o))
|
||||
|
||||
USB_CSRC = $(addprefix $(GNUKDIR)/, $(USB_SRCS))
|
||||
USB_OBJS = $(notdir $(USB_CSRC:.c=.o))
|
||||
|
||||
# all:
|
||||
# echo $(GNUK_OBJS)
|
||||
|
||||
$(TARGET): $(OBJS) $(USB_OBJS) Makefile
|
||||
$(CC) -o $(TARGET) $(OBJS) $(USB_OBJS)
|
||||
|
||||
$(GNUK_OBJS): %.o : $(GNUKDIR)/%.c Makefile
|
||||
$(CC) -c $(CFLAGS) -I. -I$(GNUKDIR) -I../chopstx $< -o $@
|
||||
|
||||
$(USB_OBJS): %.o : $(GNUKDIR)/%.c Makefile
|
||||
$(CC) -c $(CFLAGS) -I. -I$(GNUKDIR) -I../chopstx $< -o $@
|
||||
@@ -1,54 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t _regnual_start;
|
||||
uint8_t __heap_end__;
|
||||
|
||||
int
|
||||
check_crc32 (const uint32_t *start_p, const uint32_t *end_p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
sram_address (uint32_t offset)
|
||||
{
|
||||
return ((uint8_t *)0x20000000) + offset;
|
||||
}
|
||||
|
||||
const uint8_t sys_version[8] = {
|
||||
3*2+2, /* bLength */
|
||||
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
|
||||
/* sys version: "3.0" */
|
||||
'3', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
void
|
||||
led_blink (int spec)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ccid_usb_reset (int full)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ccid_card_change_signal (int how)
|
||||
{
|
||||
}
|
||||
|
||||
enum ccid_state {
|
||||
CCID_STATE_NOCARD, /* No card available */
|
||||
CCID_STATE_START, /* Initial */
|
||||
CCID_STATE_WAIT, /* Waiting APDU */
|
||||
/* Busy1, Busy2, Busy3, Busy5 */
|
||||
CCID_STATE_EXECUTE, /* Busy4 */
|
||||
CCID_STATE_RECEIVE, /* APDU Received Partially */
|
||||
CCID_STATE_SEND, /* APDU Sent Partially */
|
||||
|
||||
CCID_STATE_EXITED, /* ICC Thread Terminated */
|
||||
CCID_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||
};
|
||||
|
||||
static enum ccid_state ccid_state;
|
||||
enum ccid_state *const ccid_state_p = &ccid_state;
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* usb-emu.c - USB driver for USBIP emulation
|
||||
*
|
||||
* Copyright (C) 2017 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Chopstx, a thread library for embedded.
|
||||
*
|
||||
* Chopstx 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.
|
||||
*
|
||||
* Chopstx is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../chopstx/usb_lld.h"
|
||||
|
||||
int
|
||||
usb_lld_ctrl_ack (struct usb_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
usb_lld_ctrl_recv (struct usb_dev *dev, void *p, size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
usb_lld_current_configuration (struct usb_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_prepare_shutdown (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_ctrl_error (struct usb_dev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_reset (struct usb_dev *dev, uint8_t feature)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_set_configuration (struct usb_dev *dev, uint8_t config)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
usb_lld_shutdown (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
|
||||
int ep_rx_addr, int ep_tx_addr,
|
||||
int ep_rx_memory_size)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_stall (int ep_num)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
usb_lld_stall_tx (int ep_num)
|
||||
{
|
||||
usb_lld_stall (ep_num);
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_stall_rx (int ep_num)
|
||||
{
|
||||
usb_lld_stall (ep_num);
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* usbip-server.c - USB Device Emulation by USBIP Protocol
|
||||
*
|
||||
* Copyright (C) 2017 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Chopstx, a thread library for embedded.
|
||||
*
|
||||
* Chopstx 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.
|
||||
*
|
||||
* Chopstx 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 <unistd.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define USBIP_PORT 3240
|
||||
|
||||
#define CMD_REQ_LIST 0x01118005
|
||||
#define CMD_REQ_ATTACH 0x01118003
|
||||
#define CMD_URB 0x00000001
|
||||
#define CMD_DETACH 0x00000002
|
||||
|
||||
struct usbip_msg_head {
|
||||
uint32_t cmd;
|
||||
uint32_t seq;
|
||||
};
|
||||
|
||||
#define USBIP_REPLY_HEADER_SIZE 12
|
||||
#define DEVICE_INFO_SIZE (256+32+12+6+6)
|
||||
#define INTERFACE_INFO_SIZE 4
|
||||
#define DEVICE_LIST_SIZE (USBIP_REPLY_HEADER_SIZE+DEVICE_INFO_SIZE*1+INTERFACE_INFO_SIZE*1)
|
||||
|
||||
#define USBIP_REPLY_DEVICE_LIST "\x01\x11\x00\x05"
|
||||
#define NETWORK_UINT32_ZERO "\x00\x00\x00\x00"
|
||||
#define NETWORK_UINT32_ONE "\x00\x00\x00\x01"
|
||||
#define NETWORK_UINT32_TWO "\x00\x00\x00\x02"
|
||||
#define NETWORK_UINT16_FSIJ "\x23\x4b"
|
||||
#define NETWORK_UINT16_ZERO "\x00\x00"
|
||||
#define NETWORK_UINT16_ONE_ONE "\x01\x01"
|
||||
|
||||
static char *
|
||||
list_devices (size_t *len_p)
|
||||
{
|
||||
char *p0, *p;
|
||||
|
||||
*len_p = 0;
|
||||
p0 = malloc (DEVICE_LIST_SIZE);
|
||||
if (p0 == NULL)
|
||||
return NULL;
|
||||
|
||||
*len_p = DEVICE_LIST_SIZE;
|
||||
|
||||
p = p0;
|
||||
memcpy (p, USBIP_REPLY_DEVICE_LIST, 4);
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_ZERO, 4);
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_ONE, 4);
|
||||
p += 4;
|
||||
memset (p, 0, 256);
|
||||
strcpy (p, "/sys/devices/pci0000:00/0000:00:01.1/usb1/1-1");
|
||||
p += 256;
|
||||
memset (p, 0, 32);
|
||||
strcpy (p, "1-1");
|
||||
p += 32;
|
||||
memcpy (p, NETWORK_UINT32_ONE, 4); /* Bus */
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_TWO, 4); /* Dev */
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_ONE, 4); /* Speed */
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT16_FSIJ, 2);
|
||||
p += 2;
|
||||
memcpy (p, NETWORK_UINT16_ZERO, 2); /* Gnuk */
|
||||
p += 2;
|
||||
memcpy (p, NETWORK_UINT16_ONE_ONE, 2); /* USB 1.1 */
|
||||
p += 2;
|
||||
|
||||
*p++ = 0; /* bDeviceClass */
|
||||
*p++ = 0; /* bDeviceSubClass */
|
||||
*p++ = 0; /* bDeviceProtocol */
|
||||
*p++ = 0; /* bConfigurationValue */
|
||||
*p++ = 1; /* bConfigurationValue */
|
||||
*p++ = 1; /* bNumInterfaces */
|
||||
|
||||
*p++ = 11; /* bInterfaceClass */
|
||||
*p++ = 0; /* bInterfaceSubClass */
|
||||
*p++ = 0; /* bInterfaceProtocol */
|
||||
*p++ = 0; /* ----pad----------- */
|
||||
|
||||
return p0;
|
||||
}
|
||||
|
||||
static char *
|
||||
attach_device (char busid[32], size_t *len_p)
|
||||
{
|
||||
*len_p = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_urb (int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
run_server (void)
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_in v4addr;
|
||||
const int one = 1;
|
||||
|
||||
if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
perror ("socket");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char*)&one, sizeof (int)) < 0)
|
||||
perror ("WARN: setsockopt");
|
||||
|
||||
memset (&v4addr, 0, sizeof (v4addr));
|
||||
v4addr.sin_family = AF_INET;
|
||||
v4addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
v4addr.sin_port = htons (USBIP_PORT);
|
||||
|
||||
if (bind (sock, (const struct sockaddr *)&v4addr, sizeof (v4addr)) < 0)
|
||||
{
|
||||
perror ("bind");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* We only accept a connection from a single client. */
|
||||
if (listen (sock, 1) < 0)
|
||||
{
|
||||
perror ("listen");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int fd;
|
||||
int attached = 0;
|
||||
|
||||
/* We don't care who is connecting. */
|
||||
if ((fd = accept (sock, NULL, NULL)) < 0)
|
||||
{
|
||||
perror ("accept");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct usbip_msg_head msg;
|
||||
|
||||
if (recv (fd, (char *)&msg, sizeof (msg), 0) != sizeof (msg))
|
||||
{
|
||||
perror ("msg recv");
|
||||
break;
|
||||
}
|
||||
|
||||
msg.cmd = ntohl (msg.cmd);
|
||||
msg.seq = ntohl (msg.seq);
|
||||
|
||||
if (msg.cmd == CMD_REQ_LIST)
|
||||
{
|
||||
char *device_list;
|
||||
size_t device_list_size;
|
||||
|
||||
if (attached)
|
||||
{
|
||||
fprintf (stderr, "REQ list while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
device_list = list_devices (&device_list_size);
|
||||
|
||||
if (send (fd, device_list, device_list_size, 0) != device_list_size)
|
||||
{
|
||||
perror ("list send");
|
||||
break;
|
||||
}
|
||||
|
||||
free (device_list);
|
||||
}
|
||||
else if (msg.cmd == CMD_REQ_ATTACH)
|
||||
{
|
||||
char busid[32];
|
||||
char *attach;
|
||||
size_t attach_size;
|
||||
|
||||
if (attached)
|
||||
{
|
||||
fprintf (stderr, "REQ attach while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (recv (fd, busid, 32, 0) != 32)
|
||||
{
|
||||
perror ("attach recv");
|
||||
break;
|
||||
}
|
||||
|
||||
attach = attach_device (busid, &attach_size);
|
||||
if (send (fd, attach, attach_size, 0) != attach_size)
|
||||
{
|
||||
perror ("list send");
|
||||
break;
|
||||
}
|
||||
|
||||
free (attach);
|
||||
attached = 1;
|
||||
}
|
||||
else if (msg.cmd == CMD_URB)
|
||||
{
|
||||
if (!attached)
|
||||
{
|
||||
fprintf (stderr, "URB while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (handle_urb (fd) < 0)
|
||||
{
|
||||
fprintf (stderr, "URB handling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(msg.cmd == CMD_DETACH)
|
||||
{
|
||||
if (!attached)
|
||||
{
|
||||
fprintf (stderr, "DETACH while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* send reply??? */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Unknown command %08x, disconnecting.\n", msg.cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
run_server ();
|
||||
return 0;
|
||||
}
|
||||
@@ -495,6 +495,67 @@
|
||||
#endif /* TriCore */
|
||||
|
||||
#if defined(__arm__)
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
/* The ARM DSP instructions are available on Cortex M4, M7 and
|
||||
Cortex A CPUs */
|
||||
|
||||
#define MULADDC_1024_CORE \
|
||||
"ldmia %[s]!, { r7, r8, r9, r10 } \n\t" \
|
||||
"ldmia %[d], { r3, r4, r5, r6 } \n\t" \
|
||||
"umaal r3, %2, %[b], r7 \n\t" \
|
||||
"umaal r4, %2, %[b], r8 \n\t" \
|
||||
"umaal r5, %2, %[b], r9 \n\t" \
|
||||
"umaal r6, %2, %[b], r10 \n\t" \
|
||||
"stmia %[d]!, {r3, r4, r5, r6} \n\t"
|
||||
|
||||
#define MULADDC_1024_LOOP \
|
||||
asm( "tst %[i], #0xfe0 \n\t" \
|
||||
"beq 0f \n" \
|
||||
"1: sub %[i], %[i], #32 \n\t" \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
"tst %[i], #0xfe0 \n\t" \
|
||||
"bne 1b \n" \
|
||||
"0:" \
|
||||
: [s] "=r" (s), [d] "=r" (d), [c] "=r" (c), [i] "=r" (i) \
|
||||
: [b] "r" (b), "[s]" (s), "[d]" (d), "[c]" (c), "[i]" (i) \
|
||||
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "memory", "cc" );
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm(
|
||||
|
||||
#define MULADDC_CORE \
|
||||
"ldr r0, [%0], #4 \n\t" \
|
||||
"ldr r1, [%1] \n\t" \
|
||||
"umaal r1, %2, %3, r0 \n\t" \
|
||||
"str r1, [%1], #4 \n\t"
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
"ldmia %0!, {r0, r1, r2, r3} \n\t" \
|
||||
"ldmia %1, {r4, r5, r6, r7} \n\t" \
|
||||
"umaal r4, %2, %3, r0 \n\t" \
|
||||
"umaal r5, %2, %3, r1 \n\t" \
|
||||
"umaal r6, %2, %3, r2 \n\t" \
|
||||
"umaal r7, %2, %3, r3 \n\t" \
|
||||
"stmia %1!, {r4, r5, r6, r7} \n\t" \
|
||||
"ldmia %0!, {r0, r1, r2, r3} \n\t" \
|
||||
"ldmia %1, {r4, r5, r6, r7} \n\t" \
|
||||
"umaal r4, %2, %3, r0 \n\t" \
|
||||
"umaal r5, %2, %3, r1 \n\t" \
|
||||
"umaal r6, %2, %3, r2 \n\t" \
|
||||
"umaal r7, %2, %3, r3 \n\t" \
|
||||
"stmia %1!, {r4, r5, r6, r7} \n\t"
|
||||
|
||||
#define MULADDC_STOP \
|
||||
: "=r" (s), "=r" (d), "=r" (c) \
|
||||
: "r" (b), "0" (s), "1" (d), "2" (c) \
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5", \
|
||||
"r6", "r7", "memory");
|
||||
|
||||
#else /* __ARM_FEATURE_DSP */
|
||||
|
||||
#define MULADDC_1024_CORE \
|
||||
"ldmia %[s]!, { r8, r9, r10 } \n\t" \
|
||||
"ldmia %[d], { r5, r6, r7 } \n\t" \
|
||||
@@ -556,7 +617,7 @@
|
||||
: "r4", "r5", "r6", "r7", "r8", "r9", "r10", "memory", "cc" );
|
||||
|
||||
/* Just for reference (dead code) */
|
||||
#define MULADDC_HUIT \
|
||||
#define MULADDC_HUIT_DEAD \
|
||||
"ldmia %0!, { r4, r5 } \n\t" \
|
||||
"ldmia %1, { r8, r9 } \n\t" \
|
||||
"umull r6, r7, %3, r4 \n\t" \
|
||||
@@ -620,6 +681,7 @@
|
||||
: "r" (b), "0" (s), "1" (d), "2" (c) \
|
||||
: "r4", "r5", "r6", "r7", "memory", "cc" );
|
||||
|
||||
#endif /* __ARM_FEATURE_DSP */
|
||||
#endif /* ARMv3 */
|
||||
|
||||
#if defined(__alpha__)
|
||||
@@ -811,8 +873,8 @@
|
||||
#else
|
||||
#define MULADDC_INIT \
|
||||
{ \
|
||||
t_int s0, s1, b0, b1; \
|
||||
t_int r0, r1, rx, ry; \
|
||||
t_uint s0, s1, b0, b1; \
|
||||
t_uint r0, r1, rx, ry; \
|
||||
b0 = ( b << biH ) >> biH; \
|
||||
b1 = ( b >> biH );
|
||||
|
||||
|
||||
@@ -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,17 @@ 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 )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_ASM) && defined(__arm__)
|
||||
size_t i;
|
||||
register t_uint c = 0;
|
||||
|
||||
@@ -1526,6 +1536,52 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
|
||||
x_i = *xj;
|
||||
*xj++ = c;
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
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; */
|
||||
"mov r4, %[c]\n\t"
|
||||
"umlal r5, r4, %[x_i], %[x_i]\n\t"
|
||||
"str r5, [%[wij]], #4\n\t"
|
||||
"cmp %[xj], %[x_max1]\n\t"
|
||||
"bhi 0f\n\t"
|
||||
"mov r9, %[c]\n\t" /* R9 := 0, the constant ZERO from here. */
|
||||
"beq 1f\n"
|
||||
"2:\n\t"
|
||||
"ldmia %[xj]!, { r7, r8 }\n\t"
|
||||
"ldmia %[wij], { r5, r6 }\n\t"
|
||||
/* (C,R4,R5) := (C,R4) + w_i_j + 2*x_i*x_j; */
|
||||
"umaal r5, r4, %[x_i], r7\n\t"
|
||||
"umlal r5, %[c], %[x_i], r7\n\t"
|
||||
"umaal r4, %[c], r9, r9\n\t"
|
||||
/* (C,R4,R6) := (C,R4) + w_i_j + 2*x_i*x_j; */
|
||||
"umaal r6, r4, %[x_i], r8\n\t"
|
||||
"umlal r6, %[c], %[x_i], r8\n\t"
|
||||
"umaal r4, %[c], r9, r9\n\t"
|
||||
/**/
|
||||
"stmia %[wij]!, { r5, r6 }\n\t"
|
||||
"cmp %[xj], %[x_max1]\n\t"
|
||||
"bcc 2b\n\t"
|
||||
"bne 0f\n"
|
||||
"1:\n\t"
|
||||
/* (C,R4,R5) := (C,R4) + w_i_j + 2*x_i*x_j; */
|
||||
"ldr r5, [%[wij]]\n\t"
|
||||
"ldr r6, [%[xj]], #4\n\t"
|
||||
"umaal r5, r4, %[x_i], r6\n\t"
|
||||
"umlal r5, %[c], %[x_i], r6\n\t"
|
||||
"umaal r4, %[c], r9, r9\n\t"
|
||||
"str r5, [%[wij]], #4\n"
|
||||
"0:\n\t"
|
||||
"ldr r5, [%[wij]]\n\t"
|
||||
"adds r4, r4, r5\n\t"
|
||||
"adc %[c], %[c], #0\n\t"
|
||||
"str r4, [%[wij]]"
|
||||
: [c] "=&r" (c), [wij] "=r" (wij), [xj] "=r" (xj)
|
||||
: [x_i] "r" (x_i), [x_max1] "r" (&d[n*2-1]),
|
||||
"[wij]" (wij), "[xj]" (xj)
|
||||
: "r4", "r5", "r6", "r7", "r8", "r9", "memory", "cc");
|
||||
#else
|
||||
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; */
|
||||
@@ -1587,6 +1643,7 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
: [x_i] "r" (x_i), [x_max1] "r" (&d[n*2-1]),
|
||||
"[wij]" (wij), "[xj]" (xj)
|
||||
: "r4", "r5", "r6", "r7", "r8", "r9", "r12", "memory", "cc");
|
||||
#endif
|
||||
|
||||
c += mpi_mul_hlp( n, np, &d[i], d[i] * mm );
|
||||
}
|
||||
@@ -1598,16 +1655,29 @@ 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);
|
||||
#else
|
||||
t_uint a_input[n];
|
||||
|
||||
memcpy (a_input, &d[n], sizeof (a_input));
|
||||
mpi_montmul (n, np, mm, d, a_input);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
|
||||
*/
|
||||
#if MEMORY_SIZE >= 32
|
||||
#define MAX_WSIZE 6
|
||||
#elif MEMORY_SIZE >= 24
|
||||
#define MAX_WSIZE 5
|
||||
#else
|
||||
#define MAX_WSIZE 4
|
||||
#endif
|
||||
int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
||||
{
|
||||
int ret;
|
||||
size_t i = mpi_msb( E );
|
||||
size_t wsize = ( i > 1024 ) ? 4 : /* Because of not enough memory. */
|
||||
size_t wsize = ( i > 1024 ) ? MAX_WSIZE :
|
||||
( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
|
||||
( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
|
||||
size_t wbits, one = 1;
|
||||
@@ -1632,7 +1702,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 +1727,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 +2122,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 +2275,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 +2301,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 +2309,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 +2370,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>
|
||||
*
|
||||
@@ -147,19 +147,33 @@ static uint32_t fetch (int i)
|
||||
}
|
||||
|
||||
struct CRC {
|
||||
__IO uint32_t DR;
|
||||
__IO uint8_t IDR;
|
||||
volatile uint32_t DR;
|
||||
volatile uint8_t IDR;
|
||||
uint8_t RESERVED0;
|
||||
uint16_t RESERVED1;
|
||||
__IO uint32_t CR;
|
||||
volatile uint32_t CR;
|
||||
};
|
||||
static struct CRC *const CRC = (struct CRC *)0x40023000;
|
||||
|
||||
struct RCC {
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t CIR;
|
||||
volatile uint32_t APB2RSTR;
|
||||
volatile uint32_t APB1RSTR;
|
||||
volatile uint32_t AHBENR;
|
||||
/* ... */
|
||||
};
|
||||
static struct RCC *const RCC = (struct RCC *)0x40021000;
|
||||
#define RCC_AHBENR_CRCEN 0x00000040
|
||||
|
||||
|
||||
#define CRC_CR_RESET 0x01
|
||||
static uint32_t calc_crc32 (void)
|
||||
{
|
||||
struct CRC *CRC = (struct CRC *)0x40023000;
|
||||
int i;
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
|
||||
for (i = 0; i < 256/4; i++)
|
||||
@@ -365,7 +379,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,10 +3,9 @@ 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
|
||||
|
||||
#define NULL 0
|
||||
|
||||
#define __IO volatile
|
||||
|
||||
@@ -5,10 +5,7 @@ PROJECT = gnuk
|
||||
|
||||
CHOPSTX = ../chopstx
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= gnuk.ld
|
||||
|
||||
CSRC = main.c call-rsa.c mcu-stm32f103.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 \
|
||||
@@ -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
|
||||
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
|
||||
17
src/ac.c
17
src/ac.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ac.c -- Check access condition
|
||||
*
|
||||
* Copyright (C) 2010, 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2010, 2012, 2013, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -73,12 +73,14 @@ verify_user_0 (uint8_t access, const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
|
||||
if (ks_pw1 == NULL)
|
||||
{
|
||||
pw_len = strlen (OPENPGP_CARD_INITIAL_PW1);
|
||||
const uint8_t *initial_pw;
|
||||
|
||||
salt = NULL;
|
||||
salt_len = 0;
|
||||
gpg_do_get_initial_pw_setting (0, &pw_len, &initial_pw);
|
||||
if ((pw_len_known >= 0 && pw_len_known != pw_len)
|
||||
|| buf_len < pw_len
|
||||
|| strncmp ((const char *)pw, OPENPGP_CARD_INITIAL_PW1, pw_len))
|
||||
|| memcmp (pw, initial_pw, pw_len))
|
||||
goto failure;
|
||||
}
|
||||
else
|
||||
@@ -220,6 +222,7 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *initial_pw;
|
||||
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
||||
|
||||
if (ks_pw1 != NULL)
|
||||
@@ -237,13 +240,13 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* For the case of empty PW3 (with empty PW1), pass phrase
|
||||
* should be OPENPGP_CARD_INITIAL_PW3
|
||||
* For the case of empty PW3 (with empty PW1), passphrase is
|
||||
* OPENPGP_CARD_INITIAL_PW3, or defined by KDF DO.
|
||||
*/
|
||||
pw_len = strlen (OPENPGP_CARD_INITIAL_PW3);
|
||||
gpg_do_get_initial_pw_setting (1, &pw_len, &initial_pw);
|
||||
if ((pw_len_known >=0 && pw_len_known != pw_len)
|
||||
|| buf_len < pw_len
|
||||
|| strncmp ((const char *)pw, OPENPGP_CARD_INITIAL_PW3, pw_len))
|
||||
|| memcmp (pw, initial_pw, pw_len))
|
||||
goto failure;
|
||||
|
||||
admin_authorized = BY_ADMIN;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
197
src/configure
vendored
197
src/configure
vendored
@@ -10,6 +10,7 @@ nl=$'\n'
|
||||
# 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
|
||||
@@ -123,11 +141,14 @@ Configuration:
|
||||
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]
|
||||
@@ -137,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
|
||||
@@ -162,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;
|
||||
@@ -178,13 +196,47 @@ 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"
|
||||
def_memory_size="-DMEMORY_SIZE=1024"
|
||||
enable_hexoutput=""
|
||||
libs="-lpthread"
|
||||
else
|
||||
ldscript="gnuk.ld"
|
||||
chip="stm32f103"
|
||||
emulation=""
|
||||
cross="arm-none-eabi-"
|
||||
mcu="cortex-m3"
|
||||
def_emulation=""
|
||||
def_memory_size="-DMEMORY_SIZE=$MEMORY_SIZE"
|
||||
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"
|
||||
@@ -205,21 +257,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"
|
||||
@@ -230,12 +277,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
|
||||
@@ -266,13 +307,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
|
||||
@@ -282,53 +323,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 '};'
|
||||
@@ -337,7 +383,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
|
||||
@@ -345,7 +391,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
|
||||
@@ -362,28 +408,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 $def_memory_size";
|
||||
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
|
||||
|
||||
137
src/flash.c
137
src/flash.c
@@ -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)
|
||||
{
|
||||
@@ -103,18 +110,20 @@ static int key_available_at (const uint8_t *k, int key_size)
|
||||
|
||||
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
|
||||
void
|
||||
flash_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
|
||||
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;
|
||||
@@ -129,13 +138,13 @@ flash_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
|
||||
|
||||
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;
|
||||
|
||||
*p_do_start = data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
*p_do_end = data_pool + flash_page_size;
|
||||
@@ -149,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;
|
||||
@@ -228,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;
|
||||
@@ -246,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;
|
||||
}
|
||||
|
||||
@@ -277,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");
|
||||
@@ -333,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;
|
||||
@@ -368,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 *
|
||||
@@ -402,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);
|
||||
@@ -428,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))
|
||||
@@ -447,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);
|
||||
@@ -457,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);
|
||||
}
|
||||
@@ -465,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);
|
||||
}
|
||||
@@ -479,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
|
||||
@@ -493,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -505,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 *
|
||||
@@ -528,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;
|
||||
}
|
||||
|
||||
@@ -544,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 *
|
||||
@@ -560,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;
|
||||
}
|
||||
|
||||
@@ -596,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
|
||||
@@ -621,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
|
||||
@@ -636,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,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;
|
||||
}
|
||||
|
||||
@@ -664,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;
|
||||
@@ -689,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)
|
||||
{
|
||||
@@ -715,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 *);
|
||||
34
src/gnuk.h
34
src/gnuk.h
@@ -22,15 +22,12 @@ extern struct apdu apdu;
|
||||
#define CARD_CHANGE_REMOVE 1
|
||||
#define CARD_CHANGE_TOGGLE 2
|
||||
void ccid_card_change_signal (int how);
|
||||
void ccid_usb_reset (int);
|
||||
|
||||
/* CCID thread */
|
||||
#define EV_RX_DATA_READY 1 /* USB Rx data available */
|
||||
#define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */
|
||||
#define EV_TX_FINISHED 4 /* CCID Tx finished */
|
||||
#define EV_CARD_CHANGE 8
|
||||
#define EV_USB_SET_INTERFACE 16
|
||||
#define EV_USB_DEVICE_RESET 32
|
||||
#define EV_CARD_CHANGE 8
|
||||
|
||||
/* OpenPGPcard thread */
|
||||
#define EV_PINPAD_INPUT_DONE 1
|
||||
@@ -112,7 +109,7 @@ 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 +136,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);
|
||||
|
||||
void flash_init (const uint8_t **, const uint8_t **);
|
||||
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 +149,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 +262,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,19 +285,23 @@ 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);
|
||||
|
||||
const uint8_t *gpg_do_read_simple (uint8_t);
|
||||
void gpg_do_write_simple (uint8_t, const uint8_t *, int);
|
||||
void gpg_increment_digital_signature_counter (void);
|
||||
void gpg_do_get_initial_pw_setting (int is_pw3, int *r_len,
|
||||
const uint8_t **r_p);
|
||||
int gpg_do_kdf_check (int len, int how_many);
|
||||
|
||||
|
||||
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;
|
||||
@@ -333,7 +334,8 @@ extern uint8_t admin_authorized;
|
||||
#define NR_DO_KEYSTRING_PW1 0x11
|
||||
#define NR_DO_KEYSTRING_RC 0x12
|
||||
#define NR_DO_KEYSTRING_PW3 0x13
|
||||
#define NR_DO__LAST__ 20 /* == 0x14 */
|
||||
#define NR_DO_KDF 0x14
|
||||
#define NR_DO__LAST__ 21 /* == 0x15 */
|
||||
/* 14-bit counter for DS: Recorded in flash memory by 1-halfword (2-byte). */
|
||||
/*
|
||||
* Representation of 14-bit counter:
|
||||
@@ -432,6 +434,7 @@ extern const uint8_t gnuk_string_serial[];
|
||||
#define LED_GNUK_EXEC 32
|
||||
#define LED_START_COMMAND 64
|
||||
#define LED_FINISH_COMMAND 128
|
||||
#define LED_OFF LED_FINISH_COMMAND
|
||||
void led_blink (int spec);
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
@@ -460,5 +463,4 @@ int pinpad_getline (int msg_code, uint32_t timeout_usec);
|
||||
|
||||
extern uint8_t _regnual_start, __heap_end__[];
|
||||
|
||||
int check_crc32 (const uint32_t *start_p, const uint32_t *end_p);
|
||||
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__ = 0x01a0; /* 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
|
||||
|
||||
@@ -172,11 +135,11 @@ SECTIONS
|
||||
{
|
||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||
_keystore_pool = .;
|
||||
. += 512;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += 512;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += 512;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_updatekey_store = .;
|
||||
. += 1024;
|
||||
|
||||
201
src/main.c
201
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,15 @@
|
||||
#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/cortex-m.h"
|
||||
#include "mcu/stm32.h"
|
||||
#include "mcu/stm32f103.h"
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main thread does 1-bit LED display output
|
||||
@@ -47,6 +54,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,10 +87,15 @@ device_initialize_once (void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static volatile uint8_t fatal_code;
|
||||
static struct eventflag led_event;
|
||||
static chopstx_poll_cond_t led_event_poll_desc;
|
||||
static struct chx_poll_head *const led_event_poll[] = {
|
||||
(struct chx_poll_head *)&led_event_poll_desc
|
||||
};
|
||||
|
||||
static void display_fatal_code (void)
|
||||
{
|
||||
@@ -120,17 +136,20 @@ static void display_fatal_code (void)
|
||||
|
||||
static uint8_t led_inverted;
|
||||
|
||||
static void emit_led (int on_time, int off_time)
|
||||
static void
|
||||
emit_led (uint32_t on_time, uint32_t off_time)
|
||||
{
|
||||
set_led (!led_inverted);
|
||||
chopstx_usec_wait (on_time);
|
||||
chopstx_poll (&on_time, 1, led_event_poll);
|
||||
set_led (led_inverted);
|
||||
chopstx_usec_wait (off_time);
|
||||
chopstx_poll (&off_time, 1, led_event_poll);
|
||||
}
|
||||
|
||||
static void display_status_code (void)
|
||||
static void
|
||||
display_status_code (void)
|
||||
{
|
||||
enum ccid_state ccid_state = *ccid_state_p;
|
||||
uint32_t usec;
|
||||
|
||||
if (ccid_state == CCID_STATE_START)
|
||||
emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
||||
@@ -145,10 +164,14 @@ static void display_status_code (void)
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
|
||||
if (ccid_state == CCID_STATE_WAIT)
|
||||
chopstx_usec_wait (LED_TIMEOUT_STOP * 2);
|
||||
{
|
||||
usec = LED_TIMEOUT_STOP * 2;
|
||||
chopstx_poll (&usec, 1, led_event_poll);
|
||||
}
|
||||
else
|
||||
{
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
usec = LED_TIMEOUT_INTERVAL;
|
||||
chopstx_poll (&usec, 1, led_event_poll);
|
||||
emit_led (ccid_state == CCID_STATE_RECEIVE?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
}
|
||||
@@ -167,26 +190,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 +229,96 @@ 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;
|
||||
chopstx_conf_idle (1);
|
||||
|
||||
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 ();
|
||||
|
||||
@@ -239,12 +344,14 @@ main (int argc, char *argv[])
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (bDeviceState != UNCONNECTED)
|
||||
if (bDeviceState != USB_DEVICE_STATE_UNCONNECTED)
|
||||
break;
|
||||
|
||||
chopstx_usec_wait (250*1000);
|
||||
}
|
||||
|
||||
eventflag_prepare_poll (&led_event, &led_event_poll_desc);
|
||||
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m;
|
||||
@@ -285,8 +392,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 +402,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 +426,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 +459,46 @@ fatal (uint8_t code)
|
||||
* reclaimed to system.
|
||||
*/
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define HEAP_SIZE (32*1024)
|
||||
uint8_t __heap_base__[HEAP_SIZE];
|
||||
|
||||
#define HEAP_START __heap_base__
|
||||
#define HEAP_END (__heap_base__ + HEAP_SIZE)
|
||||
#define HEAP_ALIGNMENT 32
|
||||
#else
|
||||
extern uint8_t __heap_base__[];
|
||||
extern uint8_t __heap_end__[];
|
||||
|
||||
#define MEMORY_END (__heap_end__)
|
||||
#define MEMORY_ALIGNMENT 16
|
||||
#define MEMORY_ALIGN(n) (((n) + MEMORY_ALIGNMENT - 1) & ~(MEMORY_ALIGNMENT - 1))
|
||||
#define HEAP_START __heap_base__
|
||||
#define HEAP_END (__heap_end__)
|
||||
#define HEAP_ALIGNMENT 16
|
||||
#define HEAP_SIZE ((uintptr_t)__heap_end__ - (uintptr_t)__heap_base__)
|
||||
#endif
|
||||
|
||||
#define HEAP_ALIGN(n) (((n) + HEAP_ALIGNMENT - 1) & ~(HEAP_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 != HEAP_ALIGN((x)->size) || (x)->size > HEAP_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;
|
||||
}
|
||||
|
||||
@@ -380,7 +507,7 @@ sbrk (size_t size)
|
||||
{
|
||||
void *p = (void *)heap_p;
|
||||
|
||||
if ((size_t)(MEMORY_END - heap_p) < size)
|
||||
if ((size_t)(HEAP_END - heap_p) < size)
|
||||
return NULL;
|
||||
|
||||
heap_p += size;
|
||||
@@ -405,7 +532,7 @@ gnuk_malloc (size_t size)
|
||||
struct mem_head *m;
|
||||
struct mem_head *m0;
|
||||
|
||||
size = MEMORY_ALIGN (size + sizeof (uint32_t));
|
||||
size = HEAP_ALIGN (size + sizeof (uintptr_t));
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
DEBUG_INFO ("malloc: ");
|
||||
@@ -421,7 +548,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 +572,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 +581,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 +613,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;
|
||||
|
||||
@@ -23,32 +23,9 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mcu/stm32.h"
|
||||
#include "mcu/stm32f103.h"
|
||||
|
||||
static uint32_t
|
||||
rbit (uint32_t v)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
check_crc32 (const uint32_t *start_p, const uint32_t *end_p)
|
||||
{
|
||||
uint32_t crc32 = *end_p;
|
||||
const uint32_t *p;
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
|
||||
for (p = start_p; p < end_p; p++)
|
||||
CRC->DR = rbit (*p);
|
||||
|
||||
return (rbit (CRC->DR) ^ crc32) == 0xffffffff;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
sram_address (uint32_t 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));
|
||||
|
||||
191
src/neug.c
191
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,129 @@
|
||||
|
||||
#include "sys.h"
|
||||
#include "neug.h"
|
||||
#ifndef GNU_LINUX_EMULATION
|
||||
#include "mcu/stm32.h"
|
||||
#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;
|
||||
}
|
||||
|
||||
void
|
||||
crc32_rv_stop (void)
|
||||
{
|
||||
RCC->AHBENR &= ~RCC_AHBENR_CRCEN;
|
||||
}
|
||||
#endif
|
||||
|
||||
static chopstx_mutex_t mode_mtx;
|
||||
static chopstx_cond_t mode_cond;
|
||||
|
||||
@@ -94,11 +213,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 +283,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 +300,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 +317,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 +345,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 +759,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 +776,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);
|
||||
@@ -781,6 +901,7 @@ neug_fini (void)
|
||||
rng_should_terminate = 1;
|
||||
neug_get (1);
|
||||
chopstx_join (rng_thread, NULL);
|
||||
crc32_rv_stop ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -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);
|
||||
|
||||
360
src/openpgp-do.c
360
src/openpgp-do.c
@@ -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];
|
||||
@@ -113,13 +112,15 @@ const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
/* Extended Capabilities */
|
||||
static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
|
||||
10,
|
||||
0x74, /*
|
||||
0x75, /*
|
||||
* No Secure Messaging supported
|
||||
* GET CHALLENGE supported
|
||||
* Key import supported
|
||||
* PW status byte can be put
|
||||
* No private_use_DO
|
||||
* Algorithm attrs are changable
|
||||
* No DEC with AES
|
||||
* KDF-DO available
|
||||
*/
|
||||
0, /* Secure Messaging Algorithm: N/A (TDES=0, AES=1) */
|
||||
0x00, CHALLENGE_LEN, /* Max size of GET CHALLENGE */
|
||||
@@ -250,6 +251,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)
|
||||
{
|
||||
@@ -431,12 +454,17 @@ static const struct do_table_entry *get_do_entry (uint16_t tag);
|
||||
#define GPG_DO_KGTIME_DEC 0x00cf
|
||||
#define GPG_DO_KGTIME_AUT 0x00d0
|
||||
#define GPG_DO_RESETTING_CODE 0x00d3
|
||||
#define GPG_DO_UIF_SIG 0x00d6
|
||||
#define GPG_DO_UIF_DEC 0x00d7
|
||||
#define GPG_DO_UIF_AUT 0x00d8
|
||||
#define GPG_DO_KDF 0x00f9
|
||||
#define GPG_DO_KEY_IMPORT 0x3fff
|
||||
#define GPG_DO_LANGUAGE 0x5f2d
|
||||
#define GPG_DO_SEX 0x5f35
|
||||
#define GPG_DO_URL 0x5f50
|
||||
#define GPG_DO_HIST_BYTES 0x5f52
|
||||
#define GPG_DO_CH_CERTIFICATE 0x7f21
|
||||
#define GPG_DO_FEATURE_MNGMNT 0x7f74
|
||||
|
||||
static const uint8_t *do_ptr[NR_DO__LAST__];
|
||||
|
||||
@@ -473,6 +501,8 @@ do_tag_to_nr (uint16_t tag)
|
||||
return NR_DO_NAME;
|
||||
case GPG_DO_LANGUAGE:
|
||||
return NR_DO_LANGUAGE;
|
||||
case GPG_DO_KDF:
|
||||
return NR_DO_KDF;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -749,47 +779,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;
|
||||
@@ -809,6 +807,103 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
||||
}
|
||||
}
|
||||
|
||||
#define SIZE_OF_KDF_DO 110
|
||||
#define OPENPGP_KDF_ITERSALTED_S2K 3
|
||||
#define OPENPGP_SHA256 8
|
||||
|
||||
static int
|
||||
rw_kdf (uint16_t tag, int with_tag, const uint8_t *data, int len, int is_write)
|
||||
{
|
||||
if (tag != GPG_DO_KDF)
|
||||
return 0; /* Failure */
|
||||
|
||||
if (is_write)
|
||||
{
|
||||
const uint8_t **do_data_p = (const uint8_t **)&do_ptr[NR_DO_KDF];
|
||||
|
||||
/* KDF DO can be changed only when no keys are registered. */
|
||||
if (do_ptr[NR_DO_PRVKEY_SIG] || do_ptr[NR_DO_PRVKEY_DEC]
|
||||
|| do_ptr[NR_DO_PRVKEY_AUT])
|
||||
return 0;
|
||||
|
||||
if (*do_data_p)
|
||||
flash_do_release (*do_data_p);
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
*do_data_p = NULL;
|
||||
return 1;
|
||||
}
|
||||
else if (len != SIZE_OF_KDF_DO ||
|
||||
!(data[0] == 0x81 && data[3] == 0x82 && data[6] == 0x83
|
||||
&& data[12] == 0x84 && data[22] == 0x85 && data[32] == 0x86
|
||||
&& data[42] == 0x87 && data[76] == 0x88))
|
||||
/* Format validation failed. The valid format is:
|
||||
81 01 03 = KDF_ITERSALTED_S2K
|
||||
82 01 08 = SHA256
|
||||
83 04 4-byte... = count
|
||||
84 08 8-byte... = salt user
|
||||
85 08 8-byte... = salt reset-code
|
||||
86 08 8-byte... = salt admin
|
||||
87 20 32-byte user hash
|
||||
88 20 32-byte admin hash
|
||||
*/
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
*do_data_p = flash_do_write (NR_DO_KDF, data, SIZE_OF_KDF_DO);
|
||||
if (*do_data_p)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_do_1 (tag, do_ptr[NR_DO_KDF], with_tag);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
gpg_do_kdf_check (int len, int how_many)
|
||||
{
|
||||
const uint8_t *kdf_spec = gpg_do_read_simple (NR_DO_KDF);
|
||||
|
||||
if (kdf_spec && (kdf_spec[43] * how_many) != len)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
gpg_do_get_initial_pw_setting (int is_pw3, int *r_len, const uint8_t **r_p)
|
||||
{
|
||||
const uint8_t *kdf_spec = gpg_do_read_simple (NR_DO_KDF);
|
||||
|
||||
if (kdf_spec)
|
||||
{
|
||||
*r_len = 32;
|
||||
if (is_pw3)
|
||||
*r_p = kdf_spec + 78;
|
||||
else
|
||||
*r_p = kdf_spec + 44;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_pw3)
|
||||
{
|
||||
*r_len = strlen (OPENPGP_CARD_INITIAL_PW3);
|
||||
*r_p = (const uint8_t *)OPENPGP_CARD_INITIAL_PW3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r_len = strlen (OPENPGP_CARD_INITIAL_PW1);
|
||||
*r_p = (const uint8_t *)OPENPGP_CARD_INITIAL_PW1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
proc_resetting_code (const uint8_t *data, int len)
|
||||
{
|
||||
@@ -822,6 +917,9 @@ proc_resetting_code (const uint8_t *data, int len)
|
||||
|
||||
DEBUG_INFO ("Resetting Code!\r\n");
|
||||
|
||||
if (gpg_do_kdf_check (len, 1) == 0)
|
||||
return 0;
|
||||
|
||||
newpw_len = len;
|
||||
newpw = data;
|
||||
new_ks0[0] = newpw_len;
|
||||
@@ -858,7 +956,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 +975,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,14 +1191,16 @@ 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;
|
||||
int pw_len;
|
||||
const uint8_t *initial_pw;
|
||||
|
||||
DEBUG_INFO ("Key import\r\n");
|
||||
DEBUG_SHORT (prvkey_len);
|
||||
@@ -1108,10 +1208,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 +1235,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++;
|
||||
@@ -1189,8 +1258,8 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
memcpy (pd->dek_encrypted_2, dek, DATA_ENCRYPTION_KEY_SIZE);
|
||||
memcpy (pd->dek_encrypted_3, dek, DATA_ENCRYPTION_KEY_SIZE);
|
||||
|
||||
s2k (NULL, 0, (const uint8_t *)OPENPGP_CARD_INITIAL_PW1,
|
||||
strlen (OPENPGP_CARD_INITIAL_PW1), ks);
|
||||
gpg_do_get_initial_pw_setting (0, &pw_len, &initial_pw);
|
||||
s2k (NULL, 0, initial_pw, pw_len, ks);
|
||||
|
||||
/* Handle existing keys and keystring DOs. */
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, NULL, 0);
|
||||
@@ -1206,19 +1275,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 +1301,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 +1332,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 +1371,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 +1438,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 +1478,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 +1518,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 +1531,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)
|
||||
@@ -1516,6 +1599,8 @@ gpg_do_table[] = {
|
||||
rw_algorithm_attr },
|
||||
{ GPG_DO_ALG_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
|
||||
rw_algorithm_attr },
|
||||
{ GPG_DO_KDF, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
|
||||
rw_kdf },
|
||||
/* Fixed data */
|
||||
{ GPG_DO_HIST_BYTES, DO_FIXED, AC_ALWAYS, AC_NEVER, historical_bytes },
|
||||
{ GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
|
||||
@@ -1581,7 +1666,7 @@ gpg_data_scan (const uint8_t *do_start, const uint8_t *do_end)
|
||||
|
||||
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)
|
||||
@@ -2086,44 +2171,37 @@ 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[3])
|
||||
#define d (&buf[3])
|
||||
#define d1 (&buf[3+64])
|
||||
#define pubkey (&buf[3+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;
|
||||
int i;
|
||||
|
||||
rnd = NULL;
|
||||
do
|
||||
@@ -2150,7 +2228,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)
|
||||
{
|
||||
@@ -2161,7 +2242,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)
|
||||
{
|
||||
@@ -2172,7 +2253,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
|
||||
{
|
||||
@@ -2180,12 +2261,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 ();
|
||||
@@ -2196,14 +2286,16 @@ gpg_do_keygen (uint8_t kk_byte)
|
||||
|
||||
if (kk == GPG_KEY_FOR_SIGNING)
|
||||
{
|
||||
const uint8_t *pw = (const uint8_t *)OPENPGP_CARD_INITIAL_PW1;
|
||||
int pw_len;
|
||||
const uint8_t *initial_pw;
|
||||
uint8_t keystring[KEYSTRING_MD_SIZE];
|
||||
|
||||
/* GnuPG expects it's ready for signing. */
|
||||
/* Don't call ac_reset_pso_cds here, but load the private key */
|
||||
|
||||
gpg_reset_digital_signature_counter ();
|
||||
s2k (NULL, 0, pw, strlen (OPENPGP_CARD_INITIAL_PW1), keystring);
|
||||
gpg_do_get_initial_pw_setting (0, &pw_len, &initial_pw);
|
||||
s2k (NULL, 0, initial_pw, pw_len, keystring);
|
||||
gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER, keystring);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -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;
|
||||
@@ -109,7 +108,7 @@ gpg_init (void)
|
||||
const uint8_t *flash_do_start;
|
||||
const uint8_t *flash_do_end;
|
||||
|
||||
flash_init (&flash_do_start, &flash_do_end);
|
||||
flash_do_storage_init (&flash_do_start, &flash_do_end);
|
||||
|
||||
if (flash_do_start == NULL)
|
||||
file_selection = FILE_CARD_TERMINATED;
|
||||
@@ -117,7 +116,7 @@ gpg_init (void)
|
||||
file_selection = FILE_NONE;
|
||||
|
||||
gpg_data_scan (flash_do_start, flash_do_end);
|
||||
flash_init_keys ();
|
||||
flash_key_storage_init ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -193,6 +192,12 @@ cmd_verify (void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_do_kdf_check (len, 1) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is real authentication. */
|
||||
if (p2 == 0x81)
|
||||
r = verify_pso_cds (pw, len);
|
||||
@@ -300,6 +305,12 @@ cmd_change_password (void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_do_kdf_check (len, 2) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (who == BY_USER) /* PW1 */
|
||||
{
|
||||
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
||||
@@ -379,8 +390,10 @@ cmd_change_password (void)
|
||||
newpw_len = len - pw_len;
|
||||
if (newpw_len == 0 && admin_authorized == BY_ADMIN)
|
||||
{
|
||||
newpw_len = strlen (OPENPGP_CARD_INITIAL_PW3);
|
||||
memcpy (newpw, OPENPGP_CARD_INITIAL_PW3, newpw_len);
|
||||
const uint8_t *initial_pw;
|
||||
|
||||
gpg_do_get_initial_pw_setting (1, &newpw_len, &initial_pw);
|
||||
memcpy (newpw, initial_pw, newpw_len);
|
||||
newsalt_len = 0;
|
||||
pw3_null = 1;
|
||||
}
|
||||
@@ -518,6 +531,12 @@ cmd_reset_user_password (void)
|
||||
const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
|
||||
uint8_t old_ks[KEYSTRING_MD_SIZE];
|
||||
|
||||
if (gpg_do_kdf_check (len, 2) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_pw_locked (PW_ERR_RC))
|
||||
{
|
||||
DEBUG_INFO ("blocked.\r\n");
|
||||
@@ -582,6 +601,12 @@ cmd_reset_user_password (void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_do_kdf_check (len, 1) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
newpw_len = len;
|
||||
newpw = pw;
|
||||
random_get_salt (new_salt);
|
||||
@@ -645,10 +670,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)
|
||||
{
|
||||
@@ -658,6 +684,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
|
||||
@@ -670,7 +697,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");
|
||||
@@ -680,13 +706,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;
|
||||
@@ -706,22 +725,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;
|
||||
@@ -738,6 +761,11 @@ cmd_read_binary (void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
GPG_NO_FILE ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -760,8 +788,7 @@ cmd_select_file (void)
|
||||
|
||||
if (file_selection == FILE_CARD_TERMINATED)
|
||||
{
|
||||
file_selection = FILE_CARD_TERMINATED_OPENPGP;
|
||||
GPG_APPLICATION_TERMINATED();
|
||||
GPG_APPLICATION_TERMINATED ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1202,6 +1229,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)
|
||||
{
|
||||
@@ -1218,9 +1246,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 ();
|
||||
}
|
||||
@@ -1250,6 +1279,7 @@ cmd_write_binary (void)
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
static void
|
||||
cmd_external_authenticate (void)
|
||||
{
|
||||
@@ -1291,6 +1321,7 @@ cmd_external_authenticate (void)
|
||||
set_res_sw (0xff, 0xff);
|
||||
DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cmd_get_challenge (void)
|
||||
@@ -1323,9 +1354,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;
|
||||
}
|
||||
|
||||
@@ -1337,12 +1368,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;
|
||||
}
|
||||
|
||||
@@ -1358,8 +1391,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();
|
||||
@@ -1392,8 +1428,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 },
|
||||
@@ -1426,13 +1464,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);
|
||||
|
||||
@@ -40,14 +40,14 @@ cir_ext_disable (void)
|
||||
int rcvd = (EXTI->PR & EXTI_PR) != 0;
|
||||
|
||||
EXTI->IMR &= ~EXTI_IMR;
|
||||
EXTI->PR = EXTI_PR;
|
||||
EXTI->PR |= EXTI_PR;
|
||||
return rcvd;
|
||||
}
|
||||
|
||||
static void
|
||||
cir_ext_enable (void)
|
||||
{
|
||||
EXTI->PR = EXTI_PR;
|
||||
EXTI->PR |= EXTI_PR;
|
||||
EXTI->IMR |= EXTI_IMR;
|
||||
}
|
||||
|
||||
@@ -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 *
|
||||
@@ -1030,8 +1033,8 @@ cir_init (void)
|
||||
|
||||
/* EXTIx <= Py */
|
||||
AFIO->EXTICR[AFIO_EXTICR_INDEX] = AFIO_EXTICR1_EXTIx_Py;
|
||||
EXTI->IMR = 0;
|
||||
EXTI->FTSR = EXTI_FTSR_TR;
|
||||
EXTI->IMR &= ~EXTI_IMR;
|
||||
EXTI->FTSR |= EXTI_FTSR_TR;
|
||||
|
||||
/* TIM */
|
||||
#ifdef ENABLE_RCC_APB1
|
||||
|
||||
@@ -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)
|
||||
|
||||
65
src/stack-def.h
Normal file
65
src/stack-def.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define SIZE_1 4096
|
||||
#define SIZE_2 4096
|
||||
#define SIZE_3 (5 * 4096)
|
||||
#else
|
||||
#define SIZE_0 0x0150 /* Main */
|
||||
#define SIZE_1 0x01a0 /* CCID */
|
||||
#define SIZE_2 0x0180 /* RNG */
|
||||
#if MEMORY_SIZE >= 32
|
||||
#define SIZE_3 0x4640 /* openpgp-card */
|
||||
#elif MEMORY_SIZE >= 24
|
||||
#define SIZE_3 0x2640 /* openpgp-card */
|
||||
#else
|
||||
#define SIZE_3 0x1640 /* openpgp-card */
|
||||
#endif
|
||||
#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 *);
|
||||
433
src/usb-ccid.c
433
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
|
||||
@@ -1350,15 +1513,10 @@ ccid_card_change_signal (int how)
|
||||
eventflag_signal (&c->ccid_comm, EV_CARD_CHANGE);
|
||||
}
|
||||
|
||||
void
|
||||
ccid_usb_reset (int full)
|
||||
{
|
||||
struct ccid *c = &ccid;
|
||||
|
||||
eventflag_signal (&c->ccid_comm,
|
||||
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 +1532,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,8 +1547,6 @@ ccid_notify_slot_change (struct ccid *c)
|
||||
#define GPG_THREAD_TERMINATED 0xffff
|
||||
|
||||
|
||||
#define INTR_REQ_USB 20
|
||||
|
||||
extern uint32_t bDeviceState;
|
||||
extern void usb_device_reset (struct usb_dev *dev);
|
||||
extern int usb_setup (struct usb_dev *dev);
|
||||
@@ -1397,7 +1558,16 @@ extern int usb_get_status_interface (struct usb_dev *dev);
|
||||
|
||||
extern int usb_get_descriptor (struct usb_dev *dev);
|
||||
|
||||
static void
|
||||
extern void random_init (void);
|
||||
extern void random_fini (void);
|
||||
|
||||
|
||||
/*
|
||||
* Return 0 for normal USB event
|
||||
* -1 for USB reset
|
||||
* 1 for SET_INTERFACE or SET_CONFIGURATION
|
||||
*/
|
||||
static int
|
||||
usb_event_handle (struct usb_dev *dev)
|
||||
{
|
||||
uint8_t ep_num;
|
||||
@@ -1406,94 +1576,119 @@ usb_event_handle (struct usb_dev *dev)
|
||||
e = usb_lld_event_handler (dev);
|
||||
ep_num = USB_EVENT_ENDP (e);
|
||||
|
||||
/* Transfer to endpoint (not control endpoint) */
|
||||
if (ep_num != 0)
|
||||
{
|
||||
if (USB_EVENT_TXRX (e))
|
||||
usb_tx_done (ep_num, USB_EVENT_LEN (e));
|
||||
else
|
||||
usb_rx_ready (ep_num, USB_EVENT_LEN (e));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
switch (USB_EVENT_ID (e))
|
||||
{
|
||||
case USB_EVENT_DEVICE_RESET:
|
||||
usb_device_reset (dev);
|
||||
break;
|
||||
|
||||
case USB_EVENT_DEVICE_ADDRESSED:
|
||||
bDeviceState = ADDRESSED;
|
||||
break;
|
||||
/* Control endpoint */
|
||||
switch (USB_EVENT_ID (e))
|
||||
{
|
||||
case USB_EVENT_DEVICE_RESET:
|
||||
usb_device_reset (dev);
|
||||
return -1;
|
||||
|
||||
case USB_EVENT_GET_DESCRIPTOR:
|
||||
if (usb_get_descriptor (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
case USB_EVENT_DEVICE_ADDRESSED:
|
||||
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
|
||||
break;
|
||||
|
||||
case USB_EVENT_SET_CONFIGURATION:
|
||||
if (usb_set_configuration (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
case USB_EVENT_GET_DESCRIPTOR:
|
||||
if (usb_get_descriptor (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
|
||||
case USB_EVENT_SET_INTERFACE:
|
||||
if (usb_set_interface (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
case USB_EVENT_SET_CONFIGURATION:
|
||||
if (usb_set_configuration (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
else
|
||||
{
|
||||
if (bDeviceState == USB_DEVICE_STATE_ADDRESSED)
|
||||
/* de-Configured */
|
||||
return -1;
|
||||
else
|
||||
/* Configured */
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_EVENT_CTRL_REQUEST:
|
||||
/* Device specific device request. */
|
||||
if (usb_setup (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
case USB_EVENT_SET_INTERFACE:
|
||||
if (usb_set_interface (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
else
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case USB_EVENT_GET_STATUS_INTERFACE:
|
||||
if (usb_get_status_interface (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
case USB_EVENT_CTRL_REQUEST:
|
||||
/* Device specific device request. */
|
||||
if (usb_setup (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
|
||||
case USB_EVENT_GET_INTERFACE:
|
||||
if (usb_get_interface (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
case USB_EVENT_GET_STATUS_INTERFACE:
|
||||
if (usb_get_status_interface (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
|
||||
case USB_EVENT_SET_FEATURE_DEVICE:
|
||||
case USB_EVENT_SET_FEATURE_ENDPOINT:
|
||||
case USB_EVENT_CLEAR_FEATURE_DEVICE:
|
||||
case USB_EVENT_CLEAR_FEATURE_ENDPOINT:
|
||||
usb_lld_ctrl_ack (dev);
|
||||
break;
|
||||
case USB_EVENT_GET_INTERFACE:
|
||||
if (usb_get_interface (dev) < 0)
|
||||
usb_lld_ctrl_error (dev);
|
||||
break;
|
||||
|
||||
case USB_EVENT_CTRL_WRITE_FINISH:
|
||||
/* Control WRITE transfer finished. */
|
||||
usb_ctrl_write_finish (dev);
|
||||
break;
|
||||
case USB_EVENT_SET_FEATURE_DEVICE:
|
||||
case USB_EVENT_SET_FEATURE_ENDPOINT:
|
||||
case USB_EVENT_CLEAR_FEATURE_DEVICE:
|
||||
case USB_EVENT_CLEAR_FEATURE_ENDPOINT:
|
||||
usb_lld_ctrl_ack (dev);
|
||||
break;
|
||||
|
||||
case USB_EVENT_OK:
|
||||
case USB_EVENT_DEVICE_SUSPEND:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case USB_EVENT_CTRL_WRITE_FINISH:
|
||||
/* Control WRITE transfer finished. */
|
||||
usb_ctrl_write_finish (dev);
|
||||
break;
|
||||
|
||||
case USB_EVENT_DEVICE_SUSPEND:
|
||||
led_blink (LED_OFF);
|
||||
chopstx_usec_wait (10); /* Make sure LED off */
|
||||
random_fini ();
|
||||
chopstx_conf_idle (2);
|
||||
bDeviceState |= USB_DEVICE_STATE_SUSPEND;
|
||||
break;
|
||||
|
||||
case USB_EVENT_DEVICE_WAKEUP:
|
||||
chopstx_conf_idle (1);
|
||||
random_init ();
|
||||
bDeviceState &= ~USB_DEVICE_STATE_SUSPEND;
|
||||
break;
|
||||
|
||||
case USB_EVENT_OK:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
poll_event_intr (uint32_t *timeout, struct eventflag *ev, chopstx_intr_t *intr)
|
||||
{
|
||||
chopstx_poll_cond_t poll_desc;
|
||||
struct chx_poll_head *pd_array[2] = {
|
||||
(struct chx_poll_head *)intr,
|
||||
(struct chx_poll_head *)&poll_desc
|
||||
};
|
||||
|
||||
eventflag_prepare_poll (ev, &poll_desc);
|
||||
chopstx_poll (timeout, 2, pd_array);
|
||||
}
|
||||
static chopstx_intr_t interrupt;
|
||||
static chopstx_poll_cond_t ccid_event_poll_desc;
|
||||
static struct chx_poll_head *const ccid_poll[] = {
|
||||
(struct chx_poll_head *const)&interrupt,
|
||||
(struct chx_poll_head *const)&ccid_event_poll_desc
|
||||
};
|
||||
#define CCID_POLL_NUM (sizeof (ccid_poll)/sizeof (struct chx_poll_head *))
|
||||
|
||||
void *
|
||||
ccid_thread (void *arg)
|
||||
{
|
||||
chopstx_intr_t interrupt;
|
||||
uint32_t timeout;
|
||||
struct usb_dev dev;
|
||||
struct ccid *c = &ccid;
|
||||
uint32_t *timeout_p;
|
||||
|
||||
(void)arg;
|
||||
|
||||
@@ -1504,7 +1699,9 @@ ccid_thread (void *arg)
|
||||
chopstx_claim_irq (&interrupt, INTR_REQ_USB);
|
||||
usb_event_handle (&dev); /* For old SYS < 3.0 */
|
||||
|
||||
device_reset:
|
||||
eventflag_prepare_poll (&c->ccid_comm, &ccid_event_poll_desc);
|
||||
|
||||
reset:
|
||||
{
|
||||
struct ep_in *epi = &endpoint_in;
|
||||
struct ep_out *epo = &endpoint_out;
|
||||
@@ -1516,50 +1713,48 @@ ccid_thread (void *arg)
|
||||
ccid_init (c, epi, epo, a);
|
||||
}
|
||||
|
||||
while (bDeviceState != CONFIGURED)
|
||||
timeout = USB_CCID_TIMEOUT;
|
||||
if (bDeviceState == USB_DEVICE_STATE_CONFIGURED)
|
||||
{
|
||||
poll_event_intr (NULL, &c->ccid_comm, &interrupt);
|
||||
if (interrupt.ready)
|
||||
usb_event_handle (&dev);
|
||||
|
||||
eventflag_get (&c->ccid_comm);
|
||||
/* Ignore event while not-configured. */
|
||||
ccid_prepare_receive (c);
|
||||
ccid_notify_slot_change (c);
|
||||
}
|
||||
|
||||
interface_reset:
|
||||
timeout = USB_CCID_TIMEOUT;
|
||||
ccid_prepare_receive (c);
|
||||
ccid_notify_slot_change (c);
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m;
|
||||
|
||||
poll_event_intr (&timeout, &c->ccid_comm, &interrupt);
|
||||
if (bDeviceState == USB_DEVICE_STATE_CONFIGURED)
|
||||
timeout_p = &timeout;
|
||||
else
|
||||
timeout_p = NULL;
|
||||
|
||||
chopstx_poll (timeout_p, CCID_POLL_NUM, ccid_poll);
|
||||
|
||||
if (interrupt.ready)
|
||||
{
|
||||
usb_event_handle (&dev);
|
||||
continue;
|
||||
}
|
||||
if (usb_event_handle (&dev) == 0)
|
||||
continue;
|
||||
|
||||
timeout = USB_CCID_TIMEOUT;
|
||||
m = eventflag_get (&c->ccid_comm);
|
||||
|
||||
if (m == EV_USB_DEVICE_RESET)
|
||||
{
|
||||
/* RESET handling:
|
||||
* (1) After DEVICE_RESET, it needs to re-start out of the loop.
|
||||
* (2) After SET_CONFIGURATION or SET_INTERFACE, the
|
||||
* endpoint is reset to RX_NAK. It needs to prepare
|
||||
* receive again.
|
||||
*/
|
||||
if (c->application)
|
||||
{
|
||||
chopstx_cancel (c->application);
|
||||
chopstx_join (c->application, NULL);
|
||||
c->application = 0;
|
||||
}
|
||||
goto device_reset;
|
||||
goto reset;
|
||||
}
|
||||
else if (m == EV_USB_SET_INTERFACE)
|
||||
/* Upon receival of SET_INTERFACE, the endpoint is reset to RX_NAK.
|
||||
* Thus, we need to prepare receive again.
|
||||
*/
|
||||
goto interface_reset;
|
||||
else if (m == EV_CARD_CHANGE)
|
||||
|
||||
timeout = USB_CCID_TIMEOUT;
|
||||
m = eventflag_get (&c->ccid_comm);
|
||||
|
||||
if (m == EV_CARD_CHANGE)
|
||||
{
|
||||
if (c->ccid_state == CCID_STATE_NOCARD)
|
||||
/* Inserted! */
|
||||
@@ -1644,7 +1839,7 @@ ccid_thread (void *arg)
|
||||
}
|
||||
|
||||
/* Loading reGNUal. */
|
||||
while (bDeviceState != UNCONNECTED)
|
||||
while (bDeviceState != USB_DEVICE_STATE_UNCONNECTED)
|
||||
{
|
||||
chopstx_intr_wait (&interrupt);
|
||||
usb_event_handle (&dev);
|
||||
@@ -1687,7 +1882,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,6 +38,7 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb_conf.h"
|
||||
#include "gnuk.h"
|
||||
#include "neug.h"
|
||||
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
#include "usb-cdc.h"
|
||||
@@ -86,7 +87,7 @@ vcom_port_data_setup (struct usb_dev *dev)
|
||||
#include "usb-msc.h"
|
||||
#endif
|
||||
|
||||
uint32_t bDeviceState = UNCONNECTED; /* USB device status */
|
||||
uint32_t bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||
|
||||
#define USB_HID_REQ_GET_REPORT 1
|
||||
#define USB_HID_REQ_GET_IDLE 2
|
||||
@@ -107,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
|
||||
{
|
||||
@@ -128,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);
|
||||
}
|
||||
@@ -137,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);
|
||||
}
|
||||
@@ -145,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
|
||||
{
|
||||
@@ -160,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);
|
||||
@@ -179,15 +207,18 @@ 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);
|
||||
bDeviceState = USB_DEVICE_STATE_DEFAULT;
|
||||
}
|
||||
|
||||
#define USB_CCID_REQ_ABORT 0x01
|
||||
@@ -201,22 +232,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
|
||||
|
||||
#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)
|
||||
{
|
||||
if (check_crc32 ((const uint32_t *)&_regnual_start, end_p))
|
||||
uint32_t crc32 = *end_p;
|
||||
const uint32_t *p;
|
||||
|
||||
crc32_rv_reset ();
|
||||
|
||||
for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
|
||||
crc32_rv_step (rbit (*p));
|
||||
|
||||
if ((rbit (crc32_rv_get ()) ^ crc32) == 0xffffffff)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
usb_setup (struct usb_dev *dev)
|
||||
@@ -228,15 +271,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 */
|
||||
{
|
||||
#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;
|
||||
|
||||
@@ -248,9 +298,13 @@ 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;
|
||||
|
||||
@@ -258,6 +312,9 @@ usb_setup (struct usb_dev *dev)
|
||||
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)
|
||||
{
|
||||
@@ -356,7 +413,7 @@ usb_ctrl_write_finish (struct usb_dev *dev)
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
return;
|
||||
|
||||
bDeviceState = UNCONNECTED;
|
||||
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||
usb_lld_prepare_shutdown (); /* No further USB communication */
|
||||
led_blink (LED_GNUK_EXEC); /* Notify the main. */
|
||||
}
|
||||
@@ -417,8 +474,8 @@ 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);
|
||||
bDeviceState = CONFIGURED;
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 0);
|
||||
bDeviceState = USB_DEVICE_STATE_CONFIGURED;
|
||||
}
|
||||
else if (current_conf != dev->dev_req.value)
|
||||
{
|
||||
@@ -427,9 +484,8 @@ 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);
|
||||
bDeviceState = ADDRESSED;
|
||||
ccid_usb_reset (1);
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 1);
|
||||
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
|
||||
}
|
||||
|
||||
/* Do nothing when current_conf == value */
|
||||
@@ -450,8 +506,7 @@ usb_set_interface (struct usb_dev *dev)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
gnuk_setup_endpoints_for_interface (interface, 0);
|
||||
ccid_usb_reset (0);
|
||||
gnuk_setup_endpoints_for_interface (dev, interface, 0);
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,10 +59,13 @@ 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 */
|
||||
0x00, 0x02, /* bcdUSB = 2.0 */
|
||||
0x00, /* bDeviceClass: 0 means deferred to interface */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
|
||||
@@ -8,7 +8,7 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object extended capabilities
|
||||
When requesting extended capabilities: c0
|
||||
Then data should match: [\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
Then data should match: [\x70\x74\x75]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
|
||||
Scenario: data object algorithm attributes 1
|
||||
When requesting algorithm attributes 1: c1
|
||||
@@ -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
|
||||
|
||||
@@ -8,7 +8,7 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object extended capabilities
|
||||
When requesting extended capabilities: c0
|
||||
Then data should match: [\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
Then data should match: [\x70\x74\x75]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
|
||||
Scenario: data object algorithm attributes 1
|
||||
When requesting algorithm attributes 1: c1
|
||||
@@ -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
|
||||
|
||||
@@ -8,7 +8,7 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object extended capabilities
|
||||
When requesting extended capabilities: c0
|
||||
Then data should match: [\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
Then data should match: [\x70\x74\x75]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
|
||||
Scenario: data object algorithm attributes 1
|
||||
When requesting algorithm attributes 1: c1
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
card_reader.py - a library for smartcard reader
|
||||
|
||||
Copyright (C) 2016 Free Software Initiative of Japan
|
||||
Copyright (C) 2016, 2017 Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -179,9 +179,11 @@ class CardReader(object):
|
||||
# TPDU reader configuration
|
||||
self.ns = 0
|
||||
self.nr = 0
|
||||
# Set PPS
|
||||
pps = b"\xFF\x11\x18\xF6"
|
||||
status, chain, ret_pps = self.ccid_send_data_block(pps)
|
||||
# For Gemalto USB GemPC Pinpad SmartCard Reader
|
||||
if self.__dev.idVendor == 0x08E6 and self.__dev.idProduct == 0x3478:
|
||||
# Set PPS
|
||||
pps = b"\xFF\x11\x18\xF6"
|
||||
status, chain, ret_pps = self.ccid_send_data_block(pps)
|
||||
# Set parameters
|
||||
param = b"\x18\x10\xFF\x75\x00\xFE\x00"
|
||||
# ^--- This shoud be adapted by ATR string, see update_param_by_atr
|
||||
|
||||
@@ -146,7 +146,7 @@ def test_historical_bytes(card):
|
||||
|
||||
def test_extended_capabilities(card):
|
||||
a = get_data_object(card, 0xc0)
|
||||
assert a == None or match(b'[\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00', a)
|
||||
assert a == None or match(b'[\x70\x74\x75]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00', a)
|
||||
|
||||
def test_algorithm_attributes_1(card):
|
||||
a = get_data_object(card, 0xc1)
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user