fixes and enhancements
This commit is contained in:
9
NEWS
9
NEWS
@@ -1,5 +1,14 @@
|
|||||||
Gnuk NEWS - User visible changes
|
Gnuk NEWS - User visible changes
|
||||||
|
|
||||||
|
* Major changes in Gnuk 0.2
|
||||||
|
|
||||||
|
Released 2010-09-10, by NIIBE Yutaka
|
||||||
|
|
||||||
|
** With DEBUG=1, timeout is more than 3 seconds.
|
||||||
|
|
||||||
|
** Flash ROM entries for random numbers are cleared after use.
|
||||||
|
|
||||||
|
|
||||||
* Major changes in Gnuk 0.1
|
* Major changes in Gnuk 0.1
|
||||||
|
|
||||||
Released 2010-09-10, by NIIBE Yutaka
|
Released 2010-09-10, by NIIBE Yutaka
|
||||||
|
|||||||
18
README
18
README
@@ -1,6 +1,6 @@
|
|||||||
Gnuk - software for GPG USB Token
|
Gnuk - software for GPG USB Token
|
||||||
|
|
||||||
Version 0.1
|
Version 0.2
|
||||||
2010-09-10
|
2010-09-10
|
||||||
Niibe Yutaka
|
Niibe Yutaka
|
||||||
Free Software Initiative of Japan
|
Free Software Initiative of Japan
|
||||||
@@ -54,8 +54,8 @@ Targets
|
|||||||
|
|
||||||
We use Olimex STM32-H103 board.
|
We use Olimex STM32-H103 board.
|
||||||
|
|
||||||
I think that it runs on Olimex STM32-P103, STBee, or STBee mini too.
|
I think that it could run on Olimex STM32-P103, STBee, or STBee mini
|
||||||
Besides, we are porting it to STM32 Primer 2.
|
too. Besides, we are porting it to STM32 Primer 2.
|
||||||
|
|
||||||
|
|
||||||
Souce code
|
Souce code
|
||||||
@@ -93,11 +93,18 @@ Gnuk is distributed with external source code.
|
|||||||
STM32F10x USB Full Speed Device Library (USB-FS-Device_Lib)
|
STM32F10x USB Full Speed Device Library (USB-FS-Device_Lib)
|
||||||
is a STM32F10x library for USB functionality.
|
is a STM32F10x library for USB functionality.
|
||||||
|
|
||||||
I took Libraries/STM32_USB-FS-Device_Driver and a part of
|
I took Libraries/STM32_USB-FS-Device_Driver and
|
||||||
Project/ in STM32_USB-FS-Device_Lib distribution.
|
Project/Virtual_COM_Port in STM32_USB-FS-Device_Lib distribution.
|
||||||
See http://www.st.com for detail.
|
See http://www.st.com for detail.
|
||||||
|
|
||||||
|
|
||||||
|
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].
|
||||||
|
|
||||||
|
|
||||||
How to compile
|
How to compile
|
||||||
==============
|
==============
|
||||||
|
|
||||||
@@ -183,7 +190,6 @@ For libccid, we need following change:
|
|||||||
<string>Gemplus GemPC Key</string>
|
<string>Gemplus GemPC Key</string>
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
||||||
Then, try following to see Gnuk runs:
|
Then, try following to see Gnuk runs:
|
||||||
|
|
||||||
$ gpg --card-status
|
$ gpg --card-status
|
||||||
|
|||||||
8
THANKS
Normal file
8
THANKS
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Gnuk was originally written by NIIBE Yutaka. People contributed by
|
||||||
|
encouraging the development, testing the implementation, suggesting
|
||||||
|
improvements, or fixing bugs. Here is a list of those people.
|
||||||
|
|
||||||
|
Jan Sur jan@suhr.info
|
||||||
|
Kaz Kojima kkojima@rr.iij4u.or.jp
|
||||||
|
Shane Coughlan scoughlan@openinventionnetwork.com
|
||||||
|
Werner Koch wk@gnupg.org
|
||||||
17
doc/HACKING
17
doc/HACKING
@@ -1,3 +1,17 @@
|
|||||||
|
* configure support
|
||||||
|
|
||||||
|
configure script would be good to select a board and to generate
|
||||||
|
serial number.
|
||||||
|
|
||||||
|
|
||||||
|
* Random number update
|
||||||
|
|
||||||
|
Currently, Gnuk doesn't have random number generator, but use random
|
||||||
|
bytes calculated by hosts. When Gnuk uses random number, the entry in
|
||||||
|
Flash ROM will be cleared. Some scheme to update random number bytes
|
||||||
|
is needed. Possibly, private Data Objects.
|
||||||
|
|
||||||
|
|
||||||
* Random Number Generator
|
* Random Number Generator
|
||||||
|
|
||||||
RNG is needed for Data Encryption Key to encrypt private key (P and Q).
|
RNG is needed for Data Encryption Key to encrypt private key (P and Q).
|
||||||
@@ -10,7 +24,7 @@ be possible to get entropy from USB traffic (of other devices).
|
|||||||
It would be good not to use malloc.
|
It would be good not to use malloc.
|
||||||
|
|
||||||
|
|
||||||
* Manufacture ID
|
* [DONE] Manufacture ID
|
||||||
|
|
||||||
Get it from FSFE.
|
Get it from FSFE.
|
||||||
|
|
||||||
@@ -19,6 +33,7 @@ Get it from FSFE.
|
|||||||
|
|
||||||
Currently, aid[] in openpgp-do.c has serial number 00000001.
|
Currently, aid[] in openpgp-do.c has serial number 00000001.
|
||||||
It would be good to generate (random) number at compile time.
|
It would be good to generate (random) number at compile time.
|
||||||
|
Use same serial number for OpenPGPcard and USB serial number.
|
||||||
|
|
||||||
|
|
||||||
* Flash ROM recover from shutdown
|
* Flash ROM recover from shutdown
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ OpenPGP card protocol implementation
|
|||||||
|
|
||||||
I try to follow "no clear password(s)" policy.
|
I try to follow "no clear password(s)" policy.
|
||||||
After key import, keystrings are also removed.
|
After key import, keystrings are also removed.
|
||||||
But because of this, we only support single key for this version.
|
But because of this, it is not that easy to overwrite key(s).
|
||||||
|
|
||||||
|
|
||||||
How a private key is stored
|
How a private key is stored
|
||||||
|
|||||||
@@ -307,3 +307,10 @@ flash_key_release (const uint8_t *key_addr)
|
|||||||
{
|
{
|
||||||
(void)key_addr;
|
(void)key_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
flash_clear_halfword (uint32_t addr)
|
||||||
|
{
|
||||||
|
flash_program_halfword (addr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ extern uint8_t *flash_key_alloc (void);
|
|||||||
extern void flash_key_release (const uint8_t *);
|
extern void flash_key_release (const uint8_t *);
|
||||||
extern const uint8_t *flash_do_pool (void);
|
extern const uint8_t *flash_do_pool (void);
|
||||||
extern void flash_set_do_pool_last (const uint8_t *p);
|
extern void flash_set_do_pool_last (const uint8_t *p);
|
||||||
|
extern void flash_clear_halfword (uint32_t addr);
|
||||||
|
|
||||||
#define KEY_MAGIC_LEN 8
|
#define KEY_MAGIC_LEN 8
|
||||||
#define KEY_CONTENT_LEN 256 /* p and q */
|
#define KEY_CONTENT_LEN 256 /* p and q */
|
||||||
|
|||||||
27
src/random.c
27
src/random.c
@@ -30,9 +30,23 @@ extern void *_binary_random_bits_start;
|
|||||||
const uint8_t *
|
const uint8_t *
|
||||||
random_bytes_get (void)
|
random_bytes_get (void)
|
||||||
{
|
{
|
||||||
uint32_t addr;
|
uint32_t addr, addr0;
|
||||||
|
|
||||||
addr = (uint32_t)&_binary_random_bits_start + ((hardclock () << 5) & 0x3e0);
|
addr = (uint32_t)&_binary_random_bits_start + ((hardclock () << 5) & 0x3e0);
|
||||||
|
addr0 = addr;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (*(uint32_t *)addr != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
addr += 32;
|
||||||
|
if (addr >= ((uint32_t)&_binary_random_bits_start) + 1024)
|
||||||
|
addr = ((uint32_t)&_binary_random_bits_start);
|
||||||
|
|
||||||
|
if (addr == addr0)
|
||||||
|
fatal ();
|
||||||
|
}
|
||||||
|
|
||||||
return (const uint8_t *)addr;
|
return (const uint8_t *)addr;
|
||||||
}
|
}
|
||||||
@@ -40,12 +54,19 @@ random_bytes_get (void)
|
|||||||
void
|
void
|
||||||
random_bytes_free (const uint8_t *p)
|
random_bytes_free (const uint8_t *p)
|
||||||
{
|
{
|
||||||
(void)p;
|
int i;
|
||||||
|
uint32_t addr = (uint32_t)p;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
flash_clear_halfword (addr+i*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
get_random (void)
|
get_random (void)
|
||||||
{
|
{
|
||||||
const uint32_t *p = (const uint32_t *)random_bytes_get ();
|
const uint32_t *p = (const uint32_t *)random_bytes_get ();
|
||||||
return *p;
|
uint32_t r = *p;
|
||||||
|
|
||||||
|
random_bytes_free ((const uint8_t *)p);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,14 @@
|
|||||||
#include "hw_config.h"
|
#include "hw_config.h"
|
||||||
#include "usb_istr.h"
|
#include "usb_istr.h"
|
||||||
|
|
||||||
|
#define ICC_SET_PARAMS 0x61
|
||||||
#define ICC_POWER_ON 0x62
|
#define ICC_POWER_ON 0x62
|
||||||
#define ICC_POWER_OFF 0x63
|
#define ICC_POWER_OFF 0x63
|
||||||
#define ICC_SLOT_STATUS 0x65
|
#define ICC_SLOT_STATUS 0x65
|
||||||
#define ICC_XFR_BLOCK 0x6F
|
#define ICC_XFR_BLOCK 0x6F
|
||||||
#define ICC_DATA_BLOCK_RET 0x80
|
#define ICC_DATA_BLOCK_RET 0x80
|
||||||
#define ICC_SLOT_STATUS_RET 0x81
|
#define ICC_SLOT_STATUS_RET 0x81
|
||||||
|
#define ICC_SET_PARAMS_RET 0x82
|
||||||
|
|
||||||
#define ICC_MSG_SEQ_OFFSET 6
|
#define ICC_MSG_SEQ_OFFSET 6
|
||||||
#define ICC_MSG_STATUS_OFFSET 7
|
#define ICC_MSG_STATUS_OFFSET 7
|
||||||
@@ -153,9 +155,25 @@ enum icc_state
|
|||||||
|
|
||||||
static enum icc_state icc_state;
|
static enum icc_state icc_state;
|
||||||
|
|
||||||
/* Direct conversion, T=1, "FSIJ" */
|
/*
|
||||||
static const char ATR[] = { '\x3B', '\x84', '\x01', 'F', 'S', 'I', 'J',
|
* ATR (Answer To Reset) string
|
||||||
('\x84'^'F'^'S'^'I'^'J') };
|
*
|
||||||
|
* TS = 0x3B: Direct conversion
|
||||||
|
* T0 = 0x94: TA1 and TD1 follow, 4 historical bytes
|
||||||
|
* TA1 = 0x11: FI=1, DI=1
|
||||||
|
* TD1 = 0x81: TD2 follows, T=1
|
||||||
|
* TD2 = 0x31: TA3 and TB3 follow, T=1
|
||||||
|
* TA3 = 0xFE: IFSC = 254 bytes
|
||||||
|
* TB3 = 0x55: BWI = 5, CWI = 5 (BWT timeout 3.2 sec)
|
||||||
|
* Historical bytes: "FSIJ"
|
||||||
|
* XOR check
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static const char ATR[] = {
|
||||||
|
0x3B, 0x94, 0x11, 0x81, 0x31, 0xFE, 0x55,
|
||||||
|
'F', 'S', 'I', 'J',
|
||||||
|
(0x94^0x11^0x81^0x31^0xFE^0x55^'F'^'S'^'I'^'J')
|
||||||
|
};
|
||||||
|
|
||||||
/* Send back ATR (Answer To Reset) */
|
/* Send back ATR (Answer To Reset) */
|
||||||
enum icc_state
|
enum icc_state
|
||||||
@@ -183,7 +201,7 @@ icc_power_on (void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
icc_tx_size = ICC_MSG_DATA_OFFSET + size_atr;
|
icc_tx_size = ICC_MSG_HEADER_SIZE + size_atr;
|
||||||
USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
|
USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
|
||||||
SetEPTxValid (ENDP1);
|
SetEPTxValid (ENDP1);
|
||||||
DEBUG_INFO ("ON\r\n");
|
DEBUG_INFO ("ON\r\n");
|
||||||
@@ -217,7 +235,7 @@ icc_send_status (void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
icc_tx_size = ICC_MSG_DATA_OFFSET;
|
icc_tx_size = ICC_MSG_HEADER_SIZE;
|
||||||
USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
|
USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
|
||||||
SetEPTxValid (ENDP1);
|
SetEPTxValid (ENDP1);
|
||||||
}
|
}
|
||||||
@@ -265,7 +283,7 @@ icc_send_data_block (uint8_t status, uint8_t error, uint8_t chain,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
icc_tx_size = ICC_MSG_DATA_OFFSET + len;
|
icc_tx_size = ICC_MSG_HEADER_SIZE + len;
|
||||||
USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
|
USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
|
||||||
SetEPTxValid (ENDP1);
|
SetEPTxValid (ENDP1);
|
||||||
#ifdef DEBUG_MORE
|
#ifdef DEBUG_MORE
|
||||||
@@ -274,6 +292,33 @@ icc_send_data_block (uint8_t status, uint8_t error, uint8_t chain,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
icc_send_params (void)
|
||||||
|
{
|
||||||
|
memcpy (icc_tx_data, icc_rcv_data,
|
||||||
|
ICC_MSG_HEADER_SIZE + icc_header->data_len);
|
||||||
|
icc_tx_data[0] = ICC_SET_PARAMS_RET;
|
||||||
|
icc_tx_data[ICC_MSG_STATUS_OFFSET] = 0;
|
||||||
|
icc_tx_data[ICC_MSG_ERROR_OFFSET] = 0;
|
||||||
|
icc_tx_data[ICC_MSG_CHAIN_OFFSET] = icc_rcv_data[7];
|
||||||
|
|
||||||
|
if (!icc_tx_ready ())
|
||||||
|
{ /* not ready to send */
|
||||||
|
DEBUG_INFO ("ERR09\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
icc_tx_size = ICC_MSG_HEADER_SIZE + icc_header->data_len;
|
||||||
|
USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
|
||||||
|
SetEPTxValid (ENDP1);
|
||||||
|
#ifdef DEBUG_MORE
|
||||||
|
DEBUG_INFO ("DATA\r\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static enum icc_state
|
static enum icc_state
|
||||||
icc_handle_data (void)
|
icc_handle_data (void)
|
||||||
{
|
{
|
||||||
@@ -295,7 +340,7 @@ icc_handle_data (void)
|
|||||||
break;
|
break;
|
||||||
case ICC_STATE_WAIT:
|
case ICC_STATE_WAIT:
|
||||||
if (icc_header->msg_type == ICC_POWER_ON)
|
if (icc_header->msg_type == ICC_POWER_ON)
|
||||||
/* Not in the spec., but GPG 2 */
|
/* Not in the spec., but pcscd/libccid */
|
||||||
next_state = icc_power_on ();
|
next_state = icc_power_on ();
|
||||||
else if (icc_header->msg_type == ICC_POWER_OFF)
|
else if (icc_header->msg_type == ICC_POWER_OFF)
|
||||||
next_state = icc_power_off ();
|
next_state = icc_power_off ();
|
||||||
@@ -326,6 +371,8 @@ icc_handle_data (void)
|
|||||||
DEBUG_INFO ("ERR02\r\n");
|
DEBUG_INFO ("ERR02\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (icc_header->msg_type == ICC_SET_PARAMS)
|
||||||
|
icc_send_params ();
|
||||||
else
|
else
|
||||||
{ /* XXX: error */
|
{ /* XXX: error */
|
||||||
DEBUG_INFO ("ERR03\r\n");
|
DEBUG_INFO ("ERR03\r\n");
|
||||||
|
|||||||
@@ -75,7 +75,18 @@ static const uint8_t gnukConfigDescriptor[] = {
|
|||||||
0xfe, 0, 0, 0, /* dwMaxIFSD: */
|
0xfe, 0, 0, 0, /* dwMaxIFSD: */
|
||||||
0, 0, 0, 0, /* dwSynchProtocols: FIXED VALUE */
|
0, 0, 0, 0, /* dwSynchProtocols: FIXED VALUE */
|
||||||
0, 0, 0, 0, /* dwMechanical: FIXED VALUE */
|
0, 0, 0, 0, /* dwMechanical: FIXED VALUE */
|
||||||
0x40, 0x08, 0x04, 0x00, /* dwFeatures: Short and extended APDU level */
|
#ifdef DEBUG
|
||||||
|
0x80, 0x04, 0x04, 0x00, /* dwFeatures:
|
||||||
|
* Short and extended APDU level: 0x40000
|
||||||
|
* Automatic IFSD : 0x00400
|
||||||
|
* Automatic PPS CUR : 0x00080
|
||||||
|
*/
|
||||||
|
#else
|
||||||
|
0x40, 0x00, 0x04, 0x00, /* dwFeatures:
|
||||||
|
* Short and extended APDU level: 0x40000
|
||||||
|
* Automatic PPS PROP : 0x00040
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
0x40, 0x00, 0, 0, /* dwMaxCCIDMessageLength: 64 */
|
0x40, 0x00, 0, 0, /* dwMaxCCIDMessageLength: 64 */
|
||||||
0xff, /* bClassGetResponse: */
|
0xff, /* bClassGetResponse: */
|
||||||
0xff, /* bClassEnvelope: */
|
0xff, /* bClassEnvelope: */
|
||||||
|
|||||||
Reference in New Issue
Block a user