Compare commits

..

27 Commits

Author SHA1 Message Date
NIIBE Yutaka
57fdadf283 Version 1.2.19.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-10-12 11:42:44 +09:00
NIIBE Yutaka
870de72ee2 configure: Allow override of kdf_do variable.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-10-11 11:51:55 +09:00
NIIBE Yutaka
fa667b04f7 configure: Add KDF configuration.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-07-01 13:43:42 +09:00
Bertrand Jacquin
2a72f3df08 regnual: add missing header
regnual.c:32:1: note: ‘memset’ is declared in header ‘<string.h>’
2021-06-15 10:56:57 +09:00
NIIBE Yutaka
db2527459f Fix scripts.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-06-10 14:31:45 +09:00
NIIBE Yutaka
1ca3bbdaae Fix for key attributes (long standing bug).
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-04-30 13:55:52 +09:00
NIIBE Yutaka
98119dc991 Version 1.2.18.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-04-02 16:58:04 +09:00
NIIBE Yutaka
03cca1e451 Write ChangeLog entries and AUTHORS.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-04-02 16:53:56 +09:00
NIIBE Yutaka
3f65bf73e8 Add a check to make sure device is the one intended.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-04-01 16:23:39 +09:00
NIIBE Yutaka
07be37f45e Fix tests for Gnuk emulation (skip test with no KDF setup).
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-03-19 17:37:32 +09:00
Vincent Pelletier
dcef6e0ffa tests/card_test_personalize_card.py: Exercise ECDH, X25519 and ED25519.
ECDH curves exercised are OpenPGP recommended set: ANSIx9p{256,384,521}r1
and BRAINPOOLp{256,384,512}r1, plus X25519 and ED25519.
Signature is only tested (for now ?) with ED25519 as other signature schemes
are (usually) non-deterministic and require implementing the signature
verification algorithm rather than just testing for equality with a test
vector.

Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
2021-03-19 16:09:03 +09:00
NIIBE Yutaka
d31687ebd6 Fix typo of configure.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-03-12 12:07:57 +09:00
NIIBE Yutaka
92443f8f07 Fix previous change.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-03-12 03:00:44 +09:00
NIIBE Yutaka
4af98308e0 Version 1.2.17.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-25 15:46:02 +09:00
NIIBE Yutaka
baec3a1c1e Fix the previous commit. 2021-02-25 14:26:31 +09:00
NIIBE Yutaka
4f1325794d Require KDF Data Object for GNU/Linux emulation.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-22 10:52:44 +09:00
NIIBE Yutaka
0acf6485ae Prepare next release.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-19 16:37:08 +09:00
NIIBE Yutaka
4d15700580 Python3 update things.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-19 13:12:48 +09:00
NIIBE Yutaka
8822fcae77 Update AUTHORS.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-19 12:07:15 +09:00
NIIBE Yutaka
20a2f99691 Update Chopstx.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-19 12:07:02 +09:00
NIIBE Yutaka
acfccb729d Add changelog entries.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-18 16:00:13 +09:00
Vincent Pelletier
5283506755 tests/card_reader.py: Ignore CCID devices which report card absence.
Helps running tests on computers which have a "real" card reader in
addition to the ICC to be tested.
2021-02-18 14:42:47 +09:00
Vincent Pelletier
c688df7c2c {tests/card_reader.py,tool/gnuk_token.py}: Extend timeout.
Some devices are slow at generating RSA4096 after a key settings change,
and may take time to notice a later change to a shorter key size.

Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
2021-02-18 14:28:32 +09:00
Vincent Pelletier
594896ac57 test/feature/202_setup_passphease.feature: Fix expected PW1 value.
Since 040_passphrase_change.feature, PW1 has this value and not the reset
default.

Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
2021-02-18 14:28:27 +09:00
Vincent Pelletier
dfe046e08d tool/gnuk_token.py: Detect CCID bulk endpoints addresses.
Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
2021-02-18 14:28:23 +09:00
Vincent Pelletier
c66b01e74b test{,s}/rka_keys.py: Add missing char escape specifiers.
Removes a 2-bytes trailer to the private key template, fitting in the
2-bytes length (which itself lacked an hexadecimal escape specifier, but
without effect on the result).
Fixes the length of the DigestInfo outermost list, from 25 to the intended
49.

Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
2021-02-18 14:28:17 +09:00
NIIBE Yutaka
21a46306ae Make GNU/Linux emulation work again, with initialization support.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2021-02-18 14:04:21 +09:00
47 changed files with 1048 additions and 114 deletions

30
AUTHORS
View File

@@ -11,6 +11,16 @@ Anthony Romano:
src/main.c src/main.c
src/mod.c src/mod.c
Bertrand Jacquin
Modified:
tool/add_openpgp_authkey_from_gpgssh.py
tool/calc_precompute_table_ecc.py
tool/dfuse.py
tool/dump_mem.py
tool/get_raw_public_key.py
tool/pageant_proxy_to_gpg.py
tool/pinpadtest.py
Jeremy Drake: Jeremy Drake:
Modified: Modified:
regnual/regnual.c regnual/regnual.c
@@ -74,3 +84,23 @@ Peter Lebbing:
src/Makefile src/Makefile
Wrote: Wrote:
src/stdaln-sys.ld.in src/stdaln-sys.ld.in
Vincent Pelletier:
Modified:
test/features/202_setup_passphrase.feature
test/rsa_keys.py
tests/card_const.py
tests/card_reader.py
tests/rsa_keys.py
tool/gnuk_token.py
Wrote:
tests/card_test_ansix9p256r1.py
tests/card_test_ansix9p384r1.py
tests/card_test_ansix9p512r1.py
tests/card_test_brainpoolp256r1.py
tests/card_test_brainpoolp384r1.py
tests/card_test_brainpoolp512r1.py
tests/card_test_ed25519.py
tests/card_test_x25519.py
tests/func_pso_auth.py
tests/test_006_pso.py

124
ChangeLog
View File

@@ -1,3 +1,127 @@
2021-10-12 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.19.
* chopstx: Update to 1.20.
2021-10-11 NIIBE Yutaka <gniibe@fsij.org>
* src/configure (kdf_do): It can be overridden, now.
2021-07-01 NIIBE Yutaka <gniibe@fsij.org>
* src/configure (CONFIG): Add KDF configuration.
2021-06-10 NIIBE Yutaka <gniibe@fsij.org>
* tool/stlinkv2.py: Switch to Python3.
* tool/upgrade_by_passwd.py: Fix option handling.
2021-04-30 NIIBE Yutaka <gniibe@fsij.org>
* src/openpgp-do.c (rw_algorithm_attr): Fix writing algorithm
attribute, which may cause GC. Note that flash_enum_write needs
to call flash_enum_clear beforehand.
2021-04-28 Bertrand Jacquin <bertrand@jacquin.bzh>
* regnual/regnual.c: Include <string.h>.
2021-04-02 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.18.
2021-04-01 NIIBE Yutaka <gniibe@fsij.org>
* tool/upgrade_by_passwd.py: Check configure target and
the config in the device are same target.
2021-03-19 NIIBE Yutaka <gniibe@fsij.org>
* tests/openpgp_card.py (is_emulated_gnuk): Add.
* tests/skip_if_emulation.py: New.
* tests/skip_if_gnuk.py: New.
* tests/test_001_personalize_card.py: Skip if emulation.
* tests/test_002_personalize_reset.py: Skip if emulation.
* tests/test_003_remove_keys.py: Skip if emulation.
* tests/test_004_reset_pw3.py: Skip if emulation.
* tests/test_005_personalize_admin_less.py: Skip if emulation.
* tests/test_006_pso.py: Skip if Gnuk.
* tests/test_009_keygen.py: Skip if emulation.
* tests/test_021_personalize_admin_less.py: Rewrite.
2021-03-12 NIIBE Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_pgp_gakp): Fix patch mistake.
2021-03-01 Vincent Pelletier <plr.vincent@gmail.com>
* tests/card_const.py: Add attributes for more algos.
* tests/card_test_ansix9p256r1.py: New.
* tests/card_test_ansix9p384r1.py: New.
* tests/card_test_ansix9p512r1.py: New.
* tests/card_test_brainpoolp256r1.py: New.
* tests/card_test_brainpoolp384r1.py: New.
* tests/card_test_brainpoolp512r1.py: New.
* tests/card_test_ed25519.py: New.
* tests/card_test_x25519.py: New.
* tests/func_pso_auth.py: New.
* tests/test_006_pso.py: New.
2021-02-25 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.17.
2021-02-22 NIIBE Yutaka <gniibe@fsij.org>
* src/config.h.in (@KDF_DO_REQUIRED_DEFINE@): New.
* src/configure (KDF_DO_REQUIRED_DEFINE): New for GNU/Linux.
* src/openpgp-do.c (gpg_do_kdf_check): When LEN==0, check if
KDO data object is available.
[KDF_DO_REQUIRED] (proc_key_import): Refuse the key import when
KDF data object is not available.
* src/openpgp.c [KDF_DO_REQUIRED] (cmd_pgp_gakp): Refuse key
generation when KDF data object is not available.
2021-02-19 NIIBE Yutaka <gniibe@fsij.org>
* tool/gnuk-emulation-setup: Remove.
* tool/upgrade_by_passwd.py (main): Use tobytes.
* tool/gnuk_get_random.py: Likewise.
* tool/gnuk_remove_keys_libusb.py (main): Likewise.
Switch to Python3.
* tool/gnuk_put_binary_libusb.py (main): Use tobytes.
Switch to Python3.
* tool/gnuk_upgrade.py (main): Use tobytes.
Switch to Python3.
* chopstx: Update to 1.19.
2021-02-18 Vincent Pelletier <plr.vincent@gmail.com>
* test/features/202_setup_passphrase.feature: Fix.
* test/rsa_keys.py: Fix escape.
* tests/card_reader.py: Extend the timeout.
Handle no card.
* tests/rsa_keys.py: Fix escape.
* tool/gnuk_token.py: Avoid hard-coding the endpoints.
Longer timeout.
2021-02-18 NIIBE Yutaka <gniibe@fsij.org>
* src/configure [GNU_LINUX_EMULATION] (def_mhz): Define.
(output_vendor_product_serial_strings): Output ARCH.
* GNUK_USB_DEVICE_ID: Use "Gnuk Token" for emulation, too.
* src/main.c [GNU_LINUX_EMULATION] (main): Add initialization of
the .gnuk-flash-image file.
(gnuk_sbrk): Rename from sbrk.
2020-09-10 NIIBE Yutaka <gniibe@fsij.org> 2020-09-10 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: 1.2.16. * VERSION: 1.2.16.

