Compare commits
21 Commits
release/1.
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f86f97cdbe | ||
|
|
1e004bec78 | ||
|
|
d68bee21e5 | ||
|
|
2903e88986 | ||
|
|
25fed157e1 | ||
|
|
d5c5571423 | ||
|
|
51d4b754e6 | ||
|
|
48905155c5 | ||
|
|
772071d1ba | ||
|
|
1fa45e3273 | ||
|
|
1a5eb0ec3b | ||
|
|
106b042e75 | ||
|
|
eebd40d946 | ||
|
|
5e37c7722a | ||
|
|
b1a582e87c | ||
|
|
3f1ee534fe | ||
|
|
522ec3299e | ||
|
|
34e2099b23 | ||
|
|
baf09ecac9 | ||
|
|
db23a1d051 | ||
|
|
3f8c4d1f17 |
110
ChangeLog
110
ChangeLog
@@ -1,3 +1,113 @@
|
||||
2016-05-20 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.2.0.
|
||||
* src/usb-ccid.c (ccid_thread): Fix timeout.
|
||||
(icc_handle_timeout, icc_send_status): Tweak.
|
||||
|
||||
2016-05-19 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb_ctrl.c (usb_cb_ctrl_write_finish): Set bDeviceState.
|
||||
|
||||
* src/usb-ccid.c: Rename from usb-icc.c.
|
||||
(ccid_thread): Handle reGNUal upgrade.
|
||||
|
||||
* src/Makefile.in (CSRC): Follow the change.
|
||||
|
||||
* chopstx: Update to 0.11.
|
||||
|
||||
2016-05-18 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/gnuk.ld.in: Tweak thread size.
|
||||
* src/main.c (main): Use chopstx_setpriority.
|
||||
* src/usb-icc.c (ccid_init): Use new eventflag API.
|
||||
|
||||
* regnual/regnual.c (nvic_enable_intr): New.
|
||||
(main): Call nvic_enable_intr.
|
||||
|
||||
* chopstx: Update.
|
||||
|
||||
2016-05-16 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* regnual/regnual.c (usb_cb_rx_ready, usb_cb_tx_done)
|
||||
(usb_cb_device_reset): Follow the change of USB API.
|
||||
|
||||
* chopstx: Update.
|
||||
* src/sys.c: Update from Chopstx.
|
||||
|
||||
2016-05-13 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/neug.c (rng): Call chopstx_claim_irq before adc_start.
|
||||
Remove call of chopstx_release_irq.
|
||||
|
||||
2016-05-12 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* chopstx: Update.
|
||||
* src/sys.c: Update from Chopstx.
|
||||
* src/usb_lld.h: Likewise.
|
||||
* src/usb_stm32f103.c: Likewise.
|
||||
|
||||
* src/usb_ctrl.c (usb_intr): Follow the change of USB API.
|
||||
(usb_cb_rx_ready, usb_cb_tx_done): Likewise.
|
||||
|
||||
* src/adc.h: Remove unused declarations.
|
||||
|
||||
2016-03-08 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* tool/gnuk_token.py (gnuk_token.__init__, regnual.__init__):
|
||||
Don't call setConfiguration method.
|
||||
|
||||
* src/usb_lld.h (usb_cb_ctrl_write_finish): Change the API of
|
||||
callback, which possibly needs INDEX, VALUE, and LEN parameters.
|
||||
(usb_lld_set_data_to_recv): Fix the type of P.
|
||||
(USB_DEVICE_DESCRIPTOR_TYPE, USB_CONFIGURATION_DESCRIPTOR_TYPE)
|
||||
(USB_STRING_DESCRIPTOR_TYPE, USB_INTERFACE_DESCRIPTOR_TYPE)
|
||||
(USB_ENDPOINT_DESCRIPTOR_TYPE): Remove, as we have the enumeration
|
||||
values for same things.
|
||||
|
||||
* src/usb_stm32f103.c (handle_in0): Follow the change.
|
||||
* src/usb_ctrl.c (usb_cb_ctrl_write_finish): Likewise.
|
||||
|
||||
* src/usb_desc.c (usb_cb_get_descriptor): Use HID_INTERFACE.
|
||||
(device_desc, config_desc, string_descriptors)
|
||||
(usb_cb_get_descriptor): Use the enumeration types.
|
||||
* src/configure: Use the enumeration types.
|
||||
|
||||
* regnual/regnual.c: Follow the change of usb_lld.h.
|
||||
|
||||
2016-02-09 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (cmd_verify): Support VERIFY reset, which is
|
||||
described in the specification V2.2 and V3.1.
|
||||
|
||||
* polarssl/library/bignum.c (mpi_exp_mod): Fix to our local
|
||||
change. Thanks to Aidan Thornton for the failure test case.
|
||||
|
||||
Fix of mpi_div_mpi from upstream.
|
||||
* polarssl/library/bignum.c (int_clz, int_div_int): New.
|
||||
(mpi_div_mpi): Use int_div_int.
|
||||
|
||||
2016-02-09 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/openpgp.c (s2k): Include the unique ID of MCU into the
|
||||
computation of S2K function.
|
||||
|
||||
2016-02-08 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/modp256r1.c (modp256r1_add, modp256r1_sub): Keep the result
|
||||
less than P256R1.
|
||||
(modp256r1_reduce): Fix wrong calculation.
|
||||
* src/modp256k1.c (modp256k1_add, modp256k1_sub): Likewise.
|
||||
Thanks to Aidan Thornton.
|
||||
|
||||
2016-02-05 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/configure: Add submodule check suggested by Elliott
|
||||
Mitchell.
|
||||
|
||||
2015-11-30 perillamint <perillamint@gentoo.moe>
|
||||
|
||||
* src/openpgp.c (card_thread): Fix offset of bConfirmPIN.
|
||||
|
||||
2015-09-18 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* VERSION: 1.1.9.
|
||||
|
||||
23
NEWS
23
NEWS
@@ -1,5 +1,28 @@
|
||||
Gnuk NEWS - User visible changes
|
||||
|
||||
* Major changes in Gnuk 1.2.0
|
||||
|
||||
Released 2016-05-20, by NIIBE Yutaka
|
||||
|
||||
** Upgrade of Chopstx
|
||||
We use Chopstx 0.11.
|
||||
|
||||
** Support authentication status reset by VERIFY command.
|
||||
This feature is described in the OpenPGPcard specification V2.2 and
|
||||
V3.1, which allow user to reset authentication status.
|
||||
|
||||
** S2K algorithm tweak to defeat "copycat" service of MCU.
|
||||
Even if the existence of some services copying MCU, your private key
|
||||
will not be controled by others, in some cases.
|
||||
|
||||
** Bug fix for secp256k1 and NIST P-256.
|
||||
Bugs in basic computation were fixed.
|
||||
|
||||
** Bug fix for bignum routines.
|
||||
Bignum routine update from upstream (failure doesn't occur for our RSA
|
||||
computation, though). Another fix for mpi_exp_mod.
|
||||
|
||||
|
||||
* Major changes in Gnuk 1.1.9
|
||||
|
||||
Released 2015-09-18, by NIIBE Yutaka
|
||||
|
||||
88
README
88
README
@@ -1,28 +1,27 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 1.1.9
|
||||
2015-09-18
|
||||
Version 1.2.0
|
||||
2016-05-20
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
Warning
|
||||
=======
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
This is another experimental release of Gnuk, version 1.1.9, which has
|
||||
This is new release of Gnuk, version 1.2.0, 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 ECDSA (with NIST P256 and secp256k1), EdDSA, and ECDH
|
||||
(with NIST P256, secp256k1, and Curve25519), but this ECC feature is
|
||||
pretty much experimental, and it requires modern GnuPG with
|
||||
development version of libgcrypt.
|
||||
that the instruction of importing keys won't cause any confusion.
|
||||
|
||||
It also supports RSA-4096 experimentally, but users should know that
|
||||
it takes more than 8 second to sign/decrypt.
|
||||
It has supports of EdDSA, ECDSA (with NIST P256 and secp256k1), and
|
||||
ECDH (with NIST P256, secp256k1, and X25519), but this ECC feature is
|
||||
somehow experimental, and it requires modern GnuPG 2.1.x with
|
||||
libgcrypt 1.7.0 or later.
|
||||
|
||||
You will not able to keep using Curve25519 keys, as the key format is
|
||||
subject to change.
|
||||
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?
|
||||
@@ -63,11 +62,12 @@ A0: Good points of Gnuk are:
|
||||
|
||||
Q1: What kind of key algorithm is supported?
|
||||
A1: Gnuk version 1.0 only supports RSA-2048.
|
||||
Development version of Gnuk (1.1.x) supports 256-bit ECDSA and EdDSA,
|
||||
as well as RSA 4096-bit. But it takes long time to sign with RSA-4096.
|
||||
Gnuk version 1.2.x supports 256-bit EdDSA and ECDSA, as well as
|
||||
RSA-4096. But 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.
|
||||
@@ -77,7 +77,7 @@ A3: Orthodox choice is Olimex STM32-H103.
|
||||
choice for experiment.
|
||||
|
||||
Q4: What's version of GnuPG are you using?
|
||||
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.x in
|
||||
A4: In Debian GNU/Linux system, I use GnuPG modern 2.1.12 in
|
||||
experimental.
|
||||
|
||||
Q5: What's version of pcscd and libccid are you using?
|
||||
@@ -139,22 +139,14 @@ Ac: That's because gnome-keyring-daemon interferes GnuPG. Please
|
||||
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.
|
||||
ST-Link/V2. However, the firmware of ST-Link/V2 is proprietary.
|
||||
Now, I develop BBG-SWD, SWD debugger by BeagleBone Green.
|
||||
|
||||
|
||||
Release notes
|
||||
=============
|
||||
Tested features
|
||||
===============
|
||||
|
||||
This is ninth experimental release in version 1.1 series of Gnuk.
|
||||
|
||||
While it is daily use by its developer, some newly introduced features
|
||||
(including ECDSA/EdDSA/ECDH, key generation and firmware upgrade)
|
||||
should be considered experimental. ECDSA/EdDSA/ECDH is really
|
||||
experimental. Further, ECDH on Curve25519 is much experimental. You
|
||||
won't be able to keep using the key, since the key format of GnuPG is
|
||||
not defined and it's subject to change.
|
||||
|
||||
Tested features are:
|
||||
Gnuk is tested by test suite. Please see the test directory.
|
||||
|
||||
* Personalization of the card
|
||||
* Changing Login name, URL, Name, Sex, Language, etc.
|
||||
@@ -171,10 +163,10 @@ Tested features are:
|
||||
* Modify with pin pad
|
||||
* Card holder certificate (read)
|
||||
* Removal of keys
|
||||
* Key generation on device side
|
||||
* Key generation on device side for RSA-2048
|
||||
* Overriding key import
|
||||
|
||||
Original features of Gnuk, tested lightly:
|
||||
Original features of Gnuk, tested manually lightly:
|
||||
|
||||
* OpenPGP card serial number setup
|
||||
* Card holder certificate (write by UPDATE BINARY)
|
||||
@@ -182,12 +174,12 @@ Original features of Gnuk, tested lightly:
|
||||
|
||||
It is known not-working well:
|
||||
|
||||
* It is known that the combination of libccid 1.4.1 (or newer)
|
||||
with libusb 1.0.8 (or older) has 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.
|
||||
* 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
|
||||
@@ -256,7 +248,7 @@ External source code
|
||||
|
||||
Gnuk is distributed with external source code.
|
||||
|
||||
* chopstx/ -- Chopstx 0.10
|
||||
* chopstx/ -- Chopstx 0.11
|
||||
|
||||
We use Chopstx as the kernel for Gnuk.
|
||||
|
||||
@@ -369,9 +361,9 @@ 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.25-5+5+b1
|
||||
gcc-arm-none-eabi 15:4.9.3+svn227297-1
|
||||
gdb-arm-none-eabi 7.7.1+dfsg-5+8
|
||||
binutils-arm-none-eabi 2.26-4+8
|
||||
gcc-arm-none-eabi 15:4.9.3+svn231177-1
|
||||
gdb-arm-none-eabi 7.10-1+9
|
||||
libnewlib-arm-none-eabi 2.2.0+git20150830.5a3d536-1
|
||||
|
||||
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
||||
@@ -459,11 +451,13 @@ to access the contents. If you want to protect, killing DfuSe and
|
||||
accessing by JTAG debugger is recommended.
|
||||
|
||||
|
||||
How to configure
|
||||
================
|
||||
(Optional) Configure serial number and X.509 certificate
|
||||
========================================================
|
||||
|
||||
You need python and pyscard (python-pyscard package in Debian) or
|
||||
PyUSB 0.4.3 (python-usb package in Debian).
|
||||
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.
|
||||
@@ -616,7 +610,7 @@ Your Contributions
|
||||
==================
|
||||
|
||||
FSIJ welcomes your contributions. Please assign your copyright
|
||||
to FSIJ (if possible).
|
||||
to FSIJ (if possible), as I do.
|
||||
|
||||
|
||||
Foot note
|
||||
|
||||
1
THANKS
1
THANKS
@@ -14,6 +14,7 @@ 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
|
||||
|
||||
2
chopstx
2
chopstx
Submodule chopstx updated: a30a069ed8...5458b77d36
@@ -223,6 +223,24 @@ size_t mpi_lsb( const mpi *X )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Count leading zero bits in a given integer
|
||||
*/
|
||||
static size_t int_clz( const t_uint x )
|
||||
{
|
||||
size_t j;
|
||||
t_uint mask = (t_uint) 1 << (biL - 1);
|
||||
|
||||
for( j = 0; j < biL; j++ )
|
||||
{
|
||||
if( x & mask ) break;
|
||||
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of most significant bits
|
||||
*/
|
||||
@@ -1102,6 +1120,100 @@ int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
|
||||
return( mpi_mul_mpi( X, A, &_B ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Unsigned integer divide - 64bit dividend and 32bit divisor
|
||||
*/
|
||||
static t_uint int_div_int(t_uint u1, t_uint u0, t_uint d, t_uint *r)
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_UDBL)
|
||||
t_udbl dividend, quotient;
|
||||
#else
|
||||
const t_uint radix = (t_uint) 1 << biH;
|
||||
const t_uint uint_halfword_mask = ( (t_uint) 1 << biH ) - 1;
|
||||
t_uint d0, d1, q0, q1, rAX, r0, quotient;
|
||||
t_uint u0_msw, u0_lsw;
|
||||
size_t s;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for overflow
|
||||
*/
|
||||
if(( 0 == d ) || ( u1 >= d ))
|
||||
{
|
||||
if (r != NULL) *r = (~0);
|
||||
|
||||
return (~0);
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_HAVE_UDBL)
|
||||
dividend = (t_udbl) u1 << biL;
|
||||
dividend |= (t_udbl) u0;
|
||||
quotient = dividend / d;
|
||||
if( quotient > ( (t_udbl) 1 << biL ) - 1 )
|
||||
quotient = ( (t_udbl) 1 << biL ) - 1;
|
||||
|
||||
if( r != NULL )
|
||||
*r = (t_uint)( dividend - (quotient * d ) );
|
||||
|
||||
return (t_uint) quotient;
|
||||
#else
|
||||
|
||||
/*
|
||||
* Algorithm D, Section 4.3.1 - The Art of Computer Programming
|
||||
* Vol. 2 - Seminumerical Algorithms, Knuth
|
||||
*/
|
||||
|
||||
/*
|
||||
* Normalize the divisor, d, and dividend, u0, u1
|
||||
*/
|
||||
s = int_clz( d );
|
||||
d = d << s;
|
||||
|
||||
u1 = u1 << s;
|
||||
u1 |= ( u0 >> ( biL - s ) ) & ( -(t_sint)s >> ( biL - 1 ) );
|
||||
u0 = u0 << s;
|
||||
|
||||
d1 = d >> biH;
|
||||
d0 = d & uint_halfword_mask;
|
||||
|
||||
u0_msw = u0 >> biH;
|
||||
u0_lsw = u0 & uint_halfword_mask;
|
||||
|
||||
/*
|
||||
* Find the first quotient and remainder
|
||||
*/
|
||||
q1 = u1 / d1;
|
||||
r0 = u1 - d1 * q1;
|
||||
|
||||
while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
|
||||
{
|
||||
q1 -= 1;
|
||||
r0 += d1;
|
||||
|
||||
if ( r0 >= radix ) break;
|
||||
}
|
||||
|
||||
rAX = (u1 * radix) + (u0_msw - q1 * d);
|
||||
q0 = rAX / d1;
|
||||
r0 = rAX - q0 * d1;
|
||||
|
||||
while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
|
||||
{
|
||||
q0 -= 1;
|
||||
r0 += d1;
|
||||
|
||||
if ( r0 >= radix ) break;
|
||||
}
|
||||
|
||||
if (r != NULL)
|
||||
*r = (rAX * radix + u0_lsw - q0 * d) >> s;
|
||||
|
||||
quotient = q1 * radix + q0;
|
||||
|
||||
return quotient;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Division by mpi: A = Q * B + R (HAC 14.20)
|
||||
*/
|
||||
@@ -1159,57 +1271,7 @@ int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
|
||||
Z.p[i - t - 1] = ~0;
|
||||
else
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_UDBL)
|
||||
t_udbl r;
|
||||
|
||||
r = (t_udbl) X.p[i] << biL;
|
||||
r |= (t_udbl) X.p[i - 1];
|
||||
r /= Y.p[t];
|
||||
if( r > ((t_udbl) 1 << biL) - 1)
|
||||
r = ((t_udbl) 1 << biL) - 1;
|
||||
|
||||
Z.p[i - t - 1] = (t_uint) r;
|
||||
#else
|
||||
/*
|
||||
* __udiv_qrnnd_c, from gmp/longlong.h
|
||||
*/
|
||||
t_uint q0, q1, r0, r1;
|
||||
t_uint d0, d1, d, m;
|
||||
|
||||
d = Y.p[t];
|
||||
d0 = ( d << biH ) >> biH;
|
||||
d1 = ( d >> biH );
|
||||
|
||||
q1 = X.p[i] / d1;
|
||||
r1 = X.p[i] - d1 * q1;
|
||||
r1 <<= biH;
|
||||
r1 |= ( X.p[i - 1] >> biH );
|
||||
|
||||
m = q1 * d0;
|
||||
if( r1 < m )
|
||||
{
|
||||
q1--, r1 += d;
|
||||
while( r1 >= d && r1 < m )
|
||||
q1--, r1 += d;
|
||||
}
|
||||
r1 -= m;
|
||||
|
||||
q0 = r1 / d1;
|
||||
r0 = r1 - d1 * q0;
|
||||
r0 <<= biH;
|
||||
r0 |= ( X.p[i - 1] << biH ) >> biH;
|
||||
|
||||
m = q0 * d0;
|
||||
if( r0 < m )
|
||||
{
|
||||
q0--, r0 += d;
|
||||
while( r0 >= d && r0 < m )
|
||||
q0--, r0 += d;
|
||||
}
|
||||
r0 -= m;
|
||||
|
||||
Z.p[i - t - 1] = ( q1 << biH ) | q0;
|
||||
#endif
|
||||
Z.p[i - t - 1] = int_div_int( X.p[i], X.p[i-1], Y.p[t], NULL);
|
||||
}
|
||||
|
||||
Z.p[i - t - 1]++;
|
||||
@@ -1584,6 +1646,7 @@ int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
|
||||
memset (d, 0, 2 * N->n * ciL); /* Set D zero. */
|
||||
mpi_sub_hlp( N->n, N->p, d + N->n);
|
||||
MPI_CHK( mpi_mod_mpi( &RR, &T, N ) );
|
||||
MPI_CHK( mpi_grow( &RR, N->n ) );
|
||||
|
||||
if( _RR != NULL )
|
||||
memcpy( _RR, &RR, sizeof( mpi ) );
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* regnual.c -- Firmware installation for STM32F103 Flash ROM
|
||||
*
|
||||
* Copyright (C) 2012, 2013, 2015
|
||||
* Copyright (C) 2012, 2013, 2015, 2016
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -51,7 +51,7 @@ static uint32_t flash_end;
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t regnual_device_desc[] = {
|
||||
18, /* bLength */
|
||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||
0xFF, /* bDeviceClass: VENDOR */
|
||||
0x00, /* bDeviceSubClass */
|
||||
@@ -64,24 +64,26 @@ static const uint8_t regnual_device_desc[] = {
|
||||
0x01 /* bNumConfigurations */
|
||||
};
|
||||
|
||||
#if defined(USB_SELF_POWERED)
|
||||
#define REGNUAL_FEATURE_INIT 0xC0 /* self powered */
|
||||
#else
|
||||
#define REGNUAL_FEATURE_INIT 0x80 /* bus powered */
|
||||
#endif
|
||||
|
||||
static const uint8_t regnual_config_desc[] = {
|
||||
9,
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
||||
18, 0, /* wTotalLength: no of returned bytes */
|
||||
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
|
||||
18, 0, /* wTotalLength: no of returned bytes */
|
||||
1, /* bNumInterfaces: single vendor interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: None */
|
||||
#if defined(USB_SELF_POWERED)
|
||||
0xC0, /* bmAttributes: self powered */
|
||||
#else
|
||||
0x80, /* bmAttributes: bus powered */
|
||||
#endif
|
||||
50, /* MaxPower 100 mA */
|
||||
REGNUAL_FEATURE_INIT, /* bmAttributes: bus powered */
|
||||
50, /* MaxPower 100 mA */
|
||||
|
||||
/* Interface Descriptor */
|
||||
9,
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
0, /* bInterfaceNumber: Index of this interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
0, /* bInterfaceNumber: Index of this interface */
|
||||
0, /* Alternate setting for this interface */
|
||||
0, /* bNumEndpoints: None */
|
||||
0xFF,
|
||||
@@ -92,7 +94,7 @@ static const uint8_t regnual_config_desc[] = {
|
||||
|
||||
static const uint8_t regnual_string_lang_id[] = {
|
||||
4, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
STRING_DESCRIPTOR,
|
||||
0x09, 0x04 /* LangID = 0x0409: US-English */
|
||||
};
|
||||
|
||||
@@ -100,7 +102,7 @@ static const uint8_t regnual_string_lang_id[] = {
|
||||
|
||||
static const uint8_t regnual_string_serial[] = {
|
||||
8*2+2,
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
STRING_DESCRIPTOR,
|
||||
/* FSIJ-0.0 */
|
||||
'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0,
|
||||
'0', 0, '.', 0, '0', 0,
|
||||
@@ -110,13 +112,7 @@ static const uint8_t regnual_string_serial[] = {
|
||||
void
|
||||
usb_cb_device_reset (void)
|
||||
{
|
||||
/* Set DEVICE as not configured */
|
||||
usb_lld_set_configuration (0);
|
||||
|
||||
/* Current Feature initialization */
|
||||
usb_lld_set_feature (regnual_config_desc[7]);
|
||||
|
||||
usb_lld_reset ();
|
||||
usb_lld_reset (REGNUAL_FEATURE_INIT);
|
||||
|
||||
/* Initialize Endpoint 0 */
|
||||
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
||||
@@ -173,29 +169,30 @@ static uint32_t calc_crc32 (void)
|
||||
}
|
||||
|
||||
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
struct req_args *arg)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT) && USB_SETUP_SET (req))
|
||||
{
|
||||
if (req_no == USB_REGNUAL_SEND && value == 0)
|
||||
if (req_no == USB_REGNUAL_SEND && arg->value == 0)
|
||||
result = calc_crc32 ();
|
||||
else if (req_no == USB_REGNUAL_FLASH)
|
||||
{
|
||||
uint32_t dst_addr = (0x08000000 + value * 0x100);
|
||||
uint32_t dst_addr = (0x08000000 + arg->value * 0x100);
|
||||
|
||||
result = flash_write (dst_addr, (const uint8_t *)mem, 256);
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_PROTECT && value == 0)
|
||||
else if (req_no == USB_REGNUAL_PROTECT && arg->value == 0)
|
||||
result = flash_protect ();
|
||||
else if (req_no == USB_REGNUAL_FINISH && value == 0)
|
||||
else if (req_no == USB_REGNUAL_FINISH && arg->value == 0)
|
||||
nvic_system_reset ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
@@ -209,38 +206,38 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
|
||||
mem_info[0] = (const uint8_t *)FLASH_START;
|
||||
mem_info[1] = (const uint8_t *)flash_end;
|
||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), detail);
|
||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), arg);
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_RESULT)
|
||||
return usb_lld_reply_request (&result, sizeof (uint32_t), detail);
|
||||
return usb_lld_reply_request (&result, sizeof (uint32_t), arg);
|
||||
}
|
||||
else /* SETUP_SET */
|
||||
{
|
||||
if (req_no == USB_REGNUAL_SEND)
|
||||
{
|
||||
if (detail->value != 0 || detail->index + detail->len > 256)
|
||||
if (arg->value != 0 || arg->index + arg->len > 256)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->index + detail->len < 256)
|
||||
memset ((uint8_t *)mem + detail->index + detail->len, 0xff,
|
||||
256 - (detail->index + detail->len));
|
||||
if (arg->index + arg->len < 256)
|
||||
memset ((uint8_t *)mem + arg->index + arg->len, 0xff,
|
||||
256 - (arg->index + arg->len));
|
||||
|
||||
usb_lld_set_data_to_recv (mem + detail->index, detail->len);
|
||||
usb_lld_set_data_to_recv (mem + arg->index, arg->len);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_FLASH && detail->len == 0
|
||||
&& detail->index == 0)
|
||||
else if (req_no == USB_REGNUAL_FLASH && arg->len == 0
|
||||
&& arg->index == 0)
|
||||
{
|
||||
uint32_t dst_addr = (0x08000000 + detail->value * 0x100);
|
||||
uint32_t dst_addr = (0x08000000 + arg->value * 0x100);
|
||||
|
||||
if (dst_addr + 256 <= flash_end)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_PROTECT && detail->len == 0
|
||||
&& detail->value == 0 && detail->index == 0)
|
||||
else if (req_no == USB_REGNUAL_PROTECT && arg->len == 0
|
||||
&& arg->value == 0 && arg->index == 0)
|
||||
return USB_SUCCESS;
|
||||
else if (req_no == USB_REGNUAL_FINISH && detail->len == 0
|
||||
&& detail->value == 0 && detail->index == 0)
|
||||
else if (req_no == USB_REGNUAL_FINISH && arg->len == 0
|
||||
&& arg->value == 0 && arg->index == 0)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -250,17 +247,17 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
|
||||
int
|
||||
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
struct control_info *detail)
|
||||
struct req_args *arg)
|
||||
{
|
||||
if (rcp != DEVICE_RECIPIENT)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (desc_type == DEVICE_DESCRIPTOR)
|
||||
return usb_lld_reply_request (regnual_device_desc,
|
||||
sizeof (regnual_device_desc), detail);
|
||||
sizeof (regnual_device_desc), arg);
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
return usb_lld_reply_request (regnual_config_desc,
|
||||
sizeof (regnual_config_desc), detail);
|
||||
sizeof (regnual_config_desc), arg);
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
const uint8_t *str;
|
||||
@@ -288,7 +285,7 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
return usb_lld_reply_request (str, size, detail);
|
||||
return usb_lld_reply_request (str, size, arg);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
@@ -310,12 +307,21 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
||||
int usb_cb_interface (uint8_t cmd, struct req_args *arg)
|
||||
{
|
||||
(void)cmd; (void)detail;
|
||||
(void)cmd; (void)arg;
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
void usb_cb_rx_ready (uint8_t ep_num)
|
||||
{
|
||||
(void)ep_num;
|
||||
}
|
||||
|
||||
void usb_cb_tx_done (uint8_t ep_num)
|
||||
{
|
||||
(void)ep_num;
|
||||
}
|
||||
|
||||
static void wait (int count)
|
||||
{
|
||||
@@ -327,6 +333,30 @@ static void wait (int count)
|
||||
|
||||
#define WAIT 2400000
|
||||
|
||||
/* NVIC: Nested Vectored Interrupt Controller. */
|
||||
struct NVIC {
|
||||
volatile uint32_t ISER[8];
|
||||
uint32_t unused1[24];
|
||||
volatile uint32_t ICER[8];
|
||||
uint32_t unused2[24];
|
||||
volatile uint32_t ISPR[8];
|
||||
uint32_t unused3[24];
|
||||
volatile uint32_t ICPR[8];
|
||||
uint32_t unused4[24];
|
||||
volatile uint32_t IABR[8];
|
||||
uint32_t unused5[56];
|
||||
volatile uint32_t IPR[60];
|
||||
};
|
||||
static struct NVIC *const NVIC = (struct NVIC *const)0xE000E100;
|
||||
#define NVIC_ISER(n) (NVIC->ISER[n >> 5])
|
||||
|
||||
static void nvic_enable_intr (uint8_t irq_num)
|
||||
{
|
||||
NVIC_ISER (irq_num) = 1 << (irq_num & 0x1f);
|
||||
}
|
||||
|
||||
#define USB_LP_CAN1_RX0_IRQn 20
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -335,7 +365,14 @@ main (int argc, char *argv[])
|
||||
set_led (0);
|
||||
|
||||
flash_end = FLASH_START_ADDR + (*FLASH_SIZE_REG)*1024;
|
||||
usb_lld_init (regnual_config_desc[7]);
|
||||
|
||||
/*
|
||||
* NVIC interrupt priority was set by Gnuk.
|
||||
* USB interrupt is disabled by NVIC setting.
|
||||
* We enable the interrupt again by nvic_enable_intr.
|
||||
*/
|
||||
usb_lld_init (REGNUAL_FEATURE_INIT);
|
||||
nvic_enable_intr (USB_LP_CAN1_RX0_IRQn);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ LDSCRIPT= gnuk.ld
|
||||
CSRC = main.c usb_stm32f103.c adc_stm32f103.c \
|
||||
usb_desc.c usb_ctrl.c \
|
||||
call-rsa.c \
|
||||
usb-icc.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 \
|
||||
modp256r1.c jpc_p256r1.c ec_p256r1.c call-ec_p256r1.c \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
extern chopstx_mutex_t adc_mtx;
|
||||
extern chopstx_cond_t adc_cond;
|
||||
extern int adc_waiting;
|
||||
extern int adc_data_available;
|
||||
|
||||
void adc_init (void);
|
||||
void adc_start (void);
|
||||
void adc_stop (void);
|
||||
|
||||
#define ADC_SAMPLE_MODE 0
|
||||
#define ADC_CRC32_MODE 1
|
||||
|
||||
extern uint32_t adc_buf[64];
|
||||
|
||||
void adc_start_conversion (int offset, int count);
|
||||
|
||||
31
src/configure
vendored
31
src/configure
vendored
@@ -6,7 +6,7 @@ nl=$'\n'
|
||||
#
|
||||
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
|
||||
#
|
||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
|
||||
# Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||
# Free Software Initiative of Japan
|
||||
#
|
||||
# This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -23,6 +23,15 @@ nl=$'\n'
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# Submodule check
|
||||
#
|
||||
if ! test -f ../chopstx/rules.mk; then
|
||||
echo "Submodule 'chopstx' not found" >&2
|
||||
echo "You might need: git submodule update --init" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Default settings
|
||||
help=no
|
||||
vidpid=none
|
||||
@@ -127,7 +136,7 @@ EOF
|
||||
fi
|
||||
|
||||
if test "$vidpid" = "none"; then
|
||||
echo "Please specify Vendor ID and Product ID by --vidpid option."
|
||||
echo "Please specify Vendor ID and Product ID by --vidpid option." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -181,7 +190,7 @@ fi
|
||||
# --with-dfu option
|
||||
if test "$with_dfu" = "yes"; then
|
||||
if test "$target" = "FST_01" -o "$target" = "FST_01_00"; then
|
||||
echo "FST-01 doesn't have DFU loader, you should not use --with-dfu."
|
||||
echo "FST-01 doesn't have DFU loader, you should not use --with-dfu." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Configured for DFU"
|
||||
@@ -247,7 +256,7 @@ if test "$sys1_compat" = "yes"; then
|
||||
CONFIG="$target:dfu=$with_dfu:debug=$debug:pinpad=$pinpad:certdo=$certdo"
|
||||
else
|
||||
if test "$with_dfu" = "yes"; then
|
||||
echo "Common binary can't support DFU loader, don't use --with-dfu."
|
||||
echo "Common binary can't support DFU loader, don't use --with-dfu." >&2
|
||||
exit 1
|
||||
fi
|
||||
# Override settings for common binary. Safer side.
|
||||
@@ -267,14 +276,14 @@ output_vendor_product_serial_strings () {
|
||||
|
||||
echo "static const uint8_t ${prefix}string_vendor[] = {"
|
||||
echo " ${#VENDOR}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
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 '};'
|
||||
echo
|
||||
echo "static const uint8_t ${prefix}string_product[] = {"
|
||||
echo " ${#PRODUCT}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
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 '};'
|
||||
@@ -283,7 +292,7 @@ output_vendor_product_serial_strings () {
|
||||
echo
|
||||
echo "uint8_t ${prefix}string_serial[] = {"
|
||||
echo " ${#SERIALNO}*2+2+16, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
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,"
|
||||
@@ -293,14 +302,14 @@ output_vendor_product_serial_strings () {
|
||||
echo '#ifdef USB_STRINGS_FOR_GNUK'
|
||||
echo "static const uint8_t ${prefix}revision_detail[] = {"
|
||||
echo " ${#REVISION}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
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 '};'
|
||||
echo
|
||||
echo "static const uint8_t ${prefix}config_options[] = {"
|
||||
echo " ${#CONFIG}*2+2, /* bLength */"
|
||||
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
|
||||
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 '};'
|
||||
@@ -317,8 +326,8 @@ if !(IFS=" "
|
||||
fi
|
||||
done; exit 1) < ../GNUK_USB_DEVICE_ID
|
||||
then
|
||||
echo "Please specify valid Vendor ID and Product ID."
|
||||
echo "Check ../GNUK_USB_DEVICE_ID."
|
||||
echo "Please specify valid Vendor ID and Product ID." >&2
|
||||
echo "Check ../GNUK_USB_DEVICE_ID." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -424,8 +424,7 @@ extern const uint8_t gnuk_string_serial[];
|
||||
#define LED_START_COMMAND 8
|
||||
#define LED_FINISH_COMMAND 16
|
||||
#define LED_FATAL 32
|
||||
#define LED_USB_RESET 64
|
||||
#define LED_GNUK_EXEC 128
|
||||
#define LED_GNUK_EXEC 64
|
||||
void led_blink (int spec);
|
||||
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
*/
|
||||
__main_stack_size__ = 0x0080; /* Exception handlers */
|
||||
__process0_stack_size__ = 0x0100; /* main */
|
||||
__process1_stack_size__ = 0x0120; /* ccid */
|
||||
__process2_stack_size__ = 0x01a0; /* rng */
|
||||
__process1_stack_size__ = 0x0180; /* ccid */
|
||||
__process2_stack_size__ = 0x0160; /* rng */
|
||||
__process3_stack_size__ = 0x1640; /* gpg */
|
||||
__process4_stack_size__ = 0x0120; /* intr: usb */
|
||||
__process4_stack_size__ = 0; /* --- */
|
||||
__process5_stack_size__ = @MSC_SIZE@; /* msc */
|
||||
__process6_stack_size__ = @TIM_SIZE@; /* intr: timer */
|
||||
__process7_stack_size__ = @EXT_SIZE@; /* intr: ext */
|
||||
|
||||
190
src/main.c
190
src/main.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* main.c - main routine of Gnuk
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -37,85 +37,10 @@
|
||||
#include "random.h"
|
||||
#include "stm32f103.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "debug.h"
|
||||
|
||||
struct stdout stdout;
|
||||
|
||||
static void
|
||||
stdout_init (void)
|
||||
{
|
||||
chopstx_mutex_init (&stdout.m);
|
||||
chopstx_mutex_init (&stdout.m_dev);
|
||||
chopstx_cond_init (&stdout.cond_dev);
|
||||
stdout.connected = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_write (const char *s, int len)
|
||||
{
|
||||
int packet_len;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
chopstx_mutex_lock (&stdout.m);
|
||||
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
if (!stdout.connected)
|
||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
do
|
||||
{
|
||||
packet_len =
|
||||
(len < VIRTUAL_COM_PORT_DATA_SIZE) ? len : VIRTUAL_COM_PORT_DATA_SIZE;
|
||||
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
usb_lld_write (ENDP3, s, packet_len);
|
||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
s += packet_len;
|
||||
len -= packet_len;
|
||||
}
|
||||
/* Send a Zero-Length-Packet if the last packet is full size. */
|
||||
while (len != 0 || packet_len == VIRTUAL_COM_PORT_DATA_SIZE);
|
||||
|
||||
chopstx_mutex_unlock (&stdout.m);
|
||||
}
|
||||
|
||||
void
|
||||
EP3_IN_Callback (void)
|
||||
{
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
chopstx_cond_signal (&stdout.cond_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
}
|
||||
|
||||
void
|
||||
EP5_OUT_Callback (void)
|
||||
{
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
usb_lld_rx_enable (ENDP5);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
}
|
||||
#else
|
||||
void
|
||||
_write (const char *s, int size)
|
||||
{
|
||||
(void)s;
|
||||
(void)size;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void *USBthread (void *arg);
|
||||
|
||||
/*
|
||||
* main thread does 1-bit LED display output
|
||||
*/
|
||||
#define MAIN_TIMEOUT_INTERVAL (5000*1000)
|
||||
|
||||
#define LED_TIMEOUT_INTERVAL (75*1000)
|
||||
#define LED_TIMEOUT_ZERO (25*1000)
|
||||
#define LED_TIMEOUT_ONE (100*1000)
|
||||
@@ -195,59 +120,38 @@ static void display_fatal_code (void)
|
||||
|
||||
static uint8_t led_inverted;
|
||||
|
||||
static eventmask_t emit_led (int on_time, int off_time)
|
||||
static void emit_led (int on_time, int off_time)
|
||||
{
|
||||
eventmask_t m;
|
||||
|
||||
set_led (!led_inverted);
|
||||
m = eventflag_wait_timeout (&led_event, on_time);
|
||||
chopstx_usec_wait (on_time);
|
||||
set_led (led_inverted);
|
||||
if (m) return m;
|
||||
if ((m = eventflag_wait_timeout (&led_event, off_time)))
|
||||
return m;
|
||||
return 0;
|
||||
chopstx_usec_wait (off_time);
|
||||
}
|
||||
|
||||
static eventmask_t display_status_code (void)
|
||||
static void display_status_code (void)
|
||||
{
|
||||
eventmask_t m;
|
||||
enum icc_state icc_state = *icc_state_p;
|
||||
|
||||
if (icc_state == ICC_STATE_START)
|
||||
return emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
||||
emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP);
|
||||
else
|
||||
/* OpenPGP card thread running */
|
||||
/* OpenPGP card thread is running */
|
||||
{
|
||||
if ((m = emit_led ((auth_status & AC_ADMIN_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
||||
LED_TIMEOUT_INTERVAL)))
|
||||
return m;
|
||||
if ((m = emit_led ((auth_status & AC_OTHER_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
||||
LED_TIMEOUT_INTERVAL)))
|
||||
return m;
|
||||
if ((m = emit_led ((auth_status & AC_PSO_CDS_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
||||
LED_TIMEOUT_INTERVAL)))
|
||||
return m;
|
||||
emit_led ((auth_status & AC_ADMIN_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
emit_led ((auth_status & AC_OTHER_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
emit_led ((auth_status & AC_PSO_CDS_AUTHORIZED)?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_INTERVAL);
|
||||
|
||||
if (icc_state == ICC_STATE_WAIT)
|
||||
{
|
||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_STOP * 2)))
|
||||
return m;
|
||||
}
|
||||
chopstx_usec_wait (LED_TIMEOUT_STOP * 2);
|
||||
else
|
||||
{
|
||||
if ((m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_INTERVAL)))
|
||||
return m;
|
||||
|
||||
if ((m = emit_led (icc_state == ICC_STATE_RECEIVE?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO,
|
||||
LED_TIMEOUT_STOP)))
|
||||
return m;
|
||||
chopstx_usec_wait (LED_TIMEOUT_INTERVAL);
|
||||
emit_led (icc_state == ICC_STATE_RECEIVE?
|
||||
LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,19 +179,13 @@ calculate_regnual_entry_address (const uint8_t *addr)
|
||||
}
|
||||
|
||||
extern uint8_t __process1_stack_base__, __process1_stack_size__;
|
||||
extern uint8_t __process4_stack_base__, __process4_stack_size__;
|
||||
|
||||
const uint32_t __stackaddr_ccid = (uint32_t)&__process1_stack_base__;
|
||||
const size_t __stacksize_ccid = (size_t)&__process1_stack_size__;
|
||||
|
||||
const uint32_t __stackaddr_usb = (uint32_t)&__process4_stack_base__;
|
||||
const size_t __stacksize_usb = (size_t)&__process4_stack_size__;
|
||||
|
||||
#define PRIO_CCID 3
|
||||
#define PRIO_USB 4
|
||||
#define PRIO_MAIN 5
|
||||
|
||||
extern void *usb_intr (void *arg);
|
||||
extern void *ccid_thread (void *arg);
|
||||
|
||||
static void gnuk_malloc_init (void);
|
||||
|
||||
@@ -296,16 +194,11 @@ extern uint32_t bDeviceState;
|
||||
|
||||
/*
|
||||
* Entry point.
|
||||
*
|
||||
* NOTE: the main function is already a thread in the system on entry.
|
||||
* See the hwinit1_common function.
|
||||
*/
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
unsigned int count = 0;
|
||||
uint32_t entry;
|
||||
chopstx_t usb_thd;
|
||||
chopstx_t ccid_thd;
|
||||
|
||||
(void)argc;
|
||||
@@ -318,7 +211,7 @@ main (int argc, char *argv[])
|
||||
|
||||
adc_init ();
|
||||
|
||||
eventflag_init (&led_event, chopstx_main);
|
||||
eventflag_init (&led_event);
|
||||
|
||||
random_init ();
|
||||
|
||||
@@ -327,7 +220,7 @@ main (int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
ccid_thd = chopstx_create (PRIO_CCID, __stackaddr_ccid, __stacksize_ccid,
|
||||
USBthread, NULL);
|
||||
ccid_thread, NULL);
|
||||
|
||||
#ifdef PINPAD_CIR_SUPPORT
|
||||
cir_init ();
|
||||
@@ -336,10 +229,7 @@ main (int argc, char *argv[])
|
||||
msc_init ();
|
||||
#endif
|
||||
|
||||
usb_thd = chopstx_create (PRIO_USB, __stackaddr_usb, __stacksize_usb,
|
||||
usb_intr, NULL);
|
||||
|
||||
chopstx_main_init (PRIO_MAIN);
|
||||
chopstx_setpriority (PRIO_MAIN);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -353,56 +243,37 @@ main (int argc, char *argv[])
|
||||
{
|
||||
eventmask_t m;
|
||||
|
||||
m = eventflag_wait_timeout (&led_event, MAIN_TIMEOUT_INTERVAL);
|
||||
got_it:
|
||||
count++;
|
||||
m = eventflag_wait (&led_event);
|
||||
switch (m)
|
||||
{
|
||||
case LED_ONESHOT:
|
||||
if ((m = emit_led (100*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
emit_led (100*1000, LED_TIMEOUT_STOP);
|
||||
break;
|
||||
case LED_TWOSHOTS:
|
||||
if ((m = emit_led (50*1000, 50*1000))) goto got_it;
|
||||
if ((m = emit_led (50*1000, MAIN_TIMEOUT_INTERVAL))) goto got_it;
|
||||
emit_led (50*1000, 50*1000);
|
||||
emit_led (50*1000, LED_TIMEOUT_STOP);
|
||||
break;
|
||||
case LED_SHOW_STATUS:
|
||||
if ((count & 0x07) != 0) continue; /* Display once for eight times */
|
||||
if ((m = display_status_code ())) goto got_it;
|
||||
display_status_code ();
|
||||
break;
|
||||
case LED_START_COMMAND:
|
||||
set_led (1);
|
||||
led_inverted = 1;
|
||||
chopstx_usec_wait (LED_TIMEOUT_STOP);
|
||||
break;
|
||||
case LED_FINISH_COMMAND:
|
||||
m = eventflag_wait_timeout (&led_event, LED_TIMEOUT_STOP);
|
||||
led_inverted = 0;
|
||||
set_led (0);
|
||||
if (m)
|
||||
goto got_it;
|
||||
break;
|
||||
case LED_FATAL:
|
||||
display_fatal_code ();
|
||||
break;
|
||||
case LED_USB_RESET:
|
||||
ccid_usb_reset ();
|
||||
break;
|
||||
case LED_GNUK_EXEC:
|
||||
goto exec;
|
||||
default:
|
||||
if ((m = emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP)))
|
||||
goto got_it;
|
||||
emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MORE
|
||||
if (stdout.connected && (count % 10) == 0)
|
||||
{
|
||||
DEBUG_SHORT (count / 10);
|
||||
_write ("\r\nThis is Gnuk on STM32F103.\r\n"
|
||||
"Testing USB driver.\n\n"
|
||||
"Hello world\r\n\r\n", 30+21+15);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
exec:
|
||||
@@ -414,9 +285,6 @@ main (int argc, char *argv[])
|
||||
/* Finish application. */
|
||||
chopstx_join (ccid_thd, NULL);
|
||||
|
||||
chopstx_cancel (usb_thd);
|
||||
chopstx_join (usb_thd, NULL);
|
||||
|
||||
/* Set vector */
|
||||
SCB->VTOR = (uint32_t)&_regnual_start;
|
||||
entry = calculate_regnual_entry_address (&_regnual_start);
|
||||
@@ -458,6 +326,8 @@ main (int argc, char *argv[])
|
||||
void
|
||||
fatal (uint8_t code)
|
||||
{
|
||||
extern void _write (const char *s, int len);
|
||||
|
||||
fatal_code = code;
|
||||
eventflag_signal (&led_event, LED_FATAL);
|
||||
_write ("fatal\r\n", 7);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* modp256k1.c -- modulo arithmetic for p256k1
|
||||
*
|
||||
* Copyright (C) 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2014, 2016 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -55,12 +55,12 @@ const bn256 p256k1 = { {0xfffffc2f, 0xfffffffe, 0xffffffff, 0xffffffff,
|
||||
/*
|
||||
* Implementation Note.
|
||||
*
|
||||
* It's not always modulo p256k1. The representation is redundant
|
||||
* during computation. For example, when we add the prime - 1 and 1,
|
||||
* it won't overflow to 2^256, and the result is represented within
|
||||
* 256-bit.
|
||||
* It's always modulo p256k1.
|
||||
*
|
||||
* Once, I tried redundant representation which caused wrong
|
||||
* calculation. Implementation could be correct with redundant
|
||||
* representation, but it found that it's more expensive.
|
||||
*
|
||||
* It is guaranteed that modp256k1_reduce reduces to modulo p256k1.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -69,14 +69,16 @@ const bn256 p256k1 = { {0xfffffc2f, 0xfffffffe, 0xffffffff, 0xffffffff,
|
||||
void
|
||||
modp256k1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t carry;
|
||||
uint32_t cond;
|
||||
bn256 tmp[1];
|
||||
|
||||
carry = bn256_add (X, A, B);
|
||||
if (carry)
|
||||
bn256_sub (X, X, P256K1);
|
||||
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
|
||||
bn256_sub (tmp, X, P256K1);
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,10 +91,11 @@ modp256k1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
bn256 tmp[1];
|
||||
|
||||
borrow = bn256_sub (X, A, B);
|
||||
bn256_add (tmp, X, P256K1);
|
||||
if (borrow)
|
||||
bn256_add (X, X, P256K1);
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
else
|
||||
bn256_add (tmp, X, P256K1);
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* modp256r1.c -- modulo arithmetic for p256r1
|
||||
*
|
||||
* Copyright (C) 2011, 2013, 2014 Free Software Initiative of Japan
|
||||
* Copyright (C) 2011, 2013, 2014, 2016
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@@ -49,12 +50,12 @@ const bn256 p256r1 = { {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
|
||||
/*
|
||||
* Implementation Note.
|
||||
*
|
||||
* It's not always modulo p256r1. The representation is redundant
|
||||
* during computation. For example, when we add the prime - 1 and 1,
|
||||
* it won't overflow to 2^256, and the result is represented within
|
||||
* 256-bit.
|
||||
* It's always modulo p256r1.
|
||||
*
|
||||
* Once, I tried redundant representation which caused wrong
|
||||
* calculation. Implementation could be correct with redundant
|
||||
* representation, but it found that it's more expensive.
|
||||
*
|
||||
* It is guaranteed that modp256r1_reduce reduces to modulo p256r1.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -63,14 +64,16 @@ const bn256 p256r1 = { {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
|
||||
void
|
||||
modp256r1_add (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
{
|
||||
uint32_t carry;
|
||||
uint32_t cond;
|
||||
bn256 tmp[1];
|
||||
|
||||
carry = bn256_add (X, A, B);
|
||||
if (carry)
|
||||
bn256_sub (X, X, P256R1);
|
||||
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
|
||||
bn256_sub (tmp, X, P256R1);
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,10 +86,11 @@ modp256r1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
bn256 tmp[1];
|
||||
|
||||
borrow = bn256_sub (X, A, B);
|
||||
bn256_add (tmp, X, P256R1);
|
||||
if (borrow)
|
||||
bn256_add (X, X, P256R1);
|
||||
memcpy (X, tmp, sizeof (bn256));
|
||||
else
|
||||
bn256_add (tmp, X, P256R1);
|
||||
memcpy (tmp, tmp, sizeof (bn256));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +99,7 @@ modp256r1_sub (bn256 *X, const bn256 *A, const bn256 *B)
|
||||
void
|
||||
modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
{
|
||||
bn256 tmp[1];
|
||||
bn256 tmp[1], tmp0[1];
|
||||
uint32_t borrow;
|
||||
|
||||
#define S1 X
|
||||
@@ -116,6 +120,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S1->word[2] = A->word[2];
|
||||
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));
|
||||
/* X = S1 */
|
||||
|
||||
S2->word[7] = A->word[15];
|
||||
@@ -155,6 +164,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S5->word[2] = A->word[11];
|
||||
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));
|
||||
/* X += S5 */
|
||||
modp256r1_add (X, X, S5);
|
||||
|
||||
@@ -164,6 +178,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S6->word[2] = A->word[13];
|
||||
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));
|
||||
/* X -= S6 */
|
||||
modp256r1_sub (X, X, S6);
|
||||
|
||||
@@ -174,6 +193,11 @@ modp256r1_reduce (bn256 *X, const bn512 *A)
|
||||
S7->word[2] = A->word[14];
|
||||
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));
|
||||
/* X -= S7 */
|
||||
modp256r1_sub (X, X, S7);
|
||||
|
||||
|
||||
@@ -582,8 +582,8 @@ rng (void *arg)
|
||||
chopstx_cond_init (&mode_cond);
|
||||
|
||||
/* Enable ADCs */
|
||||
adc_start ();
|
||||
chopstx_claim_irq (&adc_intr, INTR_REQ_DMA1_Channel1);
|
||||
adc_start ();
|
||||
|
||||
ep_init (mode);
|
||||
while (!rng_should_terminate)
|
||||
@@ -641,7 +641,6 @@ rng (void *arg)
|
||||
}
|
||||
|
||||
adc_stop ();
|
||||
chopstx_release_irq (&adc_intr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* openpgp.c -- OpenPGP card protocol support
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -138,6 +138,7 @@ static void
|
||||
cmd_verify (void)
|
||||
{
|
||||
int len;
|
||||
uint8_t p1 = P1 (apdu);
|
||||
uint8_t p2 = P2 (apdu);
|
||||
int r;
|
||||
const uint8_t *pw;
|
||||
@@ -149,22 +150,36 @@ cmd_verify (void)
|
||||
pw = apdu.cmd_apdu_data;
|
||||
|
||||
if (len == 0)
|
||||
{ /* This is to examine status. */
|
||||
if (p2 == 0x81)
|
||||
r = ac_check_status (AC_PSO_CDS_AUTHORIZED);
|
||||
else if (p2 == 0x82)
|
||||
r = ac_check_status (AC_OTHER_AUTHORIZED);
|
||||
else
|
||||
r = ac_check_status (AC_ADMIN_AUTHORIZED);
|
||||
{
|
||||
if (p1 == 0)
|
||||
{ /* This is to examine status. */
|
||||
if (p2 == 0x81)
|
||||
r = ac_check_status (AC_PSO_CDS_AUTHORIZED);
|
||||
else if (p2 == 0x82)
|
||||
r = ac_check_status (AC_OTHER_AUTHORIZED);
|
||||
else
|
||||
r = ac_check_status (AC_ADMIN_AUTHORIZED);
|
||||
|
||||
if (r)
|
||||
GPG_SUCCESS (); /* If authentication done already, return success. */
|
||||
else
|
||||
{ /* If not, return retry counter, encoded. */
|
||||
r = gpg_pw_get_retry_counter (p2);
|
||||
set_res_sw (0x63, 0xc0 | (r&0x0f));
|
||||
if (r)
|
||||
GPG_SUCCESS (); /* If authentication done already, return success. */
|
||||
else
|
||||
{ /* If not, return retry counter, encoded. */
|
||||
r = gpg_pw_get_retry_counter (p2);
|
||||
set_res_sw (0x63, 0xc0 | (r&0x0f));
|
||||
}
|
||||
}
|
||||
|
||||
else if (p1 == 0xff)
|
||||
{ /* Reset the status. */
|
||||
if (p2 == 0x81)
|
||||
ac_reset_pso_cds ();
|
||||
else if (p2 == 0x82)
|
||||
ac_reset_other ();
|
||||
else
|
||||
ac_reset_admin ();
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
else
|
||||
GPG_BAD_P1_P2 ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -437,9 +452,12 @@ s2k (const unsigned char *salt, size_t slen,
|
||||
{
|
||||
sha256_context ctx;
|
||||
size_t count = S2KCOUNT;
|
||||
const uint8_t *unique = unique_device_id ();
|
||||
|
||||
sha256_start (&ctx);
|
||||
|
||||
sha256_update (&ctx, unique, 12);
|
||||
|
||||
while (count > slen + ilen)
|
||||
{
|
||||
if (slen)
|
||||
@@ -1407,7 +1425,7 @@ card_thread (chopstx_t thd, struct eventflag *ccid_comm)
|
||||
else if (m == EV_MODIFY_CMD_AVAILABLE)
|
||||
{
|
||||
#if defined(PINPAD_SUPPORT)
|
||||
uint8_t bConfirmPIN = apdu.cmd_apdu_data[5];
|
||||
uint8_t bConfirmPIN = apdu.cmd_apdu_data[0];
|
||||
uint8_t *p = apdu.cmd_apdu_data;
|
||||
|
||||
if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
|
||||
|
||||
48
src/sys.c
48
src/sys.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* sys.c - system routines for the initial page for STM32F103.
|
||||
*
|
||||
* Copyright (C) 2013, 2014, 2015 Flying Stone Technology
|
||||
* Copyright (C) 2013, 2014, 2015, 2016 Flying Stone Technology
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* Copying and distribution of this file, with or without modification,
|
||||
@@ -17,41 +17,8 @@
|
||||
#include <stdlib.h>
|
||||
#include "board.h"
|
||||
|
||||
#include "clk_gpio_init.c"
|
||||
#include "clk_gpio_init-stm32.c"
|
||||
|
||||
#define CORTEX_PRIORITY_BITS 4
|
||||
#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
|
||||
#define USB_LP_CAN1_RX0_IRQn 20
|
||||
#define STM32_USB_IRQ_PRIORITY 11
|
||||
|
||||
struct NVIC {
|
||||
uint32_t ISER[8];
|
||||
uint32_t unused1[24];
|
||||
uint32_t ICER[8];
|
||||
uint32_t unused2[24];
|
||||
uint32_t ISPR[8];
|
||||
uint32_t unused3[24];
|
||||
uint32_t ICPR[8];
|
||||
uint32_t unused4[24];
|
||||
uint32_t IABR[8];
|
||||
uint32_t unused5[56];
|
||||
uint32_t IPR[60];
|
||||
};
|
||||
|
||||
static struct NVIC *const NVICBase = ((struct NVIC *const)0xE000E100);
|
||||
#define NVIC_ISER(n) (NVICBase->ISER[n >> 5])
|
||||
#define NVIC_ICPR(n) (NVICBase->ICPR[n >> 5])
|
||||
#define NVIC_IPR(n) (NVICBase->IPR[n >> 2])
|
||||
|
||||
static void
|
||||
nvic_enable_vector (uint32_t n, uint32_t prio)
|
||||
{
|
||||
unsigned int sh = (n & 3) << 3;
|
||||
|
||||
NVIC_IPR (n) = (NVIC_IPR(n) & ~(0xFF << sh)) | (prio << sh);
|
||||
NVIC_ICPR (n) = 1 << (n & 0x1F);
|
||||
NVIC_ISER (n) = 1 << (n & 0x1F);
|
||||
}
|
||||
|
||||
static void
|
||||
usb_cable_config (int enable)
|
||||
@@ -118,13 +85,6 @@ usb_lld_sys_init (void)
|
||||
|
||||
usb_cable_config (1);
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
||||
nvic_enable_vector (USB_LP_CAN1_RX0_IRQn,
|
||||
CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
|
||||
/*
|
||||
* Note that we also have other IRQ(s):
|
||||
* USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
|
||||
* USBWakeUp_IRQn (suspend/resume)
|
||||
*/
|
||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
||||
RCC->APB1RSTR = 0;
|
||||
}
|
||||
@@ -423,8 +383,8 @@ handler vector[] __attribute__ ((section(".vectors"))) = {
|
||||
const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
|
||||
3*2+2, /* bLength */
|
||||
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE */
|
||||
/* sys version: "2.1" */
|
||||
'2', 0, '.', 0, '1', 0,
|
||||
/* sys version: "3.0" */
|
||||
'3', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
const uint32_t __attribute__((section(".sys.board_id")))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* usb-icc.c -- USB CCID protocol handling
|
||||
* usb-ccid.c -- USB CCID protocol handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -29,8 +29,14 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "debug.h"
|
||||
struct stdout stdout;
|
||||
#endif
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "usb_lld.h"
|
||||
#include "usb_conf.h"
|
||||
|
||||
/*
|
||||
* USB buffer size of USB-CCID driver
|
||||
@@ -248,7 +254,7 @@ static void ccid_reset (struct ccid *c)
|
||||
}
|
||||
|
||||
static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
|
||||
struct apdu *a, chopstx_t thd)
|
||||
struct apdu *a)
|
||||
{
|
||||
icc_state_p = &c->icc_state;
|
||||
|
||||
@@ -260,9 +266,7 @@ static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
|
||||
memset (&c->icc_header, 0, sizeof (struct icc_header));
|
||||
c->sw1sw2[0] = 0x90;
|
||||
c->sw1sw2[1] = 0x00;
|
||||
eventflag_init (&c->ccid_comm, thd);
|
||||
c->application = 0;
|
||||
eventflag_init (&c->openpgp_comm, 0);
|
||||
c->epi = epi;
|
||||
c->epo = epo;
|
||||
c->a = a;
|
||||
@@ -353,7 +357,7 @@ static void get_sw1sw2 (struct ep_in *epi, size_t len)
|
||||
/*
|
||||
* Tx done callback
|
||||
*/
|
||||
void
|
||||
static void
|
||||
EP1_IN_Callback (void)
|
||||
{
|
||||
struct ep_in *epi = &endpoint_in;
|
||||
@@ -630,7 +634,7 @@ icc_prepare_receive (struct ccid *c)
|
||||
* Rx ready callback
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
EP1_OUT_Callback (void)
|
||||
{
|
||||
struct ep_out *epo = &endpoint_out;
|
||||
@@ -671,6 +675,46 @@ EP1_OUT_Callback (void)
|
||||
}
|
||||
|
||||
|
||||
extern void EP6_IN_Callback (void);
|
||||
|
||||
void
|
||||
usb_cb_rx_ready (uint8_t ep_num)
|
||||
{
|
||||
if (ep_num == ENDP1)
|
||||
EP1_OUT_Callback ();
|
||||
#ifdef DEBUG
|
||||
else if (ep_num == ENDP5)
|
||||
{
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
usb_lld_rx_enable (ep_num);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
usb_cb_tx_done (uint8_t ep_num)
|
||||
{
|
||||
if (ep_num == ENDP1)
|
||||
EP1_IN_Callback ();
|
||||
else if (ep_num == ENDP2)
|
||||
{
|
||||
/* INTERRUPT Transfer done */
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else if (ep_num == ENDP3)
|
||||
{
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
chopstx_cond_signal (&stdout.cond_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
}
|
||||
#endif
|
||||
#ifdef PINPAD_SUPPORT
|
||||
else if (ep_num == ENDP6)
|
||||
EP6_IN_Callback ();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* ATR (Answer To Reset) string
|
||||
*
|
||||
@@ -1285,27 +1329,18 @@ icc_handle_timeout (struct ccid *c)
|
||||
{
|
||||
case ICC_STATE_EXECUTE:
|
||||
icc_send_data_block_time_extension (c);
|
||||
led_blink (LED_ONESHOT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
led_blink (LED_ONESHOT);
|
||||
return next_state;
|
||||
}
|
||||
|
||||
static struct ccid ccid;
|
||||
enum icc_state *icc_state_p = &ccid.icc_state;
|
||||
|
||||
/*
|
||||
* Another Tx done callback
|
||||
*/
|
||||
void
|
||||
EP2_IN_Callback (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ccid_card_change_signal (int how)
|
||||
{
|
||||
@@ -1329,40 +1364,54 @@ ccid_usb_reset (void)
|
||||
|
||||
#define GPG_THREAD_TERMINATED 0xffff
|
||||
|
||||
static void *ccid_thread (chopstx_t) __attribute__ ((noinline));
|
||||
|
||||
void * __attribute__ ((naked))
|
||||
USBthread (void *arg)
|
||||
{
|
||||
chopstx_t thd;
|
||||
(void)arg;
|
||||
|
||||
asm ("mov %0, sp" : "=r" (thd));
|
||||
return ccid_thread (thd);
|
||||
}
|
||||
|
||||
#define NOTIFY_SLOT_CHANGE 0x50
|
||||
|
||||
static void * __attribute__ ((noinline))
|
||||
ccid_thread (chopstx_t thd)
|
||||
#define INTR_REQ_USB 20
|
||||
|
||||
void *
|
||||
ccid_thread (void *arg)
|
||||
{
|
||||
extern uint32_t bDeviceState;
|
||||
chopstx_intr_t interrupt;
|
||||
uint32_t timeout;
|
||||
|
||||
struct ep_in *epi = &endpoint_in;
|
||||
struct ep_out *epo = &endpoint_out;
|
||||
struct ccid *c = &ccid;
|
||||
struct apdu *a = &apdu;
|
||||
|
||||
(void)arg;
|
||||
|
||||
eventflag_init (&ccid.ccid_comm);
|
||||
eventflag_init (&ccid.openpgp_comm);
|
||||
|
||||
usb_lld_init (USB_INITIAL_FEATURE);
|
||||
chopstx_claim_irq (&interrupt, INTR_REQ_USB);
|
||||
usb_interrupt_handler (); /* For old SYS < 3.0 */
|
||||
|
||||
reset:
|
||||
epi_init (epi, ENDP1, notify_tx, c);
|
||||
epo_init (epo, ENDP1, notify_icc, c);
|
||||
apdu_init (a);
|
||||
ccid_init (c, epi, epo, a, thd);
|
||||
ccid_init (c, epi, epo, a);
|
||||
|
||||
timeout = USB_ICC_TIMEOUT;
|
||||
icc_prepare_receive (c);
|
||||
while (1)
|
||||
{
|
||||
eventmask_t m;
|
||||
chopstx_poll_cond_t poll_desc;
|
||||
|
||||
m = eventflag_wait_timeout (&c->ccid_comm, USB_ICC_TIMEOUT);
|
||||
eventflag_prepare_poll (&c->ccid_comm, &poll_desc);
|
||||
chopstx_poll (&timeout, 2, &interrupt, &poll_desc);
|
||||
if (interrupt.ready)
|
||||
{
|
||||
usb_interrupt_handler ();
|
||||
continue;
|
||||
}
|
||||
|
||||
timeout = USB_ICC_TIMEOUT;
|
||||
m = eventflag_get (&c->ccid_comm);
|
||||
|
||||
if (m == EV_USB_RESET)
|
||||
{
|
||||
@@ -1465,5 +1514,66 @@ ccid_thread (chopstx_t thd)
|
||||
c->application = 0;
|
||||
}
|
||||
|
||||
/* Loading reGNUal. */
|
||||
while (bDeviceState != UNCONNECTED)
|
||||
{
|
||||
chopstx_poll (NULL, 1, &interrupt);
|
||||
usb_interrupt_handler ();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
stdout_init (void)
|
||||
{
|
||||
chopstx_mutex_init (&stdout.m);
|
||||
chopstx_mutex_init (&stdout.m_dev);
|
||||
chopstx_cond_init (&stdout.cond_dev);
|
||||
stdout.connected = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_write (const char *s, int len)
|
||||
{
|
||||
int packet_len;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
chopstx_mutex_lock (&stdout.m);
|
||||
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
if (!stdout.connected)
|
||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
do
|
||||
{
|
||||
packet_len =
|
||||
(len < VIRTUAL_COM_PORT_DATA_SIZE) ? len : VIRTUAL_COM_PORT_DATA_SIZE;
|
||||
|
||||
chopstx_mutex_lock (&stdout.m_dev);
|
||||
usb_lld_write (ENDP3, s, packet_len);
|
||||
chopstx_cond_wait (&stdout.cond_dev, &stdout.m_dev);
|
||||
chopstx_mutex_unlock (&stdout.m_dev);
|
||||
|
||||
s += packet_len;
|
||||
len -= packet_len;
|
||||
}
|
||||
/* Send a Zero-Length-Packet if the last packet is full size. */
|
||||
while (len != 0 || packet_len == VIRTUAL_COM_PORT_DATA_SIZE);
|
||||
|
||||
chopstx_mutex_unlock (&stdout.m);
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
_write (const char *s, int size)
|
||||
{
|
||||
(void)s;
|
||||
(void)size;
|
||||
}
|
||||
#endif
|
||||
107
src/usb_ctrl.c
107
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
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@@ -61,12 +61,12 @@ static struct line_coding line_coding = {
|
||||
#define CDC_CTRL_DTR 0x0001
|
||||
|
||||
static int
|
||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
vcom_port_data_setup (uint8_t req, uint8_t req_no, struct req_args *arg)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_CDC_REQ_GET_LINE_CODING)
|
||||
return usb_lld_reply_request (&line_coding, sizeof(line_coding), detail);
|
||||
return usb_lld_reply_request (&line_coding, sizeof(line_coding), arg);
|
||||
}
|
||||
else /* USB_SETUP_SET (req) */
|
||||
{
|
||||
@@ -79,7 +79,7 @@ vcom_port_data_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
{
|
||||
uint8_t connected_saved = stdout.connected;
|
||||
|
||||
if ((detail->value & CDC_CTRL_DTR) != 0)
|
||||
if ((arg->value & CDC_CTRL_DTR) != 0)
|
||||
{
|
||||
if (stdout.connected == 0)
|
||||
/* It's Open call */
|
||||
@@ -199,13 +199,7 @@ usb_cb_device_reset (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Set DEVICE as not configured */
|
||||
usb_lld_set_configuration (0);
|
||||
|
||||
/* Current Feature initialization */
|
||||
usb_lld_set_feature (USB_INITIAL_FEATURE);
|
||||
|
||||
usb_lld_reset ();
|
||||
usb_lld_reset (USB_INITIAL_FEATURE);
|
||||
|
||||
/* Initialize Endpoint 0 */
|
||||
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
|
||||
@@ -216,7 +210,7 @@ usb_cb_device_reset (void)
|
||||
gnuk_setup_endpoints_for_interface (i, 1);
|
||||
|
||||
bDeviceState = ATTACHED;
|
||||
led_blink (LED_USB_RESET); /* Notify the main. */
|
||||
ccid_usb_reset ();
|
||||
}
|
||||
|
||||
#define USB_CCID_REQ_ABORT 0x01
|
||||
@@ -264,7 +258,7 @@ static int download_check_crc32 (const uint32_t *end_p)
|
||||
}
|
||||
|
||||
int
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
@@ -273,27 +267,29 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_FSIJ_GNUK_MEMINFO)
|
||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), detail);
|
||||
return usb_lld_reply_request (mem_info, sizeof (mem_info), arg);
|
||||
}
|
||||
else /* SETUP_SET */
|
||||
{
|
||||
uint8_t *addr = (uint8_t *)(0x20000000 + detail->value * 0x100 + detail->index);
|
||||
uint8_t *addr = (uint8_t *)(0x20000000 + arg->value * 0x100
|
||||
+ arg->index);
|
||||
|
||||
if (req_no == USB_FSIJ_GNUK_DOWNLOAD)
|
||||
{
|
||||
if (*icc_state_p != ICC_STATE_EXITED)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (addr < &_regnual_start || addr + detail->len > __heap_end__)
|
||||
if (addr < &_regnual_start || addr + arg->len > __heap_end__)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->index + detail->len < 256)
|
||||
memset (addr + detail->index + detail->len, 0, 256 - (detail->index + detail->len));
|
||||
if (arg->index + arg->len < 256)
|
||||
memset (addr + arg->index + arg->len, 0,
|
||||
256 - (arg->index + arg->len));
|
||||
|
||||
usb_lld_set_data_to_recv (addr, detail->len);
|
||||
usb_lld_set_data_to_recv (addr, arg->len);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_FSIJ_GNUK_EXEC && detail->len == 0)
|
||||
else if (req_no == USB_FSIJ_GNUK_EXEC && arg->len == 0)
|
||||
{
|
||||
if (*icc_state_p != ICC_STATE_EXITED)
|
||||
return USB_UNSUPPORT;
|
||||
@@ -303,28 +299,28 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
|
||||
return download_check_crc32 ((uint32_t *)addr);
|
||||
}
|
||||
else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && detail->len == 0)
|
||||
else if (req_no == USB_FSIJ_GNUK_CARD_CHANGE && arg->len == 0)
|
||||
{
|
||||
if (detail->value != 0 && detail->value != 1 && detail->value != 2)
|
||||
if (arg->value != 0 && arg->value != 1 && arg->value != 2)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
ccid_card_change_signal (detail->value);
|
||||
ccid_card_change_signal (arg->value);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||
{
|
||||
if (detail->index == ICC_INTERFACE)
|
||||
if (arg->index == ICC_INTERFACE)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
|
||||
return usb_lld_reply_request (freq_table, sizeof (freq_table),
|
||||
detail);
|
||||
arg);
|
||||
else if (req_no == USB_CCID_REQ_GET_DATA_RATES)
|
||||
return usb_lld_reply_request (data_rate_table,
|
||||
sizeof (data_rate_table), detail);
|
||||
sizeof (data_rate_table), arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -335,24 +331,24 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
}
|
||||
}
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
else if (index == HID_INTERFACE)
|
||||
else if (arg->index == HID_INTERFACE)
|
||||
{
|
||||
switch (req_no)
|
||||
{
|
||||
case USB_HID_REQ_GET_IDLE:
|
||||
return usb_lld_reply_request (&hid_idle_rate, 1, detail);
|
||||
return usb_lld_reply_request (&hid_idle_rate, 1, arg);
|
||||
case USB_HID_REQ_SET_IDLE:
|
||||
usb_lld_set_data_to_recv (&hid_idle_rate, 1, detail);
|
||||
usb_lld_set_data_to_recv (&hid_idle_rate, 1);
|
||||
return USB_SUCCESS;
|
||||
|
||||
case USB_HID_REQ_GET_REPORT:
|
||||
/* Request of LED status and key press */
|
||||
return usb_lld_reply_request (&hid_report, 2, detail);
|
||||
return usb_lld_reply_request (&hid_report, 2, arg);
|
||||
|
||||
case USB_HID_REQ_SET_REPORT:
|
||||
/* Received LED set request */
|
||||
if (detail->len == 1)
|
||||
usb_lld_set_data_to_recv (&hid_report, detail->len);
|
||||
if (arg->len == 1)
|
||||
usb_lld_set_data_to_recv (&hid_report, arg->len);
|
||||
return USB_SUCCESS;
|
||||
|
||||
case USB_HID_REQ_GET_PROTOCOL:
|
||||
@@ -366,17 +362,17 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
else if (index == VCOM_INTERFACE_0)
|
||||
return vcom_port_data_setup (req, req_no, detail);
|
||||
else if (arg->index == VCOM_INTERFACE_0)
|
||||
return vcom_port_data_setup (req, req_no, arg);
|
||||
#endif
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
else if (index == MSC_INTERFACE)
|
||||
else if (arg->index == MSC_INTERFACE)
|
||||
{
|
||||
if (USB_SETUP_GET (req))
|
||||
{
|
||||
if (req_no == MSC_GET_MAX_LUN_COMMAND)
|
||||
return usb_lld_reply_request (lun_table, sizeof (lun_table),
|
||||
detail);
|
||||
arg);
|
||||
}
|
||||
else
|
||||
if (req_no == MSC_MASS_STORAGE_RESET_COMMAND)
|
||||
@@ -391,10 +387,11 @@ usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail)
|
||||
|
||||
|
||||
void
|
||||
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, struct req_args *arg)
|
||||
{
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
(void)arg;
|
||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
|
||||
{
|
||||
if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC)
|
||||
@@ -402,7 +399,7 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
if (*icc_state_p != ICC_STATE_EXITED)
|
||||
return;
|
||||
|
||||
(void)value; (void)index;
|
||||
bDeviceState = UNCONNECTED;
|
||||
usb_lld_prepare_shutdown (); /* No further USB communication */
|
||||
led_blink (LED_GNUK_EXEC); /* Notify the main. */
|
||||
}
|
||||
@@ -410,7 +407,7 @@ usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value)
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
|
||||
{
|
||||
if (index == HID_INTERFACE && req_no == USB_HID_REQ_SET_REPORT)
|
||||
if (arg->index == HID_INTERFACE && req_no == USB_HID_REQ_SET_REPORT)
|
||||
{
|
||||
if ((hid_report ^ hid_report_saved) & HID_LED_STATUS_CARDCHANGE)
|
||||
ccid_card_change_signal (CARD_CHANGE_TOGGLE);
|
||||
@@ -464,11 +461,11 @@ int usb_cb_handle_event (uint8_t event_type, uint16_t value)
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
||||
int usb_cb_interface (uint8_t cmd, struct req_args *arg)
|
||||
{
|
||||
const uint8_t zero = 0;
|
||||
uint16_t interface = detail->index;
|
||||
uint16_t alt = detail->value;
|
||||
uint16_t interface = arg->index;
|
||||
uint16_t alt = arg->value;
|
||||
|
||||
if (interface >= NUM_INTERFACES)
|
||||
return USB_UNSUPPORT;
|
||||
@@ -485,34 +482,10 @@ int usb_cb_interface (uint8_t cmd, struct control_info *detail)
|
||||
}
|
||||
|
||||
case USB_GET_INTERFACE:
|
||||
return usb_lld_reply_request (&zero, 1, detail);
|
||||
return usb_lld_reply_request (&zero, 1, arg);
|
||||
|
||||
case USB_QUERY_INTERFACE:
|
||||
default:
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define INTR_REQ_USB 20
|
||||
|
||||
void *
|
||||
usb_intr (void *arg)
|
||||
{
|
||||
chopstx_intr_t interrupt;
|
||||
|
||||
(void)arg;
|
||||
usb_lld_init (USB_INITIAL_FEATURE);
|
||||
chopstx_claim_irq (&interrupt, INTR_REQ_USB);
|
||||
usb_interrupt_handler ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
chopstx_intr_wait (&interrupt);
|
||||
|
||||
/* Process interrupt. */
|
||||
usb_interrupt_handler ();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ static const uint8_t hid_report_desc[] = {
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t device_desc[] = {
|
||||
18, /* bLength */
|
||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
DEVICE_DESCRIPTOR, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB = 1.1 */
|
||||
0x00, /* bDeviceClass: 0 means deferred to interface */
|
||||
0x00, /* bDeviceSubClass */
|
||||
@@ -101,9 +101,9 @@ static const uint8_t device_desc[] = {
|
||||
/* Configuation Descriptor */
|
||||
static const uint8_t config_desc[] = {
|
||||
9, /* bLength: Configuation Descriptor size */
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
||||
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
|
||||
NUM_INTERFACES, /* bNumInterfaces: */
|
||||
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
|
||||
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
|
||||
NUM_INTERFACES, /* bNumInterfaces: */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
USB_INITIAL_FEATURE, /* bmAttributes*/
|
||||
@@ -111,7 +111,7 @@ static const uint8_t config_desc[] = {
|
||||
|
||||
/* Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
ICC_INTERFACE, /* bInterfaceNumber: Index of this interface */
|
||||
0, /* Alternate setting for this interface */
|
||||
3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
|
||||
@@ -167,21 +167,21 @@ static const uint8_t config_desc[] = {
|
||||
1, /* bMaxCCIDBusySlots: 1 */
|
||||
/*Endpoint IN1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x81, /* bEndpointAddress: (IN1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint OUT1 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x01, /* bEndpointAddress: (OUT1) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval */
|
||||
/*Endpoint IN2 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x82, /* bEndpointAddress: (IN2) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
0x04, 0x00, /* wMaxPacketSize: 4 */
|
||||
@@ -190,7 +190,7 @@ static const uint8_t config_desc[] = {
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
/* Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
HID_INTERFACE, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoint used */
|
||||
@@ -209,7 +209,7 @@ static const uint8_t config_desc[] = {
|
||||
|
||||
/*Endpoint IN7 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x87, /* bEndpointAddress: (IN7) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
0x02, 0x00, /* wMaxPacketSize: 2 */
|
||||
@@ -219,7 +219,7 @@ static const uint8_t config_desc[] = {
|
||||
#ifdef ENABLE_VIRTUAL_COM_PORT
|
||||
/* Interface Descriptor */
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
VCOM_INTERFACE_0, /* bInterfaceNumber: Index of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoints used */
|
||||
@@ -251,7 +251,7 @@ static const uint8_t config_desc[] = {
|
||||
VCOM_INTERFACE_1, /* bSlaveInterface0: Data Class Interface */
|
||||
/*Endpoint 4 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x84, /* bEndpointAddress: (IN4) */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
VIRTUAL_COM_PORT_INT_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
@@ -259,7 +259,7 @@ static const uint8_t config_desc[] = {
|
||||
|
||||
/*Data class interface descriptor*/
|
||||
9, /* bLength: Endpoint Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: */
|
||||
VCOM_INTERFACE_1, /* bInterfaceNumber: Index of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: Two endpoints used */
|
||||
@@ -269,14 +269,14 @@ static const uint8_t config_desc[] = {
|
||||
0x00, /* iInterface: */
|
||||
/*Endpoint 5 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x05, /* bEndpointAddress: (OUT5) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
/*Endpoint 3 Descriptor*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x83, /* bEndpointAddress: (IN3) */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
|
||||
@@ -285,7 +285,7 @@ static const uint8_t config_desc[] = {
|
||||
#ifdef PINPAD_DND_SUPPORT
|
||||
/* Interface Descriptor.*/
|
||||
9, /* bLength: Interface Descriptor size */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
|
||||
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
|
||||
MSC_INTERFACE, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x02, /* bNumEndpoints. */
|
||||
@@ -298,14 +298,14 @@ static const uint8_t config_desc[] = {
|
||||
0x00, /* iInterface. */
|
||||
/* Endpoint Descriptor.*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x86, /* bEndpointAddress: (IN6) */
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x40, 0x00, /* wMaxPacketSize. */
|
||||
0x00, /* bInterval (ignored for bulk). */
|
||||
/* Endpoint Descriptor.*/
|
||||
7, /* bLength: Endpoint Descriptor size */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
|
||||
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
|
||||
0x06, /* bEndpointAddress: (OUT6) */
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x40, 0x00, /* wMaxPacketSize. */
|
||||
@@ -317,7 +317,7 @@ static const uint8_t config_desc[] = {
|
||||
/* USB String Descriptors */
|
||||
static const uint8_t gnuk_string_lang_id[] = {
|
||||
4, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
STRING_DESCRIPTOR,
|
||||
0x09, 0x04 /* LangID = 0x0409: US-English */
|
||||
};
|
||||
|
||||
@@ -346,20 +346,20 @@ static const struct desc string_descriptors[] = {
|
||||
|
||||
int
|
||||
usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
struct control_info *detail)
|
||||
struct req_args *arg)
|
||||
{
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (desc_type == DEVICE_DESCRIPTOR)
|
||||
return usb_lld_reply_request (device_desc, sizeof (device_desc), detail);
|
||||
return usb_lld_reply_request (device_desc, sizeof (device_desc), arg);
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
return usb_lld_reply_request (config_desc, sizeof (config_desc), detail);
|
||||
return usb_lld_reply_request (config_desc, sizeof (config_desc), arg);
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
{
|
||||
if (desc_index < NUM_STRING_DESC)
|
||||
return usb_lld_reply_request (string_descriptors[desc_index].desc,
|
||||
string_descriptors[desc_index].size,
|
||||
detail);
|
||||
arg);
|
||||
else if (desc_index == NUM_STRING_DESC)
|
||||
{
|
||||
uint8_t usbbuf[64];
|
||||
@@ -375,22 +375,22 @@ usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
usbbuf[i*2+3] = 0;
|
||||
}
|
||||
usbbuf[0] = len = i*2 + 2;
|
||||
usbbuf[1] = USB_STRING_DESCRIPTOR_TYPE;
|
||||
return usb_lld_reply_request (usbbuf, len, detail);
|
||||
usbbuf[1] = STRING_DESCRIPTOR;
|
||||
return usb_lld_reply_request (usbbuf, len, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HID_CARD_CHANGE_SUPPORT
|
||||
else if (rcp == INTERFACE_RECIPIENT)
|
||||
{
|
||||
if (detail->index == 1)
|
||||
if (arg->index == HID_INTERFACE)
|
||||
{
|
||||
if (desc_type == USB_DT_HID)
|
||||
return usb_lld_reply_request (config_desc+ICC_TOTAL_LENGTH+9, 9,
|
||||
detail);
|
||||
arg);
|
||||
else if (desc_type == USB_DT_REPORT)
|
||||
return usb_lld_reply_request (hid_report_desc, HID_REPORT_DESC_SIZE,
|
||||
detail);
|
||||
arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
|
||||
#define USB_STRING_DESCRIPTOR_TYPE 0x03
|
||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
|
||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
|
||||
|
||||
#define STANDARD_ENDPOINT_DESC_SIZE 0x09
|
||||
|
||||
/* endpoints enumeration */
|
||||
@@ -24,7 +18,7 @@
|
||||
|
||||
enum RECIPIENT_TYPE
|
||||
{
|
||||
DEVICE_RECIPIENT, /* Recipient device */
|
||||
DEVICE_RECIPIENT = 0, /* Recipient device */
|
||||
INTERFACE_RECIPIENT, /* Recipient interface */
|
||||
ENDPOINT_RECIPIENT, /* Recipient endpoint */
|
||||
OTHER_RECIPIENT
|
||||
@@ -55,19 +49,22 @@ enum
|
||||
USB_SUCCESS = 1,
|
||||
};
|
||||
|
||||
struct control_info {
|
||||
struct req_args {
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
void usb_cb_device_reset (void);
|
||||
int usb_cb_setup (uint8_t req, uint8_t req_no, struct control_info *detail);
|
||||
int usb_cb_interface (uint8_t cmd, struct control_info *detail);
|
||||
int usb_cb_setup (uint8_t req, uint8_t req_no, struct req_args *arg);
|
||||
int usb_cb_interface (uint8_t cmd, struct req_args *arg);
|
||||
int usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
|
||||
struct control_info *detail);
|
||||
struct req_args *arg);
|
||||
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value);
|
||||
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
struct req_args *arg);
|
||||
void usb_cb_tx_done (uint8_t ep_num);
|
||||
void usb_cb_rx_ready (uint8_t ep_num);
|
||||
|
||||
enum {
|
||||
USB_EVENT_ADDRESS,
|
||||
@@ -103,18 +100,17 @@ void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len);
|
||||
void usb_lld_tx_enable (int ep_num, size_t len);
|
||||
void usb_lld_write (uint8_t ep_num, const void *buf, size_t len);
|
||||
int usb_lld_reply_request (const void *buf, size_t buflen,
|
||||
struct control_info *ctrl);
|
||||
struct req_args *arg);
|
||||
void usb_lld_rx_enable (int ep_num);
|
||||
int usb_lld_rx_data_len (int ep_num);
|
||||
void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len);
|
||||
void usb_lld_reset (void);
|
||||
void usb_lld_reset (uint8_t feature);
|
||||
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_set_configuration (uint8_t config);
|
||||
uint8_t usb_lld_current_configuration (void);
|
||||
void usb_lld_set_feature (uint8_t feature);
|
||||
void usb_lld_set_data_to_recv (const void *p, size_t len);
|
||||
void usb_lld_set_data_to_recv (void *p, size_t len);
|
||||
|
||||
void usb_lld_prepare_shutdown (void);
|
||||
void usb_lld_shutdown (void);
|
||||
|
||||
@@ -62,6 +62,8 @@ struct DEVICE_INFO
|
||||
uint8_t bRequest;
|
||||
/**/
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
static struct DEVICE_INFO device_info;
|
||||
@@ -353,7 +355,7 @@ void usb_lld_init (uint8_t feature)
|
||||
dev_p->state = IN_DATA;
|
||||
|
||||
usb_lld_set_configuration (0);
|
||||
usb_lld_set_feature (feature);
|
||||
dev_p->current_feature = feature;
|
||||
|
||||
/* Reset USB */
|
||||
st103_set_cntr (CNTR_FRES);
|
||||
@@ -462,26 +464,26 @@ static void handle_datastage_in (void)
|
||||
st103_ep_set_tx_status (ENDP0, EP_TX_VALID);
|
||||
}
|
||||
|
||||
typedef int (*HANDLER) (uint8_t req, struct control_info *detail);
|
||||
typedef int (*HANDLER) (uint8_t req, struct req_args *arg);
|
||||
|
||||
static int std_none (uint8_t req, struct control_info *detail)
|
||||
static int std_none (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
(void)req; (void)detail;
|
||||
(void)req; (void)arg;
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_get_status (uint8_t req, struct control_info *detail)
|
||||
static int std_get_status (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
uint16_t status_info = 0;
|
||||
|
||||
if (detail->value != 0 || detail->len != 2 || (detail->index >> 8) != 0
|
||||
|| (req & REQUEST_DIR) == 0)
|
||||
if (arg->value != 0 || arg->len != 2 || (arg->index >> 8) != 0
|
||||
|| USB_SETUP_SET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (detail->index == 0)
|
||||
if (arg->index == 0)
|
||||
{
|
||||
/* Get Device Status */
|
||||
uint8_t feature = dev_p->current_feature;
|
||||
@@ -498,7 +500,7 @@ static int std_get_status (uint8_t req, struct control_info *detail)
|
||||
else /* Self-powered */
|
||||
status_info &= ~1;
|
||||
|
||||
return usb_lld_reply_request (&status_info, 2, detail);
|
||||
return usb_lld_reply_request (&status_info, 2, arg);
|
||||
}
|
||||
}
|
||||
else if (rcp == INTERFACE_RECIPIENT)
|
||||
@@ -508,21 +510,21 @@ static int std_get_status (uint8_t req, struct control_info *detail)
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
r = usb_cb_interface (USB_QUERY_INTERFACE, detail);
|
||||
r = usb_cb_interface (USB_QUERY_INTERFACE, arg);
|
||||
if (r != USB_SUCCESS)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
return usb_lld_reply_request (&status_info, 2, detail);
|
||||
return usb_lld_reply_request (&status_info, 2, arg);
|
||||
}
|
||||
else if (rcp == ENDPOINT_RECIPIENT)
|
||||
{
|
||||
uint8_t endpoint = (detail->index & 0x0f);
|
||||
uint8_t endpoint = (arg->index & 0x0f);
|
||||
uint16_t status;
|
||||
|
||||
if ((detail->index & 0x70) || endpoint == ENDP0)
|
||||
if ((arg->index & 0x70) || endpoint == ENDP0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if ((detail->index & 0x80))
|
||||
if ((arg->index & 0x80))
|
||||
{
|
||||
status = st103_ep_get_tx_status (endpoint);
|
||||
if (status == 0) /* Disabled */
|
||||
@@ -539,25 +541,25 @@ static int std_get_status (uint8_t req, struct control_info *detail)
|
||||
status_info |= 1; /* OUT Endpoint stalled */
|
||||
}
|
||||
|
||||
return usb_lld_reply_request (&status_info, 2, detail);
|
||||
return usb_lld_reply_request (&status_info, 2, arg);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_clear_feature (uint8_t req, struct control_info *detail)
|
||||
static int std_clear_feature (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1)
|
||||
if (USB_SETUP_GET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (detail->len != 0 || detail->index != 0)
|
||||
if (arg->len != 0 || arg->index != 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->value == DEVICE_REMOTE_WAKEUP)
|
||||
if (arg->value == DEVICE_REMOTE_WAKEUP)
|
||||
{
|
||||
dev_p->current_feature &= ~(1 << 5);
|
||||
return USB_SUCCESS;
|
||||
@@ -565,17 +567,17 @@ static int std_clear_feature (uint8_t req, struct control_info *detail)
|
||||
}
|
||||
else if (rcp == ENDPOINT_RECIPIENT)
|
||||
{
|
||||
uint8_t endpoint = (detail->index & 0x0f);
|
||||
uint8_t endpoint = (arg->index & 0x0f);
|
||||
uint16_t status;
|
||||
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->len != 0 || (detail->index >> 8) != 0
|
||||
|| detail->value != ENDPOINT_STALL || endpoint == ENDP0)
|
||||
if (arg->len != 0 || (arg->index >> 8) != 0
|
||||
|| arg->value != ENDPOINT_STALL || endpoint == ENDP0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if ((detail->index & 0x80))
|
||||
if ((arg->index & 0x80))
|
||||
status = st103_ep_get_tx_status (endpoint);
|
||||
else
|
||||
status = st103_ep_get_rx_status (endpoint);
|
||||
@@ -583,7 +585,7 @@ static int std_clear_feature (uint8_t req, struct control_info *detail)
|
||||
if (status == 0) /* Disabled */
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->index & 0x80) /* IN endpoint */
|
||||
if (arg->index & 0x80) /* IN endpoint */
|
||||
st103_ep_clear_dtog_tx (endpoint);
|
||||
else /* OUT endpoint */
|
||||
st103_ep_clear_dtog_rx (endpoint);
|
||||
@@ -595,19 +597,19 @@ static int std_clear_feature (uint8_t req, struct control_info *detail)
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_feature (uint8_t req, struct control_info *detail)
|
||||
static int std_set_feature (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1)
|
||||
if (USB_SETUP_GET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
{
|
||||
if (detail->len != 0 || detail->index != 0)
|
||||
if (arg->len != 0 || arg->index != 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->value == DEVICE_REMOTE_WAKEUP)
|
||||
if (arg->value == DEVICE_REMOTE_WAKEUP)
|
||||
{
|
||||
dev_p->current_feature |= 1 << 5;
|
||||
// event??
|
||||
@@ -616,17 +618,17 @@ static int std_set_feature (uint8_t req, struct control_info *detail)
|
||||
}
|
||||
else if (rcp == ENDPOINT_RECIPIENT)
|
||||
{
|
||||
uint8_t endpoint = (detail->index & 0x0f);
|
||||
uint8_t endpoint = (arg->index & 0x0f);
|
||||
uint32_t status;
|
||||
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->len != 0 || (detail->index >> 8) != 0
|
||||
|| detail->value != 0 || endpoint == ENDP0)
|
||||
if (arg->len != 0 || (arg->index >> 8) != 0
|
||||
|| arg->value != 0 || endpoint == ENDP0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if ((detail->index & 0x80))
|
||||
if ((arg->index & 0x80))
|
||||
status = st103_ep_get_tx_status (endpoint);
|
||||
else
|
||||
status = st103_ep_get_rx_status (endpoint);
|
||||
@@ -634,7 +636,7 @@ static int std_set_feature (uint8_t req, struct control_info *detail)
|
||||
if (status == 0) /* Disabled */
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (detail->index & 0x80)
|
||||
if (arg->index & 0x80)
|
||||
/* IN endpoint */
|
||||
st103_ep_set_tx_status (endpoint, EP_TX_STALL);
|
||||
else
|
||||
@@ -648,96 +650,94 @@ static int std_set_feature (uint8_t req, struct control_info *detail)
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_address (uint8_t req, struct control_info *detail)
|
||||
static int std_set_address (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1)
|
||||
if (USB_SETUP_GET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT && detail->len == 0 && detail->value <= 127
|
||||
&& detail->index == 0 && dev_p->current_configuration == 0)
|
||||
if (rcp == DEVICE_RECIPIENT && arg->len == 0 && arg->value <= 127
|
||||
&& arg->index == 0 && dev_p->current_configuration == 0)
|
||||
return USB_SUCCESS;
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_get_descriptor (uint8_t req, struct control_info *detail)
|
||||
static int std_get_descriptor (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 0)
|
||||
if (USB_SETUP_SET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
return usb_cb_get_descriptor (rcp, (detail->value >> 8),
|
||||
(detail->value & 0xff), detail);
|
||||
return usb_cb_get_descriptor (rcp, (arg->value >> 8),
|
||||
(arg->value & 0xff), arg);
|
||||
}
|
||||
|
||||
static int std_get_configuration (uint8_t req, struct control_info *detail)
|
||||
static int std_get_configuration (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
(void)detail;
|
||||
if ((req & REQUEST_DIR) == 0)
|
||||
if (USB_SETUP_SET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT)
|
||||
return usb_lld_reply_request (&dev_p->current_configuration, 1, detail);
|
||||
return usb_lld_reply_request (&dev_p->current_configuration, 1, arg);
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_configuration (uint8_t req, struct control_info *detail)
|
||||
static int std_set_configuration (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1)
|
||||
if (USB_SETUP_GET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == DEVICE_RECIPIENT && detail->index == 0 && detail->len == 0)
|
||||
return usb_cb_handle_event (USB_EVENT_CONFIG, detail->value);
|
||||
if (rcp == DEVICE_RECIPIENT && arg->index == 0 && arg->len == 0)
|
||||
return usb_cb_handle_event (USB_EVENT_CONFIG, arg->value);
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_get_interface (uint8_t req, struct control_info *detail)
|
||||
static int std_get_interface (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 0)
|
||||
if (USB_SETUP_SET (req))
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (rcp == INTERFACE_RECIPIENT)
|
||||
{
|
||||
if (detail->value != 0 || (detail->index >> 8) != 0 || detail->len != 1)
|
||||
if (arg->value != 0 || (arg->index >> 8) != 0 || arg->len != 1)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
return usb_cb_interface (USB_GET_INTERFACE, detail);
|
||||
return usb_cb_interface (USB_GET_INTERFACE, arg);
|
||||
}
|
||||
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
static int std_set_interface (uint8_t req, struct control_info *detail)
|
||||
static int std_set_interface (uint8_t req, struct req_args *arg)
|
||||
{
|
||||
uint8_t rcp = req & RECIPIENT;
|
||||
|
||||
if ((req & REQUEST_DIR) == 1 || rcp != INTERFACE_RECIPIENT
|
||||
|| detail->len != 0 || (detail->index >> 8) != 0
|
||||
|| (detail->value >> 8) != 0 || dev_p->current_configuration == 0)
|
||||
if (USB_SETUP_GET (req) || rcp != INTERFACE_RECIPIENT
|
||||
|| arg->len != 0 || (arg->index >> 8) != 0
|
||||
|| (arg->value >> 8) != 0 || dev_p->current_configuration == 0)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
return usb_cb_interface (USB_SET_INTERFACE, detail);
|
||||
return usb_cb_interface (USB_SET_INTERFACE, arg);
|
||||
}
|
||||
|
||||
|
||||
static void handle_setup0 (void)
|
||||
{
|
||||
const uint16_t *pw;
|
||||
struct control_info ctrl;
|
||||
uint16_t w;
|
||||
uint8_t req_no;
|
||||
int r = USB_UNSUPPORT;
|
||||
@@ -749,11 +749,11 @@ static void handle_setup0 (void)
|
||||
dev_p->bmRequestType = w & 0xff;
|
||||
dev_p->bRequest = req_no = w >> 8;
|
||||
pw++;
|
||||
ctrl.value = *pw++;
|
||||
dev_p->value = *pw++;
|
||||
pw++;
|
||||
ctrl.index = *pw++;
|
||||
dev_p->index = *pw++;
|
||||
pw++;
|
||||
ctrl.len = *pw;
|
||||
dev_p->len = *pw;
|
||||
|
||||
data_p->addr = NULL;
|
||||
data_p->len = 0;
|
||||
@@ -777,11 +777,13 @@ static void handle_setup0 (void)
|
||||
default: handler = std_none; break;
|
||||
}
|
||||
|
||||
r = (*handler) (dev_p->bmRequestType, &ctrl);
|
||||
r = (*handler) (dev_p->bmRequestType,
|
||||
(struct req_args *)&dev_p->value);
|
||||
}
|
||||
}
|
||||
else
|
||||
r = usb_cb_setup (dev_p->bmRequestType, req_no, &ctrl);
|
||||
r = usb_cb_setup (dev_p->bmRequestType, req_no,
|
||||
(struct req_args *)&dev_p->value);
|
||||
|
||||
if (r != USB_SUCCESS)
|
||||
dev_p->state = STALLED;
|
||||
@@ -789,8 +791,7 @@ static void handle_setup0 (void)
|
||||
{
|
||||
if (USB_SETUP_SET (dev_p->bmRequestType))
|
||||
{
|
||||
dev_p->value = ctrl.value;
|
||||
if (ctrl.len == 0)
|
||||
if (dev_p->len == 0)
|
||||
{
|
||||
dev_p->state = WAIT_STATUS_IN;
|
||||
st103_set_tx_count (ENDP0, 0);
|
||||
@@ -819,8 +820,8 @@ static void handle_in0 (void)
|
||||
usb_cb_handle_event (USB_EVENT_ADDRESS, dev_p->value);
|
||||
}
|
||||
else
|
||||
usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest,
|
||||
dev_p->value);
|
||||
usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest,
|
||||
(struct req_args *)&dev_p->value);
|
||||
|
||||
dev_p->state = STALLED;
|
||||
}
|
||||
@@ -842,27 +843,6 @@ static void handle_out0 (void)
|
||||
dev_p->state = STALLED;
|
||||
}
|
||||
|
||||
static void nop_proc (void)
|
||||
{
|
||||
}
|
||||
|
||||
#define WEAK __attribute__ ((weak, alias ("nop_proc")))
|
||||
void WEAK EP1_IN_Callback (void);
|
||||
void WEAK EP2_IN_Callback (void);
|
||||
void WEAK EP3_IN_Callback (void);
|
||||
void WEAK EP4_IN_Callback (void);
|
||||
void WEAK EP5_IN_Callback (void);
|
||||
void WEAK EP6_IN_Callback (void);
|
||||
void WEAK EP7_IN_Callback (void);
|
||||
|
||||
void WEAK EP1_OUT_Callback (void);
|
||||
void WEAK EP2_OUT_Callback (void);
|
||||
void WEAK EP3_OUT_Callback (void);
|
||||
void WEAK EP4_OUT_Callback (void);
|
||||
void WEAK EP5_OUT_Callback (void);
|
||||
void WEAK EP6_OUT_Callback (void);
|
||||
void WEAK EP7_OUT_Callback (void);
|
||||
|
||||
static void
|
||||
usb_handle_transfer (uint16_t istr_value)
|
||||
{
|
||||
@@ -900,37 +880,21 @@ usb_handle_transfer (uint16_t istr_value)
|
||||
if ((ep_value & EP_CTR_RX))
|
||||
{
|
||||
st103_ep_clear_ctr_rx (ep_index);
|
||||
switch ((ep_index - 1))
|
||||
{
|
||||
case 0: EP1_OUT_Callback (); break;
|
||||
case 1: EP2_OUT_Callback (); break;
|
||||
case 2: EP3_OUT_Callback (); break;
|
||||
case 3: EP4_OUT_Callback (); break;
|
||||
case 4: EP5_OUT_Callback (); break;
|
||||
case 5: EP6_OUT_Callback (); break;
|
||||
case 6: EP7_OUT_Callback (); break;
|
||||
}
|
||||
usb_cb_rx_ready (ep_index);
|
||||
}
|
||||
|
||||
if ((ep_value & EP_CTR_TX))
|
||||
{
|
||||
st103_ep_clear_ctr_tx (ep_index);
|
||||
switch ((ep_index - 1))
|
||||
{
|
||||
case 0: EP1_IN_Callback (); break;
|
||||
case 1: EP2_IN_Callback (); break;
|
||||
case 2: EP3_IN_Callback (); break;
|
||||
case 3: EP4_IN_Callback (); break;
|
||||
case 4: EP5_IN_Callback (); break;
|
||||
case 5: EP6_IN_Callback (); break;
|
||||
case 6: EP7_IN_Callback (); break;
|
||||
}
|
||||
usb_cb_tx_done (ep_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usb_lld_reset (void)
|
||||
void usb_lld_reset (uint8_t feature)
|
||||
{
|
||||
usb_lld_set_configuration (0);
|
||||
dev_p->current_feature = feature;
|
||||
st103_set_btable ();
|
||||
st103_set_daddr (0);
|
||||
}
|
||||
@@ -1037,14 +1001,9 @@ uint8_t usb_lld_current_configuration (void)
|
||||
return dev_p->current_configuration;
|
||||
}
|
||||
|
||||
void usb_lld_set_feature (uint8_t feature)
|
||||
void usb_lld_set_data_to_recv (void *p, size_t len)
|
||||
{
|
||||
dev_p->current_feature = feature;
|
||||
}
|
||||
|
||||
void usb_lld_set_data_to_recv (const void *p, size_t len)
|
||||
{
|
||||
data_p->addr = (uint8_t *)p;
|
||||
data_p->addr = p;
|
||||
data_p->len = len;
|
||||
}
|
||||
|
||||
@@ -1129,7 +1088,7 @@ void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n)
|
||||
* BUFLEN: size of the data.
|
||||
*/
|
||||
int
|
||||
usb_lld_reply_request (const void *buf, size_t buflen, struct control_info *ctl)
|
||||
usb_lld_reply_request (const void *buf, size_t buflen, struct req_args *ctl)
|
||||
{
|
||||
uint32_t len_asked = ctl->len;
|
||||
uint32_t len;
|
||||
|
||||
@@ -67,7 +67,6 @@ class gnuk_token(object):
|
||||
if interface.interfaceSubClass != CCID_SUBCLASS:
|
||||
raise ValueError("Wrong interface sub class")
|
||||
self.__devhandle = device.open()
|
||||
self.__devhandle.setConfiguration(configuration.value)
|
||||
self.__devhandle.claimInterface(interface)
|
||||
self.__devhandle.setAltInterface(0)
|
||||
|
||||
@@ -473,10 +472,6 @@ class regnual(object):
|
||||
if intf.interfaceClass != 0xff:
|
||||
raise ValueError("Wrong interface class")
|
||||
self.__devhandle = dev.open()
|
||||
try:
|
||||
self.__devhandle.setConfiguration(conf)
|
||||
except:
|
||||
pass
|
||||
self.__devhandle.claimInterface(intf)
|
||||
self.__devhandle.setAltInterface(0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user