Compare commits

..

81 Commits

Author SHA1 Message Date
NIIBE Yutaka
ad704edc4e Version 1.2.6.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-10-11 16:50:13 +09:00
NIIBE Yutaka
97a1870e6e Fix test/*. 2017-10-11 16:08:17 +09:00
NIIBE Yutaka
f72e132967 Fix configure. 2017-10-11 11:24:12 +09:00
NIIBE Yutaka
a22b695f96 No --vidpid for GNU/Linux. 2017-10-10 21:06:42 +09:00
NIIBE Yutaka
0c901d8052 Support --debug option for GNU/Linux emulation. 2017-10-10 14:36:34 +09:00
NIIBE Yutaka
a1b8e7f40c STM8S Discovery kit is supported again. 2017-10-06 17:19:55 +09:00
NIIBE Yutaka
dccda32b93 Fix for 64KB STM32F103. 2017-10-06 17:04:45 +09:00
NIIBE Yutaka
75049ce949 Fix linker script. 2017-10-06 17:00:00 +09:00
NIIBE Yutaka
be80a3ef2f For emulation, support --vidpid at runtime. 2017-10-06 10:20:54 +09:00
NIIBE Yutaka
94424e85c3 Fix stack size for ARM. 2017-10-05 17:07:06 +09:00
NIIBE Yutaka
43980d1c81 RSA in a single step. 2017-10-05 17:06:50 +09:00
NIIBE Yutaka
183cec8a04 Emulation tool added. 2017-10-05 13:53:48 +09:00
NIIBE Yutaka
7bae61f300 Fix bignum for 64-bit machine. 2017-10-05 13:45:24 +09:00
NIIBE Yutaka
7e4ee2b361 Serial string for GNU/Linux emulation. 2017-10-04 18:54:16 +09:00
NIIBE Yutaka
30fde2a0f0 Fix bignum for 64-bit machine. 2017-10-04 17:08:42 +09:00
NIIBE Yutaka
eee8d046a9 Fix gnuk_malloc for 64-bit. 2017-10-04 12:38:37 +09:00
NIIBE Yutaka
550010f25f Tweak the size of stack of openpgp-card thread. 2017-10-04 10:45:39 +09:00
NIIBE Yutaka
3adbe30c4d RSA key generation in two steps. 2017-10-04 09:44:19 +09:00
NIIBE Yutaka
d9ec8778fc Don't use malloc if not needed. 2017-10-03 16:12:41 +09:00
NIIBE Yutaka
eff0c7077d Don't provide stdlib.h, but provide gnuk-malloc.h. 2017-10-03 16:04:43 +09:00
NIIBE Yutaka
289d3db8c4 generate flash.data. 2017-10-03 13:50:51 +09:00
NIIBE Yutaka
7c5eb7efd2 Fix non-use of stdlib.h. 2017-10-03 13:27:12 +09:00
NIIBE Yutaka
6f1fbdd82d flash memory handling change to support GNU/Linux. 2017-10-03 11:50:48 +09:00
NIIBE Yutaka
cbedf98a52 Not for GNU/Linux. 2017-10-02 16:45:08 +09:00
NIIBE Yutaka
15689b5b86 FLASH_UPGRADE_SUPPORT is not relevant to GNU/Linux. 2017-10-02 16:24:56 +09:00
NIIBE Yutaka
8170b60ee2 Fix for main.c. 2017-10-02 16:08:20 +09:00
NIIBE Yutaka
ca7f4c8758 More USB fix for GNU/Linux. 2017-10-02 15:29:45 +09:00
NIIBE Yutaka
0b4099d6d1 mpi_montsqr fix for GNU/Linux. 2017-10-02 15:27:27 +09:00
NIIBE Yutaka
65fee7eb2a Fix flash.c for GNU/Linux emulation. 2017-09-30 21:03:17 +09:00
NIIBE Yutaka
0c229f5712 Small USB clean up. 2017-09-30 20:51:21 +09:00
NIIBE Yutaka
5948f6ec50 Revert part of simplification. 2017-09-30 20:20:36 +09:00
NIIBE Yutaka
7b1ea00307 More fix for USB. 2017-09-29 21:06:15 +09:00
NIIBE Yutaka
277be86958 Fix USB code for USBIP on GNU/Linux. 2017-09-29 19:23:39 +09:00
NIIBE Yutaka
a6b90ad648 Fix for FLASH_UPGRADE_SUPPORT. 2017-09-29 16:58:59 +09:00
NIIBE Yutaka
547e263d6b Fix for 64-bit machine (emulation). 2017-09-29 14:15:48 +09:00
NIIBE Yutaka
7004453669 Stack definition change. 2017-09-29 13:18:49 +09:00
NIIBE Yutaka
81b18f2db4 More for GNU/Linux emulation. 2017-09-28 16:44:54 +09:00
NIIBE Yutaka
86715dd4fe More fixes. 2017-09-28 15:36:59 +09:00
NIIBE Yutaka
62f27f319c Fix for GNU/Linux. 2017-09-28 15:25:06 +09:00
NIIBE Yutaka
7345f3c241 Rename flash functions. 2017-09-28 15:10:20 +09:00
NIIBE Yutaka
f4b9073b11 stdlib fixes. 2017-09-28 15:09:21 +09:00
NIIBE Yutaka
6678ac28c2 GNU/Linux emulation is done by Chopstx. 2017-09-28 11:04:28 +09:00
NIIBE Yutaka
83414a747a Version 1.2.5. 2017-08-11 22:12:09 +09:00
NIIBE Yutaka
8a615d087b Update .gitignore. 2017-08-11 22:11:49 +09:00
NIIBE Yutaka
967b949967 Tweak process size of gpg. 2017-08-11 22:00:01 +09:00
NIIBE Yutaka
11afbdde14 src/config.mk generation. 2017-08-11 21:06:59 +09:00
NIIBE Yutaka
328766af12 Merge branch 'master' of git.gniibe.org:gnuk/gnuk 2017-08-04 08:33:46 +09:00
NIIBE Yutaka
2b340ee1c5 Fix factory-reset for admin-less mode.
Reported-by: Stanislas Bach <sbach@0g.re>
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-08-04 08:32:39 +09:00
NIIBE Yutaka
86e6adf47e Fix factory-reset for admin-less mode.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-08-03 21:35:20 +09:00
Jeremy Drake
eea011fe70 Allow compile-time override of detected flash size.
On the STM32F103C8, as used in the "blue pill" boards, it has been
determined that, despite these only officially having 64KiB flash, it is
possible to actually use 128KiB of flash.

This commit allows for a preprocessor define
STM32F103_OVERRIDE_FLASH_SIZE which, when set, is used as the size of
flash in KiB instead of reading it from the FLASH_SIZE_REG.
2017-08-03 21:20:47 +09:00
Jeremy Drake
e736227de7 Erase CERTDO on terminate.
When both certdo and lifecycle support are enabled, flash_terminate
neglected to erase the certdo pages.  It now does so.
2017-08-02 11:13:02 +09:00
NIIBE Yutaka
22156ea7f9 Fix factory-reset. 2017-08-01 13:30:02 +09:00
Anthony Romano
db45e62ebe configure: sanitize for shellcheck
Signed-off-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-20 12:25:24 +09:00
Anthony Romano
3270740631 docker: source checking container
Includes shellcheck and scan-build

Signed-off-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-20 12:24:44 +09:00
NIIBE Yutaka
e4e72a29ae Initialize TMP to avoid confusion by static analysis.
--

The computation using TMP is keeping it constant-time only, but
it is better not to confuse static analysis.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-07-19 11:55:20 +09:00
NIIBE Yutaka
25d3f021c1 Support no git situation.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-07-19 11:25:38 +09:00
NIIBE Yutaka
ae76d66d53 Fix accessing garbage on error path.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Reported-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-19 10:48:16 +09:00
NIIBE Yutaka
10c5010141 Git is assumed for the source with .git.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-07-18 14:12:20 +09:00
Anthony Romano
d12483c3c9 Support building with docker.
Signed-off-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-18 13:38:46 +09:00
Anthony Romano
67acb670d1 call fatal if mem_head size is corrupted.
Signed-off-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-18 13:31:06 +09:00
Anthony Romano
a44244b27e avoid null dereference when openpgp algo goes from !rsa2k to rsa2k.
Detected with scan-build.

Signed-off-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-18 13:27:12 +09:00
Anthony Romano
2622840e27 remove unused calculations from mod_reduce.
Detected with scan-build.

Signed-off-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-18 13:19:42 +09:00
Anthony Romano
a51ac8593b call-rsa: free modulus buffers on error paths.
* MPI_CHK jumps to cleanup on ret != 0, so p_q_modulus is never freed if
  rsa_gen_key fails (detected via scan-build).
* modulus_calc never freed its modulus buffer on error.

Signed-off-by: Anthony Romano <anthony.romano@coreos.com>
2017-07-18 13:15:42 +09:00
NIIBE Yutaka
de81caba3e Update Chopstx.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-07-18 12:58:23 +09:00
NIIBE Yutaka
fa69a85826 Version 1.2.4.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-05-12 17:22:20 +09:00
NIIBE Yutaka
5c3c3e3001 usbip list -r 127.0.0.1 now works.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-05-12 14:13:53 +09:00
NIIBE Yutaka
6dcb4dd027 Add usb-emu.c.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-05-02 15:05:15 +09:00
NIIBE Yutaka
fa08f44cac Fix old documentation (note) for firmware update.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-05-01 14:58:15 +09:00
NIIBE Yutaka
4c2294ea6c Portability change.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-04-28 16:14:30 +09:00
NIIBE Yutaka
86eaa26d32 New: src/mcu-stm32f103.c.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-04-28 15:49:38 +09:00
NIIBE Yutaka
9e52789203 Fix long standing buf of digital signature counter.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-04-28 14:54:15 +09:00
NIIBE Yutaka
702bc8cbde Move data objects at the end of flash.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-04-27 15:23:25 +09:00
NIIBE Yutaka
2cfce76d91 [SECURITY] Flash memory usage change.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-04-27 14:36:32 +09:00
NIIBE Yutaka
207652246a emulation: USB device emulation by USBIP protocol. 2017-04-18 15:45:25 +09:00
NIIBE Yutaka
32779b6f96 Version 1.2.3. 2017-02-02 16:33:30 +09:00
NIIBE Yutaka
55c1015faa Increase CCID thread stack size by 0x20 for newer GCC. 2017-02-02 14:11:11 +09:00
NIIBE Yutaka
0932465f0b Update Chopstx to 1.3. 2017-02-02 13:07:35 +09:00
NIIBE Yutaka
4417799a51 Update README 2017-02-01 17:16:54 +09:00
Szczepan Zalega
b424cecf1e Regnual update tool: do not allow other than binary formats (upgrade_by_passwd)
Signed-off-by: Szczepan Zalega <szczepan@nitrokey.com>
2017-02-01 15:40:56 +09:00
NIIBE Yutaka
7ef417ae36 tool: Improve tool/*.py.
--

Szczepan Zalega's idea of using the file GNUK_USB_DEVICE_ID would
good, but not merged yet.  Because it makes difficult to distribute
the scripts.  We need to consider installing tools and the file
like GNUK_USB_DEVICE_ID altogether.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-02-01 12:34:35 +09:00
NIIBE Yutaka
d4469c24ec fix NIST P-256 / secp256k1 key generation. 2016-10-21 15:30:07 +09:00
56 changed files with 1800 additions and 720 deletions

2
.gitignore vendored
View File

@@ -2,7 +2,7 @@
*.o
*.pyc
src/.dep
src/Makefile
src/config.mk
src/config.h
src/gnuk.ld
src/board.h

10
AUTHORS
View File

@@ -1,3 +1,13 @@
Anthony Romano:
Modified:
src/call-rsa.c
src/main.c
src/mod.c
Jeremy Drake:
Modified:
regnual/regnual.c
Kaz Kojima:
Added STM32 Primer2 support.

324
ChangeLog
View File

@@ -1,3 +1,327 @@
2017-10-11 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.6.
* regnual/Makefile (LDSCRIPT): Move after include.
* regnual/types.h: Add uintptr_t.
* test/features/002_get_data_static.feature (data object AID): Fix
for any binary value.
* 402_get_data_static.feature: Likewise.
* 802_get_data_static.feature: Likewise.
2017-10-10 NIIBE Yutaka <gniibe@fsij.org>
* src/main.c (main): Support --debug option.
* chopstx: Update to 1.5.
2017-10-06 NIIBE Yutaka <gniibe@fsij.org>
* src/configure (flash_override): Fix suggested by Jeremy Drake.
(help): STM8S_DISCOVERY is supported again.
2017-10-06 NIIBE Yutaka <gniibe@fsij.org>
* src/gnuk.ld.in (.stacks): Specify NOLOAD type.
* src/configure: Allow not specifying VIDPID.
* src/main.c [GNU_LINUX_EMULATION] (main): Handle "--vidpid"
option to assign vendor ID and product ID of USB.
* src/usb_desc.c [GNU_LINUX_EMULATION] (device_desc): Export.
* GNUK_USB_DEVICE_ID (0000:0000): New.
2017-10-05 NIIBE Yutaka <gniibe@fsij.org>
* src/stack-def.h (SIZE_1, SIZE_3): Tweak the size.
* src/call-rsa.c (rsa_genkey): Single step.
* src/openpgp-do.c (gpg_do_keygen): Do RSA key generation in single
step, using APDU buffer.
* src/openpgp.c (cmd_pgp_gakp): Supply the APDU as a buffer.
* src/Makefile (install): New target.
* src/configure (prefix. exec_prefix, libexecdir): Add.
* src/main.c [GNU_LINUX_EMULATION] (main): Option handling.
* tool/gnuk-emulation-setup: New.
* polarssl/library/bignum.c (M_LIMBS, limbs_M, MAX_A_LIMBS)
(limbs_MAX_A, mpi_gen_prime): Fix for 64-bit machine.
2017-10-04 NIIBE Yutaka <gniibe@fsij.org>
* src/configure (output_vendor_product_serial_strings): Support
GNU/Linux emulation.
* polarssl/library/bignum.c (mpi_div_mpi): Fix for 64-bit machine.
* src/main.c (gnuk_malloc, gnuk_free): Fix for 64-bit machine.
* src/stack-def.h (SIZE_3): Tweak the size.
* src/openpgp-do.c (gpg_do_keygen): Do RSA key generation in two
steps.
* src/call-rsa.c (rsa_genkey_start, rsa_genkey_finish): New.
(rsa_genkey): Remove.
2017-10-03 NIIBE Yutaka <gniibe@fsij.org>
* src/call-ec.c (ecc_compute_public): No use of malloc.
* src/call-rsa.c (modulus_calc, rsa_genkey): Likewise.
* src/ecc-edwards.c (eddsa_compute_public_25519): Likewise.
* src/ecc-mont.c (ecdh_compute_public_25519): Likewise.
* src/openpgp-do.c (gpg_do_write_prvkey, gpg_do_chks_prvkey)
(proc_key_import, gpg_do_keygen): Likewise.
* polarssl/library/rsa.c: Don't include stdlib.h.
* src/gnuk-malloc.h: Rename from stdlib.h.
* polarssl/library/bignum.c: Include gnuk-malloc.h.
* src/Makefile (build/flash.data): Generate.
* src/main.c (flash_addr_key_storage_start)
(flash_addr_data_storage_start): New.
(main): Determine flash address.
* src/flash.c (FLASH_ADDR_KEY_STORAGE_START)
(FLASH_ADDR_DATA_STORAGE_START): New.
(flash_do_storage_init, flash_terminate, flash_activate)
(flash_key_storage_init, flash_copying_gc, flash_do_release)
(flash_key_getpage): Use new macros.
2017-10-02 NIIBE Yutaka <gniibe@fsij.org>
* src/main.c (device_initialize_once): Not for GNU/Linux.
* src/openpgp.c, src/flash.c: Distinguish FLASH_UPGRADE_SUPPORT.
* src/main.c [GNU_LINUX_EMULATION]: Use emulated_main.
(MEMORY_SIZE, MEMORY_END): Fix for GNU/Linux.
* src/usb-ccid.c (INTR_REQ_USB): Fix for GNU/Linux.
* polarssl/library/bignum.c (mpi_montsqr): Easy C implementation.
2017-09-30 NIIBE Yutaka <gniibe@fsij.org>
* src/flash.c (flash_terminate, flash_activate)
(flash_copying_gc, flash_do_write_internal, flash_do_release)
(flash_key_write, flash_check_all_other_keys_released)
(flash_key_fill_zero_as_released, flash_key_release)
(flash_key_release_page, flash_clear_halfword)
(flash_put_data_internal, flash_put_data, flash_bool_clear)
(flash_bool_write_internal, flash_bool_write)
(flash_enum_write_internal, flash_enum_write)
(flash_cnt123_write_internal, flash_cnt123_increment)
(flash_cnt123_clear, flash_erase_binary, flash_write_binary): Fix
for GNU/Linux.
* src/usb-ccid.c (ccid_tx_done): Rename from EP1_IN_Callback.
(ccid_rx_ready): Rename from EP1_OUT_Callback.
2017-09-29 NIIBE Yutaka <gniibe@fsij.org>
* src/usb-ccid.c (epo_init, epi_init, ccid_thread): Simplify.
(EP1_IN_Callback, ccid_prepare_receive, EP1_OUT_Callback)
(usb_rx_ready, ccid_error, ccid_power_on, ccid_send_status)
(ccid_send_data_block_internal, ccid_send_data_block_0x9000)
(ccid_send_data_block_gr, ccid_send_params)
(ccid_notify_slot_change, _write) [GNU_LINUX_EMULATION]: Use
different usb driver API.
* src/usb_ctrl.c (usb_device_reset): Fix control endpoint init.
(gnuk_setup_endpoints_for_interface): Add DEV
argument.
(usb_device_reset) [GNU_LINUX_EMULATION]: Use usb_lld_setup_endp.
2017-09-29 NIIBE Yutaka <gniibe@fsij.org>
* src/main.c [FLASH_UPGRADE_SUPPORT] (main): Factor out flash ROM
upgrade support.
(calculate_regnual_entry_address): Likewise.
* src/usb_ctrl.c (usb_setup, download_check_crc32): Likewise.
* src/openpgp.c (modify_binary): Fix for 64-bit machine.
* src/openpgp-do.c (encrypt, decrypt): Likewise.
(gpg_data_scan): Likewise.
(gpg_do_chks_prvkey): Fix error return path.
* src/stack-def.h: New.
* src/gnuk.ld.in: Remove stack definitions.
* src/configure: Remove stack size modifications.
* src/main.c (STACK_MAIN, STACK_PROCESS_1): Use stack-def.h.
* src/usb-ccid.c (STACK_PROCESS_3): Likewise.
* src/usb-msc.c (STACK_PROCESS_5): Likewise.
* src/pin-cir.c (STACK_PROCESS_6, STACK_PROCESS_7): Likewise.
* src/usb_ctrl.c (download_check_crc32): Use chrc32_rv_ functions.
* src/mcu-stm32f103.c (rbit, check_crc32): Remove.
* src/neug.c: Update from NeuG.
* src/neug.h: Ditto.
2017-09-28 NIIBE Yutaka <gniibe@fsij.org>
* src/ec_p256k1.c (coefficient_a): Remove.
* polarssl/library/bignum.c (mpi_fill_pseudo_random): Fix for
64-bit machine.
* src/call-rsa.c (rsa_decrypt): Fix for 64-bit machine.
* src/flash.c (flash_do_storage_init): Rename from flash_init.
(flash_key_storage_init): Rename from flash_init_keys.
* src/openpgp.c (gpg_init): Use new function names.
* src/stdlib.h: Update for GNU/Linux emulation.
* src/Makefile: Support GNU/Linux emulation.
* src/configure: Support GNU/Linux emulation.
* emulation: Remove.
2017-08-11 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.5.
* chopstx: Update to 1.4.
* src/gnuk.ld.in (__process3_stack_size__): Tweak the size.
* src/configure: Define STM32F103_OVERRIDE_FLASH_SIZE_KB for
BULE_PILL.
* src/configure: Let generate src/config.mk.
* src/Makefile: Rename from src/Makefile.in.
* regnual/Makefile: Use src/config.mk.
2017-08-03 NIIBE Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_terminate_df): Fix for admin-less mode.
2017-08-03 Jeremy Drake <jeremydrake+gnuk@eacceleration.com>
* regnual/regnual.c (main): Allow compile time
flash size definition by STM32F103_OVERRIDE_FLASH_SIZE_KB.
2017-08-02 Jeremy Drake <jeremydrake+gnuk@eacceleration.com>
* src/flash.c (flash_terminate): Erase Certificate DO, too.
2017-08-01 NIIBE Yutaka <gniibe@fsij.org>
* src/openpgp.c (FILE_CARD_TERMINATED_OPENPGP): Remove.
(cmd_select_file): Don't change file_selection.
2017-07-19 NIIBE Yutaka <gniibe@fsij.org>
* src/mod.c (mod_inv): Clear TMP.
* src/configure (REVISION): Generate even when no git.
* polarssl/library/bignum.c (mpi_exp_mod): Call mpi_grow for X
after the initialization of RR.
2017-07-18 NIIBE Yutaka <gniibe@fsij.org>
* src/configure: Bark when no git available.
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
* docker: New.
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
* src/main.c (MEMORY_SIZE, MEM_HEAD_IS_CORRUPT, MEM_HEAD_CHECK):
New.
(gnuk_malloc, gnuk_free): Add calls to MEM_HEAD_CHECK.
* src/gnuk.h (FATAL_HEAP): New.
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
* src/openpgp-do.c (gpg_reset_algo_attr): New.
(rw_algorithm_attr): Use gpg_reset_algo_attr.
Fix null dereference.
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
* src/mod.c (mod_reduce): Clean up unused code.
2017-07-18 Anthony Romano <anthony.romano@coreos.com>
* src/call-rsa.c (modulus_calc): Free modulus on error.
(rsa_genkey): Remove bogus check, and call chopstx_cleanup_pop
with 1 to release p_q_modulus on error. Assign NULL to clp.arg
when it's goes with no error.
* src/main.c (gnuk_free): Allow NULL.
2017-07-18 NIIBE Yutaka <gniibe@fsij.org>
* Update chopstx (with USBIP emulation).
2017-05-12 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.4.
2017-04-28 NIIBE Yutaka <gniibe@fsij.org>
* src/mcu-stm32f103.c: New.
(check_crc32, sram_address): New.
* src/usb_ctrl.c (download_check_crc32): Use check_crc32 and
sram_address.
* src/openpgp-do.c (gpg_write_digital_signature_counter): Fix
writing lower 10-bit.
2017-04-27 NIIBE Yutaka <gniibe@fsij.org>
* src/gnuk.ld.in (_data_pool): Move to the end.
* src/flash.c (flash_init): Return address of end of data object.
* src/openpgp.c (gpg_init): Get address of end of data object.
* src/openpgp-do.c (gpg_data_scan): Check the end address.
2017-02-02 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.3.
* src/gnuk.ld.in (__process1_stack_size__): Increase by 0x20.
* chopstx: Update to 1.3.
* src/configure: Add BLUE_PILL in the help message.
2017-02-01 NIIBE Yutaka <gniibe@fsij.org>
* README: Update README. Thanks to Paul Fertser.
2017-01-02 Szczepan Zalega <szczepan@nitrokey.com>
* tool/upgrade_by_passwd.py: Add file extention check.
2017-02-01 NIIBE Yutaka <gniibe@fsij.org>
* tool/upgrade_by_passwd.py (main): More verbose messages
suggested by Szczepan Zalega <szczepan@nitrokey.com>.
* tool/gnuk_token.py (USB_PRODUCT_LIST): New.
(gnuk_devices_by_vidpid): Support searching by USB_PRODUCT_LIST.
Thanks to Szczepan Zalega <szczepan@nitrokey.com>.
* tool/usb_strings.py: Use gnuk_token.py.
2016-10-21 Niibe Yutaka <gniibe@fsij.org>
* src/ecc.c (check_secret): Fix condition.
2016-10-15 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.2.

View File

@@ -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
View File

@@ -1,5 +1,51 @@
Gnuk NEWS - User visible changes
* Major changes in Gnuk 1.2.6
Released 2017-10-11, by NIIBE Yutaka
** Port to GNU/Linux emulation
We can "run" Gnuk Token on GNU/Linux by emulation through USBIP.
** Upgrade of Chopstx
We use Chopstx 1.5.
* Major changes in Gnuk 1.2.5
Released 2017-08-11, by NIIBE Yutaka
** "factory-reset" fix
Gnuk's behavior was implemented by referring the gpg implementation.
It found that gpg implementation was not good from the viewpoint of
the OpenPGP card specification. GnuPG was fixed to match the OpenPGP
card specification already. Thus, Gnuk is now fixed.
** Upgrade of Chopstx
We use Chopstx 1.4.
* Major changes in Gnuk 1.2.4
Released 2017-05-12, by NIIBE Yutaka
** Flash ROM security fix
The partial content of flash ROM might be exposed when scanning of
data object had a problem. Added boundary check and changed layout of
flash ROM.
* Major changes in Gnuk 1.2.3
Released 2017-02-02, by NIIBE Yutaka
** ECC key generation on the device
Bug fixed.
** Upgrade of Chopstx
We use Chopstx 1.3.
* Major changes in Gnuk 1.2.2
Released 2016-10-15, by NIIBE Yutaka

103
README
View File

@@ -1,28 +1,35 @@
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
Version 1.2.2
2016-10-15
Version 1.2.6
2017-10-11
Niibe Yutaka
Free Software Initiative of Japan
Release Notes
=============
This is the release of Gnuk, version 1.2.2, which has major
This is the release of Gnuk, version 1.2.6, which has major
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
overriding key import, but importing keys (or generating keys) results
password reset. Please update your documentation for Gnuk Token, so
password reset. Also, you need to import private keys before changing
your password. Please update your documentation for Gnuk Token, so
that the instruction of importing keys won't cause any confusion.
It has supports of EdDSA, ECDSA (with NIST P256 and secp256k1), and
ECDH (with X25519, NIST P256 and secp256k1), but this ECC feature is
somehow experimental, and it requires modern GnuPG 2.1 with libgcrypt
somehow experimental, and it requires modern GnuPG 2.2 with libgcrypt
1.7.0 or later.
It also supports RSA-4096, but users should know that it takes more
than 8 seconds to sign/decrypt. Key generation of RSA-4096 just fails,
because the device doesn't have enough memory.
With this release, you can test how Gnuk Token works on GNU/Linux,
without real hardware, by USBIP emulation (--target=GNU_LINUX).
Please note that this emulation is intended only for testing. When
Gnuk does crypto computation on host, it is vulnerable by side channel
attacks.
What's Gnuk?
============
@@ -47,7 +54,7 @@ FAQ
Q0: How Gnuk USB Token is superior than other solutions (OpenPGP
card 2.0, YubiKey, etc.) ?
http://www.g10code.de/p-card.html
https://www.g10code.de/p-card.html
https://www.yubico.com/
A0: Good points of Gnuk are:
* If you have skill of electronics and like DIY, you can build
@@ -77,12 +84,12 @@ A3: Orthodox choice is Olimex STM32-H103.
choice for experiment.
Q4: What's version of GnuPG are you using?
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.13 in
experimental.
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.18 in
unstable.
Q5: What's version of pcscd and libccid are you using?
A5: I don't use them, pcscd and libccid are optional, you can use Gnuk
without them.
Token without them.
I tested pcscd 1.5.5-4 and libccid 1.3.11-2 which were in Debian
squeeze.
@@ -224,7 +231,9 @@ Gnuk source code is under src/ directory.
Note that SHA-2 hash function implementation, src/sha256.c, is based
on the original implementation by Dr. Brian Gladman. See:
http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php
http://brg.a2hosted.com//oldsite/cryptography_technology/sha/index.php
(was at:
http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php)
License
@@ -248,7 +257,7 @@ External source code
Gnuk is distributed with external source code.
* chopstx/ -- Chopstx 1.1
* chopstx/ -- Chopstx 1.5
We use Chopstx as the kernel for Gnuk.
@@ -361,10 +370,10 @@ You need GNU toolchain and newlib for 'arm-none-eabi' target.
On Debian we can install the packages of gcc-arm-none-eabi,
gdb-arm-none-eabi and its friends. I'm using:
binutils-arm-none-eabi 2.26-4+8
gcc-arm-none-eabi 15:4.9.3+svn231177-1
gdb-arm-none-eabi 7.10-1+9
libnewlib-arm-none-eabi 2.2.0+git20150830.5a3d536-1
binutils-arm-none-eabi 2.28-4+9+b3
gcc-arm-none-eabi 15:5.4.1+svn241155-1
gdb-arm-none-eabi 7.12-6+9+b2
libnewlib-arm-none-eabi 2.4.0.20160527-2
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
GNU Toolchain for 'arm-none-eabi' target.
@@ -395,18 +404,14 @@ How to install
Olimex STM32-H103 board
-----------------------
If you are using Olimex JTAG-Tiny, type following to invoke OpenOCD:
If you are using Olimex JTAG-Tiny, type following to invoke OpenOCD
and write "gnuk.elf" to Flash ROM:
$ openocd -f interface/ftdi/olimex-jtag-tiny.cfg -f board/olimex_stm32_h103.cfg
$ openocd -f interface/ftdi/olimex-jtag-tiny.cfg \
-f board/olimex_stm32_h103.cfg \
-c "program build/gnuk.elf verify reset exit"
Then, with another terminal, type following to write "gnuk.elf" to Flash ROM:
$ telnet localhost 4444
> reset halt
> flash write_image erase gnuk.elf
> reset
> exit
$
Command invocation is assumed in src/ directory.
Flying Stone Tiny 01
@@ -414,9 +419,10 @@ Flying Stone Tiny 01
If you are using Flying Stone Tiny 01, you need a SWD writer.
OpenOCD 0.9 now supports ST-Link/V2. We can use it:
OpenOCD 0.9.0 now supports ST-Link/V2. We can use it like:
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x_stlink.cfg
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
-c "program build/gnuk.elf verify reset exit"
@@ -435,20 +441,24 @@ Then, reset the board.
How to protect flash ROM
========================
Invoke your OpenOCD and type:
To protect, invoke OpenOCD like (for FST-01):
$ telnet localhost 4444
> reset halt
> stm32f1x lock 0
> reset
> shutdown
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
-c init -c "reset halt" -c "stm32f1x lock 0" -c reset -c exit
After power-off / power-on sequence, the contents of flash ROM cannot
be accessible from JTAG debugger.
Unprotecting is:
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
-c init -c "reset halt" -c "stm32f1x unlock 0" -c reset -c exit
Upon unprotection, flash is erased.
Note that it would be still possible for some implementation of DfuSe
to access the contents. If you want to protect, killing DfuSe and
accessing by JTAG debugger is recommended.
to access the contents, even if it's protected. If you really want to
protect, killing DfuSe and accessing by JTAG debugger is recommended.
(Optional) Configure serial number and X.509 certificate
@@ -536,7 +546,7 @@ Gnuk supports key generation, but this feature is young and should be
considered experimental.
For detail, please see documentation under doc/. You can see the HTML
version at: http://www.fsij.org/doc-gnuk/
version at: https://www.fsij.org/doc-gnuk/
How to debug
@@ -551,6 +561,10 @@ Inside GDB, we can connect OpenOCD by:
(gdb) target remote localhost:3333
or
(gdb) target extended-remote localhost:3333
You can see the output of PCSCD:
@@ -578,33 +592,28 @@ You can get it by:
$ git clone git://anonscm.debian.org/gnuk/gnuk/gnuk.git
It's also available at: www.gniibe.org
You can browse at: http://git.gniibe.org/gitweb?p=gnuk/gnuk.git;a=summary
You can browse at: https://git.gniibe.org/gitweb?p=gnuk/gnuk.git;a=summary
I put Chopstx as a submodule of Git. Please do this:
$ git submodule init
$ git submodule update
We have migrated from ChibiOS/RT to Chopstx in Gnuk 1.1. If you have
old code of ChibiOS/RT, you need:
Edit .git/config to remove chibios reference
git rm --cached chibios
$ git submodule update --init
Information on the Web
======================
Please visit: http://www.fsij.org/gnuk/
For more information, please visit: https://www.fsij.org/gnuk/
Please see the FST-01 support pages:
http://www.gniibe.org/category/fst-01.html
https://www.gniibe.org/category/fst-01.html
Please consider to join Gnuk-users mailing list:
https://lists.alioth.debian.org/mailman/listinfo/gnuk-users
The mailing list will be moved to lists.debian.org.
Your Contributions
==================

5
THANKS
View File

@@ -11,12 +11,14 @@ Achim Pietig achim@pietig.com
Aidan Thornton
Anibal Monsalve Salazar anibal@debian.org
Andre Zepezauer andre.zepezauer@student.uni-halle.de
Anthony Romano anthony.romano@coreos.com
Bertrand Jacquin bertrand@jacquin.bzh
Clint Adams clint@softwarefreedom.org
Daniel Kahn Gillmor dkg@fifthhorseman.net
Elliott Mitchell
Hironobu SUZUKI hironobu@h2np.net
Jan Suhr jan@suhr.info
Jeremy Drake jeremydrake+gnuk@eacceleration.com
Jonathan McDowell noodles@earth.li
Kaz Kojima kkojima@rr.iij4u.or.jp
Kenji Rikitake
@@ -29,9 +31,12 @@ NAGAMI Takeshi nagami-takeshi@aist.go.jp
Nguyễn Hồng Quân quannguyen@mbm.vn
Nico Rikken nico@nicorikken.eu
NOKUBI Takatsugu knok@daionet.gr.jp
Paul Fertser
Paul Bakker polarssl_maintainer@polarssl.org
Santiago Ruano Rincón santiago@debian.org
Shane Coughlan scoughlan@openinventionnetwork.com
Stanislas Bach sbach@0g.re
Szczepan Zalega szczepan@nitrokey.com
Vasily Evseenko
Werner Koch wk@gnupg.org
Yuji Imai ug@xcast.jp

View File

@@ -1 +1 @@
release/1.2.2
release/1.2.6

Submodule chopstx updated: d448d3c678...96d2a81331

View File

@@ -50,39 +50,9 @@ With the script below, I extract public key of the keygrip
$ ./get_raw_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
Here is the script, get_raw_public_key.py::
#! /usr/bin/python
import sys, binascii
from subprocess import check_output
def get_gpg_public_key(keygrip):
result = check_output(["gpg-connect-agent", "READKEY %s" % keygrip, "/bye"])
key = ""
while True:
i = result.find('%')
if i < 0:
key += result
break
hex_str = result[i+1:i+3]
key += result[0:i]
key += chr(int(hex_str,16))
result = result[i+3:]
pos = key.index("D (10:public-key(3:rsa(1:n257:") + 31 # skip NUL too
key = key[pos:-17] # )(1:e3:XYZ)))\nOK\n
if len(key) != 256:
raise ValueError, binascii.hexlify(key)
return key
if __name__ == '__main__':
keygrip = sys.argv[1]
k = get_gpg_public_key(keygrip)
shorthand = keygrip[0:8] + ".bin"
f = open(shorthand,"w")
f.write(k)
f.close()
(The script is available in the directory gnuk/tool. Please note that
it was written in the early stage of the development. The quality of
the code is somewhat questionable.)
Then, we can put the data of public key into token by::

7
docker/Dockerfile.check Normal file
View 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
View 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

View 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
View 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

View File

@@ -37,7 +37,7 @@
#include "polarssl/bignum.h"
#include "polarssl/bn_mul.h"
#include <stdlib.h>
#include <gnuk-malloc.h>
#define ciL (sizeof(t_uint)) /* chars in limb */
#define biL (ciL << 3) /* bits in limb */
@@ -223,6 +223,7 @@ size_t mpi_lsb( const mpi *X )
return( 0 );
}
#if !defined(POLARSSL_HAVE_UDBL)
/*
* Count leading zero bits in a given integer
*/
@@ -240,6 +241,7 @@ static size_t int_clz( const t_uint x )
return j;
}
#endif
/*
* Return the number of most significant bits
@@ -1140,9 +1142,9 @@ static t_uint int_div_int(t_uint u1, t_uint u0, t_uint d, t_uint *r)
*/
if(( 0 == d ) || ( u1 >= d ))
{
if (r != NULL) *r = (~0);
if (r != NULL) *r = (~0UL);
return (~0);
return (~0UL);
}
#if defined(POLARSSL_HAVE_UDBL)
@@ -1268,7 +1270,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
for( i = n; i > t ; i-- )
{
if( X.p[i] >= Y.p[t] )
Z.p[i - t - 1] = ~0;
Z.p[i - t - 1] = ~0UL;
else
{
Z.p[i - t - 1] = int_div_int( X.p[i], X.p[i-1], Y.p[t], NULL);
@@ -1295,7 +1297,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
if( mpi_cmp_int( &X, 0 ) < 0 )
while( mpi_cmp_int( &X, 0 ) < 0 )
{
MPI_CHK( mpi_copy( &T1, &Y ) );
MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
@@ -1512,9 +1514,22 @@ static void mpi_montred( size_t n, const t_uint *np, t_uint mm, t_uint *d )
/*
* Montgomery square: A = A * A * R^-1 mod N
* A is placed at the upper half of D.
*
* n : number of limbs of N
* np: pointer to limbs of bignum N
* mm: m' = -N^(-1) mod b where b = 2^number-of-bit-in-limb
* d (destination): the result [<-- temp -->][<--- A ---->]
* lower part upper part
* n-limb n-limb
*/
static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
{
#ifdef BIGNUM_C_IMPLEMENTATION
t_uint a_input[n];
memcpy (a_input, &d[n], sizeof (a_input));
mpi_montmul (n, np, mm, d, a_input);
#else
size_t i;
register t_uint c = 0;
@@ -1526,6 +1541,7 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
x_i = *xj;
*xj++ = c;
asm (/* (C,R4,R5) := w_i_i + x_i*x_i; w_i_i := R5; */
"mov %[c], #0\n\t"
"ldr r5, [%[wij]]\n\t" /* R5 := w_i_i; */
@@ -1598,6 +1614,7 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
mpi_sub_hlp( n, np, d );
else
mpi_sub_hlp( n, d - n, d - n);
#endif
}
/*
@@ -1632,7 +1649,6 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
* Init temps and window size
*/
mpi_montg_init( &mm, N );
MPI_CHK( mpi_grow( X, N->n ) );
/*
* If 1st call, pre-compute R^2 mod N
@@ -1658,6 +1674,8 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
memset (d, 0, N->n * ciL); /* Set lower half of D zero. */
}
MPI_CHK( mpi_grow( X, N->n ) );
/*
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
*/
@@ -2051,17 +2069,19 @@ jkiss (struct jkiss_state *s)
static int mpi_fill_pseudo_random ( mpi *X, size_t size)
{
int ret;
uint32_t *p;
uint32_t *p, *p_end;
MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
MPI_CHK( mpi_lset( X, 0 ) );
/* Assume little endian. */
p = X->p;
while (p < X->p + (size/ciL))
p = (uint32_t *)X->p;
p_end = (uint32_t *)(X->p + (size/sizeof (uint32_t)));
while (p < p_end)
*p++ = jkiss (&jkiss_state_v);
if ((size % ciL))
*p = jkiss (&jkiss_state_v) & ((1 << (8*(size % ciL))) - 1);
if ((size%sizeof (uint32_t)))
*p = jkiss (&jkiss_state_v) & ((1 << (8*(size % sizeof (uint32_t)))) - 1);
cleanup:
return ret;
@@ -2202,10 +2222,24 @@ cleanup:
* Value M: multiply all primes up to 701 (except 97) and 797
* (so that MAX_A will be convenient value)
*/
#ifdef __LP64__
#define M_LIMBS 16
#else
#define M_LIMBS 31
#endif
#define M_SIZE 122
static const t_uint limbs_M[] = { /* Little endian */
#ifdef __LP64__
0x9344A6AB84EEB59EUL, 0xEC855CDAFF21529FUL,
0x477E991E009BAB38UL, 0x2EEA23579F5B86F3UL,
0xAC17D30441D6502FUL, 0x38FF52B90A468A6DUL,
0x63630419FD42E5EFUL, 0x48CE17D091DB2572UL,
0x708AB00AE3B57D0EUL, 0xF8A9DE08CD723598UL,
0x731411374432C93BUL, 0x554DF2612779FAB3UL,
0xDEEBDA58953D2BA5UL, 0xD1D66F2F5F57D007UL,
0xB85C9607E84E9F2BUL, 0x000000000000401DUL
#else
0x84EEB59E, 0x9344A6AB, 0xFF21529F, 0xEC855CDA,
0x009BAB38, 0x477E991E, 0x9F5B86F3, 0x2EEA2357,
0x41D6502F, 0xAC17D304, 0x0A468A6D, 0x38FF52B9,
@@ -2214,6 +2248,7 @@ static const t_uint limbs_M[] = { /* Little endian */
0x4432C93B, 0x73141137, 0x2779FAB3, 0x554DF261,
0x953D2BA5, 0xDEEBDA58, 0x5F57D007, 0xD1D66F2F,
0xE84E9F2B, 0xB85C9607, 0x0000401D
#endif
};
static const mpi M[1] = {{ 1, M_LIMBS, (t_uint *)limbs_M }};
@@ -2221,10 +2256,18 @@ static const mpi M[1] = {{ 1, M_LIMBS, (t_uint *)limbs_M }};
/*
* MAX_A : 2^1024 / M - 1
*/
#ifdef __LP64__
#define MAX_A_LIMBS 1
#else
#define MAX_A_LIMBS 2
#endif
#define MAX_A_FILL_SIZE 6
static const t_uint limbs_MAX_A[] = { /* Little endian */
#ifdef __LP64__
0x0003FE2556A2B35FUL
#else
0x56A2B35F, 0x0003FE25
#endif
};
static const mpi MAX_A[1] = {{ 1, MAX_A_LIMBS, (t_uint *)limbs_MAX_A }};
@@ -2274,9 +2317,8 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
MPI_CHK ( mpi_mul_mpi ( X, X, M ) );
MPI_CHK ( mpi_add_abs ( X, X, B ) );
if (X->n <= 31 || (X->p[31] & 0xc0000000) == 0)
if (X->n <= M_LIMBS || (X->p[M_LIMBS-1] & 0xc0000000) == 0)
continue;
ret = mpi_is_prime ( X );
if (ret == 0 || ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE)
break;

View File

@@ -39,7 +39,6 @@
#include "polarssl/md.h"
#endif
#include <stdlib.h>
#include <stdio.h>
/*

View File

@@ -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

View File

@@ -1,7 +1,7 @@
/*
* regnual.c -- Firmware installation for STM32F103 Flash ROM
*
* Copyright (C) 2012, 2013, 2015, 2016
* Copyright (C) 2012, 2013, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -365,7 +365,11 @@ main (int argc, char *argv[])
set_led (0);
#if defined(STM32F103_OVERRIDE_FLASH_SIZE_KB)
flash_end = FLASH_START_ADDR + STM32F103_OVERRIDE_FLASH_SIZE_KB*1024;
#else
flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
#endif
/*
* NVIC interrupt priority was set by Gnuk.

View File

@@ -3,6 +3,7 @@ typedef unsigned long size_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned int uintptr_t;
#define TRUE 1
#define FALSE 0

View File

@@ -5,11 +5,8 @@ PROJECT = gnuk
CHOPSTX = ../chopstx
# Define linker script file here
LDSCRIPT= gnuk.ld
CSRC = main.c usb_desc.c usb_ctrl.c \
call-rsa.c \
CSRC = main.c call-rsa.c \
usb_desc.c usb_ctrl.c \
usb-ccid.c openpgp.c ac.c openpgp-do.c flash.c \
bn.c mod.c \
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
@@ -27,12 +24,19 @@ CRYPTSRC = $(CRYPTSRCDIR)/bignum.c $(CRYPTSRCDIR)/rsa.c $(CRYPTSRCDIR)/aes.c
CSRC += $(CRYPTSRC)
INCDIR += $(CRYPTINCDIR)
@PINPAD_MAKE_OPTION@
@DEBUG_MAKE_OPTION@
@HEXOUTPUT_MAKE_OPTION@
include config.mk
USE_SYS = yes
USE_USB = yes
USE_ADC = yes
USE_EVENTFLAG = yes
ifeq ($(EMULATION),)
DEFS += -DFLASH_UPGRADE_SUPPORT
else
DEFS += -DBN256_C_IMPLEMENTATION -DBIGNUM_C_IMPLEMENTATION
endif
ifneq ($(ENABLE_DEBUG),)
CSRC += debug.c
endif
@@ -45,23 +49,17 @@ ifeq ($(ENABLE_PINPAD),dnd)
CSRC += usb-msc.c
endif
CHIP=stm32f103
USE_SYS = yes
USE_USB = yes
USE_ADC = yes
ifeq ($(CHIP),stm32f103)
CSRC += mcu-stm32f103.c
endif
###################################
CROSS = arm-none-eabi-
CC = $(CROSS)gcc
LD = $(CROSS)gcc
OBJCOPY = $(CROSS)objcopy
MCU = cortex-m3
CWARN = -Wall -Wextra -Wstrict-prototypes
# DEFS: Add
DEFS = @USE_SYS3@
OPT = -O3 -Os -g
LIBS =
#######################
include $(CHOPSTX)/rules.mk
@@ -75,5 +73,18 @@ sys.c: board.h
build/bignum.o: OPT = -O3 -g
distclean: clean
-rm -f gnuk.ld config.h board.h Makefile \
-rm -f gnuk.ld config.h board.h config.mk \
usb-strings.c.inc usb-vid-pid-ver.c.inc
ifneq ($(EMULATION),)
# By specifying DESTDIR on invocation of "make", you can install
# program to different ROOT.
# The variables prefix, exec_prefix, libexecdir are defined in
# config.mk.
install: build/gnuk
test -d "$(DESTDIR)$(libexecdir)" || mkdir -p "$(DESTDIR)$(libexecdir)"
install -c build/gnuk "$(DESTDIR)$(libexecdir)"
endif

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,7 +1,7 @@
/*
* call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -24,7 +24,6 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <chopstx.h>
#include "config.h"
@@ -41,7 +40,7 @@ static struct chx_cleanup clp;
static void
rsa_cleanup (void *arg)
{
free (arg);
(void)arg;
rsa_free (&rsa_ctx);
}
@@ -111,28 +110,23 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
/*
* LEN: length in byte
*/
uint8_t *
modulus_calc (const uint8_t *p, int len)
int
modulus_calc (const uint8_t *p, int len, uint8_t *pubkey)
{
mpi P, Q, N;
uint8_t *modulus;
int ret;
modulus = malloc (len);
if (modulus == NULL)
return NULL;
mpi_init (&P); mpi_init (&Q); mpi_init (&N);
MPI_CHK( mpi_read_binary (&P, p, len / 2) );
MPI_CHK( mpi_read_binary (&Q, p + len / 2, len / 2) );
MPI_CHK( mpi_mul_mpi (&N, &P, &Q) );
MPI_CHK( mpi_write_binary (&N, modulus, len) );
MPI_CHK( mpi_write_binary (&N, pubkey, len) );
cleanup:
mpi_free (&P); mpi_free (&Q); mpi_free (&N);
if (ret != 0)
return NULL;
else
return modulus;
return -1;
return 0;
}
@@ -142,6 +136,9 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
{
mpi P1, Q1, H;
int ret;
#ifdef GNU_LINUX_EMULATION
size_t output_len;
#endif
DEBUG_INFO ("RSA decrypt:");
DEBUG_WORD ((uint32_t)&ret);
@@ -177,9 +174,16 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
clp.arg = NULL;
chopstx_cleanup_push (&clp);
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
#ifdef GNU_LINUX_EMULATION
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
RSA_PRIVATE, &output_len, input,
output, MAX_RES_APDU_DATA_SIZE);
*output_len_p = (unsigned int)output_len;
#else
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
RSA_PRIVATE, output_len_p, input,
output, MAX_RES_APDU_DATA_SIZE);
#endif
chopstx_setcancelstate (cs);
chopstx_cleanup_pop (0);
}
@@ -232,54 +236,39 @@ rsa_verify (const uint8_t *pubkey, int pubkey_len,
#define RSA_EXPONENT 0x10001
uint8_t *
rsa_genkey (int pubkey_len)
int
rsa_genkey (int pubkey_len, uint8_t *pubkey, uint8_t *p_q)
{
int ret;
uint8_t index = 0;
uint8_t *p_q_modulus = (uint8_t *)malloc (pubkey_len * 2);
uint8_t *p = p_q_modulus;
uint8_t *q = p_q_modulus + pubkey_len / 2;
uint8_t *modulus = p_q_modulus + pubkey_len;
uint8_t *p = p_q;
uint8_t *q = p_q + pubkey_len / 2;
int cs;
extern int prng_seed (int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
extern void neug_flush (void);
if (p_q_modulus == NULL)
return NULL;
neug_flush ();
prng_seed (random_gen, &index);
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
clp.next = NULL;
clp.routine = rsa_cleanup;
clp.arg = (void *)p_q_modulus;
clp.arg = NULL;
chopstx_cleanup_push (&clp);
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
MPI_CHK( rsa_gen_key (&rsa_ctx, random_gen, &index, pubkey_len * 8,
RSA_EXPONENT) );
if (ret != 0)
{
chopstx_setcancelstate (cs);
chopstx_cleanup_pop (0);
free (p_q_modulus);
rsa_free (&rsa_ctx);
return NULL;
}
MPI_CHK( mpi_write_binary (&rsa_ctx.P, p, pubkey_len / 2) );
MPI_CHK( mpi_write_binary (&rsa_ctx.Q, q, pubkey_len / 2) );
MPI_CHK( mpi_write_binary (&rsa_ctx.N, modulus, pubkey_len) );
MPI_CHK( mpi_write_binary (&rsa_ctx.N, pubkey, pubkey_len) );
cleanup:
chopstx_setcancelstate (cs);
chopstx_cleanup_pop (0);
rsa_free (&rsa_ctx);
chopstx_cleanup_pop (1);
if (ret != 0)
return NULL;
return -1;
else
return p_q_modulus;
return 0;
}

204
src/configure vendored
View File

@@ -6,10 +6,11 @@ nl=$'\n'
#
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
#
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
# Free Software Initiative of Japan
#
# This file is a part of Gnuk, a GnuPG USB Token implementation.
#
# Gnuk is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@@ -36,7 +37,6 @@ fi
help=no
vidpid=none
target=FST_01
verbose=no
with_dfu=default
debug=no
sys1_compat=yes
@@ -44,26 +44,35 @@ pinpad=no
certdo=no
hid_card_change=no
factory_reset=no
flash_override=""
# For emulation
prefix=/usr/local
exec_prefix='${prefix}'
libexecdir='${exec_prefix}/libexec'
# Revision number
if test -e ../.git; then
REVISION=`git describe --dirty="-modified"`
if type git >/dev/null 2>&1; then
REVISION=$(git describe --dirty="-modified")
else
# echo 'No git available, please install git'
GIT_REVISION=$(sed -e 's/^\(.......\).*$/g\1/' "../.git/$(sed -e 's/^ref: //' ../.git/HEAD)")
REVISION=$(cat ../VERSION)-$GIT_REVISION
fi
else
REVISION=`cat ../VERSION`
REVISION=$(cat ../VERSION)
fi
# Process each option
for option; do
case $option in
*=*) optarg=`expr "X$option" : '[^=]*=\(.*\)'` ;;
*=*) optarg=$(expr "X$option" : '[^=]*=\(.*\)') ;;
*) optarg=yes ;;
esac
case $option in
-h | --help)
help=yes ;;
-v | --verbose)
verbose=yes ;;
--vidpid=*)
vidpid=$optarg ;;
--target=*)
@@ -96,6 +105,15 @@ for option; do
with_dfu=yes ;;
--without-dfu)
with_dfu=no ;;
#
# For emulation
#
--prefix=*)
prefix=optarg ;;
--exec-prefix=*)
exec_prefix=optarg ;;
--libexecdir=*)
libexecdir=optarg ;;
*)
echo "Unrecognized option \`$option'" >&2
echo "Try \`$0 --help' for more information." >&2
@@ -118,15 +136,19 @@ Configuration:
FST_01
FST_01G
OLIMEX_STM32_H103
STM32_PRIMER2
STBEE
STBEE_MINI
MAPLE_MINI
ST_DONGLE
ST_NUCLEO_F103
NITROKEY_START
BLUE_PILL
STM8S_DISCOVERY
CQ_STARM
STM32_PRIMER2
STBEE
STBEE_MINI
FST_01_00 (unreleased version with 8MHz XTAL)
--enable-factory-reset
support life cycle management [no]
--enable-debug debug with virtual COM port [no]
--enable-pinpad=cir
PIN entry support [no]
@@ -136,21 +158,14 @@ Configuration:
--disable-sys1-compat disable SYS 1.0 compatibility [no]
executable is target independent
but requires SYS 2.0 or newer
--enable-factory-reset
support life cycle management [no]
--with-dfu build image for DFU [<target specific>]
EOF
exit 0
fi
if test "$vidpid" = "none"; then
echo "Please specify Vendor ID and Product ID by --vidpid option." >&2
exit 1
fi
BOARD_HEADER_FILE=board-`echo $target | tr '_[:upper:]' '-[:lower:]'`.h
echo Header file is: $BOARD_HEADER_FILE
ln -sf ../chopstx/board/$BOARD_HEADER_FILE board.h
BOARD_HEADER_FILE=board-$(echo $target | tr '_[:upper:]' '-[:lower:]').h
echo "Header file is: $BOARD_HEADER_FILE"
ln -sf "../chopstx/board/$BOARD_HEADER_FILE" board.h
# Flash page size in byte
FLASH_PAGE_SIZE=1024
@@ -161,6 +176,10 @@ MEMORY_SIZE=20
# Settings for TARGET
case $target in
BLUE_PILL|STM8S_DISCOVERY)
# It's 64KB version of STM32F103, but actually has 128KB
flash_override="-DSTM32F103_OVERRIDE_FLASH_SIZE_KB=128"
;;
CQ_STARM|STBEE_MINI)
if test "$with_dfu" = "default"; then
with_dfu=yes;
@@ -177,13 +196,45 @@ STBEE)
if test "$with_dfu" = "default"; then
with_dfu=yes;
fi ;;
STM8S_DISCOVERY)
FLASH_SIZE=64
;;
*)
;;
esac
if test "$target" = "GNU_LINUX"; then
ldscript=""
chip="gnu-linux"
emulation="yes"
cross=""
mcu="none"
def_emulation="-DGNU_LINUX_EMULATION"
enable_hexoutput=""
libs="-lpthread"
else
ldscript="gnuk.ld"
chip="stm32f103"
emulation=""
cross="arm-none-eabi-"
mcu="cortex-m3"
def_emulation=""
enable_hexoutput=yes
libs=""
fi
if test "$emulation" = "yes"; then
if test "$vidpid" = "none"; then
vidpid=0000:0000
else
echo "Please don't specify VID:PID for emulation at compile time;"
echo "It is a user who should specify VID:PID at run time."
exit 1
fi
else
if test "$vidpid" = "none"; then
echo "Please specify Vendor ID and Product ID by --vidpid option." >&2
exit 1
fi
fi
# --enable-debug option
if test "$debug" = "yes"; then
DEBUG_MAKE_OPTION="ENABLE_DEBUG=1"
@@ -204,21 +255,16 @@ if test "$with_dfu" = "yes"; then
fi
echo "Configured for DFU"
ORIGIN=0x08003000
FLASH_SIZE=`expr $FLASH_SIZE - 12`
FLASH_SIZE=$((FLASH_SIZE - 12))
DFU_DEFINE="#define DFU_SUPPORT 1"
HEXOUTPUT_MAKE_OPTION="ENABLE_OUTPUT_HEX=yes"
else
with_dfu=no
echo "Configured for bare system (no-DFU)"
ORIGIN=0x08000000
DFU_DEFINE="#undef DFU_SUPPORT"
HEXOUTPUT_MAKE_OPTION=""
fi
# --enable-pinpad option
MSC_SIZE="0"
TIM_SIZE="0"
EXT_SIZE="0"
if test "$pinpad" = "no"; then
PINPAD_MAKE_OPTION="# ENABLE_PINPAD="
PINPAD_DEFINE="#undef PINPAD_SUPPORT"
@@ -229,12 +275,6 @@ else
PINPAD_DEFINE="#define PINPAD_SUPPORT 1"
PINPAD_MORE_DEFINE="#define PINPAD_${pinpad^^[a-z]}_SUPPORT 1"
echo "PIN pad option enabled ($pinpad)"
if test "$pinpad" = "dnd"; then
MSC_SIZE="0x0200"
elif test "$pinpad" = "cir"; then
TIM_SIZE="0x00c0"
EXT_SIZE="0x00c0"
fi
fi
# --enable-certdo option
@@ -265,13 +305,13 @@ else
fi
### !!! Replace following string of "FSIJ" to yours !!! ####
SERIALNO="FSIJ-`cat ../VERSION | sed -e 's%^[^/]*/%%'`-"
SERIALNO="FSIJ-$(sed -e 's%^[^/]*/%%' <../VERSION)-"
SERIALNO_STR_LEN_DEFINE="#define SERIALNO_STR_LEN ${#SERIALNO}"
if test "$sys1_compat" = "yes"; then
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo"
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset"
else
if test "$with_dfu" = "yes"; then
echo "Common binary can't support DFU loader, don't use --with-dfu." >&2
@@ -281,53 +321,58 @@ else
FLASH_PAGE_SIZE=2048
FLASH_SIZE=128
MEMORY_SIZE=20
CONFIG="common:debug=$debug:pinpad=$pinpad:certdo=$certdo"
CONFIG="common:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset"
fi
output_vid_pid_version () {
echo $VIDPID | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\\${nl} 0x\4, 0x\3, /* idProduct */%p"
echo $VERSION | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
echo "$VIDPID" | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\\${nl} 0x\4, 0x\3, /* idProduct */%p"
echo "$VERSION" | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
}
output_vendor_product_serial_strings () {
prefix=$1
name=$1
echo "static const uint8_t ${prefix}string_vendor[] = {"
echo " ${#VENDOR}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo "static const uint8_t ${name}string_vendor[] = {"
echo " ${#VENDOR}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo " /* Manufacturer: \"$VENDOR\" */"
echo $VENDOR | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo "$VENDOR" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo '};'
echo
echo "static const uint8_t ${prefix}string_product[] = {"
echo " ${#PRODUCT}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo "static const uint8_t ${name}string_product[] = {"
echo " ${#PRODUCT}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo " /* Product name: \"$PRODUCT\" */"
echo $PRODUCT | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo "$PRODUCT" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo '};'
if test -n "$prefix"; then
if test -n "$name"; then
echo
echo "const uint8_t ${prefix}string_serial[] = {"
echo " ${#SERIALNO}*2+2+16, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo "const uint8_t ${name}string_serial[] = {"
echo " ${#SERIALNO}*2+2+16, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo " /* Serial number: \"$SERIALNO\" */"
echo $SERIALNO | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
echo "$SERIALNO" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
if test "$emulation" = "yes"; then
echo " 'E', 0, 'M', 0, 'U', 0, 'L', 0,"
echo " 'A', 0, 'T', 0, 'E', 0, 'D', 0,"
else
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
echo " 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,"
fi
echo '};'
echo
echo '#ifdef USB_STRINGS_FOR_GNUK'
echo "static const uint8_t ${prefix}revision_detail[] = {"
echo " ${#REVISION}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo "static const uint8_t ${name}revision_detail[] = {"
echo " ${#REVISION}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo " /* revision detail: \"$REVISION\" */"
echo $REVISION | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo "$REVISION" | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo '};'
echo
echo "static const uint8_t ${prefix}config_options[] = {"
echo " ${#CONFIG}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo "static const uint8_t ${name}config_options[] = {"
echo " ${#CONFIG}*2+2, /* bLength */"
echo " STRING_DESCRIPTOR, /* bDescriptorType */"
echo " /* configure options: \"$CONFIG\" */"
echo $CONFIG | sed -e "s/\(........\)/\1\\${nl}/g" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "/^ ./s/ $//p"
echo '};'
@@ -336,7 +381,7 @@ output_vendor_product_serial_strings () {
}
if !(IFS=" "
while read VIDPID VERSION PRODUCT VENDOR; do
while read -r VIDPID VERSION PRODUCT VENDOR; do
if test "$vidpid" = "$VIDPID"; then
output_vid_pid_version > usb-vid-pid-ver.c.inc
output_vendor_product_serial_strings gnuk_ >usb-strings.c.inc
@@ -344,7 +389,7 @@ if !(IFS=" "
fi
done; exit 1) < ../GNUK_USB_DEVICE_ID
then
echo "Please specify valid Vendor ID and Product ID." >&2
echo "Please specify valid Vendor ID and Product ID." >&2
echo "Check ../GNUK_USB_DEVICE_ID." >&2
exit 1
fi
@@ -361,28 +406,35 @@ else
fi
sed -e "s%@USE_SYS3@%$use_sys3%" \
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
-e "s%@HEXOUTPUT_MAKE_OPTION@%$HEXOUTPUT_MAKE_OPTION%" \
< Makefile.in > Makefile
(echo "CHIP=$chip";
echo "EMULATION=$emulation";
echo "CROSS=$cross";
echo "MCU=$mcu";
echo "DEFS=$use_sys3 $flash_override $def_emulation";
echo "LDSCRIPT=$ldscript";
echo "LIBS=$libs";
echo "$DEBUG_MAKE_OPTION";
echo "$PINPAD_MAKE_OPTION";
echo "ENABLE_FRAUCHEKY=$enable_fraucheky";
echo "ENABLE_OUTPUT_HEX=$enable_hexoutput"
if test "$emulation" = "yes"; then
echo "prefix=$prefix"
echo "exec_prefix=$exec_prefix"
echo "libexecdir=$libexecdir"
fi
) > config.mk
if test "$certdo" = "yes"; then
sed -e "/^@CERTDO_SUPPORT_START@$/ d" -e "/^@CERTDO_SUPPORT_END@$/ d" \
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
-e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
-e "s/@MSC_SIZE@/$MSC_SIZE/" \
-e "s/@TIM_SIZE@/$TIM_SIZE/" \
-e "s/@EXT_SIZE@/$EXT_SIZE/" \
< gnuk.ld.in > gnuk.ld
else
sed -e "/^@CERTDO_SUPPORT_START@$/,/^@CERTDO_SUPPORT_END@$/ d" \
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
-e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
-e "s/@MSC_SIZE@/$MSC_SIZE/" \
-e "s/@TIM_SIZE@/$TIM_SIZE/" \
-e "s/@EXT_SIZE@/$EXT_SIZE/" \
< gnuk.ld.in > gnuk.ld
fi
sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \

View File

@@ -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 }}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -384,7 +384,7 @@ FUNC(check_secret) (const bn256 *d0, bn256 *d1)
{
ac Q0[1], Q1[1];
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) <= 0)
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) != 0)
/* == 0 or >= N, it's not valid. */
return 0;

View File

@@ -1,7 +1,7 @@
/*
* flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -53,24 +53,21 @@
* <alignment to page>
* ch_certificate_startp
* <2048 bytes>
* _data_pool
* <two pages>
* _keystore_pool
* Three flash pages for keystore
* a page contains a key data of:
* For RSA-2048: 512-byte (p, q and N)
* For RSA-4096: 1024-byte (p, q and N)
* For ECDSA/ECDH and EdDSA, there are padding after public key
* _data_pool
* <two pages>
*/
#define FLASH_DATA_POOL_HEADER_SIZE 2
#define FLASH_DATA_POOL_SIZE (flash_page_size*2)
static uint16_t flash_page_size;
static const uint8_t *data_pool;
extern uint8_t _keystore_pool;
static uint8_t *last_p;
/* The first halfword is generation for the data page (little endian) */
@@ -78,8 +75,18 @@ const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
0x00, 0x00, 0xff, 0xff
};
/* Linker set this symbol */
#ifdef GNU_LINUX_EMULATION
extern uint8_t *flash_addr_key_storage_start;
extern uint8_t *flash_addr_data_storage_start;
#define FLASH_ADDR_KEY_STORAGE_START flash_addr_key_storage_start
#define FLASH_ADDR_DATA_STORAGE_START flash_addr_data_storage_start
#else
/* Linker sets these symbols */
extern uint8_t _keystore_pool;
extern uint8_t _data_pool;
#define FLASH_ADDR_KEY_STORAGE_START ((&_keystore_pool))
#define FLASH_ADDR_DATA_STORAGE_START ((&_data_pool))
#endif
static int key_available_at (const uint8_t *k, int key_size)
{
@@ -102,39 +109,45 @@ static int key_available_at (const uint8_t *k, int key_size)
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
const uint8_t *
flash_init (void)
void
flash_do_storage_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
{
uint16_t gen0, gen1;
uint16_t *gen0_p = (uint16_t *)&_data_pool;
uint16_t *gen0_p = (uint16_t *)FLASH_ADDR_DATA_STORAGE_START;
uint16_t *gen1_p;
flash_page_size = 1024;
#if !defined (GNU_LINUX_EMULATION)
if (((*CHIP_ID_REG) & 0xfff) == 0x0414)
flash_page_size = 2048;
#endif
gen1_p = (uint16_t *)(&_data_pool + flash_page_size);
data_pool = &_data_pool;
gen1_p = (uint16_t *)(FLASH_ADDR_DATA_STORAGE_START + flash_page_size);
data_pool = FLASH_ADDR_DATA_STORAGE_START;
/* Check data pool generation and choose the page */
gen0 = *gen0_p;
gen1 = *gen1_p;
if (gen0 == 0xffff && gen1 == 0xffff)
/* It's terminated. */
return NULL;
{
/* It's terminated. */
*p_do_start = *p_do_end = NULL;
return;
}
if (gen0 == 0xffff)
/* Use another page if a page is erased. */
data_pool = &_data_pool + flash_page_size;
data_pool = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
else if (gen1 == 0xffff)
/* Or use different page if another page is erased. */
data_pool = &_data_pool;
data_pool = FLASH_ADDR_DATA_STORAGE_START;
else if ((gen0 == 0xfffe && gen1 == 0) || gen1 > gen0)
/* When both pages have valid header, use newer page. */
data_pool = &_data_pool + flash_page_size;
data_pool = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
return data_pool + FLASH_DATA_POOL_HEADER_SIZE;
*p_do_start = data_pool + FLASH_DATA_POOL_HEADER_SIZE;
*p_do_end = data_pool + flash_page_size;
}
static uint8_t *flash_key_getpage (enum kind_of_key kk);
@@ -145,28 +158,33 @@ flash_terminate (void)
int i;
for (i = 0; i < 3; i++)
flash_erase_page ((uint32_t)flash_key_getpage (i));
flash_erase_page ((uint32_t)&_data_pool);
flash_erase_page ((uint32_t)(&_data_pool + flash_page_size));
data_pool = &_data_pool;
last_p = &_data_pool + FLASH_DATA_POOL_HEADER_SIZE;
flash_erase_page ((uintptr_t)flash_key_getpage (i));
flash_erase_page ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START);
flash_erase_page ((uintptr_t)(FLASH_ADDR_DATA_STORAGE_START + flash_page_size));
data_pool = FLASH_ADDR_DATA_STORAGE_START;
last_p = FLASH_ADDR_DATA_STORAGE_START + FLASH_DATA_POOL_HEADER_SIZE;
#if defined(CERTDO_SUPPORT)
flash_erase_page ((uintptr_t)&ch_certificate_start);
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
flash_erase_page ((uintptr_t)(&ch_certificate_start + flash_page_size));
#endif
}
void
flash_activate (void)
{
flash_program_halfword ((uint32_t)&_data_pool, 0);
flash_program_halfword ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START, 0);
}
void
flash_init_keys (void)
flash_key_storage_init (void)
{
const uint8_t *p;
int i;
/* For each key, find its address. */
p = &_keystore_pool;
p = FLASH_ADDR_KEY_STORAGE_START;
for (i = 0; i < 3; i++)
{
const uint8_t *k;
@@ -224,15 +242,15 @@ flash_copying_gc (void)
uint8_t *src, *dst;
uint16_t generation;
if (data_pool == &_data_pool)
if (data_pool == FLASH_ADDR_DATA_STORAGE_START)
{
src = &_data_pool;
dst = &_data_pool + flash_page_size;
src = FLASH_ADDR_DATA_STORAGE_START;
dst = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
}
else
{
src = &_data_pool + flash_page_size;
dst = &_data_pool;
src = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
dst = FLASH_ADDR_DATA_STORAGE_START;
}
generation = *(uint16_t *)src;
@@ -242,8 +260,8 @@ flash_copying_gc (void)
generation = 0;
else
generation++;
flash_program_halfword ((uint32_t)dst, generation);
flash_erase_page ((uint32_t)src);
flash_program_halfword ((uintptr_t)dst, generation);
flash_erase_page ((uintptr_t)src);
return 0;
}
@@ -273,10 +291,10 @@ void
flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len)
{
uint16_t hw;
uint32_t addr;
uintptr_t addr;
int i;
addr = (uint32_t)p;
addr = (uintptr_t)p;
hw = nr | (len << 8);
if (flash_program_halfword (addr, hw) != 0)
flash_warning ("DO WRITE ERROR");
@@ -329,13 +347,14 @@ flash_warning (const char *msg)
void
flash_do_release (const uint8_t *do_data)
{
uint32_t addr = (uint32_t)do_data - 1;
uint32_t addr_tag = addr;
uintptr_t addr = (uintptr_t)do_data - 1;
uintptr_t addr_tag = addr;
int i;
int len = do_data[0];
/* Don't filling zero for data in code (such as ds_count_initial_value) */
if (do_data < &_data_pool || do_data > &_data_pool + FLASH_DATA_POOL_SIZE)
if (do_data < FLASH_ADDR_DATA_STORAGE_START
|| do_data > FLASH_ADDR_DATA_STORAGE_START + FLASH_DATA_POOL_SIZE)
return;
addr += 2;
@@ -364,7 +383,7 @@ static uint8_t *
flash_key_getpage (enum kind_of_key kk)
{
/* There is a page for each KK. */
return &_keystore_pool + (flash_page_size * kk);
return FLASH_ADDR_KEY_STORAGE_START + (flash_page_size * kk);
}
uint8_t *
@@ -398,10 +417,10 @@ flash_key_write (uint8_t *key_addr,
const uint8_t *pubkey, int pubkey_len)
{
uint16_t hw;
uint32_t addr;
uintptr_t addr;
int i;
addr = (uint32_t)key_addr;
addr = (uintptr_t)key_addr;
for (i = 0; i < key_data_len/2; i ++)
{
hw = key_data[i*2] | (key_data[i*2+1]<<8);
@@ -424,7 +443,7 @@ flash_key_write (uint8_t *key_addr,
static int
flash_check_all_other_keys_released (const uint8_t *key_addr, int key_size)
{
uint32_t start = (uint32_t)key_addr & ~(flash_page_size - 1);
uintptr_t start = (uintptr_t)key_addr & ~(flash_page_size - 1);
const uint32_t *p = (const uint32_t *)start;
while (p < (const uint32_t *)(start + flash_page_size))
@@ -443,7 +462,7 @@ static void
flash_key_fill_zero_as_released (uint8_t *key_addr, int key_size)
{
int i;
uint32_t addr = (uint32_t)key_addr;
uintptr_t addr = (uintptr_t)key_addr;
for (i = 0; i < key_size/2; i++)
flash_program_halfword (addr + i*2, 0);
@@ -453,7 +472,7 @@ void
flash_key_release (uint8_t *key_addr, int key_size)
{
if (flash_check_all_other_keys_released (key_addr, key_size))
flash_erase_page (((uint32_t)key_addr & ~(flash_page_size - 1)));
flash_erase_page (((uintptr_t)key_addr & ~(flash_page_size - 1)));
else
flash_key_fill_zero_as_released (key_addr, key_size);
}
@@ -461,12 +480,12 @@ flash_key_release (uint8_t *key_addr, int key_size)
void
flash_key_release_page (enum kind_of_key kk)
{
flash_erase_page ((uint32_t)flash_key_getpage (kk));
flash_erase_page ((uintptr_t)flash_key_getpage (kk));
}
void
flash_clear_halfword (uint32_t addr)
flash_clear_halfword (uintptr_t addr)
{
flash_program_halfword (addr, 0);
}
@@ -475,7 +494,7 @@ flash_clear_halfword (uint32_t addr)
void
flash_put_data_internal (const uint8_t *p, uint16_t hw)
{
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
}
void
@@ -489,7 +508,7 @@ flash_put_data (uint16_t hw)
DEBUG_INFO ("data allocation failure.\r\n");
}
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
}
@@ -501,14 +520,14 @@ flash_bool_clear (const uint8_t **addr_p)
if ((p = *addr_p) == NULL)
return;
flash_program_halfword ((uint32_t)p, 0);
flash_program_halfword ((uintptr_t)p, 0);
*addr_p = NULL;
}
void
flash_bool_write_internal (const uint8_t *p, int nr)
{
flash_program_halfword ((uint32_t)p, nr);
flash_program_halfword ((uintptr_t)p, nr);
}
const uint8_t *
@@ -524,7 +543,7 @@ flash_bool_write (uint8_t nr)
return NULL;
}
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
return p;
}
@@ -540,7 +559,7 @@ flash_enum_write_internal (const uint8_t *p, int nr, uint8_t v)
{
uint16_t hw = nr | (v << 8);
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
}
const uint8_t *
@@ -556,7 +575,7 @@ flash_enum_write (uint8_t nr, uint8_t v)
return NULL;
}
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
return p;
}
@@ -592,14 +611,14 @@ flash_cnt123_write_internal (const uint8_t *p, int which, int v)
uint16_t hw;
hw = NR_COUNTER_123 | (which << 8);
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
if (v == 1)
return;
else if (v == 2)
flash_program_halfword ((uint32_t)p+2, 0xc3c3);
flash_program_halfword ((uintptr_t)p+2, 0xc3c3);
else /* v == 3 */
flash_program_halfword ((uint32_t)p+2, 0);
flash_program_halfword ((uintptr_t)p+2, 0);
}
void
@@ -617,7 +636,7 @@ flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
return;
}
hw = NR_COUNTER_123 | (which << 8);
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
*addr_p = p + 2;
}
else
@@ -632,7 +651,7 @@ flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
else
hw = 0;
flash_program_halfword ((uint32_t)p, hw);
flash_program_halfword ((uintptr_t)p, hw);
}
}
@@ -644,9 +663,9 @@ flash_cnt123_clear (const uint8_t **addr_p)
if ((p = *addr_p) == NULL)
return;
flash_program_halfword ((uint32_t)p, 0);
flash_program_halfword ((uintptr_t)p, 0);
p -= 2;
flash_program_halfword ((uint32_t)p, 0);
flash_program_halfword ((uintptr_t)p, 0);
*addr_p = NULL;
}
@@ -660,9 +679,9 @@ flash_erase_binary (uint8_t file_id)
const uint8_t *p = &ch_certificate_start;
if (flash_check_blank (p, FLASH_CH_CERTIFICATE_SIZE) == 0)
{
flash_erase_page ((uint32_t)p);
flash_erase_page ((uintptr_t)p);
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
flash_erase_page ((uint32_t)p + flash_page_size);
flash_erase_page ((uintptr_t)p + flash_page_size);
}
return 0;
@@ -685,17 +704,19 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
maxsize = 6;
p = &openpgpcard_aid[8];
}
#ifdef FLASH_UPGRADE_SUPPORT
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
{
maxsize = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
if (len == 0 && offset == 0)
{ /* This means removal of update key. */
if (flash_program_halfword ((uint32_t)p, 0) != 0)
if (flash_program_halfword ((uintptr_t)p, 0) != 0)
flash_warning ("DO WRITE ERROR");
return 0;
}
}
#endif
#if defined(CERTDO_SUPPORT)
else if (file_id == FILEID_CH_CERTIFICATE)
{
@@ -711,13 +732,13 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
else
{
uint16_t hw;
uint32_t addr;
uintptr_t addr;
int i;
if (flash_check_blank (p + offset, len) == 0)
return -1;
addr = (uint32_t)p + offset;
addr = (uintptr_t)p + offset;
for (i = 0; i < len/2; i++)
{
hw = data[i*2] | (data[i*2+1]<<8);

16
src/gnuk-malloc.h Normal file
View 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 *);

View File

@@ -106,13 +106,13 @@ extern uint16_t data_objects_number_of_bytes;
#define CHALLENGE_LEN 32
void gpg_data_scan (const uint8_t *p);
void gpg_data_scan (const uint8_t *start, const uint8_t *end);
void gpg_data_copy (const uint8_t *p);
void gpg_do_terminate (void);
void gpg_do_get_data (uint16_t tag, int with_tag);
void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
void gpg_do_public_key (uint8_t kk_byte);
void gpg_do_keygen (uint8_t kk_byte);
void gpg_do_keygen (uint8_t *buf);
const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
@@ -139,10 +139,10 @@ enum size_of_key {
int gpg_get_algo_attr (enum kind_of_key kk);
int gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s);
const uint8_t *flash_init (void);
void flash_do_storage_init (const uint8_t **, const uint8_t **);
void flash_terminate (void);
void flash_activate (void);
void flash_init_keys (void);
void flash_key_storage_init (void);
void flash_do_release (const uint8_t *);
const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
uint8_t *flash_key_alloc (enum kind_of_key);
@@ -152,7 +152,7 @@ int flash_key_write (uint8_t *key_addr,
const uint8_t *key_data, int key_data_len,
const uint8_t *pubkey, int pubkey_len);
void flash_set_data_pool_last (const uint8_t *p);
void flash_clear_halfword (uint32_t addr);
void flash_clear_halfword (uintptr_t addr);
void flash_increment_counter (uint8_t counter_tag_nr);
void flash_reset_counter (uint8_t counter_tag_nr);
@@ -265,22 +265,22 @@ void put_binary (const char *s, int len);
#endif
int rsa_sign (const uint8_t *, uint8_t *, int, struct key_data *, int);
uint8_t *modulus_calc (const uint8_t *, int);
int modulus_calc (const uint8_t *, int, uint8_t *);
int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *,
unsigned int *);
int rsa_verify (const uint8_t *, int, const uint8_t *, const uint8_t *);
uint8_t *rsa_genkey (int);
int rsa_genkey (int, uint8_t *, uint8_t *);
int ecdsa_sign_p256r1 (const uint8_t *hash, uint8_t *output,
const uint8_t *key_data);
uint8_t *ecc_compute_public_p256r1 (const uint8_t *key_data);
int ecc_compute_public_p256r1 (const uint8_t *key_data, uint8_t *);
int ecc_check_secret_p256r1 (const uint8_t *d0, uint8_t *d1);
int ecdh_decrypt_p256r1 (const uint8_t *input, uint8_t *output,
const uint8_t *key_data);
int ecdsa_sign_p256k1 (const uint8_t *hash, uint8_t *output,
const uint8_t *key_data);
uint8_t *ecc_compute_public_p256k1 (const uint8_t *key_data);
int ecc_compute_public_p256k1 (const uint8_t *key_data, uint8_t *);
int ecc_check_secret_p256k1 (const uint8_t *d0, uint8_t *d1);
int ecdh_decrypt_p256k1 (const uint8_t *input, uint8_t *output,
const uint8_t *key_data);
@@ -288,8 +288,8 @@ int ecdh_decrypt_p256k1 (const uint8_t *input, uint8_t *output,
int eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *output,
const uint8_t *sk_a, const uint8_t *seed,
const uint8_t *pk);
uint8_t *eddsa_compute_public_25519 (const uint8_t *a);
uint8_t *ecdh_compute_public_25519 (const uint8_t *a);
void eddsa_compute_public_25519 (const uint8_t *a, uint8_t *);
void ecdh_compute_public_25519 (const uint8_t *a, uint8_t *);
int ecdh_decrypt_curve25519 (const uint8_t *input, uint8_t *output,
const uint8_t *key_data);
@@ -301,6 +301,7 @@ void gpg_increment_digital_signature_counter (void);
void fatal (uint8_t code) __attribute__ ((noreturn));
#define FATAL_FLASH 1
#define FATAL_RANDOM 2
#define FATAL_HEAP 3
extern uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
extern uint8_t admin_authorized;
@@ -459,3 +460,5 @@ int pinpad_getline (int msg_code, uint32_t timeout_usec);
#endif
extern uint8_t _regnual_start, __heap_end__[];
uint8_t * sram_address (uint32_t offset);

View File

@@ -1,16 +1,6 @@
/*
* ST32F103 memory setup.
*/
__main_stack_size__ = 0x0080; /* Exception handlers */
__process0_stack_size__ = 0x0100; /* main */
__process1_stack_size__ = 0x0180; /* ccid */
__process2_stack_size__ = 0x0180; /* rng */
__process3_stack_size__ = 0x1640; /* gpg */
__process4_stack_size__ = 0; /* --- */
__process5_stack_size__ = @MSC_SIZE@; /* msc */
__process6_stack_size__ = @TIM_SIZE@; /* intr: timer */
__process7_stack_size__ = @EXT_SIZE@; /* intr: ext */
MEMORY
{
flash0 : org = @ORIGIN@, len = 4k
@@ -82,45 +72,18 @@ SECTIONS
_etext = .;
_textdata = _etext;
.stacks :
.stacks (NOLOAD) :
{
. = ALIGN(8);
__main_stack_base__ = .;
. += __main_stack_size__;
. = ALIGN(8);
__main_stack_end__ = .;
__process0_stack_base__ = .;
. += __process0_stack_size__;
. = ALIGN(8);
__process0_stack_end__ = .;
__process1_stack_base__ = .;
. += __process1_stack_size__;
. = ALIGN(8);
__process1_stack_end__ = .;
__process2_stack_base__ = .;
. += __process2_stack_size__;
. = ALIGN(8);
__process2_stack_end__ = .;
__process3_stack_base__ = .;
. += __process3_stack_size__;
. = ALIGN(8);
__process3_stack_end__ = .;
__process4_stack_base__ = .;
. += __process4_stack_size__;
. = ALIGN(8);
__process4_stack_end__ = .;
__process5_stack_base__ = .;
. += __process5_stack_size__;
. = ALIGN(8);
__process5_stack_end__ = .;
__process6_stack_base__ = .;
. += __process6_stack_size__;
. = ALIGN(8);
__process6_stack_end__ = .;
__process7_stack_base__ = .;
. += __process7_stack_size__;
. = ALIGN(8);
__process7_stack_end__ = .;
*(.main_stack)
*(.process_stack.0)
*(.process_stack.1)
*(.process_stack.2)
*(.process_stack.3)
*(.process_stack.4)
*(.process_stack.5)
*(.process_stack.6)
*(.process_stack.7)
. = ALIGN(8);
} > ram
@@ -171,10 +134,6 @@ SECTIONS
.gnuk_flash :
{
. = ALIGN (@FLASH_PAGE_SIZE@);
_data_pool = .;
KEEP(*(.gnuk_data))
. = ALIGN(@FLASH_PAGE_SIZE@);
. += @FLASH_PAGE_SIZE@;
_keystore_pool = .;
. += 512;
. = ALIGN(@FLASH_PAGE_SIZE@);
@@ -185,6 +144,10 @@ SECTIONS
_updatekey_store = .;
. += 1024;
. = ALIGN(@FLASH_PAGE_SIZE@);
_data_pool = .;
KEEP(*(.gnuk_data))
. = ALIGN(@FLASH_PAGE_SIZE@);
. += @FLASH_PAGE_SIZE@;
} > flash =0xffffffff
}

View File

@@ -1,7 +1,7 @@
/*
* main.c - main routine of Gnuk
*
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -35,8 +35,13 @@
#include "usb_lld.h"
#include "usb-cdc.h"
#include "random.h"
#ifdef GNU_LINUX_EMULATION
#include <stdio.h>
#include <stdlib.h>
#define main emulated_main
#else
#include "mcu/stm32f103.h"
#endif
/*
* main thread does 1-bit LED display output
@@ -47,6 +52,10 @@
#define LED_TIMEOUT_STOP (200*1000)
#ifdef GNU_LINUX_EMULATION
uint8_t *flash_addr_key_storage_start;
uint8_t *flash_addr_data_storage_start;
#else
#define ID_OFFSET (2+SERIALNO_STR_LEN*2)
static void
device_initialize_once (void)
@@ -76,6 +85,7 @@ device_initialize_once (void)
}
}
}
#endif
static volatile uint8_t fatal_code;
@@ -167,26 +177,30 @@ led_blink (int spec)
eventflag_signal (&led_event, spec);
}
#ifdef FLASH_UPGRADE_SUPPORT
/*
* In Gnuk 1.0.[12], reGNUal was not relocatable.
* Now, it's relocatable, but we need to calculate its entry address
* based on it's pre-defined address.
*/
#define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
static uint32_t
static uintptr_t
calculate_regnual_entry_address (const uint8_t *addr)
{
const uint8_t *p = addr + 4;
uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
uintptr_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
v -= REGNUAL_START_ADDRESS_COMPATIBLE;
v += (uint32_t)addr;
v += (uintptr_t)addr;
return v;
}
#endif
extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
#define STACK_ADDR_CCID ((uint32_t)__process1_stack_base__)
#define STACK_SIZE_CCID ((uint32_t)__process1_stack_size__)
#define STACK_MAIN
#define STACK_PROCESS_1
#include "stack-def.h"
#define STACK_ADDR_CCID ((uintptr_t)process1_base)
#define STACK_SIZE_CCID (sizeof process1_base)
#define PRIO_CCID 3
#define PRIO_MAIN 5
@@ -202,18 +216,94 @@ extern uint32_t bDeviceState;
* Entry point.
*/
int
main (int argc, char *argv[])
main (int argc, const char *argv[])
{
uint32_t entry;
#ifdef GNU_LINUX_EMULATION
uintptr_t flash_addr;
const char *flash_image_path;
char *path_string = NULL;
#endif
#ifdef FLASH_UPGRADE_SUPPORT
uintptr_t entry;
#endif
chopstx_t ccid_thd;
(void)argc;
(void)argv;
gnuk_malloc_init ();
#ifdef GNU_LINUX_EMULATION
#define FLASH_IMAGE_NAME ".gnuk-flash-image"
if (argc >= 4 || (argc == 2 && !strcmp (argv[1], "--help")))
{
fprintf (stdout, "Usage: %s [--vidpid=Vxxx:Pxxx] [flash-image-file]",
argv[0]);
exit (0);
}
if (argc >= 2 && !strncmp (argv[1], "--debug=", 8))
{
debug = strtol (&argv[1][8], NULL, 10);
argc--;
argv++;
}
if (argc >= 2 && !strncmp (argv[1], "--vidpid=", 9))
{
extern uint8_t device_desc[];
uint32_t id;
char *p;
id = (uint32_t)strtol (&argv[1][9], &p, 16);
device_desc[8] = (id & 0xff);
device_desc[9] = (id >> 8);
if (p && p[0] == ':')
{
id = (uint32_t)strtol (&p[1], NULL, 16);
device_desc[10] = (id & 0xff);
device_desc[11] = (id >> 8);
}
argc--;
argv++;
}
if (argc == 1)
{
char *p = getenv ("HOME");
if (p == NULL)
{
fprintf (stderr, "Can't find $HOME\n");
exit (1);
}
path_string = malloc (strlen (p) + strlen (FLASH_IMAGE_NAME) + 2);
p = stpcpy (path_string, p);
*p++ = '/';
strcpy (p, FLASH_IMAGE_NAME);
flash_image_path = path_string;
}
else
flash_image_path = argv[1];
flash_addr = flash_init (flash_image_path);
flash_addr_key_storage_start = (uint8_t *)flash_addr;
flash_addr_data_storage_start = (uint8_t *)flash_addr + 4096;
#else
(void)argc;
(void)argv;
#endif
flash_unlock ();
#ifdef GNU_LINUX_EMULATION
if (path_string)
free (path_string);
#else
device_initialize_once ();
#endif
adc_init ();
@@ -285,8 +375,9 @@ main (int argc, char *argv[])
/* Finish application. */
chopstx_join (ccid_thd, NULL);
#ifdef FLASH_UPGRADE_SUPPORT
/* Set vector */
SCB->VTOR = (uint32_t)&_regnual_start;
SCB->VTOR = (uintptr_t)&_regnual_start;
entry = calculate_regnual_entry_address (&_regnual_start);
#ifdef DFU_SUPPORT
#define FLASH_SYS_START_ADDR 0x08000000
@@ -294,12 +385,12 @@ main (int argc, char *argv[])
#define CHIP_ID_REG ((uint32_t *)0xE0042000)
{
extern uint8_t _sys;
uint32_t addr;
uintptr_t addr;
handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
uint32_t flash_page_size = 1024; /* 1KiB default */
if ((*CHIP_ID_ADDR)&0x07 == 0x04) /* High dencity device. */
if ((*CHIP_ID_REG)&0x07 == 0x04) /* High dencity device. */
flash_page_size = 2048; /* It's 2KiB. */
/* Kill DFU */
@@ -318,6 +409,9 @@ main (int argc, char *argv[])
/* Leave Gnuk to exec reGNUal */
flash_erase_all_and_exec ((void (*)(void))entry);
#endif
#else
exit (0);
#endif
/* Never reached */
return 0;
@@ -348,30 +442,46 @@ fatal (uint8_t code)
* reclaimed to system.
*/
#ifdef GNU_LINUX_EMULATION
#define MEMORY_SIZE (32*1024)
uint8_t __heap_base__[MEMORY_SIZE];
#define HEAP_START __heap_base__
#define MEMORY_END (__heap_base__ + MEMORY_SIZE)
#define MEMORY_ALIGNMENT 32
#else
extern uint8_t __heap_base__[];
extern uint8_t __heap_end__[];
#define HEAP_START __heap_base__
#define MEMORY_END (__heap_end__)
#define MEMORY_ALIGNMENT 16
#define MEMORY_SIZE ((uintptr_t)__heap_end__ - (uintptr_t)__heap_base__)
#endif
#define MEMORY_ALIGN(n) (((n) + MEMORY_ALIGNMENT - 1) & ~(MEMORY_ALIGNMENT - 1))
static uint8_t *heap_p;
static chopstx_mutex_t malloc_mtx;
struct mem_head {
uint32_t size;
uintptr_t size;
/**/
struct mem_head *next, *prev; /* free list chain */
struct mem_head *neighbor; /* backlink to neighbor */
};
#define MEM_HEAD_IS_CORRUPT(x) \
((x)->size != MEMORY_ALIGN((x)->size) || (x)->size > MEMORY_SIZE)
#define MEM_HEAD_CHECK(x) if (MEM_HEAD_IS_CORRUPT(x)) fatal (FATAL_HEAP)
static struct mem_head *free_list;
static void
gnuk_malloc_init (void)
{
chopstx_mutex_init (&malloc_mtx);
heap_p = __heap_base__;
heap_p = HEAP_START;
free_list = NULL;
}
@@ -405,7 +515,7 @@ gnuk_malloc (size_t size)
struct mem_head *m;
struct mem_head *m0;
size = MEMORY_ALIGN (size + sizeof (uint32_t));
size = MEMORY_ALIGN (size + sizeof (uintptr_t));
chopstx_mutex_lock (&malloc_mtx);
DEBUG_INFO ("malloc: ");
@@ -421,7 +531,7 @@ gnuk_malloc (size_t size)
m->size = size;
break;
}
MEM_HEAD_CHECK (m);
if (m->size == size)
{
remove_from_free_list (m);
@@ -445,8 +555,8 @@ gnuk_malloc (size_t size)
}
else
{
DEBUG_WORD ((uint32_t)m + sizeof (uint32_t));
return (void *)m + sizeof (uint32_t);
DEBUG_WORD ((uintptr_t)m + sizeof (uintptr_t));
return (void *)m + sizeof (uintptr_t);
}
}
@@ -454,18 +564,23 @@ gnuk_malloc (size_t size)
void
gnuk_free (void *p)
{
struct mem_head *m = (struct mem_head *)((void *)p - sizeof (uint32_t));
struct mem_head *m = (struct mem_head *)((void *)p - sizeof (uintptr_t));
struct mem_head *m0;
if (p == NULL)
return;
chopstx_mutex_lock (&malloc_mtx);
m0 = free_list;
DEBUG_INFO ("free: ");
DEBUG_SHORT (m->size);
DEBUG_WORD ((uint32_t)p);
DEBUG_WORD ((uintptr_t)p);
MEM_HEAD_CHECK (m);
m->neighbor = NULL;
while (m0)
{
MEM_HEAD_CHECK (m0);
if ((void *)m + m->size == (void *)m0)
m0->neighbor = m;
else if ((void *)m0 + m0->size == (void *)m)
@@ -481,6 +596,7 @@ gnuk_free (void *p)
heap_p -= m->size;
while (mn)
{
MEM_HEAD_CHECK (mn);
heap_p -= mn->size;
remove_from_free_list (mn);
mn = mn->neighbor;

32
src/mcu-stm32f103.c Normal file
View File

@@ -0,0 +1,32 @@
/*
* mcu-stm32f103.c - STM32F103 specific routines
*
* Copyright (C) 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
*
* Gnuk is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include "mcu/stm32f103.h"
uint8_t *
sram_address (uint32_t offset)
{
return ((uint8_t *)0x20000000) + offset;
}

View File

@@ -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));

View File

@@ -1,7 +1,7 @@
/*
* neug.c - true random number generation
*
* Copyright (C) 2011, 2012, 2013, 2016
* Copyright (C) 2011, 2012, 2013, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -29,10 +29,122 @@
#include "sys.h"
#include "neug.h"
#ifndef GNU_LINUX_EMULATION
#include "mcu/stm32f103.h"
#endif
#include "adc.h"
#include "sha256.h"
#ifdef GNU_LINUX_EMULATION
static const uint32_t crc32_rv_table[256] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
static uint32_t crc;
void
crc32_rv_reset (void)
{
crc = 0xffffffff;
}
void
crc32_rv_step (uint32_t v)
{
crc = crc32_rv_table[(crc ^ (v << 0)) >> 24] ^ (crc << 8);
crc = crc32_rv_table[(crc ^ (v << 8)) >> 24] ^ (crc << 8);
crc = crc32_rv_table[(crc ^ (v << 16)) >> 24] ^ (crc << 8);
crc = crc32_rv_table[(crc ^ (v << 24)) >> 24] ^ (crc << 8);
}
uint32_t
crc32_rv_get (void)
{
return crc;
}
uint32_t
rbit (uint32_t v)
{
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
v = ( v >> 16 ) | ( v << 16);
return v;
}
#else
void
crc32_rv_reset (void)
{
RCC->AHBENR |= RCC_AHBENR_CRCEN;
CRC->CR = CRC_CR_RESET;
}
void
crc32_rv_step (uint32_t v)
{
CRC->DR = v;
}
uint32_t
crc32_rv_get (void)
{
return CRC->DR;
}
uint32_t
rbit (uint32_t v)
{
uint32_t r;
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
return r;
}
#endif
static chopstx_mutex_t mode_mtx;
static chopstx_cond_t mode_cond;
@@ -94,11 +206,11 @@ static void noise_source_continuous_test_word (uint8_t b0, uint8_t b1,
* Then, three-byte from noise source follows.
*
* One-byte was used in the previous turn, and we have three bytes in
* CRC->DR.
* CRC32.
*/
static void ep_fill_initial_string (void)
{
uint32_t v = CRC->DR;
uint32_t v = crc32_rv_get ();
uint8_t b1, b2, b3;
b3 = v >> 24;
@@ -164,11 +276,11 @@ static int ep_process (int mode)
sha256_ctx_data.wbuf[1] = adc_buf[1];
for (i = 0; i < EP_ROUND_0_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
CRC->DR = adc_buf[i*4 + 4];
CRC->DR = adc_buf[i*4 + 5];
v = CRC->DR;
crc32_rv_step (adc_buf[i*4 + 2]);
crc32_rv_step (adc_buf[i*4 + 3]);
crc32_rv_step (adc_buf[i*4 + 4]);
crc32_rv_step (adc_buf[i*4 + 5]);
v = crc32_rv_get ();
ep_fill_wbuf_v (i+2, 1, v);
}
@@ -181,11 +293,11 @@ static int ep_process (int mode)
{
for (i = 0; i < EP_ROUND_1_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
crc32_rv_step (adc_buf[i*4]);
crc32_rv_step (adc_buf[i*4 + 1]);
crc32_rv_step (adc_buf[i*4 + 2]);
crc32_rv_step (adc_buf[i*4 + 3]);
v = crc32_rv_get ();
ep_fill_wbuf_v (i, 1, v);
}
@@ -198,23 +310,23 @@ static int ep_process (int mode)
{
for (i = 0; i < EP_ROUND_2_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
crc32_rv_step (adc_buf[i*4]);
crc32_rv_step (adc_buf[i*4 + 1]);
crc32_rv_step (adc_buf[i*4 + 2]);
crc32_rv_step (adc_buf[i*4 + 3]);
v = crc32_rv_get ();
ep_fill_wbuf_v (i, 1, v);
}
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR & 0xff; /* First byte of CRC->DR is used here. */
crc32_rv_step (adc_buf[i*4]);
crc32_rv_step (adc_buf[i*4 + 1]);
crc32_rv_step (adc_buf[i*4 + 2]);
crc32_rv_step (adc_buf[i*4 + 3]);
v = crc32_rv_get () & 0xff; /* First byte of CRC32 is used here. */
noise_source_continuous_test (v);
sha256_ctx_data.wbuf[i] = v;
ep_init (NEUG_MODE_CONDITIONED); /* The rest three-byte of
CRC->DR is used here. */
CRC32 is used here. */
n = SHA256_DIGEST_SIZE / 2;
memcpy (((uint8_t *)sha256_ctx_data.wbuf) + EP_ROUND_2_INPUTS,
sha256_output, n);
@@ -226,11 +338,11 @@ static int ep_process (int mode)
{
for (i = 0; i < EP_ROUND_RAW_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
crc32_rv_step (adc_buf[i*4]);
crc32_rv_step (adc_buf[i*4 + 1]);
crc32_rv_step (adc_buf[i*4 + 2]);
crc32_rv_step (adc_buf[i*4 + 3]);
v = crc32_rv_get ();
ep_fill_wbuf_v (i, 1, v);
}
@@ -640,9 +752,11 @@ rng (void *arg)
static struct rng_rb the_ring_buffer;
extern uint8_t __process2_stack_base__[], __process2_stack_size__[];
#define STACK_ADDR_RNG ((uint32_t)__process2_stack_base__)
#define STACK_SIZE_RNG ((uint32_t)__process2_stack_size__)
#define STACK_PROCESS_2
#include "stack-def.h"
#define STACK_ADDR_RNG ((uintptr_t)process2_base)
#define STACK_SIZE_RNG (sizeof process2_base)
#define PRIO_RNG 2
/**
@@ -655,15 +769,14 @@ neug_init (uint32_t *buf, uint8_t size)
struct rng_rb *rb = &the_ring_buffer;
int i;
RCC->AHBENR |= RCC_AHBENR_CRCEN;
CRC->CR = CRC_CR_RESET;
crc32_rv_reset ();
/*
* This initialization ensures that it generates different sequence
* even if all physical conditions are same.
*/
for (i = 0; i < 3; i++)
CRC->DR = *u++;
crc32_rv_step (*u++);
neug_mode = NEUG_MODE_CONDITIONED;
rb_init (rb, buf, size);

View File

@@ -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);

View File

@@ -1,7 +1,7 @@
/*
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -24,7 +24,6 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "config.h"
@@ -40,7 +39,7 @@
#define CLEAN_PAGE_FULL 1
#define CLEAN_SINGLE 0
static void gpg_do_delete_prvkey (enum kind_of_key kk, int clean_page_full);
static void gpg_reset_digital_signature_counter (void);
#define PASSWORD_ERRORS_MAX 3 /* >= errors, it will be locked */
static const uint8_t *pw_err_counter_p[3];
@@ -250,6 +249,28 @@ gpg_get_algo_attr (enum kind_of_key kk)
return algo_attr_p[1];
}
static void
gpg_reset_algo_attr (enum kind_of_key kk)
{
gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
if (kk == GPG_KEY_FOR_SIGNING)
{
gpg_reset_digital_signature_counter ();
gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0);
}
else if (kk == GPG_KEY_FOR_DECRYPTION)
{
gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0);
}
else
{
gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0);
}
}
static const uint8_t *
get_algo_attr_data_object (enum kind_of_key kk)
{
@@ -336,7 +357,7 @@ gpg_write_digital_signature_counter (const uint8_t *p, uint32_t dsc)
else
{
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
hw1 = NR_COUNTER_DS_LSB;
hw1 = NR_COUNTER_DS_LSB | ((dsc & 0x0300) >> 8) | ((dsc & 0x00ff) << 8);
flash_put_data_internal (p, hw0);
flash_put_data_internal (p+2, hw1);
return p+4;
@@ -749,47 +770,15 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
return 0; /* Error. */
else if (algo == ALGO_RSA2K && *algo_attr_pp != NULL)
{
gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
gpg_reset_algo_attr (kk);
flash_enum_clear (algo_attr_pp);
if (kk == GPG_KEY_FOR_SIGNING)
{
gpg_reset_digital_signature_counter ();
gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0);
}
else if (kk == GPG_KEY_FOR_DECRYPTION)
{
gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0);
}
else
{
gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0);
}
if (*algo_attr_pp != NULL)
return 0;
}
else if ((algo != ALGO_RSA2K && *algo_attr_pp == NULL)
|| (*algo_attr_pp)[1] != algo)
else if ((algo != ALGO_RSA2K && *algo_attr_pp == NULL) ||
(*algo_attr_pp != NULL && (*algo_attr_pp)[1] != algo))
{
gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
if (kk == GPG_KEY_FOR_SIGNING)
{
gpg_reset_digital_signature_counter ();
gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0);
}
else if (kk == GPG_KEY_FOR_DECRYPTION)
{
gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0);
}
else
{
gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0);
gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0);
}
gpg_reset_algo_attr (kk);
*algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo);
if (*algo_attr_pp == NULL)
return 0;
@@ -858,7 +847,7 @@ encrypt (const uint8_t *key, const uint8_t *iv, uint8_t *data, int len)
{
aes_context aes;
uint8_t iv0[INITIAL_VECTOR_SIZE];
unsigned int iv_offset;
size_t iv_offset;
DEBUG_INFO ("ENC\r\n");
DEBUG_BINARY (data, len);
@@ -877,7 +866,7 @@ decrypt (const uint8_t *key, const uint8_t *iv, uint8_t *data, int len)
{
aes_context aes;
uint8_t iv0[INITIAL_VECTOR_SIZE];
unsigned int iv_offset;
size_t iv_offset;
aes_setkey_enc (&aes, key, 128); /* This is setkey_enc, because of CFB. */
memcpy (iv0, iv, INITIAL_VECTOR_SIZE);
@@ -1093,11 +1082,11 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
int attr = gpg_get_algo_attr (kk);;
const uint8_t *p;
int r;
struct prvkey_data *pd;
struct prvkey_data prv;
struct prvkey_data *pd = &prv;
uint8_t *key_addr;
const uint8_t *dek, *iv;
struct key_data_internal kdi;
uint8_t *pubkey_allocated_here = NULL;
int pubkey_len;
uint8_t ks[KEYSTRING_MD_SIZE];
enum kind_of_key kk0;
@@ -1108,10 +1097,6 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
/* Delete it first, if any. */
gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
pd = (struct prvkey_data *)malloc (sizeof (struct prvkey_data));
if (pd == NULL)
return -1;
if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
{
pubkey_len = prvkey_len * 2;
@@ -1139,38 +1124,11 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
return -1;
}
if (pubkey == NULL)
{
if (attr == ALGO_SECP256K1)
pubkey_allocated_here = ecc_compute_public_p256k1 (key_data);
else if (attr == ALGO_NISTP256R1)
pubkey_allocated_here = ecc_compute_public_p256r1 (key_data);
else if (attr == ALGO_ED25519)
pubkey_allocated_here = eddsa_compute_public_25519 (key_data);
else if (attr == ALGO_CURVE25519)
pubkey_allocated_here = ecdh_compute_public_25519 (key_data);
else /* RSA */
pubkey_allocated_here = modulus_calc (key_data, prvkey_len);
if (pubkey_allocated_here == NULL)
{
free (pd);
return -1;
}
}
DEBUG_INFO ("Getting keystore address...\r\n");
key_addr = flash_key_alloc (kk);
if (key_addr == NULL)
{
if (pubkey_allocated_here)
{
memset (pubkey_allocated_here, 0, pubkey_len);
free (pubkey_allocated_here);
}
free (pd);
return -1;
}
return -1;
kd[kk].pubkey = key_addr + prvkey_len;
num_prv_keys++;
@@ -1206,19 +1164,11 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
encrypt (dek, iv, (uint8_t *)&kdi, kdi_len (prvkey_len));
r = flash_key_write (key_addr, (const uint8_t *)kdi.data, prvkey_len,
pubkey_allocated_here? pubkey_allocated_here: pubkey,
pubkey_len);
if (pubkey_allocated_here)
{
memset (pubkey_allocated_here, 0, pubkey_len);
free (pubkey_allocated_here);
}
pubkey, pubkey_len);
if (r < 0)
{
random_bytes_free (dek);
memset (pd, 0, sizeof (struct prvkey_data));
free (pd);
return r;
}
@@ -1240,7 +1190,6 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
random_bytes_free (dek);
memset (pd, 0, sizeof (struct prvkey_data));
free (pd);
if (p == NULL)
return -1;
@@ -1272,18 +1221,15 @@ gpg_do_chks_prvkey (enum kind_of_key kk,
uint8_t nr = get_do_ptr_nr_for_kk (kk);
const uint8_t *do_data = do_ptr[nr];
uint8_t dek[DATA_ENCRYPTION_KEY_SIZE];
struct prvkey_data *pd;
const uint8_t *p;
struct prvkey_data prv;
struct prvkey_data *pd = &prv;
uint8_t *dek_p;
int update_needed = 0;
int r = 1; /* Success */
if (do_data == NULL)
return 0; /* No private key */
pd = (struct prvkey_data *)malloc (sizeof (struct prvkey_data));
if (pd == NULL)
return -1;
memcpy (pd, &do_data[1], sizeof (struct prvkey_data));
dek_p = ((uint8_t *)pd) + INITIAL_VECTOR_SIZE
@@ -1314,18 +1260,19 @@ gpg_do_chks_prvkey (enum kind_of_key kk,
if (update_needed)
{
const uint8_t *p;
flash_do_release (do_data);
do_ptr[nr] = NULL;
p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data));
do_ptr[nr] = p;
if (p == NULL)
r = -1;
}
memset (pd, 0, sizeof (struct prvkey_data));
free (pd);
if (update_needed && p == NULL)
return -1;
return 1;
return r;
}
@@ -1380,6 +1327,7 @@ proc_key_import (const uint8_t *data, int len)
const uint8_t *keystring_admin;
int attr;
const uint8_t *p = data;
uint8_t pubkey[512];
if (admin_authorized == BY_ADMIN)
keystring_admin = keystring_md_pw3;
@@ -1419,13 +1367,35 @@ proc_key_import (const uint8_t *data, int len)
}
if (attr == ALGO_RSA2K)
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
r = gpg_do_write_prvkey (kk, &data[26], len - 26, keystring_admin, NULL);
{
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
r = modulus_calc (&data[26], len - 26, pubkey);
if (r >= 0)
r = gpg_do_write_prvkey (kk, &data[26], len - 26, keystring_admin,
pubkey);
}
else if (attr == ALGO_RSA4K)
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
r = gpg_do_write_prvkey (kk, &data[28], len - 28, keystring_admin, NULL);
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
r = gpg_do_write_prvkey (kk, &data[12], len - 12, keystring_admin, NULL);
{
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
r = modulus_calc (&data[28], len - 28, pubkey);
if (r >= 0)
r = gpg_do_write_prvkey (kk, &data[28], len - 28, keystring_admin,
pubkey);
}
else if (attr == ALGO_NISTP256R1)
{
r = ecc_compute_public_p256r1 (&data[12], pubkey);
if (r >= 0)
r = gpg_do_write_prvkey (kk, &data[12], len - 12, keystring_admin,
pubkey);
}
else if (attr == ALGO_SECP256K1)
{
r = ecc_compute_public_p256k1 (&data[12], pubkey);
if (r >= 0)
r = gpg_do_write_prvkey (kk, &data[12], len - 12, keystring_admin,
pubkey);
}
else if (attr == ALGO_ED25519)
{
uint8_t hash[64];
@@ -1437,7 +1407,8 @@ proc_key_import (const uint8_t *data, int len)
hash[0] &= 248;
hash[31] &= 127;
hash[31] |= 64;
r = gpg_do_write_prvkey (kk, hash, 64, keystring_admin, NULL);
eddsa_compute_public_25519 (hash, pubkey);
r = gpg_do_write_prvkey (kk, hash, 64, keystring_admin, pubkey);
}
else if (attr == ALGO_CURVE25519)
{
@@ -1449,7 +1420,8 @@ proc_key_import (const uint8_t *data, int len)
for (i = 0; i < 32; i++)
priv[31-i] = data[12+i];
r = gpg_do_write_prvkey (kk, priv, 32, keystring_admin, NULL);
ecdh_compute_public_25519 (priv, pubkey);
r = gpg_do_write_prvkey (kk, priv, 32, keystring_admin, pubkey);
}
if (r < 0)
@@ -1543,7 +1515,7 @@ gpg_do_table[] = {
* Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc.
*/
void
gpg_data_scan (const uint8_t *p_start)
gpg_data_scan (const uint8_t *do_start, const uint8_t *do_end)
{
const uint8_t *p;
int i;
@@ -1556,10 +1528,15 @@ gpg_data_scan (const uint8_t *p_start)
pw_err_counter_p[PW_ERR_RC] = NULL;
pw_err_counter_p[PW_ERR_PW3] = NULL;
algo_attr_sig_p = algo_attr_dec_p = algo_attr_aut_p = NULL;
digital_signature_counter = 0;
/* When the card is terminated no data objects are valid. */
if (do_start == NULL)
return;
/* Traverse DO, counters, etc. in DATA pool */
p = p_start;
while (p && *p != NR_EMPTY)
p = do_start;
while (p < do_end && *p != NR_EMPTY)
{
uint8_t nr = *p++;
uint8_t second_byte = *p;
@@ -1571,10 +1548,12 @@ gpg_data_scan (const uint8_t *p_start)
if (nr < 0x80)
{
/* It's Data Object */
do_ptr[nr] = p;
if (nr < NR_DO__LAST__)
do_ptr[nr] = p;
p += second_byte + 1; /* second_byte has length */
if (((uint32_t)p & 1))
if (((uintptr_t)p & 1))
p++;
}
else if (nr >= 0x80 && nr <= 0xbf)
@@ -2079,42 +2058,35 @@ gpg_do_write_simple (uint8_t nr, const uint8_t *data, int size)
}
void
gpg_do_keygen (uint8_t kk_byte)
gpg_do_keygen (uint8_t *buf)
{
uint8_t kk_byte = buf[0];
enum kind_of_key kk = kkb_to_kk (kk_byte);
int attr = gpg_get_algo_attr (kk);;
int prvkey_len = gpg_get_algo_attr_key_size (kk, GPG_KEY_PRIVATE);
const uint8_t *keystring_admin;
uint8_t *p_q_modulus = NULL;
uint8_t d[64];
const uint8_t *rnd;
const uint8_t *prv;
const uint8_t *pubkey;
int r;
const uint8_t *rnd;
int r = 0;
#define p_q buf
#define d buf
#define d1 (&buf[64])
#define pubkey (&buf[256])
DEBUG_INFO ("Keygen\r\n");
DEBUG_BYTE (kk_byte);
if (admin_authorized == BY_ADMIN)
keystring_admin = keystring_md_pw3;
else
keystring_admin = NULL;
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
{
p_q_modulus = rsa_genkey (prvkey_len);
if (p_q_modulus == NULL)
if (rsa_genkey (prvkey_len, pubkey, p_q) < 0)
{
GPG_MEMORY_FAILURE ();
return;
}
prv = p_q_modulus;
pubkey = p_q_modulus + prvkey_len;
prv = p_q;
}
else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
{
uint8_t d1[32];
const uint8_t *p;
int i, r;
@@ -2143,7 +2115,10 @@ gpg_do_keygen (uint8_t kk_byte)
random_bytes_free (rnd);
prv = d;
pubkey = NULL;
if (attr == ALGO_SECP256K1)
r = ecc_compute_public_p256k1 (prv, pubkey);
else if (attr == ALGO_NISTP256R1)
r = ecc_compute_public_p256r1 (prv, pubkey);
}
else if (attr == ALGO_ED25519)
{
@@ -2154,7 +2129,7 @@ gpg_do_keygen (uint8_t kk_byte)
d[31] &= 127;
d[31] |= 64;
prv = d;
pubkey = NULL;
eddsa_compute_public_25519 (d, pubkey);
}
else if (attr == ALGO_CURVE25519)
{
@@ -2165,7 +2140,7 @@ gpg_do_keygen (uint8_t kk_byte)
d[31] &= 127;
d[31] |= 64;
prv = d;
pubkey = NULL;
ecdh_compute_public_25519 (prv, pubkey);
}
else
{
@@ -2173,12 +2148,21 @@ gpg_do_keygen (uint8_t kk_byte)
return;
}
r = gpg_do_write_prvkey (kk, prv, prvkey_len, keystring_admin, pubkey);
if (p_q_modulus)
if (r >= 0)
{
memset (p_q_modulus, 0, prvkey_len * 2);
free (p_q_modulus);
const uint8_t *keystring_admin;
if (admin_authorized == BY_ADMIN)
keystring_admin = keystring_md_pw3;
else
keystring_admin = NULL;
r = gpg_do_write_prvkey (kk, prv, prvkey_len, keystring_admin, pubkey);
}
/* Clear private key data in the buffer. */
memset (buf, 0, 256);
if (r < 0)
{
GPG_ERROR ();

View File

@@ -1,7 +1,7 @@
/*
* openpgp.c -- OpenPGP card protocol support
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -98,7 +98,6 @@ set_res_sw (uint8_t sw1, uint8_t sw2)
#define FILE_EF_UPDATE_KEY_2 7
#define FILE_EF_UPDATE_KEY_3 8
#define FILE_EF_CH_CERTIFICATE 9
#define FILE_CARD_TERMINATED_OPENPGP 254
#define FILE_CARD_TERMINATED 255
uint8_t file_selection;
@@ -106,17 +105,18 @@ uint8_t file_selection;
static void
gpg_init (void)
{
const uint8_t *flash_data_start;
const uint8_t *flash_do_start;
const uint8_t *flash_do_end;
flash_data_start = flash_init ();
flash_do_storage_init (&flash_do_start, &flash_do_end);
if (flash_data_start == NULL)
if (flash_do_start == NULL)
file_selection = FILE_CARD_TERMINATED;
else
file_selection = FILE_NONE;
gpg_data_scan (flash_data_start);
flash_init_keys ();
gpg_data_scan (flash_do_start, flash_do_end);
flash_key_storage_init ();
}
static void
@@ -644,10 +644,11 @@ cmd_pgp_gakp (void)
{
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
GPG_SECURITY_FAILURE ();
gpg_do_keygen (apdu.cmd_apdu_data[0]);
gpg_do_keygen (&apdu.cmd_apdu_data[0]);
}
}
#ifdef FLASH_UPGRADE_SUPPORT
const uint8_t *
gpg_get_firmware_update_key (uint8_t keyno)
{
@@ -657,6 +658,7 @@ gpg_get_firmware_update_key (uint8_t keyno)
p = &_updatekey_store + keyno * FIRMWARE_UPDATE_KEY_CONTENT_LEN;
return p;
}
#endif
#ifdef CERTDO_SUPPORT
#define FILEID_CH_CERTIFICATE_IS_VALID 1
@@ -669,7 +671,6 @@ cmd_read_binary (void)
{
int is_short_EF = (P1 (apdu) & 0x80) != 0;
uint8_t file_id;
const uint8_t *p;
uint16_t offset;
DEBUG_INFO (" - Read binary\r\n");
@@ -679,13 +680,6 @@ cmd_read_binary (void)
else
file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
if ((!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
|| file_id > FILEID_CH_CERTIFICATE)
{
GPG_NO_FILE ();
return;
}
if (is_short_EF)
{
file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
@@ -705,22 +699,26 @@ cmd_read_binary (void)
}
return;
}
if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
#ifdef FLASH_UPGRADE_SUPPORT
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
{
if (offset != 0)
GPG_MEMORY_FAILURE ();
else
{
const uint8_t *p;
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
res_APDU_size = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
memcpy (res_APDU, p, FIRMWARE_UPDATE_KEY_CONTENT_LEN);
GPG_SUCCESS ();
}
}
#endif
#if defined(CERTDO_SUPPORT)
else /* file_id == FILEID_CH_CERTIFICATE */
else if (file_id == FILEID_CH_CERTIFICATE)
{
const uint8_t *p;
uint16_t len = 256;
p = &ch_certificate_start;
@@ -737,6 +735,11 @@ cmd_read_binary (void)
}
}
#endif
else
{
GPG_NO_FILE ();
return;
}
}
static void
@@ -759,8 +762,7 @@ cmd_select_file (void)
if (file_selection == FILE_CARD_TERMINATED)
{
file_selection = FILE_CARD_TERMINATED_OPENPGP;
GPG_APPLICATION_TERMINATED();
GPG_APPLICATION_TERMINATED ();
return;
}
@@ -1201,6 +1203,7 @@ modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
return;
}
#ifdef FLASH_UPGRADE_SUPPORT
if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3
&& len == 0 && offset == 0)
{
@@ -1217,9 +1220,10 @@ modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
if (i == 4) /* all update keys are removed */
{
p = gpg_get_firmware_update_key (0);
flash_erase_page ((uint32_t)p);
flash_erase_page ((uintptr_t)p);
}
}
#endif
GPG_SUCCESS ();
}
@@ -1249,6 +1253,7 @@ cmd_write_binary (void)
}
#ifdef FLASH_UPGRADE_SUPPORT
static void
cmd_external_authenticate (void)
{
@@ -1290,6 +1295,7 @@ cmd_external_authenticate (void)
set_res_sw (0xff, 0xff);
DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
}
#endif
static void
cmd_get_challenge (void)
@@ -1322,9 +1328,9 @@ cmd_get_challenge (void)
static void
cmd_activate_file (void)
{
if (file_selection != FILE_CARD_TERMINATED_OPENPGP)
if (file_selection != FILE_CARD_TERMINATED)
{
GPG_NO_RECORD();
GPG_NO_RECORD ();
return;
}
@@ -1336,12 +1342,14 @@ cmd_activate_file (void)
static void
cmd_terminate_df (void)
{
const uint8_t *ks_pw3;
uint8_t p1 = P1 (apdu);
uint8_t p2 = P2 (apdu);
if (file_selection != FILE_DF_OPENPGP)
{
GPG_NO_RECORD();
GPG_NO_RECORD ();
return;
}
@@ -1357,8 +1365,11 @@ cmd_terminate_df (void)
return;
}
ks_pw3 = gpg_do_read_simple (NR_DO_KEYSTRING_PW3);
if (!ac_check_status (AC_ADMIN_AUTHORIZED) && !gpg_pw_locked (PW_ERR_PW3))
if (!ac_check_status (AC_ADMIN_AUTHORIZED)
&& !((ks_pw3 && gpg_pw_locked (PW_ERR_PW3))
|| (ks_pw3 == NULL && gpg_pw_locked (PW_ERR_PW1))))
{
/* Only allow the case admin authorized, or, admin pass is locked. */
GPG_SECURITY_FAILURE();
@@ -1391,8 +1402,10 @@ const struct command cmds[] = {
{ INS_ACTIVATE_FILE, cmd_activate_file },
#endif
{ INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
#ifdef FLASH_UPGRADE_SUPPORT
{ INS_EXTERNAL_AUTHENTICATE, /* Not in OpenPGP card protocol */
cmd_external_authenticate },
#endif
{ INS_GET_CHALLENGE, cmd_get_challenge }, /* Not in OpenPGP card protocol */
{ INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
{ INS_SELECT_FILE, cmd_select_file },
@@ -1425,13 +1438,13 @@ process_command_apdu (void)
if (file_selection == FILE_CARD_TERMINATED
&& cmd != INS_SELECT_FILE && cmd != INS_ACTIVATE_FILE
&& cmd != INS_GET_CHALLENGE && cmd != INS_EXTERNAL_AUTHENTICATE)
GPG_APPLICATION_TERMINATED();
GPG_APPLICATION_TERMINATED ();
else if (file_selection != FILE_DF_OPENPGP
&& cmd != INS_SELECT_FILE && cmd != INS_ACTIVATE_FILE
&& cmd != INS_GET_CHALLENGE && cmd != INS_EXTERNAL_AUTHENTICATE
&& cmd != INS_WRITE_BINARY && cmd != INS_UPDATE_BINARY
&& cmd != INS_READ_BINARY)
GPG_NO_RECORD();
GPG_NO_RECORD ();
else
{
chopstx_setcancelstate (1);

View File

@@ -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 *

View File

@@ -47,7 +47,6 @@
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "sha256.h"
#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)

View File

@@ -32,7 +32,6 @@
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "sha512.h"
#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)

59
src/stack-def.h Normal file
View File

@@ -0,0 +1,59 @@
#ifdef GNU_LINUX_EMULATION
#define SIZE_1 4096
#define SIZE_2 4096
#define SIZE_3 (4 * 4096)
#else
#define SIZE_0 0x0100 /* Main */
#define SIZE_1 0x01a0 /* CCID */
#define SIZE_2 0x0180 /* RNG */
#define SIZE_3 0x1640 /* openpgp-card */
#define SIZE_4 0x0000 /* --- */
#define SIZE_5 0x0200 /* msc */
#define SIZE_6 0x00c0 /* timer (cir) */
#define SIZE_7 0x00c0 /* ext (cir) */
#endif
#if defined(STACK_MAIN) && !defined(GNU_LINUX_EMULATION)
/* Idle+Exception handlers */
char __main_stack_end__[0] __attribute__ ((section(".main_stack")));
char main_base[0x0080] __attribute__ ((section(".main_stack")));
/* Main program */
char __process0_stack_end__[0] __attribute__ ((section(".process_stack.0")));
char process0_base[SIZE_0] __attribute__ ((section(".process_stack.0")));
#endif
/* First thread program */
#if defined(STACK_PROCESS_1)
char process1_base[SIZE_1] __attribute__ ((section(".process_stack.1")));
#endif
/* Second thread program */
#if defined(STACK_PROCESS_2)
char process2_base[SIZE_2] __attribute__ ((section(".process_stack.2")));
#endif
/* Third thread program */
#if defined(STACK_PROCESS_3)
char process3_base[SIZE_3] __attribute__ ((section(".process_stack.3")));
#endif
/* Fourth thread program */
#if defined(STACK_PROCESS_4)
char process4_base[SIZE_4] __attribute__ ((section(".process_stack.4")));
#endif
/* Fifth thread program */
#if defined(STACK_PROCESS_5)
char process5_base[SIZE_5] __attribute__ ((section(".process_stack.5")));
#endif
/* Sixth thread program */
#if defined(STACK_PROCESS_6)
char process6_base[SIZE_6] __attribute__ ((section(".process_stack.6")));
#endif
/* Seventh thread program */
#if defined(STACK_PROCESS_7)
char process7_base[SIZE_7] __attribute__ ((section(".process_stack.7")));
#endif

View File

@@ -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 *);

View File

@@ -1,7 +1,7 @@
/*
* usb-ccid.c -- USB CCID protocol handling
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -30,6 +30,7 @@
#include "config.h"
#ifdef DEBUG
#include "usb-cdc.h"
#include "debug.h"
struct stdout stdout;
#endif
@@ -345,13 +346,21 @@ static void get_sw1sw2 (struct ep_in *epi, size_t len)
epi->next_buf = no_buf;
}
#ifdef GNU_LINUX_EMULATION
static uint8_t endp1_tx_buf[64]; /* Only support single CCID interface. */
#endif
/*
* Tx done callback
*/
static void
EP1_IN_Callback (uint16_t len)
ccid_tx_done (uint8_t ep_num, uint16_t len)
{
/*
* If we support multiple CCID interfaces, we select endpoint object
* by EP_NUM. Because it has only single CCID interface now, it's
* hard-coded, here.
*/
struct ep_in *epi = &endpoint_in;
(void)len;
@@ -361,7 +370,12 @@ EP1_IN_Callback (uint16_t len)
else
{
epi->tx_done = 1;
usb_lld_tx_enable (epi->ep_num, 0); /* send ZLP */
/* send ZLP */
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (ep_num, endp1_tx_buf, 0);
#else
usb_lld_tx_enable (ep_num, 0);
#endif
}
else
{
@@ -372,7 +386,11 @@ EP1_IN_Callback (uint16_t len)
while (epi->buf)
if (epi->buf_len < remain)
{
usb_lld_txcpy (epi->buf, epi->ep_num, offset, epi->buf_len);
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+offset, epi->buf, epi->buf_len);
#else
usb_lld_txcpy (epi->buf, ep_num, offset, epi->buf_len);
#endif
offset += epi->buf_len;
remain -= epi->buf_len;
tx_size += epi->buf_len;
@@ -380,7 +398,11 @@ EP1_IN_Callback (uint16_t len)
}
else
{
usb_lld_txcpy (epi->buf, epi->ep_num, offset, remain);
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+offset, epi->buf, remain);
#else
usb_lld_txcpy (epi->buf, ep_num, offset, remain);
#endif
epi->buf += remain;
epi->cnt += remain;
epi->buf_len -= remain;
@@ -390,7 +412,12 @@ EP1_IN_Callback (uint16_t len)
if (tx_size < USB_LL_BUF_SIZE)
epi->tx_done = 1;
usb_lld_tx_enable (epi->ep_num, tx_size);
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (ep_num, endp1_tx_buf, tx_size);
#else
usb_lld_tx_enable (ep_num, tx_size);
#endif
}
}
@@ -609,6 +636,9 @@ static void ccid_abdata (struct ep_out *epo, size_t len)
}
}
#ifdef GNU_LINUX_EMULATION
static uint8_t endp1_rx_buf[64]; /* Only support single CCID interface. */
#endif
static void
ccid_prepare_receive (struct ccid *c)
@@ -619,17 +649,25 @@ ccid_prepare_receive (struct ccid *c)
c->epo->cnt = 0;
c->epo->next_buf = ccid_abdata;
c->epo->end_rx = end_ccid_rx;
#ifdef GNU_LINUX_EMULATION
usb_lld_rx_enable_buf (c->epo->ep_num, endp1_rx_buf, 64);
#else
usb_lld_rx_enable (c->epo->ep_num);
#endif
DEBUG_INFO ("Rx ready\r\n");
}
/*
* Rx ready callback
*/
static void
EP1_OUT_Callback (uint16_t len)
ccid_rx_ready (uint8_t ep_num, uint16_t len)
{
/*
* If we support multiple CCID interfaces, we select endpoint object
* by EP_NUM. Because it has only single CCID interface now, it's
* hard-coded, here.
*/
struct ep_out *epo = &endpoint_out;
int offset = 0;
int cont;
@@ -640,7 +678,11 @@ EP1_OUT_Callback (uint16_t len)
break;
else if (len <= epo->buf_len)
{
usb_lld_rxcpy (epo->buf, epo->ep_num, offset, len);
#ifdef GNU_LINUX_EMULATION
memcpy (epo->buf, endp1_rx_buf + offset, len);
#else
usb_lld_rxcpy (epo->buf, ep_num, offset, len);
#endif
epo->buf += len;
epo->cnt += len;
epo->buf_len -= len;
@@ -648,7 +690,11 @@ EP1_OUT_Callback (uint16_t len)
}
else /* len > buf_len */
{
usb_lld_rxcpy (epo->buf, epo->ep_num, offset, epo->buf_len);
#ifdef GNU_LINUX_EMULATION
memcpy (epo->buf, endp1_rx_buf + offset, epo->buf_len);
#else
usb_lld_rxcpy (epo->buf, ep_num, offset, epo->buf_len);
#endif
len -= epo->buf_len;
offset += epo->buf_len;
epo->next_buf (epo, len); /* Update epo->buf, cnt, buf_len */
@@ -661,7 +707,11 @@ EP1_OUT_Callback (uint16_t len)
cont = epo->end_rx (epo, orig_len);
if (cont)
usb_lld_rx_enable (epo->ep_num);
#ifdef GNU_LINUX_EMULATION
usb_lld_rx_enable_buf (ep_num, endp1_rx_buf, 64);
#else
usb_lld_rx_enable (ep_num);
#endif
else
notify_icc (epo);
}
@@ -669,16 +719,24 @@ EP1_OUT_Callback (uint16_t len)
extern void EP6_IN_Callback (uint16_t len);
#if defined(DEBUG) && defined(GNU_LINUX_EMULATION)
static uint8_t endp5_buf[VIRTUAL_COM_PORT_DATA_SIZE];
#endif
static void
usb_rx_ready (uint8_t ep_num, uint16_t len)
{
if (ep_num == ENDP1)
EP1_OUT_Callback (len);
ccid_rx_ready (ep_num, len);
#ifdef DEBUG
else if (ep_num == ENDP5)
{
chopstx_mutex_lock (&stdout.m_dev);
#ifdef GNU_LINUX_EMULATION
usb_lld_rx_enable (ep_num, endp5_buf, VIRTUAL_COM_PORT_DATA_SIZE);
#else
usb_lld_rx_enable (ep_num);
#endif
chopstx_mutex_unlock (&stdout.m_dev);
}
#endif
@@ -688,7 +746,7 @@ static void
usb_tx_done (uint8_t ep_num, uint16_t len)
{
if (ep_num == ENDP1)
EP1_IN_Callback (len);
ccid_tx_done (ep_num, len);
else if (ep_num == ENDP2)
{
/* INTERRUPT Transfer done */
@@ -756,14 +814,21 @@ static void ccid_error (struct ccid *c, int offset)
/* This is a single packet Bulk-IN transaction */
c->epi->buf = NULL;
c->epi->tx_done = 1;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf, ccid_reply, CCID_MSG_HEADER_SIZE);
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, CCID_MSG_HEADER_SIZE);
#else
usb_lld_write (c->epi->ep_num, ccid_reply, CCID_MSG_HEADER_SIZE);
#endif
}
extern void *openpgp_card_thread (void *arg);
extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
#define STACK_ADDR_GPG ((uint32_t)__process3_stack_base__)
#define STACK_SIZE_GPG ((uint32_t)__process3_stack_size__)
#define STACK_PROCESS_3
#include "stack-def.h"
#define STACK_ADDR_GPG ((uintptr_t)process3_base)
#define STACK_SIZE_GPG (sizeof process3_base)
#define PRIO_GPG 1
@@ -793,9 +858,14 @@ ccid_power_on (struct ccid *c)
p[CCID_MSG_ERROR_OFFSET] = 0x00;
p[CCID_MSG_CHAIN_OFFSET] = 0x00;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head));
#else
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
usb_lld_txcpy (ATR_head, c->epi->ep_num, CCID_MSG_HEADER_SIZE,
sizeof (ATR_head));
#endif
for (i = 1; i < (int)sizeof (ATR_head); i++)
xor_check ^= ATR_head[i];
memcpy (p, historical_bytes + 1, hist_len);
@@ -806,13 +876,22 @@ ccid_power_on (struct ccid *c)
for (i = 0; i < hist_len; i++)
xor_check ^= p[i];
p[i] = xor_check;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+sizeof (ATR_head), p, hist_len+1);
#else
usb_lld_txcpy (p, c->epi->ep_num, CCID_MSG_HEADER_SIZE + sizeof (ATR_head),
hist_len+1);
#endif
/* This is a single packet Bulk-IN transaction */
c->epi->buf = NULL;
c->epi->tx_done = 1;
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
CCID_MSG_HEADER_SIZE + size_atr);
#else
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + size_atr);
#endif
DEBUG_INFO ("ON\r\n");
return CCID_STATE_WAIT;
@@ -843,7 +922,13 @@ ccid_send_status (struct ccid *c)
/* This is a single packet Bulk-IN transaction */
c->epi->buf = NULL;
c->epi->tx_done = 1;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf, ccid_reply, CCID_MSG_HEADER_SIZE);
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, CCID_MSG_HEADER_SIZE);
#else
usb_lld_write (c->epi->ep_num, ccid_reply, CCID_MSG_HEADER_SIZE);
#endif
led_blink (LED_SHOW_STATUS);
#ifdef DEBUG_MORE
@@ -890,19 +975,35 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
p[CCID_MSG_ERROR_OFFSET] = error;
p[CCID_MSG_CHAIN_OFFSET] = 0;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
#else
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
#endif
if (len == 0)
{
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
CCID_MSG_HEADER_SIZE);
#else
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE);
#endif
return;
}
if (CCID_MSG_HEADER_SIZE + len <= USB_LL_BUF_SIZE)
{
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
c->a->res_apdu_data, c->a->res_apdu_data_len);
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+c->a->res_apdu_data_len,
c->sw1sw2, 2);
#else
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num,
CCID_MSG_HEADER_SIZE, c->a->res_apdu_data_len);
usb_lld_txcpy (c->sw1sw2, c->epi->ep_num,
CCID_MSG_HEADER_SIZE + c->a->res_apdu_data_len, 2);
#endif
c->epi->buf = NULL;
if (CCID_MSG_HEADER_SIZE + len < USB_LL_BUF_SIZE)
c->epi->tx_done = 1;
@@ -910,10 +1011,17 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
}
else if (CCID_MSG_HEADER_SIZE + len - 1 == USB_LL_BUF_SIZE)
{
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
c->a->res_apdu_data, c->a->res_apdu_data_len);
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+c->a->res_apdu_data_len,
c->sw1sw2, 1);
#else
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num,
CCID_MSG_HEADER_SIZE, c->a->res_apdu_data_len);
usb_lld_txcpy (c->sw1sw2, c->epi->ep_num,
CCID_MSG_HEADER_SIZE + c->a->res_apdu_data_len, 1);
#endif
c->epi->buf = &c->sw1sw2[1];
c->epi->cnt = 1;
c->epi->buf_len = 1;
@@ -921,8 +1029,13 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
}
else if (CCID_MSG_HEADER_SIZE + len - 2 == USB_LL_BUF_SIZE)
{
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
c->a->res_apdu_data, c->a->res_apdu_data_len);
#else
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num,
CCID_MSG_HEADER_SIZE, c->a->res_apdu_data_len);
#endif
c->epi->buf = &c->sw1sw2[0];
c->epi->cnt = 0;
c->epi->buf_len = 2;
@@ -930,8 +1043,13 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
}
else
{
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
c->a->res_apdu_data, USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
#else
usb_lld_txcpy (c->a->res_apdu_data, c->epi->ep_num, CCID_MSG_HEADER_SIZE,
USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
#endif
c->epi->buf = c->a->res_apdu_data + USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE;
c->epi->cnt = USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE;
c->epi->buf_len = c->a->res_apdu_data_len
@@ -939,7 +1057,11 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
c->epi->next_buf = get_sw1sw2;
}
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, tx_size);
#else
usb_lld_tx_enable (c->epi->ep_num, tx_size);
#endif
#ifdef DEBUG_MORE
DEBUG_INFO ("DATA\r\n");
#endif
@@ -976,11 +1098,20 @@ ccid_send_data_block_0x9000 (struct ccid *c)
p[CCID_MSG_CHAIN_OFFSET+1] = 0x90;
p[CCID_MSG_CHAIN_OFFSET+2] = 0x00;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE + len);
#else
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE + len);
#endif
c->epi->buf = NULL;
c->epi->tx_done = 1;
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
CCID_MSG_HEADER_SIZE + len);
#else
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + len);
#endif
#ifdef DEBUG_MORE
DEBUG_INFO ("DATA\r\n");
#endif
@@ -1007,7 +1138,11 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
p[CCID_MSG_ERROR_OFFSET] = 0;
p[CCID_MSG_CHAIN_OFFSET] = 0;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
#else
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
#endif
set_sw1sw2 (c, chunk_len);
@@ -1022,10 +1157,19 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
else
size_for_sw = 0;
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, c->p, chunk_len);
#else
usb_lld_txcpy (c->p, c->epi->ep_num, CCID_MSG_HEADER_SIZE, chunk_len);
#endif
if (size_for_sw)
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+chunk_len,
c->sw1sw2, size_for_sw);
#else
usb_lld_txcpy (c->sw1sw2, c->epi->ep_num,
CCID_MSG_HEADER_SIZE + chunk_len, size_for_sw);
#endif
tx_size = CCID_MSG_HEADER_SIZE + chunk_len + size_for_sw;
if (size_for_sw == 2)
{
@@ -1044,8 +1188,13 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
}
else
{
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE,
c->p, USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
#else
usb_lld_txcpy (c->p, c->epi->ep_num, CCID_MSG_HEADER_SIZE,
USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
#endif
c->epi->buf = c->p + USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE;
c->epi->cnt = 0;
c->epi->buf_len = chunk_len - (USB_LL_BUF_SIZE - CCID_MSG_HEADER_SIZE);
@@ -1054,7 +1203,11 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
c->p += chunk_len;
c->len -= chunk_len;
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf, tx_size);
#else
usb_lld_tx_enable (c->epi->ep_num, tx_size);
#endif
#ifdef DEBUG_MORE
DEBUG_INFO ("DATA\r\n");
#endif
@@ -1086,13 +1239,23 @@ ccid_send_params (struct ccid *c)
p[CCID_MSG_ERROR_OFFSET] = 0;
p[CCID_MSG_CHAIN_OFFSET] = 0x01; /* ProtocolNum: T=1 */
#ifdef GNU_LINUX_EMULATION
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, params, sizeof params);
#else
usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
usb_lld_txcpy (params, c->epi->ep_num, CCID_MSG_HEADER_SIZE, sizeof params);
#endif
/* This is a single packet Bulk-IN transaction */
c->epi->buf = NULL;
c->epi->tx_done = 1;
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (c->epi->ep_num, endp1_tx_buf,
CCID_MSG_HEADER_SIZE + sizeof params);
#else
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + sizeof params);
#endif
#ifdef DEBUG_MORE
DEBUG_INFO ("PARAMS\r\n");
#endif
@@ -1359,6 +1522,9 @@ ccid_usb_reset (int full)
full ? EV_USB_DEVICE_RESET : EV_USB_SET_INTERFACE);
}
#ifdef GNU_LINUX_EMULATION
static uint8_t endp2_tx_buf[2];
#endif
#define NOTIFY_SLOT_CHANGE 0x50
static void
@@ -1374,7 +1540,12 @@ ccid_notify_slot_change (struct ccid *c)
notification[0] = NOTIFY_SLOT_CHANGE;
notification[1] = msg;
#ifdef GNU_LINUX_EMULATION
memcpy (endp2_tx_buf, notification, sizeof notification);
usb_lld_tx_enable_buf (ENDP2, endp2_tx_buf, sizeof notification);
#else
usb_lld_write (ENDP2, notification, sizeof notification);
#endif
led_blink (LED_TWOSHOTS);
}
@@ -1384,7 +1555,12 @@ ccid_notify_slot_change (struct ccid *c)
#define GPG_THREAD_TERMINATED 0xffff
#ifdef GNU_LINUX_EMULATION
#include <signal.h>
#define INTR_REQ_USB SIGUSR1
#else
#define INTR_REQ_USB 20
#endif
extern uint32_t bDeviceState;
extern void usb_device_reset (struct usb_dev *dev);
@@ -1687,7 +1863,11 @@ _write (const char *s, int len)
(len < VIRTUAL_COM_PORT_DATA_SIZE) ? len : VIRTUAL_COM_PORT_DATA_SIZE;
chopstx_mutex_lock (&stdout.m_dev);
#ifdef GNU_LINUX_EMULATION
usb_lld_tx_enable_buf (ENDP3, s, packet_len);
#else
usb_lld_write (ENDP3, s, packet_len);
#endif
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
chopstx_mutex_unlock (&stdout.m_dev);