View File

@@ -1,5 +1,5 @@
# VID:PID bcdDev Product_STRING Vendor_STRING # VID:PID bcdDev Product_STRING Vendor_STRING
0000:0000 0200 Gnuk Emulation Free Software Initiative of Japan 0000:0000 0200 Gnuk Token Free Software Initiative of Japan
234b:0000 0200 Gnuk Token Free Software Initiative of Japan 234b:0000 0200 Gnuk Token Free Software Initiative of Japan
20a0:4211 0200 Nitrokey Start Nitrokey 20a0:4211 0200 Nitrokey Start Nitrokey
1209:2440 0200 Gnuk Token GnuPG e.V. 1209:2440 0200 Gnuk Token GnuPG e.V.

65
NEWS
View File

@@ -1,6 +1,71 @@
Gnuk NEWS - User visible changes Gnuk NEWS - User visible changes
* Major changes in Gnuk 1.2.19
Released 2021-10-12, by NIIBE Yutaka
** KDF Data Object configuration
KDF Data Object should be highly recommended for all configurations.
Nevertheless, for backward compatibillity, in Gnuk 1.2, it is optional
by default; It is up to user to configure KDF Data Object before
importing private keys. In this situation, it is not good to
introduce new build-time option like --enable-always-require-kdf-do,
because it might wrongly encourage use of Gnuk with no KDF Data Object
setting, by confusion. If needed, please run configure:
kdf_do=required ./configure --enable-factory-reset --target...
or
kdf_do=optional ./configure --enable-factory-reset --target...
Please note that such a use of variable by shell command line is not
well supported by the configure script (for other variables), but
override of kdf_do is needed in some situations.
** Upgrade of Chopstx
We use Chopstx 1.20. This enables use with PC/SC for GNU/Linux
emulation.
* Major changes in Gnuk 1.2.18
Released 2021-04-02, by NIIBE Yutaka
** GNU/Linux emulation bug fix
This time, for GNU/Linux emulation, KDF Data Object is required before
keygen and key import, really.
** tool/upgrade_by_passwd.py
Now, it checks if the target of binary being written and the
configured target of running device are same. This check can be
skipped by -s option. Please note that FST-01 and FST-01SZ are
different target, as it's MHz is different.
* Major changes in Gnuk 1.2.17
Released 2021-02-25, by NIIBE Yutaka
** GNU/Linux: KDF Data Object is required before keygen and key import
For GNU/Linux emulation, KDF Data Object is required before keygen and
key import.
** GNU/Linux emulation
Since 1.2.10, it was not build-able because of MHZ definition. It is
build-able again, and its USB product string is now "Gnuk Token". It
has ACK button support using terminal. It now has start-up message,
and its driver show useful information to setup USBIP. When no file
for the .gnuk-flash-image file, it is automatically created.
** Removal of tool/gnuk-emulation-setup
Because it is automatically created, the tool is not needed any more.
** Upgrade of Chopstx
We use Chopstx 1.19.
* Major changes in Gnuk 1.2.16 * Major changes in Gnuk 1.2.16
Released 2020-09-10, by NIIBE Yutaka Released 2020-09-10, by NIIBE Yutaka

23
README
View File

@@ -1,14 +1,14 @@
Gnuk - An Implementation of USB Cryptographic Token for GnuPG Gnuk - An Implementation of USB Cryptographic Token for GnuPG
Version 1.2.16 Version 1.2.19
2020-09-10 2021-10-12
Niibe Yutaka Niibe Yutaka
Free Software Initiative of Japan Free Software Initiative of Japan
Release Notes Release Notes
============= =============
This is the release of Gnuk, version 1.2.16, which has major This is the release of Gnuk, version 1.2.19, which has major
incompatible changes to Gnuk 1.0.x. Specifically, it now supports incompatible changes to Gnuk 1.0.x. Specifically, it now supports
overriding key import, but importing keys (or generating keys) results overriding key import, but importing keys (or generating keys) results
password reset. Also, you need to import private keys before changing password reset. Also, you need to import private keys before changing
@@ -28,7 +28,8 @@ experimental. To use the feature, you need to use newer GnuPG (2.2.6
or later). You need to prepare the KDF-DO on your token by the or later). You need to prepare the KDF-DO on your token by the
card-edit/kdf-setup command. card-edit/kdf-setup command.
With FST-01SZ, experimental ack button support is available for test. With FST-01SZ and GNU/Linux emulation, experimental ack button support
is available for test.
What's Gnuk? What's Gnuk?
@@ -242,7 +243,7 @@ External source code
Gnuk is distributed with external source code. Gnuk is distributed with external source code.
* chopstx/ -- Chopstx 1.18 * chopstx/ -- Chopstx 1.20
We use Chopstx as the kernel for Gnuk. We use Chopstx as the kernel for Gnuk.
@@ -361,13 +362,13 @@ How to compile
You need GNU toolchain and newlib for 'arm-none-eabi' target. You need GNU toolchain and newlib for 'arm-none-eabi' target.
On Debian we can install the packages of gcc-arm-none-eabi, On Debian we can install the packages of gcc-arm-none-eabi
gdb-arm-none-eabi and its friends. I'm using: and its friends. I'm using:
binutils-arm-none-eabi 2.31.1-12+11 binutils-arm-none-eabi 2.35.2-2+14+b2
gcc-arm-none-eabi 15:7-2018-q2-6 gcc-arm-none-eabi 15:8-2019-q3-1+b1
gdb-multiarch 8.2.1-1 libnewlib-arm-none-eabi 3.3.0-1
libnewlib-arm-none-eabi 3.1.0.20181231-1 gdb-multiarch 10.1-2
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
GNU Toolchain for 'arm-none-eabi' target. GNU Toolchain for 'arm-none-eabi' target.

2
THANKS
View File

@@ -18,6 +18,7 @@ Clint Adams clint@softwarefreedom.org
Daniel Kahn Gillmor dkg@fifthhorseman.net Daniel Kahn Gillmor dkg@fifthhorseman.net
Elliott Mitchell Elliott Mitchell
Fabio Utzig utzig@apache.org Fabio Utzig utzig@apache.org
Heiko Schaefer heiko.schaefer@posteo.de
Hironobu SUZUKI hironobu@h2np.net Hironobu SUZUKI hironobu@h2np.net
Jan Suhr jan@suhr.info Jan Suhr jan@suhr.info
Jeremy Drake jeremydrake+gnuk@eacceleration.com Jeremy Drake jeremydrake+gnuk@eacceleration.com
@@ -41,5 +42,6 @@ Shane Coughlan scoughlan@openinventionnetwork.com
Stanislas Bach sbach@0g.re Stanislas Bach sbach@0g.re
Szczepan Zalega szczepan@nitrokey.com Szczepan Zalega szczepan@nitrokey.com
Vasily Evseenko Vasily Evseenko
Vincent Pelletier plr.vincent@gmail.com
Werner Koch wk@gnupg.org Werner Koch wk@gnupg.org
Yuji Imai ug@xcast.jp Yuji Imai ug@xcast.jp

View File

@@ -1 +1 @@
release/1.2.16 release/1.2.19

Submodule chopstx updated: cc49f4ef23...a6b96fe434

View File

@@ -26,6 +26,8 @@
* ReGNUal * ReGNUal
*/ */
#include <string.h>
#include "types.h" #include "types.h"
#include "usb_lld.h" #include "usb_lld.h"
#include "sys.h" #include "sys.h"

View File

@@ -12,3 +12,4 @@
@LIFE_CYCLE_MANAGEMENT_DEFINE@ @LIFE_CYCLE_MANAGEMENT_DEFINE@
@ACKBTN_DEFINE@ @ACKBTN_DEFINE@
@SERIALNO_STR_LEN_DEFINE@ @SERIALNO_STR_LEN_DEFINE@
@KDF_DO_REQUIRED_DEFINE@

23
src/configure vendored
View File

