Compare commits
6 Commits
extended-a
...
release/0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c98f1fe8c6 | ||
|
|
14673b825b | ||
|
|
6550dd5353 | ||
|
|
3d732a7c2d | ||
|
|
aff9080b35 | ||
|
|
21debc0567 |
80
ChangeLog
80
ChangeLog
@@ -1,3 +1,83 @@
|
||||
2012-02-02 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* Version 0.17.
|
||||
|
||||
* src/usb_desc.c (gnukStringSerial): Updated.
|
||||
(gnukConfigDescriptor): Short APDU only.
|
||||
|
||||
* tool/gnuk_put_binary.py (cmd_get_response): New.
|
||||
(cmd_select_openpgp, cmd_get_data): Call cmd_get_response.
|
||||
|
||||
2012-01-30 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb-icc.c (struct ccid): Add chained_cls_ins_p1_p2.
|
||||
(end_cmd_apdu_head, icc_cmd_apdu_data, icc_handle_data): Add checking
|
||||
CMD APDU head for command chaining.
|
||||
|
||||
2012-01-20 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
Short APDU only CCID driver.
|
||||
* STM32_USB-FS-Device_Driver/src/usb_core.c (DataStageOut)
|
||||
(DataStageIn): Use usb_lld_to_pmabuf and usb_lld_from_pmabuf.
|
||||
|
||||
* src/configure (CERTDO_SUPPORT): Comment fix.
|
||||
|
||||
* src/gnuk.h (struct adpu): expected_res_size has type uint16_t.
|
||||
(MAX_CMD_APDU_DATA_SIZE, MAX_RES_APDU_DATA_SIZE): New.
|
||||
(MAX_CMD_APDU_SIZE, MAX_RES_APDU_SIZE, USB_BUF_SIZE): Remove.
|
||||
(icc_state_p): New.
|
||||
(set_res_sw): Rename from set_res_apdu.
|
||||
|
||||
* src/call-rsa.c (rsa_decrypt): Use MAX_RES_APDU_DATA_SIZE.
|
||||
|
||||
* src/openpgp.c (set_res_sw): Rename from set_res_apdu.
|
||||
* src/openpgp.h: Use set_res_sw.
|
||||
|
||||
* src/main.c: Handle icc_state_p.
|
||||
|
||||
* src/openpgp-do.c (historical_bytes): command chaining but short
|
||||
APDU only.
|
||||
(extended_capabilities): Change for short APDU only.
|
||||
|
||||
* src/usb-icc.c (USB_BUF_SIZE): Define here (was in gnuk.h).
|
||||
(struct ep_in, epi_init, struct ep_out, epo_init, endpoint_out)
|
||||
(endpoint_in, icc_state_p, struct ccid, APDU_STATE_WAIT_COMMAND)
|
||||
(APDU_STATE_COMMAND_CHAINING, APDU_STATE_COMMAND_RECEIVED)
|
||||
(APDU_STATE_RESULT, APDU_STATE_RESULT_GET_RESPONSE, ccid_reset)
|
||||
(ccid_init, CMD_APDU_HEAD_SIZE, apdu_init, notify_tx, no_buf)
|
||||
(set_sw1sw2, get_sw1sw2, notify_icc, end_icc_rx, end_abdata)
|
||||
(end_cmd_apdu_head, end_nomore_data, end_cmd_apdu_data)
|
||||
(nomore_data, INS_GET_RESPONSE, icc_cmd_apdu_data, icc_abdata)
|
||||
(icc_send_data_block_0x9000, icc_send_data_block_gr, ccid): New.
|
||||
(icc_data_size, icc_seq, icc_next_p, icc_chain_p, icc_tx_size)
|
||||
(icc_thread, icc_state, gpg_thread, ICC_RESPONSE_MSG_DATA_SIZE):
|
||||
Remove.
|
||||
(EP1_IN_Callback): Rewrite using epi.
|
||||
(EP2_OUT_Callback): Rewrite using epo.
|
||||
(icc_prepare_receive): Rewrite using epo and struct ccid.
|
||||
(ATR): Change ofr short APDU only.
|
||||
(icc_error, icc_power_on, icc_send_status, icc_power_off)
|
||||
(icc_send_data_block, icc_send_params, icc_handle_data)
|
||||
(icc_handle_timeout, USBthread): Rewrite using struct ccid.
|
||||
|
||||
* src/usb_desc.c (gnukConfigDescriptor): dwFeatures: Short APDU
|
||||
level, dwMaxCCIDMessageLength: 271.
|
||||
|
||||
* src/usb_lld.c (usb_lld_to_pmabuf, usb_lld_from_pmabuf): New.
|
||||
* src/usb_lld.h (usb_lld_txcpy, void usb_lld_write) Use
|
||||
usb_lld_to_pmabuf.
|
||||
(usb_lld_rxcpy): Use usb_lld_from_pmabuf.
|
||||
|
||||
* src/stmusb.mk (usb_mem.c): Remove.
|
||||
|
||||
* gnuk_put_binary.py (cmd_select_openpgp): No response APDU data.
|
||||
(cmd_verify, cmd_write_binary): Send short APDU.
|
||||
(__main__): Remove RANDOM_NUMBER_BITS support.
|
||||
|
||||
Bug fix for CERTDO_SUPPORT.
|
||||
* src/gnuk.ld.in: Add missing alignment for _data_pool (when no
|
||||
CERTDO_SUPPORT).
|
||||
|
||||
2012-01-19 Niibe Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/usb-icc.c (icc_handle_data): Handle the case when it only
|
||||
|
||||
11
NEWS
11
NEWS
@@ -2,14 +2,19 @@ Gnuk NEWS - User visible changes
|
||||
|
||||
* Major changes in Gnuk 0.17
|
||||
|
||||
Released 2012-01-XX, by NIIBE Yutaka
|
||||
Released 2012-02-02, by NIIBE Yutaka
|
||||
|
||||
** ISO 7816 SELECT command behavior is strict now
|
||||
** USB CCID/ICCD protocol implementation change
|
||||
Gnuk now only supports short APDU level exchange, not support.
|
||||
extended APDU level exchange. Thus, Gnuk could be compatible to older
|
||||
host side software implementation.
|
||||
|
||||
** ISO 7816 SELECT command behavior is somewhat strict now
|
||||
Old implementations do not check DF name for SELECT command.
|
||||
This causes some trouble when Gnuk Token is identified as if it were
|
||||
different card/token. Now, DF name of OpenPGP card is checked.
|
||||
|
||||
** USB CCID/ICCD low level bug is fixed
|
||||
** USB CCID/ICCD low-level bug is fixed
|
||||
When the size of command APDU data is just 49, the lower level packet
|
||||
size is 64. This is maximum size of BULK-OUT transfer packet, and
|
||||
caused trouble in the past implementations. Example is setting url
|
||||
|
||||
23
README
23
README
@@ -1,7 +1,7 @@
|
||||
Gnuk - software for GnuPG USB Token
|
||||
|
||||
Version 0.16
|
||||
2011-12-14
|
||||
Version 0.17
|
||||
2012-02-02
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
@@ -104,12 +104,15 @@ Ab: That's because gnome-keyring-daemon interferes GnuPG. Type:
|
||||
and at the tab of "Startup Programs", disable check buttons for
|
||||
"GPG Password Agent" and "SSH Key Agent".
|
||||
|
||||
Qc: Do you know a good SWD debugger to connect FST-01 or something?
|
||||
Ac: Perhaps, you can use a part of STM32F4 Discovery Kit as SWD
|
||||
debugger. It seems that there is a free software tool for that.
|
||||
|
||||
|
||||
Release notes
|
||||
=============
|
||||
|
||||
This is seventeenth release of Gnuk. While it works well for specific
|
||||
This is eighteenth release of Gnuk. While it works well for specific
|
||||
usages and it is considered stable, it is still somewhat experimental.
|
||||
|
||||
Tested features are:
|
||||
@@ -127,18 +130,13 @@ Tested features are:
|
||||
* Changing value of password status bytes (0x00C4): forcesig
|
||||
* Verify with pin pad
|
||||
* Modify with pin pad
|
||||
* Card holder certificate
|
||||
|
||||
It is known not-working well:
|
||||
|
||||
* For some version of kernel and libccid, --enable-debug can't
|
||||
work well. Please disable DEBUG option if it doesn't work well.
|
||||
|
||||
* Card holder certificate
|
||||
It is implemented in Gnuk side. But its large size matters
|
||||
(> 1KB). Some versions of GnuPG cannot handle a data object
|
||||
of large size with PC/SC backend. Specifically,
|
||||
handle_transmit function in pcsc-wrapper.c uses the buffer
|
||||
of size 1024-byte.
|
||||
work well. Please make sure to disable DEBUG option if it
|
||||
doesn't work well.
|
||||
|
||||
Not supported feature(s):
|
||||
|
||||
@@ -241,8 +239,7 @@ Gnuk is distributed with external source code.
|
||||
Host Requirements
|
||||
=================
|
||||
|
||||
For GNU/Linux, libccid version >= 1.3.11 is required.
|
||||
libccid version == 1.3.9 is known not working well by the issue [r4235].
|
||||
For GNU/Linux, libccid version >= 1.3.11 is recommended.
|
||||
|
||||
I think that it should not be requirment but the kernel version of my use is:
|
||||
Linux version 2.6.32-5-686 (Debian 2.6.32-18) (ben@decadent.org.uk) (gcc version 4.3.5 (Debian 4.3.5-2) ) #1 SMP Sat Jul 24 02:27:10 UTC 2010
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usb_lib.h"
|
||||
extern void usb_lld_to_pmabuf (const void *src, uint16_t addr, uint32_t n);
|
||||
extern void usb_lld_from_pmabuf (void *dst, uint16_t addr, uint32_t n);
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define ValBit(VAR,Place) (VAR & (1 << Place))
|
||||
@@ -460,7 +463,7 @@ void DataStageOut(void)
|
||||
#ifdef STM32F10X_CL
|
||||
OTGD_FS_PCD_EP_Read(ENDP0, Buffer, Length);
|
||||
#else
|
||||
PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
|
||||
usb_lld_from_pmabuf (Buffer, GetEPRxAddr(ENDP0), Length);
|
||||
#endif /* STM32F10X_CL */
|
||||
}
|
||||
|
||||
@@ -544,7 +547,7 @@ void DataStageIn(void)
|
||||
#ifdef STM32F10X_CL
|
||||
OTGD_FS_PCD_EP_Write (ENDP0, DataBuffer, Length);
|
||||
#else
|
||||
UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
|
||||
usb_lld_to_pmabuf (DataBuffer, GetEPTxAddr(ENDP0), Length);
|
||||
#endif /* STM32F10X_CL */
|
||||
|
||||
SetEPTxCount(ENDP0, Length);
|
||||
|
||||
@@ -167,7 +167,7 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
#endif
|
||||
|
||||
r = rsa_pkcs1_decrypt (&rsa_ctx, RSA_PRIVATE, &output_len,
|
||||
input, output, MAX_RES_APDU_SIZE - 2);
|
||||
input, output, MAX_RES_APDU_DATA_SIZE);
|
||||
rsa_free (&rsa_ctx);
|
||||
if (r < 0)
|
||||
{
|
||||
|
||||
2
src/configure
vendored
2
src/configure
vendored
@@ -173,7 +173,7 @@ fi
|
||||
# --enable-certdo option
|
||||
if test "$certdo" = "yes"; then
|
||||
CERTDO_DEFINE="#define CERTDO_SUPPORT 1"
|
||||
echo "CERT.3 Data Object is supported (Note: it is not supported by GnuPG)"
|
||||
echo "CERT.3 Data Object is supported"
|
||||
else
|
||||
CERTDO_DEFINE="#undef CERTDO_SUPPORT"
|
||||
echo "CERT.3 Data Object is not supported"
|
||||
|
||||
21
src/gnuk.h
21
src/gnuk.h
@@ -36,7 +36,7 @@ struct apdu {
|
||||
uint8_t *cmd_apdu_head; /* CLS INS P1 P2 [ internal Lc ] */
|
||||
uint8_t *cmd_apdu_data;
|
||||
uint16_t cmd_apdu_data_len; /* Nc, calculated by Lc field */
|
||||
uint32_t expected_res_size; /* Ne, calculated by Le field */
|
||||
uint16_t expected_res_size; /* Ne, calculated by Le field */
|
||||
|
||||
/* response APDU */
|
||||
uint16_t sw;
|
||||
@@ -55,10 +55,10 @@ extern struct apdu apdu;
|
||||
#define EV_VERIFY_CMD_AVAILABLE ((eventmask_t)8)
|
||||
#define EV_MODIFY_CMD_AVAILABLE ((eventmask_t)16)
|
||||
|
||||
/* maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */
|
||||
#define MAX_CMD_APDU_SIZE (7+282) /* header + data */
|
||||
/* maximum res apdu data is public key 5+9+256+2 (gpg_do_public_key) */
|
||||
#define MAX_RES_APDU_SIZE ((5+9+256)+2) /* Data + status */
|
||||
/* Maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */
|
||||
#define MAX_CMD_APDU_DATA_SIZE (22+4+128+128) /* without header */
|
||||
/* Maximum res apdu data is public key 5+9+256 (gpg_do_public_key) */
|
||||
#define MAX_RES_APDU_DATA_SIZE (5+9+256) /* without trailer */
|
||||
|
||||
#define ICC_MSG_HEADER_SIZE 10
|
||||
|
||||
@@ -68,13 +68,6 @@ extern struct apdu apdu;
|
||||
/* USB buffer size of LL (Low-level): size of single Bulk transaction */
|
||||
#define USB_LL_BUF_SIZE 64
|
||||
|
||||
/*
|
||||
* USB buffer size of USB-ICC driver
|
||||
* (Changing this, dwMaxCCIDMessageLength too !!)
|
||||
*/
|
||||
#define USB_BUF_SIZE ((10 + 10 + MAX_CMD_APDU_SIZE + USB_LL_BUF_SIZE - 1) \
|
||||
/ USB_LL_BUF_SIZE * USB_LL_BUF_SIZE)
|
||||
|
||||
enum icc_state
|
||||
{
|
||||
ICC_STATE_START, /* Initial */
|
||||
@@ -85,7 +78,7 @@ enum icc_state
|
||||
ICC_STATE_SEND, /* APDU Sent Partially */
|
||||
};
|
||||
|
||||
extern volatile enum icc_state icc_state;
|
||||
extern enum icc_state *icc_state_p;
|
||||
|
||||
extern volatile uint8_t auth_status;
|
||||
#define AC_NONE_AUTHORIZED 0x00
|
||||
@@ -116,7 +109,7 @@ extern void ac_reset_admin (void);
|
||||
extern void ac_fini (void);
|
||||
|
||||
|
||||
extern void set_res_apdu (uint8_t sw1, uint8_t sw2);
|
||||
extern void set_res_sw (uint8_t sw1, uint8_t sw2);
|
||||
extern uint16_t data_objects_number_of_bytes;
|
||||
|
||||
extern void gpg_data_scan (const uint8_t *p);
|
||||
|
||||
@@ -128,6 +128,7 @@ SECTIONS
|
||||
|
||||
.gnuk_flash :
|
||||
{
|
||||
. = ALIGN (@FLASH_PAGE_SIZE@);
|
||||
_data_pool = .;
|
||||
KEEP(*(.gnuk_data))
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
|
||||
@@ -287,6 +287,13 @@ static void display_fatal_code (void)
|
||||
|
||||
static void display_status_code (void)
|
||||
{
|
||||
enum icc_state icc_state;
|
||||
|
||||
if (icc_state_p == NULL)
|
||||
icc_state = ICC_STATE_START;
|
||||
else
|
||||
icc_state = *icc_state_p;
|
||||
|
||||
if (icc_state == ICC_STATE_START)
|
||||
{
|
||||
set_led (1);
|
||||
|
||||
@@ -77,12 +77,11 @@ uint16_t data_objects_number_of_bytes;
|
||||
static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
10,
|
||||
0x00,
|
||||
0x31, 0x80, /* Full DF name */
|
||||
0x31, 0x84, /* Full DF name, GET DATA, MF */
|
||||
0x73,
|
||||
0x80, 0x01, 0x40, /* Full DF name */
|
||||
0x80, 0x01, 0x80, /* Full DF name */
|
||||
/* 1-byte */
|
||||
/* No command chaining */
|
||||
/* Extended Lc and Le */
|
||||
/* Command chaining, No extended Lc and Le */
|
||||
0x00, 0x90, 0x00 /* Status info (no life cycle management) */
|
||||
};
|
||||
|
||||
@@ -90,27 +89,24 @@ static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
|
||||
10,
|
||||
0x30, /*
|
||||
* No SM, No get challenge,
|
||||
* No SM,
|
||||
* No get challenge,
|
||||
* Key import supported,
|
||||
* PW status byte can be put,
|
||||
* No private_use_DO,
|
||||
* No algo change allowed
|
||||
*/
|
||||
0, /* Secure Messaging Algorithm: N/A (TDES=0, AES=1) */
|
||||
0x00, 0x00, /* Max get challenge */
|
||||
0x00, 0x00, /* Max get challenge (0: Get challenge not supported) */
|
||||
#ifdef CERTDO_SUPPORT
|
||||
0x07, 0xfe, /* max. length of cardholder certificate (2KB - 2)*/
|
||||
0x08, 0x00, /* max. length of cardholder certificate (2KiB) */
|
||||
#else
|
||||
0x00, 0x00,
|
||||
#endif
|
||||
/* Max. length of command data */
|
||||
(MAX_CMD_APDU_SIZE>>8), (MAX_CMD_APDU_SIZE&0xff),
|
||||
/* Max. length of response data */
|
||||
#ifdef CERTDO_SUPPORT
|
||||
0x08, 0x00, /* the case of cardholder ceritificate */
|
||||
#else
|
||||
(MAX_RES_APDU_SIZE>>8), (MAX_RES_APDU_SIZE&0xff),
|
||||
#endif
|
||||
/* Max. length of command APDU data */
|
||||
0x00, 0xff,
|
||||
/* Max. length of response APDU data */
|
||||
0x01, 0x00,
|
||||
};
|
||||
|
||||
/* Algorithm Attributes */
|
||||
|
||||
@@ -67,7 +67,7 @@ select_file_TOP_result[] __attribute__ ((aligned (1))) = {
|
||||
};
|
||||
|
||||
void
|
||||
set_res_apdu (uint8_t sw1, uint8_t sw2)
|
||||
set_res_sw (uint8_t sw1, uint8_t sw2)
|
||||
{
|
||||
apdu.sw = (sw1 << 8) | sw2;
|
||||
}
|
||||
@@ -510,7 +510,7 @@ cmd_select_file (void)
|
||||
if (apdu.cmd_apdu_data_len != 6
|
||||
|| memcmp (openpgpcard_aid, apdu.cmd_apdu_data, 6) != 0)
|
||||
{
|
||||
DEBUG_WORD (apdu.cmd_apdu_data_len);
|
||||
DEBUG_SHORT (apdu.cmd_apdu_data_len);
|
||||
DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
||||
|
||||
GPG_NO_FILE ();
|
||||
@@ -528,6 +528,7 @@ cmd_select_file (void)
|
||||
res_APDU[1] = 0x12;
|
||||
res_APDU[2] = 0x84; /* overwrite: DF name */
|
||||
res_APDU_size += 2;
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
}
|
||||
else if (apdu.cmd_apdu_data_len == 2
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#define GPG_MEMORY_FAILURE() set_res_apdu (0x65, 0x81)
|
||||
#define GPG_SECURITY_FAILURE() set_res_apdu (0x69, 0x82)
|
||||
#define GPG_SECURITY_AUTH_BLOCKED() set_res_apdu (0x69, 0x83)
|
||||
#define GPG_CONDITION_NOT_SATISFIED() set_res_apdu (0x69, 0x85)
|
||||
#define GPG_COMMAND_NOT_ALLOWED() set_res_apdu (0x69, 0x86)
|
||||
#define GPG_FUNCTION_NOT_SUPPORTED() set_res_apdu (0x6a, 0x81)
|
||||
#define GPG_NO_FILE() set_res_apdu (0x6a, 0x82)
|
||||
#define GPG_NO_RECORD() set_res_apdu (0x6a, 0x88)
|
||||
#define GPG_BAD_P0_P1() set_res_apdu (0x6b, 0x00)
|
||||
#define GPG_NO_INS() set_res_apdu (0x6d, 0x00)
|
||||
#define GPG_ERROR() set_res_apdu (0x6f, 0x00)
|
||||
#define GPG_SUCCESS() set_res_apdu (0x90, 0x00)
|
||||
#define GPG_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
|
||||
#define GPG_SECURITY_FAILURE() set_res_sw (0x69, 0x82)
|
||||
#define GPG_SECURITY_AUTH_BLOCKED() set_res_sw (0x69, 0x83)
|
||||
#define GPG_CONDITION_NOT_SATISFIED() set_res_sw (0x69, 0x85)
|
||||
#define GPG_COMMAND_NOT_ALLOWED() set_res_sw (0x69, 0x86)
|
||||
#define GPG_FUNCTION_NOT_SUPPORTED() set_res_sw (0x6a, 0x81)
|
||||
#define GPG_NO_FILE() set_res_sw (0x6a, 0x82)
|
||||
#define GPG_NO_RECORD() set_res_sw (0x6a, 0x88)
|
||||
#define GPG_BAD_P0_P1() set_res_sw (0x6b, 0x00)
|
||||
#define GPG_NO_INS() set_res_sw (0x6d, 0x00)
|
||||
#define GPG_ERROR() set_res_sw (0x6f, 0x00)
|
||||
#define GPG_SUCCESS() set_res_sw (0x90, 0x00)
|
||||
|
||||
@@ -3,5 +3,5 @@ STMUSBSRCDIR = $(STMUSBDIR)/src
|
||||
STMUSBINCDIR = $(STMUSBDIR)/inc
|
||||
STMUSBSRC= \
|
||||
$(STMUSBSRCDIR)/usb_init.c $(STMUSBSRCDIR)/usb_int.c \
|
||||
$(STMUSBSRCDIR)/usb_mem.c $(STMUSBSRCDIR)/usb_core.c \
|
||||
$(STMUSBSRCDIR)/usb_core.c \
|
||||
$(STMUSBSRCDIR)/usb_regs.c
|
||||
|
||||
1558
src/usb-icc.c
1558
src/usb-icc.c
File diff suppressed because it is too large
Load Diff
@@ -101,8 +101,8 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
* It is different now for better interaction to GPG's in-stock
|
||||
* ccid-driver.
|
||||
*/
|
||||
0x42, 0x08, 0x04, 0x00, /* dwFeatures (not ICCD):
|
||||
* Short and extended APDU level: 0x40000 *
|
||||
0x42, 0x08, 0x02, 0x00, /* dwFeatures (not ICCD):
|
||||
* Short APDU level : 0x20000 *
|
||||
* (what? means ICCD?) : 0x00800 *
|
||||
* Automatic IFSD : 0x00400
|
||||
* NAD value other than 0x00 : 0x00200
|
||||
@@ -115,7 +115,7 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
* Auto activaction of ICC : 0x00004
|
||||
* Automatic conf. based on ATR : 0x00002 g
|
||||
*/
|
||||
0x40, 0x01, 0, 0, /* dwMaxCCIDMessageLength */
|
||||
0x0f, 0x01, 0, 0, /* dwMaxCCIDMessageLength: 271 */
|
||||
0xff, /* bClassGetResponse: */
|
||||
0xff, /* bClassEnvelope: */
|
||||
0, 0, /* wLCDLayout: FIXED VALUE */
|
||||
@@ -275,7 +275,7 @@ static const uint8_t gnukStringProduct[] = {
|
||||
const uint8_t gnukStringSerial[] = {
|
||||
13*2+2, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'0', 0, '.', 0, '1', 0, '6', 0, /* Version number of Gnuk */
|
||||
'0', 0, '.', 0, '1', 0, '7', 0, /* Version number of Gnuk */
|
||||
'-', 0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
|
||||
@@ -27,3 +27,76 @@ void usb_lld_init (void) {
|
||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
||||
RCC->APB1RSTR = 0;
|
||||
}
|
||||
|
||||
void usb_lld_to_pmabuf (const void *src, uint16_t wPMABufAddr, size_t n)
|
||||
{
|
||||
const uint8_t *s = (const uint8_t *)src;
|
||||
uint16_t *p;
|
||||
uint16_t w;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
if ((wPMABufAddr & 1))
|
||||
{
|
||||
p = (uint16_t *)(PMAAddr + (wPMABufAddr - 1) * 2);
|
||||
w = *p;
|
||||
w = (w & 0xff) | (*s++) << 8;
|
||||
*p = w;
|
||||
p += 2;
|
||||
n--;
|
||||
}
|
||||
else
|
||||
p = (uint16_t *)(PMAAddr + wPMABufAddr * 2);
|
||||
|
||||
while (n >= 2)
|
||||
{
|
||||
w = *s++;
|
||||
w |= (*s++) << 8;
|
||||
*p = w;
|
||||
p += 2;
|
||||
n -= 2;
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
w = *s;
|
||||
*p = w;
|
||||
}
|
||||
}
|
||||
|
||||
void usb_lld_from_pmabuf (void *dst, uint16_t wPMABufAddr, size_t n)
|
||||
{
|
||||
uint8_t *d = (uint8_t *)dst;
|
||||
uint16_t *p;
|
||||
uint16_t w;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
if ((wPMABufAddr & 1))
|
||||
{
|
||||
p = (uint16_t *)(PMAAddr + (wPMABufAddr - 1) * 2);
|
||||
w = *p;
|
||||
*d++ = (w >> 8);
|
||||
p += 2;
|
||||
n--;
|
||||
}
|
||||
else
|
||||
p = (uint16_t *)(PMAAddr + wPMABufAddr * 2);
|
||||
|
||||
while (n >= 2)
|
||||
{
|
||||
w = *p;
|
||||
*d++ = (w & 0xff);
|
||||
*d++ = (w >> 8);
|
||||
p += 2;
|
||||
n -= 2;
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
w = *p;
|
||||
*d = (w & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#define STM32_USB_IRQ_PRIORITY 11
|
||||
void usb_lld_init (void);
|
||||
|
||||
extern void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
|
||||
extern void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
|
||||
|
||||
extern inline void usb_lld_stall_tx (int ep_num)
|
||||
{
|
||||
SetEPTxStatus (ep_num, EP_TX_STALL);
|
||||
@@ -16,10 +19,10 @@ extern inline int usb_lld_tx_data_len (int ep_num)
|
||||
return GetEPTxCount (ep_num);
|
||||
}
|
||||
|
||||
extern inline void usb_lld_txcpy (const uint8_t *src,
|
||||
extern inline void usb_lld_txcpy (const void *src,
|
||||
int ep_num, int offset, size_t len)
|
||||
{
|
||||
UserToPMABufferCopy ((uint8_t *)src, GetEPTxAddr (ep_num) + offset, len);
|
||||
usb_lld_to_pmabuf (src, GetEPTxAddr (ep_num) + offset, len);
|
||||
}
|
||||
|
||||
extern inline void usb_lld_tx_enable (int ep_num, size_t len)
|
||||
@@ -28,9 +31,9 @@ extern inline void usb_lld_tx_enable (int ep_num, size_t len)
|
||||
SetEPTxValid (ep_num);
|
||||
}
|
||||
|
||||
extern inline void usb_lld_write (uint8_t ep_num, void *buf, size_t len)
|
||||
extern inline void usb_lld_write (uint8_t ep_num, const void *buf, size_t len)
|
||||
{
|
||||
UserToPMABufferCopy (buf, GetEPTxAddr (ep_num), len);
|
||||
usb_lld_to_pmabuf (buf, GetEPTxAddr (ep_num), len);
|
||||
SetEPTxCount (ep_num, len);
|
||||
SetEPTxValid (ep_num);
|
||||
}
|
||||
@@ -48,5 +51,5 @@ extern inline int usb_lld_rx_data_len (int ep_num)
|
||||
extern inline void usb_lld_rxcpy (uint8_t *dst,
|
||||
int ep_num, int offset, size_t len)
|
||||
{
|
||||
PMAToUserBufferCopy (dst, GetEPRxAddr (ep_num) + offset, len);
|
||||
usb_lld_from_pmabuf (dst, GetEPRxAddr (ep_num) + offset, len);
|
||||
}
|
||||
|
||||
@@ -43,8 +43,15 @@ class GnukToken(object):
|
||||
cardservice = cardrequest.waitforcard()
|
||||
self.connection = cardservice.connection
|
||||
|
||||
def cmd_get_response(self, expected_len):
|
||||
apdu = [0x00, 0xc0, 0x00, 0x00, expected_len ]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
return response
|
||||
|
||||
def cmd_verify(self, who, passwd):
|
||||
apdu = [0x00, 0x20, 0x00, 0x80+who, 0, 0, len(passwd)] + s2l(passwd)
|
||||
apdu = [0x00, 0x20, 0x00, 0x80+who, len(passwd)] + s2l(passwd)
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
@@ -59,10 +66,20 @@ class GnukToken(object):
|
||||
while count*256 < data_len:
|
||||
if count == 0:
|
||||
d = data[:256]
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 0, len(d)>>8, len(d)&0xff] + s2l(d)
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, len(d) ] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, 0x80+fileid, 0x00, 255 ] + s2l(d[:255])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu0)
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 1 ] + s2l(d[255:])
|
||||
else:
|
||||
d = data[256*count:256*(count+1)]
|
||||
apdu = [0x00, ins, count, 0x00, 0, len(d)>>8, len(d)&0xff] + s2l(d)
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, count, 0x00, len(d) ] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, count, 0x00, 255 ] + s2l(d[:255])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu0)
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 1 ] + s2l(d[255:])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
if is_update:
|
||||
@@ -72,15 +89,19 @@ class GnukToken(object):
|
||||
count += 1
|
||||
|
||||
def cmd_select_openpgp(self):
|
||||
apdu = [0x00, 0xa4, 0x04, 0x00, 6, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01 ]
|
||||
apdu = [0x00, 0xa4, 0x04, 0x0c, 6, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01 ]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
if sw1 == 0x61:
|
||||
response = self.cmd_get_response(sw2)
|
||||
elif not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
|
||||
def cmd_get_data(self, tagh, tagl):
|
||||
apdu = [0x00, 0xca, tagh, tagl]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
if sw1 == 0x61:
|
||||
response = self.cmd_get_response(sw2)
|
||||
elif not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
return response
|
||||
|
||||
@@ -146,18 +167,6 @@ if __name__ == '__main__':
|
||||
exit(1)
|
||||
print "Writing serial number"
|
||||
data = binascii.unhexlify(serial_data_hex)
|
||||
elif sys.argv[1] == '-r':
|
||||
fileid = 1 # Random number bits
|
||||
if len(sys.argv) == 3:
|
||||
filename = sys.argv[2]
|
||||
f = open(filename)
|
||||
else:
|
||||
filename = stdin
|
||||
f = sys.stdin
|
||||
data = f.read()
|
||||
f.close()
|
||||
print "%s: %d" % (filename, len(data))
|
||||
print "Updating random bits"
|
||||
else:
|
||||
fileid = 0 # Card holder certificate
|
||||
filename = sys.argv[1]
|
||||
|
||||
Reference in New Issue
Block a user