View File

@@ -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;

View File

@@ -1,7 +1,7 @@
/*
* usb_ctrl.c - USB control pipe device specific code for Gnuk
*
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -38,7 +38,7 @@
#include "usb_lld.h"
#include "usb_conf.h"
#include "gnuk.h"
#include "mcu/stm32f103.h"
#include "neug.h"
#ifdef ENABLE_VIRTUAL_COM_PORT
#include "usb-cdc.h"
@@ -108,15 +108,25 @@ static uint16_t hid_report;
#endif
static void
gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
gnuk_setup_endpoints_for_interface (struct usb_dev *dev,
uint16_t interface, int stop)
{
#if !defined(GNU_LINUX_EMULATION)
(void)dev;
#endif
if (interface == CCID_INTERFACE)
{
if (!stop)
{
#ifdef GNU_LINUX_EMULATION
usb_lld_setup_endp (dev, ENDP1, 1, 1);
usb_lld_setup_endp (dev, ENDP2, 0, 1);
#else
usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, ENDP1_RXADDR,
ENDP1_TXADDR, GNUK_MAX_PACKET_SIZE);
usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
#endif
}
else
{
@@ -129,7 +139,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
else if (interface == HID_INTERFACE)
{
if (!stop)
#ifdef GNU_LINUX_EMULATION
usb_lld_setup_endp (dev, ENDP7, 0, 1);
#else
usb_lld_setup_endpoint (ENDP7, EP_INTERRUPT, 0, 0, ENDP7_TXADDR, 0);
#endif
else
usb_lld_stall_tx (ENDP7);
}
@@ -138,7 +152,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
else if (interface == VCOM_INTERFACE_0)
{
if (!stop)
#ifdef GNU_LINUX_EMULATION
usb_lld_setup_endp (dev, ENDP4, 0, 1);
#else
usb_lld_setup_endpoint (ENDP4, EP_INTERRUPT, 0, 0, ENDP4_TXADDR, 0);
#endif
else
usb_lld_stall_tx (ENDP4);
}
@@ -146,9 +164,14 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
{
if (!stop)
{
#ifdef GNU_LINUX_EMULATION
usb_lld_setup_endp (dev, ENDP3, 0, 1);
usb_lld_setup_endp (dev, ENDP5, 1, 0);
#else
usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, 0, ENDP3_TXADDR, 0);
usb_lld_setup_endpoint (ENDP5, EP_BULK, 0, ENDP5_RXADDR, 0,
VIRTUAL_COM_PORT_DATA_SIZE);
#endif
}
else
{
@@ -161,8 +184,12 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
else if (interface == MSC_INTERFACE)
{
if (!stop)
#ifdef GNU_LINUX_EMULATION
usb_lld_setup_endp (dev, ENDP6, 1, 1);
#else
usb_lld_setup_endpoint (ENDP6, EP_BULK, 0,
ENDP6_RXADDR, ENDP6_TXADDR, 64);
#endif
else
{
usb_lld_stall_tx (ENDP6);
@@ -180,12 +207,16 @@ usb_device_reset (struct usb_dev *dev)
usb_lld_reset (dev, USB_INITIAL_FEATURE);
/* Initialize Endpoint 0 */
#ifdef GNU_LINUX_EMULATION
usb_lld_setup_endp (dev, ENDP0, 1, 1);
#else
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
GNUK_MAX_PACKET_SIZE);
64);
#endif
/* Stop the interface */
for (i = 0; i < NUM_INTERFACES; i++)
gnuk_setup_endpoints_for_interface (i, 1);
gnuk_setup_endpoints_for_interface (dev, i, 1);
bDeviceState = ATTACHED;
ccid_usb_reset (1);
@@ -202,38 +233,34 @@ static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
#endif
#ifdef FLASH_UPGRADE_SUPPORT
static const uint8_t *const mem_info[] = { &_regnual_start, __heap_end__, };
#endif
#define USB_FSIJ_GNUK_MEMINFO 0
#define USB_FSIJ_GNUK_DOWNLOAD 1
#define USB_FSIJ_GNUK_EXEC 2
#define USB_FSIJ_GNUK_CARD_CHANGE 3
static uint32_t rbit (uint32_t v)
{
uint32_t r;
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
return r;
}
#ifdef FLASH_UPGRADE_SUPPORT
/* After calling this function, CRC module remain enabled. */
static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
static int
download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
{
uint32_t crc32 = *end_p;
const uint32_t *p;
RCC->AHBENR |= RCC_AHBENR_CRCEN;
CRC->CR = CRC_CR_RESET;
crc32_rv_reset ();
for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
CRC->DR = rbit (*p);
crc32_rv_step (rbit (*p));
if ((rbit (CRC->DR) ^ crc32) == 0xffffffff)
if ((rbit (crc32_rv_get ()) ^ crc32) == 0xffffffff)
return usb_lld_ctrl_ack (dev);
return -1;
}
#endif
int
usb_setup (struct usb_dev *dev)
@@ -245,16 +272,22 @@ usb_setup (struct usb_dev *dev)
{
if (USB_SETUP_GET (arg->type))
{
#ifdef FLASH_UPGRADE_SUPPORT
if (arg->request == USB_FSIJ_GNUK_MEMINFO)
return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
#else
return -1;
#endif
}
else /* SETUP_SET */
{
uint8_t *addr = (uint8_t *)(0x20000000 + arg->value * 0x100
+ arg->index);
#ifdef FLASH_UPGRADE_SUPPORT
uint8_t *addr = sram_address ((arg->value * 0x100) + arg->index);
#endif
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
{
#ifdef FLASH_UPGRADE_SUPPORT
if (*ccid_state_p != CCID_STATE_EXITED)
return -1;
@@ -266,16 +299,23 @@ usb_setup (struct usb_dev *dev)
256 - (arg->index + arg->len));
return usb_lld_ctrl_recv (dev, addr, arg->len);
#else
return -1;
#endif
}
else if (arg->request == USB_FSIJ_GNUK_EXEC && arg->len == 0)
{
#ifdef FLASH_UPGRADE_SUPPORT
if (*ccid_state_p != CCID_STATE_EXITED)
return -1;
if (((uint32_t)addr & 0x03))
if (((uintptr_t)addr & 0x03))
return -1;
return download_check_crc32 (dev, (uint32_t *)addr);
#else
return -1;
#endif
}
else if (arg->request == USB_FSIJ_GNUK_CARD_CHANGE && arg->len == 0)
{
@@ -435,7 +475,7 @@ usb_set_configuration (struct usb_dev *dev)
usb_lld_set_configuration (dev, 1);
for (i = 0; i < NUM_INTERFACES; i++)
gnuk_setup_endpoints_for_interface (i, 0);
gnuk_setup_endpoints_for_interface (dev, i, 0);
bDeviceState = CONFIGURED;
}
else if (current_conf != dev->dev_req.value)
@@ -445,7 +485,7 @@ usb_set_configuration (struct usb_dev *dev)
usb_lld_set_configuration (dev, 0);
for (i = 0; i < NUM_INTERFACES; i++)
gnuk_setup_endpoints_for_interface (i, 1);
gnuk_setup_endpoints_for_interface (dev, i, 1);
bDeviceState = ADDRESSED;
ccid_usb_reset (1);
}
@@ -468,7 +508,7 @@ usb_set_interface (struct usb_dev *dev)
return -1;
else
{
gnuk_setup_endpoints_for_interface (interface, 0);
gnuk_setup_endpoints_for_interface (dev, interface, 0);
ccid_usb_reset (0);
return usb_lld_ctrl_ack (dev);
}