@@ -6,7 +6,7 @@ nl=$'\n'
# #
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka # This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
# #
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 # Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2021
# Free Software Initiative of Japan # Free Software Initiative of Japan
# #
# This file is a part of Gnuk, a GnuPG USB Token implementation. # This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -46,6 +46,7 @@ hid_card_change=no
factory_reset=no factory_reset=no
ackbtn_support=yes ackbtn_support=yes
flash_override="" flash_override=""
kdf_do=${kdf_do:-optional}
# For emulation # For emulation
prefix=/usr/local prefix=/usr/local
exec_prefix='${prefix}' exec_prefix='${prefix}'
@@ -210,26 +211,28 @@ FST_01SZ)
;; ;;
esac esac
def_mhz="-DMHZ=$MHZ"
if test "$target" = "GNU_LINUX"; then if test "$target" = "GNU_LINUX"; then
ldscript="" ldscript=""
chip="gnu-linux" chip="gnu-linux"
arch="gnu-linux"
emulation="yes" emulation="yes"
cross="" cross=""
mcu="none" mcu="none"
kdf_do=${kdf_do:-required}
def_emulation="-DGNU_LINUX_EMULATION" def_emulation="-DGNU_LINUX_EMULATION"
def_memory_size="-DMEMORY_SIZE=1024" def_memory_size="-DMEMORY_SIZE=1024"
def_mhz=""
enable_hexoutput="" enable_hexoutput=""
libs="-lpthread" libs="-lpthread"
else else
ldscript="gnuk.ld" ldscript="gnuk.ld"
chip="stm32f103" chip="stm32f103"
arch="cortex-m"
emulation="" emulation=""
cross="arm-none-eabi-" cross="arm-none-eabi-"
mcu="cortex-m3" mcu="cortex-m3"
def_emulation="" def_emulation=""
def_memory_size="-DMEMORY_SIZE=$MEMORY_SIZE" def_memory_size="-DMEMORY_SIZE=$MEMORY_SIZE"
def_mhz="-DMHZ=$MHZ"
enable_hexoutput=yes enable_hexoutput=yes
libs="" libs=""
fi fi
@@ -337,6 +340,14 @@ else
echo "Acknowledge button is not supported" echo "Acknowledge button is not supported"
fi fi
# KDF Data Object is always required for GNU/Linux emulation
if test "$kdf_do" = "required"; then
KDF_DO_REQUIRED_DEFINE="#define KDF_DO_REQUIRED 1"
echo "KDF DO is required before key import/generation"
else
KDF_DO_REQUIRED_DEFINE="#undef KDF_DO_REQUIRED"
fi
### !!! Replace following string of "FSIJ" to yours !!! #### ### !!! Replace following string of "FSIJ" to yours !!! ####
SERIALNO="FSIJ-$(sed -e 's%^[^/]*/%%' <../VERSION)-" SERIALNO="FSIJ-$(sed -e 's%^[^/]*/%%' <../VERSION)-"
@@ -344,7 +355,7 @@ SERIALNO_STR_LEN_DEFINE="#define SERIALNO_STR_LEN ${#SERIALNO}"
if test "$sys1_compat" = "yes"; then if test "$sys1_compat" = "yes"; then
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset" CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset:kdf=$kdf_do"
else else
if test "$with_dfu" = "yes"; then if test "$with_dfu" = "yes"; then
echo "Common binary can't support DFU loader, don't use --with-dfu." >&2 echo "Common binary can't support DFU loader, don't use --with-dfu." >&2
@@ -354,7 +365,7 @@ else
FLASH_PAGE_SIZE=2048 FLASH_PAGE_SIZE=2048
FLASH_SIZE=128 FLASH_SIZE=128
MEMORY_SIZE=20 MEMORY_SIZE=20
CONFIG="common:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset" CONFIG="common:debug=$debug:pinpad=$pinpad:certdo=$certdo:factory_reset=$factory_reset:kdf=$kdf_do"
fi fi
output_vid_pid_version () { output_vid_pid_version () {
@@ -470,6 +481,7 @@ fi
(echo "CHIP=$chip"; (echo "CHIP=$chip";
echo "ARCH=$arch";
echo "EMULATION=$emulation"; echo "EMULATION=$emulation";
echo "CROSS=$cross"; echo "CROSS=$cross";
echo "MCU=$mcu"; echo "MCU=$mcu";
@@ -519,5 +531,6 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
-e "s/@LIFE_CYCLE_MANAGEMENT_DEFINE@/$LIFE_CYCLE_MANAGEMENT_DEFINE/" \ -e "s/@LIFE_CYCLE_MANAGEMENT_DEFINE@/$LIFE_CYCLE_MANAGEMENT_DEFINE/" \
-e "s/@ACKBTN_DEFINE@/$ACKBTN_DEFINE/" \ -e "s/@ACKBTN_DEFINE@/$ACKBTN_DEFINE/" \
-e "s/@SERIALNO_STR_LEN_DEFINE@/$SERIALNO_STR_LEN_DEFINE/" \ -e "s/@SERIALNO_STR_LEN_DEFINE@/$SERIALNO_STR_LEN_DEFINE/" \
-e "s/@KDF_DO_REQUIRED_DEFINE@/$KDF_DO_REQUIRED_DEFINE/" \
< config.h.in > config.h < config.h.in > config.h
exit 0 exit 0

View File

@@ -1,7 +1,7 @@
/* /*
* main.c - main routine of Gnuk * main.c - main routine of Gnuk
* *
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018 * Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018, 2021
* Free Software Initiative of Japan * Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@@ -36,6 +36,11 @@
#include "usb-cdc.h" #include "usb-cdc.h"
#include "random.h" #include "random.h"
#ifdef GNU_LINUX_EMULATION #ifdef GNU_LINUX_EMULATION
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define main emulated_main #define main emulated_main
@@ -372,6 +377,34 @@ main (int argc, const char *argv[])
else else
flash_image_path = argv[1]; flash_image_path = argv[1];
if (access (flash_image_path, F_OK) < 0)
{
int fd;
char buf[8192];
memset (buf, 0xff, sizeof buf);
memset (buf+4*1024, 0, 2);
fd = open (flash_image_path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
if (fd < 0)
{
perror ("creating flash file");
exit (1);
}
if (write (fd, buf, sizeof buf) != sizeof buf)
{
perror ("initializing flash file");
close (fd);
exit (1);
}
close (fd);
}
puts ("Gnuk (emulation with USBIP), a GnuPG USB Token implementation");
puts ("Copyright (C) 2021 Free Software Initiative of Japan");
puts ("This is free software under GPLv3+.");
flash_addr = flash_init (flash_image_path); flash_addr = flash_init (flash_image_path);
flash_addr_key_storage_start = (uint8_t *)flash_addr; flash_addr_key_storage_start = (uint8_t *)flash_addr;
flash_addr_data_storage_start = (uint8_t *)flash_addr + 4096; flash_addr_data_storage_start = (uint8_t *)flash_addr + 4096;
@@ -563,11 +596,11 @@ gnuk_malloc_init (void)
} }
static void * static void *
sbrk (size_t size) gnuk_sbrk (intptr_t size)
{ {
void *p = (void *)heap_p; void *p = (void *)heap_p;
if ((size_t)(HEAP_END - heap_p) < size) if ((HEAP_END - heap_p) < size)
return NULL; return NULL;
heap_p += size; heap_p += size;
@@ -603,7 +636,7 @@ gnuk_malloc (size_t size)
{ {
if (m == NULL) if (m == NULL)
{ {
m = (struct mem_head *)sbrk (size); m = (struct mem_head *)gnuk_sbrk (size);
if (m) if (m)
m->size = size; m->size = size;
break; break;

View File

@@ -815,6 +815,8 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
else if (algo == ALGO_RSA2K && *algo_attr_pp != NULL) else if (algo == ALGO_RSA2K && *algo_attr_pp != NULL)
{ {
gpg_reset_algo_attr (kk); gpg_reset_algo_attr (kk);
/* Read it again, since GC may occur. */
algo_attr_pp = get_algo_attr_pointer (kk);
flash_enum_clear (algo_attr_pp); flash_enum_clear (algo_attr_pp);
if (*algo_attr_pp != NULL) if (*algo_attr_pp != NULL)
return 0; return 0;
@@ -823,6 +825,10 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
(*algo_attr_pp != NULL && (*algo_attr_pp)[1] != algo)) (*algo_attr_pp != NULL && (*algo_attr_pp)[1] != algo))
{ {
gpg_reset_algo_attr (kk); gpg_reset_algo_attr (kk);
/* Read it again, since GC may occur. */
algo_attr_pp = get_algo_attr_pointer (kk);
if (*algo_attr_pp)
flash_enum_clear (algo_attr_pp);
*algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo); *algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo);
if (*algo_attr_pp == NULL) if (*algo_attr_pp == NULL)
return 0; return 0;
@@ -986,11 +992,25 @@ rw_kdf (uint16_t tag, int with_tag, const uint8_t *data, int len, int is_write)
} }
} }
/*
* Check LEN is valid for HOW_MANY of passphrase string.
*
* HOW_MANY = 1: LEN is valid for a single passphrase string.
* HOW_MANY = 2: LEN is valid for two single passphrase strings.
* This is used to change passphrase.
* The second passphrase may be nothing.
*
* LEN = 0: Check if KDF-DO is available.
*/
int int
gpg_do_kdf_check (int len, int how_many) gpg_do_kdf_check (int len, int how_many)
{ {
const uint8_t *kdf_do = do_ptr[NR_DO_KDF]; const uint8_t *kdf_do = do_ptr[NR_DO_KDF];
if (len == 0)
return kdf_do != NULL;
if (kdf_do) if (kdf_do)
{ {
const uint8_t *kdf_spec = kdf_do+1; const uint8_t *kdf_spec = kdf_do+1;
@@ -1598,6 +1618,13 @@ proc_key_import (const uint8_t *data, int len)
const uint8_t *p = data; const uint8_t *p = data;
uint8_t pubkey[512]; uint8_t pubkey[512];
#ifdef KDF_DO_REQUIRED
const uint8_t *kdf_do = do_ptr[NR_DO_KDF];
if (kdf_do == NULL)
return 0; /* Error. */
#endif
if (admin_authorized == BY_ADMIN) if (admin_authorized == BY_ADMIN)
keystring_admin = keystring_md_pw3; keystring_admin = keystring_md_pw3;
else else

View File

@@ -738,7 +738,12 @@ cmd_pgp_gakp (struct eventflag *ccid_comm)
{ {
if (!ac_check_status (AC_ADMIN_AUTHORIZED)) if (!ac_check_status (AC_ADMIN_AUTHORIZED))
GPG_SECURITY_FAILURE (); GPG_SECURITY_FAILURE ();
gpg_do_keygen (&apdu.cmd_apdu_data[0]); #ifdef KDF_DO_REQUIRED
else if (!gpg_do_kdf_check (0, 0))
GPG_CONDITION_NOT_SATISFIED ();
#endif
else
gpg_do_keygen (&apdu.cmd_apdu_data[0]);
} }
} }

View File

@@ -4,7 +4,7 @@ Feature: setup pass phrase
A token should support pass phrase: PW1, PW3 and reset code A token should support pass phrase: PW1, PW3 and reset code
Scenario: setup PW1 (admin-full mode) Scenario: setup PW1 (admin-full mode)
Given cmd_change_reference_data with 1 and "123456user pass phrase" Given cmd_change_reference_data with 1 and "another user pass phraseuser pass phrase"
Then it should get success Then it should get success
Scenario: verify PW1 (1) Scenario: verify PW1 (1)

View File

@@ -70,11 +70,11 @@ def build_privkey_template_for_remove(openpgp_keyno):
keyspec = b'\xb8' keyspec = b'\xb8'
else: else:
keyspec = b'\xa4' keyspec = b'\xa4'
return b'\x4d\02' + keyspec + b'\0x00' return b'\x4d\x02' + keyspec + b'\x00'
def compute_digestinfo(msg): def compute_digestinfo(msg):
digest = sha256(msg).digest() digest = sha256(msg).digest()
prefix = b'\x30\31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20' prefix = b'\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'
return prefix + digest return prefix + digest
# egcd and modinv are from wikibooks # egcd and modinv are from wikibooks

View File

@@ -2,3 +2,11 @@ FACTORY_PASSPHRASE_PW1=b"123456"
FACTORY_PASSPHRASE_PW3=b"12345678" FACTORY_PASSPHRASE_PW3=b"12345678"
KEY_ATTRIBUTES_RSA4K=b"\x01\x10\x00\x00\x20\x00" KEY_ATTRIBUTES_RSA4K=b"\x01\x10\x00\x00\x20\x00"
KEY_ATTRIBUTES_RSA2K=b"\x01\x08\x00\x00\x20\x00" KEY_ATTRIBUTES_RSA2K=b"\x01\x08\x00\x00\x20\x00"
KEY_ATTRIBUTES_ECDH_ANSIX9P256R1=b"\x12\x2a\x86\x48\xce\x3d\x03\x01\x07"
KEY_ATTRIBUTES_ECDH_ANSIX9P384R1=b"\x12\x2b\x81\x04\x00\x22"
KEY_ATTRIBUTES_ECDH_ANSIX9P521R1=b"\x12\x2b\x81\x04\x00\x23"
KEY_ATTRIBUTES_ECDH_BRAINPOOLP256R1=b"\x12\x2b\x24\x03\x03\x02\x08\x01\x01\x07"
KEY_ATTRIBUTES_ECDH_BRAINPOOLP384R1=b"\x12\x2b\x24\x03\x03\x02\x08\x01\x01\x0b"
KEY_ATTRIBUTES_ECDH_BRAINPOOLP512R1=b"\x12\x2b\x24\x03\x03\x02\x08\x01\x01\x0d"
KEY_ATTRIBUTES_X25519=b"\x12\x2b\x06\x01\x04\x01\x97\x55\x01\x05\x01"
KEY_ATTRIBUTES_ED25519=b"\x16\x2b\x06\x01\x04\x01\xda\x47\x0f\x01"

View File

@@ -126,9 +126,12 @@ class CardReader(object):
# intf.extra_descriptors[41] # intf.extra_descriptors[41]
self.__dev = dev self.__dev = dev
self.__timeout = 10000 self.__timeout = 100000
self.__seq = 0 self.__seq = 0
if self.ccid_get_status() & 0x03 not in (0, 1):
raise ValueError("Card absent")
def get_string(self, num): def get_string(self, num):
return get_string(self.__dev, num) return get_string(self.__dev, num)

View File

@@ -0,0 +1,58 @@
"""
card_test_ansix9p256r1.py - test ansix9p256r1 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_AnsiX9P256R1(object):
def test_ECDH_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(2, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc5903#section-8.1
assert_ec_pso(
card=card,
key_index=1,
key_attributes=KEY_ATTRIBUTES_ECDH_ANSIX9P256R1,
key_attribute_caption='ECDH ansix9p256r1',
private_key=(
b'\xC8\x8F\x01\xF5\x10\xD9\xAC\x3F\x70\xA2\x92\xDA\xA2\x31\x6D\xE5'
b'\x44\xE9\xAA\xB8\xAF\xE8\x40\x49\xC6\x2A\x9C\x57\x86\x2D\x14\x33'
),
expected_public_key=(
b'\x04'
b'\xDA\xD0\xB6\x53\x94\x22\x1C\xF9\xB0\x51\xE1\xFE\xCA\x57\x87\xD0'
b'\x98\xDF\xE6\x37\xFC\x90\xB9\xEF\x94\x5D\x0C\x37\x72\x58\x11\x80'
b'\x52\x71\xA0\x46\x1C\xDB\x82\x52\xD6\x1F\x1C\x45\x6F\xA3\xE5\x9A'
b'\xB1\xF4\x5B\x33\xAC\xCF\x5F\x58\x38\x9E\x05\x77\xB8\x99\x0B\xB3'
),
pso_input=(
b'\xa6\x46\x7f\x49\x43\x86\x41'
b'\x04'
b'\xD1\x2D\xFB\x52\x89\xC8\xD4\xF8\x12\x08\xB7\x02\x70\x39\x8C\x34'
b'\x22\x96\x97\x0A\x0B\xCC\xB7\x4C\x73\x6F\xC7\x55\x44\x94\xBF\x63'
b'\x56\xFB\xF3\xCA\x36\x6C\xC2\x3E\x81\x57\x85\x4C\x13\xC5\x8D\x6A'
b'\xAC\x23\xF0\x46\xAD\xA3\x0F\x83\x53\xE7\x4F\x33\x03\x98\x72\xAB'
),
expected_pso_output=(
b'\xD6\x84\x0F\x6B\x42\xF6\xED\xAF\xD1\x31\x16\xE0\xE1\x25\x65\x20'
b'\x2F\xEF\x8E\x9E\xCE\x7D\xCE\x03\x81\x24\x64\xD0\x4B\x94\x42\xDE'
),
)

View File

@@ -0,0 +1,64 @@
"""
card_test_ansix9p384r1.py - test ansix9p384r1 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_AnsiX9P384R1(object):
def test_ECDH_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(2, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc5903#section-8.2
assert_ec_pso(
card=card,
key_index=1,
key_attributes=KEY_ATTRIBUTES_ECDH_ANSIX9P384R1,
key_attribute_caption='ECDH ansix9p384r1',
private_key=(
b'\x09\x9F\x3C\x70\x34\xD4\xA2\xC6\x99\x88\x4D\x73\xA3\x75\xA6\x7F'
b'\x76\x24\xEF\x7C\x6B\x3C\x0F\x16\x06\x47\xB6\x74\x14\xDC\xE6\x55'
b'\xE3\x5B\x53\x80\x41\xE6\x49\xEE\x3F\xAE\xF8\x96\x78\x3A\xB1\x94'
),
expected_public_key=(
b'\x04'
b'\x66\x78\x42\xD7\xD1\x80\xAC\x2C\xDE\x6F\x74\xF3\x75\x51\xF5\x57'
b'\x55\xC7\x64\x5C\x20\xEF\x73\xE3\x16\x34\xFE\x72\xB4\xC5\x5E\xE6'
b'\xDE\x3A\xC8\x08\xAC\xB4\xBD\xB4\xC8\x87\x32\xAE\xE9\x5F\x41\xAA'
b'\x94\x82\xED\x1F\xC0\xEE\xB9\xCA\xFC\x49\x84\x62\x5C\xCF\xC2\x3F'
b'\x65\x03\x21\x49\xE0\xE1\x44\xAD\xA0\x24\x18\x15\x35\xA0\xF3\x8E'
b'\xEB\x9F\xCF\xF3\xC2\xC9\x47\xDA\xE6\x9B\x4C\x63\x45\x73\xA8\x1C'
),
pso_input=(
b'\xa6\x66\x7f\x49\x63\x86\x61'
b'\x04'
b'\xE5\x58\xDB\xEF\x53\xEE\xCD\xE3\xD3\xFC\xCF\xC1\xAE\xA0\x8A\x89'
b'\xA9\x87\x47\x5D\x12\xFD\x95\x0D\x83\xCF\xA4\x17\x32\xBC\x50\x9D'
b'\x0D\x1A\xC4\x3A\x03\x36\xDE\xF9\x6F\xDA\x41\xD0\x77\x4A\x35\x71'
b'\xDC\xFB\xEC\x7A\xAC\xF3\x19\x64\x72\x16\x9E\x83\x84\x30\x36\x7F'
b'\x66\xEE\xBE\x3C\x6E\x70\xC4\x16\xDD\x5F\x0C\x68\x75\x9D\xD1\xFF'
b'\xF8\x3F\xA4\x01\x42\x20\x9D\xFF\x5E\xAA\xD9\x6D\xB9\xE6\x38\x6C'
),
expected_pso_output=(
b'\x11\x18\x73\x31\xC2\x79\x96\x2D\x93\xD6\x04\x24\x3F\xD5\x92\xCB'
b'\x9D\x0A\x92\x6F\x42\x2E\x47\x18\x75\x21\x28\x7E\x71\x56\xC5\xC4'
b'\xD6\x03\x13\x55\x69\xB9\xE9\xD0\x9C\xF5\xD4\xA2\x70\xF5\x97\x46'
),
)

View File

@@ -0,0 +1,76 @@
"""
card_test_ansix9p512r1.py - test ansix9p512r1 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_AnsiX9P512R1(object):
def test_ECDH_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(2, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc5903#section-8.3
assert_ec_pso(
card=card,
key_index=1,
key_attributes=KEY_ATTRIBUTES_ECDH_ANSIX9P521R1,
key_attribute_caption='ECDH ansix9p521r1',
private_key=(
b'\x00\x37\xAD\xE9\x31\x9A\x89\xF4\xDA\xBD\xB3\xEF\x41\x1A\xAC\xCC'
b'\xA5\x12\x3C\x61\xAC\xAB\x57\xB5\x39\x3D\xCE\x47\x60\x81\x72\xA0'
b'\x95\xAA\x85\xA3\x0F\xE1\xC2\x95\x2C\x67\x71\xD9\x37\xBA\x97\x77'
b'\xF5\x95\x7B\x26\x39\xBA\xB0\x72\x46\x2F\x68\xC2\x7A\x57\x38\x2D'
b'\x4A\x52'
),
expected_public_key=(
b'\x04'
b'\x00\x15\x41\x7E\x84\xDB\xF2\x8C\x0A\xD3\xC2\x78\x71\x33\x49\xDC'
b'\x7D\xF1\x53\xC8\x97\xA1\x89\x1B\xD9\x8B\xAB\x43\x57\xC9\xEC\xBE'
b'\xE1\xE3\xBF\x42\xE0\x0B\x8E\x38\x0A\xEA\xE5\x7C\x2D\x10\x75\x64'
b'\x94\x18\x85\x94\x2A\xF5\xA7\xF4\x60\x17\x23\xC4\x19\x5D\x17\x6C'
b'\xED\x3E'
b'\x01\x7C\xAE\x20\xB6\x64\x1D\x2E\xEB\x69\x57\x86\xD8\xC9\x46\x14'
b'\x62\x39\xD0\x99\xE1\x8E\x1D\x5A\x51\x4C\x73\x9D\x7C\xB4\xA1\x0A'
b'\xD8\xA7\x88\x01\x5A\xC4\x05\xD7\x79\x9D\xC7\x5E\x7B\x7D\x5B\x6C'
b'\xF2\x26\x1A\x6A\x7F\x15\x07\x43\x8B\xF0\x1B\xEB\x6C\xA3\x92\x6F'
b'\x95\x82'
),
pso_input=(
b'\xa6\x81\x8c\x7f\x49\x81\x88\x86\x81\x85'
b'\x04'
b'\x00\xD0\xB3\x97\x5A\xC4\xB7\x99\xF5\xBE\xA1\x6D\x5E\x13\xE9\xAF'
b'\x97\x1D\x5E\x9B\x98\x4C\x9F\x39\x72\x8B\x5E\x57\x39\x73\x5A\x21'
b'\x9B\x97\xC3\x56\x43\x6A\xDC\x6E\x95\xBB\x03\x52\xF6\xBE\x64\xA6'
b'\xC2\x91\x2D\x4E\xF2\xD0\x43\x3C\xED\x2B\x61\x71\x64\x00\x12\xD9'
b'\x46\x0F'
b'\x01\x5C\x68\x22\x63\x83\x95\x6E\x3B\xD0\x66\xE7\x97\xB6\x23\xC2'
b'\x7C\xE0\xEA\xC2\xF5\x51\xA1\x0C\x2C\x72\x4D\x98\x52\x07\x7B\x87'
b'\x22\x0B\x65\x36\xC5\xC4\x08\xA1\xD2\xAE\xBB\x8E\x86\xD6\x78\xAE'
b'\x49\xCB\x57\x09\x1F\x47\x32\x29\x65\x79\xAB\x44\xFC\xD1\x7F\x0F'
b'\xC5\x6A'
),
expected_pso_output=(
b'\x01\x14\x4C\x7D\x79\xAE\x69\x56\xBC\x8E\xDB\x8E\x7C\x78\x7C\x45'
b'\x21\xCB\x08\x6F\xA6\x44\x07\xF9\x78\x94\xE5\xE6\xB2\xD7\x9B\x04'
b'\xD1\x42\x7E\x73\xCA\x4B\xAA\x24\x0A\x34\x78\x68\x59\x81\x0C\x06'
b'\xB3\xC7\x15\xA3\xA8\xCC\x31\x51\xF2\xBE\xE4\x17\x99\x6D\x19\xF3'
b'\xDD\xEA'
),
)

View File

@@ -0,0 +1,58 @@
"""
card_test_brainpoolp256r1.py - test brainpoolp256r1 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_BrainpoolP256R1(object):
def test_ECDH_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(2, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc7027#appendix-A.1
assert_ec_pso(
card=card,
key_index=1,
key_attributes=KEY_ATTRIBUTES_ECDH_BRAINPOOLP256R1,
key_attribute_caption='ECDH brainpoolp256r1',
private_key=(
b'\x81\xDB\x1E\xE1\x00\x15\x0F\xF2\xEA\x33\x8D\x70\x82\x71\xBE\x38'
b'\x30\x0C\xB5\x42\x41\xD7\x99\x50\xF7\x7B\x06\x30\x39\x80\x4F\x1D'
),
expected_public_key=(
b'\x04'
b'\x44\x10\x6E\x91\x3F\x92\xBC\x02\xA1\x70\x5D\x99\x53\xA8\x41\x4D'
b'\xB9\x5E\x1A\xAA\x49\xE8\x1D\x9E\x85\xF9\x29\xA8\xE3\x10\x0B\xE5'
b'\x8A\xB4\x84\x6F\x11\xCA\xCC\xB7\x3C\xE4\x9C\xBD\xD1\x20\xF5\xA9'
b'\x00\xA6\x9F\xD3\x2C\x27\x22\x23\xF7\x89\xEF\x10\xEB\x08\x9B\xDC'
),
pso_input=(
b'\xa6\x46\x7f\x49\x43\x86\x41'
b'\x04'
b'\x8D\x2D\x68\x8C\x6C\xF9\x3E\x11\x60\xAD\x04\xCC\x44\x29\x11\x7D'
b'\xC2\xC4\x18\x25\xE1\xE9\xFC\xA0\xAD\xDD\x34\xE6\xF1\xB3\x9F\x7B'
b'\x99\x0C\x57\x52\x08\x12\xBE\x51\x26\x41\xE4\x70\x34\x83\x21\x06'
b'\xBC\x7D\x3E\x8D\xD0\xE4\xC7\xF1\x13\x6D\x70\x06\x54\x7C\xEC\x6A'
),
expected_pso_output=(
b'\x89\xAF\xC3\x9D\x41\xD3\xB3\x27\x81\x4B\x80\x94\x0B\x04\x25\x90'
b'\xF9\x65\x56\xEC\x91\xE6\xAE\x79\x39\xBC\xE3\x1F\x3A\x18\xBF\x2B'
),
)

View File

@@ -0,0 +1,64 @@
"""
card_test_brainpoolp384r1.py - test brainpoolp384r1 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_BrainpoolP384R1(object):
def test_ECDH_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(2, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc7027#appendix-A.2
assert_ec_pso(
card=card,
key_index=1,
key_attributes=KEY_ATTRIBUTES_ECDH_BRAINPOOLP384R1,
key_attribute_caption='ECDH brainpoolp384r1',
private_key=(
b'\x1E\x20\xF5\xE0\x48\xA5\x88\x6F\x1F\x15\x7C\x74\xE9\x1B\xDE\x2B'
b'\x98\xC8\xB5\x2D\x58\xE5\x00\x3D\x57\x05\x3F\xC4\xB0\xBD\x65\xD6'
b'\xF1\x5E\xB5\xD1\xEE\x16\x10\xDF\x87\x07\x95\x14\x36\x27\xD0\x42'
),
expected_public_key=(
b'\x04'
b'\x68\xB6\x65\xDD\x91\xC1\x95\x80\x06\x50\xCD\xD3\x63\xC6\x25\xF4'
b'\xE7\x42\xE8\x13\x46\x67\xB7\x67\xB1\xB4\x76\x79\x35\x88\xF8\x85'
b'\xAB\x69\x8C\x85\x2D\x4A\x6E\x77\xA2\x52\xD6\x38\x0F\xCA\xF0\x68'
b'\x55\xBC\x91\xA3\x9C\x9E\xC0\x1D\xEE\x36\x01\x7B\x7D\x67\x3A\x93'
b'\x12\x36\xD2\xF1\xF5\xC8\x39\x42\xD0\x49\xE3\xFA\x20\x60\x74\x93'
b'\xE0\xD0\x38\xFF\x2F\xD3\x0C\x2A\xB6\x7D\x15\xC8\x5F\x7F\xAA\x59'
),
pso_input=(
b'\xa6\x66\x7f\x49\x63\x86\x61'
b'\x04'
b'\x4D\x44\x32\x6F\x26\x9A\x59\x7A\x5B\x58\xBB\xA5\x65\xDA\x55\x56'
b'\xED\x7F\xD9\xA8\xA9\xEB\x76\xC2\x5F\x46\xDB\x69\xD1\x9D\xC8\xCE'
b'\x6A\xD1\x8E\x40\x4B\x15\x73\x8B\x20\x86\xDF\x37\xE7\x1D\x1E\xB4'
b'\x62\xD6\x92\x13\x6D\xE5\x6C\xBE\x93\xBF\x5F\xA3\x18\x8E\xF5\x8B'
b'\xC8\xA3\xA0\xEC\x6C\x1E\x15\x1A\x21\x03\x8A\x42\xE9\x18\x53\x29'
b'\xB5\xB2\x75\x90\x3D\x19\x2F\x8D\x4E\x1F\x32\xFE\x9C\xC7\x8C\x48'
),
expected_pso_output=(
b'\x0B\xD9\xD3\xA7\xEA\x0B\x3D\x51\x9D\x09\xD8\xE4\x8D\x07\x85\xFB'
b'\x74\x4A\x6B\x35\x5E\x63\x04\xBC\x51\xC2\x29\xFB\xBC\xE2\x39\xBB'
b'\xAD\xF6\x40\x37\x15\xC3\x5D\x4F\xB2\xA5\x44\x4F\x57\x5D\x4F\x42'
),
)

View File

@@ -0,0 +1,70 @@
"""
card_test_brainpoolp512r1.py - test brainpoolp512r1 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_BrainpoolP512R1(object):
def test_ECDH_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(2, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc7027#appendix-A.3
assert_ec_pso(
card=card,
key_index=1,
key_attributes=KEY_ATTRIBUTES_ECDH_BRAINPOOLP512R1,
key_attribute_caption='ECDH brainpoolp512r1',
private_key=(
b'\x16\x30\x2F\xF0\xDB\xBB\x5A\x8D\x73\x3D\xAB\x71\x41\xC1\xB4\x5A'
b'\xCB\xC8\x71\x59\x39\x67\x7F\x6A\x56\x85\x0A\x38\xBD\x87\xBD\x59'
b'\xB0\x9E\x80\x27\x96\x09\xFF\x33\x3E\xB9\xD4\xC0\x61\x23\x1F\xB2'
b'\x6F\x92\xEE\xB0\x49\x82\xA5\xF1\xD1\x76\x4C\xAD\x57\x66\x54\x22'
),
expected_public_key=(
b'\x04'
b'\x0A\x42\x05\x17\xE4\x06\xAA\xC0\xAC\xDC\xE9\x0F\xCD\x71\x48\x77'
b'\x18\xD3\xB9\x53\xEF\xD7\xFB\xEC\x5F\x7F\x27\xE2\x8C\x61\x49\x99'
b'\x93\x97\xE9\x1E\x02\x9E\x06\x45\x7D\xB2\xD3\xE6\x40\x66\x8B\x39'
b'\x2C\x2A\x7E\x73\x7A\x7F\x0B\xF0\x44\x36\xD1\x16\x40\xFD\x09\xFD'
b'\x72\xE6\x88\x2E\x8D\xB2\x8A\xAD\x36\x23\x7C\xD2\x5D\x58\x0D\xB2'
b'\x37\x83\x96\x1C\x8D\xC5\x2D\xFA\x2E\xC1\x38\xAD\x47\x2A\x0F\xCE'
b'\xF3\x88\x7C\xF6\x2B\x62\x3B\x2A\x87\xDE\x5C\x58\x83\x01\xEA\x3E'
b'\x5F\xC2\x69\xB3\x73\xB6\x07\x24\xF5\xE8\x2A\x6A\xD1\x47\xFD\xE7'
),
pso_input=(
b'\xa6\x81\x88\x7f\x49\x81\x84\x86\x81\x81'
b'\x04'
b'\x9D\x45\xF6\x6D\xE5\xD6\x7E\x2E\x6D\xB6\xE9\x3A\x59\xCE\x0B\xB4'
b'\x81\x06\x09\x7F\xF7\x8A\x08\x1D\xE7\x81\xCD\xB3\x1F\xCE\x8C\xCB'
b'\xAA\xEA\x8D\xD4\x32\x0C\x41\x19\xF1\xE9\xCD\x43\x7A\x2E\xAB\x37'
b'\x31\xFA\x96\x68\xAB\x26\x8D\x87\x1D\xED\xA5\x5A\x54\x73\x19\x9F'
b'\x2F\xDC\x31\x30\x95\xBC\xDD\x5F\xB3\xA9\x16\x36\xF0\x7A\x95\x9C'
b'\x8E\x86\xB5\x63\x6A\x1E\x93\x0E\x83\x96\x04\x9C\xB4\x81\x96\x1D'
b'\x36\x5C\xC1\x14\x53\xA0\x6C\x71\x98\x35\x47\x5B\x12\xCB\x52\xFC'
b'\x3C\x38\x3B\xCE\x35\xE2\x7E\xF1\x94\x51\x2B\x71\x87\x62\x85\xFA'
),
expected_pso_output=(
b'\xA7\x92\x70\x98\x65\x5F\x1F\x99\x76\xFA\x50\xA9\xD5\x66\x86\x5D'
b'\xC5\x30\x33\x18\x46\x38\x1C\x87\x25\x6B\xAF\x32\x26\x24\x4B\x76'
b'\xD3\x64\x03\xC0\x24\xD7\xBB\xF0\xAA\x08\x03\xEA\xFF\x40\x5D\x3D'
b'\x24\xF1\x1A\x9B\x5C\x0B\xEF\x67\x9F\xE1\x45\x4B\x21\xC4\xCD\x1F'
),
)

View File

@@ -0,0 +1,51 @@
"""
card_test_ed25519.py - test ed25519 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
import hashlib
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_ED25519(object):
def test_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(1, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc8032#section-7.3
assert_ec_pso(
card=card,
key_index=0,
key_attributes=KEY_ATTRIBUTES_ED25519,
key_attribute_caption='ed25519',
private_key=(
b'\x83\x3f\xe6\x24\x09\x23\x7b\x9d\x62\xec\x77\x58\x75\x20\x91\x1e'
b'\x9a\x75\x9c\xec\x1d\x19\x75\x5b\x7d\xa9\x01\xb9\x6d\xca\x3d\x42'
),
expected_public_key=(
b'\xec\x17\x2b\x93\xad\x5e\x56\x3b\xf4\x93\x2c\x70\xe1\x24\x50\x34'
b'\xc3\x54\x67\xef\x2e\xfd\x4d\x64\xeb\xf8\x19\x68\x34\x67\xe2\xbf'
),
pso_input=hashlib.sha512(b'\x61\x62\x63').digest(),
expected_pso_output=(
b'\x98\xa7\x02\x22\xf0\xb8\x12\x1a\xa9\xd3\x0f\x81\x3d\x68\x3f\x80'
b'\x9e\x46\x2b\x46\x9c\x7f\xf8\x76\x39\x49\x9b\xb9\x4e\x6d\xae\x41'
b'\x31\xf8\x50\x42\x46\x3c\x2a\x35\x5a\x20\x03\xd0\x62\xad\xf5\xaa'
b'\xa1\x0b\x8c\x61\xe6\x36\x06\x2a\xaa\xd1\x1c\x2a\x26\x08\x34\x06'
),
)

52
tests/card_test_x25519.py Normal file
View File

@@ -0,0 +1,52 @@
"""
card_test_x25519.py - test x25519 support
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
from func_pso_auth import assert_ec_pso
from card_const import *
class Test_Card_X25519(object):
def test_reference_vectors(self, card):
assert card.verify(3, FACTORY_PASSPHRASE_PW3)
assert card.verify(2, FACTORY_PASSPHRASE_PW1)
# https://tools.ietf.org/html/rfc7748#section-6.1
assert_ec_pso(
card=card,
key_index=1,
key_attributes=KEY_ATTRIBUTES_X25519,
key_attribute_caption='x25519',
private_key=(
b'\x77\x07\x6d\x0a\x73\x18\xa5\x7d\x3c\x16\xc1\x72\x51\xb2\x66\x45'
b'\xdf\x4c\x2f\x87\xeb\xc0\x99\x2a\xb1\x77\xfb\xa5\x1d\xb9\x2c\x2a'
),
expected_public_key=(
b'\x85\x20\xf0\x09\x89\x30\xa7\x54\x74\x8b\x7d\xdc\xb4\x3e\xf7\x5a'
b'\x0d\xbf\x3a\x0d\x26\x38\x1a\xf4\xeb\xa4\xa9\x8e\xaa\x9b\x4e\x6a'
),
pso_input=(
b'\xa6\x25\x7f\x49\x22\x86\x20'
b'\xde\x9e\xdb\x7d\x7b\x7d\xc1\xb4\xd3\x5b\x61\xc2\xec\xe4\x35\x37'
b'\x3f\x83\x43\xc8\x5b\x78\x67\x4d\xad\xfc\x7e\x14\x6f\x88\x2b\x4f'
),
expected_pso_output=(
b'\x4a\x5d\x9d\x5b\xa4\xce\x2d\xe1\x72\x8e\x3b\xf4\x80\x35\x0f\x25'
b'\xe0\x7e\x21\xc9\x47\xd1\x9e\x33\x76\xf0\x9b\x3c\x1e\x16\x17\x42'
),
)

108
tests/func_pso_auth.py Normal file
View File

@@ -0,0 +1,108 @@
"""
func_pso_auth.py - functions for testing PSO commands
Copyright (C) 2021 Vincent Pelletier <plr.vincent@gmail.com>
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/>.
"""
import pytest
from card_const import KEY_ATTRIBUTES_RSA2K
def _encodeDERLength(length):
if length < 0x80:
return length.to_bytes(1, 'big')
if length < 0x100:
return b'\x81' + length.to_bytes(1, 'big')
return b'\x82' + length.to_bytes(2, 'big')
def get_ec_pso(
card,
key_index,
key_attributes,
key_attribute_caption,
private_key, expected_public_key,
pso_input,
):
"""
If card supports, change key attributes for given key slot, store
given private key, check that the card could derive the expected
public key from it, then call the appropriate PSO for this key slot
and return its result.
Sets key attributes to RSA2K before returning to caller.
Skips the test if initial key attribute change is rejected by the card.
"""
key_attribute_index, control_reference_template, pso_p1, pso_p2 = (
(0xc1, b'\xb6\x00', 0x9e, 0x9a), # Sign
(0xc2, b'\xb8\x00', 0x80, 0x86), # Decrypt
(0xc3, b'\xa4\x00', 0x9e, 0x9a), # Authenticate
)[key_index]
try:
card.cmd_put_data(0x00, key_attribute_index, key_attributes)
except ValueError:
pytest.skip('No %s support' % (key_attribute_caption, ))
try:
private_key_len = len(private_key)
r = card.cmd_put_data_odd(
0x3f,
0xff,
b'\x4d' + _encodeDERLength(private_key_len + 10) +
control_reference_template +
b'\x7f\x48\x02'
b'\x92' + _encodeDERLength(private_key_len) +
b'\x5f\x48' + _encodeDERLength(private_key_len) +
private_key,
)
assert r
r = card.cmd_get_public_key(key_index + 1)
expected_public_key_len = len(expected_public_key)
encoded_expected_public_key_len = _encodeDERLength(
expected_public_key_len,
)
expected_public_key_response = (
b'\x7f\x49' + _encodeDERLength(
expected_public_key_len +
len(encoded_expected_public_key_len) + 1,
) +
b'\x86' + encoded_expected_public_key_len +
expected_public_key
)
assert r == expected_public_key_response
return card.cmd_pso(pso_p1, pso_p2, pso_input)
finally:
card.cmd_put_data(0x00, key_attribute_index, KEY_ATTRIBUTES_RSA2K)
def assert_ec_pso(
card,
key_index,
key_attributes,
key_attribute_caption,
private_key, expected_public_key,
pso_input, expected_pso_output,
):
"""
Calls get_ec_pso and checks if produced output matches the expected value.
"""
r = get_ec_pso(
card=card,
key_index=key_index,
key_attributes=key_attributes,
key_attribute_caption=key_attribute_caption,
private_key=private_key,
expected_public_key=expected_public_key,
pso_input=pso_input,
)
assert r == expected_pso_output

View File

@@ -60,6 +60,7 @@ class OpenPGP_Card(object):
self.__kdf_salt_reset = None self.__kdf_salt_reset = None
self.__kdf_salt_admin = None self.__kdf_salt_admin = None
self.is_gnuk = (reader.get_string(2) == "Gnuk Token") self.is_gnuk = (reader.get_string(2) == "Gnuk Token")
self.is_emulated_gnuk = (reader.get_string(3)[-8:] == "EMULATED")
def configure_with_kdf(self): def configure_with_kdf(self):
kdf_data = self.cmd_get_data(0x00, 0xf9) kdf_data = self.cmd_get_data(0x00, 0xf9)

View File

@@ -70,11 +70,11 @@ def build_privkey_template_for_remove(openpgp_keyno):
keyspec = b'\xb8' keyspec = b'\xb8'
else: else:
keyspec = b'\xa4' keyspec = b'\xa4'
return b'\x4d\02' + keyspec + b'\0x00' return b'\x4d\x02' + keyspec + b'\x00'
def compute_digestinfo(msg): def compute_digestinfo(msg):
digest = sha256(msg).digest() digest = sha256(msg).digest()
prefix = b'\x30\31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20' prefix = b'\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'
return prefix + digest return prefix + digest
# egcd and modinv are from wikibooks # egcd and modinv are from wikibooks

View File

@@ -0,0 +1,6 @@
import pytest
@pytest.fixture(scope="module",autouse=True)
def check_emulation(card):
if card.is_emulated_gnuk:
pytest.skip("Emulation requires KDF setup", allow_module_level=True)

6
tests/skip_if_gnuk.py Normal file
View File

@@ -0,0 +1,6 @@
import pytest
@pytest.fixture(scope="module",autouse=True)
def check_gnuk(card):
if card.is_gnuk:
pytest.skip("Gnuk has no support for those features", allow_module_level=True)

View File

@@ -1 +1,2 @@
from skip_if_emulation import *
from card_test_personalize_card import * from card_test_personalize_card import *

View File

@@ -1 +1,2 @@
from skip_if_emulation import *
from card_test_personalize_reset import * from card_test_personalize_reset import *

View File

@@ -1 +1,2 @@
from skip_if_emulation import *
from card_test_remove_keys import * from card_test_remove_keys import *

View File

@@ -1 +1,2 @@
from skip_if_emulation import *
from card_test_reset_pw3 import * from card_test_reset_pw3 import *

View File

@@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from skip_if_emulation import *
from skip_gnuk_only_tests import * from skip_gnuk_only_tests import *
from card_test_personalize_admin_less import * from card_test_personalize_admin_less import *

9
tests/test_006_pso.py Normal file
View File

@@ -0,0 +1,9 @@
from skip_if_gnuk import *
from card_test_ed25519 import *
from card_test_x25519 import *
from card_test_ansix9p256r1 import *
from card_test_ansix9p384r1 import *
from card_test_ansix9p512r1 import *
from card_test_brainpoolp256r1 import *
from card_test_brainpoolp384r1 import *
from card_test_brainpoolp512r1 import *

View File

@@ -20,5 +20,6 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from skip_if_emulation import *
from card_test_keygen import * from card_test_keygen import *
from card_test_remove_keys import * from card_test_remove_keys import *

View File

@@ -1 +1,5 @@
from test_005_personalize_admin_less import * from skip_gnuk_only_tests import *
from card_test_personalize_admin_less import *
from card_test_personalize_reset import *
from card_test_remove_keys import *
from card_test_reset_pw3 import *

View File

@@ -1,48 +0,0 @@
#! /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

@@ -11,7 +11,7 @@ if __name__ == '__main__':
looping = (len(sys.argv) > 1) looping = (len(sys.argv) > 1)
while True: while True:
try: try:
challenge = gnuk.cmd_get_challenge().tostring() challenge = gnuk.cmd_get_challenge().tobytes()
except Exception as e: except Exception as e:
print(count) print(count)
raise e raise e

View File

@@ -1,10 +1,10 @@
#! /usr/bin/python #! /usr/bin/python3
""" """
gnuk_put_binary.py - a tool to put binary to Gnuk Token gnuk_put_binary.py - a tool to put binary to Gnuk Token
This tool is for importing certificate, writing serial number, etc. This tool is for importing certificate, writing serial number, etc.
Copyright (C) 2011, 2012 Free Software Initiative of Japan Copyright (C) 2011, 2012, 2021 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org> Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation. This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -56,7 +56,7 @@ def main(fileid, is_update, data, passwd):
if fileid == 0: if fileid == 0:
data_in_device = gnuk.cmd_get_data(0x00, 0x4f) data_in_device = gnuk.cmd_get_data(0x00, 0x4f)
print(' '.join([ "%02x" % d for d in data_in_device ])) print(' '.join([ "%02x" % d for d in data_in_device ]))
compare(data + b'\x00\x00', data_in_device[8:].tostring()) compare(data + b'\x00\x00', data_in_device[8:].tobytes())
elif fileid >= 1 and fileid <= 4: elif fileid >= 1 and fileid <= 4:
data_in_device = gnuk.cmd_read_binary(fileid) data_in_device = gnuk.cmd_read_binary(fileid)
compare(data, data_in_device) compare(data, data_in_device)

View File

@@ -1,9 +1,9 @@
#! /usr/bin/python #! /usr/bin/python3
""" """
gnuk_remove_keys_libusb.py - a tool to remove keys in Gnuk Token gnuk_remove_keys_libusb.py - a tool to remove keys in Gnuk Token
Copyright (C) 2012, 2018 Free Software Initiative of Japan Copyright (C) 2012, 2018, 2021 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org> Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation. This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -51,7 +51,7 @@ def main(passwd):
gnuk.icc_power_on() gnuk.icc_power_on()
gnuk.cmd_select_openpgp() gnuk.cmd_select_openpgp()
# Compute passwd data # Compute passwd data
kdf_data = gnuk.cmd_get_data(0x00, 0xf9).tostring() kdf_data = gnuk.cmd_get_data(0x00, 0xf9).tobytes()
if kdf_data == b"": if kdf_data == b"":
passwd_data = passwd.encode('UTF-8') passwd_data = passwd.encode('UTF-8')
else: else:

View File

@@ -88,11 +88,17 @@ class gnuk_token(object):
alt.interfaceSubClass == HID_SUBCLASS_NO_BOOT and \ alt.interfaceSubClass == HID_SUBCLASS_NO_BOOT and \
alt.interfaceProtocol == HID_PROTOCOL_0: alt.interfaceProtocol == HID_PROTOCOL_0:
self.__hid_intf = alt.interfaceNumber self.__hid_intf = alt.interfaceNumber
elif alt.interfaceClass == CCID_CLASS and \
alt.interfaceSubClass == CCID_SUBCLASS and \
alt.interfaceProtocol == CCID_PROTOCOL_0:
for endpoint in alt.endpoints:
if endpoint.type == usb.ENDPOINT_TYPE_BULK:
if endpoint.address & usb.ENDPOINT_DIR_MASK == usb.ENDPOINT_IN:
self.__bulkin = endpoint.address
else:
self.__bulkout = endpoint.address
self.__bulkout = 1 self.__timeout = 100000
self.__bulkin = 0x81
self.__timeout = 10000
self.__seq = 0 self.__seq = 0
def get_string(self, num): def get_string(self, num):

View File

@@ -1,9 +1,9 @@
#! /usr/bin/python #! /usr/bin/python3
""" """
gnuk_upgrade.py - a tool to upgrade firmware of Gnuk Token gnuk_upgrade.py - a tool to upgrade firmware of Gnuk Token
Copyright (C) 2012, 2015 Free Software Initiative of Japan Copyright (C) 2012, 2015, 2021 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org> Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation. This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -70,7 +70,7 @@ def gpg_sign(keygrip, hash):
raise ValueError(binascii.hexlify(signed)) raise ValueError(binascii.hexlify(signed))
return signed return signed
def main(keyno,keygrip, data_regnual, data_upgrade): def main(keyno, keygrip, data_regnual, data_upgrade):
l = len(data_regnual) l = len(data_regnual)
if (l & 0x03) != 0: if (l & 0x03) != 0:
data_regnual = data_regnual.ljust(l + 4 - (l & 0x03), b'\x00') data_regnual = data_regnual.ljust(l + 4 - (l & 0x03), b'\x00')
@@ -91,7 +91,7 @@ def main(keyno,keygrip, data_regnual, data_upgrade):
elif icc.icc_get_status() == 1: elif icc.icc_get_status() == 1:
icc.icc_power_on() icc.icc_power_on()
icc.cmd_select_openpgp() icc.cmd_select_openpgp()
challenge = icc.cmd_get_challenge().tostring() challenge = icc.cmd_get_challenge().tobytes()
signed = gpg_sign(keygrip, binascii.hexlify(challenge)) signed = gpg_sign(keygrip, binascii.hexlify(challenge))
icc.cmd_external_authenticate(keyno, signed) icc.cmd_external_authenticate(keyno, signed)
icc.stop_gnuk() icc.stop_gnuk()
@@ -107,17 +107,19 @@ def main(keyno,keygrip, data_regnual, data_upgrade):
del icc del icc
icc = None icc = None
# #
print("Wait 3 seconds...")
time.sleep(3)
# Then, send upgrade program...
reg = None reg = None
for dev in gnuk_devices_by_vidpid(): print("Waiting for device to appear:")
try: while reg == None:
reg = regnual(dev) print(" Wait {} second{}...".format(wait_e, 's' if wait_e > 1 else ''))
print("Device: %d" % dev.filename) time.sleep(wait_e)
break for dev in gnuk_devices_by_vidpid():
except: try:
pass reg = regnual(dev)
print("Device: %s" % dev.filename)
break
except:
pass
# Then, send upgrade program...
mem_info = reg.mem_info() mem_info = reg.mem_info()
print("%08x:%08x" % mem_info) print("%08x:%08x" % mem_info)
print("Downloading the program") print("Downloading the program")

View File

@@ -1,4 +1,4 @@
#! /usr/bin/python #! /usr/bin/python3
""" """
stlinkv2.py - a tool to control ST-Link/V2 stlinkv2.py - a tool to control ST-Link/V2

View File

@@ -1,10 +1,10 @@
#! /usr/bin/python #! /usr/bin/python3
""" """
upgrade_by_passwd.py - a tool to install another firmware for Gnuk Token upgrade_by_passwd.py - a tool to install another firmware for Gnuk Token
which is just shipped from factory which is just shipped from factory
Copyright (C) 2012, 2013, 2015, 2018 Copyright (C) 2012, 2013, 2015, 2018, 2021
Free Software Initiative of Japan Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org> Author: NIIBE Yutaka <gniibe@fsij.org>
@@ -52,7 +52,7 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
gnuk.cmd_select_openpgp() gnuk.cmd_select_openpgp()
# Compute passwd data # Compute passwd data
try: try:
kdf_data = gnuk.cmd_get_data(0x00, 0xf9).tostring() kdf_data = gnuk.cmd_get_data(0x00, 0xf9).tobytes()
except: except:
kdf_data = b"" kdf_data = b""
if kdf_data == b"": if kdf_data == b"":
@@ -70,7 +70,7 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False) gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
gnuk.cmd_select_openpgp() gnuk.cmd_select_openpgp()
challenge = gnuk.cmd_get_challenge().tostring() challenge = gnuk.cmd_get_challenge().tobytes()
digestinfo = binascii.unhexlify(SHA256_OID_PREFIX) + challenge digestinfo = binascii.unhexlify(SHA256_OID_PREFIX) + challenge
signed = rsa.compute_signature(rsa_key, digestinfo) signed = rsa.compute_signature(rsa_key, digestinfo)
signed_bytes = rsa.integer_to_bytes_256(signed) signed_bytes = rsa.integer_to_bytes_256(signed)
@@ -128,26 +128,53 @@ if __name__ == '__main__':
keyno = 0 keyno = 0
passwd = None passwd = None
wait_e = DEFAULT_WAIT_FOR_REENUMERATION wait_e = DEFAULT_WAIT_FOR_REENUMERATION
while len(sys.argv) > 3: skip_check = False
while len(sys.argv) > 1:
option = sys.argv[1] option = sys.argv[1]
sys.argv.pop(1)
if option == '-f': # F for Factory setting if option == '-f': # F for Factory setting
sys.argv.pop(1)
passwd = DEFAULT_PW3 passwd = DEFAULT_PW3
elif option == '-e': # E for Enumeration elif option == '-e': # E for Enumeration
sys.argv.pop(1)
wait_e = int(sys.argv[1]) wait_e = int(sys.argv[1])
sys.argv.pop(1) sys.argv.pop(1)
elif option == '-k': # K for Key number elif option == '-k': # K for Key number
sys.argv.pop(1)
keyno = int(sys.argv[1]) keyno = int(sys.argv[1])
sys.argv.pop(1) sys.argv.pop(1)
elif option == '-s': # S for skip the check of target
sys.argv.pop(1)
skip_check = True
else: else:
raise ValueError("unknown option", option) if option[0] == '-':
raise ValueError("unknown option", option)
else:
break
if not passwd: if not passwd:
passwd = getpass("Admin password: ") passwd = getpass("Admin password: ")
filename_regnual = sys.argv[1] if len(sys.argv) > 1:
filename_upgrade = sys.argv[2] filename_regnual = sys.argv[1]
filename_upgrade = sys.argv[2]
else:
filename_regnual = "../regnual/regnual.bin"
filename_upgrade = "../src/build/gnuk.bin"
if not filename_regnual.endswith('bin') or not filename_upgrade.endswith('bin'): if not filename_regnual.endswith('bin') or not filename_upgrade.endswith('bin'):
print("Both input files must be in binary format (*.bin)!") print("Both input files must be in binary format (*.bin)!")
exit(1) exit(1)
if not skip_check:
# More checks
gnuk = get_gnuk_device()
u_target = gnuk.get_string(5).split(b':')[0].decode('UTF-8')
del gnuk
f = open("../src/usb-strings.c.inc","r")
config_str = f.read()
f.close()
conf_options=config_str[config_str.find('/* configure options: "')+23:]
target=conf_options[:conf_options.find(':')]
if target != u_target:
print("Target", target, "!= device info from USB " , u_target)
exit(1)
#
f = open(filename_regnual,"rb") f = open(filename_regnual,"rb")
data_regnual = f.read() data_regnual = f.read()
f.close() f.close()