Compare commits
17 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa69a85826 | ||
|
|
5c3c3e3001 | ||
|
|
6dcb4dd027 | ||
|
|
fa08f44cac | ||
|
|
4c2294ea6c | ||
|
|
86eaa26d32 | ||
|
|
9e52789203 | ||
|
|
702bc8cbde | ||
|
|
2cfce76d91 | ||
|
|
207652246a | ||
|
|
32779b6f96 | ||
|
|
55c1015faa | ||
|
|
0932465f0b | ||
|
|
4417799a51 | ||
|
|
b424cecf1e | ||
|
|
7ef417ae36 | ||
|
|
d4469c24ec |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ regnual/regnual.elf
|
|||||||
doc/_build
|
doc/_build
|
||||||
tests/.cache
|
tests/.cache
|
||||||
tests/__pycache__
|
tests/__pycache__
|
||||||
|
emulation/gnuk_emulation
|
||||||
|
|||||||
54
ChangeLog
54
ChangeLog
@@ -1,3 +1,57 @@
|
|||||||
|
2017-05-12 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* VERSION: 1.2.4.
|
||||||
|
|
||||||
|
2017-04-28 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/mcu-stm32f103.c: New.
|
||||||
|
(check_crc32, sram_address): New.
|
||||||
|
|
||||||
|
* src/usb_ctrl.c (download_check_crc32): Use check_crc32 and
|
||||||
|
sram_address.
|
||||||
|
|
||||||
|
* src/openpgp-do.c (gpg_write_digital_signature_counter): Fix
|
||||||
|
writing lower 10-bit.
|
||||||
|
|
||||||
|
2017-04-27 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/gnuk.ld.in (_data_pool): Move to the end.
|
||||||
|
|
||||||
|
* src/flash.c (flash_init): Return address of end of data object.
|
||||||
|
* src/openpgp.c (gpg_init): Get address of end of data object.
|
||||||
|
* src/openpgp-do.c (gpg_data_scan): Check the end address.
|
||||||
|
|
||||||
|
2017-02-02 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* VERSION: 1.2.3.
|
||||||
|
|
||||||
|
* src/gnuk.ld.in (__process1_stack_size__): Increase by 0x20.
|
||||||
|
* chopstx: Update to 1.3.
|
||||||
|
* src/configure: Add BLUE_PILL in the help message.
|
||||||
|
|
||||||
|
2017-02-01 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* README: Update README. Thanks to Paul Fertser.
|
||||||
|
|
||||||
|
2017-01-02 Szczepan Zalega <szczepan@nitrokey.com>
|
||||||
|
|
||||||
|
* tool/upgrade_by_passwd.py: Add file extention check.
|
||||||
|
|
||||||
|
2017-02-01 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* tool/upgrade_by_passwd.py (main): More verbose messages
|
||||||
|
suggested by Szczepan Zalega <szczepan@nitrokey.com>.
|
||||||
|
|
||||||
|
* tool/gnuk_token.py (USB_PRODUCT_LIST): New.
|
||||||
|
(gnuk_devices_by_vidpid): Support searching by USB_PRODUCT_LIST.
|
||||||
|
Thanks to Szczepan Zalega <szczepan@nitrokey.com>.
|
||||||
|
|
||||||
|
* tool/usb_strings.py: Use gnuk_token.py.
|
||||||
|
|
||||||
|
2016-10-21 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
* src/ecc.c (check_secret): Fix condition.
|
||||||
|
|
||||||
2016-10-15 NIIBE Yutaka <gniibe@fsij.org>
|
2016-10-15 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* VERSION: 1.2.2.
|
* VERSION: 1.2.2.
|
||||||
|
|||||||
21
NEWS
21
NEWS
@@ -1,5 +1,26 @@
|
|||||||
Gnuk NEWS - User visible changes
|
Gnuk NEWS - User visible changes
|
||||||
|
|
||||||
|
* Major changes in Gnuk 1.2.4
|
||||||
|
|
||||||
|
Released 2017-05-12, by NIIBE Yutaka
|
||||||
|
|
||||||
|
** Flash ROM security fix
|
||||||
|
The partial content of flash ROM might be exposed when scanning of
|
||||||
|
data object had a problem. Added boundary check and changed layout of
|
||||||
|
flash ROM.
|
||||||
|
|
||||||
|
|
||||||
|
* Major changes in Gnuk 1.2.3
|
||||||
|
|
||||||
|
Released 2017-02-02, by NIIBE Yutaka
|
||||||
|
|
||||||
|
** ECC key generation on the device
|
||||||
|
Bug fixed.
|
||||||
|
|
||||||
|
** Upgrade of Chopstx
|
||||||
|
We use Chopstx 1.3.
|
||||||
|
|
||||||
|
|
||||||
* Major changes in Gnuk 1.2.2
|
* Major changes in Gnuk 1.2.2
|
||||||
|
|
||||||
Released 2016-10-15, by NIIBE Yutaka
|
Released 2016-10-15, by NIIBE Yutaka
|
||||||
|
|||||||
83
README
83
README
@@ -1,14 +1,14 @@
|
|||||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||||
|
|
||||||
Version 1.2.2
|
Version 1.2.4
|
||||||
2016-10-15
|
2017-05-12
|
||||||
Niibe Yutaka
|
Niibe Yutaka
|
||||||
Free Software Initiative of Japan
|
Free Software Initiative of Japan
|
||||||
|
|
||||||
Release Notes
|
Release Notes
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the release of Gnuk, version 1.2.2, which has major
|
This is the release of Gnuk, version 1.2.4, which has major
|
||||||
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
||||||
overriding key import, but importing keys (or generating keys) results
|
overriding key import, but importing keys (or generating keys) results
|
||||||
password reset. Please update your documentation for Gnuk Token, so
|
password reset. Please update your documentation for Gnuk Token, so
|
||||||
@@ -47,7 +47,7 @@ FAQ
|
|||||||
|
|
||||||
Q0: How Gnuk USB Token is superior than other solutions (OpenPGP
|
Q0: How Gnuk USB Token is superior than other solutions (OpenPGP
|
||||||
card 2.0, YubiKey, etc.) ?
|
card 2.0, YubiKey, etc.) ?
|
||||||
http://www.g10code.de/p-card.html
|
https://www.g10code.de/p-card.html
|
||||||
https://www.yubico.com/
|
https://www.yubico.com/
|
||||||
A0: Good points of Gnuk are:
|
A0: Good points of Gnuk are:
|
||||||
* If you have skill of electronics and like DIY, you can build
|
* If you have skill of electronics and like DIY, you can build
|
||||||
@@ -77,12 +77,12 @@ A3: Orthodox choice is Olimex STM32-H103.
|
|||||||
choice for experiment.
|
choice for experiment.
|
||||||
|
|
||||||
Q4: What's version of GnuPG are you using?
|
Q4: What's version of GnuPG are you using?
|
||||||
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.13 in
|
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.18 in
|
||||||
experimental.
|
unstable.
|
||||||
|
|
||||||
Q5: What's version of pcscd and libccid are you using?
|
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
|
A5: I don't use them, pcscd and libccid are optional, you can use Gnuk
|
||||||
without them.
|
Token without them.
|
||||||
I tested pcscd 1.5.5-4 and libccid 1.3.11-2 which were in Debian
|
I tested pcscd 1.5.5-4 and libccid 1.3.11-2 which were in Debian
|
||||||
squeeze.
|
squeeze.
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ External source code
|
|||||||
|
|
||||||
Gnuk is distributed with external source code.
|
Gnuk is distributed with external source code.
|
||||||
|
|
||||||
* chopstx/ -- Chopstx 1.1
|
* chopstx/ -- Chopstx 1.3
|
||||||
|
|
||||||
We use Chopstx as the kernel for Gnuk.
|
We use Chopstx as the kernel for Gnuk.
|
||||||
|
|
||||||
@@ -361,10 +361,10 @@ You need GNU toolchain and newlib for 'arm-none-eabi' target.
|
|||||||
On Debian we can install the packages of gcc-arm-none-eabi,
|
On Debian we can install the packages of gcc-arm-none-eabi,
|
||||||
gdb-arm-none-eabi and its friends. I'm using:
|
gdb-arm-none-eabi and its friends. I'm using:
|
||||||
|
|
||||||
binutils-arm-none-eabi 2.26-4+8
|
binutils-arm-none-eabi 2.28-4+9+b2
|
||||||
gcc-arm-none-eabi 15:4.9.3+svn231177-1
|
gcc-arm-none-eabi 15:5.4.1+svn241155-1
|
||||||
gdb-arm-none-eabi 7.10-1+9
|
gdb-arm-none-eabi 7.12-6+9+b2
|
||||||
libnewlib-arm-none-eabi 2.2.0+git20150830.5a3d536-1
|
libnewlib-arm-none-eabi 2.4.0.20160527-2
|
||||||
|
|
||||||
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
||||||
GNU Toolchain for 'arm-none-eabi' target.
|
GNU Toolchain for 'arm-none-eabi' target.
|
||||||
@@ -395,18 +395,14 @@ How to install
|
|||||||
Olimex STM32-H103 board
|
Olimex STM32-H103 board
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
If you are using Olimex JTAG-Tiny, type following to invoke OpenOCD:
|
If you are using Olimex JTAG-Tiny, type following to invoke OpenOCD
|
||||||
|
and write "gnuk.elf" to Flash ROM:
|
||||||
|
|
||||||
$ openocd -f interface/ftdi/olimex-jtag-tiny.cfg -f board/olimex_stm32_h103.cfg
|
$ openocd -f interface/ftdi/olimex-jtag-tiny.cfg \
|
||||||
|
-f board/olimex_stm32_h103.cfg \
|
||||||
|
-c "program build/gnuk.elf verify reset exit"
|
||||||
|
|
||||||
Then, with another terminal, type following to write "gnuk.elf" to Flash ROM:
|
Command invocation is assumed in src/ directory.
|
||||||
|
|
||||||
$ telnet localhost 4444
|
|
||||||
> reset halt
|
|
||||||
> flash write_image erase gnuk.elf
|
|
||||||
> reset
|
|
||||||
> exit
|
|
||||||
$
|
|
||||||
|
|
||||||
|
|
||||||
Flying Stone Tiny 01
|
Flying Stone Tiny 01
|
||||||
@@ -414,9 +410,10 @@ Flying Stone Tiny 01
|
|||||||
|
|
||||||
If you are using Flying Stone Tiny 01, you need a SWD writer.
|
If you are using Flying Stone Tiny 01, you need a SWD writer.
|
||||||
|
|
||||||
OpenOCD 0.9 now supports ST-Link/V2. We can use it:
|
OpenOCD 0.9.0 now supports ST-Link/V2. We can use it like:
|
||||||
|
|
||||||
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x_stlink.cfg
|
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
|
||||||
|
-c "program build/gnuk.elf verify reset exit"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -435,20 +432,24 @@ Then, reset the board.
|
|||||||
How to protect flash ROM
|
How to protect flash ROM
|
||||||
========================
|
========================
|
||||||
|
|
||||||
Invoke your OpenOCD and type:
|
To protect, invoke OpenOCD like (for FST-01):
|
||||||
|
|
||||||
$ telnet localhost 4444
|
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \
|
||||||
> reset halt
|
-c init -c "reset halt" -c "stm32f1x lock 0" -c reset -c exit
|
||||||
> stm32f1x lock 0
|
|
||||||
> reset
|
|
||||||
> shutdown
|
|
||||||
|
|
||||||
After power-off / power-on sequence, the contents of flash ROM cannot
|
After power-off / power-on sequence, the contents of flash ROM cannot
|
||||||
be accessible from JTAG debugger.
|
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
|
Note that it would be still possible for some implementation of DfuSe
|
||||||
to access the contents. If you want to protect, killing DfuSe and
|
to access the contents, even if it's protected. If you really want to
|
||||||
accessing by JTAG debugger is recommended.
|
protect, killing DfuSe and accessing by JTAG debugger is recommended.
|
||||||
|
|
||||||
|
|
||||||
(Optional) Configure serial number and X.509 certificate
|
(Optional) Configure serial number and X.509 certificate
|
||||||
@@ -551,6 +552,10 @@ Inside GDB, we can connect OpenOCD by:
|
|||||||
|
|
||||||
(gdb) target remote localhost:3333
|
(gdb) target remote localhost:3333
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
(gdb) target extended-remote localhost:3333
|
||||||
|
|
||||||
|
|
||||||
You can see the output of PCSCD:
|
You can see the output of PCSCD:
|
||||||
|
|
||||||
@@ -582,14 +587,14 @@ 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:
|
I put Chopstx as a submodule of Git. Please do this:
|
||||||
|
|
||||||
$ git submodule init
|
$ git submodule update --init
|
||||||
$ git submodule update
|
|
||||||
|
|
||||||
We have migrated from ChibiOS/RT to Chopstx in Gnuk 1.1. If you have
|
Gnuk 1.0 uses ChibiOS/RT, and then, we have migrated from to Chopstx
|
||||||
old code of ChibiOS/RT, you need:
|
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
|
Edit .git/config to remove chibios reference and
|
||||||
git rm --cached chibios
|
$ git rm --cached chibios
|
||||||
|
|
||||||
|
|
||||||
Information on the Web
|
Information on the Web
|
||||||
@@ -599,7 +604,7 @@ Please visit: http://www.fsij.org/gnuk/
|
|||||||
|
|
||||||
Please see the FST-01 support pages:
|
Please see the FST-01 support pages:
|
||||||
|
|
||||||
http://www.gniibe.org/category/fst-01.html
|
https://www.gniibe.org/category/fst-01.html
|
||||||
|
|
||||||
Please consider to join Gnuk-users mailing list:
|
Please consider to join Gnuk-users mailing list:
|
||||||
|
|
||||||
|
|||||||
2
THANKS
2
THANKS
@@ -29,9 +29,11 @@ NAGAMI Takeshi nagami-takeshi@aist.go.jp
|
|||||||
Nguyễn Hồng Quân quannguyen@mbm.vn
|
Nguyễn Hồng Quân quannguyen@mbm.vn
|
||||||
Nico Rikken nico@nicorikken.eu
|
Nico Rikken nico@nicorikken.eu
|
||||||
NOKUBI Takatsugu knok@daionet.gr.jp
|
NOKUBI Takatsugu knok@daionet.gr.jp
|
||||||
|
Paul Fertser
|
||||||
Paul Bakker polarssl_maintainer@polarssl.org
|
Paul Bakker polarssl_maintainer@polarssl.org
|
||||||
Santiago Ruano Rincón santiago@debian.org
|
Santiago Ruano Rincón santiago@debian.org
|
||||||
Shane Coughlan scoughlan@openinventionnetwork.com
|
Shane Coughlan scoughlan@openinventionnetwork.com
|
||||||
|
Szczepan Zalega szczepan@nitrokey.com
|
||||||
Vasily Evseenko
|
Vasily Evseenko
|
||||||
Werner Koch wk@gnupg.org
|
Werner Koch wk@gnupg.org
|
||||||
Yuji Imai ug@xcast.jp
|
Yuji Imai ug@xcast.jp
|
||||||
|
|||||||
2
chopstx
2
chopstx
Submodule chopstx updated: d448d3c678...89eb54929e
@@ -50,39 +50,9 @@ With the script below, I extract public key of the keygrip
|
|||||||
|
|
||||||
$ ./get_raw_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
|
$ ./get_raw_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
|
||||||
|
|
||||||
Here is the script, get_raw_public_key.py::
|
(The script is available in the directory gnuk/tool. Please note that
|
||||||
|
it was written in the early stage of the development. The quality of
|
||||||
#! /usr/bin/python
|
the code is somewhat questionable.)
|
||||||
|
|
||||||
import sys, binascii
|
|
||||||
from subprocess import check_output
|
|
||||||
|
|
||||||
def get_gpg_public_key(keygrip):
|
|
||||||
result = check_output(["gpg-connect-agent", "READKEY %s" % keygrip, "/bye"])
|
|
||||||
key = ""
|
|
||||||
while True:
|
|
||||||
i = result.find('%')
|
|
||||||
if i < 0:
|
|
||||||
key += result
|
|
||||||
break
|
|
||||||
hex_str = result[i+1:i+3]
|
|
||||||
key += result[0:i]
|
|
||||||
key += chr(int(hex_str,16))
|
|
||||||
result = result[i+3:]
|
|
||||||
|
|
||||||
pos = key.index("D (10:public-key(3:rsa(1:n257:") + 31 # skip NUL too
|
|
||||||
key = key[pos:-17] # )(1:e3:XYZ)))\nOK\n
|
|
||||||
if len(key) != 256:
|
|
||||||
raise ValueError, binascii.hexlify(key)
|
|
||||||
return key
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
keygrip = sys.argv[1]
|
|
||||||
k = get_gpg_public_key(keygrip)
|
|
||||||
shorthand = keygrip[0:8] + ".bin"
|
|
||||||
f = open(shorthand,"w")
|
|
||||||
f.write(k)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
|
|
||||||
Then, we can put the data of public key into token by::
|
Then, we can put the data of public key into token by::
|
||||||
|
|||||||
31
emulation/Makefile
Normal file
31
emulation/Makefile
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
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 $@
|
||||||
54
emulation/glue.c
Normal file
54
emulation/glue.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#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;
|
||||||
103
emulation/usb-emu.c
Normal file
103
emulation/usb-emu.c
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
278
emulation/usbip-server.c
Normal file
278
emulation/usbip-server.c
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
@@ -8,8 +8,8 @@ CHOPSTX = ../chopstx
|
|||||||
# Define linker script file here
|
# Define linker script file here
|
||||||
LDSCRIPT= gnuk.ld
|
LDSCRIPT= gnuk.ld
|
||||||
|
|
||||||
CSRC = main.c usb_desc.c usb_ctrl.c \
|
CSRC = main.c call-rsa.c mcu-stm32f103.c \
|
||||||
call-rsa.c \
|
usb_desc.c usb_ctrl.c \
|
||||||
usb-ccid.c openpgp.c ac.c openpgp-do.c flash.c \
|
usb-ccid.c openpgp.c ac.c openpgp-do.c flash.c \
|
||||||
bn.c mod.c \
|
bn.c mod.c \
|
||||||
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
|
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
|
||||||
|
|||||||
9
src/configure
vendored
9
src/configure
vendored
@@ -6,7 +6,7 @@ nl=$'\n'
|
|||||||
#
|
#
|
||||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||||
#
|
#
|
||||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||||
# Free Software Initiative of Japan
|
# Free Software Initiative of Japan
|
||||||
#
|
#
|
||||||
# This file is a part of Gnuk, a GnuPG USB Token implementation.
|
# This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
@@ -118,14 +118,15 @@ Configuration:
|
|||||||
FST_01
|
FST_01
|
||||||
FST_01G
|
FST_01G
|
||||||
OLIMEX_STM32_H103
|
OLIMEX_STM32_H103
|
||||||
STM32_PRIMER2
|
|
||||||
STBEE
|
|
||||||
STBEE_MINI
|
|
||||||
MAPLE_MINI
|
MAPLE_MINI
|
||||||
ST_DONGLE
|
ST_DONGLE
|
||||||
ST_NUCLEO_F103
|
ST_NUCLEO_F103
|
||||||
NITROKEY_START
|
NITROKEY_START
|
||||||
|
BLUE_PILL
|
||||||
CQ_STARM
|
CQ_STARM
|
||||||
|
STM32_PRIMER2
|
||||||
|
STBEE
|
||||||
|
STBEE_MINI
|
||||||
FST_01_00 (unreleased version with 8MHz XTAL)
|
FST_01_00 (unreleased version with 8MHz XTAL)
|
||||||
--enable-debug debug with virtual COM port [no]
|
--enable-debug debug with virtual COM port [no]
|
||||||
--enable-pinpad=cir
|
--enable-pinpad=cir
|
||||||
|
|||||||
@@ -384,7 +384,7 @@ FUNC(check_secret) (const bn256 *d0, bn256 *d1)
|
|||||||
{
|
{
|
||||||
ac Q0[1], Q1[1];
|
ac Q0[1], Q1[1];
|
||||||
|
|
||||||
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) <= 0)
|
if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) != 0)
|
||||||
/* == 0 or >= N, it's not valid. */
|
/* == 0 or >= N, it's not valid. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
16
src/flash.c
16
src/flash.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
|
* flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||||
* Free Software Initiative of Japan
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
@@ -102,8 +102,8 @@ static int key_available_at (const uint8_t *k, int key_size)
|
|||||||
|
|
||||||
|
|
||||||
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
|
#define CHIP_ID_REG ((uint32_t *)0xe0042000)
|
||||||
const uint8_t *
|
void
|
||||||
flash_init (void)
|
flash_init (const uint8_t **p_do_start, const uint8_t **p_do_end)
|
||||||
{
|
{
|
||||||
uint16_t gen0, gen1;
|
uint16_t gen0, gen1;
|
||||||
uint16_t *gen0_p = (uint16_t *)&_data_pool;
|
uint16_t *gen0_p = (uint16_t *)&_data_pool;
|
||||||
@@ -121,8 +121,11 @@ flash_init (void)
|
|||||||
gen1 = *gen1_p;
|
gen1 = *gen1_p;
|
||||||
|
|
||||||
if (gen0 == 0xffff && gen1 == 0xffff)
|
if (gen0 == 0xffff && gen1 == 0xffff)
|
||||||
/* It's terminated. */
|
{
|
||||||
return NULL;
|
/* It's terminated. */
|
||||||
|
*p_do_start = *p_do_end = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (gen0 == 0xffff)
|
if (gen0 == 0xffff)
|
||||||
/* Use another page if a page is erased. */
|
/* Use another page if a page is erased. */
|
||||||
@@ -134,7 +137,8 @@ flash_init (void)
|
|||||||
/* When both pages have valid header, use newer page. */
|
/* When both pages have valid header, use newer page. */
|
||||||
data_pool = &_data_pool + flash_page_size;
|
data_pool = &_data_pool + flash_page_size;
|
||||||
|
|
||||||
return data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
*p_do_start = data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||||
|
*p_do_end = data_pool + flash_page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *flash_key_getpage (enum kind_of_key kk);
|
static uint8_t *flash_key_getpage (enum kind_of_key kk);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ extern uint16_t data_objects_number_of_bytes;
|
|||||||
|
|
||||||
#define CHALLENGE_LEN 32
|
#define CHALLENGE_LEN 32
|
||||||
|
|
||||||
void gpg_data_scan (const uint8_t *p);
|
void gpg_data_scan (const uint8_t *start, const uint8_t *end);
|
||||||
void gpg_data_copy (const uint8_t *p);
|
void gpg_data_copy (const uint8_t *p);
|
||||||
void gpg_do_terminate (void);
|
void gpg_do_terminate (void);
|
||||||
void gpg_do_get_data (uint16_t tag, int with_tag);
|
void gpg_do_get_data (uint16_t tag, int with_tag);
|
||||||
@@ -139,7 +139,7 @@ enum size_of_key {
|
|||||||
int gpg_get_algo_attr (enum kind_of_key kk);
|
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);
|
int gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s);
|
||||||
|
|
||||||
const uint8_t *flash_init (void);
|
void flash_init (const uint8_t **, const uint8_t **);
|
||||||
void flash_terminate (void);
|
void flash_terminate (void);
|
||||||
void flash_activate (void);
|
void flash_activate (void);
|
||||||
void flash_init_keys (void);
|
void flash_init_keys (void);
|
||||||
@@ -459,3 +459,6 @@ int pinpad_getline (int msg_code, uint32_t timeout_usec);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern uint8_t _regnual_start, __heap_end__[];
|
extern uint8_t _regnual_start, __heap_end__[];
|
||||||
|
|
||||||
|
int check_crc32 (const uint32_t *start_p, const uint32_t *end_p);
|
||||||
|
uint8_t * sram_address (uint32_t offset);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
__main_stack_size__ = 0x0080; /* Exception handlers */
|
__main_stack_size__ = 0x0080; /* Exception handlers */
|
||||||
__process0_stack_size__ = 0x0100; /* main */
|
__process0_stack_size__ = 0x0100; /* main */
|
||||||
__process1_stack_size__ = 0x0180; /* ccid */
|
__process1_stack_size__ = 0x01a0; /* ccid */
|
||||||
__process2_stack_size__ = 0x0180; /* rng */
|
__process2_stack_size__ = 0x0180; /* rng */
|
||||||
__process3_stack_size__ = 0x1640; /* gpg */
|
__process3_stack_size__ = 0x1640; /* gpg */
|
||||||
__process4_stack_size__ = 0; /* --- */
|
__process4_stack_size__ = 0; /* --- */
|
||||||
@@ -171,10 +171,6 @@ SECTIONS
|
|||||||
.gnuk_flash :
|
.gnuk_flash :
|
||||||
{
|
{
|
||||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||||
_data_pool = .;
|
|
||||||
KEEP(*(.gnuk_data))
|
|
||||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
|
||||||
. += @FLASH_PAGE_SIZE@;
|
|
||||||
_keystore_pool = .;
|
_keystore_pool = .;
|
||||||
. += 512;
|
. += 512;
|
||||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||||
@@ -185,6 +181,10 @@ SECTIONS
|
|||||||
_updatekey_store = .;
|
_updatekey_store = .;
|
||||||
. += 1024;
|
. += 1024;
|
||||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||||
|
_data_pool = .;
|
||||||
|
KEEP(*(.gnuk_data))
|
||||||
|
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||||
|
. += @FLASH_PAGE_SIZE@;
|
||||||
} > flash =0xffffffff
|
} > flash =0xffffffff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
56
src/mcu-stm32f103.c
Normal file
56
src/mcu-stm32f103.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* mcu-stm32f103.c - STM32F103 specific routines
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017
|
||||||
|
* Free Software Initiative of Japan
|
||||||
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
*
|
||||||
|
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
|
*
|
||||||
|
* Gnuk is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mcu/stm32f103.h"
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return ((uint8_t *)0x20000000) + offset;
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
|
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||||
* Free Software Initiative of Japan
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
@@ -336,7 +336,7 @@ gpg_write_digital_signature_counter (const uint8_t *p, uint32_t dsc)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
|
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
|
||||||
hw1 = NR_COUNTER_DS_LSB;
|
hw1 = NR_COUNTER_DS_LSB | ((dsc & 0x0300) >> 8) | ((dsc & 0x00ff) << 8);
|
||||||
flash_put_data_internal (p, hw0);
|
flash_put_data_internal (p, hw0);
|
||||||
flash_put_data_internal (p+2, hw1);
|
flash_put_data_internal (p+2, hw1);
|
||||||
return p+4;
|
return p+4;
|
||||||
@@ -1543,7 +1543,7 @@ gpg_do_table[] = {
|
|||||||
* Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc.
|
* Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gpg_data_scan (const uint8_t *p_start)
|
gpg_data_scan (const uint8_t *do_start, const uint8_t *do_end)
|
||||||
{
|
{
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
int i;
|
int i;
|
||||||
@@ -1556,10 +1556,15 @@ gpg_data_scan (const uint8_t *p_start)
|
|||||||
pw_err_counter_p[PW_ERR_RC] = NULL;
|
pw_err_counter_p[PW_ERR_RC] = NULL;
|
||||||
pw_err_counter_p[PW_ERR_PW3] = NULL;
|
pw_err_counter_p[PW_ERR_PW3] = NULL;
|
||||||
algo_attr_sig_p = algo_attr_dec_p = algo_attr_aut_p = NULL;
|
algo_attr_sig_p = algo_attr_dec_p = algo_attr_aut_p = NULL;
|
||||||
|
digital_signature_counter = 0;
|
||||||
|
|
||||||
|
/* When the card is terminated no data objects are valid. */
|
||||||
|
if (do_start == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Traverse DO, counters, etc. in DATA pool */
|
/* Traverse DO, counters, etc. in DATA pool */
|
||||||
p = p_start;
|
p = do_start;
|
||||||
while (p && *p != NR_EMPTY)
|
while (p < do_end && *p != NR_EMPTY)
|
||||||
{
|
{
|
||||||
uint8_t nr = *p++;
|
uint8_t nr = *p++;
|
||||||
uint8_t second_byte = *p;
|
uint8_t second_byte = *p;
|
||||||
@@ -1571,7 +1576,9 @@ gpg_data_scan (const uint8_t *p_start)
|
|||||||
if (nr < 0x80)
|
if (nr < 0x80)
|
||||||
{
|
{
|
||||||
/* It's Data Object */
|
/* It's Data Object */
|
||||||
do_ptr[nr] = p;
|
if (nr < NR_DO__LAST__)
|
||||||
|
do_ptr[nr] = p;
|
||||||
|
|
||||||
p += second_byte + 1; /* second_byte has length */
|
p += second_byte + 1; /* second_byte has length */
|
||||||
|
|
||||||
if (((uint32_t)p & 1))
|
if (((uint32_t)p & 1))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* openpgp.c -- OpenPGP card protocol support
|
* openpgp.c -- OpenPGP card protocol support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||||
* Free Software Initiative of Japan
|
* Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
@@ -106,16 +106,17 @@ uint8_t file_selection;
|
|||||||
static void
|
static void
|
||||||
gpg_init (void)
|
gpg_init (void)
|
||||||
{
|
{
|
||||||
const uint8_t *flash_data_start;
|
const uint8_t *flash_do_start;
|
||||||
|
const uint8_t *flash_do_end;
|
||||||
|
|
||||||
flash_data_start = flash_init ();
|
flash_init (&flash_do_start, &flash_do_end);
|
||||||
|
|
||||||
if (flash_data_start == NULL)
|
if (flash_do_start == NULL)
|
||||||
file_selection = FILE_CARD_TERMINATED;
|
file_selection = FILE_CARD_TERMINATED;
|
||||||
else
|
else
|
||||||
file_selection = FILE_NONE;
|
file_selection = FILE_NONE;
|
||||||
|
|
||||||
gpg_data_scan (flash_data_start);
|
gpg_data_scan (flash_do_start, flash_do_end);
|
||||||
flash_init_keys ();
|
flash_init_keys ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
#include "usb_lld.h"
|
#include "usb_lld.h"
|
||||||
#include "usb_conf.h"
|
#include "usb_conf.h"
|
||||||
#include "gnuk.h"
|
#include "gnuk.h"
|
||||||
#include "mcu/stm32f103.h"
|
|
||||||
|
|
||||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||||
#include "usb-cdc.h"
|
#include "usb-cdc.h"
|
||||||
@@ -209,27 +208,11 @@ static const uint8_t *const mem_info[] = { &_regnual_start, __heap_end__, };
|
|||||||
#define USB_FSIJ_GNUK_EXEC 2
|
#define USB_FSIJ_GNUK_EXEC 2
|
||||||
#define USB_FSIJ_GNUK_CARD_CHANGE 3
|
#define USB_FSIJ_GNUK_CARD_CHANGE 3
|
||||||
|
|
||||||
static uint32_t rbit (uint32_t v)
|
|
||||||
{
|
|
||||||
uint32_t r;
|
|
||||||
|
|
||||||
asm ("rbit %0, %1" : "=r" (r) : "r" (v));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* After calling this function, CRC module remain enabled. */
|
/* After calling this function, CRC module remain enabled. */
|
||||||
static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
|
static int
|
||||||
|
download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
|
||||||
{
|
{
|
||||||
uint32_t crc32 = *end_p;
|
if (check_crc32 ((const uint32_t *)&_regnual_start, end_p))
|
||||||
const uint32_t *p;
|
|
||||||
|
|
||||||
RCC->AHBENR |= RCC_AHBENR_CRCEN;
|
|
||||||
CRC->CR = CRC_CR_RESET;
|
|
||||||
|
|
||||||
for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
|
|
||||||
CRC->DR = rbit (*p);
|
|
||||||
|
|
||||||
if ((rbit (CRC->DR) ^ crc32) == 0xffffffff)
|
|
||||||
return usb_lld_ctrl_ack (dev);
|
return usb_lld_ctrl_ack (dev);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@@ -250,8 +233,7 @@ usb_setup (struct usb_dev *dev)
|
|||||||
}
|
}
|
||||||
else /* SETUP_SET */
|
else /* SETUP_SET */
|
||||||
{
|
{
|
||||||
uint8_t *addr = (uint8_t *)(0x20000000 + arg->value * 0x100
|
uint8_t *addr = sram_address ((arg->value * 0x100) + arg->index);
|
||||||
+ arg->index);
|
|
||||||
|
|
||||||
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
||||||
{
|
{
|
||||||
@@ -272,7 +254,7 @@ usb_setup (struct usb_dev *dev)
|
|||||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
if (*ccid_state_p != CCID_STATE_EXITED)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (((uint32_t)addr & 0x03))
|
if (((uintptr_t)addr & 0x03))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return download_check_crc32 (dev, (uint32_t *)addr);
|
return download_check_crc32 (dev, (uint32_t *)addr);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
gnuk_token.py - a library for Gnuk Token
|
gnuk_token.py - a library for Gnuk Token
|
||||||
|
|
||||||
Copyright (C) 2011, 2012, 2013, 2015
|
Copyright (C) 2011, 2012, 2013, 2015, 2017
|
||||||
Free Software Initiative of Japan
|
Free Software Initiative of Japan
|
||||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
@@ -26,6 +26,12 @@ import binascii
|
|||||||
import usb, time
|
import usb, time
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
|
# Possible Gnuk Token products
|
||||||
|
USB_PRODUCT_LIST=[
|
||||||
|
{ 'vendor' : 0x234b, 'product' : 0x0000 }, # FSIJ Gnuk Token
|
||||||
|
{ 'vendor' : 0x20a0, 'product' : 0x4211 }, # Nitrokey Start
|
||||||
|
]
|
||||||
|
|
||||||
# USB class, subclass, protocol
|
# USB class, subclass, protocol
|
||||||
CCID_CLASS = 0x0B
|
CCID_CLASS = 0x0B
|
||||||
CCID_SUBCLASS = 0x00
|
CCID_SUBCLASS = 0x00
|
||||||
@@ -586,19 +592,18 @@ def gnuk_devices():
|
|||||||
alt.interfaceProtocol == CCID_PROTOCOL_0:
|
alt.interfaceProtocol == CCID_PROTOCOL_0:
|
||||||
yield dev, config, alt
|
yield dev, config, alt
|
||||||
|
|
||||||
USB_VENDOR_FSIJ=0x234b
|
|
||||||
USB_PRODUCT_GNUK=0x0000
|
|
||||||
|
|
||||||
def gnuk_devices_by_vidpid():
|
def gnuk_devices_by_vidpid():
|
||||||
busses = usb.busses()
|
busses = usb.busses()
|
||||||
for bus in busses:
|
for bus in busses:
|
||||||
devices = bus.devices
|
devices = bus.devices
|
||||||
for dev in devices:
|
for dev in devices:
|
||||||
if dev.idVendor != USB_VENDOR_FSIJ:
|
for cand in USB_PRODUCT_LIST:
|
||||||
continue
|
if dev.idVendor != cand['vendor']:
|
||||||
if dev.idProduct != USB_PRODUCT_GNUK:
|
continue
|
||||||
continue
|
if dev.idProduct != cand['product']:
|
||||||
yield dev
|
continue
|
||||||
|
yield dev
|
||||||
|
break
|
||||||
|
|
||||||
def get_gnuk_device():
|
def get_gnuk_device():
|
||||||
icc = None
|
icc = None
|
||||||
|
|||||||
@@ -69,8 +69,9 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
|
|||||||
gnuk = None
|
gnuk = None
|
||||||
#
|
#
|
||||||
reg = None
|
reg = None
|
||||||
|
print("Waiting for device to appear:")
|
||||||
while reg == None:
|
while reg == None:
|
||||||
print("Wait %d seconds..." % wait_e)
|
print(" Wait %d seconds..." % wait_e)
|
||||||
time.sleep(wait_e)
|
time.sleep(wait_e)
|
||||||
for dev in gnuk_devices_by_vidpid():
|
for dev in gnuk_devices_by_vidpid():
|
||||||
try:
|
try:
|
||||||
@@ -84,9 +85,13 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
|
|||||||
print("%08x:%08x" % mem_info)
|
print("%08x:%08x" % mem_info)
|
||||||
print("Downloading the program")
|
print("Downloading the program")
|
||||||
reg.download(mem_info[0], data_upgrade)
|
reg.download(mem_info[0], data_upgrade)
|
||||||
|
print("Protecting device")
|
||||||
reg.protect()
|
reg.protect()
|
||||||
|
print("Finish flashing")
|
||||||
reg.finish()
|
reg.finish()
|
||||||
|
print("Resetting device")
|
||||||
reg.reset_device()
|
reg.reset_device()
|
||||||
|
print("Update procedure finished")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
@@ -119,6 +124,9 @@ if __name__ == '__main__':
|
|||||||
passwd = getpass("Admin password: ")
|
passwd = getpass("Admin password: ")
|
||||||
filename_regnual = sys.argv[1]
|
filename_regnual = sys.argv[1]
|
||||||
filename_upgrade = sys.argv[2]
|
filename_upgrade = sys.argv[2]
|
||||||
|
if not filename_regnual.endswith('bin') or not filename_upgrade.endswith('bin'):
|
||||||
|
print("Both input files must be in binary format (*.bin)!")
|
||||||
|
exit(1)
|
||||||
f = open(filename_regnual,"rb")
|
f = open(filename_regnual,"rb")
|
||||||
data_regnual = f.read()
|
data_regnual = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"""
|
"""
|
||||||
usb_strings.py - a tool to dump USB string
|
usb_strings.py - a tool to dump USB string
|
||||||
|
|
||||||
Copyright (C) 2012, 2015 Free Software Initiative of Japan
|
Copyright (C) 2012, 2015, 2017 Free Software Initiative of Japan
|
||||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
@@ -22,28 +22,14 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from gnuk_token import *
|
||||||
import usb, sys
|
import usb, sys
|
||||||
|
|
||||||
USB_VENDOR_FSIJ=0x234b
|
|
||||||
USB_PRODUCT_GNUK=0x0000
|
|
||||||
|
|
||||||
def gnuk_devices_by_vidpid():
|
|
||||||
busses = usb.busses()
|
|
||||||
for bus in busses:
|
|
||||||
devices = bus.devices
|
|
||||||
for dev in devices:
|
|
||||||
if dev.idVendor != USB_VENDOR_FSIJ:
|
|
||||||
continue
|
|
||||||
if dev.idProduct != USB_PRODUCT_GNUK:
|
|
||||||
continue
|
|
||||||
yield dev
|
|
||||||
|
|
||||||
field = ['', 'Vendor', 'Product', 'Serial', 'Revision', 'Config', 'Sys', 'Board']
|
field = ['', 'Vendor', 'Product', 'Serial', 'Revision', 'Config', 'Sys', 'Board']
|
||||||
|
|
||||||
def main(n):
|
def main(n):
|
||||||
for dev in gnuk_devices_by_vidpid():
|
for dev in gnuk_devices_by_vidpid():
|
||||||
handle = dev.open()
|
handle = dev.open()
|
||||||
print("Device: %s" % dev.filename)
|
|
||||||
try:
|
try:
|
||||||
for i in range(1,n):
|
for i in range(1,n):
|
||||||
s = handle.getString(i, 512)
|
s = handle.getString(i, 512)
|
||||||
|
|||||||
Reference in New Issue
Block a user