Compare commits

..

21 Commits

Author SHA1 Message Date
NIIBE Yutaka
f86f97cdbe Version 1.2.0 2016-05-20 14:10:39 +09:00
NIIBE Yutaka
1e004bec78 Fix reGNUal upgrade 2016-05-19 17:34:38 +09:00
NIIBE Yutaka
d68bee21e5 mv usb-icc.c usb-ccid.c 2016-05-19 16:58:52 +09:00
NIIBE Yutaka
2903e88986 Update Chopstx to 0.11 2016-05-19 14:04:31 +09:00
NIIBE Yutaka
25fed157e1 Follow the change of eventflag change, fixining long-standing bug of LED 2016-05-19 11:50:13 +09:00
NIIBE Yutaka
d5c5571423 LED blink change 2016-05-18 21:57:34 +09:00
NIIBE Yutaka
51d4b754e6 integrate ccid and usb threads 2016-05-18 21:34:14 +09:00
NIIBE Yutaka
48905155c5 Follow Chopstx change 2016-05-18 19:43:47 +09:00
NIIBE Yutaka
772071d1ba Update reGNUal wrt sys 3.0 2016-05-18 13:32:00 +09:00
NIIBE Yutaka
1fa45e3273 Fix reGNUal 2016-05-16 22:43:51 +09:00
NIIBE Yutaka
1a5eb0ec3b update from Chopstx 2016-05-16 22:37:23 +09:00
NIIBE Yutaka
106b042e75 neug follow update of chopstx 2016-05-13 22:31:09 +09:00
NIIBE Yutaka
eebd40d946 usb call back moved to usb_ctrl.c 2016-05-13 22:30:47 +09:00
NIIBE Yutaka
5e37c7722a Update chopstx 2016-05-12 21:57:53 +09:00
NIIBE Yutaka
b1a582e87c Fix USB stack a bit 2016-03-08 11:58:43 +09:00
NIIBE Yutaka
3f1ee534fe Support VERIFY reset feature 2016-02-09 14:19:36 +09:00
NIIBE Yutaka
522ec3299e Bignum fixes 2016-02-09 14:13:13 +09:00
NIIBE Yutaka
34e2099b23 change of S2K 2016-02-09 14:01:07 +09:00
NIIBE Yutaka
baf09ecac9 Fix the implementation for NIST P-256 and secp256k1 2016-02-08 11:24:55 +09:00
NIIBE Yutaka
db23a1d051 submodule check in configure 2016-02-08 10:11:02 +09:00
NIIBE Yutaka
3f8c4d1f17 Fix offset of bConfirmPIN 2015-11-30 13:38:00 +09:00
25 changed files with 824 additions and 689 deletions

110
ChangeLog
View File

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

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

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

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

View File

@@ -1 +1 @@
release/1.1.9
release/1.2.0

Submodule chopstx updated: a30a069ed8...5458b77d36

View File

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

View File

@@ -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,23 +64,25 @@ 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 */
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
REGNUAL_FEATURE_INIT, /* bmAttributes: bus powered */
50, /* MaxPower 100 mA */
/* Interface Descriptor */
9,
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
0, /* bInterfaceNumber: Index of this interface */
0, /* Alternate setting for this interface */
0, /* bNumEndpoints: None */
@@ -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)
{

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

@@ -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);
if (borrow)
bn256_add (X, X, P256K1);
else
bn256_add (tmp, X, P256K1);
if (borrow)
memcpy (X, tmp, sizeof (bn256));
else
memcpy (tmp, tmp, sizeof (bn256));
}
/**

View File

@@ -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);
if (borrow)
bn256_add (X, X, P256R1);
else
bn256_add (tmp, X, P256R1);
if (borrow)
memcpy (X, tmp, sizeof (bn256));
else
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);

View File

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

View File

@@ -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,6 +150,8 @@ cmd_verify (void)
pw = apdu.cmd_apdu_data;
if (len == 0)
{
if (p1 == 0)
{ /* This is to examine status. */
if (p2 == 0x81)
r = ac_check_status (AC_PSO_CDS_AUTHORIZED);
@@ -164,7 +167,19 @@ cmd_verify (void)
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

View File

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

View File

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

View File

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

View File

@@ -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,7 +101,7 @@ 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 */
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
W_TOTAL_LENGTH, 0x00, /* wTotalLength:no of returned bytes */
NUM_INTERFACES, /* bNumInterfaces: */
0x01, /* bConfigurationValue: Configuration value */
@@ -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

View File

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

View File

@@ -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);
@@ -820,7 +821,7 @@ static void handle_in0 (void)
}
else
usb_cb_ctrl_write_finish (dev_p->bmRequestType, dev_p->bRequest,
dev_p->value);
(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;

View File

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