Compare commits
294 Commits
release/1.
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 2519f799fd | |||
| 32f563a28d | |||
| 7b471948b4 | |||
| d2363c8ad8 | |||
| 9306ad5043 | |||
| 54d031bc27 | |||
| 6909e0359c | |||
| 5acd8a23d9 | |||
| d5a539986e | |||
| 8a19a2cb66 | |||
| 5e4a264ac0 | |||
| a9079e8b5c | |||
| 057920600f | |||
| 7d1b5e4b71 | |||
| fe66b67317 | |||
| 14f0acd749 | |||
| 9ccbd5804a | |||
| b4b82e1557 | |||
| 357a4b3510 | |||
| 1fdb74eb10 | |||
| 977a09f69f | |||
| cd271fbeb5 | |||
| 7e17548610 | |||
| fd7a7c7dfa | |||
| 8de235b26f | |||
| 53cbb62738 | |||
| 511f6de8b1 | |||
| 0132723c7a | |||
| a37f7aca5c | |||
| 531be827dd | |||
| d6c040400a | |||
| b8ada80163 | |||
| 1d63372017 | |||
| 8dfbf63452 | |||
| b9f6c3be7a | |||
|
|
9d3c08bd2b | ||
|
|
a909502388 | ||
|
|
286b620648 | ||
|
|
cce65c6d34 | ||
|
|
57fdadf283 | ||
|
|
870de72ee2 | ||
|
|
fa667b04f7 | ||
|
|
2a72f3df08 | ||
|
|
db2527459f | ||
|
|
1ca3bbdaae | ||
|
|
98119dc991 | ||
|
|
03cca1e451 | ||
|
|
3f65bf73e8 | ||
|
|
07be37f45e | ||
|
|
dcef6e0ffa | ||
|
|
d31687ebd6 | ||
|
|
92443f8f07 | ||
|
|
4af98308e0 | ||
|
|
baec3a1c1e | ||
|
|
4f1325794d | ||
|
|
0acf6485ae | ||
|
|
4d15700580 | ||
|
|
8822fcae77 | ||
|
|
20a2f99691 | ||
|
|
acfccb729d | ||
|
|
5283506755 | ||
|
|
c688df7c2c | ||
|
|
594896ac57 | ||
|
|
dfe046e08d | ||
|
|
c66b01e74b | ||
|
|
21a46306ae | ||
|
|
e5158572ee | ||
|
|
2142d0aa35 | ||
|
|
dd47cf4312 | ||
|
|
ffbb754fc0 | ||
|
|
d85750d791 | ||
|
|
d20e9e9b1e | ||
|
|
bf30144144 | ||
|
|
934daf3585 | ||
|
|
22420ed1f4 | ||
|
|
e97e3b1810 | ||
|
|
49f2544918 | ||
|
|
d156fc6261 | ||
|
|
81d6945081 | ||
|
|
c3e9db14e8 | ||
|
|
9180c35420 | ||
|
|
cc0d59cfe6 | ||
|
|
9c1368fdd0 | ||
|
|
2dd5a76002 | ||
|
|
f68ff0bddc | ||
|
|
add3299306 | ||
|
|
e28ec2c4c4 | ||
|
|
1ba05a0f0f | ||
|
|
2d50795d0a | ||
|
|
fd493562c3 | ||
|
|
16c6af215a | ||
|
|
177ef67edf | ||
|
|
126283b1ac | ||
|
|
076d727061 | ||
|
|
41fa424450 | ||
|
|
940332c47f | ||
|
|
aedf8267ec | ||
|
|
e9d9de3ae2 | ||
|
|
fc109fd8af | ||
|
|
3d06051a32 | ||
|
|
b7368e41e9 | ||
|
|
e760d5b780 | ||
|
|
b57c33c204 | ||
|
|
ca3312eb25 | ||
|
|
6a1f50abda | ||
|
|
66f39c57cd | ||
|
|
4b5f93624e | ||
|
|
0ef687ea4c | ||
|
|
786b4adc42 | ||
|
|
385261c9a0 | ||
|
|
65689199e7 | ||
|
|
8d15086d06 | ||
|
|
c17fd5401b | ||
|
|
56cd4ae7b5 | ||
|
|
fc36773c6a | ||
|
|
7249775c17 | ||
|
|
980cff0a2f | ||
|
|
8f44f5d3c6 | ||
|
|
37a84ed218 | ||
|
|
6c72147248 | ||
|
|
3d37003d8c | ||
|
|
becf8fabc5 | ||
|
|
17492287f3 | ||
|
|
c800dee95e | ||
|
|
2c390dc763 | ||
|
|
5aee75fd4b | ||
|
|
69e8c0f334 | ||
|
|
317cc2036d | ||
|
|
312d15c3fa | ||
|
|
d356f1b1e0 | ||
|
|
9cb6591491 | ||
|
|
ebec8ee156 | ||
|
|
f810fb83d3 | ||
|
|
12079974fd | ||
|
|
ca79f5421f | ||
|
|
c438367d67 | ||
|
|
4c6511231c | ||
|
|
ba750d153d | ||
|
|
72647f01d0 | ||
|
|
c6e32a36fb | ||
|
|
c3a0eb1439 | ||
|
|
030a9c576d | ||
|
|
8a5e0eb783 | ||
|
|
bce53546e7 | ||
|
|
b2b19e1ad4 | ||
|
|
58fa773bb7 | ||
|
|
ea88c3da66 | ||
|
|
b905b4802f | ||
|
|
40f2c6c49e | ||
|
|
61a7f9602b | ||
|
|
5465fda927 | ||
|
|
f7c46a6c55 | ||
|
|
4550458806 | ||
|
|
93a2bac94b | ||
|
|
24adc09406 | ||
|
|
bf9fc628b3 | ||
|
|
d76534dd3a | ||
|
|
d9c5dcf206 | ||
|
|
26448d58ee | ||
|
|
9cfeb817bd | ||
|
|
b6534dceba | ||
|
|
b47bd693ba | ||
|
|
1a7d3a698f | ||
|
|
f7b03f7fb5 | ||
|
|
44971541fe | ||
|
|
53ed5e0a42 | ||
|
|
63eccda0a1 | ||
|
|
f430c90715 | ||
|
|
1f18ec1d63 | ||
|
|
ec7423f493 | ||
|
|
e50dda28d1 | ||
|
|
8ad176921f | ||
|
|
d71b116be8 | ||
|
|
d9d3f35ac3 | ||
|
|
7cc8d8930e | ||
|
|
6446a5bd89 | ||
|
|
8b0cb8be65 | ||
|
|
c73bb0548e | ||
|
|
40b1d453dc | ||
|
|
3b965fafc0 | ||
|
|
35edbdc731 | ||
|
|
d4c776e308 | ||
|
|
6c0c510347 | ||
|
|
704d8a5cf1 | ||
|
|
55781cb7bb | ||
|
|
de24655920 | ||
|
|
7bfe0f5427 | ||
|
|
ec058537ed | ||
|
|
abeb1015ec | ||
|
|
c5f20dc355 | ||
|
|
4ff0b3c5f8 | ||
|
|
4e517778d0 | ||
|
|
c81544fffd | ||
|
|
ad42010272 | ||
|
|
8ce91267be | ||
|
|
b5c2ace2ae | ||
|
|
4cbc661fb7 | ||
|
|
543f28574e | ||
|
|
fe94e1885b | ||
|
|
ce82b347f9 | ||
|
|
d54712c04c | ||
|
|
9c63c874d0 | ||
|
|
bb9b31166f | ||
|
|
e417846408 | ||
|
|
21a481060c | ||
|
|
d4c9d6653b | ||
|
|
f00306627b | ||
|
|
f4b36b7503 | ||
|
|
e85527d302 | ||
|
|
bd58997dc9 | ||
|
|
9d5834d47b | ||
|
|
36ecf67694 | ||
|
|
c9b1e511ba | ||
|
|
01b5aa5984 | ||
|
|
b735c02ec2 | ||
|
|
2ecb104ae4 | ||
|
|
6b4f3c9934 | ||
|
|
660aaeb04b | ||
|
|
1022534c02 | ||
|
|
46cc64cf03 | ||
|
|
effc65381a | ||
|
|
6cbf5a4822 | ||
|
|
8ff3865890 | ||
|
|
43009f39e8 | ||
|
|
56fb5002bf | ||
|
|
3bb5097031 | ||
|
|
8319f4a14b | ||
|
|
f7cf0a3461 | ||
|
|
5ac52d3f2f | ||
|
|
209d459d09 | ||
|
|
ad704edc4e | ||
|
|
97a1870e6e | ||
|
|
f72e132967 | ||
|
|
a22b695f96 | ||
|
|
0c901d8052 | ||
|
|
a1b8e7f40c | ||
|
|
dccda32b93 | ||
|
|
75049ce949 | ||
|
|
be80a3ef2f | ||
|
|
94424e85c3 | ||
|
|
43980d1c81 | ||
|
|
183cec8a04 | ||
|
|
7bae61f300 | ||
|
|
7e4ee2b361 | ||
|
|
30fde2a0f0 | ||
|
|
eee8d046a9 | ||
|
|
550010f25f | ||
|
|
3adbe30c4d | ||
|
|
d9ec8778fc | ||
|
|
eff0c7077d | ||
|
|
289d3db8c4 | ||
|
|
7c5eb7efd2 | ||
|
|
6f1fbdd82d | ||
|
|
cbedf98a52 | ||
|
|
15689b5b86 | ||
|
|
8170b60ee2 | ||
|
|
ca7f4c8758 | ||
|
|
0b4099d6d1 | ||
|
|
65fee7eb2a | ||
|
|
0c229f5712 | ||
|
|
5948f6ec50 | ||
|
|
7b1ea00307 | ||
|
|
277be86958 | ||
|
|
a6b90ad648 | ||
|
|
547e263d6b | ||
|
|
7004453669 | ||
|
|
81b18f2db4 | ||
|
|
86715dd4fe | ||
|
|
62f27f319c | ||
|
|
7345f3c241 | ||
|
|
f4b9073b11 | ||
|
|
6678ac28c2 | ||
|
|
83414a747a | ||
|
|
8a615d087b | ||
|
|
967b949967 | ||
|
|
11afbdde14 | ||
|
|
328766af12 | ||
|
|
2b340ee1c5 | ||
|
|
86e6adf47e | ||
|
|
eea011fe70 | ||
|
|
e736227de7 | ||
|
|
22156ea7f9 | ||
|
|
db45e62ebe | ||
|
|
3270740631 | ||
|
|
e4e72a29ae | ||
|
|
25d3f021c1 | ||
|
|
ae76d66d53 | ||
|
|
10c5010141 | ||
|
|
d12483c3c9 | ||
|
|
67acb670d1 | ||
|
|
a44244b27e | ||
|
|
2622840e27 | ||
|
|
a51ac8593b | ||
|
|
de81caba3e |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,17 +1,20 @@
|
||||
*.lst
|
||||
*.o
|
||||
*.pyc
|
||||
regnual/regnual-no-vidpid.elf
|
||||
src/.dep
|
||||
src/Makefile
|
||||
src/config.mk
|
||||
src/config.h
|
||||
src/gnuk.ld
|
||||
src/stdaln-sys.ld
|
||||
src/board.h
|
||||
src/build/*
|
||||
src/*.inc
|
||||
src/put-vid-pid-ver.sh
|
||||
regnual/regnual.bin
|
||||
regnual/regnual.hex
|
||||
regnual/regnual.elf
|
||||
doc/_build
|
||||
tests/.cache
|
||||
tests/__pycache__
|
||||
emulation/gnuk_emulation
|
||||
tests/.pytest_cache
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "chopstx"]
|
||||
path = chopstx
|
||||
url = ../../chopstx/chopstx.git
|
||||
url = ../chopstx.git
|
||||
|
||||
50
AUTHORS
50
AUTHORS
@@ -1,50 +0,0 @@
|
||||
Kaz Kojima:
|
||||
Added STM32 Primer2 support.
|
||||
|
||||
NIIBE Yutaka:
|
||||
Founder of the project.
|
||||
Wrote tools for STLink/V2:
|
||||
tool/stlinkv2.py
|
||||
Wrote tools for DfuSe:
|
||||
tool/dfuse.py
|
||||
tool/dump_mem.py
|
||||
tool/intel_hex.py
|
||||
Wrote a tool for Gnuk:
|
||||
tool/gnuk_put_binary.py
|
||||
tool/gnuk_put_binary_libusb.py
|
||||
tool/gnuk_remove_keys.py
|
||||
tool/gnuk_upgrade.py
|
||||
Wrote a tool for USB Hub:
|
||||
tool/hub_ctrl.py
|
||||
Wrote a tool for testing card reader with pinpad:
|
||||
tool/pinpadtest.py
|
||||
Wrote reGNUal implementation:
|
||||
regnual/regnual.c
|
||||
regnual/sys.c
|
||||
Wrote Gnuk implementation:
|
||||
gnuk.svg
|
||||
src/configure
|
||||
src/ac.c
|
||||
src/call-rsa.c
|
||||
src/debug.c
|
||||
src/flash.c
|
||||
src/gnuk.h
|
||||
src/main.c
|
||||
src/neug.c
|
||||
src/openpgp-do.c
|
||||
src/openpgp.c
|
||||
src/openpgp.h
|
||||
src/pin-cir.c
|
||||
src/pin-dial.c
|
||||
src/pin-dnd.c
|
||||
src/random.c
|
||||
src/sys.c
|
||||
src/usb-icc.c
|
||||
src/usb-msc.c
|
||||
src/usb-msc.h
|
||||
src/usb_ctrl.c
|
||||
src/usb_desc.c
|
||||
src/usb_lld.c
|
||||
src/usb_lld.h
|
||||
*
|
||||
and others.
|
||||
2477
ChangeLog-1_0
2477
ChangeLog-1_0
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,7 @@
|
||||
# VID:PID bcdDev Product_STRING Vendor_STRING
|
||||
0000: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
|
||||
1209:2440 0200 Gnuk Token GnuPG e.V.
|
||||
1337:0010 0200 Gnuk Token Deon Spengler
|
||||
##########<TAB> ##<TAB> ##########<TAB> #################
|
||||
|
||||
283
NEWS
283
NEWS
@@ -1,5 +1,281 @@
|
||||
Gnuk NEWS - User visible changes
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.20
|
||||
|
||||
Released 2022-04-22, by NIIBE Yutaka
|
||||
|
||||
** Minor fixes for newer compiler
|
||||
|
||||
For build with newer compiler, Gnuk and regnual are fixed for address
|
||||
calculation and access to object on memory, as well as declarations of
|
||||
function and type in standard C library.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
|
||||
We use Chopstx 1.21. This includes fix to silence compiler warnings.
|
||||
|
||||
|
||||
* 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
|
||||
|
||||
Released 2020-09-10, by NIIBE Yutaka
|
||||
|
||||
** New Data Object (Algorithm Information) of OpenPGP card v3.4
|
||||
The tag is 0x00FA. This is useful for user interaction to show which
|
||||
algorithms are supported by the device.
|
||||
|
||||
** Ed25519 signing allowing longer message
|
||||
For OpenPGP, it does hashing on host side before requesting signing to
|
||||
the device. Thus, the length of message to be signed is limited and
|
||||
determined by the hash algorithm. That's good feature of OpenPGP. On
|
||||
the other hand, there is a use case, like OpenSSH certificate signing,
|
||||
where the length of message is a kind of arbitrary. Even though Gnuk
|
||||
(or OpenPGP card protocol itself) has limitation, we removed the
|
||||
length check against EDDSA_HASH_LEN_MAX at cmd_pso.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.15
|
||||
|
||||
Released 2020-01-24, by NIIBE Yutaka
|
||||
|
||||
** Switch to Python3
|
||||
Scripts under tool/ are switched to Python3.
|
||||
Thanks to Bertrand Jacquin.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.18.
|
||||
|
||||
** Tests also support OpenPGPcard
|
||||
Now, a test suite under "tests" may be used to OpenPGPcard.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.14
|
||||
|
||||
Released 2019-03-05, by NIIBE Yutaka
|
||||
|
||||
** Timeout for ACK button support
|
||||
When a user doesn't acknowledge (> 15 seconds), the operation
|
||||
timeouts, and authentication state is cleared.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.14.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.13
|
||||
|
||||
Released 2018-12-26, by NIIBE Yutaka
|
||||
|
||||
** DFU support and its firmware upgrade fix
|
||||
DFU support was not well maintained, and firmware upgrade was not
|
||||
possible for boards with DFU. Now, at least for Maple Mini, it is
|
||||
tested. Note that using Gnuk with DFU on a board is only for an
|
||||
experiment, because DFU can access the content of flash ROM. DFU
|
||||
should be killed by upgrading to normal Gnuk, so that you can have
|
||||
your private keys.
|
||||
|
||||
** Fix for UIF Data Object
|
||||
When flash ROM is full and coping to new page, UIF DO was not properly
|
||||
copied. This bug resulted losing the flag for user interaction. Now,
|
||||
it's properly copied, keeping the setting of the feature.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.13.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.12
|
||||
|
||||
Released 2018-11-25, by NIIBE Yutaka
|
||||
|
||||
** FST-01SZ fixes
|
||||
Fixes for Ack button support and serial number.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.11
|
||||
|
||||
Released 2018-11-12, by NIIBE Yutaka
|
||||
|
||||
** Experimental ACK button support with FST-01SZ
|
||||
While OpenPGP card specification verison 3 has description for the
|
||||
"user interaction" button and data objects, there were no
|
||||
implementation. To evaluate the feature, experimental support is
|
||||
added.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.12, which comes with ACK button driver and supports
|
||||
FST-01SZ.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.10
|
||||
|
||||
Released 2018-05-10, by NIIBE Yutaka
|
||||
|
||||
** No inclusion of VID:PID in gnuk-no-vidpid.elf
|
||||
Now, we have new file named gnuk-no-vidpid.elf with no VID:PID. The
|
||||
file gnuk.elf has the VID:PID, like version 1.2.7 or older.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.9, which supports GD32F103.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.9
|
||||
|
||||
Released 2018-04-05, by NIIBE Yutaka
|
||||
|
||||
** A test suite fix: Clear PW3
|
||||
Until 1.2.8, after running the test suite under "tests", PW3 keystring
|
||||
remained, which affects use of admin-less mode. New test case is
|
||||
added to clear PW3.
|
||||
|
||||
** tool/upgrade_by_passwd.py supports KDF-DO auth
|
||||
With KDF-DO, firmware upgrade didn't work. Now, it's supported.
|
||||
|
||||
** Add "single-salt" support for KDF-DO
|
||||
With KDF-DO, "admin-less" mode didn't work well. With new feature of
|
||||
"single-salt" support, we can use "admin-less" mode with KDF-DO.
|
||||
|
||||
** factory-reset deletes all upgrade public keys
|
||||
By card-edit/factory-reset by GnuPG, it deletes all upgrade public
|
||||
keys, now.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.8
|
||||
|
||||
Released 2018-01-23, by NIIBE Yutaka
|
||||
|
||||
** No inclusion of VID:PID in gnuk.elf
|
||||
|
||||
Distribution of binary image with VID:PID would violate vendor ID
|
||||
agreement to USB Forum. Now, we have new file named gnuk-vidpid.elf
|
||||
for flashing. The file gnuk.elf can be used to generate
|
||||
gnuk-vidpid.elf and we can check if it is reproducible or not.
|
||||
|
||||
** Passphrase length check
|
||||
|
||||
Now, Gnuk checks length of passphrase if it's too short when
|
||||
changing passphrase.
|
||||
|
||||
** Remove unused DEK with BY_ADMIN
|
||||
|
||||
For admin-less mode, DEK by OPENPGP_CARD_INITIAL_PW3 remained on flash
|
||||
ROM. This could be considered a backdoor, if some other person had or
|
||||
kept access to the flash ROM, cheating a user. Now, the DEK is
|
||||
cleared by zero when the token is set to admin-less mode.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.8.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.7
|
||||
|
||||
Released 2017-11-26, by NIIBE Yutaka
|
||||
|
||||
** reGNUal
|
||||
reGNUal enables CRC module by itself.
|
||||
|
||||
** Flash update change
|
||||
CRC module is disabled when Gnuk stops. It's reGNUal which needs to
|
||||
enable CRC module.
|
||||
|
||||
** Support of USB suspend
|
||||
USB suspend and wakeup event are now handled.
|
||||
|
||||
** KDF-DO support and KDF by host
|
||||
KDF-DO is now available. Host can use this feature.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.6.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.6
|
||||
|
||||
Released 2017-10-11, by NIIBE Yutaka
|
||||
|
||||
** Port to GNU/Linux emulation
|
||||
We can "run" Gnuk Token on GNU/Linux by emulation through USBIP.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.5.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.5
|
||||
|
||||
Released 2017-08-11, by NIIBE Yutaka
|
||||
|
||||
** "factory-reset" fix
|
||||
Gnuk's behavior was implemented by referring the gpg implementation.
|
||||
It found that gpg implementation was not good from the viewpoint of
|
||||
the OpenPGP card specification. GnuPG was fixed to match the OpenPGP
|
||||
card specification already. Thus, Gnuk is now fixed.
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 1.4.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.2.4
|
||||
|
||||
Released 2017-05-12, by NIIBE Yutaka
|
||||
@@ -757,6 +1033,7 @@ Gnuk Token could run with GPG4WIN on MS Windows. GPG4WIN runs with
|
||||
|
||||
** This is initial release. Only it supports digital signing.
|
||||
|
||||
Local Variables:
|
||||
mode: outline
|
||||
End:
|
||||
|
||||
# Local Variables:
|
||||
# mode: outline
|
||||
# End:
|
||||
|
||||
625
README
625
README
@@ -1,625 +0,0 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 1.2.4
|
||||
2017-05-12
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
This is the release of Gnuk, version 1.2.4, which has major
|
||||
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
||||
overriding key import, but importing keys (or generating keys) results
|
||||
password reset. Please update your documentation for Gnuk Token, so
|
||||
that the instruction of importing keys won't cause any confusion.
|
||||
|
||||
It has supports of 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
|
||||
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.
|
||||
|
||||
|
||||
What's Gnuk?
|
||||
============
|
||||
|
||||
Gnuk is an implementation of USB cryptographic token for GNU Privacy
|
||||
Guard. Gnuk supports OpenPGP card protocol version 3, and it runs on
|
||||
STM32F103 processor.
|
||||
|
||||
I wish that Gnuk will be a developer's soother who uses GnuPG. I have
|
||||
been nervous of storing secret key(s) on usual secondary storage.
|
||||
There is a solution with OpenPGP card, but it is not the choice for
|
||||
me, as card reader is not common device. With Gnuk, this issue will
|
||||
be solved by a USB token.
|
||||
|
||||
Please look at the graphics of "gnuk.svg" for the software name. My
|
||||
son used to be with his NUK(R), always, everywhere. Now, I am with a
|
||||
USB Cryptographic Token by "Gnuk", always, everywhere.
|
||||
|
||||
|
||||
FAQ
|
||||
===
|
||||
|
||||
Q0: How Gnuk USB Token is superior than other solutions (OpenPGP
|
||||
card 2.0, YubiKey, etc.) ?
|
||||
https://www.g10code.de/p-card.html
|
||||
https://www.yubico.com/
|
||||
A0: Good points of Gnuk are:
|
||||
* If you have skill of electronics and like DIY, you can build
|
||||
Gnuk Token cheaper (see Q8-A8).
|
||||
* You can study Gnuk to modify and to enhance. For example, you
|
||||
can implement your own authentication method with some sensor
|
||||
such as an acceleration sensor.
|
||||
* It is "of Free Software"; Gnuk is distributed under GPLv3+,
|
||||
"by Free Software"; Gnuk development requires only Free Software
|
||||
(GNU Toolchain, Python, etc.),
|
||||
"for Free Software"; Gnuk supports GnuPG.
|
||||
|
||||
Q1: What kind of key algorithm is supported?
|
||||
A1: Gnuk version 1.0 only supports RSA-2048.
|
||||
Gnuk version 1.2.x supports 255-bit EdDSA, as well as RSA-4096.
|
||||
(Note that it takes long time to sign with RSA-4096.)
|
||||
|
||||
Q2: How long does it take for digital signing?
|
||||
A2: It takes a second and a half or so for RSA-2048.
|
||||
It takes more than 8 secondd for RSA-4096.
|
||||
|
||||
Q3: What's your recommendation for target board?
|
||||
A3: Orthodox choice is Olimex STM32-H103.
|
||||
FST-01 (Flying Stone Tiny 01) is available for sale, and it is a
|
||||
kind of the best choice, hopefully.
|
||||
If you have a skill of electronics, STM32 Nucleo F103 is the best
|
||||
choice for experiment.
|
||||
|
||||
Q4: What's version of GnuPG are you using?
|
||||
A4: In Debian GNU/Linux system, I use GnuPG 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
|
||||
Token without them.
|
||||
I tested pcscd 1.5.5-4 and libccid 1.3.11-2 which were in Debian
|
||||
squeeze.
|
||||
|
||||
Q6: What kinds of hardware is required for development?
|
||||
A6: You need a target board plus a JTAG/SWD debugger. If you just
|
||||
want to test Gnuk for target boards with DfuSe, JTAG debugger is
|
||||
not the requirement. Note that for real use, you need JTAG/SWD
|
||||
debugger to enable flash ROM protection.
|
||||
|
||||
Q7: How much does it cost?
|
||||
A7: Olimex STM32-H103 plus ARM-USB-TINY-H cost 70 Euro or so.
|
||||
|
||||
Q8: How much does it cost for DIY version?
|
||||
A8: STM32 Nucleo F103 costs about $10 USD.
|
||||
|
||||
Q9: I got an error like "gpg: selecting openpgp failed: ec=6.108", what's up?
|
||||
A9: Older GnuPG's SCDaemon has problems for handling insertion/removal of
|
||||
card/reader. When your newly inserted token is not found by
|
||||
GnuPG, try killing scdaemon and let it to be invoked again. I do:
|
||||
|
||||
$ gpg-connect-agent "SCD KILLSCD" "SCD BYE" /bye
|
||||
|
||||
and confirm scdaemon doesn't exist, then,
|
||||
|
||||
$ gpg-connect-agent learn /bye
|
||||
|
||||
Qa: With GNOME 2, I can't use Gnuk Token for SSH. How can we use it for SSH?
|
||||
Aa: You need to deactivate seahorse-agent and gnome-keyring, but use
|
||||
gpg-agant for the role of ssh-agent. For gnome-keyring please do:
|
||||
|
||||
$ gconftool-2 --type bool --set /apps/gnome-keyring/daemon-components/ssh false
|
||||
|
||||
Qb: With GNOME 3.0, I can't use Gnuk Token at all. Why?
|
||||
Ab: That's because gnome-keyring-daemon interferes GnuPG. Type:
|
||||
|
||||
$ gnome-session-properties
|
||||
|
||||
and at the tab of "Startup Programs", disable check buttons for
|
||||
"GPG Password Agent" and "SSH Key Agent".
|
||||
|
||||
Qc: With GNOME 3.x (x >= 8?), I can't use Gnuk Token at all. Why?
|
||||
Ac: That's because gnome-keyring-daemon interferes GnuPG. Please
|
||||
disable the invocation of gnome-keyring-daemon. In Debian
|
||||
wheezy, it's in the files /etc/xdg/autostart/gnome-keyring-ssh.desktop
|
||||
and /etc/xdg/autostart/gnome-keyring-gpg.desktop.
|
||||
We have a line something like:
|
||||
|
||||
OnlyShowIn=GNOME;Unity;MATE;
|
||||
|
||||
Please edit this line to:
|
||||
|
||||
OnlyShowIn=
|
||||
|
||||
Qd: Do you know a good SWD debugger to connect FST-01 or something?
|
||||
Ad: ST-Link/V2 is cheap one. We have a tool/stlinkv2.py as flash ROM
|
||||
writer program. STM32 Nucleo F103 comes with the valiant of
|
||||
ST-Link/V2. However, the firmware of ST-Link/V2 is proprietary.
|
||||
Now, I develop BBG-SWD, SWD debugger by BeagleBone Green.
|
||||
|
||||
|
||||
Tested features
|
||||
===============
|
||||
|
||||
Gnuk is tested by test suite. Please see the test directory.
|
||||
|
||||
* Personalization of the card
|
||||
* Changing Login name, URL, Name, Sex, Language, etc.
|
||||
* Password handling (PW1, RC, PW3)
|
||||
* Key import for three types:
|
||||
* key for digital signing
|
||||
* key for decryption
|
||||
* key for authentication
|
||||
* PSO: Digital Signature
|
||||
* PSO: Decipher
|
||||
* INTERNAL AUTHENTICATE
|
||||
* Changing value of password status bytes (0x00C4): forcesig
|
||||
* Verify with pin pad
|
||||
* Modify with pin pad
|
||||
* Card holder certificate (read)
|
||||
* Removal of keys
|
||||
* Key generation on device side for RSA-2048
|
||||
* Overriding key import
|
||||
|
||||
Original features of Gnuk, tested manually lightly:
|
||||
|
||||
* OpenPGP card serial number setup
|
||||
* Card holder certificate (write by UPDATE BINARY)
|
||||
* Upgrading with "EXTERNAL AUTHENTICATE" by reGNUal
|
||||
|
||||
It is known not-working well:
|
||||
|
||||
* It is known that the specific combination of libccid 1.4.1
|
||||
(or newer) with libusb 1.0.8 (or older) had a minor problem.
|
||||
It is rare but it is possible for USB communication to be
|
||||
failed, because of a bug in libusb implementation. Use
|
||||
libusbx 1.0.9 or newer, or don't use PC/SC, but use internal
|
||||
CCID driver of GnuPG.
|
||||
|
||||
|
||||
Targets
|
||||
=======
|
||||
|
||||
We use Olimex STM32-H103 board and Flying Stone Tiny 01 (FST-01).
|
||||
|
||||
With DfuSe support, STBee is also our targets. But this target with
|
||||
DfuSe is for experiment only, because it is impossible for DfuSe to
|
||||
disable read from flash. For real use, please consider killing DfuSe
|
||||
and enabling read protection using JTAG debugger.
|
||||
|
||||
For experimental PIN-pad support, I connect a consumer IR receive
|
||||
module to FST-01, and use controller for TV. PIN verification is
|
||||
supported by this configuration. Yes, it is not secure at all, since
|
||||
it is very easy to monitor IR output of the controllers. It is just
|
||||
an experiment. Note that hardware needed for this experiment is only
|
||||
a consumer IR receive module which is as cheap as 50 JPY.
|
||||
|
||||
Note that you need pinpad support for GnuPG to use PIN-pad enabled
|
||||
Gnuk. The pinpad support for GnuPG is only available in version 2.
|
||||
|
||||
|
||||
Build system and Host system
|
||||
============================
|
||||
|
||||
Makefile is written for GNU make. You need Bash 4.x for configure.
|
||||
|
||||
If your bash is not installed as /bin/bash, you need to run configure
|
||||
script prepending 'bash' before './configure'.
|
||||
|
||||
Some tools are written in Python. If your Python is not installed as
|
||||
/usr/bin/python, please prepend 'python' for your command invocation.
|
||||
Python 2.7 and PyUSB 0.4.3 is assumed.
|
||||
|
||||
|
||||
Souce code
|
||||
==========
|
||||
|
||||
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
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
It is distributed under GNU General Public Licence version 3 or later
|
||||
(GPLv3+). Please see src/COPYING.
|
||||
|
||||
Please note that it is distributed with external source code too.
|
||||
Please read relevant licenses for external source code as well.
|
||||
|
||||
The author(s) of Gnuk expect users of Gnuk will be able to access the
|
||||
source code of Gnuk, so that users can study the code and can modify
|
||||
if needed. This doesn't mean person who has a Gnuk Token should be
|
||||
able to access everything on the Token, regardless of its protections.
|
||||
Private keys, and other information should be protected properly.
|
||||
|
||||
|
||||
External source code
|
||||
====================
|
||||
|
||||
Gnuk is distributed with external source code.
|
||||
|
||||
* chopstx/ -- Chopstx 1.3
|
||||
|
||||
We use Chopstx as the kernel for Gnuk.
|
||||
|
||||
Chopstx is distributed under GPLv3+ (with a special exception).
|
||||
|
||||
|
||||
* polarssl/ -- based on PolarSSL 1.2.10 (now mbedTLS)
|
||||
|
||||
Souce code taken from: http://polarssl.org/
|
||||
|
||||
We use PolarSSL for RSA computation, and AES encryption/decryption.
|
||||
|
||||
PolarSSL is distributed under GPLv2+. We use PolarSSL under GPLv3
|
||||
as our options.
|
||||
|
||||
The file include/polarssl/bn_mul.h is heavily modified for ARM
|
||||
Cortex-M3.
|
||||
|
||||
The function rsa_private in polarssl/library/rsa.c is modified so
|
||||
that it doesn't check T against N. The function rsa_pkcs1_sign is
|
||||
modified to avoid warnings in case of !POLARSSL_PKCS1_V21.
|
||||
|
||||
The functions rsa_pkcs1_verify and rsa_rsassa_pkcs1_v15_verify in
|
||||
include/polarssl/rsa.h and polarssl/library/rsa.c are modified
|
||||
(fixed) for last argument SIG, as the memory at SIG aren't modified
|
||||
by those routines.
|
||||
|
||||
The constant POLARSSL_MPI_MAX_SIZE in include/polarssl/bignum.h is
|
||||
modified for 2048-bit keys only Gnuk.
|
||||
|
||||
The function mpi_mul_hlp in library/bignum.c is modified for more
|
||||
optimization for ARM Cortex-M3. Functions mpi_montred, mpi_sub_hlp,
|
||||
mpi_sub_abs, mpi_mul_mpi, mpi_montmul, and mpi_exp_mod are modified
|
||||
to avoid side channel attacks. Note that we don't use RSA-blinding
|
||||
technique for Gnuk. Function mpi_gen_prime and mpi_is_prime are
|
||||
modified to use Fouque-Tibouchi method. Function mpi_exp_mod is
|
||||
modified to use new function mpi_montsqr for speed up.
|
||||
|
||||
The file library/aes.c is modified so that some constants can
|
||||
go to .sys section.
|
||||
|
||||
The file include/polarssl/config.h are modified not to define
|
||||
POLARSSL_HAVE_LONGLONG to avoid linking libgcc, to define
|
||||
POLARSSL_AES_ROM_TABLES to have AES tables, not to define
|
||||
POLARSSL_CIPHER_MODE_CTR, POLARSSL_FS_IO, POLARSSL_PKCS1_V21,
|
||||
POLARSSL_SELF_TEST, and POLARSSL_PADLOCK_C, and only define
|
||||
POLARSSL_GENPRIME when defined KEYGEN_SUPPORT.
|
||||
|
||||
|
||||
USB vendor ID and product ID (USB device ID)
|
||||
============================================
|
||||
|
||||
When you have a vendor ID and assign a product ID for Gnuk, edit the
|
||||
file GNUK_USB_DEVICE_ID and add an entry for yours. In this case,
|
||||
please contact Niibe, so that it is listed to the file in the official
|
||||
release of the source code.
|
||||
|
||||
When you are modifing Gnuk and installing the binary to device, you
|
||||
should replace the vendor string and serial number to yours (in the
|
||||
file GNUK_USB_DEVICE_ID and SERIALNO of the script of src/configure),
|
||||
so that users can see it's not by original vendor, and it is modified
|
||||
version.
|
||||
|
||||
FSIJ allows you to use USB device ID of FSIJ (234b:0000) for devices
|
||||
with Gnuk under one of following conditions:
|
||||
|
||||
* For everyone for experimental purpose:
|
||||
|
||||
- You must not distribute a binary with FSIJ's USB device ID, but
|
||||
must use the binary by yourself only for your experiment. Note
|
||||
that "Distributing binary" includes distributing a device which
|
||||
holds the binary.
|
||||
|
||||
* For general individuals:
|
||||
|
||||
- You must use your Gnuk device with a card serial number which is
|
||||
*not* by FSIJ. Easy one would be a card serial number generated
|
||||
by chip unique ID.
|
||||
|
||||
* For individuals with explicit permission from FSIJ.
|
||||
|
||||
- You should have an assigned card serial number by FSIJ,
|
||||
please use that number for your device.
|
||||
(There a file 'GNUK_SERIAL_NUMBER' in the official release.)
|
||||
|
||||
FSIJ could give companies or business entities "second source
|
||||
manufacturer" license to use USB device ID of FSIJ for devices with
|
||||
unmodified version of Gnuk, provided they support Free Software and
|
||||
respect users' freedom for computing. Please ask FSIJ for the
|
||||
license.
|
||||
|
||||
Otherwise, companies which want to distribute Gnuk devices, please use
|
||||
your own USB vendor ID and product ID. Please replace vendor string
|
||||
and possibly product string to yours, when you modify Gnuk.
|
||||
|
||||
|
||||
Host Requirements
|
||||
=================
|
||||
|
||||
For GNU/Linux, PC/SC service is an option, you can use GnuPG's
|
||||
internal CCID driver instead. If you chose using PC/SC service,
|
||||
libccid version >= 1.3.11 is recommended for GNU/Linux.
|
||||
|
||||
|
||||
How to compile
|
||||
==============
|
||||
|
||||
You need GNU toolchain and newlib for 'arm-none-eabi' target.
|
||||
|
||||
On Debian we can install the packages of gcc-arm-none-eabi,
|
||||
gdb-arm-none-eabi and its friends. I'm using:
|
||||
|
||||
binutils-arm-none-eabi 2.28-4+9+b2
|
||||
gcc-arm-none-eabi 15:5.4.1+svn241155-1
|
||||
gdb-arm-none-eabi 7.12-6+9+b2
|
||||
libnewlib-arm-none-eabi 2.4.0.20160527-2
|
||||
|
||||
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
||||
GNU Toolchain for 'arm-none-eabi' target.
|
||||
|
||||
Change directory to `src':
|
||||
|
||||
$ cd gnuk-VERSION/src
|
||||
|
||||
Then, run `configure':
|
||||
|
||||
$ ./configure --vidpid=<VID:PID>
|
||||
|
||||
Here, you need to specify USB vendor ID and product ID. For FSIJ's,
|
||||
it's: --vidpid=234b:0000 . Please read section 'USB vendor ID and
|
||||
product ID' above.
|
||||
|
||||
|
||||
Then, type:
|
||||
|
||||
$ make
|
||||
|
||||
Then, we will have "gnuk.elf" under src/build directory.
|
||||
|
||||
|
||||
How to install
|
||||
==============
|
||||
|
||||
Olimex STM32-H103 board
|
||||
-----------------------
|
||||
|
||||
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 \
|
||||
-c "program build/gnuk.elf verify reset exit"
|
||||
|
||||
Command invocation is assumed in src/ directory.
|
||||
|
||||
|
||||
Flying Stone Tiny 01
|
||||
--------------------
|
||||
|
||||
If you are using Flying Stone Tiny 01, you need a SWD writer.
|
||||
|
||||
OpenOCD 0.9.0 now supports ST-Link/V2. We can use it like:
|
||||
|
||||
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
|
||||
-c "program build/gnuk.elf verify reset exit"
|
||||
|
||||
|
||||
|
||||
STBee
|
||||
-----
|
||||
|
||||
Reset the board with "USER" switch pushed. Type following to write
|
||||
to flash:
|
||||
|
||||
# cd ../tool
|
||||
# ./dfuse.py ../src/build/gnuk.hex
|
||||
|
||||
Then, reset the board.
|
||||
|
||||
|
||||
How to protect flash ROM
|
||||
========================
|
||||
|
||||
To protect, invoke OpenOCD like (for FST-01):
|
||||
|
||||
$ 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, 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
|
||||
========================================================
|
||||
|
||||
This is completely optional.
|
||||
|
||||
For this procedure, you need python and pyscard (python-pyscard
|
||||
package in Debian) or PyUSB 0.4.3 (python-usb package in Debian).
|
||||
|
||||
(1) [pyscard] Stop scdaemon
|
||||
[PyUSB] Stop the pcsc daemon.
|
||||
|
||||
If scdaemon is running, please kill it, or you will get "Smartcard
|
||||
Exception" by "Sharing violation".
|
||||
|
||||
$ gpg-connect-agent "SCD KILLSCD" "SCD BYE" /bye
|
||||
|
||||
In case of PyUSB tool, you need to stop pcscd.
|
||||
|
||||
# /etc/init.d/pcscd stop
|
||||
|
||||
|
||||
(2) [Optional] Write fixed serial number
|
||||
|
||||
If you use fixed serial number in the file 'GNUK_SERIAL_NUMBER', you can do:
|
||||
|
||||
$ EMAIL=<YOUR-EMAIL-ADDRESS> ../tool/gnuk_put_binary_usb.py -s ../GNUK_SERIAL_NUMBER
|
||||
Writing serial number
|
||||
...
|
||||
|
||||
(3) [Optional] Write card holder certificate
|
||||
|
||||
If you have card holder certificate binary file, you can do:
|
||||
|
||||
$ ../tool/gnuk_put_binary_usb.py ../../<YOUR-CERTIFICATE>.bin
|
||||
../../<YOUR-CERTIFICATE>.bin: <LENGTH-OF-YOUR-CERTIFICATE>
|
||||
Updating card holder certificate
|
||||
...
|
||||
|
||||
|
||||
How to run
|
||||
==========
|
||||
|
||||
Debug enabled
|
||||
-------------
|
||||
|
||||
If you compiled with --enable-debug option, Gnuk has two interfaces
|
||||
(one is CCID/ICCD device and another is virtual COM port). Open
|
||||
virtual COM port by:
|
||||
|
||||
$ cu -l /dev/ttyACM0
|
||||
|
||||
and you will see debug output of Gnuk.
|
||||
|
||||
|
||||
Testing Gnuk
|
||||
------------
|
||||
|
||||
Type following command to see Gnuk runs:
|
||||
|
||||
$ gpg --card-status
|
||||
|
||||
|
||||
Besides, there is a functionality test under test/ directory. See
|
||||
test/README.
|
||||
|
||||
|
||||
Personalize the Token, import keys, and change the password
|
||||
-----------------------------------------------------------
|
||||
|
||||
You can personalize the token, putting your information like: Name,
|
||||
Login name, Sex, Languages, URL. To do so, GnuPG command is:
|
||||
|
||||
$ gpg --card-edit
|
||||
|
||||
Note that the factory setting of user password is "123456" and admin
|
||||
password is "12345678" as the specification.
|
||||
|
||||
It is recommended to create your keys on your computer, and import
|
||||
them to Gnuk Token. After you create your keys (they must be 2048-bit
|
||||
RSA), you can import them.
|
||||
|
||||
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/
|
||||
|
||||
|
||||
How to debug
|
||||
============
|
||||
|
||||
We can use GDB.
|
||||
|
||||
$ arm-none-eabi-gdb gnuk.elf
|
||||
|
||||
|
||||
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:
|
||||
|
||||
# /etc/init.d/pcscd stop
|
||||
# LIBCCID_ifdLogLevel=7 /usr/sbin/pcscd --debug --foreground
|
||||
|
||||
|
||||
You can observe the traffic of USB using "usbmon". See the file:
|
||||
linux/Documentation/usb/usbmon.txt
|
||||
|
||||
|
||||
Firmware update
|
||||
===============
|
||||
|
||||
See doc/note/firmware-update.
|
||||
|
||||
|
||||
Git Repositories
|
||||
================
|
||||
|
||||
Please use: https://anonscm.debian.org/cgit/gnuk/gnuk/
|
||||
|
||||
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
|
||||
|
||||
I put Chopstx as a submodule of Git. Please do this:
|
||||
|
||||
$ git submodule update --init
|
||||
|
||||
Gnuk 1.0 uses ChibiOS/RT, and then, we have migrated from to Chopstx
|
||||
in the development phase of Gnuk 1.1. If you have old code of
|
||||
ChibiOS/RT, you need:
|
||||
|
||||
Edit .git/config to remove chibios reference and
|
||||
$ git rm --cached chibios
|
||||
|
||||
|
||||
Information on the Web
|
||||
======================
|
||||
|
||||
Please visit: http://www.fsij.org/gnuk/
|
||||
|
||||
Please see the FST-01 support pages:
|
||||
|
||||
https://www.gniibe.org/category/fst-01.html
|
||||
|
||||
Please consider to join Gnuk-users mailing list:
|
||||
|
||||
https://lists.alioth.debian.org/mailman/listinfo/gnuk-users
|
||||
|
||||
|
||||
Your Contributions
|
||||
==================
|
||||
|
||||
FSIJ welcomes your contributions. Please assign your copyright
|
||||
to FSIJ (if possible), as I do.
|
||||
|
||||
|
||||
Foot note
|
||||
==========
|
||||
|
||||
* NUK(R) is a registered trademark owend by MAPA GmbH, Germany.
|
||||
--
|
||||
138
README.md
Normal file
138
README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
***Note:*** *This fork of Gnuk fixes some compiling bugs and focuses on using the "ST-Link V2" clone hardware.*
|
||||
|
||||
Here is the link to the original project: <http://git.gniibe.org/cgit/gnuk/gnuk.git/>
|
||||
|
||||
What's Gnuk?
|
||||
============
|
||||
Gnuk is an implementation of a USB cryptographic security token that supports the OpenPGP card protocol version 2. It runs on a STM32F103 processor (and its compatible). In short it allows one to convert a cheap $2 "ST-Link V2" clone device into a hardware security token.
|
||||
|
||||
It has supports of Ed25519 and X25519 (ECDH on Curve25519). It also has experimental support of ECDSA (on NIST P256 and secp256k1) and ECDH (on NIST P256 and secp256k1).
|
||||
|
||||
Gnuk supports the Key Derived Function (KDF) functionality. To use this feature one will need to use GnuPG 2.2.6 or later.
|
||||
|
||||
How to build the Gnuk firmware
|
||||
==============================
|
||||
You will need the GNU toolchain for arm-none-eabi and newlib.
|
||||
|
||||
To clone the source code and compile, use the following commands.
|
||||
```
|
||||
git clone --recursive https://git.spengler.co.za/deon/gnuk.git gnuk
|
||||
cd gnuk/src
|
||||
./configure --vidpid=1337:0010
|
||||
make
|
||||
```
|
||||
|
||||
Then, you will have "gnuk.bin" under src/build directory.
|
||||
|
||||
***Please read section 'USB vendor ID and product ID' below.***
|
||||
|
||||
How to flash the Gnuk firmware
|
||||
==============================
|
||||
In order to flash the firmware ensure that you have openocd installed.
|
||||
|
||||
Execute openocd and connect with telnet
|
||||
```
|
||||
openocd -f ../misc/stm32f103.cfg
|
||||
telnet localhost 4444
|
||||
```
|
||||
|
||||
Use the following commands to unlock, flash the firmware and lock the device again.
|
||||
```
|
||||
reset halt
|
||||
stm32f1x unlock 0
|
||||
reset halt
|
||||
flash write_bank 0 ./build/gnuk.bin 0
|
||||
stm32f1x lock 0
|
||||
reset halt
|
||||
```
|
||||
|
||||
How to reflash the ST-LINK
|
||||
==========================
|
||||
To reflash the ST-LINK, connect the device to a programmer as before while keeping pins 7 and 8 shorted. While the LED is blinking, run openocd. Once it’s running (i.e. it doesn’t show any errors), you can unshort the pins.
|
||||
|
||||
Then use the following to unlock and reflash.
|
||||
```
|
||||
reset halt
|
||||
stm32f1x unlock 0
|
||||
reset halt
|
||||
stm32f1x mass_erase 0
|
||||
flash write_bank 0 ./build/gnuk.bin 0
|
||||
stm32f1x lock 0
|
||||
reset halt
|
||||
```
|
||||
|
||||
***Note: That reprograming will wipe the flash memory and you will lose all key's that was on the device.***
|
||||
|
||||
Testing Gnuk
|
||||
============
|
||||
Type following command to see if GnuPG detects the Gnuk token.
|
||||
```
|
||||
gpg --card-status
|
||||
```
|
||||
|
||||
***See tests/README for functionality tests.***
|
||||
|
||||
Personalize the Token, import keys, and change the password
|
||||
===========================================================
|
||||
You can personalize your token by putting in your information like: Name, Login and Language.
|
||||
|
||||
The KDF setting needs to be enabled before any keys are imported into the Gnuk token. Once a key has been imported the KDF setting can't be changed until the token has been reset.
|
||||
|
||||
***Note:*** That the factory user password is "123456" and admin password is "12345678". It is recommended to create your keys on your computer, and import them into the token. Gnuk supports key generation, but this feature is young and should be considered experimental.
|
||||
|
||||
To configure your Gnuk token use the following command.
|
||||
```
|
||||
gpg --card-edit
|
||||
```
|
||||
|
||||
For further details, please see documentation under doc.
|
||||
|
||||
Firmware update
|
||||
===============
|
||||
See doc/note/firmware-update.
|
||||
|
||||
How to debug
|
||||
============
|
||||
Ensure that you have arm-none-eabi-gdb installed and then you must configure and compile the Gnuk firmware with --enable-debug option. After flashing Gnuk debug firmware one will see two interfaces, one is CCID/ICCD device and the another is a virtual COM port.
|
||||
|
||||
Open the virtual COM with the following command:
|
||||
```
|
||||
picocom /dev/ttyACM0
|
||||
```
|
||||
and you will see debug output of Gnuk firmware.
|
||||
|
||||
You can now use GDB with the following command.
|
||||
```
|
||||
arm-none-eabi-gdb src/build/gnuk.elf
|
||||
```
|
||||
|
||||
Inside GDB, we can connect OpenOCD by:
|
||||
```
|
||||
(gdb) target remote localhost:3333
|
||||
```
|
||||
|
||||
You can see the output of PCSCD with the following command:
|
||||
```
|
||||
/usr/bin/pcscd --debug --foreground
|
||||
```
|
||||
|
||||
You can also observe the traffic of the USB interface using "usbmon".
|
||||
|
||||
USB vendor ID and product ID (USB device ID)
|
||||
============================================
|
||||
When you have a vendor ID and assign a product ID for Gnuk, edit the file GNUK_USB_DEVICE_ID and add an entry for yours. In this case, please contact Niibe, so that it is listed to the file in the official release of the source code.
|
||||
|
||||
When you are modifing Gnuk and installing the binary to device, you should replace the vendor string and serial number to yours (in the file GNUK_USB_DEVICE_ID and SERIALNO of the script of src/configure), so that users can see it's not by original vendor, and it is modified version.
|
||||
|
||||
FSIJ allows you to use USB device ID of FSIJ (234b:0000) for devices with Gnuk under one of following conditions:
|
||||
* For everyone for experimental purpose:
|
||||
- You must not distribute a binary with FSIJ's USB device ID, but must use the binary by yourself only for your experiment. Note that "Distributing binary" includes distributing a device which holds the binary.
|
||||
* For general individuals:
|
||||
- You must use your Gnuk device with a card serial number which is *not* by FSIJ. Easy one would be a card serial number generated by chip unique ID.
|
||||
* For individuals with explicit permission from FSIJ.
|
||||
- You should have an assigned card serial number by FSIJ, please use that number for your device.
|
||||
(There a file 'GNUK_SERIAL_NUMBER' in the official release.)
|
||||
|
||||
FSIJ could give companies or business entities "second source manufacturer" license to use USB device ID of FSIJ for devices with unmodified version of Gnuk, provided they support Free Software and respect users' freedom for computing. Please ask FSIJ for the license.
|
||||
|
||||
Otherwise, companies which want to distribute Gnuk devices, please use your own USB vendor ID and product ID. Please replace vendor string and possibly product string to yours, when you modify Gnuk.
|
||||
39
THANKS
39
THANKS
@@ -1,39 +0,0 @@
|
||||
-*- coding: utf-8 -*-
|
||||
|
||||
We would like to express our gratitudes to Werner Koch for GnuPG, and
|
||||
Giovanni Di Sirio for ChibiOS/RT.
|
||||
|
||||
Gnuk was originally written by NIIBE Yutaka. People contributed by
|
||||
encouraging the development, testing the implementation, suggesting
|
||||
improvements, or fixing bugs. Here is a list of those people.
|
||||
|
||||
Achim Pietig achim@pietig.com
|
||||
Aidan Thornton
|
||||
Anibal Monsalve Salazar anibal@debian.org
|
||||
Andre Zepezauer andre.zepezauer@student.uni-halle.de
|
||||
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
|
||||
Jonathan McDowell noodles@earth.li
|
||||
Kaz Kojima kkojima@rr.iij4u.or.jp
|
||||
Kenji Rikitake
|
||||
Ludovic Rousseau ludovic.rousseau@free.fr
|
||||
Luis Felipe R. Murillo luisfelipe@ucla.edu
|
||||
Mateusz Zalega mateusz@nitrokey.com
|
||||
MATSUU Takuto matsuu@gentoo.org
|
||||
Micah Anderson micah@debian.org
|
||||
NAGAMI Takeshi nagami-takeshi@aist.go.jp
|
||||
Nguyễn Hồng Quân quannguyen@mbm.vn
|
||||
Nico Rikken nico@nicorikken.eu
|
||||
NOKUBI Takatsugu knok@daionet.gr.jp
|
||||
Paul Fertser
|
||||
Paul Bakker polarssl_maintainer@polarssl.org
|
||||
Santiago Ruano Rincón santiago@debian.org
|
||||
Shane Coughlan scoughlan@openinventionnetwork.com
|
||||
Szczepan Zalega szczepan@nitrokey.com
|
||||
Vasily Evseenko
|
||||
Werner Koch wk@gnupg.org
|
||||
Yuji Imai ug@xcast.jp
|
||||
2
chopstx
2
chopstx
Submodule chopstx updated: 89eb54929e...a8e9074faf
@@ -40,11 +40,11 @@ We are using "-O3 -Os" for compiler option.
|
||||
Building Gnuk
|
||||
-------------
|
||||
|
||||
Change directory to ``src``:
|
||||
Change directory to ``src``: ::
|
||||
|
||||
$ cd gnuk-VERSION/src
|
||||
|
||||
Then, run ``configure``:
|
||||
Then, run ``configure``: ::
|
||||
|
||||
$ ./configure --vidpid=<VID:PID>
|
||||
|
||||
@@ -52,8 +52,14 @@ Here, you need to specify USB vendor ID and product ID. For FSIJ's,
|
||||
it's: --vidpid=234b:0000 . Please read the section 'USB vendor ID and
|
||||
product ID' in README.
|
||||
|
||||
Type:
|
||||
Type: ::
|
||||
|
||||
$ make
|
||||
|
||||
Then, we will have "gnuk.elf" under src/build directory.
|
||||
|
||||
If you are not the authorized vendor, please never distribute this
|
||||
file of "gnuk.elf", which includes VID:PID in the image. If you would
|
||||
like to distribute the image (for example, to check if it's
|
||||
reproducible or not), the file "gnuk-no-vidpid.elf" is the one with no
|
||||
VID:PID.
|
||||
|
||||
@@ -16,7 +16,7 @@ In addition to settings of Gnuk, I create a file
|
||||
|
||||
# For updating firmware, permission settings are needed.
|
||||
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0000", \
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="234b", ATTR{idProduct}=="0000", \
|
||||
ENV{ID_USB_INTERFACES}=="*:ff0000:*", GROUP="pcscd"
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ setting). It should have lines something like: ::
|
||||
# Gnuk Token by FSIJ
|
||||
|
||||
SUBSYSTEMS=="usb", ACTION=="add", \
|
||||
ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0000", \
|
||||
ATTR{idVendor}=="234b", ATTR{idProduct}=="0000", \
|
||||
ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
|
||||
|
||||
I have those lines in /etc/udev/rules.d/69-gnuk.rules.
|
||||
@@ -73,16 +73,21 @@ and make: ::
|
||||
$ make
|
||||
|
||||
Please take care of configure options. The default target in 1.0.x
|
||||
series is Olimex STM32 H103 (not FST-01). The default target in 1.1.8
|
||||
series is Olimex STM32 H103 (not FST-01). The default target in 1.2.x
|
||||
is FST-01.
|
||||
|
||||
Then you get build/gnuk.elf.
|
||||
|
||||
Then you get build/gnuk.elf and build/gnuk.bin.
|
||||
If you are not the authorized vendor, please never distribute this
|
||||
file of "gnuk.elf", which includes VID:PID in the image. If you would
|
||||
like to distribute the image (for example, to check if it's
|
||||
reproducible or not), the file "gnuk-no-vidpid.elf" is the one with no
|
||||
VID:PID.
|
||||
|
||||
Invoking configure with FSIJ's USB ID (234b:0000) means that you are
|
||||
using FSIJ's USB ID (for reGNUal in this case). Please note that FSIJ
|
||||
only allows use of its USB ID for specific situations. Please read
|
||||
README of Gnuk about that.
|
||||
Invoking configure with FSIJ's USB ID (234b:0000) and generating
|
||||
gnuk.elf means that you are using FSIJ's USB ID (for reGNUal in this
|
||||
case). Please note that FSIJ only allows use of its USB ID for
|
||||
specific situations. Please read README of Gnuk about that.
|
||||
|
||||
|
||||
Bulding reGNUal
|
||||
@@ -117,13 +122,13 @@ your environment for Gnuk Token.
|
||||
How to run the script: ::
|
||||
|
||||
$ cd tool
|
||||
$ ./upgrade_by_passwd.py ../regnual/regnual.bin ../src/build/gnuk.bin
|
||||
$ ./upgrade_by_passwd.py
|
||||
|
||||
Then, the script on your host PC invoke the steps described above, and
|
||||
you will get new version of Gnuk installed.
|
||||
|
||||
You can also specify -p option to enter your password (other than
|
||||
factory setting).
|
||||
You can also specify -f option to skip entering your password (it
|
||||
assumes the factory setting).
|
||||
|
||||
If you already have configured another upgrade key installed, you can
|
||||
specify different slot by -k ``<slot_no>`` option. SLOT_NO can be 0
|
||||
|
||||
@@ -30,9 +30,9 @@ command.
|
||||
|
||||
Or, you can use ``gpgconf`` command. Type::
|
||||
|
||||
$ gpgconf --reload scdameon
|
||||
$ gpgconf --reload scdaemon
|
||||
|
||||
will do the samething.
|
||||
will do the same thing.
|
||||
|
||||
|
||||
Let GPG-AGENT/SCDAEMON learn
|
||||
|
||||
@@ -37,7 +37,7 @@ When we only install "gnupg2" package for 2.0 (with no "gnupg" package),
|
||||
there will be no udev rules (there is a bug report #543217 for this issue).
|
||||
In this case, we need something like this in /etc/udev/rules.d/60-gnuk.rules::
|
||||
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0000", \
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="234b", ATTR{idProduct}=="0000", \
|
||||
ENV{ID_SMARTCARD_READER}="1", ENV{ID_SMARTCARD_READER_DRIVER}="gnupg"
|
||||
|
||||
Usually, udev daemon automatically handles for the changes of configuration
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
SRCS = usbip-server.c usb-emu.c glue.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
TARGET=gnuk_emulation
|
||||
GNUKDIR=../src
|
||||
|
||||
GNUK_SRCS = main.c call-rsa.c \
|
||||
usb-ccid.c openpgp.c ac.c openpgp-do.c flash.c \
|
||||
bn.c mod.c \
|
||||
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
|
||||
random.c neug.c sha256.c
|
||||
USB_SRCS=usb_desc.c usb_ctrl.c
|
||||
|
||||
GNUK_CSRC = $(addprefix $(GNUKDIR)/, $(GNUK_SRCS))
|
||||
GNUK_OBJS = $(notdir $(GNUK_CSRC:.c=.o))
|
||||
|
||||
USB_CSRC = $(addprefix $(GNUKDIR)/, $(USB_SRCS))
|
||||
USB_OBJS = $(notdir $(USB_CSRC:.c=.o))
|
||||
|
||||
# all:
|
||||
# echo $(GNUK_OBJS)
|
||||
|
||||
$(TARGET): $(OBJS) $(USB_OBJS) Makefile
|
||||
$(CC) -o $(TARGET) $(OBJS) $(USB_OBJS)
|
||||
|
||||
$(GNUK_OBJS): %.o : $(GNUKDIR)/%.c Makefile
|
||||
$(CC) -c $(CFLAGS) -I. -I$(GNUKDIR) -I../chopstx $< -o $@
|
||||
|
||||
$(USB_OBJS): %.o : $(GNUKDIR)/%.c Makefile
|
||||
$(CC) -c $(CFLAGS) -I. -I$(GNUKDIR) -I../chopstx $< -o $@
|
||||
@@ -1,54 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t _regnual_start;
|
||||
uint8_t __heap_end__;
|
||||
|
||||
int
|
||||
check_crc32 (const uint32_t *start_p, const uint32_t *end_p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
sram_address (uint32_t offset)
|
||||
{
|
||||
return ((uint8_t *)0x20000000) + offset;
|
||||
}
|
||||
|
||||
const uint8_t sys_version[8] = {
|
||||
3*2+2, /* bLength */
|
||||
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
|
||||
/* sys version: "3.0" */
|
||||
'3', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
void
|
||||
led_blink (int spec)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ccid_usb_reset (int full)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ccid_card_change_signal (int how)
|
||||
{
|
||||
}
|
||||
|
||||
enum ccid_state {
|
||||
CCID_STATE_NOCARD, /* No card available */
|
||||
CCID_STATE_START, /* Initial */
|
||||
CCID_STATE_WAIT, /* Waiting APDU */
|
||||
/* Busy1, Busy2, Busy3, Busy5 */
|
||||
CCID_STATE_EXECUTE, /* Busy4 */
|
||||
CCID_STATE_RECEIVE, /* APDU Received Partially */
|
||||
CCID_STATE_SEND, /* APDU Sent Partially */
|
||||
|
||||
CCID_STATE_EXITED, /* ICC Thread Terminated */
|
||||
CCID_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||
};
|
||||
|
||||
static enum ccid_state ccid_state;
|
||||
enum ccid_state *const ccid_state_p = &ccid_state;
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* usb-emu.c - USB driver for USBIP emulation
|
||||
*
|
||||
* Copyright (C) 2017 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Chopstx, a thread library for embedded.
|
||||
*
|
||||
* Chopstx is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chopstx is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../chopstx/usb_lld.h"
|
||||
|
||||
int
|
||||
usb_lld_ctrl_ack (struct usb_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
usb_lld_ctrl_recv (struct usb_dev *dev, void *p, size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
usb_lld_ctrl_send (struct usb_dev *dev, const void *buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
usb_lld_current_configuration (struct usb_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_prepare_shutdown (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_ctrl_error (struct usb_dev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_reset (struct usb_dev *dev, uint8_t feature)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_set_configuration (struct usb_dev *dev, uint8_t config)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
usb_lld_shutdown (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
|
||||
int ep_rx_addr, int ep_tx_addr,
|
||||
int ep_rx_memory_size)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_stall (int ep_num)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
usb_lld_stall_tx (int ep_num)
|
||||
{
|
||||
usb_lld_stall (ep_num);
|
||||
}
|
||||
|
||||
void
|
||||
usb_lld_stall_rx (int ep_num)
|
||||
{
|
||||
usb_lld_stall (ep_num);
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* usbip-server.c - USB Device Emulation by USBIP Protocol
|
||||
*
|
||||
* Copyright (C) 2017 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Chopstx, a thread library for embedded.
|
||||
*
|
||||
* Chopstx is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chopstx is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define USBIP_PORT 3240
|
||||
|
||||
#define CMD_REQ_LIST 0x01118005
|
||||
#define CMD_REQ_ATTACH 0x01118003
|
||||
#define CMD_URB 0x00000001
|
||||
#define CMD_DETACH 0x00000002
|
||||
|
||||
struct usbip_msg_head {
|
||||
uint32_t cmd;
|
||||
uint32_t seq;
|
||||
};
|
||||
|
||||
#define USBIP_REPLY_HEADER_SIZE 12
|
||||
#define DEVICE_INFO_SIZE (256+32+12+6+6)
|
||||
#define INTERFACE_INFO_SIZE 4
|
||||
#define DEVICE_LIST_SIZE (USBIP_REPLY_HEADER_SIZE+DEVICE_INFO_SIZE*1+INTERFACE_INFO_SIZE*1)
|
||||
|
||||
#define USBIP_REPLY_DEVICE_LIST "\x01\x11\x00\x05"
|
||||
#define NETWORK_UINT32_ZERO "\x00\x00\x00\x00"
|
||||
#define NETWORK_UINT32_ONE "\x00\x00\x00\x01"
|
||||
#define NETWORK_UINT32_TWO "\x00\x00\x00\x02"
|
||||
#define NETWORK_UINT16_FSIJ "\x23\x4b"
|
||||
#define NETWORK_UINT16_ZERO "\x00\x00"
|
||||
#define NETWORK_UINT16_ONE_ONE "\x01\x01"
|
||||
|
||||
static char *
|
||||
list_devices (size_t *len_p)
|
||||
{
|
||||
char *p0, *p;
|
||||
|
||||
*len_p = 0;
|
||||
p0 = malloc (DEVICE_LIST_SIZE);
|
||||
if (p0 == NULL)
|
||||
return NULL;
|
||||
|
||||
*len_p = DEVICE_LIST_SIZE;
|
||||
|
||||
p = p0;
|
||||
memcpy (p, USBIP_REPLY_DEVICE_LIST, 4);
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_ZERO, 4);
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_ONE, 4);
|
||||
p += 4;
|
||||
memset (p, 0, 256);
|
||||
strcpy (p, "/sys/devices/pci0000:00/0000:00:01.1/usb1/1-1");
|
||||
p += 256;
|
||||
memset (p, 0, 32);
|
||||
strcpy (p, "1-1");
|
||||
p += 32;
|
||||
memcpy (p, NETWORK_UINT32_ONE, 4); /* Bus */
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_TWO, 4); /* Dev */
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT32_ONE, 4); /* Speed */
|
||||
p += 4;
|
||||
memcpy (p, NETWORK_UINT16_FSIJ, 2);
|
||||
p += 2;
|
||||
memcpy (p, NETWORK_UINT16_ZERO, 2); /* Gnuk */
|
||||
p += 2;
|
||||
memcpy (p, NETWORK_UINT16_ONE_ONE, 2); /* USB 1.1 */
|
||||
p += 2;
|
||||
|
||||
*p++ = 0; /* bDeviceClass */
|
||||
*p++ = 0; /* bDeviceSubClass */
|
||||
*p++ = 0; /* bDeviceProtocol */
|
||||
*p++ = 0; /* bConfigurationValue */
|
||||
*p++ = 1; /* bConfigurationValue */
|
||||
*p++ = 1; /* bNumInterfaces */
|
||||
|
||||
*p++ = 11; /* bInterfaceClass */
|
||||
*p++ = 0; /* bInterfaceSubClass */
|
||||
*p++ = 0; /* bInterfaceProtocol */
|
||||
*p++ = 0; /* ----pad----------- */
|
||||
|
||||
return p0;
|
||||
}
|
||||
|
||||
static char *
|
||||
attach_device (char busid[32], size_t *len_p)
|
||||
{
|
||||
*len_p = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_urb (int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
run_server (void)
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_in v4addr;
|
||||
const int one = 1;
|
||||
|
||||
if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
perror ("socket");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char*)&one, sizeof (int)) < 0)
|
||||
perror ("WARN: setsockopt");
|
||||
|
||||
memset (&v4addr, 0, sizeof (v4addr));
|
||||
v4addr.sin_family = AF_INET;
|
||||
v4addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
v4addr.sin_port = htons (USBIP_PORT);
|
||||
|
||||
if (bind (sock, (const struct sockaddr *)&v4addr, sizeof (v4addr)) < 0)
|
||||
{
|
||||
perror ("bind");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* We only accept a connection from a single client. */
|
||||
if (listen (sock, 1) < 0)
|
||||
{
|
||||
perror ("listen");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int fd;
|
||||
int attached = 0;
|
||||
|
||||
/* We don't care who is connecting. */
|
||||
if ((fd = accept (sock, NULL, NULL)) < 0)
|
||||
{
|
||||
perror ("accept");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct usbip_msg_head msg;
|
||||
|
||||
if (recv (fd, (char *)&msg, sizeof (msg), 0) != sizeof (msg))
|
||||
{
|
||||
perror ("msg recv");
|
||||
break;
|
||||
}
|
||||
|
||||
msg.cmd = ntohl (msg.cmd);
|
||||
msg.seq = ntohl (msg.seq);
|
||||
|
||||
if (msg.cmd == CMD_REQ_LIST)
|
||||
{
|
||||
char *device_list;
|
||||
size_t device_list_size;
|
||||
|
||||
if (attached)
|
||||
{
|
||||
fprintf (stderr, "REQ list while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
device_list = list_devices (&device_list_size);
|
||||
|
||||
if (send (fd, device_list, device_list_size, 0) != device_list_size)
|
||||
{
|
||||
perror ("list send");
|
||||
break;
|
||||
}
|
||||
|
||||
free (device_list);
|
||||
}
|
||||
else if (msg.cmd == CMD_REQ_ATTACH)
|
||||
{
|
||||
char busid[32];
|
||||
char *attach;
|
||||
size_t attach_size;
|
||||
|
||||
if (attached)
|
||||
{
|
||||
fprintf (stderr, "REQ attach while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (recv (fd, busid, 32, 0) != 32)
|
||||
{
|
||||
perror ("attach recv");
|
||||
break;
|
||||
}
|
||||
|
||||
attach = attach_device (busid, &attach_size);
|
||||
if (send (fd, attach, attach_size, 0) != attach_size)
|
||||
{
|
||||
perror ("list send");
|
||||
break;
|
||||
}
|
||||
|
||||
free (attach);
|
||||
attached = 1;
|
||||
}
|
||||
else if (msg.cmd == CMD_URB)
|
||||
{
|
||||
if (!attached)
|
||||
{
|
||||
fprintf (stderr, "URB while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (handle_urb (fd) < 0)
|
||||
{
|
||||
fprintf (stderr, "URB handling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(msg.cmd == CMD_DETACH)
|
||||
{
|
||||
if (!attached)
|
||||
{
|
||||
fprintf (stderr, "DETACH while attached\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* send reply??? */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Unknown command %08x, disconnecting.\n", msg.cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
run_server ();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,553 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
id="svg3961"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="gnuk-sticers.svg">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3967" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="1031.615"
|
||||
x2="240.89818"
|
||||
y1="1031.615"
|
||||
x1="85.996228"
|
||||
id="linearGradient4296"
|
||||
xlink:href="#linearGradient4290"
|
||||
inkscape:collect="always" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective3903" />
|
||||
<filter
|
||||
id="filter3875"
|
||||
inkscape:collect="always">
|
||||
<feBlend
|
||||
id="feBlend3877"
|
||||
in2="BackgroundImage"
|
||||
mode="screen"
|
||||
inkscape:collect="always" />
|
||||
</filter>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective3830" />
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10-5" />
|
||||
<linearGradient
|
||||
id="linearGradient0">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3620" />
|
||||
<stop
|
||||
id="stop3632"
|
||||
offset="0.07"
|
||||
style="stop-color:#c8c8e0;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3630"
|
||||
offset="0.17"
|
||||
style="stop-color:#9696c8;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3628"
|
||||
offset="0.33"
|
||||
style="stop-color:#6464b4;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#3232a0;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop3634" />
|
||||
<stop
|
||||
id="stop3636"
|
||||
offset="0.66"
|
||||
style="stop-color:#282898;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3626"
|
||||
offset="0.85"
|
||||
style="stop-color:#1e1e90;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#000088;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3622" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient0"
|
||||
id="radialGradient0"
|
||||
cx="450"
|
||||
cy="750"
|
||||
fx="450"
|
||||
fy="750"
|
||||
r="201.5"
|
||||
gradientTransform="matrix(1,0,0,0.75369458,-1.760006,108.15135)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient1">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop0" />
|
||||
<stop
|
||||
id="stop1"
|
||||
offset="0.0625"
|
||||
style="stop-color:#f8fcff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop2"
|
||||
offset="0.17166339"
|
||||
style="stop-color:#f0f8ff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3"
|
||||
offset="0.30279359"
|
||||
style="stop-color:#ecf4ff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#e8f0ff;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop4" />
|
||||
<stop
|
||||
id="stop5"
|
||||
offset="0.65893352"
|
||||
style="stop-color:#e0ecff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop6"
|
||||
offset="0.83552629"
|
||||
style="stop-color:#d8e8ff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#d0e0ff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop7" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="radialGradient1"
|
||||
cx="0"
|
||||
cy="440"
|
||||
fx="0"
|
||||
fy="440"
|
||||
r="80"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter0"
|
||||
x="-0.1423529"
|
||||
width="1.2847058"
|
||||
y="-0.13404847"
|
||||
height="1.2680969">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.0538481"
|
||||
id="feGaussianBlur0" />
|
||||
</filter>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
id="perspective2884" />
|
||||
<inkscape:perspective
|
||||
id="perspective10"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
id="linearGradient4290"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop4292"
|
||||
offset="0"
|
||||
style="stop-color:#000734;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop4294"
|
||||
offset="1"
|
||||
style="stop-color:#000734;stop-opacity:0;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:document-units="mm"
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="-75.714286"
|
||||
inkscape:cy="520"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1122"
|
||||
inkscape:window-height="692"
|
||||
inkscape:window-x="150"
|
||||
inkscape:window-y="51"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
style="display:inline"
|
||||
transform="translate(0.5,-946.62598)"
|
||||
id="layer1-63"
|
||||
inkscape:label="Layer1"
|
||||
inkscape:tile-cx="124.59931"
|
||||
inkscape:tile-cy="53.118107"
|
||||
inkscape:tile-w="248.19862"
|
||||
inkscape:tile-h="105.23622"
|
||||
inkscape:tile-x0="0.5"
|
||||
inkscape:tile-y0="0.49999656">
|
||||
<rect
|
||||
y="947.12598"
|
||||
x="0"
|
||||
height="105.23622"
|
||||
width="248.19862"
|
||||
id="rect0"
|
||||
style="fill:#d9fffe;fill-opacity:1;stroke:none" />
|
||||
<line id="line0"
|
||||
x1="0" y1="947.12598" x2="20" y2="947.12598"
|
||||
style="stroke:#000044;stroke-width:0.5;stroke-opacity:1;stroke-dasharray:2,1;stroke-dashoffset:1" />
|
||||
<line id="line1"
|
||||
x1="248.19862" y1="947.12598" x2="248.19862" y2="957.12598"
|
||||
style="stroke:#000044;stroke-width:0.5;stroke-opacity:1;stroke-dasharray:2,1;stroke-dashoffset:1" />
|
||||
<line id="line2"
|
||||
x1="248.19862" y1="1052.3622" x2="228.19862" y2="1052.3622"
|
||||
style="stroke:#000044;stroke-width:0.5;stroke-opacity:1;stroke-dasharray:2,1;stroke-dashoffset:1" />
|
||||
<line id="line3"
|
||||
x1="0" y1="1052.3622" x2="0" y2="1042.3622"
|
||||
style="stroke:#000044;stroke-width:0.5;stroke-opacity:1;stroke-dasharray:2,1;stroke-dashoffset:1" />
|
||||
<image
|
||||
xlink:href="FSIJ-s.png"
|
||||
width="41.757679"
|
||||
height="28.346457"
|
||||
id="image2886"
|
||||
x="202.27382"
|
||||
y="951.12598" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text2890"
|
||||
y="1014.9048"
|
||||
x="94.433884"
|
||||
style="font-size:52.27830124px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#032b7f;fill-opacity:1;stroke:none;font-family:Courier 10 Pitch;-inkscape-font-specification:Courier 10 Pitch Bold"
|
||||
xml:space="preserve"><tspan
|
||||
y="1014.9048"
|
||||
x="94.433884"
|
||||
id="tspan2892"
|
||||
sodipodi:role="line">GNUK</tspan></text>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
id="layer1-6"
|
||||
transform="matrix(-0.1014557,0,0,0.1014557,90.73972,926.6016)">
|
||||
<path
|
||||
style="fill:#000050;fill-opacity:1;stroke:#000000;stroke-width:2.29999995px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 0,0 c 0,0 0,0 -76,0 0,0 -8,-9 -12,-12 -18,-15 -48,-48 -36,-84 4,-14 12,-36 12,-36 -10,6 -50,26 -66,54 -8,16 -18,30 -18,54 0,24 25,100 48,108 0,0 0,0 150,0 0,0 0,0 150,0 23,-8 48,-84 48,-108 0,-24 -10,-38 -18,-54 -16,-28 -46,-48 -66,-54 0,0 8,22 12,36 12,36 -18,69 -36,84 C 88,-9 80,0 80,0 z"
|
||||
transform="matrix(-1.76,0,0,1.76,410,560)"
|
||||
id="path0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#000040;fill-opacity:1;stroke:none"
|
||||
d="m 411.01194,560.94628 c 0,0 0,0 133.76,0 0,0 14.08,-15.84 21.12,-21.12 31.68,-26.4 84.48,-84.48 63.36,-147.84 -7.04,-24.64 -21.12,-63.36 -21.12,-63.36 17.6,10.56 38,45.76 66.16,95.04 14.08,28.16 19.18,52.8 19.18,95.04 0,42.24 -44,176 -84.48,190.08 0,0 62.5,0 -201.5,0 0,0 62.5,0 -201.5,0 -40.48,-14.08 -84.48,-147.84 -84.48,-190.08 0,-42.24 5.1,-66.88 19.18,-95.04 28.16,-49.28 30.96,-84.48 66.16,-95.04 0,0 -14.08,38.72 -21.12,63.36 -21.12,63.36 31.68,121.44 63.36,147.84 7.04,5.28 21.12,21.12 21.12,21.12 z"
|
||||
id="path0-9"
|
||||
sodipodi:nodetypes="ccccccscccscccccc" />
|
||||
<path
|
||||
style="fill:#c0c0fd;fill-opacity:1;stroke:#000000;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 409.21999,592 c 0,0 90,0 90,-33 0,-20 -4,-28 -12,-40 -5,-8 -8,-18 -8,-28 -1,-13 -1,-20 8,-36 6,-9 8,-23 5,-33 -5,-14 -19,-23 -33,-25 -16,-5 -35,-4 -50,-5 -15,1 -34,0 -50,5 -14,2 -28,9 -33,25 -3,10 1,24 5,33 9,16 9,23 8,36 0,10 -3,20 -8,28 -8,12 -12,20 -12,40 0,33 90,33 90,33 z"
|
||||
id="path1" />
|
||||
<path
|
||||
style="fill:url(#radialGradient1);fill-opacity:1;fill-rule:evenodd;stroke:#d0e0ff;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 0,592 c 0,0 -90,0 -90,-33 0,-20 4,-28 12,-40 5,-8 8,-18 8,-28 1,-13 1,-20 -8,-36 -6,-9 -8,-23 -5,-33 5,-14 19,-23 33,-25 16,-5 35,-4 50,-5 15,1 34,0 50,5 14,2 28,9 33,25 3,10 -1,24 -5,33 -9,16 -9,23 -8,36 0,10 3,20 8,28 8,12 12,20 12,40 0,33 -90,33 -90,33 z"
|
||||
id="path1-1"
|
||||
transform="matrix(-0.75,0,0,0.8,410,100)" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter0)"
|
||||
d="m 344.11439,411.54794 c 7.16035,-2.82917 12.68023,-7.05316 25.88561,-1.83463 -11.82218,3.36559 -30.19974,8.74598 -28.4554,30.10894 0,1.43822 0.19526,2.84651 0.53302,4.18858 -5.07909,-3.45362 -6.70449,-9.04022 -6.70449,-15.93734 0,-10.74221 5.00989,-12.63545 8.74126,-16.52555 z"
|
||||
id="path1-2"
|
||||
sodipodi:nodetypes="ccccsc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter0)"
|
||||
d="m 474.68123,406.16125 c 7.16035,-2.82917 12.68023,-7.05316 25.88561,-1.83463 -11.82218,3.36559 -30.19974,8.74598 -28.4554,30.10894 0,1.43822 0.19526,2.84651 0.53302,4.18858 -5.07909,-3.45362 -6.70449,-9.04022 -6.70449,-15.93734 0,-10.74221 5.00989,-12.63545 8.74126,-16.52555 z"
|
||||
id="path1-3"
|
||||
sodipodi:nodetypes="ccccsc"
|
||||
transform="matrix(-1,0,0,1,949.00681,5.38669)" />
|
||||
<path
|
||||
style="fill:#afcfff;fill-opacity:1;stroke:#000000;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 236.90125,452.90625 C 135.34805,496.35376 97.060607,634.496 151.37,761.4375 c 50.02335,116.92341 158.1859,159.40625 257.75,159.40625 99.5641,0 207.72665,-42.48284 257.75,-159.40625 C 721.17939,634.496 682.89195,496.35376 581.33875,452.90625 526.07714,429.26367 466.8919,524.375 409.12,524.375 c -57.7719,0 -116.77668,-94.67646 -172.21875,-71.46875 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#radialGradient0);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path3"
|
||||
d="m 538.23999,720 a 130,150 0 0 1 -260,0 130,150 0 1 1 260,0 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4.47213602px;stroke-opacity:1"
|
||||
d="m 538.30032,722.21875 c 56.32313,26.16396 100.82185,68.68738 119.76563,119.4375 33.50451,82.59901 -5.55269,179.72665 -93.67188,230.71875 -89.66782,55.4574 -224.43374,55.4574 -314.10156,0 -88.11919,-50.9921 -127.13733,-148.11974 -93.63281,-230.71875 18.61816,-50.41349 63.06491,-92.92973 119.25781,-119.1875 11.1304,10.32118 18.58377,23.0939 22.34375,36.6875 -5.94376,3.59375 -11.63988,7.47175 -16.99219,11.625 -73.95399,55.19241 -81.85302,155.28934 -18.59375,218.125 47.75721,51.30795 139.68,72.55545 213.4375,46.68755 87.41094,-28.2229 135.47694,-110.93384 113.94531,-183.2813 -9.09953,-36.85675 -36.47131,-70.33241 -73.67187,-92.96875 2.51871,-9.1715 6.69761,-18.00492 12.57812,-26 2.55237,-3.99852 5.70954,-7.71801 9.33594,-11.125 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<text
|
||||
sodipodi:linespacing="85.000002%"
|
||||
id="text3817"
|
||||
y="1038.1145"
|
||||
x="98.368591"
|
||||
style="font-size:18px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:85.00000238%;writing-mode:lr-tb;text-anchor:start;fill:#120054;fill-opacity:1;stroke:none;display:inline;font-family:Gentium Basic;-inkscape-font-specification:Gentium Basic Bold Italic"
|
||||
xml:space="preserve"><tspan
|
||||
y="1038.1145"
|
||||
x="98.368591"
|
||||
style="fill:#120054;fill-opacity:1"
|
||||
id="tspan4288"
|
||||
sodipodi:role="line">GnuPG USB Token</tspan></text>
|
||||
</g>
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
id="use4758" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,105.23622)"
|
||||
id="use4760" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,210.47244)"
|
||||
id="use4762" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,315.70866)"
|
||||
id="use4764" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,420.94489)"
|
||||
id="use4766" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,526.18111)"
|
||||
id="use4768" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,631.41733)"
|
||||
id="use4770" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,736.65355)"
|
||||
id="use4772" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,841.88977)"
|
||||
id="use4774" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(0,947.12599)"
|
||||
id="use4776" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,0)"
|
||||
id="use4778" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,105.23622)"
|
||||
id="use4780" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,210.47244)"
|
||||
id="use4782" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,315.70866)"
|
||||
id="use4784" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,420.94489)"
|
||||
id="use4786" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,526.18111)"
|
||||
id="use4788" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,631.41733)"
|
||||
id="use4790" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,736.65355)"
|
||||
id="use4792" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,841.88977)"
|
||||
id="use4794" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(248.19862,947.12599)"
|
||||
id="use4796" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,0)"
|
||||
id="use4798" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,105.23622)"
|
||||
id="use4800" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,210.47244)"
|
||||
id="use4802" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,315.70866)"
|
||||
id="use4804" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,420.94489)"
|
||||
id="use4806" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,526.18111)"
|
||||
id="use4808" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,631.41733)"
|
||||
id="use4810" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,736.65355)"
|
||||
id="use4812" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,841.88977)"
|
||||
id="use4814" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
inkscape:tiled-clone-of="#layer1-63"
|
||||
xlink:href="#layer1-63"
|
||||
transform="translate(496.39725,947.12599)"
|
||||
id="use4816" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 20 KiB |
4
misc/stm32f103.cfg
Normal file
4
misc/stm32f103.cfg
Normal file
@@ -0,0 +1,4 @@
|
||||
telnet_port 4444
|
||||
source [find interface/stlink.cfg]
|
||||
source [find target/stm32f1x.cfg]
|
||||
set WORKAREASIZE 0x10000
|
||||
@@ -495,6 +495,67 @@
|
||||
#endif /* TriCore */
|
||||
|
||||
#if defined(__arm__)
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
/* The ARM DSP instructions are available on Cortex M4, M7 and
|
||||
Cortex A CPUs */
|
||||
|
||||
#define MULADDC_1024_CORE \
|
||||
"ldmia %[s]!, { r7, r8, r9, r10 } \n\t" \
|
||||
"ldmia %[d], { r3, r4, r5, r6 } \n\t" \
|
||||
"umaal r3, %2, %[b], r7 \n\t" \
|
||||
"umaal r4, %2, %[b], r8 \n\t" \
|
||||
"umaal r5, %2, %[b], r9 \n\t" \
|
||||
"umaal r6, %2, %[b], r10 \n\t" \
|
||||
"stmia %[d]!, {r3, r4, r5, r6} \n\t"
|
||||
|
||||
#define MULADDC_1024_LOOP \
|
||||
asm( "tst %[i], #0xfe0 \n\t" \
|
||||
"beq 0f \n" \
|
||||
"1: sub %[i], %[i], #32 \n\t" \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
MULADDC_1024_CORE MULADDC_1024_CORE \
|
||||
"tst %[i], #0xfe0 \n\t" \
|
||||
"bne 1b \n" \
|
||||
"0:" \
|
||||
: [s] "=r" (s), [d] "=r" (d), [c] "=r" (c), [i] "=r" (i) \
|
||||
: [b] "r" (b), "[s]" (s), "[d]" (d), "[c]" (c), "[i]" (i) \
|
||||
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "memory", "cc" );
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm(
|
||||
|
||||
#define MULADDC_CORE \
|
||||
"ldr r0, [%0], #4 \n\t" \
|
||||
"ldr r1, [%1] \n\t" \
|
||||
"umaal r1, %2, %3, r0 \n\t" \
|
||||
"str r1, [%1], #4 \n\t"
|
||||
|
||||
#define MULADDC_HUIT \
|
||||
"ldmia %0!, {r0, r1, r2, r3} \n\t" \
|
||||
"ldmia %1, {r4, r5, r6, r7} \n\t" \
|
||||
"umaal r4, %2, %3, r0 \n\t" \
|
||||
"umaal r5, %2, %3, r1 \n\t" \
|
||||
"umaal r6, %2, %3, r2 \n\t" \
|
||||
"umaal r7, %2, %3, r3 \n\t" \
|
||||
"stmia %1!, {r4, r5, r6, r7} \n\t" \
|
||||
"ldmia %0!, {r0, r1, r2, r3} \n\t" \
|
||||
"ldmia %1, {r4, r5, r6, r7} \n\t" \
|
||||
"umaal r4, %2, %3, r0 \n\t" \
|
||||
"umaal r5, %2, %3, r1 \n\t" \
|
||||
"umaal r6, %2, %3, r2 \n\t" \
|
||||
"umaal r7, %2, %3, r3 \n\t" \
|
||||
"stmia %1!, {r4, r5, r6, r7} \n\t"
|
||||
|
||||
#define MULADDC_STOP \
|
||||
: "=r" (s), "=r" (d), "=r" (c) \
|
||||
: "r" (b), "0" (s), "1" (d), "2" (c) \
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5", \
|
||||
"r6", "r7", "memory");
|
||||
|
||||
#else /* __ARM_FEATURE_DSP */
|
||||
|
||||
#define MULADDC_1024_CORE \
|
||||
"ldmia %[s]!, { r8, r9, r10 } \n\t" \
|
||||
"ldmia %[d], { r5, r6, r7 } \n\t" \
|
||||
@@ -556,7 +617,7 @@
|
||||
: "r4", "r5", "r6", "r7", "r8", "r9", "r10", "memory", "cc" );
|
||||
|
||||
/* Just for reference (dead code) */
|
||||
#define MULADDC_HUIT \
|
||||
#define MULADDC_HUIT_DEAD \
|
||||
"ldmia %0!, { r4, r5 } \n\t" \
|
||||
"ldmia %1, { r8, r9 } \n\t" \
|
||||
"umull r6, r7, %3, r4 \n\t" \
|
||||
@@ -620,6 +681,7 @@
|
||||
: "r" (b), "0" (s), "1" (d), "2" (c) \
|
||||
: "r4", "r5", "r6", "r7", "memory", "cc" );
|
||||
|
||||
#endif /* __ARM_FEATURE_DSP */
|
||||
#endif /* ARMv3 */
|
||||
|
||||
#if defined(__alpha__)
|
||||
@@ -811,8 +873,8 @@
|
||||
#else
|
||||
#define MULADDC_INIT \
|
||||
{ \
|
||||
t_int s0, s1, b0, b1; \
|
||||
t_int r0, r1, rx, ry; \
|
||||
t_uint s0, s1, b0, b1; \
|
||||
t_uint r0, r1, rx, ry; \
|
||||
b0 = ( b << biH ) >> biH; \
|
||||
b1 = ( b >> biH );
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "polarssl/bignum.h"
|
||||
#include "polarssl/bn_mul.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gnuk-malloc.h>
|
||||
|
||||
#define ciL (sizeof(t_uint)) /* chars in limb */
|
||||
#define biL (ciL << 3) /* bits in limb */
|
||||
@@ -223,6 +223,7 @@ size_t mpi_lsb( const mpi *X )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if !defined(POLARSSL_HAVE_UDBL)
|
||||
/*
|
||||
* Count leading zero bits in a given integer
|
||||
*/
|
||||
@@ -240,6 +241,7 @@ static size_t int_clz( const t_uint x )
|
||||
|
||||
return j;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the number of most significant bits
|
||||
@@ -1140,9 +1142,9 @@ static t_uint int_div_int(t_uint u1, t_uint u0, t_uint d, t_uint *r)
|
||||
*/
|
||||
if(( 0 == d ) || ( u1 >= d ))
|
||||
{
|
||||
if (r != NULL) *r = (~0);
|
||||
if (r != NULL) *r = (~0UL);
|
||||
|
||||
return (~0);
|
||||
return (~0UL);
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_HAVE_UDBL)
|
||||
@@ -1268,7 +1270,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
|
||||
for( i = n; i > t ; i-- )
|
||||
{
|
||||
if( X.p[i] >= Y.p[t] )
|
||||
Z.p[i - t - 1] = ~0;
|
||||
Z.p[i - t - 1] = ~0UL;
|
||||
else
|
||||
{
|
||||
Z.p[i - t - 1] = int_div_int( X.p[i], X.p[i-1], Y.p[t], NULL);
|
||||
@@ -1295,7 +1297,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
|
||||
MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
|
||||
MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
|
||||
|
||||
if( mpi_cmp_int( &X, 0 ) < 0 )
|
||||
while( mpi_cmp_int( &X, 0 ) < 0 )
|
||||
{
|
||||
MPI_CHK( mpi_copy( &T1, &Y ) );
|
||||
MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
|
||||
@@ -1512,9 +1514,17 @@ static void mpi_montred( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
/*
|
||||
* Montgomery square: A = A * A * R^-1 mod N
|
||||
* A is placed at the upper half of D.
|
||||
*
|
||||
* n : number of limbs of N
|
||||
* np: pointer to limbs of bignum N
|
||||
* mm: m' = -N^(-1) mod b where b = 2^number-of-bit-in-limb
|
||||
* d (destination): the result [<-- temp -->][<--- A ---->]
|
||||
* lower part upper part
|
||||
* n-limb n-limb
|
||||
*/
|
||||
static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_ASM) && defined(__arm__)
|
||||
size_t i;
|
||||
register t_uint c = 0;
|
||||
|
||||
@@ -1526,6 +1536,52 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
|
||||
x_i = *xj;
|
||||
*xj++ = c;
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
asm (/* (C,R4,R5) := w_i_i + x_i*x_i; w_i_i := R5; */
|
||||
"mov %[c], #0\n\t"
|
||||
"ldr r5, [%[wij]]\n\t" /* R5 := w_i_i; */
|
||||
"mov r4, %[c]\n\t"
|
||||
"umlal r5, r4, %[x_i], %[x_i]\n\t"
|
||||
"str r5, [%[wij]], #4\n\t"
|
||||
"cmp %[xj], %[x_max1]\n\t"
|
||||
"bhi 0f\n\t"
|
||||
"mov r9, %[c]\n\t" /* R9 := 0, the constant ZERO from here. */
|
||||
"beq 1f\n"
|
||||
"2:\n\t"
|
||||
"ldmia %[xj]!, { r7, r8 }\n\t"
|
||||
"ldmia %[wij], { r5, r6 }\n\t"
|
||||
/* (C,R4,R5) := (C,R4) + w_i_j + 2*x_i*x_j; */
|
||||
"umaal r5, r4, %[x_i], r7\n\t"
|
||||
"umlal r5, %[c], %[x_i], r7\n\t"
|
||||
"umaal r4, %[c], r9, r9\n\t"
|
||||
/* (C,R4,R6) := (C,R4) + w_i_j + 2*x_i*x_j; */
|
||||
"umaal r6, r4, %[x_i], r8\n\t"
|
||||
"umlal r6, %[c], %[x_i], r8\n\t"
|
||||
"umaal r4, %[c], r9, r9\n\t"
|
||||
/**/
|
||||
"stmia %[wij]!, { r5, r6 }\n\t"
|
||||
"cmp %[xj], %[x_max1]\n\t"
|
||||
"bcc 2b\n\t"
|
||||
"bne 0f\n"
|
||||
"1:\n\t"
|
||||
/* (C,R4,R5) := (C,R4) + w_i_j + 2*x_i*x_j; */
|
||||
"ldr r5, [%[wij]]\n\t"
|
||||
"ldr r6, [%[xj]], #4\n\t"
|
||||
"umaal r5, r4, %[x_i], r6\n\t"
|
||||
"umlal r5, %[c], %[x_i], r6\n\t"
|
||||
"umaal r4, %[c], r9, r9\n\t"
|
||||
"str r5, [%[wij]], #4\n"
|
||||
"0:\n\t"
|
||||
"ldr r5, [%[wij]]\n\t"
|
||||
"adds r4, r4, r5\n\t"
|
||||
"adc %[c], %[c], #0\n\t"
|
||||
"str r4, [%[wij]]"
|
||||
: [c] "=&r" (c), [wij] "=r" (wij), [xj] "=r" (xj)
|
||||
: [x_i] "r" (x_i), [x_max1] "r" (&d[n*2-1]),
|
||||
"[wij]" (wij), "[xj]" (xj)
|
||||
: "r4", "r5", "r6", "r7", "r8", "r9", "memory", "cc");
|
||||
#else
|
||||
asm (/* (C,R4,R5) := w_i_i + x_i*x_i; w_i_i := R5; */
|
||||
"mov %[c], #0\n\t"
|
||||
"ldr r5, [%[wij]]\n\t" /* R5 := w_i_i; */
|
||||
@@ -1587,6 +1643,7 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
: [x_i] "r" (x_i), [x_max1] "r" (&d[n*2-1]),
|
||||
"[wij]" (wij), "[xj]" (xj)
|
||||
: "r4", "r5", "r6", "r7", "r8", "r9", "r12", "memory", "cc");
|
||||
#endif
|
||||
|
||||
c += mpi_mul_hlp( n, np, &d[i], d[i] * mm );
|
||||
}
|
||||
@@ -1598,16 +1655,29 @@ static void mpi_montsqr( size_t n, const t_uint *np, t_uint mm, t_uint *d )
|
||||
mpi_sub_hlp( n, np, d );
|
||||
else
|
||||
mpi_sub_hlp( n, d - n, d - n);
|
||||
#else
|
||||
t_uint a_input[n];
|
||||
|
||||
memcpy (a_input, &d[n], sizeof (a_input));
|
||||
mpi_montmul (n, np, mm, d, a_input);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
|
||||
*/
|
||||
#if MEMORY_SIZE >= 32
|
||||
#define MAX_WSIZE 6
|
||||
#elif MEMORY_SIZE >= 24
|
||||
#define MAX_WSIZE 5
|
||||
#else
|
||||
#define MAX_WSIZE 4
|
||||
#endif
|
||||
int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
||||
{
|
||||
int ret;
|
||||
size_t i = mpi_msb( E );
|
||||
size_t wsize = ( i > 1024 ) ? 4 : /* Because of not enough memory. */
|
||||
size_t wsize = ( i > 1024 ) ? MAX_WSIZE :
|
||||
( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
|
||||
( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
|
||||
size_t wbits, one = 1;
|
||||
@@ -1632,7 +1702,6 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
||||
* Init temps and window size
|
||||
*/
|
||||
mpi_montg_init( &mm, N );
|
||||
MPI_CHK( mpi_grow( X, N->n ) );
|
||||
|
||||
/*
|
||||
* If 1st call, pre-compute R^2 mod N
|
||||
@@ -1658,6 +1727,8 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
||||
memset (d, 0, N->n * ciL); /* Set lower half of D zero. */
|
||||
}
|
||||
|
||||
MPI_CHK( mpi_grow( X, N->n ) );
|
||||
|
||||
/*
|
||||
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
|
||||
*/
|
||||
@@ -2051,17 +2122,19 @@ jkiss (struct jkiss_state *s)
|
||||
static int mpi_fill_pseudo_random ( mpi *X, size_t size)
|
||||
{
|
||||
int ret;
|
||||
uint32_t *p;
|
||||
uint32_t *p, *p_end;
|
||||
|
||||
MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
|
||||
MPI_CHK( mpi_lset( X, 0 ) );
|
||||
|
||||
/* Assume little endian. */
|
||||
p = X->p;
|
||||
while (p < X->p + (size/ciL))
|
||||
p = (uint32_t *)X->p;
|
||||
p_end = (uint32_t *)(X->p + (size/sizeof (uint32_t)));
|
||||
while (p < p_end)
|
||||
*p++ = jkiss (&jkiss_state_v);
|
||||
if ((size % ciL))
|
||||
*p = jkiss (&jkiss_state_v) & ((1 << (8*(size % ciL))) - 1);
|
||||
|
||||
if ((size%sizeof (uint32_t)))
|
||||
*p = jkiss (&jkiss_state_v) & ((1 << (8*(size % sizeof (uint32_t)))) - 1);
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
@@ -2202,10 +2275,24 @@ cleanup:
|
||||
* Value M: multiply all primes up to 701 (except 97) and 797
|
||||
* (so that MAX_A will be convenient value)
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
#define M_LIMBS 16
|
||||
#else
|
||||
#define M_LIMBS 31
|
||||
#endif
|
||||
#define M_SIZE 122
|
||||
|
||||
static const t_uint limbs_M[] = { /* Little endian */
|
||||
#ifdef __LP64__
|
||||
0x9344A6AB84EEB59EUL, 0xEC855CDAFF21529FUL,
|
||||
0x477E991E009BAB38UL, 0x2EEA23579F5B86F3UL,
|
||||
0xAC17D30441D6502FUL, 0x38FF52B90A468A6DUL,
|
||||
0x63630419FD42E5EFUL, 0x48CE17D091DB2572UL,
|
||||
0x708AB00AE3B57D0EUL, 0xF8A9DE08CD723598UL,
|
||||
0x731411374432C93BUL, 0x554DF2612779FAB3UL,
|
||||
0xDEEBDA58953D2BA5UL, 0xD1D66F2F5F57D007UL,
|
||||
0xB85C9607E84E9F2BUL, 0x000000000000401DUL
|
||||
#else
|
||||
0x84EEB59E, 0x9344A6AB, 0xFF21529F, 0xEC855CDA,
|
||||
0x009BAB38, 0x477E991E, 0x9F5B86F3, 0x2EEA2357,
|
||||
0x41D6502F, 0xAC17D304, 0x0A468A6D, 0x38FF52B9,
|
||||
@@ -2214,6 +2301,7 @@ static const t_uint limbs_M[] = { /* Little endian */
|
||||
0x4432C93B, 0x73141137, 0x2779FAB3, 0x554DF261,
|
||||
0x953D2BA5, 0xDEEBDA58, 0x5F57D007, 0xD1D66F2F,
|
||||
0xE84E9F2B, 0xB85C9607, 0x0000401D
|
||||
#endif
|
||||
};
|
||||
|
||||
static const mpi M[1] = {{ 1, M_LIMBS, (t_uint *)limbs_M }};
|
||||
@@ -2221,10 +2309,18 @@ static const mpi M[1] = {{ 1, M_LIMBS, (t_uint *)limbs_M }};
|
||||
/*
|
||||
* MAX_A : 2^1024 / M - 1
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
#define MAX_A_LIMBS 1
|
||||
#else
|
||||
#define MAX_A_LIMBS 2
|
||||
#endif
|
||||
#define MAX_A_FILL_SIZE 6
|
||||
static const t_uint limbs_MAX_A[] = { /* Little endian */
|
||||
#ifdef __LP64__
|
||||
0x0003FE2556A2B35FUL
|
||||
#else
|
||||
0x56A2B35F, 0x0003FE25
|
||||
#endif
|
||||
};
|
||||
|
||||
static const mpi MAX_A[1] = {{ 1, MAX_A_LIMBS, (t_uint *)limbs_MAX_A }};
|
||||
@@ -2274,9 +2370,8 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
|
||||
|
||||
MPI_CHK ( mpi_mul_mpi ( X, X, M ) );
|
||||
MPI_CHK ( mpi_add_abs ( X, X, B ) );
|
||||
if (X->n <= 31 || (X->p[31] & 0xc0000000) == 0)
|
||||
if (X->n <= M_LIMBS || (X->p[M_LIMBS-1] & 0xc0000000) == 0)
|
||||
continue;
|
||||
|
||||
ret = mpi_is_prime ( X );
|
||||
if (ret == 0 || ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE)
|
||||
break;
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "polarssl/md.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# Makefile for reGNUal
|
||||
|
||||
PROJECT = regnual
|
||||
PROJECT = regnual-no-vidpid
|
||||
|
||||
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
|
||||
@@ -38,13 +41,18 @@ regnual.hex: regnual.elf
|
||||
$(OBJCOPY) -Obinary regnual.elf regnual.bin
|
||||
$(OBJCOPY) -Oihex regnual.elf regnual.hex
|
||||
|
||||
regnual.elf: regnual-no-vidpid.elf
|
||||
cp -p regnual-no-vidpid.elf regnual.elf
|
||||
env FILE="regnual.elf" PATH="../src:$$PATH" bash put-vid-pid-ver.sh
|
||||
|
||||
usb-stm32f103.o: ../chopstx/mcu/usb-stm32f103.c
|
||||
$(CC) $(CFLAGS) -c -o usb-stm32f103.o ../chopstx/mcu/usb-stm32f103.c
|
||||
|
||||
regnual.elf: $(OBJS) $(LDSCRIPT)
|
||||
$(CC) $(LDFLAGS) -o regnual.elf $(OBJS)
|
||||
regnual-no-vidpid.elf: $(OBJS) $(LDSCRIPT)
|
||||
$(CC) $(LDFLAGS) -o regnual-no-vidpid.elf $(OBJS)
|
||||
|
||||
clean:
|
||||
-rm -f $(OBJS) regnual.elf regnual.hex regnual.bin *.lst
|
||||
-rm -f $(OBJS) regnual-no-vidpid.elf regnual.elf regnual.hex regnual.bin \
|
||||
*.lst
|
||||
|
||||
distclean: clean
|
||||
|
||||
@@ -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, 2018
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -26,12 +26,12 @@
|
||||
* ReGNUal
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "usb_lld.h"
|
||||
#include "sys.h"
|
||||
|
||||
extern void *memset (void *s, int c, size_t n);
|
||||
|
||||
extern void set_led (int);
|
||||
extern int flash_write (uint32_t dst_addr, const uint8_t *src, size_t len);
|
||||
extern int flash_protect (void);
|
||||
@@ -57,7 +57,9 @@ static const uint8_t regnual_device_desc[] = {
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
#include "../src/usb-vid-pid-ver.c.inc"
|
||||
0x00, 0x00, /* idVendor (will be replaced) */
|
||||
0x00, 0x00, /* idProduct (will be replaced) */
|
||||
0x00, 0x00, /* bcdDevice (will be replaced) */
|
||||
1, /* Index of string descriptor describing manufacturer */
|
||||
2, /* Index of string descriptor describing product */
|
||||
3, /* Index of string descriptor describing the device's serial number */
|
||||
@@ -147,19 +149,33 @@ static uint32_t fetch (int i)
|
||||
}
|
||||
|
||||
struct CRC {
|
||||
__IO uint32_t DR;
|
||||
__IO uint8_t IDR;
|
||||
volatile uint32_t DR;
|
||||
volatile uint8_t IDR;
|
||||
uint8_t RESERVED0;
|
||||
uint16_t RESERVED1;
|
||||
__IO uint32_t CR;
|
||||
volatile uint32_t CR;
|
||||
};
|
||||
static struct CRC *const CRC = (struct CRC *)0x40023000;
|
||||
|
||||
struct RCC {
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CFGR;
|
||||
volatile uint32_t CIR;
|
||||
volatile uint32_t APB2RSTR;
|
||||
volatile uint32_t APB1RSTR;
|
||||
volatile uint32_t AHBENR;
|
||||
/* ... */
|
||||
};
|
||||
static struct RCC *const RCC = (struct RCC *)0x40021000;
|
||||
#define RCC_AHBENR_CRCEN 0x00000040
|
||||
|
||||
|
||||
#define CRC_CR_RESET 0x01
|
||||
static uint32_t calc_crc32 (void)
|
||||
{
|
||||
struct CRC *CRC = (struct CRC *)0x40023000;
|
||||
int i;
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
|
||||
for (i = 0; i < 256/4; i++)
|
||||
@@ -365,7 +381,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.
|
||||
|
||||
@@ -1,12 +1,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
|
||||
|
||||
#define NULL 0
|
||||
|
||||
#define __IO volatile
|
||||
|
||||
110
src/Makefile
Normal file
110
src/Makefile
Normal file
@@ -0,0 +1,110 @@
|
||||
# Makefile for Gnuk
|
||||
|
||||
# Define project name here
|
||||
PROJECT = gnuk
|
||||
|
||||
CHOPSTX = ../chopstx
|
||||
|
||||
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 \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
|
||||
random.c neug.c sha256.c
|
||||
|
||||
INCDIR =
|
||||
|
||||
CRYPTDIR = ../polarssl
|
||||
CRYPTSRCDIR = $(CRYPTDIR)/library
|
||||
CRYPTINCDIR = $(CRYPTDIR)/include
|
||||
CRYPTSRC = $(CRYPTSRCDIR)/bignum.c $(CRYPTSRCDIR)/rsa.c $(CRYPTSRCDIR)/aes.c
|
||||
|
||||
CSRC += $(CRYPTSRC)
|
||||
INCDIR += $(CRYPTINCDIR)
|
||||
|
||||
include config.mk
|
||||
|
||||
USE_SYS = yes
|
||||
USE_USB = yes
|
||||
USE_ADC = yes
|
||||
USE_EVENTFLAG = yes
|
||||
|
||||
ifeq ($(EMULATION),)
|
||||
DEFS += -DFLASH_UPGRADE_SUPPORT
|
||||
else
|
||||
DEFS += -DBN256_C_IMPLEMENTATION
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_DEBUG),)
|
||||
CSRC += debug.c
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_PINPAD),)
|
||||
CSRC += pin-$(ENABLE_PINPAD).c
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_PINPAD),dnd)
|
||||
CSRC += usb-msc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CHIP),stm32f103)
|
||||
CSRC += mcu-stm32f103.c
|
||||
endif
|
||||
|
||||
ifneq ($(USE_DFU),)
|
||||
OBJS_ADD += build/stdaln-sys-bin.o
|
||||
endif
|
||||
|
||||
###################################
|
||||
CC = $(CROSS)gcc
|
||||
LD = $(CROSS)gcc
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
|
||||
CWARN = -Wall -Wextra -Wstrict-prototypes
|
||||
OPT = -O3 -Os -g
|
||||
|
||||
#######################
|
||||
include $(CHOPSTX)/rules.mk
|
||||
|
||||
board.h:
|
||||
@echo Please run configure to have a symbolic link \'board.h\'
|
||||
@exit 1
|
||||
|
||||
sys.c: board.h
|
||||
|
||||
build/bignum.o: OPT = -O3 -g
|
||||
|
||||
build/stdaln-sys.elf: build/sys-$(CHIP).o stdaln-sys.ld
|
||||
@echo
|
||||
$(LD) -v $< $(MCFLAGS) -nostartfiles -Tstdaln-sys.ld -Wl,--no-warn-mismatch,--gc-sections $(LLIBDIR) -o $@
|
||||
|
||||
build/stdaln-sys-bin.o: build/stdaln-sys.elf
|
||||
@echo
|
||||
$(OBJCOPY) -O binary -j .sys $< build/stdaln-sys.bin
|
||||
$(OBJCOPY) -I binary -O default --rename-section .data=.rodata \
|
||||
build/stdaln-sys.bin $@
|
||||
|
||||
distclean: clean
|
||||
-rm -f gnuk.ld stdaln-sys.ld config.h board.h config.mk \
|
||||
usb-strings.c.inc put-vid-pid-ver.sh
|
||||
|
||||
ifeq ($(EMULATION),)
|
||||
build/gnuk.elf: build/gnuk-no-vidpid.elf binary-edit.sh put-vid-pid-ver.sh
|
||||
cp -p build/gnuk-no-vidpid.elf build/gnuk.elf
|
||||
env FILE="build/gnuk.elf" bash put-vid-pid-ver.sh
|
||||
$(OBJCOPY) -O ihex build/gnuk.elf build/gnuk.hex
|
||||
$(OBJCOPY) -O binary build/gnuk.elf build/gnuk.bin
|
||||
else
|
||||
# By specifying DESTDIR on invocation of "make", you can install
|
||||
# program to different ROOT.
|
||||
|
||||
# The variables prefix, exec_prefix, libexecdir are defined in
|
||||
# config.mk.
|
||||
|
||||
install: build/gnuk
|
||||
test -d "$(DESTDIR)$(libexecdir)" || mkdir -p "$(DESTDIR)$(libexecdir)"
|
||||
install -c build/gnuk "$(DESTDIR)$(libexecdir)"
|
||||
|
||||
endif
|
||||
@@ -1,79 +0,0 @@
|
||||
# Makefile for Gnuk
|
||||
|
||||
# Define project name here
|
||||
PROJECT = gnuk
|
||||
|
||||
CHOPSTX = ../chopstx
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= gnuk.ld
|
||||
|
||||
CSRC = main.c call-rsa.c mcu-stm32f103.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 \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
mod25638.c ecc-edwards.c ecc-mont.c sha512.c \
|
||||
random.c neug.c sha256.c
|
||||
|
||||
INCDIR =
|
||||
|
||||
CRYPTDIR = ../polarssl
|
||||
CRYPTSRCDIR = $(CRYPTDIR)/library
|
||||
CRYPTINCDIR = $(CRYPTDIR)/include
|
||||
CRYPTSRC = $(CRYPTSRCDIR)/bignum.c $(CRYPTSRCDIR)/rsa.c $(CRYPTSRCDIR)/aes.c
|
||||
|
||||
CSRC += $(CRYPTSRC)
|
||||
INCDIR += $(CRYPTINCDIR)
|
||||
|
||||
@PINPAD_MAKE_OPTION@
|
||||
@DEBUG_MAKE_OPTION@
|
||||
@HEXOUTPUT_MAKE_OPTION@
|
||||
|
||||
USE_EVENTFLAG = yes
|
||||
|
||||
ifneq ($(ENABLE_DEBUG),)
|
||||
CSRC += debug.c
|
||||
endif
|
||||
|
||||
ifneq ($(ENABLE_PINPAD),)
|
||||
CSRC += pin-$(ENABLE_PINPAD).c
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_PINPAD),dnd)
|
||||
CSRC += usb-msc.c
|
||||
endif
|
||||
|
||||
CHIP=stm32f103
|
||||
USE_SYS = yes
|
||||
USE_USB = yes
|
||||
USE_ADC = yes
|
||||
|
||||
###################################
|
||||
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
|
||||
|
||||
board.h:
|
||||
@echo Please run configure to have a symbolic link \'board.h\'
|
||||
@exit 1
|
||||
|
||||
sys.c: board.h
|
||||
|
||||
build/bignum.o: OPT = -O3 -g
|
||||
|
||||
distclean: clean
|
||||
-rm -f gnuk.ld config.h board.h Makefile \
|
||||
usb-strings.c.inc usb-vid-pid-ver.c.inc
|
||||
56
src/ac.c
56
src/ac.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ac.c -- Check access condition
|
||||
*
|
||||
* Copyright (C) 2010, 2012, 2013 Free Software Initiative of Japan
|
||||
* Copyright (C) 2010, 2012, 2013, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -63,7 +63,7 @@ verify_user_0 (uint8_t access, const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
const uint8_t *ks_pw1, int save_ks)
|
||||
{
|
||||
int pw_len;
|
||||
int r1, r2;
|
||||
int r;
|
||||
uint8_t keystring[KEYSTRING_MD_SIZE];
|
||||
const uint8_t *salt;
|
||||
int salt_len;
|
||||
@@ -73,12 +73,14 @@ verify_user_0 (uint8_t access, const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
|
||||
if (ks_pw1 == NULL)
|
||||
{
|
||||
pw_len = strlen (OPENPGP_CARD_INITIAL_PW1);
|
||||
const uint8_t *initial_pw;
|
||||
|
||||
salt = NULL;
|
||||
salt_len = 0;
|
||||
gpg_do_get_initial_pw_setting (0, &pw_len, &initial_pw);
|
||||
if ((pw_len_known >= 0 && pw_len_known != pw_len)
|
||||
|| buf_len < pw_len
|
||||
|| strncmp ((const char *)pw, OPENPGP_CARD_INITIAL_PW1, pw_len))
|
||||
|| memcmp (pw, initial_pw, pw_len))
|
||||
goto failure;
|
||||
}
|
||||
else
|
||||
@@ -97,21 +99,31 @@ verify_user_0 (uint8_t access, const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
memcpy (keystring_md_pw3, keystring, KEYSTRING_MD_SIZE);
|
||||
|
||||
if (access == AC_PSO_CDS_AUTHORIZED)
|
||||
{
|
||||
r1 = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER, keystring);
|
||||
r2 = 0;
|
||||
}
|
||||
r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER, keystring);
|
||||
else
|
||||
{
|
||||
int r1, r2;
|
||||
|
||||
r1 = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, BY_USER, keystring);
|
||||
r2 = gpg_do_load_prvkey (GPG_KEY_FOR_AUTHENTICATION, BY_USER, keystring);
|
||||
|
||||
if (r1 < 0 || r2 < 0)
|
||||
r = -1;
|
||||
else if (r1 == 0)
|
||||
{
|
||||
if (r2 == 0)
|
||||
/* No encryption/authentication keys, then, check signing key. */
|
||||
r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER, keystring);
|
||||
else
|
||||
r = r2;
|
||||
}
|
||||
else if (r2 == 0)
|
||||
r = r1;
|
||||
else
|
||||
r = 1;
|
||||
}
|
||||
|
||||
if (r1 < 0 || r2 < 0
|
||||
|| (r1 == 0 && r2 == 0 && ks_pw1 != NULL
|
||||
&& ((ks_pw1[0] & PW_LEN_KEYSTRING_BIT) == 0
|
||||
|| memcmp (KS_GET_KEYSTRING (ks_pw1),
|
||||
keystring, KEYSTRING_MD_SIZE) != 0)))
|
||||
if (r < 0)
|
||||
{
|
||||
failure:
|
||||
gpg_pw_increment_err_counter (PW_ERR_PW1);
|
||||
@@ -161,7 +173,7 @@ verify_admin_00 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
const uint8_t *ks, int save_ks)
|
||||
{
|
||||
int pw_len;
|
||||
int r1, r2;
|
||||
int r;
|
||||
uint8_t keystring[KEYSTRING_MD_SIZE];
|
||||
const uint8_t *salt;
|
||||
int salt_len;
|
||||
@@ -177,12 +189,11 @@ verify_admin_00 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
if (save_ks)
|
||||
memcpy (keystring_md_pw3, keystring, KEYSTRING_MD_SIZE);
|
||||
|
||||
r1 = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_ADMIN, keystring);
|
||||
r2 = 0;
|
||||
r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_ADMIN, keystring);
|
||||
|
||||
if (r1 < 0 || r2 < 0)
|
||||
if (r < 0)
|
||||
return -1;
|
||||
else if (r1 == 0 && r2 == 0)
|
||||
else if (r == 0)
|
||||
if ((ks[0] & PW_LEN_KEYSTRING_BIT) == 0
|
||||
|| memcmp (KS_GET_KEYSTRING (ks), keystring, KEYSTRING_MD_SIZE) != 0)
|
||||
return -1;
|
||||
@@ -220,6 +231,7 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *initial_pw;
|
||||
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
||||
|
||||
if (ks_pw1 != NULL)
|
||||
@@ -237,13 +249,13 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known,
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* For the case of empty PW3 (with empty PW1), pass phrase
|
||||
* should be OPENPGP_CARD_INITIAL_PW3
|
||||
* For the case of empty PW3 (with empty PW1), passphrase is
|
||||
* OPENPGP_CARD_INITIAL_PW3, or defined by KDF DO.
|
||||
*/
|
||||
pw_len = strlen (OPENPGP_CARD_INITIAL_PW3);
|
||||
gpg_do_get_initial_pw_setting (1, &pw_len, &initial_pw);
|
||||
if ((pw_len_known >=0 && pw_len_known != pw_len)
|
||||
|| buf_len < pw_len
|
||||
|| strncmp ((const char *)pw, OPENPGP_CARD_INITIAL_PW3, pw_len))
|
||||
|| memcmp (pw, initial_pw, pw_len))
|
||||
goto failure;
|
||||
|
||||
admin_authorized = BY_ADMIN;
|
||||
|
||||
76
src/binary-edit.sh
Normal file
76
src/binary-edit.sh
Normal file
@@ -0,0 +1,76 @@
|
||||
# This is a Bash script to be included.
|
||||
|
||||
# Idx Name Size VMA LMA File off Algn
|
||||
# =================
|
||||
# 2 .text 00004a40 080010f0 080010f0 000110f0 2**4
|
||||
# 08006550 l O .text 00000012 device_desc
|
||||
# =================
|
||||
# VMA =0x080010f0
|
||||
# FOFF=0x000110f0
|
||||
# ADDR=0x08005ad0
|
||||
# file_off_ADDR = ADDR - VMA + FOFF
|
||||
# = 0x08005ad0 - 0x080010f0 + 0x000110f0 = 0x00015ad0
|
||||
|
||||
function calc_addr () {
|
||||
local line_sym="" VMA FOFF ADDR
|
||||
|
||||
arm-none-eabi-objdump -h -t -j .text $FILE | \
|
||||
egrep -e '(^ +[0-9] +\.text +|device_desc)' | \
|
||||
while read -r F0 F1 F2 F3 F4 F5 F6; do
|
||||
if [ -z "$line_sym" ]; then
|
||||
VMA=$F3
|
||||
FOFF=$F5
|
||||
line_sym="next is a line for the symbol"
|
||||
else
|
||||
ADDR=$F0
|
||||
echo "$((0x$ADDR - 0x$VMA + 0x$FOFF))"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
declare -a OFFSETS
|
||||
OFFSETS=($(calc_addr))
|
||||
file_off_ADDR=${OFFSETS[0]}
|
||||
file_off_fraucheky_ADDR=${OFFSETS[1]}
|
||||
|
||||
echo "Offset is $file_off_ADDR"
|
||||
if [ -n "$file_off_fraucheky_ADDR" ]; then
|
||||
echo "Offset is $file_off_fraucheky_ADDR"
|
||||
fi
|
||||
|
||||
function replace_file_byte_at () {
|
||||
printf "\x$1" | dd of=$FILE bs=1 seek=$2 conv=notrunc >& /dev/null
|
||||
}
|
||||
|
||||
#
|
||||
# vid_lsb: 8
|
||||
# vid_msb: 9
|
||||
# pid_lsb: 10
|
||||
# pid_msb: 11
|
||||
# bcd_device_lsb: 12
|
||||
# bcd_device_msb: 13
|
||||
#
|
||||
|
||||
function replace_vid_lsb () {
|
||||
replace_file_byte_at $1 $((addr + 8))
|
||||
}
|
||||
|
||||
function replace_vid_msb () {
|
||||
replace_file_byte_at $1 $((addr + 9))
|
||||
}
|
||||
|
||||
function replace_pid_lsb () {
|
||||
replace_file_byte_at $1 $((addr + 10))
|
||||
}
|
||||
|
||||
function replace_pid_msb () {
|
||||
replace_file_byte_at $1 $((addr + 11))
|
||||
}
|
||||
|
||||
function replace_bcd_device_lsb () {
|
||||
replace_file_byte_at $1 $((addr + 12))
|
||||
}
|
||||
|
||||
function replace_bcd_device_msb () {
|
||||
replace_file_byte_at $1 $((addr + 13))
|
||||
}
|
||||
23
src/bn.c
23
src/bn.c
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* bn.c -- 256-bit (and 512-bit) bignum calculation
|
||||
*
|
||||
* Copyright (C) 2011, 2013, 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2013, 2014, 2019
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -412,17 +413,15 @@ bn256_cmp (const bn256 *A, const bn256 *B)
|
||||
void
|
||||
bn256_random (bn256 *X)
|
||||
{
|
||||
const uint8_t *rand = random_bytes_get ();
|
||||
int i, j;
|
||||
const uint8_t *rand;
|
||||
|
||||
X->word[7] = ((uint32_t *)rand)[7];
|
||||
X->word[6] = ((uint32_t *)rand)[6];
|
||||
X->word[5] = ((uint32_t *)rand)[5];
|
||||
X->word[4] = ((uint32_t *)rand)[4];
|
||||
X->word[3] = ((uint32_t *)rand)[3];
|
||||
X->word[2] = ((uint32_t *)rand)[2];
|
||||
X->word[1] = ((uint32_t *)rand)[1];
|
||||
X->word[0] = ((uint32_t *)rand)[0];
|
||||
|
||||
random_bytes_free (rand);
|
||||
for (i = 0; i < 256/256; i++)
|
||||
{
|
||||
rand = random_bytes_get ();
|
||||
for (j = 0; j < BN256_WORDS; j++)
|
||||
X->word[i*BN256_WORDS+j] = ((uint32_t *)rand)[j];
|
||||
random_bytes_free (rand);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* call-ec.c - interface between Gnuk and Elliptic curve over GF(prime)
|
||||
*
|
||||
* Copyright (C) 2013, 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2013, 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -54,28 +54,21 @@ FUNC(ecdsa_sign) (const uint8_t *hash, uint8_t *output,
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
FUNC(ecc_compute_public) (const uint8_t *key_data)
|
||||
int
|
||||
FUNC(ecc_compute_public) (const uint8_t *key_data, uint8_t *pubkey)
|
||||
{
|
||||
uint8_t *p0, *p, *p1;
|
||||
uint8_t *p, *p1;
|
||||
ac q[1];
|
||||
bn256 k[1];
|
||||
int i;
|
||||
|
||||
p0 = (uint8_t *)malloc (ECDSA_BYTE_SIZE * 2);
|
||||
if (p0 == NULL)
|
||||
return NULL;
|
||||
|
||||
p = (uint8_t *)k;
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
p[ECDSA_BYTE_SIZE - i - 1] = key_data[i];
|
||||
if (FUNC(compute_kG) (q, k) < 0)
|
||||
{
|
||||
free (p0);
|
||||
return NULL;
|
||||
}
|
||||
return -1;
|
||||
|
||||
p = p0;
|
||||
p = pubkey;
|
||||
p1 = (uint8_t *)q->x;
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
*p++ = p1[ECDSA_BYTE_SIZE - i - 1];
|
||||
@@ -83,7 +76,7 @@ FUNC(ecc_compute_public) (const uint8_t *key_data)
|
||||
for (i = 0; i < ECDSA_BYTE_SIZE; i++)
|
||||
*p++ = p1[ECDSA_BYTE_SIZE - i - 1];
|
||||
|
||||
return p0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* call-ec_p256k1.c - interface between Gnuk and Elliptic curve over
|
||||
* GF(p256k1)
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bn.h"
|
||||
#include "affine.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* call-ec_p256r1.c - interface between Gnuk and Elliptic curve over
|
||||
* GF(p256r1)
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bn.h"
|
||||
#include "affine.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2017
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
#include "config.h"
|
||||
@@ -41,7 +40,7 @@ static struct chx_cleanup clp;
|
||||
static void
|
||||
rsa_cleanup (void *arg)
|
||||
{
|
||||
free (arg);
|
||||
(void)arg;
|
||||
rsa_free (&rsa_ctx);
|
||||
}
|
||||
|
||||
@@ -111,28 +110,23 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
|
||||
/*
|
||||
* LEN: length in byte
|
||||
*/
|
||||
uint8_t *
|
||||
modulus_calc (const uint8_t *p, int len)
|
||||
int
|
||||
modulus_calc (const uint8_t *p, int len, uint8_t *pubkey)
|
||||
{
|
||||
mpi P, Q, N;
|
||||
uint8_t *modulus;
|
||||
int ret;
|
||||
|
||||
modulus = malloc (len);
|
||||
if (modulus == NULL)
|
||||
return NULL;
|
||||
|
||||
mpi_init (&P); mpi_init (&Q); mpi_init (&N);
|
||||
MPI_CHK( mpi_read_binary (&P, p, len / 2) );
|
||||
MPI_CHK( mpi_read_binary (&Q, p + len / 2, len / 2) );
|
||||
MPI_CHK( mpi_mul_mpi (&N, &P, &Q) );
|
||||
MPI_CHK( mpi_write_binary (&N, modulus, len) );
|
||||
MPI_CHK( mpi_write_binary (&N, pubkey, len) );
|
||||
cleanup:
|
||||
mpi_free (&P); mpi_free (&Q); mpi_free (&N);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
else
|
||||
return modulus;
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,6 +136,9 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
{
|
||||
mpi P1, Q1, H;
|
||||
int ret;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
size_t output_len;
|
||||
#endif
|
||||
|
||||
DEBUG_INFO ("RSA decrypt:");
|
||||
DEBUG_WORD ((uint32_t)&ret);
|
||||
@@ -177,9 +174,16 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, &output_len, input,
|
||||
output, MAX_RES_APDU_DATA_SIZE);
|
||||
*output_len_p = (unsigned int)output_len;
|
||||
#else
|
||||
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, output_len_p, input,
|
||||
output, MAX_RES_APDU_DATA_SIZE);
|
||||
#endif
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
}
|
||||
@@ -232,54 +236,39 @@ rsa_verify (const uint8_t *pubkey, int pubkey_len,
|
||||
|
||||
#define RSA_EXPONENT 0x10001
|
||||
|
||||
uint8_t *
|
||||
rsa_genkey (int pubkey_len)
|
||||
int
|
||||
rsa_genkey (int pubkey_len, uint8_t *pubkey, uint8_t *p_q)
|
||||
{
|
||||
int ret;
|
||||
uint8_t index = 0;
|
||||
uint8_t *p_q_modulus = (uint8_t *)malloc (pubkey_len * 2);
|
||||
uint8_t *p = p_q_modulus;
|
||||
uint8_t *q = p_q_modulus + pubkey_len / 2;
|
||||
uint8_t *modulus = p_q_modulus + pubkey_len;
|
||||
uint8_t *p = p_q;
|
||||
uint8_t *q = p_q + pubkey_len / 2;
|
||||
int cs;
|
||||
|
||||
extern int prng_seed (int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
extern void neug_flush (void);
|
||||
|
||||
if (p_q_modulus == NULL)
|
||||
return NULL;
|
||||
|
||||
neug_flush ();
|
||||
prng_seed (random_gen, &index);
|
||||
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
|
||||
|
||||
clp.next = NULL;
|
||||
clp.routine = rsa_cleanup;
|
||||
clp.arg = (void *)p_q_modulus;
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
MPI_CHK( rsa_gen_key (&rsa_ctx, random_gen, &index, pubkey_len * 8,
|
||||
RSA_EXPONENT) );
|
||||
if (ret != 0)
|
||||
{
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
free (p_q_modulus);
|
||||
rsa_free (&rsa_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.P, p, pubkey_len / 2) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.Q, q, pubkey_len / 2) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.N, modulus, pubkey_len) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.N, pubkey, pubkey_len) );
|
||||
|
||||
cleanup:
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
rsa_free (&rsa_ctx);
|
||||
chopstx_cleanup_pop (1);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
return -1;
|
||||
else
|
||||
return p_q_modulus;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
#define ENABLE_VIRTUAL_COM_PORT 1
|
||||
#endif
|
||||
@DFU_DEFINE@
|
||||
@ORIGIN_DEFINE@
|
||||
@ORIGIN_REAL_DEFINE@
|
||||
@PINPAD_DEFINE@
|
||||
@PINPAD_MORE_DEFINE@
|
||||
@CERTDO_DEFINE@
|
||||
@HID_CARD_CHANGE_DEFINE@
|
||||
@SERIALNO_STR_LEN_DEFINE@
|
||||
@LIFE_CYCLE_MANAGEMENT_DEFINE@
|
||||
@ACKBTN_DEFINE@
|
||||
@SERIALNO_STR_LEN_DEFINE@
|
||||
@KDF_DO_REQUIRED_DEFINE@
|
||||
|
||||
292
src/configure
vendored
292
src/configure
vendored
@@ -6,10 +6,11 @@ nl=$'\n'
|
||||
#
|
||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||
#
|
||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2021
|
||||
# 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
|
||||
@@ -35,35 +36,45 @@ fi
|
||||
# Default settings
|
||||
help=no
|
||||
vidpid=none
|
||||
target=FST_01
|
||||
verbose=no
|
||||
target=ST_DONGLE
|
||||
with_dfu=default
|
||||
debug=no
|
||||
sys1_compat=yes
|
||||
pinpad=no
|
||||
certdo=no
|
||||
hid_card_change=no
|
||||
factory_reset=no
|
||||
factory_reset=yes
|
||||
ackbtn_support=yes
|
||||
flash_override=""
|
||||
kdf_do=${kdf_do:-optional}
|
||||
# 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 +107,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
|
||||
@@ -117,17 +137,21 @@ Configuration:
|
||||
supported targets are:
|
||||
FST_01
|
||||
FST_01G
|
||||
FST_01SZ
|
||||
OLIMEX_STM32_H103
|
||||
MAPLE_MINI
|
||||
ST_DONGLE
|
||||
ST_NUCLEO_F103
|
||||
NITROKEY_START
|
||||
BLUE_PILL
|
||||
STM8S_DISCOVERY
|
||||
CQ_STARM
|
||||
STM32_PRIMER2
|
||||
STBEE
|
||||
STBEE_MINI
|
||||
FST_01_00 (unreleased version with 8MHz XTAL)
|
||||
--enable-factory-reset
|
||||
support life cycle management [no]
|
||||
--enable-debug debug with virtual COM port [no]
|
||||
--enable-pinpad=cir
|
||||
PIN entry support [no]
|
||||
@@ -137,22 +161,17 @@ 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
|
||||
|
||||
# Frequency
|
||||
MHZ=72
|
||||
# Flash page size in byte
|
||||
FLASH_PAGE_SIZE=1024
|
||||
# Flash memory size in KiB
|
||||
@@ -162,6 +181,10 @@ MEMORY_SIZE=20
|
||||
|
||||
# Settings for TARGET
|
||||
case $target in
|
||||
BLUE_PILL|STM8S_DISCOVERY)
|
||||
# It's 64KB version of STM32F103, but actually has 128KB
|
||||
flash_override="-DSTM32F103_OVERRIDE_FLASH_SIZE_KB=128"
|
||||
;;
|
||||
CQ_STARM|STBEE_MINI)
|
||||
if test "$with_dfu" = "default"; then
|
||||
with_dfu=yes;
|
||||
@@ -178,13 +201,57 @@ STBEE)
|
||||
if test "$with_dfu" = "default"; then
|
||||
with_dfu=yes;
|
||||
fi ;;
|
||||
STM8S_DISCOVERY)
|
||||
FLASH_SIZE=64
|
||||
BLUE_PILL_G)
|
||||
MHZ=96
|
||||
;;
|
||||
FST_01SZ)
|
||||
MHZ=96
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
def_mhz="-DMHZ=$MHZ"
|
||||
if test "$target" = "GNU_LINUX"; then
|
||||
ldscript=""
|
||||
chip="gnu-linux"
|
||||
arch="gnu-linux"
|
||||
emulation="yes"
|
||||
cross=""
|
||||
mcu="none"
|
||||
kdf_do=${kdf_do:-required}
|
||||
def_emulation="-DGNU_LINUX_EMULATION"
|
||||
def_memory_size="-DMEMORY_SIZE=1024"
|
||||
enable_hexoutput=""
|
||||
libs="-lpthread"
|
||||
else
|
||||
ldscript="gnuk.ld"
|
||||
chip="stm32f103"
|
||||
arch="cortex-m"
|
||||
emulation=""
|
||||
cross="arm-none-eabi-"
|
||||
mcu="cortex-m3"
|
||||
def_emulation=""
|
||||
def_memory_size="-DMEMORY_SIZE=$MEMORY_SIZE"
|
||||
enable_hexoutput=yes
|
||||
libs=""
|
||||
fi
|
||||
|
||||
if test "$emulation" = "yes"; then
|
||||
if test "$vidpid" = "none"; then
|
||||
vidpid=0000:0000
|
||||
else
|
||||
echo "Please don't specify VID:PID for emulation at compile time;"
|
||||
echo "It is a user who should specify VID:PID at run time."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if test "$vidpid" = "none"; then
|
||||
echo "Please specify Vendor ID and Product ID by --vidpid option." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# --enable-debug option
|
||||
if test "$debug" = "yes"; then
|
||||
DEBUG_MAKE_OPTION="ENABLE_DEBUG=1"
|
||||
@@ -196,6 +263,8 @@ else
|
||||
echo "Debug option disabled"
|
||||
fi
|
||||
|
||||
ORIGIN_REAL=0x08000000
|
||||
ORIGIN_REAL_DEFINE="#define ORIGIN_REAL $ORIGIN_REAL"
|
||||
# --with-dfu option
|
||||
if test "$with_dfu" = "yes"; then
|
||||
if test "$target" = "FST_01" -o "$target" = "FST_01G" \
|
||||
@@ -204,22 +273,25 @@ if test "$with_dfu" = "yes"; then
|
||||
exit 1
|
||||
fi
|
||||
echo "Configured for DFU"
|
||||
ORIGIN=0x08003000
|
||||
FLASH_SIZE=`expr $FLASH_SIZE - 12`
|
||||
if test "$target" = "MAPLE_MINI"; then
|
||||
# Note that the default bootloader is too large, need for instance
|
||||
# STM32duino for DFU on Maple Mini
|
||||
ORIGIN=0x08002000
|
||||
FLASH_SIZE=$((FLASH_SIZE - 8))
|
||||
else
|
||||
ORIGIN=0x08003000
|
||||
FLASH_SIZE=$((FLASH_SIZE - 12))
|
||||
fi
|
||||
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
|
||||
ORIGIN=${ORIGIN_REAL}
|
||||
DFU_DEFINE="#undef DFU_SUPPORT"
|
||||
HEXOUTPUT_MAKE_OPTION=""
|
||||
fi
|
||||
ORIGIN_DEFINE="#define ORIGIN $ORIGIN"
|
||||
|
||||
# --enable-pinpad option
|
||||
MSC_SIZE="0"
|
||||
TIM_SIZE="0"
|
||||
EXT_SIZE="0"
|
||||
if test "$pinpad" = "no"; then
|
||||
PINPAD_MAKE_OPTION="# ENABLE_PINPAD="
|
||||
PINPAD_DEFINE="#undef PINPAD_SUPPORT"
|
||||
@@ -230,12 +302,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,14 +331,31 @@ else
|
||||
echo "Life cycle management is NOT supported"
|
||||
fi
|
||||
|
||||
# Acknowledge button support
|
||||
if test "$ackbtn_support" = "yes"; then
|
||||
ACKBTN_DEFINE="#define ACKBTN_SUPPORT 1"
|
||||
echo "Acknowledge button is supported"
|
||||
else
|
||||
ACKBTN_DEFINE="#undef ACKBTN_SUPPORT"
|
||||
echo "Acknowledge button is not supported"
|
||||
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 !!! ####
|
||||
SERIALNO="FSIJ-`cat ../VERSION | sed -e 's%^[^/]*/%%'`-"
|
||||
SERIALNO="DTS-$(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:kdf=$kdf_do"
|
||||
else
|
||||
if test "$with_dfu" = "yes"; then
|
||||
echo "Common binary can't support DFU loader, don't use --with-dfu." >&2
|
||||
@@ -282,53 +365,82 @@ 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:kdf=$kdf_do"
|
||||
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]\)$%\1\t\2\t\3\t\4%p" | \
|
||||
while read -r FIRST SECOND THIRD FOURTH; do
|
||||
if test $FIRST != 00; then
|
||||
echo replace_vid_msb $FIRST
|
||||
fi
|
||||
if test $SECOND != 00; then
|
||||
echo replace_vid_lsb $SECOND
|
||||
fi
|
||||
if test $THIRD != 00; then
|
||||
echo replace_pid_msb $THIRD
|
||||
fi
|
||||
if test $FOURTH != 00; then
|
||||
echo replace_pid_lsb $FOURTH
|
||||
fi
|
||||
done
|
||||
echo "$VERSION" | \
|
||||
sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$%\1\t\2%p" | \
|
||||
while read -r FIRST SECOND; do
|
||||
if test $FIRST != 00; then
|
||||
echo replace_bcd_device_msb $FIRST
|
||||
fi
|
||||
if test $SECOND != 00; then
|
||||
echo replace_bcd_device_lsb $SECOND
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
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,16 +448,22 @@ output_vendor_product_serial_strings () {
|
||||
fi
|
||||
}
|
||||
|
||||
(echo "#! /bin/bash"
|
||||
echo
|
||||
echo 'source "binary-edit.sh"') > put-vid-pid-ver.sh
|
||||
|
||||
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
|
||||
echo >> put-vid-pid-ver.sh
|
||||
echo 'addr=$file_off_ADDR' >> put-vid-pid-ver.sh
|
||||
output_vid_pid_version >> put-vid-pid-ver.sh
|
||||
output_vendor_product_serial_strings gnuk_ >usb-strings.c.inc
|
||||
exit 0
|
||||
fi
|
||||
done; exit 1) < ../GNUK_USB_DEVICE_ID
|
||||
then
|
||||
echo "Please specify valid Vendor ID and Product ID." >&2
|
||||
echo "Please specify valid Vendor ID and Product ID." >&2
|
||||
echo "Check ../GNUK_USB_DEVICE_ID." >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -362,37 +480,57 @@ 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 "ARCH=$arch";
|
||||
echo "EMULATION=$emulation";
|
||||
echo "CROSS=$cross";
|
||||
echo "MCU=$mcu";
|
||||
echo "DEFS=$use_sys3 $flash_override $def_emulation $def_memory_size $def_mhz";
|
||||
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 "$ackbtn_support" = "yes"; then
|
||||
echo "USE_ACKBTN=yes"
|
||||
fi
|
||||
if test "$with_dfu" = "yes"; then
|
||||
echo "USE_DFU=yes"
|
||||
fi
|
||||
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/@ORIGIN_REAL@/$ORIGIN_REAL/" -e "s/@MEMORY_SIZE@/$MEMORY_SIZE/" \
|
||||
< stdaln-sys.ld.in > stdaln-sys.ld
|
||||
sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
|
||||
-e "s/@DFU_DEFINE@/$DFU_DEFINE/" \
|
||||
-e "s/@ORIGIN_DEFINE@/$ORIGIN_DEFINE/" \
|
||||
-e "s/@ORIGIN_REAL_DEFINE@/$ORIGIN_REAL_DEFINE/" \
|
||||
-e "s/@PINPAD_DEFINE@/$PINPAD_DEFINE/" \
|
||||
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
|
||||
-e "s/@CERTDO_DEFINE@/$CERTDO_DEFINE/" \
|
||||
-e "s/@HID_CARD_CHANGE_DEFINE@/$HID_CARD_CHANGE_DEFINE/" \
|
||||
-e "s/@LIFE_CYCLE_MANAGEMENT_DEFINE@/$LIFE_CYCLE_MANAGEMENT_DEFINE/" \
|
||||
-e "s/@ACKBTN_DEFINE@/$ACKBTN_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
|
||||
exit 0
|
||||
|
||||
@@ -42,9 +42,11 @@
|
||||
/*
|
||||
* a = 0, b = 7
|
||||
*/
|
||||
#if 0
|
||||
static const bn256 coefficient_a[1] = {
|
||||
{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}
|
||||
};
|
||||
#endif
|
||||
|
||||
static const bn256 coefficient_b[1] = {
|
||||
{{ 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* ecc-edwards.c - Elliptic curve computation for
|
||||
* the twisted Edwards curve: -x^2 + y^2 = 1 + d*x^2*y^2
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bn.h"
|
||||
@@ -708,7 +707,7 @@ eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
eddsa_public_key_25519 (bn256 *pk, const bn256 *a)
|
||||
{
|
||||
ac R[1];
|
||||
@@ -730,18 +729,10 @@ eddsa_public_key_25519 (bn256 *pk, const bn256 *a)
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
eddsa_compute_public_25519 (const uint8_t *kd)
|
||||
void
|
||||
eddsa_compute_public_25519 (const uint8_t *kd, uint8_t *pubkey)
|
||||
{
|
||||
uint8_t *p0;
|
||||
const bn256 *a = (const bn256 *)kd;
|
||||
|
||||
p0 = (uint8_t *)malloc (sizeof (bn256));
|
||||
if (p0 == NULL)
|
||||
return NULL;
|
||||
|
||||
eddsa_public_key_25519 ((bn256 *)p0, a);
|
||||
return p0;
|
||||
eddsa_public_key_25519 ((bn256 *)pubkey, (const bn256 *)kd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* ecc-mont.c - Elliptic curve computation for
|
||||
* the Montgomery curve: y^2 = x^3 + 486662*x^2 + x.
|
||||
*
|
||||
* Copyright (C) 2014, 2015 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2015, 2017 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "bn.h"
|
||||
#include "mod25638.h"
|
||||
#include "mod.h"
|
||||
@@ -198,22 +197,17 @@ compute_nQ (bn256 *res, const bn256 *n, const bn256 *q_x)
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
ecdh_compute_public_25519 (const uint8_t *key_data)
|
||||
void
|
||||
ecdh_compute_public_25519 (const uint8_t *key_data, uint8_t *pubkey)
|
||||
{
|
||||
uint8_t *p;
|
||||
bn256 gx[1];
|
||||
bn256 k[1];
|
||||
|
||||
memset (gx, 0, sizeof (bn256));
|
||||
gx[0].word[0] = 9; /* Gx = 9 */
|
||||
memcpy (k, key_data, sizeof (bn256));
|
||||
p = (uint8_t *)malloc (sizeof (bn256));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
compute_nQ ((bn256 *)p, k, gx);
|
||||
return p;
|
||||
compute_nQ ((bn256 *)pubkey, k, gx);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
149
src/flash.c
149
src/flash.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -53,33 +53,40 @@
|
||||
* <alignment to page>
|
||||
* ch_certificate_startp
|
||||
* <2048 bytes>
|
||||
* _data_pool
|
||||
* <two pages>
|
||||
* _keystore_pool
|
||||
* Three flash pages for keystore
|
||||
* a page contains a key data of:
|
||||
* For RSA-2048: 512-byte (p, q and N)
|
||||
* For RSA-4096: 1024-byte (p, q and N)
|
||||
* For ECDSA/ECDH and EdDSA, there are padding after public key
|
||||
* _data_pool
|
||||
* <two pages>
|
||||
*/
|
||||
|
||||
#define FLASH_DATA_POOL_HEADER_SIZE 2
|
||||
#define FLASH_DATA_POOL_SIZE (flash_page_size*2)
|
||||
|
||||
static uint16_t flash_page_size;
|
||||
|
||||
static const uint8_t *data_pool;
|
||||
extern uint8_t _keystore_pool;
|
||||
|
||||
static uint8_t *last_p;
|
||||
|
||||
/* The first halfword is generation for the data page (little endian) */
|
||||
const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
||||
const uint8_t flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
||||
0x00, 0x00, 0xff, 0xff
|
||||
};
|
||||
|
||||
/* Linker set this symbol */
|
||||
extern uint8_t _data_pool;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
extern uint8_t *flash_addr_key_storage_start;
|
||||
extern uint8_t *flash_addr_data_storage_start;
|
||||
#define FLASH_ADDR_KEY_STORAGE_START flash_addr_key_storage_start
|
||||
#define FLASH_ADDR_DATA_STORAGE_START flash_addr_data_storage_start
|
||||
#else
|
||||
/* Linker sets these symbols */
|
||||
extern uint8_t _keystore_pool[];
|
||||
extern uint8_t _data_pool[];
|
||||
#define FLASH_ADDR_KEY_STORAGE_START ((_keystore_pool))
|
||||
#define FLASH_ADDR_DATA_STORAGE_START ((_data_pool))
|
||||
#endif
|
||||
|
||||
static int key_available_at (const uint8_t *k, int key_size)
|
||||
{
|
||||
@@ -103,18 +110,20 @@ static int key_available_at (const uint8_t *k, int key_size)
|
||||
|
||||
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
|
||||
void
|
||||
flash_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
|
||||
flash_do_storage_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
|
||||
{
|
||||
uint16_t gen0, gen1;
|
||||
uint16_t *gen0_p = (uint16_t *)&_data_pool;
|
||||
uint16_t *gen0_p = (uint16_t *)FLASH_ADDR_DATA_STORAGE_START;
|
||||
uint16_t *gen1_p;
|
||||
|
||||
flash_page_size = 1024;
|
||||
#if !defined (GNU_LINUX_EMULATION)
|
||||
if (((*CHIP_ID_REG) & 0xfff) == 0x0414)
|
||||
flash_page_size = 2048;
|
||||
#endif
|
||||
|
||||
gen1_p = (uint16_t *)(&_data_pool + flash_page_size);
|
||||
data_pool = &_data_pool;
|
||||
gen1_p = (uint16_t *)(FLASH_ADDR_DATA_STORAGE_START + flash_page_size);
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START;
|
||||
|
||||
/* Check data pool generation and choose the page */
|
||||
gen0 = *gen0_p;
|
||||
@@ -129,13 +138,13 @@ flash_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
|
||||
|
||||
if (gen0 == 0xffff)
|
||||
/* Use another page if a page is erased. */
|
||||
data_pool = &_data_pool + flash_page_size;
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
else if (gen1 == 0xffff)
|
||||
/* Or use different page if another page is erased. */
|
||||
data_pool = &_data_pool;
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START;
|
||||
else if ((gen0 == 0xfffe && gen1 == 0) || gen1 > gen0)
|
||||
/* When both pages have valid header, use newer page. */
|
||||
data_pool = &_data_pool + flash_page_size;
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
|
||||
*p_do_start = data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
*p_do_end = data_pool + flash_page_size;
|
||||
@@ -148,29 +157,40 @@ flash_terminate (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
const uint8_t *p;
|
||||
|
||||
p = gpg_get_firmware_update_key (0);
|
||||
flash_erase_page ((uintptr_t)p);
|
||||
#endif
|
||||
for (i = 0; i < 3; i++)
|
||||
flash_erase_page ((uint32_t)flash_key_getpage (i));
|
||||
flash_erase_page ((uint32_t)&_data_pool);
|
||||
flash_erase_page ((uint32_t)(&_data_pool + flash_page_size));
|
||||
data_pool = &_data_pool;
|
||||
last_p = &_data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
flash_erase_page ((uintptr_t)flash_key_getpage (i));
|
||||
flash_erase_page ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START);
|
||||
flash_erase_page ((uintptr_t)(FLASH_ADDR_DATA_STORAGE_START + flash_page_size));
|
||||
data_pool = FLASH_ADDR_DATA_STORAGE_START;
|
||||
last_p = FLASH_ADDR_DATA_STORAGE_START + FLASH_DATA_POOL_HEADER_SIZE;
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
flash_erase_page ((uintptr_t)&ch_certificate_start);
|
||||
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
|
||||
flash_erase_page ((uintptr_t)(&ch_certificate_start + flash_page_size));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
flash_activate (void)
|
||||
{
|
||||
flash_program_halfword ((uint32_t)&_data_pool, 0);
|
||||
flash_program_halfword ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flash_init_keys (void)
|
||||
flash_key_storage_init (void)
|
||||
{
|
||||
const uint8_t *p;
|
||||
int i;
|
||||
|
||||
/* For each key, find its address. */
|
||||
p = &_keystore_pool;
|
||||
p = FLASH_ADDR_KEY_STORAGE_START;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
const uint8_t *k;
|
||||
@@ -228,15 +248,15 @@ flash_copying_gc (void)
|
||||
uint8_t *src, *dst;
|
||||
uint16_t generation;
|
||||
|
||||
if (data_pool == &_data_pool)
|
||||
if (data_pool == FLASH_ADDR_DATA_STORAGE_START)
|
||||
{
|
||||
src = &_data_pool;
|
||||
dst = &_data_pool + flash_page_size;
|
||||
src = FLASH_ADDR_DATA_STORAGE_START;
|
||||
dst = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
src = &_data_pool + flash_page_size;
|
||||
dst = &_data_pool;
|
||||
src = FLASH_ADDR_DATA_STORAGE_START + flash_page_size;
|
||||
dst = FLASH_ADDR_DATA_STORAGE_START;
|
||||
}
|
||||
|
||||
generation = *(uint16_t *)src;
|
||||
@@ -246,8 +266,8 @@ flash_copying_gc (void)
|
||||
generation = 0;
|
||||
else
|
||||
generation++;
|
||||
flash_program_halfword ((uint32_t)dst, generation);
|
||||
flash_erase_page ((uint32_t)src);
|
||||
flash_program_halfword ((uintptr_t)dst, generation);
|
||||
flash_erase_page ((uintptr_t)src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -277,10 +297,10 @@ void
|
||||
flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len)
|
||||
{
|
||||
uint16_t hw;
|
||||
uint32_t addr;
|
||||
uintptr_t addr;
|
||||
int i;
|
||||
|
||||
addr = (uint32_t)p;
|
||||
addr = (uintptr_t)p;
|
||||
hw = nr | (len << 8);
|
||||
if (flash_program_halfword (addr, hw) != 0)
|
||||
flash_warning ("DO WRITE ERROR");
|
||||
@@ -333,13 +353,14 @@ flash_warning (const char *msg)
|
||||
void
|
||||
flash_do_release (const uint8_t *do_data)
|
||||
{
|
||||
uint32_t addr = (uint32_t)do_data - 1;
|
||||
uint32_t addr_tag = addr;
|
||||
uintptr_t addr = (uintptr_t)do_data - 1;
|
||||
uintptr_t addr_tag = addr;
|
||||
int i;
|
||||
int len = do_data[0];
|
||||
|
||||
/* Don't filling zero for data in code (such as ds_count_initial_value) */
|
||||
if (do_data < &_data_pool || do_data > &_data_pool + FLASH_DATA_POOL_SIZE)
|
||||
if (do_data < FLASH_ADDR_DATA_STORAGE_START
|
||||
|| do_data > FLASH_ADDR_DATA_STORAGE_START + FLASH_DATA_POOL_SIZE)
|
||||
return;
|
||||
|
||||
addr += 2;
|
||||
@@ -368,7 +389,7 @@ static uint8_t *
|
||||
flash_key_getpage (enum kind_of_key kk)
|
||||
{
|
||||
/* There is a page for each KK. */
|
||||
return &_keystore_pool + (flash_page_size * kk);
|
||||
return FLASH_ADDR_KEY_STORAGE_START + (flash_page_size * kk);
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
@@ -402,10 +423,10 @@ flash_key_write (uint8_t *key_addr,
|
||||
const uint8_t *pubkey, int pubkey_len)
|
||||
{
|
||||
uint16_t hw;
|
||||
uint32_t addr;
|
||||
uintptr_t addr;
|
||||
int i;
|
||||
|
||||
addr = (uint32_t)key_addr;
|
||||
addr = (uintptr_t)key_addr;
|
||||
for (i = 0; i < key_data_len/2; i ++)
|
||||
{
|
||||
hw = key_data[i*2] | (key_data[i*2+1]<<8);
|
||||
@@ -428,7 +449,7 @@ flash_key_write (uint8_t *key_addr,
|
||||
static int
|
||||
flash_check_all_other_keys_released (const uint8_t *key_addr, int key_size)
|
||||
{
|
||||
uint32_t start = (uint32_t)key_addr & ~(flash_page_size - 1);
|
||||
uintptr_t start = (uintptr_t)key_addr & ~(flash_page_size - 1);
|
||||
const uint32_t *p = (const uint32_t *)start;
|
||||
|
||||
while (p < (const uint32_t *)(start + flash_page_size))
|
||||
@@ -447,7 +468,7 @@ static void
|
||||
flash_key_fill_zero_as_released (uint8_t *key_addr, int key_size)
|
||||
{
|
||||
int i;
|
||||
uint32_t addr = (uint32_t)key_addr;
|
||||
uintptr_t addr = (uintptr_t)key_addr;
|
||||
|
||||
for (i = 0; i < key_size/2; i++)
|
||||
flash_program_halfword (addr + i*2, 0);
|
||||
@@ -457,7 +478,7 @@ void
|
||||
flash_key_release (uint8_t *key_addr, int key_size)
|
||||
{
|
||||
if (flash_check_all_other_keys_released (key_addr, key_size))
|
||||
flash_erase_page (((uint32_t)key_addr & ~(flash_page_size - 1)));
|
||||
flash_erase_page (((uintptr_t)key_addr & ~(flash_page_size - 1)));
|
||||
else
|
||||
flash_key_fill_zero_as_released (key_addr, key_size);
|
||||
}
|
||||
@@ -465,12 +486,12 @@ flash_key_release (uint8_t *key_addr, int key_size)
|
||||
void
|
||||
flash_key_release_page (enum kind_of_key kk)
|
||||
{
|
||||
flash_erase_page ((uint32_t)flash_key_getpage (kk));
|
||||
flash_erase_page ((uintptr_t)flash_key_getpage (kk));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flash_clear_halfword (uint32_t addr)
|
||||
flash_clear_halfword (uintptr_t addr)
|
||||
{
|
||||
flash_program_halfword (addr, 0);
|
||||
}
|
||||
@@ -479,7 +500,7 @@ flash_clear_halfword (uint32_t addr)
|
||||
void
|
||||
flash_put_data_internal (const uint8_t *p, uint16_t hw)
|
||||
{
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -493,7 +514,7 @@ flash_put_data (uint16_t hw)
|
||||
DEBUG_INFO ("data allocation failure.\r\n");
|
||||
}
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
|
||||
|
||||
@@ -505,14 +526,14 @@ flash_bool_clear (const uint8_t **addr_p)
|
||||
if ((p = *addr_p) == NULL)
|
||||
return;
|
||||
|
||||
flash_program_halfword ((uint32_t)p, 0);
|
||||
flash_program_halfword ((uintptr_t)p, 0);
|
||||
*addr_p = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
flash_bool_write_internal (const uint8_t *p, int nr)
|
||||
{
|
||||
flash_program_halfword ((uint32_t)p, nr);
|
||||
flash_program_halfword ((uintptr_t)p, nr);
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
@@ -528,7 +549,7 @@ flash_bool_write (uint8_t nr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -544,7 +565,7 @@ flash_enum_write_internal (const uint8_t *p, int nr, uint8_t v)
|
||||
{
|
||||
uint16_t hw = nr | (v << 8);
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
@@ -560,7 +581,7 @@ flash_enum_write (uint8_t nr, uint8_t v)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -596,14 +617,14 @@ flash_cnt123_write_internal (const uint8_t *p, int which, int v)
|
||||
uint16_t hw;
|
||||
|
||||
hw = NR_COUNTER_123 | (which << 8);
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
|
||||
if (v == 1)
|
||||
return;
|
||||
else if (v == 2)
|
||||
flash_program_halfword ((uint32_t)p+2, 0xc3c3);
|
||||
flash_program_halfword ((uintptr_t)p+2, 0xc3c3);
|
||||
else /* v == 3 */
|
||||
flash_program_halfword ((uint32_t)p+2, 0);
|
||||
flash_program_halfword ((uintptr_t)p+2, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -621,7 +642,7 @@ flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
|
||||
return;
|
||||
}
|
||||
hw = NR_COUNTER_123 | (which << 8);
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
*addr_p = p + 2;
|
||||
}
|
||||
else
|
||||
@@ -636,7 +657,7 @@ flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
|
||||
else
|
||||
hw = 0;
|
||||
|
||||
flash_program_halfword ((uint32_t)p, hw);
|
||||
flash_program_halfword ((uintptr_t)p, hw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,9 +669,9 @@ flash_cnt123_clear (const uint8_t **addr_p)
|
||||
if ((p = *addr_p) == NULL)
|
||||
return;
|
||||
|
||||
flash_program_halfword ((uint32_t)p, 0);
|
||||
flash_program_halfword ((uintptr_t)p, 0);
|
||||
p -= 2;
|
||||
flash_program_halfword ((uint32_t)p, 0);
|
||||
flash_program_halfword ((uintptr_t)p, 0);
|
||||
*addr_p = NULL;
|
||||
}
|
||||
|
||||
@@ -664,9 +685,9 @@ flash_erase_binary (uint8_t file_id)
|
||||
const uint8_t *p = &ch_certificate_start;
|
||||
if (flash_check_blank (p, FLASH_CH_CERTIFICATE_SIZE) == 0)
|
||||
{
|
||||
flash_erase_page ((uint32_t)p);
|
||||
flash_erase_page ((uintptr_t)p);
|
||||
if (FLASH_CH_CERTIFICATE_SIZE > flash_page_size)
|
||||
flash_erase_page ((uint32_t)p + flash_page_size);
|
||||
flash_erase_page ((uintptr_t)p + flash_page_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -689,17 +710,19 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
maxsize = 6;
|
||||
p = &openpgpcard_aid[8];
|
||||
}
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
{
|
||||
maxsize = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
|
||||
if (len == 0 && offset == 0)
|
||||
{ /* This means removal of update key. */
|
||||
if (flash_program_halfword ((uint32_t)p, 0) != 0)
|
||||
if (flash_program_halfword ((uintptr_t)p, 0) != 0)
|
||||
flash_warning ("DO WRITE ERROR");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
else if (file_id == FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
@@ -715,13 +738,13 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
else
|
||||
{
|
||||
uint16_t hw;
|
||||
uint32_t addr;
|
||||
uintptr_t addr;
|
||||
int i;
|
||||
|
||||
if (flash_check_blank (p + offset, len) == 0)
|
||||
return -1;
|
||||
|
||||
addr = (uint32_t)p + offset;
|
||||
addr = (uintptr_t)p + offset;
|
||||
for (i = 0; i < len/2; i++)
|
||||
{
|
||||
hw = data[i*2] | (data[i*2+1]<<8);
|
||||
|
||||
16
src/gnuk-malloc.h
Normal file
16
src/gnuk-malloc.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Gnuk uses its own malloc functions.
|
||||
*
|
||||
* The intention is no-dependency to C library. But, we provide
|
||||
* malloc and free here, since RSA routines uses malloc/free
|
||||
* internally.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h> /* NULL and size_t */
|
||||
|
||||
#define malloc(size) gnuk_malloc (size)
|
||||
#define free(p) gnuk_free (p)
|
||||
|
||||
void *gnuk_malloc (size_t);
|
||||
void gnuk_free (void *);
|
||||
82
src/gnuk.h
82
src/gnuk.h
@@ -22,22 +22,20 @@ extern struct apdu apdu;
|
||||
#define CARD_CHANGE_REMOVE 1
|
||||
#define CARD_CHANGE_TOGGLE 2
|
||||
void ccid_card_change_signal (int how);
|
||||
void ccid_usb_reset (int);
|
||||
|
||||
/* CCID thread */
|
||||
#define EV_RX_DATA_READY 1 /* USB Rx data available */
|
||||
#define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */
|
||||
#define EV_TX_FINISHED 4 /* CCID Tx finished */
|
||||
#define EV_CARD_CHANGE 8
|
||||
#define EV_USB_SET_INTERFACE 16
|
||||
#define EV_USB_DEVICE_RESET 32
|
||||
#define EV_CARD_CHANGE 1
|
||||
#define EV_TX_FINISHED 2 /* CCID Tx finished */
|
||||
#define EV_EXEC_ACK_REQUIRED 4 /* OpenPGPcard Execution ACK required */
|
||||
#define EV_EXEC_FINISHED 8 /* OpenPGPcard Execution finished */
|
||||
#define EV_RX_DATA_READY 16 /* USB Rx data available */
|
||||
|
||||
/* OpenPGPcard thread */
|
||||
#define EV_PINPAD_INPUT_DONE 1
|
||||
#define EV_EXIT 2
|
||||
#define EV_MODIFY_CMD_AVAILABLE 1
|
||||
#define EV_VERIFY_CMD_AVAILABLE 2
|
||||
#define EV_CMD_AVAILABLE 4
|
||||
#define EV_VERIFY_CMD_AVAILABLE 8
|
||||
#define EV_MODIFY_CMD_AVAILABLE 16
|
||||
#define EV_EXIT 8
|
||||
#define EV_PINPAD_INPUT_DONE 16
|
||||
|
||||
/* Maximum cmd apdu data is key import 24+4+256+256 (proc_key_import) */
|
||||
#define MAX_CMD_APDU_DATA_SIZE (24+4+256+256) /* without header */
|
||||
@@ -56,17 +54,17 @@ enum ccid_state {
|
||||
CCID_STATE_NOCARD, /* No card available */
|
||||
CCID_STATE_START, /* Initial */
|
||||
CCID_STATE_WAIT, /* Waiting APDU */
|
||||
/* Busy1, Busy2, Busy3, Busy5 */
|
||||
CCID_STATE_EXECUTE, /* Busy4 */
|
||||
CCID_STATE_RECEIVE, /* APDU Received Partially */
|
||||
CCID_STATE_SEND, /* APDU Sent Partially */
|
||||
|
||||
CCID_STATE_EXITED, /* ICC Thread Terminated */
|
||||
CCID_STATE_EXECUTE, /* Executing command */
|
||||
CCID_STATE_ACK_REQUIRED_0, /* Ack required (executing)*/
|
||||
CCID_STATE_ACK_REQUIRED_1, /* Waiting user's ACK (execution finished) */
|
||||
|
||||
CCID_STATE_EXITED, /* CCID Thread Terminated */
|
||||
CCID_STATE_EXEC_REQUESTED, /* Exec requested */
|
||||
};
|
||||
|
||||
|
||||
extern enum ccid_state *const ccid_state_p;
|
||||
enum ccid_state ccid_get_ccid_state (void);
|
||||
|
||||
extern volatile uint8_t auth_status;
|
||||
#define AC_NONE_AUTHORIZED 0x00
|
||||
@@ -112,7 +110,7 @@ void gpg_do_terminate (void);
|
||||
void gpg_do_get_data (uint16_t tag, int with_tag);
|
||||
void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
|
||||
void gpg_do_public_key (uint8_t kk_byte);
|
||||
void gpg_do_keygen (uint8_t kk_byte);
|
||||
void gpg_do_keygen (uint8_t *buf);
|
||||
|
||||
const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
|
||||
|
||||
@@ -126,8 +124,8 @@ const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
|
||||
|
||||
enum kind_of_key {
|
||||
GPG_KEY_FOR_SIGNING = 0,
|
||||
GPG_KEY_FOR_DECRYPTION,
|
||||
GPG_KEY_FOR_AUTHENTICATION,
|
||||
GPG_KEY_FOR_DECRYPTION = 1,
|
||||
GPG_KEY_FOR_AUTHENTICATION = 2,
|
||||
};
|
||||
|
||||
enum size_of_key {
|
||||
@@ -139,10 +137,10 @@ enum size_of_key {
|
||||
int gpg_get_algo_attr (enum kind_of_key kk);
|
||||
int gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s);
|
||||
|
||||
void flash_init (const uint8_t **, const uint8_t **);
|
||||
void flash_do_storage_init (const uint8_t **, const uint8_t **);
|
||||
void flash_terminate (void);
|
||||
void flash_activate (void);
|
||||
void flash_init_keys (void);
|
||||
void flash_key_storage_init (void);
|
||||
void flash_do_release (const uint8_t *);
|
||||
const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
|
||||
uint8_t *flash_key_alloc (enum kind_of_key);
|
||||
@@ -152,7 +150,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 +263,22 @@ void put_binary (const char *s, int len);
|
||||
#endif
|
||||
|
||||
int rsa_sign (const uint8_t *, uint8_t *, int, struct key_data *, int);
|
||||
uint8_t *modulus_calc (const uint8_t *, int);
|
||||
int modulus_calc (const uint8_t *, int, uint8_t *);
|
||||
int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *,
|
||||
unsigned int *);
|
||||
int rsa_verify (const uint8_t *, int, const uint8_t *, const uint8_t *);
|
||||
uint8_t *rsa_genkey (int);
|
||||
int rsa_genkey (int, uint8_t *, uint8_t *);
|
||||
|
||||
int ecdsa_sign_p256r1 (const uint8_t *hash, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
uint8_t *ecc_compute_public_p256r1 (const uint8_t *key_data);
|
||||
int ecc_compute_public_p256r1 (const uint8_t *key_data, uint8_t *);
|
||||
int ecc_check_secret_p256r1 (const uint8_t *d0, uint8_t *d1);
|
||||
int ecdh_decrypt_p256r1 (const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
|
||||
int ecdsa_sign_p256k1 (const uint8_t *hash, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
uint8_t *ecc_compute_public_p256k1 (const uint8_t *key_data);
|
||||
int ecc_compute_public_p256k1 (const uint8_t *key_data, uint8_t *);
|
||||
int ecc_check_secret_p256k1 (const uint8_t *d0, uint8_t *d1);
|
||||
int ecdh_decrypt_p256k1 (const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
@@ -288,19 +286,24 @@ int ecdh_decrypt_p256k1 (const uint8_t *input, uint8_t *output,
|
||||
int eddsa_sign_25519 (const uint8_t *input, size_t ilen, uint32_t *output,
|
||||
const uint8_t *sk_a, const uint8_t *seed,
|
||||
const uint8_t *pk);
|
||||
uint8_t *eddsa_compute_public_25519 (const uint8_t *a);
|
||||
uint8_t *ecdh_compute_public_25519 (const uint8_t *a);
|
||||
void eddsa_compute_public_25519 (const uint8_t *a, uint8_t *);
|
||||
void ecdh_compute_public_25519 (const uint8_t *a, uint8_t *);
|
||||
int ecdh_decrypt_curve25519 (const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
|
||||
const uint8_t *gpg_do_read_simple (uint8_t);
|
||||
void gpg_do_write_simple (uint8_t, const uint8_t *, int);
|
||||
void gpg_increment_digital_signature_counter (void);
|
||||
void gpg_do_get_initial_pw_setting (int is_pw3, int *r_len,
|
||||
const uint8_t **r_p);
|
||||
int gpg_do_kdf_check (int len, int how_many);
|
||||
int gpg_do_get_uif (enum kind_of_key kk);
|
||||
|
||||
|
||||
void fatal (uint8_t code) __attribute__ ((noreturn));
|
||||
#define FATAL_FLASH 1
|
||||
#define FATAL_RANDOM 2
|
||||
#define FATAL_HEAP 3
|
||||
|
||||
extern uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
|
||||
extern uint8_t admin_authorized;
|
||||
@@ -333,7 +336,8 @@ extern uint8_t admin_authorized;
|
||||
#define NR_DO_KEYSTRING_PW1 0x11
|
||||
#define NR_DO_KEYSTRING_RC 0x12
|
||||
#define NR_DO_KEYSTRING_PW3 0x13
|
||||
#define NR_DO__LAST__ 20 /* == 0x14 */
|
||||
#define NR_DO_KDF 0x14
|
||||
#define NR_DO__LAST__ 21 /* == 0x15 */
|
||||
/* 14-bit counter for DS: Recorded in flash memory by 1-halfword (2-byte). */
|
||||
/*
|
||||
* Representation of 14-bit counter:
|
||||
@@ -376,7 +380,17 @@ extern uint8_t admin_authorized;
|
||||
#define NR_KEY_ALGO_ATTR_DEC 0xf2
|
||||
#define NR_KEY_ALGO_ATTR_AUT 0xf3
|
||||
/*
|
||||
* NR_UINT_SOMETHING could be here... Use 0xf[456789abcd]
|
||||
* Representation of User Interaction Flag:
|
||||
* 0 (UIF disabled): 0xf?00 or No record in flash memory
|
||||
* 1 (UIF enabled): 0xf?01
|
||||
* 2 (UIF permanently enabled): 0xf?02
|
||||
*
|
||||
*/
|
||||
#define NR_DO_UIF_SIG 0xf6
|
||||
#define NR_DO_UIF_DEC 0xf7
|
||||
#define NR_DO_UIF_AUT 0xf8
|
||||
/*
|
||||
* NR_UINT_SOMETHING could be here... Use 0xf[459abcd]
|
||||
*/
|
||||
/* 123-counters: Recorded in flash memory by 2-halfword (4-byte). */
|
||||
/*
|
||||
@@ -432,6 +446,8 @@ extern const uint8_t gnuk_string_serial[];
|
||||
#define LED_GNUK_EXEC 32
|
||||
#define LED_START_COMMAND 64
|
||||
#define LED_FINISH_COMMAND 128
|
||||
#define LED_WAIT_FOR_BUTTON 256
|
||||
#define LED_OFF LED_FINISH_COMMAND
|
||||
void led_blink (int spec);
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
@@ -458,7 +474,7 @@ int pinpad_getline (int msg_code, uint32_t timeout_usec);
|
||||
|
||||
#endif
|
||||
|
||||
extern uint8_t _regnual_start, __heap_end__[];
|
||||
|
||||
int check_crc32 (const uint32_t *start_p, const uint32_t *end_p);
|
||||
extern uint8_t _regnual_start[], __heap_end__[];
|
||||
|
||||
uint8_t * sram_address (uint32_t offset);
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
/*
|
||||
* ST32F103 memory setup.
|
||||
*/
|
||||
__main_stack_size__ = 0x0080; /* Exception handlers */
|
||||
__process0_stack_size__ = 0x0100; /* main */
|
||||
__process1_stack_size__ = 0x01a0; /* ccid */
|
||||
__process2_stack_size__ = 0x0180; /* rng */
|
||||
__process3_stack_size__ = 0x1640; /* gpg */
|
||||
__process4_stack_size__ = 0; /* --- */
|
||||
__process5_stack_size__ = @MSC_SIZE@; /* msc */
|
||||
__process6_stack_size__ = @TIM_SIZE@; /* intr: timer */
|
||||
__process7_stack_size__ = @EXT_SIZE@; /* intr: ext */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash0 : org = @ORIGIN@, len = 4k
|
||||
@@ -82,45 +72,18 @@ SECTIONS
|
||||
_etext = .;
|
||||
_textdata = _etext;
|
||||
|
||||
.stacks :
|
||||
.stacks (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__main_stack_base__ = .;
|
||||
. += __main_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__main_stack_end__ = .;
|
||||
__process0_stack_base__ = .;
|
||||
. += __process0_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process0_stack_end__ = .;
|
||||
__process1_stack_base__ = .;
|
||||
. += __process1_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process1_stack_end__ = .;
|
||||
__process2_stack_base__ = .;
|
||||
. += __process2_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process2_stack_end__ = .;
|
||||
__process3_stack_base__ = .;
|
||||
. += __process3_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process3_stack_end__ = .;
|
||||
__process4_stack_base__ = .;
|
||||
. += __process4_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process4_stack_end__ = .;
|
||||
__process5_stack_base__ = .;
|
||||
. += __process5_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process5_stack_end__ = .;
|
||||
__process6_stack_base__ = .;
|
||||
. += __process6_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process6_stack_end__ = .;
|
||||
__process7_stack_base__ = .;
|
||||
. += __process7_stack_size__;
|
||||
. = ALIGN(8);
|
||||
__process7_stack_end__ = .;
|
||||
*(.main_stack)
|
||||
*(.process_stack.0)
|
||||
*(.process_stack.1)
|
||||
*(.process_stack.2)
|
||||
*(.process_stack.3)
|
||||
*(.process_stack.4)
|
||||
*(.process_stack.5)
|
||||
*(.process_stack.6)
|
||||
*(.process_stack.7)
|
||||
. = ALIGN(8);
|
||||
} > ram
|
||||
|
||||
@@ -172,11 +135,11 @@ SECTIONS
|
||||
{
|
||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||
_keystore_pool = .;
|
||||
. += 512;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += 512;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += 512;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_updatekey_store = .;
|
||||
. += 1024;
|
||||
|
||||
346
src/main.c
346
src/main.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* main.c - main routine of Gnuk
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018, 2021
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -35,8 +35,18 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb-cdc.h"
|
||||
#include "random.h"
|
||||
#include "mcu/stm32f103.h"
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define main emulated_main
|
||||
#else
|
||||
#include "mcu/stm32f103.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* main thread does 1-bit LED display output
|
||||
@@ -46,7 +56,33 @@
|
||||
#define LED_TIMEOUT_ONE (100*1000)
|
||||
#define LED_TIMEOUT_STOP (200*1000)
|
||||
|
||||
#ifdef DFU_SUPPORT
|
||||
static int
|
||||
flash_write_any (uintptr_t dst_addr, const uint8_t *src, size_t len)
|
||||
{
|
||||
int status;
|
||||
|
||||
while (len)
|
||||
{
|
||||
uint16_t hw = *src++;
|
||||
|
||||
hw |= (*src++ << 8);
|
||||
status = flash_program_halfword (dst_addr, hw);
|
||||
if (status != 0)
|
||||
return 0; /* error return */
|
||||
|
||||
dst_addr += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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)
|
||||
@@ -59,7 +95,7 @@ device_initialize_once (void)
|
||||
* This is the first time invocation.
|
||||
* Setup serial number by unique device ID.
|
||||
*/
|
||||
const uint8_t *u = unique_device_id () + 8;
|
||||
const uint8_t *u = unique_device_id () + (MHZ < 96 ? 8: 0);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
@@ -74,12 +110,66 @@ device_initialize_once (void)
|
||||
nibble += (nibble >= 10 ? ('A' - 10) : '0');
|
||||
flash_put_data_internal (&p[i*4+2], nibble);
|
||||
}
|
||||
|
||||
#ifdef DFU_SUPPORT
|
||||
#define CHIP_ID_REG ((uint32_t *)0xE0042000)
|
||||
/*
|
||||
* Overwrite DFU bootloader with a copy of SYS linked to ORIGIN_REAL.
|
||||
* Then protect flash from readout.
|
||||
*/
|
||||
{
|
||||
extern uint8_t _binary_build_stdaln_sys_bin_start;
|
||||
extern uint8_t _binary_build_stdaln_sys_bin_size;
|
||||
size_t stdaln_sys_size = (size_t) &_binary_build_stdaln_sys_bin_size;
|
||||
extern const uint32_t FT0[256], FT1[256], FT2[256];
|
||||
extern handler vector_table[];
|
||||
uintptr_t addr;
|
||||
uint32_t flash_page_size = 1024; /* 1KiB default */
|
||||
|
||||
if (((*CHIP_ID_REG)&0x07) == 0x04) /* High density device. */
|
||||
flash_page_size = 2048; /* It's 2KiB. */
|
||||
|
||||
/* Kill DFU */
|
||||
for (addr = ORIGIN_REAL; addr < ORIGIN;
|
||||
addr += flash_page_size)
|
||||
flash_erase_page (addr);
|
||||
|
||||
/* Copy SYS */
|
||||
addr = ORIGIN_REAL;
|
||||
flash_write_any(addr, &_binary_build_stdaln_sys_bin_start,
|
||||
stdaln_sys_size);
|
||||
addr += stdaln_sys_size;
|
||||
flash_write_any(addr, (const uint8_t *) &FT0, sizeof(FT0));
|
||||
addr += sizeof(FT0);
|
||||
flash_write_any(addr, (const uint8_t *) &FT1, sizeof(FT1));
|
||||
addr += sizeof(FT1);
|
||||
flash_write_any(addr, (const uint8_t *) &FT2, sizeof(FT2));
|
||||
|
||||
addr = ORIGIN_REAL + 0x1000;
|
||||
if (addr < ORIGIN) {
|
||||
/* Need to patch top of stack and reset vector there */
|
||||
handler *new_vector = (handler *) addr;
|
||||
flash_write((uintptr_t) &new_vector[0], (const uint8_t *)
|
||||
&vector_table[0], sizeof(handler));
|
||||
flash_write((uintptr_t) &new_vector[1], (const uint8_t *)
|
||||
&vector[1], sizeof(handler));
|
||||
}
|
||||
|
||||
flash_protect();
|
||||
nvic_system_reset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static volatile uint8_t fatal_code;
|
||||
static struct eventflag led_event;
|
||||
static chopstx_poll_cond_t led_event_poll_desc;
|
||||
static struct chx_poll_head *const led_event_poll[] = {
|
||||
(struct chx_poll_head *)&led_event_poll_desc
|
||||
};
|
||||
|
||||
static void display_fatal_code (void)
|
||||
{
|
||||
@@ -120,17 +210,20 @@ static void display_fatal_code (void)
|
||||
|
||||
static uint8_t led_inverted;
|
||||
|
||||
static void emit_led (int on_time, int off_time)
|
||||
static void
|
||||
emit_led (uint32_t on_time, uint32_t off_time)
|
||||
{
|
||||
set_led (!led_inverted);
|
||||
chopstx_usec_wait (on_time);
|
||||
chopstx_poll (&on_time, 1, led_event_poll);
|
||||
set_led (led_inverted);
|
||||
chopstx_usec_wait (off_time);
|
||||
chopstx_poll (&off_time, 1, led_event_poll);
|
||||
}
|
||||
|
||||
static void display_status_code (void)
|
||||
static void
|
||||
display_status_code (void)
|
||||
{
|
||||
enum ccid_state ccid_state = *ccid_state_p;
|
||||
enum ccid_state ccid_state = ccid_get_ccid_state ();
|
||||
uint32_t usec;
|
||||
|
||||
if (ccid_state == CCID_STATE_START)
|
||||
emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
||||
@@ -145,12 +238,15 @@ static void display_status_code (void)
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
|
||||
if (ccid_state == CCID_STATE_WAIT)
|
||||
chopstx_usec_wait (LED_TIMEOUT_STOP * 2);
|
||||
{
|
||||
usec = LED_TIMEOUT_STOP * 2;
|
||||
chopstx_poll (&usec, 1, led_event_poll);
|
||||
}
|
||||
else
|
||||
{
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
emit_led (ccid_state == CCID_STATE_RECEIVE?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
usec = LED_TIMEOUT_INTERVAL;
|
||||
chopstx_poll (&usec, 1, led_event_poll);
|
||||
emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,26 +263,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 +302,125 @@ 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;
|
||||
int wait_for_ack = 0;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
chopstx_conf_idle (1);
|
||||
|
||||
gnuk_malloc_init ();
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define FLASH_IMAGE_NAME ".gnuk-flash-image"
|
||||
|
||||
if (argc >= 4 || (argc == 2 && !strcmp (argv[1], "--help")))
|
||||
{
|
||||
fprintf (stdout, "Usage: %s [--vidpid=Vxxx:Pxxx] [flash-image-file]",
|
||||
argv[0]);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (argc >= 2 && !strncmp (argv[1], "--debug=", 8))
|
||||
{
|
||||
debug = strtol (&argv[1][8], NULL, 10);
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc >= 2 && !strncmp (argv[1], "--vidpid=", 9))
|
||||
{
|
||||
extern uint8_t device_desc[];
|
||||
uint32_t id;
|
||||
char *p;
|
||||
|
||||
id = (uint32_t)strtol (&argv[1][9], &p, 16);
|
||||
device_desc[8] = (id & 0xff);
|
||||
device_desc[9] = (id >> 8);
|
||||
|
||||
if (p && p[0] == ':')
|
||||
{
|
||||
id = (uint32_t)strtol (&p[1], NULL, 16);
|
||||
device_desc[10] = (id & 0xff);
|
||||
device_desc[11] = (id >> 8);
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
char *p = getenv ("HOME");
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
fprintf (stderr, "Can't find $HOME\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
path_string = malloc (strlen (p) + strlen (FLASH_IMAGE_NAME) + 2);
|
||||
|
||||
p = stpcpy (path_string, p);
|
||||
*p++ = '/';
|
||||
strcpy (p, FLASH_IMAGE_NAME);
|
||||
flash_image_path = path_string;
|
||||
}
|
||||
else
|
||||
flash_image_path = argv[1];
|
||||
|
||||
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_key_storage_start = (uint8_t *)flash_addr;
|
||||
flash_addr_data_storage_start = (uint8_t *)flash_addr + 4096;
|
||||
#else
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
#endif
|
||||
|
||||
flash_unlock ();
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
if (path_string)
|
||||
free (path_string);
|
||||
#else
|
||||
device_initialize_once ();
|
||||
#endif
|
||||
|
||||
adc_init ();
|
||||
|
||||
@@ -239,17 +446,23 @@ main (int argc, char *argv[])
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (bDeviceState != UNCONNECTED)
|
||||
if (bDeviceState != USB_DEVICE_STATE_UNCONNECTED)
|
||||
break;
|
||||
|
||||
chopstx_usec_wait (250*1000);
|
||||
}
|
||||
|
||||
eventflag_prepare_poll (&led_event, &led_event_poll_desc);
|
||||
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m;
|
||||
|
||||
m = eventflag_wait (&led_event);
|
||||
if (wait_for_ack)
|
||||
m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_INTERVAL);
|
||||
else
|
||||
m = eventflag_wait (&led_event);
|
||||
|
||||
switch (m)
|
||||
{
|
||||
case LED_ONESHOT:
|
||||
@@ -270,8 +483,11 @@ main (int argc, char *argv[])
|
||||
break;
|
||||
case LED_GNUK_EXEC:
|
||||
goto exec;
|
||||
case LED_WAIT_FOR_BUTTON:
|
||||
wait_for_ack ^= 1;
|
||||
/* fall through */
|
||||
default:
|
||||
emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_ZERO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -285,30 +501,15 @@ main (int argc, char *argv[])
|
||||
/* Finish application. */
|
||||
chopstx_join (ccid_thd, NULL);
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
/* Set vector */
|
||||
SCB->VTOR = (uint32_t)&_regnual_start;
|
||||
entry = calculate_regnual_entry_address (&_regnual_start);
|
||||
SCB->VTOR = (uintptr_t)_regnual_start;
|
||||
entry = calculate_regnual_entry_address (_regnual_start);
|
||||
#ifdef DFU_SUPPORT
|
||||
#define FLASH_SYS_START_ADDR 0x08000000
|
||||
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
|
||||
#define CHIP_ID_REG ((uint32_t *)0xE0042000)
|
||||
{
|
||||
extern uint8_t _sys;
|
||||
uint32_t addr;
|
||||
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. */
|
||||
flash_page_size = 2048; /* It's 2KiB. */
|
||||
|
||||
/* Kill DFU */
|
||||
for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
|
||||
addr += flash_page_size)
|
||||
flash_erase_page (addr);
|
||||
|
||||
/* copy system service routines */
|
||||
flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
|
||||
/* Use SYS at ORIGIN_REAL instead of the one at ORIGIN */
|
||||
handler *new_vector = (handler *)ORIGIN_REAL;
|
||||
void (*func) (void (*)(void)) = (void (*)(void (*)(void))) new_vector[9];
|
||||
|
||||
/* Leave Gnuk to exec reGNUal */
|
||||
(*func) ((void (*)(void))entry);
|
||||
@@ -318,6 +519,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,39 +552,55 @@ fatal (uint8_t code)
|
||||
* reclaimed to system.
|
||||
*/
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define HEAP_SIZE (32*1024)
|
||||
uint8_t __heap_base__[HEAP_SIZE];
|
||||
|
||||
#define HEAP_START __heap_base__
|
||||
#define HEAP_END (__heap_base__ + HEAP_SIZE)
|
||||
#define HEAP_ALIGNMENT 32
|
||||
#else
|
||||
extern uint8_t __heap_base__[];
|
||||
extern uint8_t __heap_end__[];
|
||||
|
||||
#define MEMORY_END (__heap_end__)
|
||||
#define MEMORY_ALIGNMENT 16
|
||||
#define MEMORY_ALIGN(n) (((n) + MEMORY_ALIGNMENT - 1) & ~(MEMORY_ALIGNMENT - 1))
|
||||
#define HEAP_START __heap_base__
|
||||
#define HEAP_END (__heap_end__)
|
||||
#define HEAP_ALIGNMENT 16
|
||||
#define HEAP_SIZE ((uintptr_t)__heap_end__ - (uintptr_t)__heap_base__)
|
||||
#endif
|
||||
|
||||
#define HEAP_ALIGN(n) (((n) + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT - 1))
|
||||
|
||||
static uint8_t *heap_p;
|
||||
static chopstx_mutex_t malloc_mtx;
|
||||
|
||||
struct mem_head {
|
||||
uint32_t size;
|
||||
uintptr_t size;
|
||||
/**/
|
||||
struct mem_head *next, *prev; /* free list chain */
|
||||
struct mem_head *neighbor; /* backlink to neighbor */
|
||||
};
|
||||
|
||||
#define MEM_HEAD_IS_CORRUPT(x) \
|
||||
((x)->size != HEAP_ALIGN((x)->size) || (x)->size > HEAP_SIZE)
|
||||
#define MEM_HEAD_CHECK(x) if (MEM_HEAD_IS_CORRUPT(x)) fatal (FATAL_HEAP)
|
||||
|
||||
static struct mem_head *free_list;
|
||||
|
||||
static void
|
||||
gnuk_malloc_init (void)
|
||||
{
|
||||
chopstx_mutex_init (&malloc_mtx);
|
||||
heap_p = __heap_base__;
|
||||
heap_p = HEAP_START;
|
||||
free_list = NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
sbrk (size_t size)
|
||||
gnuk_sbrk (intptr_t size)
|
||||
{
|
||||
void *p = (void *)heap_p;
|
||||
|
||||
if ((size_t)(MEMORY_END - heap_p) < size)
|
||||
if ((HEAP_END - heap_p) < size)
|
||||
return NULL;
|
||||
|
||||
heap_p += size;
|
||||
@@ -405,7 +625,7 @@ gnuk_malloc (size_t size)
|
||||
struct mem_head *m;
|
||||
struct mem_head *m0;
|
||||
|
||||
size = MEMORY_ALIGN (size + sizeof (uint32_t));
|
||||
size = HEAP_ALIGN (size + sizeof (uintptr_t));
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
DEBUG_INFO ("malloc: ");
|
||||
@@ -416,12 +636,12 @@ gnuk_malloc (size_t size)
|
||||
{
|
||||
if (m == NULL)
|
||||
{
|
||||
m = (struct mem_head *)sbrk (size);
|
||||
m = (struct mem_head *)gnuk_sbrk (size);
|
||||
if (m)
|
||||
m->size = size;
|
||||
break;
|
||||
}
|
||||
|
||||
MEM_HEAD_CHECK (m);
|
||||
if (m->size == size)
|
||||
{
|
||||
remove_from_free_list (m);
|
||||
@@ -445,8 +665,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 +674,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 +706,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;
|
||||
|
||||
@@ -25,30 +25,6 @@
|
||||
#include <stdint.h>
|
||||
#include "mcu/stm32f103.h"
|
||||
|
||||
static uint32_t
|
||||
rbit (uint32_t v)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
check_crc32 (const uint32_t *start_p, const uint32_t *end_p)
|
||||
{
|
||||
uint32_t crc32 = *end_p;
|
||||
const uint32_t *p;
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
|
||||
for (p = start_p; p < end_p; p++)
|
||||
CRC->DR = rbit (*p);
|
||||
|
||||
return (rbit (CRC->DR) ^ crc32) == 0xffffffff;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
sram_address (uint32_t offset)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,6 @@ mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
bn512 q_big[1], tmp[1];
|
||||
uint32_t carry;
|
||||
#define borrow carry
|
||||
uint32_t borrow_next;
|
||||
|
||||
memset (q, 0, sizeof (bn256));
|
||||
q->word[0] = A->word[15];
|
||||
@@ -110,9 +109,7 @@ mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
= tmp->word[11] = tmp->word[10] = tmp->word[9] = 0;
|
||||
|
||||
borrow = bn256_sub (X, (bn256 *)&q_big->word[0], (bn256 *)&tmp->word[0]);
|
||||
borrow_next = (q_big->word[8] < borrow);
|
||||
q_big->word[8] -= borrow;
|
||||
borrow_next += (q_big->word[8] < tmp->word[8]);
|
||||
q_big->word[8] -= tmp->word[8];
|
||||
|
||||
carry = q_big->word[8];
|
||||
@@ -122,7 +119,7 @@ mod_reduce (bn256 *X, const bn512 *A, const bn256 *B, const bn256 *MU_lower)
|
||||
bn256_sub (q, X, B);
|
||||
|
||||
if (carry)
|
||||
carry -= bn256_sub (X, X, B);
|
||||
bn256_sub (X, X, B);
|
||||
else
|
||||
bn256_sub (q, X, B);
|
||||
|
||||
@@ -159,6 +156,7 @@ mod_inv (bn256 *C, const bn256 *X, const bn256 *N)
|
||||
#define borrow carry
|
||||
int n = MAX_GCD_STEPS_BN256;
|
||||
|
||||
memset (tmp, 0, sizeof (bn256));
|
||||
memset (C, 0, sizeof (bn256));
|
||||
memcpy (u, X, sizeof (bn256));
|
||||
memcpy (v, N, sizeof (bn256));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* modp256k1.c -- modulo arithmetic for p256k1
|
||||
*
|
||||
* Copyright (C) 2014, 2016 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2016, 2020 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -71,14 +71,12 @@ modp256k1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t cond;
|
||||
bn256 tmp[1];
|
||||
bn256 dummy[1];
|
||||
|
||||
cond = (bn256_add (X, A, B) == 0);
|
||||
cond &= bn256_sub (tmp, X, P256K1);
|
||||
if (cond)
|
||||
/* No-carry AND borrow */
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
else
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
memcpy (cond?dummy:X, tmp, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,13 +87,12 @@ modp256k1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t borrow;
|
||||
bn256 tmp[1];
|
||||
bn256 dummy[1];
|
||||
|
||||
borrow = bn256_sub (X, A, B);
|
||||
bn256_add (tmp, X, P256K1);
|
||||
if (borrow)
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
else
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
memcpy (borrow?X:dummy, tmp, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* modp256r1.c -- modulo arithmetic for p256r1
|
||||
*
|
||||
* Copyright (C) 2011, 2013, 2014, 2016
|
||||
* Copyright (C) 2011, 2013, 2014, 2016, 2020
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -66,14 +66,12 @@ modp256r1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t cond;
|
||||
bn256 tmp[1];
|
||||
bn256 dummy[1];
|
||||
|
||||
cond = (bn256_add (X, A, B) == 0);
|
||||
cond &= bn256_sub (tmp, X, P256R1);
|
||||
if (cond)
|
||||
/* No-carry AND borrow */
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
else
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
memcpy (cond?dummy:X, tmp, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,13 +82,12 @@ modp256r1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t borrow;
|
||||
bn256 tmp[1];
|
||||
bn256 dummy[1];
|
||||
|
||||
borrow = bn256_sub (X, A, B);
|
||||
bn256_add (tmp, X, P256R1);
|
||||
if (borrow)
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
else
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
memcpy (borrow?X:dummy, tmp, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,6 +97,7 @@ void
|
||||
modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
{
|
||||
bn256 tmp[1], tmp0[1];
|
||||
bn256 dummy[1];
|
||||
uint32_t borrow;
|
||||
|
||||
#define S1 X
|
||||
@@ -121,10 +119,8 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S1->word[1] = A->word[1];
|
||||
S1->word[0] = A->word[0];
|
||||
borrow = bn256_sub (tmp0, S1, P256R1);
|
||||
if (borrow)
|
||||
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||
else
|
||||
memcpy (S1, tmp0, sizeof (bn256));
|
||||
memcpy (borrow?dummy:S1, tmp0, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
/* X = S1 */
|
||||
|
||||
S2->word[7] = A->word[15];
|
||||
@@ -165,10 +161,8 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S5->word[1] = A->word[10];
|
||||
S5->word[0] = A->word[9];
|
||||
borrow = bn256_sub (tmp0, S5, P256R1);
|
||||
if (borrow)
|
||||
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||
else
|
||||
memcpy (S5, tmp0, sizeof (bn256));
|
||||
memcpy (borrow?dummy:S5, tmp0, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
/* X += S5 */
|
||||
modp256r1_add (X, X, S5);
|
||||
|
||||
@@ -179,10 +173,8 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S6->word[1] = A->word[12];
|
||||
S6->word[0] = A->word[11];
|
||||
borrow = bn256_sub (tmp0, S6, P256R1);
|
||||
if (borrow)
|
||||
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||
else
|
||||
memcpy (S6, tmp0, sizeof (bn256));
|
||||
memcpy (borrow?dummy:S6, tmp0, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
/* X -= S6 */
|
||||
modp256r1_sub (X, X, S6);
|
||||
|
||||
@@ -194,10 +186,8 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S7->word[1] = A->word[13];
|
||||
S7->word[0] = A->word[12];
|
||||
borrow = bn256_sub (tmp0, S7, P256R1);
|
||||
if (borrow)
|
||||
memcpy (tmp0, tmp0, sizeof (bn256));
|
||||
else
|
||||
memcpy (S7, tmp0, sizeof (bn256));
|
||||
memcpy (borrow?dummy:S7, tmp0, sizeof (bn256));
|
||||
asm ("" : "=m" (dummy) : "m" (dummy) : "memory");
|
||||
/* X -= S7 */
|
||||
modp256r1_sub (X, X, S7);
|
||||
|
||||
|
||||
195
src/neug.c
195
src/neug.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* neug.c - true random number generation
|
||||
*
|
||||
* Copyright (C) 2011, 2012, 2013, 2016
|
||||
* Copyright (C) 2011, 2012, 2013, 2016, 2017, 2018
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -29,10 +29,133 @@
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
void
|
||||
crc32_rv_stop (void)
|
||||
{
|
||||
}
|
||||
#else
|
||||
void
|
||||
crc32_rv_reset (void)
|
||||
{
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
}
|
||||
|
||||
void
|
||||
crc32_rv_step (uint32_t v)
|
||||
{
|
||||
CRC->DR = v;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
crc32_rv_get (void)
|
||||
{
|
||||
return CRC->DR;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rbit (uint32_t v)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
crc32_rv_stop (void)
|
||||
{
|
||||
RCC->AHBENR &= ~RCC_AHBENR_CRCEN;
|
||||
}
|
||||
#endif
|
||||
|
||||
static chopstx_mutex_t mode_mtx;
|
||||
static chopstx_cond_t mode_cond;
|
||||
|
||||
@@ -94,11 +217,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 +287,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 +304,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 +321,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 +349,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 +763,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 +780,14 @@ neug_init (uint32_t *buf, uint8_t size)
|
||||
struct rng_rb *rb = &the_ring_buffer;
|
||||
int i;
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
||||
CRC->CR = CRC_CR_RESET;
|
||||
crc32_rv_reset ();
|
||||
|
||||
/*
|
||||
* This initialization ensures that it generates different sequence
|
||||
* even if all physical conditions are same.
|
||||
*/
|
||||
for (i = 0; i < 3; i++)
|
||||
CRC->DR = *u++;
|
||||
crc32_rv_step (*u++);
|
||||
|
||||
neug_mode = NEUG_MODE_CONDITIONED;
|
||||
rb_init (rb, buf, size);
|
||||
@@ -781,6 +905,7 @@ neug_fini (void)
|
||||
rng_should_terminate = 1;
|
||||
neug_get (1);
|
||||
chopstx_join (rng_thread, NULL);
|
||||
crc32_rv_stop ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -26,3 +26,8 @@ void neug_fini (void);
|
||||
void neug_mode_select (uint8_t mode);
|
||||
|
||||
int neug_consume_random (void (*proc) (uint32_t, int));
|
||||
|
||||
void crc32_rv_reset (void);
|
||||
void crc32_rv_step (uint32_t v);
|
||||
uint32_t crc32_rv_get (void);
|
||||
uint32_t rbit (uint32_t v);
|
||||
|
||||
664
src/openpgp-do.c
664
src/openpgp-do.c
File diff suppressed because it is too large
Load Diff
271
src/openpgp.c
271
src/openpgp.c
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* openpgp.c -- OpenPGP card protocol support
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||
* 2019
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -37,6 +38,7 @@
|
||||
|
||||
static struct eventflag *openpgp_comm;
|
||||
|
||||
#define USER_PASSWD_MINLEN 6
|
||||
#define ADMIN_PASSWD_MINLEN 8
|
||||
|
||||
#define CLS(a) a.cmd_apdu_head[0]
|
||||
@@ -98,7 +100,6 @@ set_res_sw (uint8_t sw1, uint8_t sw2)
|
||||
#define FILE_EF_UPDATE_KEY_2 7
|
||||
#define FILE_EF_UPDATE_KEY_3 8
|
||||
#define FILE_EF_CH_CERTIFICATE 9
|
||||
#define FILE_CARD_TERMINATED_OPENPGP 254
|
||||
#define FILE_CARD_TERMINATED 255
|
||||
|
||||
uint8_t file_selection;
|
||||
@@ -109,7 +110,7 @@ gpg_init (void)
|
||||
const uint8_t *flash_do_start;
|
||||
const uint8_t *flash_do_end;
|
||||
|
||||
flash_init (&flash_do_start, &flash_do_end);
|
||||
flash_do_storage_init (&flash_do_start, &flash_do_end);
|
||||
|
||||
if (flash_do_start == NULL)
|
||||
file_selection = FILE_CARD_TERMINATED;
|
||||
@@ -117,7 +118,7 @@ gpg_init (void)
|
||||
file_selection = FILE_NONE;
|
||||
|
||||
gpg_data_scan (flash_do_start, flash_do_end);
|
||||
flash_init_keys ();
|
||||
flash_key_storage_init ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -145,7 +146,7 @@ get_pinpad_input (int msg_code)
|
||||
#endif
|
||||
|
||||
static void
|
||||
cmd_verify (void)
|
||||
cmd_verify (struct eventflag *ccid_comm)
|
||||
{
|
||||
int len;
|
||||
uint8_t p1 = P1 (apdu);
|
||||
@@ -153,6 +154,7 @@ cmd_verify (void)
|
||||
int r;
|
||||
const uint8_t *pw;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - VERIFY\r\n");
|
||||
DEBUG_BYTE (p2);
|
||||
|
||||
@@ -171,7 +173,8 @@ cmd_verify (void)
|
||||
r = ac_check_status (AC_ADMIN_AUTHORIZED);
|
||||
|
||||
if (r)
|
||||
GPG_SUCCESS (); /* If authentication done already, return success. */
|
||||
/* If authentication done already, return success. */
|
||||
GPG_SUCCESS ();
|
||||
else
|
||||
{ /* If not, return retry counter, encoded. */
|
||||
r = gpg_pw_get_retry_counter (p2);
|
||||
@@ -193,6 +196,12 @@ cmd_verify (void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_do_kdf_check (len, 1) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is real authentication. */
|
||||
if (p2 == 0x81)
|
||||
r = verify_pso_cds (pw, len);
|
||||
@@ -268,7 +277,7 @@ gpg_change_keystring (int who_old, const uint8_t *old_ks,
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_change_password (void)
|
||||
cmd_change_password (struct eventflag *ccid_comm)
|
||||
{
|
||||
uint8_t old_ks[KEYSTRING_MD_SIZE];
|
||||
uint8_t new_ks0[KEYSTRING_SIZE];
|
||||
@@ -288,6 +297,7 @@ cmd_change_password (void)
|
||||
int salt_len;
|
||||
const uint8_t *ks_pw3;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO ("Change PW\r\n");
|
||||
DEBUG_BYTE (who);
|
||||
|
||||
@@ -300,6 +310,12 @@ cmd_change_password (void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_do_kdf_check (len, 2) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (who == BY_USER) /* PW1 */
|
||||
{
|
||||
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
||||
@@ -336,8 +352,9 @@ cmd_change_password (void)
|
||||
newpw_len = len - pw_len;
|
||||
ks_pw3 = gpg_do_read_simple (NR_DO_KEYSTRING_PW3);
|
||||
|
||||
/* Check length of password for admin-less mode. */
|
||||
if (ks_pw3 == NULL && newpw_len < ADMIN_PASSWD_MINLEN)
|
||||
/* Check length of password */
|
||||
if ((ks_pw3 == NULL && newpw_len < ADMIN_PASSWD_MINLEN)
|
||||
|| newpw_len < USER_PASSWD_MINLEN)
|
||||
{
|
||||
DEBUG_INFO ("new password length is too short.");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
@@ -352,8 +369,24 @@ cmd_change_password (void)
|
||||
|
||||
if (ks_pw3 == NULL)
|
||||
{
|
||||
salt = NULL;
|
||||
salt_len = 0;
|
||||
if (admin_authorized == BY_USER)
|
||||
{
|
||||
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
||||
|
||||
if (ks_pw1 == NULL)
|
||||
{
|
||||
GPG_SECURITY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
|
||||
salt = KS_GET_SALT (ks_pw1);
|
||||
salt_len = SALT_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
salt = NULL;
|
||||
salt_len = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -377,13 +410,22 @@ cmd_change_password (void)
|
||||
{
|
||||
newpw = pw + pw_len;
|
||||
newpw_len = len - pw_len;
|
||||
|
||||
if (newpw_len == 0 && admin_authorized == BY_ADMIN)
|
||||
{
|
||||
newpw_len = strlen (OPENPGP_CARD_INITIAL_PW3);
|
||||
memcpy (newpw, OPENPGP_CARD_INITIAL_PW3, newpw_len);
|
||||
const uint8_t *initial_pw;
|
||||
|
||||
gpg_do_get_initial_pw_setting (1, &newpw_len, &initial_pw);
|
||||
memcpy (newpw, initial_pw, newpw_len);
|
||||
newsalt_len = 0;
|
||||
pw3_null = 1;
|
||||
}
|
||||
else if (newpw_len < ADMIN_PASSWD_MINLEN)
|
||||
{
|
||||
DEBUG_INFO ("new password length is too short.");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
who_old = admin_authorized;
|
||||
}
|
||||
@@ -413,11 +455,26 @@ cmd_change_password (void)
|
||||
}
|
||||
else if (r > 0 && who == BY_USER)
|
||||
{
|
||||
/* When it was already admin-less mode, admin_authorized is
|
||||
* BY_USER. If no PW3 keystring, it's becoming admin-less mode,
|
||||
* now. For these two cases, we need to reset admin
|
||||
* authorization status. */
|
||||
if (admin_authorized == BY_USER)
|
||||
ac_reset_admin ();
|
||||
else if (ks_pw3 == NULL)
|
||||
{
|
||||
enum kind_of_key kk0;
|
||||
|
||||
/* Remove keystrings for BY_ADMIN. */
|
||||
for (kk0 = 0; kk0 <= GPG_KEY_FOR_AUTHENTICATION; kk0++)
|
||||
gpg_do_chks_prvkey (kk0, BY_ADMIN, NULL, 0, NULL);
|
||||
|
||||
ac_reset_admin ();
|
||||
}
|
||||
|
||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KS_META_SIZE);
|
||||
ac_reset_pso_cds ();
|
||||
ac_reset_other ();
|
||||
if (admin_authorized == BY_USER)
|
||||
ac_reset_admin ();
|
||||
DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n");
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
@@ -493,7 +550,7 @@ s2k (const unsigned char *salt, size_t slen,
|
||||
|
||||
|
||||
static void
|
||||
cmd_reset_user_password (void)
|
||||
cmd_reset_user_password (struct eventflag *ccid_comm)
|
||||
{
|
||||
uint8_t p1 = P1 (apdu);
|
||||
int len;
|
||||
@@ -504,9 +561,11 @@ cmd_reset_user_password (void)
|
||||
uint8_t new_ks0[KEYSTRING_SIZE];
|
||||
uint8_t *new_ks = KS_GET_KEYSTRING (new_ks0);
|
||||
uint8_t *new_salt = KS_GET_SALT (new_ks0);
|
||||
const uint8_t *ks_pw3 = gpg_do_read_simple (NR_DO_KEYSTRING_PW3);
|
||||
const uint8_t *salt;
|
||||
int salt_len;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO ("Reset PW1\r\n");
|
||||
DEBUG_BYTE (p1);
|
||||
|
||||
@@ -518,6 +577,12 @@ cmd_reset_user_password (void)
|
||||
const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
|
||||
uint8_t old_ks[KEYSTRING_MD_SIZE];
|
||||
|
||||
if (gpg_do_kdf_check (len, 2) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_pw_locked (PW_ERR_RC))
|
||||
{
|
||||
DEBUG_INFO ("blocked.\r\n");
|
||||
@@ -537,6 +602,16 @@ cmd_reset_user_password (void)
|
||||
salt_len = SALT_SIZE;
|
||||
newpw = pw + pw_len;
|
||||
newpw_len = len - pw_len;
|
||||
|
||||
/* Check length of new password */
|
||||
if ((ks_pw3 == NULL && newpw_len < ADMIN_PASSWD_MINLEN)
|
||||
|| newpw_len < USER_PASSWD_MINLEN)
|
||||
{
|
||||
DEBUG_INFO ("new password length is too short.");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
random_get_salt (new_salt);
|
||||
s2k (salt, salt_len, pw, pw_len, old_ks);
|
||||
s2k (new_salt, SALT_SIZE, newpw, newpw_len, new_ks);
|
||||
@@ -582,8 +657,24 @@ cmd_reset_user_password (void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpg_do_kdf_check (len, 1) == 0)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
newpw_len = len;
|
||||
newpw = pw;
|
||||
|
||||
/* Check length of new password */
|
||||
if ((ks_pw3 == NULL && newpw_len < ADMIN_PASSWD_MINLEN)
|
||||
|| newpw_len < USER_PASSWD_MINLEN)
|
||||
{
|
||||
DEBUG_INFO ("new password length is too short.");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
random_get_salt (new_salt);
|
||||
s2k (new_salt, SALT_SIZE, newpw, newpw_len, new_ks);
|
||||
new_ks0[0] = newpw_len;
|
||||
@@ -618,12 +709,13 @@ cmd_reset_user_password (void)
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_put_data (void)
|
||||
cmd_put_data (struct eventflag *ccid_comm)
|
||||
{
|
||||
uint8_t *data;
|
||||
uint16_t tag;
|
||||
int len;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - PUT DATA\r\n");
|
||||
|
||||
tag = ((P1 (apdu)<<8) | P2 (apdu));
|
||||
@@ -633,8 +725,9 @@ cmd_put_data (void)
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_pgp_gakp (void)
|
||||
cmd_pgp_gakp (struct eventflag *ccid_comm)
|
||||
{
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - Generate Asymmetric Key Pair\r\n");
|
||||
DEBUG_BYTE (P1 (apdu));
|
||||
|
||||
@@ -645,19 +738,26 @@ cmd_pgp_gakp (void)
|
||||
{
|
||||
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
const uint8_t *
|
||||
gpg_get_firmware_update_key (uint8_t keyno)
|
||||
{
|
||||
extern uint8_t _updatekey_store;
|
||||
extern uint8_t _updatekey_store[1024];
|
||||
const uint8_t *p;
|
||||
|
||||
p = &_updatekey_store + keyno * FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
p = _updatekey_store + keyno * FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CERTDO_SUPPORT
|
||||
#define FILEID_CH_CERTIFICATE_IS_VALID 1
|
||||
@@ -666,13 +766,13 @@ gpg_get_firmware_update_key (uint8_t keyno)
|
||||
#endif
|
||||
|
||||
static void
|
||||
cmd_read_binary (void)
|
||||
cmd_read_binary (struct eventflag *ccid_comm)
|
||||
{
|
||||
int is_short_EF = (P1 (apdu) & 0x80) != 0;
|
||||
uint8_t file_id;
|
||||
const uint8_t *p;
|
||||
uint16_t offset;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - Read binary\r\n");
|
||||
|
||||
if (is_short_EF)
|
||||
@@ -680,13 +780,6 @@ cmd_read_binary (void)
|
||||
else
|
||||
file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
|
||||
|
||||
if ((!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
|
||||
|| file_id > FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
GPG_NO_FILE ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_short_EF)
|
||||
{
|
||||
file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
|
||||
@@ -706,22 +799,26 @@ cmd_read_binary (void)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
{
|
||||
if (offset != 0)
|
||||
GPG_MEMORY_FAILURE ();
|
||||
else
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
|
||||
res_APDU_size = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
memcpy (res_APDU, p, FIRMWARE_UPDATE_KEY_CONTENT_LEN);
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
else /* file_id == FILEID_CH_CERTIFICATE */
|
||||
else if (file_id == FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
const uint8_t *p;
|
||||
uint16_t len = 256;
|
||||
|
||||
p = &ch_certificate_start;
|
||||
@@ -738,11 +835,17 @@ cmd_read_binary (void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
GPG_NO_FILE ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_select_file (void)
|
||||
cmd_select_file (struct eventflag *ccid_comm)
|
||||
{
|
||||
(void)ccid_comm;
|
||||
if (P1 (apdu) == 4) /* Selection by DF name */
|
||||
{
|
||||
DEBUG_INFO (" - select DF by name\r\n");
|
||||
@@ -760,8 +863,7 @@ cmd_select_file (void)
|
||||
|
||||
if (file_selection == FILE_CARD_TERMINATED)
|
||||
{
|
||||
file_selection = FILE_CARD_TERMINATED_OPENPGP;
|
||||
GPG_APPLICATION_TERMINATED();
|
||||
GPG_APPLICATION_TERMINATED ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -812,10 +914,11 @@ cmd_select_file (void)
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_get_data (void)
|
||||
cmd_get_data (struct eventflag *ccid_comm)
|
||||
{
|
||||
uint16_t tag = ((P1 (apdu)<<8) | P2 (apdu));
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - Get Data\r\n");
|
||||
|
||||
gpg_do_get_data (tag, 0);
|
||||
@@ -830,7 +933,7 @@ cmd_get_data (void)
|
||||
#define ECC_CIPHER_DO_HEADER_SIZE 7
|
||||
|
||||
static void
|
||||
cmd_pso (void)
|
||||
cmd_pso (struct eventflag *ccid_comm)
|
||||
{
|
||||
int len = apdu.cmd_apdu_data_len;
|
||||
int r = -1;
|
||||
@@ -857,6 +960,11 @@ cmd_pso (void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
if (gpg_do_get_uif (GPG_KEY_FOR_SIGNING))
|
||||
eventflag_signal (ccid_comm, EV_EXEC_ACK_REQUIRED);
|
||||
#endif
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
/* Check size of digestInfo */
|
||||
@@ -902,13 +1010,6 @@ cmd_pso (void)
|
||||
{
|
||||
uint32_t output[64/4]; /* Require 4-byte alignment. */
|
||||
|
||||
if (len > EDDSA_HASH_LEN_MAX)
|
||||
{
|
||||
DEBUG_INFO ("wrong hash length.");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = EDDSA_SIGNATURE_LENGTH;
|
||||
r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output,
|
||||
@@ -948,6 +1049,13 @@ cmd_pso (void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
if (gpg_do_get_uif (GPG_KEY_FOR_DECRYPTION))
|
||||
eventflag_signal (ccid_comm, EV_EXEC_ACK_REQUIRED);
|
||||
#else
|
||||
(void)ccid_comm;
|
||||
#endif
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
/* Skip padding 0x00 */
|
||||
@@ -1024,7 +1132,7 @@ cmd_pso (void)
|
||||
|
||||
#define MAX_RSA_DIGEST_INFO_LEN 102 /* 40% */
|
||||
static void
|
||||
cmd_internal_authenticate (void)
|
||||
cmd_internal_authenticate (struct eventflag *ccid_comm)
|
||||
{
|
||||
int attr = gpg_get_algo_attr (GPG_KEY_FOR_AUTHENTICATION);
|
||||
int pubkey_len = gpg_get_algo_attr_key_size (GPG_KEY_FOR_AUTHENTICATION,
|
||||
@@ -1054,6 +1162,13 @@ cmd_internal_authenticate (void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
if (gpg_do_get_uif (GPG_KEY_FOR_AUTHENTICATION))
|
||||
eventflag_signal (ccid_comm, EV_EXEC_ACK_REQUIRED);
|
||||
#else
|
||||
(void)ccid_comm;
|
||||
#endif
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
if (len > MAX_RSA_DIGEST_INFO_LEN)
|
||||
@@ -1101,13 +1216,6 @@ cmd_internal_authenticate (void)
|
||||
{
|
||||
uint32_t output[64/4]; /* Require 4-byte alignment. */
|
||||
|
||||
if (len > EDDSA_HASH_LEN_MAX)
|
||||
{
|
||||
DEBUG_INFO ("wrong hash length.");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
cs = chopstx_setcancelstate (0);
|
||||
result_len = EDDSA_SIGNATURE_LENGTH;
|
||||
r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output,
|
||||
@@ -1202,6 +1310,7 @@ modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3
|
||||
&& len == 0 && offset == 0)
|
||||
{
|
||||
@@ -1218,9 +1327,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 ();
|
||||
}
|
||||
@@ -1228,10 +1338,11 @@ modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
|
||||
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
static void
|
||||
cmd_update_binary (void)
|
||||
cmd_update_binary (struct eventflag *ccid_comm)
|
||||
{
|
||||
int len = apdu.cmd_apdu_data_len;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - UPDATE BINARY\r\n");
|
||||
modify_binary (MBD_OPRATION_UPDATE, P1 (apdu), P2 (apdu), len);
|
||||
DEBUG_INFO ("UPDATE BINARY done.\r\n");
|
||||
@@ -1240,18 +1351,20 @@ cmd_update_binary (void)
|
||||
|
||||
|
||||
static void
|
||||
cmd_write_binary (void)
|
||||
cmd_write_binary (struct eventflag *ccid_comm)
|
||||
{
|
||||
int len = apdu.cmd_apdu_data_len;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - WRITE BINARY\r\n");
|
||||
modify_binary (MBD_OPRATION_WRITE, P1 (apdu), P2 (apdu), len);
|
||||
DEBUG_INFO ("WRITE BINARY done.\r\n");
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
static void
|
||||
cmd_external_authenticate (void)
|
||||
cmd_external_authenticate (struct eventflag *ccid_comm)
|
||||
{
|
||||
const uint8_t *pubkey;
|
||||
const uint8_t *signature = apdu.cmd_apdu_data;
|
||||
@@ -1259,6 +1372,7 @@ cmd_external_authenticate (void)
|
||||
uint8_t keyno = P2 (apdu);
|
||||
int r;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n");
|
||||
|
||||
if (keyno >= 4)
|
||||
@@ -1291,12 +1405,14 @@ cmd_external_authenticate (void)
|
||||
set_res_sw (0xff, 0xff);
|
||||
DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cmd_get_challenge (void)
|
||||
cmd_get_challenge (struct eventflag *ccid_comm)
|
||||
{
|
||||
int len = apdu.expected_res_size;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - GET CHALLENGE\r\n");
|
||||
|
||||
if (len > CHALLENGE_LEN)
|
||||
@@ -1311,6 +1427,13 @@ cmd_get_challenge (void)
|
||||
if (challenge)
|
||||
random_bytes_free (challenge);
|
||||
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
if (gpg_do_get_uif (GPG_KEY_FOR_SIGNING)
|
||||
|| gpg_do_get_uif (GPG_KEY_FOR_DECRYPTION)
|
||||
|| gpg_do_get_uif (GPG_KEY_FOR_AUTHENTICATION))
|
||||
eventflag_signal (ccid_comm, EV_EXEC_ACK_REQUIRED);
|
||||
#endif
|
||||
|
||||
challenge = random_bytes_get ();
|
||||
memcpy (res_APDU, challenge, len);
|
||||
res_APDU_size = len;
|
||||
@@ -1321,11 +1444,12 @@ cmd_get_challenge (void)
|
||||
|
||||
#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
|
||||
static void
|
||||
cmd_activate_file (void)
|
||||
cmd_activate_file (struct eventflag *ccid_comm)
|
||||
{
|
||||
if (file_selection != FILE_CARD_TERMINATED_OPENPGP)
|
||||
(void)ccid_comm;
|
||||
if (file_selection != FILE_CARD_TERMINATED)
|
||||
{
|
||||
GPG_NO_RECORD();
|
||||
GPG_NO_RECORD ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1335,14 +1459,16 @@ cmd_activate_file (void)
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_terminate_df (void)
|
||||
cmd_terminate_df (struct eventflag *ccid_comm)
|
||||
{
|
||||
const uint8_t *ks_pw3;
|
||||
uint8_t p1 = P1 (apdu);
|
||||
uint8_t p2 = P2 (apdu);
|
||||
|
||||
(void)ccid_comm;
|
||||
if (file_selection != FILE_DF_OPENPGP)
|
||||
{
|
||||
GPG_NO_RECORD();
|
||||
GPG_NO_RECORD ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1358,8 +1484,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();
|
||||
@@ -1380,7 +1509,7 @@ cmd_terminate_df (void)
|
||||
struct command
|
||||
{
|
||||
uint8_t command;
|
||||
void (*cmd_handler) (void);
|
||||
void (*cmd_handler) (struct eventflag *ccid_comm);
|
||||
};
|
||||
|
||||
const struct command cmds[] = {
|
||||
@@ -1392,8 +1521,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 },
|
||||
@@ -1412,7 +1543,7 @@ const struct command cmds[] = {
|
||||
#define NUM_CMDS ((int)(sizeof (cmds) / sizeof (struct command)))
|
||||
|
||||
static void
|
||||
process_command_apdu (void)
|
||||
process_command_apdu (struct eventflag *ccid_comm)
|
||||
{
|
||||
int i;
|
||||
uint8_t cmd = INS (apdu);
|
||||
@@ -1426,17 +1557,17 @@ 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);
|
||||
cmds[i].cmd_handler ();
|
||||
cmds[i].cmd_handler (ccid_comm);
|
||||
chopstx_setcancelstate (0);
|
||||
}
|
||||
}
|
||||
@@ -1550,7 +1681,7 @@ openpgp_card_thread (void *arg)
|
||||
break;
|
||||
|
||||
led_blink (LED_START_COMMAND);
|
||||
process_command_apdu ();
|
||||
process_command_apdu (ccid_comm);
|
||||
led_blink (LED_FINISH_COMMAND);
|
||||
done:
|
||||
eventflag_signal (ccid_comm, EV_EXEC_FINISHED);
|
||||
|
||||
@@ -40,14 +40,14 @@ cir_ext_disable (void)
|
||||
int rcvd = (EXTI->PR & EXTI_PR) != 0;
|
||||
|
||||
EXTI->IMR &= ~EXTI_IMR;
|
||||
EXTI->PR = EXTI_PR;
|
||||
EXTI->PR |= EXTI_PR;
|
||||
return rcvd;
|
||||
}
|
||||
|
||||
static void
|
||||
cir_ext_enable (void)
|
||||
{
|
||||
EXTI->PR = EXTI_PR;
|
||||
EXTI->PR |= EXTI_PR;
|
||||
EXTI->IMR |= EXTI_IMR;
|
||||
}
|
||||
|
||||
@@ -964,9 +964,14 @@ cir_timer_interrupt (void)
|
||||
}
|
||||
|
||||
|
||||
extern uint8_t __process6_stack_base__[], __process6_stack_size__[];
|
||||
#define STACK_ADDR_TIM ((uint32_t)__process6_stack_base__)
|
||||
#define STACK_SIZE_TIM ((uint32_t)__process6_stack_size__)
|
||||
#define STACK_PROCESS_6
|
||||
#define STACK_PROCESS_7
|
||||
#include "stack-def.h"
|
||||
#define STACK_ADDR_TIM ((uintptr_t)process6_base)
|
||||
#define STACK_SIZE_TIM (sizeof process6_base)
|
||||
#define STACK_ADDR_EXT ((uintptr_t)process7_base)
|
||||
#define STACK_SIZE_EXT (sizeof process7_base)
|
||||
|
||||
#define PRIO_TIM 4
|
||||
|
||||
static void *
|
||||
@@ -981,14 +986,13 @@ tim_main (void *arg)
|
||||
{
|
||||
chopstx_intr_wait (&interrupt);
|
||||
cir_timer_interrupt ();
|
||||
chopstx_intr_done (&interrupt);
|
||||
}
|
||||
|
||||
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 *
|
||||
@@ -1003,6 +1007,7 @@ ext_main (void *arg)
|
||||
{
|
||||
chopstx_intr_wait (&interrupt);
|
||||
cir_ext_interrupt ();
|
||||
chopstx_intr_done (&interrupt);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1030,8 +1035,8 @@ cir_init (void)
|
||||
|
||||
/* EXTIx <= Py */
|
||||
AFIO->EXTICR[AFIO_EXTICR_INDEX] = AFIO_EXTICR1_EXTIx_Py;
|
||||
EXTI->IMR = 0;
|
||||
EXTI->FTSR = EXTI_FTSR_TR;
|
||||
EXTI->IMR &= ~EXTI_IMR;
|
||||
EXTI->FTSR |= EXTI_FTSR_TR;
|
||||
|
||||
/* TIM */
|
||||
#ifdef ENABLE_RCC_APB1
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "sha256.h"
|
||||
|
||||
#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "sha512.h"
|
||||
|
||||
#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
|
||||
|
||||
65
src/stack-def.h
Normal file
65
src/stack-def.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define SIZE_1 4096
|
||||
#define SIZE_2 4096
|
||||
#define SIZE_3 (5 * 4096)
|
||||
#else
|
||||
#define SIZE_0 0x0160 /* Main */
|
||||
#define SIZE_1 0x01a0 /* CCID */
|
||||
#define SIZE_2 0x0180 /* RNG */
|
||||
#if MEMORY_SIZE >= 32
|
||||
#define SIZE_3 0x4640 /* openpgp-card */
|
||||
#elif MEMORY_SIZE >= 24
|
||||
#define SIZE_3 0x2640 /* openpgp-card */
|
||||
#else
|
||||
#define SIZE_3 0x1640 /* openpgp-card */
|
||||
#endif
|
||||
#define SIZE_4 0x0000 /* --- */
|
||||
#define SIZE_5 0x0200 /* msc */
|
||||
#define SIZE_6 0x00c0 /* timer (cir) */
|
||||
#define SIZE_7 0x00c0 /* ext (cir) */
|
||||
#endif
|
||||
|
||||
#if defined(STACK_MAIN) && !defined(GNU_LINUX_EMULATION)
|
||||
/* Idle+Exception handlers */
|
||||
char __main_stack_end__[0] __attribute__ ((section(".main_stack")));
|
||||
char main_base[0x0080] __attribute__ ((section(".main_stack")));
|
||||
|
||||
/* Main program */
|
||||
char __process0_stack_end__[0] __attribute__ ((section(".process_stack.0")));
|
||||
char process0_base[SIZE_0] __attribute__ ((section(".process_stack.0")));
|
||||
#endif
|
||||
|
||||
/* First thread program */
|
||||
#if defined(STACK_PROCESS_1)
|
||||
char process1_base[SIZE_1] __attribute__ ((section(".process_stack.1")));
|
||||
#endif
|
||||
|
||||
/* Second thread program */
|
||||
#if defined(STACK_PROCESS_2)
|
||||
char process2_base[SIZE_2] __attribute__ ((section(".process_stack.2")));
|
||||
#endif
|
||||
|
||||
/* Third thread program */
|
||||
#if defined(STACK_PROCESS_3)
|
||||
char process3_base[SIZE_3] __attribute__ ((section(".process_stack.3")));
|
||||
#endif
|
||||
|
||||
/* Fourth thread program */
|
||||
#if defined(STACK_PROCESS_4)
|
||||
char process4_base[SIZE_4] __attribute__ ((section(".process_stack.4")));
|
||||
#endif
|
||||
|
||||
/* Fifth thread program */
|
||||
#if defined(STACK_PROCESS_5)
|
||||
char process5_base[SIZE_5] __attribute__ ((section(".process_stack.5")));
|
||||
#endif
|
||||
|
||||
/* Sixth thread program */
|
||||
#if defined(STACK_PROCESS_6)
|
||||
char process6_base[SIZE_6] __attribute__ ((section(".process_stack.6")));
|
||||
#endif
|
||||
|
||||
/* Seventh thread program */
|
||||
#if defined(STACK_PROCESS_7)
|
||||
char process7_base[SIZE_7] __attribute__ ((section(".process_stack.7")));
|
||||
#endif
|
||||
39
src/stdaln-sys.ld.in
Normal file
39
src/stdaln-sys.ld.in
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* ST32F103 memory setup.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
flash0 : org = @ORIGIN_REAL@, len = 4k
|
||||
ram : org = 0x20000000, len = @MEMORY_SIZE@k
|
||||
}
|
||||
|
||||
__ram_start__ = ORIGIN(ram);
|
||||
__ram_size__ = LENGTH(ram);
|
||||
__ram_end__ = __ram_start__ + __ram_size__;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
|
||||
.sys : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
_sys = .;
|
||||
KEEP(*(.vectors))
|
||||
. = ALIGN(16);
|
||||
KEEP(*(.sys.version))
|
||||
KEEP(*(.sys.board_id))
|
||||
KEEP(*(.sys.board_name))
|
||||
build/sys-*.o(.text)
|
||||
build/sys-*.o(.text.*)
|
||||
build/sys-*.o(.rodata)
|
||||
build/sys-*.o(.rodata.*)
|
||||
. = ALIGN(1024);
|
||||
} > flash0
|
||||
|
||||
.aesft : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
*(.sys.0)
|
||||
*(.sys.1)
|
||||
*(.sys.2)
|
||||
} > flash0
|
||||
}
|
||||
13
src/stdlib.h
13
src/stdlib.h
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* stdlib.h replacement to replace malloc functions
|
||||
*/
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#include <stddef.h> /* NULL */
|
||||
|
||||
#define malloc(size) gnuk_malloc (size)
|
||||
#define free(p) gnuk_free (p)
|
||||
|
||||
void *gnuk_malloc (size_t);
|
||||
void gnuk_free (void *);
|
||||
589
src/usb-ccid.c
589
src/usb-ccid.c
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
101
src/usb_ctrl.c
101
src/usb_ctrl.c
@@ -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, 2018
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "usb_lld.h"
|
||||
#include "usb_conf.h"
|
||||
#include "gnuk.h"
|
||||
#include "neug.h"
|
||||
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
#include "usb-cdc.h"
|
||||
@@ -86,7 +87,7 @@ vcom_port_data_setup (struct usb_dev *dev)
|
||||
#include "usb-msc.h"
|
||||
#endif
|
||||
|
||||
uint32_t bDeviceState = UNCONNECTED; /* USB device status */
|
||||
uint32_t bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||
|
||||
#define USB_HID_REQ_GET_REPORT 1
|
||||
#define USB_HID_REQ_GET_IDLE 2
|
||||
@@ -107,15 +108,25 @@ static uint16_t hid_report;
|
||||
#endif
|
||||
|
||||
static void
|
||||
gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
gnuk_setup_endpoints_for_interface (struct usb_dev *dev,
|
||||
uint16_t interface, int stop)
|
||||
{
|
||||
#if !defined(GNU_LINUX_EMULATION)
|
||||
(void)dev;
|
||||
#endif
|
||||
|
||||
if (interface == CCID_INTERFACE)
|
||||
{
|
||||
if (!stop)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP1, 1, 1);
|
||||
usb_lld_setup_endp (dev, ENDP2, 0, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, ENDP1_RXADDR,
|
||||
ENDP1_TXADDR, GNUK_MAX_PACKET_SIZE);
|
||||
usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -128,7 +139,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
else if (interface == HID_INTERFACE)
|
||||
{
|
||||
if (!stop)
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP7, 0, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP7, EP_INTERRUPT, 0, 0, ENDP7_TXADDR, 0);
|
||||
#endif
|
||||
else
|
||||
usb_lld_stall_tx (ENDP7);
|
||||
}
|
||||
@@ -137,7 +152,11 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
else if (interface == VCOM_INTERFACE_0)
|
||||
{
|
||||
if (!stop)
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP4, 0, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP4, EP_INTERRUPT, 0, 0, ENDP4_TXADDR, 0);
|
||||
#endif
|
||||
else
|
||||
usb_lld_stall_tx (ENDP4);
|
||||
}
|
||||
@@ -145,9 +164,14 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
{
|
||||
if (!stop)
|
||||
{
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP3, 0, 1);
|
||||
usb_lld_setup_endp (dev, ENDP5, 1, 0);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, 0, ENDP3_TXADDR, 0);
|
||||
usb_lld_setup_endpoint (ENDP5, EP_BULK, 0, ENDP5_RXADDR, 0,
|
||||
VIRTUAL_COM_PORT_DATA_SIZE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -160,8 +184,12 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
else if (interface == MSC_INTERFACE)
|
||||
{
|
||||
if (!stop)
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
usb_lld_setup_endp (dev, ENDP6, 1, 1);
|
||||
#else
|
||||
usb_lld_setup_endpoint (ENDP6, EP_BULK, 0,
|
||||
ENDP6_RXADDR, ENDP6_TXADDR, 64);
|
||||
#endif
|
||||
else
|
||||
{
|
||||
usb_lld_stall_tx (ENDP6);
|
||||
@@ -174,20 +202,17 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
|
||||
void
|
||||
usb_device_reset (struct usb_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
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);
|
||||
|
||||
bDeviceState = ATTACHED;
|
||||
ccid_usb_reset (1);
|
||||
bDeviceState = USB_DEVICE_STATE_DEFAULT;
|
||||
}
|
||||
|
||||
#define USB_CCID_REQ_ABORT 0x01
|
||||
@@ -201,22 +226,34 @@ static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
|
||||
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
|
||||
#endif
|
||||
|
||||
static const uint8_t *const mem_info[] = { &_regnual_start, __heap_end__, };
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
static const uint8_t *const mem_info[] = { _regnual_start, __heap_end__, };
|
||||
#endif
|
||||
|
||||
#define USB_FSIJ_GNUK_MEMINFO 0
|
||||
#define USB_FSIJ_GNUK_DOWNLOAD 1
|
||||
#define USB_FSIJ_GNUK_EXEC 2
|
||||
#define USB_FSIJ_GNUK_CARD_CHANGE 3
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
/* After calling this function, CRC module remain enabled. */
|
||||
static int
|
||||
download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
|
||||
{
|
||||
if (check_crc32 ((const uint32_t *)&_regnual_start, end_p))
|
||||
uint32_t crc32 = *end_p;
|
||||
const uint32_t *p;
|
||||
|
||||
crc32_rv_reset ();
|
||||
|
||||
for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
|
||||
crc32_rv_step (rbit (*p));
|
||||
|
||||
if ((rbit (crc32_rv_get ()) ^ crc32) == 0xffffffff)
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
usb_setup (struct usb_dev *dev)
|
||||
@@ -228,19 +265,26 @@ usb_setup (struct usb_dev *dev)
|
||||
{
|
||||
if (USB_SETUP_GET (arg->type))
|
||||
{
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (arg->request == USB_FSIJ_GNUK_MEMINFO)
|
||||
return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else /* SETUP_SET */
|
||||
{
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
uint8_t *addr = sram_address ((arg->value * 0x100) + arg->index);
|
||||
#endif
|
||||
|
||||
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
||||
{
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (ccid_get_ccid_state () != CCID_STATE_EXITED)
|
||||
return -1;
|
||||
|
||||
if (addr < &_regnual_start || addr + arg->len > __heap_end__)
|
||||
if (addr < _regnual_start || addr + arg->len > __heap_end__)
|
||||
return -1;
|
||||
|
||||
if (arg->index + arg->len < 256)
|
||||
@@ -248,16 +292,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)
|
||||
{
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (ccid_get_ccid_state () != CCID_STATE_EXITED)
|
||||
return -1;
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -353,10 +404,10 @@ usb_ctrl_write_finish (struct usb_dev *dev)
|
||||
{
|
||||
if (USB_SETUP_SET (arg->type) && arg->request == USB_FSIJ_GNUK_EXEC)
|
||||
{
|
||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||
if (ccid_get_ccid_state () != CCID_STATE_EXITED)
|
||||
return;
|
||||
|
||||
bDeviceState = UNCONNECTED;
|
||||
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||
usb_lld_prepare_shutdown (); /* No further USB communication */
|
||||
led_blink (LED_GNUK_EXEC); /* Notify the main. */
|
||||
}
|
||||
@@ -417,8 +468,8 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
|
||||
usb_lld_set_configuration (dev, 1);
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
gnuk_setup_endpoints_for_interface (i, 0);
|
||||
bDeviceState = CONFIGURED;
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 0);
|
||||
bDeviceState = USB_DEVICE_STATE_CONFIGURED;
|
||||
}
|
||||
else if (current_conf != dev->dev_req.value)
|
||||
{
|
||||
@@ -427,9 +478,8 @@ usb_set_configuration (struct usb_dev *dev)
|
||||
|
||||
usb_lld_set_configuration (dev, 0);
|
||||
for (i = 0; i < NUM_INTERFACES; i++)
|
||||
gnuk_setup_endpoints_for_interface (i, 1);
|
||||
bDeviceState = ADDRESSED;
|
||||
ccid_usb_reset (1);
|
||||
gnuk_setup_endpoints_for_interface (dev, i, 1);
|
||||
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
|
||||
}
|
||||
|
||||
/* Do nothing when current_conf == value */
|
||||
@@ -450,8 +500,7 @@ usb_set_interface (struct usb_dev *dev)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
gnuk_setup_endpoints_for_interface (interface, 0);
|
||||
ccid_usb_reset (0);
|
||||
gnuk_setup_endpoints_for_interface (dev, interface, 0);
|
||||
return usb_lld_ctrl_ack (dev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,15 +59,20 @@ static const uint8_t hid_report_desc[] = {
|
||||
#define USB_CCID_DATA_SIZE 64
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t device_desc[] = {
|
||||
#if !defined(GNU_LINUX_EMULATION)
|
||||
static const
|
||||
#endif
|
||||
uint8_t device_desc[] = {
|
||||
18, /* bLength */
|
||||
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||
0x00, 0x02, /* bcdUSB = 2.0 */
|
||||
0x00, /* bDeviceClass: 0 means deferred to interface */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
#include "usb-vid-pid-ver.c.inc"
|
||||
0x00, 0x00, /* idVendor (will be replaced) */
|
||||
0x00, 0x00, /* idProduct (will be replaced) */
|
||||
0x00, 0x00, /* bcdDevice (will be replaced) */
|
||||
1, /* Index of string descriptor describing manufacturer */
|
||||
2, /* Index of string descriptor describing product */
|
||||
3, /* Index of string descriptor describing the device's serial number */
|
||||
|
||||
@@ -8,7 +8,7 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object extended capabilities
|
||||
When requesting extended capabilities: c0
|
||||
Then data should match: [\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
Then data should match: [\x70\x74\x75]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
|
||||
Scenario: data object algorithm attributes 1
|
||||
When requesting algorithm attributes 1: c1
|
||||
@@ -24,4 +24,4 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object AID
|
||||
When requesting AID: 4f
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00......\x00\x00
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00[\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff]\x00\x00
|
||||
|
||||
@@ -4,7 +4,7 @@ Feature: setup pass phrase
|
||||
A token should support pass phrase: PW1, PW3 and reset code
|
||||
|
||||
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
|
||||
|
||||
Scenario: verify PW1 (1)
|
||||
|
||||
@@ -8,7 +8,7 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object extended capabilities
|
||||
When requesting extended capabilities: c0
|
||||
Then data should match: [\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
Then data should match: [\x70\x74\x75]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
|
||||
Scenario: data object algorithm attributes 1
|
||||
When requesting algorithm attributes 1: c1
|
||||
@@ -24,4 +24,4 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object AID
|
||||
When requesting AID: 4f
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00......\x00\x00
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00[\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff]\x00\x00
|
||||
|
||||
@@ -8,7 +8,7 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object extended capabilities
|
||||
When requesting extended capabilities: c0
|
||||
Then data should match: [\x70\x74]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
Then data should match: [\x70\x74\x75]\x00\x00\x20[\x00\x08]\x00\x00\xff\x01\x00
|
||||
|
||||
Scenario: data object algorithm attributes 1
|
||||
When requesting algorithm attributes 1: c1
|
||||
@@ -24,4 +24,4 @@ Feature: command GET DATA
|
||||
|
||||
Scenario: data object AID
|
||||
When requesting AID: 4f
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00......\x00\x00
|
||||
Then data should match: \xd2\x76\x00\x01\x24\x01\x02\x00[\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff][\x00-\xff]\x00\x00
|
||||
|
||||
@@ -70,11 +70,11 @@ def build_privkey_template_for_remove(openpgp_keyno):
|
||||
keyspec = b'\xb8'
|
||||
else:
|
||||
keyspec = b'\xa4'
|
||||
return b'\x4d\02' + keyspec + b'\0x00'
|
||||
return b'\x4d\x02' + keyspec + b'\x00'
|
||||
|
||||
def compute_digestinfo(msg):
|
||||
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
|
||||
|
||||
# egcd and modinv are from wikibooks
|
||||
|
||||
@@ -6,7 +6,7 @@ Gnuk Token is supported as well.
|
||||
|
||||
You need to install:
|
||||
|
||||
$ sudo apt-get install python3-pytest python3-usb
|
||||
$ sudo apt install python3-pytest python3-usb python3-cffi
|
||||
|
||||
Please run test by typing:
|
||||
|
||||
|
||||
12
tests/card_const.py
Normal file
12
tests/card_const.py
Normal file
@@ -0,0 +1,12 @@
|
||||
FACTORY_PASSPHRASE_PW1=b"123456"
|
||||
FACTORY_PASSPHRASE_PW3=b"12345678"
|
||||
KEY_ATTRIBUTES_RSA4K=b"\x01\x10\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"
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
card_reader.py - a library for smartcard reader
|
||||
|
||||
Copyright (C) 2016 Free Software Initiative of Japan
|
||||
Copyright (C) 2016, 2017, 2019 Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -25,6 +25,7 @@ from struct import pack
|
||||
from usb.util import find_descriptor, claim_interface, get_string, \
|
||||
endpoint_type, endpoint_direction, \
|
||||
ENDPOINT_TYPE_BULK, ENDPOINT_OUT, ENDPOINT_IN
|
||||
from binascii import hexlify
|
||||
|
||||
# USB class, subclass, protocol
|
||||
CCID_CLASS = 0x0B
|
||||
@@ -125,9 +126,12 @@ class CardReader(object):
|
||||
# intf.extra_descriptors[41]
|
||||
|
||||
self.__dev = dev
|
||||
self.__timeout = 10000
|
||||
self.__timeout = 100000
|
||||
self.__seq = 0
|
||||
|
||||
if self.ccid_get_status() & 0x03 not in (0, 1):
|
||||
raise ValueError("Card absent")
|
||||
|
||||
def get_string(self, num):
|
||||
return get_string(self.__dev, num)
|
||||
|
||||
@@ -168,7 +172,7 @@ class CardReader(object):
|
||||
return status
|
||||
|
||||
def ccid_power_on(self):
|
||||
msg = ccid_compose(0x62, self.__seq, rsv=1) # Vcc=5V
|
||||
msg = ccid_compose(0x62, self.__seq, rsv=2) # Vcc=3.3V
|
||||
self.__dev.write(self.__bulkout, msg, self.__timeout)
|
||||
self.increment_seq()
|
||||
status, chain, data = self.ccid_get_result()
|
||||
@@ -179,9 +183,11 @@ class CardReader(object):
|
||||
# TPDU reader configuration
|
||||
self.ns = 0
|
||||
self.nr = 0
|
||||
# Set PPS
|
||||
pps = b"\xFF\x11\x18\xF6"
|
||||
status, chain, ret_pps = self.ccid_send_data_block(pps)
|
||||
# For Gemalto's SmartCard Reader(s)
|
||||
if self.__dev.idVendor == 0x08E6:
|
||||
# Set PPS
|
||||
pps = b"\xFF\x11\x18\xF6"
|
||||
status, chain, ret_pps = self.ccid_send_data_block(pps)
|
||||
# Set parameters
|
||||
param = b"\x18\x10\xFF\x75\x00\xFE\x00"
|
||||
# ^--- This shoud be adapted by ATR string, see update_param_by_atr
|
||||
@@ -235,16 +241,21 @@ class CardReader(object):
|
||||
|
||||
def send_tpdu(self, info=None, more=0, response_time_ext=0,
|
||||
edc_error=0, no_error=0):
|
||||
rsv = 0
|
||||
if info:
|
||||
data = compose_i_block(self.ns, info, more)
|
||||
elif response_time_ext:
|
||||
# compose S-block
|
||||
data = b"\x00\xE3\x00\xE3"
|
||||
# compose S-block response
|
||||
pcb = 0xe3
|
||||
bwi_byte = bytes([response_time_ext])
|
||||
edc = compute_edc(pcb, bwi_byte)
|
||||
data = bytes([0, pcb, 1]) + bwi_byte + bytes([edc])
|
||||
rsv = response_time_ext
|
||||
elif edc_error:
|
||||
data = compose_r_block(self.nr, edc_error=1)
|
||||
elif no_error:
|
||||
data = compose_r_block(self.nr)
|
||||
msg = ccid_compose(0x6f, self.__seq, data=data)
|
||||
msg = ccid_compose(0x6f, self.__seq, rsv=rsv, data=data)
|
||||
self.__dev.write(self.__bulkout, msg, self.__timeout)
|
||||
self.increment_seq()
|
||||
|
||||
@@ -275,7 +286,7 @@ class CardReader(object):
|
||||
res = b""
|
||||
while True:
|
||||
if is_s_block_time_ext(blk):
|
||||
self.send_tpdu(response_time_ext=1)
|
||||
self.send_tpdu(response_time_ext=blk[3])
|
||||
elif is_i_block_last(blk):
|
||||
self.nr = self.nr ^ 1
|
||||
if is_edc_error(blk):
|
||||
|
||||
58
tests/card_test_ansix9p256r1.py
Normal file
58
tests/card_test_ansix9p256r1.py
Normal 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'
|
||||
),
|
||||
)
|
||||
64
tests/card_test_ansix9p384r1.py
Normal file
64
tests/card_test_ansix9p384r1.py
Normal 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'
|
||||
),
|
||||
)
|
||||
76
tests/card_test_ansix9p512r1.py
Normal file
76
tests/card_test_ansix9p512r1.py
Normal 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'
|
||||
),
|
||||
)
|
||||
58
tests/card_test_brainpoolp256r1.py
Normal file
58
tests/card_test_brainpoolp256r1.py
Normal 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'
|
||||
),
|
||||
)
|
||||
64
tests/card_test_brainpoolp384r1.py
Normal file
64
tests/card_test_brainpoolp384r1.py
Normal 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'
|
||||
),
|
||||
)
|
||||
70
tests/card_test_brainpoolp512r1.py
Normal file
70
tests/card_test_brainpoolp512r1.py
Normal 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'
|
||||
),
|
||||
)
|
||||
51
tests/card_test_ed25519.py
Normal file
51
tests/card_test_ed25519.py
Normal 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'
|
||||
),
|
||||
)
|
||||
36
tests/card_test_kdf_full.py
Normal file
36
tests/card_test_kdf_full.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""
|
||||
card_test_kdf_full.py - test KDF data object
|
||||
|
||||
Copyright (C) 2018, 2019 g10 Code GmbH
|
||||
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/>.
|
||||
"""
|
||||
|
||||
from card_const import *
|
||||
from constants_for_test import *
|
||||
|
||||
class Test_Card_KDF_full(object):
|
||||
|
||||
def test_verify_pw3(self, card):
|
||||
v = card.verify(3, FACTORY_PASSPHRASE_PW3)
|
||||
assert v
|
||||
|
||||
def test_kdf_put_full(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xf9, KDF_FULL)
|
||||
if r:
|
||||
card.configure_with_kdf()
|
||||
assert r
|
||||
35
tests/card_test_kdf_single.py
Normal file
35
tests/card_test_kdf_single.py
Normal file
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
card_test_kdf_single.py - test KDF data object
|
||||
|
||||
Copyright (C) 2018, 2019 g10 Code GmbH
|
||||
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/>.
|
||||
"""
|
||||
|
||||
from card_const import *
|
||||
from constants_for_test import *
|
||||
|
||||
class Test_Card_KDF_Single(object):
|
||||
def test_verify_pw3(self, card):
|
||||
v = card.verify(3, FACTORY_PASSPHRASE_PW3)
|
||||
assert v
|
||||
|
||||
def test_kdf_put_single(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xf9, KDF_SINGLE)
|
||||
if r:
|
||||
card.configure_with_kdf()
|
||||
assert r
|
||||
84
tests/card_test_keygen.py
Normal file
84
tests/card_test_keygen.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""
|
||||
card_test_keygen.py - test key generation
|
||||
|
||||
Copyright (C) 2018, 2019 g10 Code GmbH
|
||||
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/>.
|
||||
"""
|
||||
|
||||
from binascii import hexlify
|
||||
import rsa_keys
|
||||
from card_const import *
|
||||
|
||||
class Test_Card_Keygen(object):
|
||||
def test_keygen_1(self, card):
|
||||
pk = card.cmd_genkey(1)
|
||||
fpr_date = rsa_keys.calc_fpr(pk[0], pk[1])
|
||||
r = card.cmd_put_data(0x00, 0xc7, fpr_date[0])
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xce, fpr_date[1])
|
||||
assert r
|
||||
|
||||
def test_keygen_2(self, card):
|
||||
pk = card.cmd_genkey(2)
|
||||
fpr_date = rsa_keys.calc_fpr(pk[0], pk[1])
|
||||
r = card.cmd_put_data(0x00, 0xc8, fpr_date[0])
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xcf, fpr_date[1])
|
||||
assert r
|
||||
|
||||
def test_keygen_3(self, card):
|
||||
pk = card.cmd_genkey(3)
|
||||
fpr_date = rsa_keys.calc_fpr(pk[0], pk[1])
|
||||
r = card.cmd_put_data(0x00, 0xc9, fpr_date[0])
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xd0, fpr_date[1])
|
||||
assert r
|
||||
|
||||
def test_verify_pw1(self, card):
|
||||
v = card.cmd_verify(1, FACTORY_PASSPHRASE_PW1)
|
||||
assert v
|
||||
|
||||
def test_signature_sigkey(self, card):
|
||||
msg = b"Sign me please"
|
||||
pk = card.cmd_get_public_key(1)
|
||||
pk_info = (pk[9:9+256], pk[9+256+2:])
|
||||
digest = rsa_keys.compute_digestinfo(msg)
|
||||
sig = int(hexlify(card.cmd_pso(0x9e, 0x9a, digest)),16)
|
||||
r = rsa_keys.verify_signature(pk_info, digest, sig)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_2(self, card):
|
||||
v = card.cmd_verify(2, FACTORY_PASSPHRASE_PW1)
|
||||
assert v
|
||||
|
||||
def test_decryption(self, card):
|
||||
msg = b"encrypt me please"
|
||||
pk = card.cmd_get_public_key(2)
|
||||
pk_info = (pk[9:9+256], pk[9+256+2:])
|
||||
ciphertext = rsa_keys.encrypt_with_pubkey(pk_info, msg)
|
||||
r = card.cmd_pso(0x80, 0x86, ciphertext)
|
||||
assert r == msg
|
||||
|
||||
def test_signature_authkey(self, card):
|
||||
msg = b"Sign me please to authenticate"
|
||||
pk = card.cmd_get_public_key(3)
|
||||
pk_info = (pk[9:9+256], pk[9+256+2:])
|
||||
digest = rsa_keys.compute_digestinfo(msg)
|
||||
sig = int(hexlify(card.cmd_internal_authenticate(digest)),16)
|
||||
r = rsa_keys.verify_signature(pk_info, digest, sig)
|
||||
assert r
|
||||
312
tests/card_test_personalize_admin_less.py
Normal file
312
tests/card_test_personalize_admin_less.py
Normal file
@@ -0,0 +1,312 @@
|
||||
"""
|
||||
card_test_personalize_admin_less.py - test admin-less mode
|
||||
|
||||
Copyright (C) 2016, 2018, 2019 g10 Code GmbH
|
||||
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/>.
|
||||
"""
|
||||
|
||||
from struct import pack
|
||||
from re import match, DOTALL
|
||||
from util import *
|
||||
import rsa_keys
|
||||
from card_const import *
|
||||
from constants_for_test import *
|
||||
|
||||
class Test_Card_Personalize_Adminless(object):
|
||||
def test_verify_pw3_0(self, card):
|
||||
v = card.verify(3, FACTORY_PASSPHRASE_PW3)
|
||||
assert v
|
||||
|
||||
def test_rsa_import_key_1(self, card):
|
||||
t = rsa_keys.build_privkey_template(1, 0)
|
||||
r = card.cmd_put_data_odd(0x3f, 0xff, t)
|
||||
assert r
|
||||
|
||||
def test_rsa_import_key_2(self, card):
|
||||
t = rsa_keys.build_privkey_template(2, 1)
|
||||
r = card.cmd_put_data_odd(0x3f, 0xff, t)
|
||||
assert r
|
||||
|
||||
def test_rsa_import_key_3(self, card):
|
||||
t = rsa_keys.build_privkey_template(3, 2)
|
||||
r = card.cmd_put_data_odd(0x3f, 0xff, t)
|
||||
assert r
|
||||
|
||||
def test_fingerprint_1_put(self, card):
|
||||
fpr1 = rsa_keys.fpr[0]
|
||||
r = card.cmd_put_data(0x00, 0xc7, fpr1)
|
||||
assert r
|
||||
|
||||
def test_fingerprint_2_put(self, card):
|
||||
fpr2 = rsa_keys.fpr[1]
|
||||
r = card.cmd_put_data(0x00, 0xc8, fpr2)
|
||||
assert r
|
||||
|
||||
def test_fingerprint_3_put(self, card):
|
||||
fpr3 = rsa_keys.fpr[2]
|
||||
r = card.cmd_put_data(0x00, 0xc9, fpr3)
|
||||
assert r
|
||||
|
||||
def test_timestamp_1_put(self, card):
|
||||
timestamp1 = rsa_keys.timestamp[0]
|
||||
r = card.cmd_put_data(0x00, 0xce, timestamp1)
|
||||
assert r
|
||||
|
||||
def test_timestamp_2_put(self, card):
|
||||
timestamp2 = rsa_keys.timestamp[1]
|
||||
r = card.cmd_put_data(0x00, 0xcf, timestamp2)
|
||||
assert r
|
||||
|
||||
def test_timestamp_3_put(self, card):
|
||||
timestamp3 = rsa_keys.timestamp[2]
|
||||
r = card.cmd_put_data(0x00, 0xd0, timestamp3)
|
||||
assert r
|
||||
|
||||
def test_ds_counter_0(self, card):
|
||||
c = get_data_object(card, 0x7a)
|
||||
assert c == b'\x93\x03\x00\x00\x00'
|
||||
|
||||
def test_pw1_status(self, card):
|
||||
s = get_data_object(card, 0xc4)
|
||||
assert match(b'\x01...\x03[\x00\x03]\x03', s, DOTALL)
|
||||
|
||||
def test_app_data(self, card):
|
||||
app_data = get_data_object(card, 0x6e)
|
||||
hist_len = app_data[20]
|
||||
# FIXME: parse and check DO of C0, C1, C2, C3, C4, and C6
|
||||
assert app_data[0:8] == b"\x4f\x10\xd2\x76\x00\x01\x24\x01" and \
|
||||
app_data[18:18+2] == b"\x5f\x52"
|
||||
|
||||
def test_public_key_1(self, card):
|
||||
pk = card.cmd_get_public_key(1)
|
||||
assert rsa_keys.key[0][0] == pk[9:9+256]
|
||||
|
||||
def test_public_key_2(self, card):
|
||||
pk = card.cmd_get_public_key(2)
|
||||
assert rsa_keys.key[1][0] == pk[9:9+256]
|
||||
|
||||
def test_public_key_3(self, card):
|
||||
pk = card.cmd_get_public_key(3)
|
||||
assert rsa_keys.key[2][0] == pk[9:9+256]
|
||||
|
||||
# Changing PW1 to admin-less mode
|
||||
|
||||
def test_setup_pw1_0(self, card):
|
||||
r = card.change_passwd(1, FACTORY_PASSPHRASE_PW1, PW1_TEST0)
|
||||
assert r
|
||||
|
||||
# Now, it's admin-less mode, auth-status admin cleared
|
||||
|
||||
def test_verify_pw3_fail_1(self, card):
|
||||
try:
|
||||
v = card.verify(3, FACTORY_PASSPHRASE_PW3)
|
||||
except ValueError as e:
|
||||
v = False
|
||||
assert not v
|
||||
|
||||
def test_verify_pw1_0(self, card):
|
||||
v = card.verify(1, PW1_TEST0)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_0_2(self, card):
|
||||
v = card.verify(2, PW1_TEST0)
|
||||
assert v
|
||||
|
||||
def test_setup_pw1_1(self, card):
|
||||
r = card.change_passwd(1, PW1_TEST0, PW1_TEST1)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_1(self, card):
|
||||
v = card.verify(1, PW1_TEST1)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_1_2(self, card):
|
||||
v = card.verify(2, PW1_TEST1)
|
||||
assert v
|
||||
|
||||
def test_verify_pw3_admin_less_1(self, card):
|
||||
v = card.verify(3, PW1_TEST1)
|
||||
assert v
|
||||
|
||||
def test_setup_reset_code(self, card):
|
||||
r = card.setup_reset_code(RESETCODE_TEST)
|
||||
assert r
|
||||
|
||||
def test_reset_code(self, card):
|
||||
r = card.reset_passwd_by_resetcode(RESETCODE_TEST, PW1_TEST2)
|
||||
assert r
|
||||
|
||||
# Changing PW1, auth status for admin cleared
|
||||
def test_login_put_fail(self, card):
|
||||
try:
|
||||
r = card.cmd_put_data(0x00, 0x5e, b"gpg_user")
|
||||
except ValueError as e:
|
||||
r = e.args[0]
|
||||
assert r == "6982"
|
||||
|
||||
def test_verify_pw1_2(self, card):
|
||||
v = card.verify(1, PW1_TEST2)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_2_2(self, card):
|
||||
v = card.verify(2, PW1_TEST2)
|
||||
assert v
|
||||
|
||||
def test_verify_pw3_fail_2(self, card):
|
||||
try:
|
||||
v = card.verify(3, FACTORY_PASSPHRASE_PW3)
|
||||
except ValueError as e:
|
||||
v = e.args[0]
|
||||
assert v == "6982"
|
||||
|
||||
def test_sign_0(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT0)
|
||||
r = card.cmd_pso(0x9e, 0x9a, digestinfo)
|
||||
sig = rsa_keys.compute_signature(0, digestinfo)
|
||||
sig_bytes = sig.to_bytes(int((sig.bit_length()+7)/8), byteorder='big')
|
||||
assert r == sig_bytes
|
||||
|
||||
# Since forcesig setting, failed
|
||||
def test_sign_1(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT1)
|
||||
try:
|
||||
r = card.cmd_pso(0x9e, 0x9a, digestinfo)
|
||||
except ValueError as e:
|
||||
r = e.args[0]
|
||||
assert r == "6982"
|
||||
|
||||
def test_ds_counter_1(self, card):
|
||||
c = get_data_object(card, 0x7a)
|
||||
assert c == b'\x93\x03\x00\x00\x01'
|
||||
|
||||
def test_sign_auth_0(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT0)
|
||||
r = card.cmd_internal_authenticate(digestinfo)
|
||||
sig = rsa_keys.compute_signature(2, digestinfo)
|
||||
sig_bytes = sig.to_bytes(int((sig.bit_length()+7)/8), byteorder='big')
|
||||
assert r == sig_bytes
|
||||
|
||||
def test_sign_auth_1(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT1)
|
||||
r = card.cmd_internal_authenticate(digestinfo)
|
||||
sig = rsa_keys.compute_signature(2, digestinfo)
|
||||
sig_bytes = sig.to_bytes(int((sig.bit_length()+7)/8), byteorder='big')
|
||||
assert r == sig_bytes
|
||||
|
||||
def test_decrypt_0(self, card):
|
||||
ciphertext = rsa_keys.encrypt(1, PLAIN_TEXT0)
|
||||
r = card.cmd_pso(0x80, 0x86, ciphertext)
|
||||
assert r == PLAIN_TEXT0
|
||||
|
||||
def test_decrypt_1(self, card):
|
||||
ciphertext = rsa_keys.encrypt(1, PLAIN_TEXT1)
|
||||
r = card.cmd_pso(0x80, 0x86, ciphertext)
|
||||
assert r == PLAIN_TEXT1
|
||||
|
||||
def test_verify_pw3_admin_less_2(self, card):
|
||||
v = card.verify(3, PW1_TEST2)
|
||||
assert v
|
||||
|
||||
def test_login_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0x5e, b"gpg_user")
|
||||
assert r
|
||||
|
||||
def test_name_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0x5b, b"GnuPG User")
|
||||
assert r
|
||||
|
||||
def test_lang_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x2d, b"ja")
|
||||
assert r
|
||||
|
||||
def test_sex_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x35, b"1")
|
||||
assert r
|
||||
|
||||
def test_url_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x50, b"https://www.fsij.org/gnuk/")
|
||||
assert r
|
||||
|
||||
def test_pw1_status_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xc4, b"\x01")
|
||||
assert r
|
||||
|
||||
def test_login(self, card):
|
||||
login = get_data_object(card, 0x5e)
|
||||
assert login == b"gpg_user"
|
||||
|
||||
def test_name_lang_sex(self, card):
|
||||
name = b"GnuPG User"
|
||||
lang = b"ja"
|
||||
sex = b"1"
|
||||
expected = b'\x5b' + pack('B', len(name)) + name \
|
||||
+ b'\x5f\x2d' + pack('B', len(lang)) + lang \
|
||||
+ b'\x5f\x35' + pack('B', len(sex)) + sex
|
||||
name_lang_sex = get_data_object(card, 0x65)
|
||||
assert name_lang_sex == expected
|
||||
|
||||
def test_url(self, card):
|
||||
url = get_data_object(card, 0x5f50)
|
||||
assert url == b"https://www.fsij.org/gnuk/"
|
||||
|
||||
def test_pw1_status(self, card):
|
||||
s = get_data_object(card, 0xc4)
|
||||
assert match(b'\x01...\x03[\x00\x03]\x03', s, DOTALL)
|
||||
|
||||
# Setting PW3, changed to admin-full mode
|
||||
|
||||
def test_setup_pw3_1(self, card):
|
||||
r = card.change_passwd(3, PW1_TEST2, PW3_TEST1)
|
||||
assert r
|
||||
|
||||
def test_verify_pw3_1(self, card):
|
||||
v = card.verify(3, PW3_TEST1)
|
||||
assert v
|
||||
|
||||
def test_reset_userpass_admin(self, card):
|
||||
r = card.reset_passwd_by_admin(PW1_TEST3)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_3(self, card):
|
||||
v = card.verify(1, PW1_TEST3)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_3_2(self, card):
|
||||
v = card.verify(2, PW1_TEST3)
|
||||
assert v
|
||||
|
||||
def test_setup_pw1_4(self, card):
|
||||
r = card.change_passwd(1, PW1_TEST3, PW1_TEST4)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_4(self, card):
|
||||
v = card.verify(1, PW1_TEST4)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_4_2(self, card):
|
||||
v = card.verify(2, PW1_TEST4)
|
||||
assert v
|
||||
|
||||
def test_setup_pw3_2(self, card):
|
||||
r = card.change_passwd(3, PW3_TEST1, PW3_TEST0)
|
||||
assert r
|
||||
|
||||
def test_verify_pw3_2(self, card):
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
|
||||
277
tests/card_test_personalize_card.py
Normal file
277
tests/card_test_personalize_card.py
Normal file
@@ -0,0 +1,277 @@
|
||||
"""
|
||||
card_test_personalize_card.py - test personalizing card
|
||||
|
||||
Copyright (C) 2016, 2018, 2019 g10 Code GmbH
|
||||
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/>.
|
||||
"""
|
||||
|
||||
from struct import pack
|
||||
from re import match, DOTALL
|
||||
from util import *
|
||||
import rsa_keys
|
||||
from card_const import *
|
||||
from constants_for_test import *
|
||||
|
||||
class Test_Card_Personalize_Card(object):
|
||||
def test_setup_pw3_0(self, card):
|
||||
r = card.change_passwd(3, FACTORY_PASSPHRASE_PW3, PW3_TEST0)
|
||||
assert r
|
||||
|
||||
def test_verify_pw3_0(self, card):
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
|
||||
def test_login_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0x5e, b"gpg_user")
|
||||
assert r
|
||||
|
||||
def test_name_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0x5b, b"GnuPG User")
|
||||
assert r
|
||||
|
||||
def test_lang_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x2d, b"ja")
|
||||
assert r
|
||||
|
||||
def test_sex_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x35, b"1")
|
||||
assert r
|
||||
|
||||
def test_url_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x50, b"https://www.fsij.org/gnuk/")
|
||||
assert r
|
||||
|
||||
def test_pw1_status_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xc4, b"\x01")
|
||||
assert r
|
||||
|
||||
def test_login(self, card):
|
||||
login = get_data_object(card, 0x5e)
|
||||
assert login == b"gpg_user"
|
||||
|
||||
def test_name_lang_sex(self, card):
|
||||
name = b"GnuPG User"
|
||||
lang = b"ja"
|
||||
sex = b"1"
|
||||
expected = b'\x5b' + pack('B', len(name)) + name \
|
||||
+ b'\x5f\x2d' + pack('B', len(lang)) + lang \
|
||||
+ b'\x5f\x35' + pack('B', len(sex)) + sex
|
||||
name_lang_sex = get_data_object(card, 0x65)
|
||||
assert name_lang_sex == expected
|
||||
|
||||
def test_url(self, card):
|
||||
url = get_data_object(card, 0x5f50)
|
||||
assert url == b"https://www.fsij.org/gnuk/"
|
||||
|
||||
def test_pw1_status(self, card):
|
||||
s = get_data_object(card, 0xc4)
|
||||
assert match(b'\x01...\x03[\x00\x03]\x03', s, DOTALL)
|
||||
|
||||
def test_rsa_import_key_1(self, card):
|
||||
t = rsa_keys.build_privkey_template(1, 0)
|
||||
r = card.cmd_put_data_odd(0x3f, 0xff, t)
|
||||
assert r
|
||||
|
||||
def test_rsa_import_key_2(self, card):
|
||||
t = rsa_keys.build_privkey_template(2, 1)
|
||||
r = card.cmd_put_data_odd(0x3f, 0xff, t)
|
||||
assert r
|
||||
|
||||
def test_rsa_import_key_3(self, card):
|
||||
t = rsa_keys.build_privkey_template(3, 2)
|
||||
r = card.cmd_put_data_odd(0x3f, 0xff, t)
|
||||
assert r
|
||||
|
||||
def test_fingerprint_1_put(self, card):
|
||||
fpr1 = rsa_keys.fpr[0]
|
||||
r = card.cmd_put_data(0x00, 0xc7, fpr1)
|
||||
assert r
|
||||
|
||||
def test_fingerprint_2_put(self, card):
|
||||
fpr2 = rsa_keys.fpr[1]
|
||||
r = card.cmd_put_data(0x00, 0xc8, fpr2)
|
||||
assert r
|
||||
|
||||
def test_fingerprint_3_put(self, card):
|
||||
fpr3 = rsa_keys.fpr[2]
|
||||
r = card.cmd_put_data(0x00, 0xc9, fpr3)
|
||||
assert r
|
||||
|
||||
def test_timestamp_1_put(self, card):
|
||||
timestamp1 = rsa_keys.timestamp[0]
|
||||
r = card.cmd_put_data(0x00, 0xce, timestamp1)
|
||||
assert r
|
||||
|
||||
def test_timestamp_2_put(self, card):
|
||||
timestamp2 = rsa_keys.timestamp[1]
|
||||
r = card.cmd_put_data(0x00, 0xcf, timestamp2)
|
||||
assert r
|
||||
|
||||
def test_timestamp_3_put(self, card):
|
||||
timestamp3 = rsa_keys.timestamp[2]
|
||||
r = card.cmd_put_data(0x00, 0xd0, timestamp3)
|
||||
assert r
|
||||
|
||||
def test_ds_counter_0(self, card):
|
||||
c = get_data_object(card, 0x7a)
|
||||
assert c == b'\x93\x03\x00\x00\x00'
|
||||
|
||||
def test_pw1_status(self, card):
|
||||
s = get_data_object(card, 0xc4)
|
||||
assert match(b'\x01...\x03[\x00\x03]\x03', s, DOTALL)
|
||||
|
||||
def test_app_data(self, card):
|
||||
app_data = get_data_object(card, 0x6e)
|
||||
hist_len = app_data[20]
|
||||
# FIXME: parse and check DO of C0, C1, C2, C3, C4, and C6
|
||||
assert app_data[0:8] == b"\x4f\x10\xd2\x76\x00\x01\x24\x01" and \
|
||||
app_data[18:18+2] == b"\x5f\x52"
|
||||
|
||||
def test_public_key_1(self, card):
|
||||
pk = card.cmd_get_public_key(1)
|
||||
assert rsa_keys.key[0][0] == pk[9:9+256]
|
||||
|
||||
def test_public_key_2(self, card):
|
||||
pk = card.cmd_get_public_key(2)
|
||||
assert rsa_keys.key[1][0] == pk[9:9+256]
|
||||
|
||||
def test_public_key_3(self, card):
|
||||
pk = card.cmd_get_public_key(3)
|
||||
assert rsa_keys.key[2][0] == pk[9:9+256]
|
||||
|
||||
def test_setup_pw1_0(self, card):
|
||||
r = card.change_passwd(1, FACTORY_PASSPHRASE_PW1, PW1_TEST0)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_0(self, card):
|
||||
v = card.verify(1, PW1_TEST0)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_0_2(self, card):
|
||||
v = card.verify(2, PW1_TEST0)
|
||||
assert v
|
||||
|
||||
def test_setup_pw1_1(self, card):
|
||||
r = card.change_passwd(1, PW1_TEST0, PW1_TEST1)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_1(self, card):
|
||||
v = card.verify(1, PW1_TEST1)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_1_2(self, card):
|
||||
v = card.verify(2, PW1_TEST1)
|
||||
assert v
|
||||
|
||||
def test_setup_reset_code(self, card):
|
||||
r = card.setup_reset_code(RESETCODE_TEST)
|
||||
assert r
|
||||
|
||||
def test_reset_code(self, card):
|
||||
r = card.reset_passwd_by_resetcode(RESETCODE_TEST, PW1_TEST2)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_2(self, card):
|
||||
v = card.verify(1, PW1_TEST2)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_2_2(self, card):
|
||||
v = card.verify(2, PW1_TEST2)
|
||||
assert v
|
||||
|
||||
def test_setup_pw3_1(self, card):
|
||||
r = card.change_passwd(3, PW3_TEST0, PW3_TEST1)
|
||||
assert r
|
||||
|
||||
def test_verify_pw3_1(self, card):
|
||||
v = card.verify(3, PW3_TEST1)
|
||||
assert v
|
||||
|
||||
def test_reset_userpass_admin(self, card):
|
||||
r = card.reset_passwd_by_admin(PW1_TEST3)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_3(self, card):
|
||||
v = card.verify(1, PW1_TEST3)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_3_2(self, card):
|
||||
v = card.verify(2, PW1_TEST3)
|
||||
assert v
|
||||
|
||||
def test_setup_pw1_4(self, card):
|
||||
r = card.change_passwd(1, PW1_TEST3, PW1_TEST4)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_4(self, card):
|
||||
v = card.verify(1, PW1_TEST4)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_4_2(self, card):
|
||||
v = card.verify(2, PW1_TEST4)
|
||||
assert v
|
||||
|
||||
def test_setup_pw3_2(self, card):
|
||||
r = card.change_passwd(3, PW3_TEST1, PW3_TEST0)
|
||||
assert r
|
||||
|
||||
def test_verify_pw3_2(self, card):
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
|
||||
def test_sign_0(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT0)
|
||||
r = card.cmd_pso(0x9e, 0x9a, digestinfo)
|
||||
sig = rsa_keys.compute_signature(0, digestinfo)
|
||||
sig_bytes = sig.to_bytes(int((sig.bit_length()+7)/8), byteorder='big')
|
||||
assert r == sig_bytes
|
||||
|
||||
def test_sign_1(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT1)
|
||||
r = card.cmd_pso(0x9e, 0x9a, digestinfo)
|
||||
sig = rsa_keys.compute_signature(0, digestinfo)
|
||||
sig_bytes = sig.to_bytes(int((sig.bit_length()+7)/8), byteorder='big')
|
||||
assert r == sig_bytes
|
||||
|
||||
def test_ds_counter_1(self, card):
|
||||
c = get_data_object(card, 0x7a)
|
||||
assert c == b'\x93\x03\x00\x00\x02'
|
||||
|
||||
def test_sign_auth_0(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT0)
|
||||
r = card.cmd_internal_authenticate(digestinfo)
|
||||
sig = rsa_keys.compute_signature(2, digestinfo)
|
||||
sig_bytes = sig.to_bytes(int((sig.bit_length()+7)/8), byteorder='big')
|
||||
assert r == sig_bytes
|
||||
|
||||
def test_sign_auth_1(self, card):
|
||||
digestinfo = rsa_keys.compute_digestinfo(PLAIN_TEXT1)
|
||||
r = card.cmd_internal_authenticate(digestinfo)
|
||||
sig = rsa_keys.compute_signature(2, digestinfo)
|
||||
sig_bytes = sig.to_bytes(int((sig.bit_length()+7)/8), byteorder='big')
|
||||
assert r == sig_bytes
|
||||
|
||||
def test_decrypt_0(self, card):
|
||||
ciphertext = rsa_keys.encrypt(1, PLAIN_TEXT0)
|
||||
r = card.cmd_pso(0x80, 0x86, ciphertext)
|
||||
assert r == PLAIN_TEXT0
|
||||
|
||||
def test_decrypt_1(self, card):
|
||||
ciphertext = rsa_keys.encrypt(1, PLAIN_TEXT1)
|
||||
r = card.cmd_pso(0x80, 0x86, ciphertext)
|
||||
assert r == PLAIN_TEXT1
|
||||
82
tests/card_test_personalize_reset.py
Normal file
82
tests/card_test_personalize_reset.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""
|
||||
card_test_personalize_reset.py - test resetting personalization of card
|
||||
|
||||
Copyright (C) 2016, 2018, 2019 g10 Code GmbH
|
||||
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/>.
|
||||
"""
|
||||
|
||||
from struct import pack
|
||||
from re import match, DOTALL
|
||||
from util import *
|
||||
import rsa_keys
|
||||
from card_const import *
|
||||
from constants_for_test import *
|
||||
|
||||
class Test_Personalize_Reset(object):
|
||||
def test_login_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0x5e, b"")
|
||||
assert r
|
||||
|
||||
def test_name_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0x5b, b"")
|
||||
assert r
|
||||
|
||||
def test_lang_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x2d, b"")
|
||||
assert r
|
||||
|
||||
def test_sex_put(self, card):
|
||||
try:
|
||||
# Gnuk
|
||||
r = card.cmd_put_data(0x5f, 0x35, b"")
|
||||
except ValueError:
|
||||
# OpenPGP card which doesn't allow b""
|
||||
r = card.cmd_put_data(0x5f, 0x35, b"9")
|
||||
assert r
|
||||
|
||||
def test_url_put(self, card):
|
||||
r = card.cmd_put_data(0x5f, 0x50, b"")
|
||||
assert r
|
||||
|
||||
def test_pw1_status_put(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xc4, b"\x00")
|
||||
assert r
|
||||
|
||||
def test_setup_pw3_0(self, card):
|
||||
r = card.change_passwd(3, PW3_TEST0, FACTORY_PASSPHRASE_PW3)
|
||||
assert r
|
||||
|
||||
def test_verify_pw3_0(self, card):
|
||||
v = card.verify(3, FACTORY_PASSPHRASE_PW3)
|
||||
assert v
|
||||
|
||||
def test_setup_pw1_0(self, card):
|
||||
r = card.change_passwd(1, PW1_TEST4, FACTORY_PASSPHRASE_PW1)
|
||||
assert r
|
||||
|
||||
def test_verify_pw1_0(self, card):
|
||||
v = card.verify(1, FACTORY_PASSPHRASE_PW1)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_0_2(self, card):
|
||||
v = card.verify(2, FACTORY_PASSPHRASE_PW1)
|
||||
assert v
|
||||
|
||||
def test_delete_reset_code(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xd3, b"")
|
||||
assert r
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
test_remove_keys_card.py - test removing keys on card
|
||||
card_test_remove_keys.py - test removing keys on card
|
||||
|
||||
Copyright (C) 2016 g10 Code GmbH
|
||||
Copyright (C) 2016, 2018, 2019 g10 Code GmbH
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -22,23 +22,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Remove a key material on card by changing algorithm attributes of the key
|
||||
|
||||
KEY_ATTRIBUTES_RSA4K=b"\x01\x10\x00\x00\x20\x00"
|
||||
KEY_ATTRIBUTES_RSA2K=b"\x01\x08\x00\x00\x20\x00"
|
||||
from card_const import *
|
||||
|
||||
def test_rsa_import_key_1(card):
|
||||
r = card.cmd_put_data(0x00, 0xc1, KEY_ATTRIBUTES_RSA4K)
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xc1, KEY_ATTRIBUTES_RSA2K)
|
||||
assert r
|
||||
class Test_Remove_Keys(object):
|
||||
|
||||
def test_rsa_import_key_2(card):
|
||||
r = card.cmd_put_data(0x00, 0xc2, KEY_ATTRIBUTES_RSA4K)
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xc2, KEY_ATTRIBUTES_RSA2K)
|
||||
assert r
|
||||
def test_rsa_keyattr_change_1(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xc1, KEY_ATTRIBUTES_RSA4K)
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xc1, KEY_ATTRIBUTES_RSA2K)
|
||||
assert r
|
||||
|
||||
def test_rsa_import_key_3(card):
|
||||
r = card.cmd_put_data(0x00, 0xc3, KEY_ATTRIBUTES_RSA4K)
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xc3, KEY_ATTRIBUTES_RSA2K)
|
||||
assert r
|
||||
def test_rsa_keyattr_change_2(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xc2, KEY_ATTRIBUTES_RSA4K)
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xc2, KEY_ATTRIBUTES_RSA2K)
|
||||
assert r
|
||||
|
||||
def test_rsa_keyattr_change_3(self, card):
|
||||
r = card.cmd_put_data(0x00, 0xc3, KEY_ATTRIBUTES_RSA4K)
|
||||
if r:
|
||||
r = card.cmd_put_data(0x00, 0xc3, KEY_ATTRIBUTES_RSA2K)
|
||||
assert r
|
||||
46
tests/card_test_reset_pw3.py
Normal file
46
tests/card_test_reset_pw3.py
Normal file
@@ -0,0 +1,46 @@
|
||||
"""
|
||||
card_test_reset_pw3.py - test resetting pw3
|
||||
|
||||
Copyright (C) 2018, 2019 g10 Code GmbH
|
||||
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/>.
|
||||
"""
|
||||
|
||||
from card_const import *
|
||||
import pytest
|
||||
|
||||
class Test_Reset_PW3(object):
|
||||
# Gnuk specific feature of clear PW3
|
||||
def test_setup_pw3_null(self, card):
|
||||
if card.is_gnuk:
|
||||
r = card.change_passwd(3, FACTORY_PASSPHRASE_PW3, None)
|
||||
assert r
|
||||
else:
|
||||
pytest.skip("Gnuk only feature of clearing PW3")
|
||||
|
||||
def test_verify_pw3(self, card):
|
||||
v = card.verify(3, FACTORY_PASSPHRASE_PW3)
|
||||
assert v
|
||||
|
||||
# Check PW1 again to see the possiblity of admin-less mode
|
||||
def test_verify_pw1(self, card):
|
||||
v = card.verify(1, FACTORY_PASSPHRASE_PW1)
|
||||
assert v
|
||||
|
||||
def test_verify_pw1_2(self, card):
|
||||
v = card.verify(2, FACTORY_PASSPHRASE_PW1)
|
||||
assert v
|
||||
52
tests/card_test_x25519.py
Normal file
52
tests/card_test_x25519.py
Normal 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'
|
||||
),
|
||||
)
|
||||
@@ -16,3 +16,4 @@ def card():
|
||||
card.cmd_select_openpgp()
|
||||
yield card
|
||||
del card
|
||||
reader.ccid_power_off()
|
||||
|
||||
21
tests/constants_for_test.py
Normal file
21
tests/constants_for_test.py
Normal file
@@ -0,0 +1,21 @@
|
||||
PW1_TEST0=b"another user pass phrase"
|
||||
PW1_TEST1=b"PASSPHRASE SHOULD BE LONG"
|
||||
PW1_TEST2=b"new user pass phrase"
|
||||
PW1_TEST3=b"next user pass phrase"
|
||||
PW1_TEST4=b"another user pass phrase"
|
||||
PW3_TEST0=b"admin pass phrase"
|
||||
PW3_TEST1=b"another admin pass phrase"
|
||||
|
||||
RESETCODE_TEST=b"example reset code 000"
|
||||
|
||||
PLAIN_TEXT0=b"This is a test message."
|
||||
PLAIN_TEXT1=b"RSA decryption is as easy as pie."
|
||||
PLAIN_TEXT2=b"This is another test message.\nMultiple lines.\n"
|
||||
|
||||
KDF_FULL=b"\x81\x01\x03\x82\x01\x08\x83\x04\x00\xC8\x00\x00\x84\x08\xC5\x1F\xB7\xF9\xEE\xF3\xD3\xE8\x85\x08\x75\x1A\x2A\x70\xC0\x7C\xB1\x81\x86\x08\xE6\xB2\x4E\x0C\xEE\x92\xAB\x93\x87\x20\xA2\x08\x89\x16\x09\xD3\xE4\x3D\x48\xAC\x5B\xAA\xBD\xE9\xF1\xB8\xD2\xFC\xD8\x3C\x5F\x35\xCB\xEB\xDA\xFB\x75\x92\x88\xC6\x8B\x2D\x88\x20\xF1\x34\x00\xD2\x5F\x28\x57\xE6\x66\xAA\x9E\xBB\xE0\x7C\x57\x4B\x84\x8B\xD6\x52\x14\xE7\x31\x99\x1A\x3D\x2D\xAA\x3F\x8A\x7F\x03"
|
||||
KDF_FULL_HASH_PW1=b"\xA2\x08\x89\x16\x09\xD3\xE4\x3D\x48\xAC\x5B\xAA\xBD\xE9\xF1\xB8\xD2\xFC\xD8\x3C\x5F\x35\xCB\xEB\xDA\xFB\x75\x92\x88\xC6\x8B\x2D"
|
||||
KDF_FULL_HASH_PW3=b"\xF1\x34\x00\xD2\x5F\x28\x57\xE6\x66\xAA\x9E\xBB\xE0\x7C\x57\x4B\x84\x8B\xD6\x52\x14\xE7\x31\x99\x1A\x3D\x2D\xAA\x3F\x8A\x7F\x03"
|
||||
|
||||
KDF_SINGLE=b"\x81\x01\x03\x82\x01\x08\x83\x04\x00\xC8\x00\x00\x84\x08\x69\x9E\xDA\xAD\x5A\x72\x5F\x4C\x87\x20\x12\xDB\x16\x9A\x9D\x1A\x56\xCA\x2B\x9E\x96\x7F\xC4\xDA\xB8\xAE\x70\x41\x51\x8E\x3C\xEF\x49\x7E\xC2\x56\x60\x32\x2F\x4C\x03\x07\x88\x20\x1C\x93\x99\xC3\x6D\x49\x92\x27\x54\x39\x76\x7E\xA7\xB4\xEE\xE5\x16\xDA\x92\xC0\x0E\xF4\x74\xBD\x01\x28\x0F\x0C\x30\x45\x4B\xBB"
|
||||
KDF_SINGLE_HASH_PW1=b"\x12\xDB\x16\x9A\x9D\x1A\x56\xCA\x2B\x9E\x96\x7F\xC4\xDA\xB8\xAE\x70\x41\x51\x8E\x3C\xEF\x49\x7E\xC2\x56\x60\x32\x2F\x4C\x03\x07"
|
||||
KDF_SINGLE_HASH_PW3=b"\x1C\x93\x99\xC3\x6D\x49\x92\x27\x54\x39\x76\x7E\xA7\xB4\xEE\xE5\x16\xDA\x92\xC0\x0E\xF4\x74\xBD\x01\x28\x0F\x0C\x30\x45\x4B\xBB"
|
||||
108
tests/func_pso_auth.py
Normal file
108
tests/func_pso_auth.py
Normal 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
|
||||
1
tests/kdf_calc.py
Symbolic link
1
tests/kdf_calc.py
Symbolic link
@@ -0,0 +1 @@
|
||||
../tool/kdf_calc.py
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
openpgp_card.py - a library for OpenPGP card
|
||||
|
||||
Copyright (C) 2011, 2012, 2013, 2015, 2016
|
||||
Copyright (C) 2011, 2012, 2013, 2015, 2016, 2018, 2019
|
||||
Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
@@ -21,7 +21,8 @@ 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 struct import pack
|
||||
from struct import pack, unpack
|
||||
from kdf_calc import kdf_calc
|
||||
|
||||
def iso7816_compose(ins, p1, p2, data, cls=0x00, le=None):
|
||||
data_len = len(data)
|
||||
@@ -54,6 +55,85 @@ class OpenPGP_Card(object):
|
||||
"""
|
||||
|
||||
self.__reader = reader
|
||||
self.__kdf_iters = None
|
||||
self.__kdf_salt_user = None
|
||||
self.__kdf_salt_reset = None
|
||||
self.__kdf_salt_admin = None
|
||||
self.is_gnuk = (reader.get_string(2) == "Gnuk Token")
|
||||
self.is_emulated_gnuk = (reader.get_string(3)[-8:] == "EMULATED")
|
||||
|
||||
def configure_with_kdf(self):
|
||||
kdf_data = self.cmd_get_data(0x00, 0xf9)
|
||||
if kdf_data != b"":
|
||||
algo, subalgo, iters, salt_user, salt_reset, salt_admin, hash_user, hash_admin = parse_kdf_data(kdf_data)
|
||||
self.__kdf_iters = iters
|
||||
self.__kdf_salt_user = salt_user
|
||||
self.__kdf_salt_reset = salt_reset
|
||||
self.__kdf_salt_admin = salt_admin
|
||||
else:
|
||||
self.__kdf_iters = None
|
||||
self.__kdf_salt_user = None
|
||||
self.__kdf_salt_reset = None
|
||||
self.__kdf_salt_admin = None
|
||||
|
||||
# Higher layer VERIFY possibly using KDF Data Object
|
||||
def verify(self, who, passwd):
|
||||
if self.__kdf_iters:
|
||||
salt = self.__kdf_salt_user
|
||||
if who == 3 and self.__kdf_salt_admin:
|
||||
salt = self.__kdf_salt_admin
|
||||
pw_hash = kdf_calc(passwd, salt, self.__kdf_iters)
|
||||
return self.cmd_verify(who, pw_hash)
|
||||
else:
|
||||
return self.cmd_verify(who, passwd)
|
||||
|
||||
# Higher layer CHANGE_PASSWD possibly using KDF Data Object
|
||||
def change_passwd(self, who, passwd_old, passwd_new):
|
||||
if self.__kdf_iters:
|
||||
salt = self.__kdf_salt_user
|
||||
if who == 3 and self.__kdf_salt_admin:
|
||||
salt = self.__kdf_salt_admin
|
||||
hash_old = kdf_calc(passwd_old, salt, self.__kdf_iters)
|
||||
if passwd_new:
|
||||
hash_new = kdf_calc(passwd_new, salt, self.__kdf_iters)
|
||||
else:
|
||||
hash_new = b""
|
||||
return self.cmd_change_reference_data(who, hash_old + hash_new)
|
||||
else:
|
||||
if not passwd_new:
|
||||
passwd_new = b""
|
||||
return self.cmd_change_reference_data(who, passwd_old + passwd_new)
|
||||
|
||||
# Higher layer SETUP_RESET_CODE possibly using KDF Data Object
|
||||
def setup_reset_code(self, resetcode):
|
||||
if self.__kdf_iters:
|
||||
salt = self.__kdf_salt_user
|
||||
if self.__kdf_salt_reset:
|
||||
salt = self.__kdf_salt_user
|
||||
reset_hash = kdf_calc(resetcode, salt, self.__kdf_iters)
|
||||
return self.cmd_put_data(0x00, 0xd3, reset_hash)
|
||||
else:
|
||||
return self.cmd_put_data(0x00, 0xd3, resetcode)
|
||||
|
||||
# Higher layer reset passwd possibly using KDF Data Object
|
||||
def reset_passwd_by_resetcode(self, resetcode, pw1):
|
||||
if self.__kdf_iters:
|
||||
salt = self.__kdf_salt_user
|
||||
if self.__kdf_salt_reset:
|
||||
salt = self.__kdf_salt_user
|
||||
reset_hash = kdf_calc(resetcode, salt, self.__kdf_iters)
|
||||
pw1_hash = kdf_calc(pw1, self.__kdf_salt_user, self.__kdf_iters)
|
||||
return self.cmd_reset_retry_counter(0, 0x81, reset_hash + pw1_hash)
|
||||
else:
|
||||
return self.cmd_reset_retry_counter(0, 0x81, resetcode + pw1)
|
||||
|
||||
# Higher layer reset passwd possibly using KDF Data Object
|
||||
def reset_passwd_by_admin(self, pw1):
|
||||
if self.__kdf_iters:
|
||||
pw1_hash = kdf_calc(pw1, self.__kdf_salt_user, self.__kdf_iters)
|
||||
return self.cmd_reset_retry_counter(2, 0x81, pw1_hash)
|
||||
else:
|
||||
return self.cmd_reset_retry_counter(2, 0x81, pw1)
|
||||
|
||||
def cmd_get_response(self, expected_len):
|
||||
result = b""
|
||||
@@ -260,16 +340,20 @@ class OpenPGP_Card(object):
|
||||
data = b'\xb8\x00'
|
||||
else:
|
||||
data = b'\xa4\x00'
|
||||
cmd_data = iso7816_compose(0x47, 0x80, 0, data)
|
||||
if self.__reader.is_tpdu_reader():
|
||||
cmd_data = iso7816_compose(0x47, 0x80, 0, data, le=512)
|
||||
else:
|
||||
cmd_data = iso7816_compose(0x47, 0x80, 0, data)
|
||||
sw = self.__reader.send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
if len(sw) < 2:
|
||||
raise ValueError(sw)
|
||||
if sw[0] == 0x90 and sw[1] == 0x00:
|
||||
return b""
|
||||
elif sw[0] != 0x61:
|
||||
if sw[-2] == 0x61:
|
||||
pk = self.cmd_get_response(sw[1])
|
||||
elif sw[-2] == 0x90 and sw[-1] == 0x00:
|
||||
pk = sw
|
||||
else:
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
pk = self.cmd_get_response(sw[1])
|
||||
return (pk[9:9+256], pk[9+256+2:9+256+2+3])
|
||||
return (pk[9:9+256], pk[9+256+2:-2])
|
||||
|
||||
def cmd_get_public_key(self, keyno):
|
||||
if keyno == 1:
|
||||
@@ -280,10 +364,9 @@ class OpenPGP_Card(object):
|
||||
data = b'\xa4\x00'
|
||||
if self.__reader.is_tpdu_reader():
|
||||
cmd_data = iso7816_compose(0x47, 0x81, 0, data, le=512)
|
||||
r = self.__reader.send_cmd(cmd_data)
|
||||
else:
|
||||
cmd_data = iso7816_compose(0x47, 0x81, 0, data)
|
||||
r = self.__reader.send_cmd(cmd_data)
|
||||
r = self.__reader.send_cmd(cmd_data)
|
||||
if len(r) < 2:
|
||||
raise ValueError(r)
|
||||
sw = r[-2:]
|
||||
@@ -336,3 +419,48 @@ class OpenPGP_Card(object):
|
||||
raise ValueError(sw)
|
||||
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
|
||||
def parse_kdf_data(kdf_data):
|
||||
if len(kdf_data) == 90:
|
||||
single_salt = True
|
||||
elif len(kdf_data) == 110:
|
||||
single_salt = False
|
||||
else:
|
||||
raise ValueError("length does not much", kdf_data)
|
||||
|
||||
if kdf_data[0:2] != b'\x81\x01':
|
||||
raise ValueError("data does not much")
|
||||
algo = kdf_data[2]
|
||||
if kdf_data[3:5] != b'\x82\x01':
|
||||
raise ValueError("data does not much")
|
||||
subalgo = kdf_data[5]
|
||||
if kdf_data[6:8] != b'\x83\x04':
|
||||
raise ValueError("data does not much")
|
||||
iters = unpack(">I", kdf_data[8:12])[0]
|
||||
if kdf_data[12:14] != b'\x84\x08':
|
||||
raise ValueError("data does not much")
|
||||
salt = kdf_data[14:22]
|
||||
if single_salt:
|
||||
salt_reset = None
|
||||
salt_admin = None
|
||||
if kdf_data[22:24] != b'\x87\x20':
|
||||
raise ValueError("data does not much")
|
||||
hash_user = kdf_data[24:56]
|
||||
if kdf_data[56:58] != b'\x88\x20':
|
||||
raise ValueError("data does not much")
|
||||
hash_admin = kdf_data[58:90]
|
||||
else:
|
||||
if kdf_data[22:24] != b'\x85\x08':
|
||||
raise ValueError("data does not much")
|
||||
salt_reset = kdf_data[24:32]
|
||||
if kdf_data[32:34] != b'\x86\x08':
|
||||
raise ValueError("data does not much")
|
||||
salt_admin = kdf_data[34:42]
|
||||
if kdf_data[42:44] != b'\x87\x20':
|
||||
raise ValueError("data does not much")
|
||||
hash_user = kdf_data[44:76]
|
||||
if kdf_data[76:78] != b'\x88\x20':
|
||||
raise ValueError("data does not much")
|
||||
hash_admin = kdf_data[78:110]
|
||||
return ( algo, subalgo, iters, salt, salt_reset, salt_admin,
|
||||
hash_user, hash_admin )
|
||||
|
||||
@@ -70,11 +70,11 @@ def build_privkey_template_for_remove(openpgp_keyno):
|
||||
keyspec = b'\xb8'
|
||||
else:
|
||||
keyspec = b'\xa4'
|
||||
return b'\x4d\02' + keyspec + b'\0x00'
|
||||
return b'\x4d\x02' + keyspec + b'\x00'
|
||||
|
||||
def compute_digestinfo(msg):
|
||||
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
|
||||
|
||||
# egcd and modinv are from wikibooks
|
||||
|
||||
6
tests/skip_gnuk_only_tests.py
Normal file
6
tests/skip_gnuk_only_tests.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture(scope="module",autouse=True)
|
||||
def check_gnuk(card):
|
||||
if not card.is_gnuk:
|
||||
pytest.skip("Gnuk only feature", allow_module_level=True)
|
||||
6
tests/skip_if_emulation.py
Normal file
6
tests/skip_if_emulation.py
Normal 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)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user