View File

@@ -59,7 +59,10 @@ static const uint8_t hid_report_desc[] = {
#define USB_CCID_DATA_SIZE 64
/* USB Standard Device Descriptor */
static const uint8_t device_desc[] = {
#if !defined(GNU_LINUX_EMULATION)
static const
#endif
uint8_t device_desc[] = {
18, /* bLength */
DEVICE_DESCRIPTOR, /* bDescriptorType */
0x10, 0x01, /* bcdUSB = 1.1 */

View File

@@ -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

View File

@@ -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

View File

@@ -24,4 +24,4 @@ Feature: command GET DATA
Scenario: data object AID
When requesting AID: 4f
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00......\x00\x00
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00[\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff]\x00\x00

48
tool/gnuk-emulation-setup Executable file
View 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

View File

@@ -1,7 +1,7 @@
"""
gnuk_token.py - a library for Gnuk Token
Copyright (C) 2011, 2012, 2013, 2015
Copyright (C) 2011, 2012, 2013, 2015, 2017
Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org>
@@ -26,6 +26,12 @@ import binascii
import usb, time
from array import array
# Possible Gnuk Token products
USB_PRODUCT_LIST=[
{ 'vendor' : 0x234b, 'product' : 0x0000 }, # FSIJ Gnuk Token
{ 'vendor' : 0x20a0, 'product' : 0x4211 }, # Nitrokey Start
]
# USB class, subclass, protocol
CCID_CLASS = 0x0B
CCID_SUBCLASS = 0x00
@@ -586,19 +592,18 @@ def gnuk_devices():
alt.interfaceProtocol == CCID_PROTOCOL_0:
yield dev, config, alt
USB_VENDOR_FSIJ=0x234b
USB_PRODUCT_GNUK=0x0000
def gnuk_devices_by_vidpid():
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
if dev.idVendor != USB_VENDOR_FSIJ:
continue
if dev.idProduct != USB_PRODUCT_GNUK:
continue
yield dev
for cand in USB_PRODUCT_LIST:
if dev.idVendor != cand['vendor']:
continue
if dev.idProduct != cand['product']:
continue
yield dev
break
def get_gnuk_device():
icc = None

View File

@@ -69,8 +69,9 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
gnuk = None
#
reg = None
print("Waiting for device to appear:")
while reg == None:
print("Wait %d seconds..." % wait_e)
print(" Wait %d seconds..." % wait_e)
time.sleep(wait_e)
for dev in gnuk_devices_by_vidpid():
try:
@@ -84,9 +85,13 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
print("%08x:%08x" % mem_info)
print("Downloading the program")
reg.download(mem_info[0], data_upgrade)
print("Protecting device")
reg.protect()
print("Finish flashing")
reg.finish()
print("Resetting device")
reg.reset_device()
print("Update procedure finished")
return 0
from getpass import getpass
@@ -119,6 +124,9 @@ if __name__ == '__main__':
passwd = getpass("Admin password: ")
filename_regnual = sys.argv[1]
filename_upgrade = sys.argv[2]
if not filename_regnual.endswith('bin') or not filename_upgrade.endswith('bin'):
print("Both input files must be in binary format (*.bin)!")
exit(1)
f = open(filename_regnual,"rb")
data_regnual = f.read()
f.close()

View File

@@ -3,7 +3,7 @@
"""
usb_strings.py - a tool to dump USB string
Copyright (C) 2012, 2015 Free Software Initiative of Japan
Copyright (C) 2012, 2015, 2017 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -22,28 +22,14 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from gnuk_token import *
import usb, sys
USB_VENDOR_FSIJ=0x234b
USB_PRODUCT_GNUK=0x0000
def gnuk_devices_by_vidpid():
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
if dev.idVendor != USB_VENDOR_FSIJ:
continue
if dev.idProduct != USB_PRODUCT_GNUK:
continue
yield dev
field = ['', 'Vendor', 'Product', 'Serial', 'Revision', 'Config', 'Sys', 'Board']
def main(n):
for dev in gnuk_devices_by_vidpid():
handle = dev.open()
print("Device: %s" % dev.filename)
try:
for i in range(1,n):
s = handle.getString(i, 512)