works now again

This commit is contained in:
NIIBE Yutaka
2010-09-06 01:55:29 +09:00
parent 043946aad0
commit 6b752f7489
13 changed files with 215 additions and 141 deletions

19
README
View File

@@ -1,7 +1,9 @@
Gnuk - software for GPG USB Token Gnuk - software for GPG USB Token
Version 0.0 2010-09-05 Version 0.0
2010-09-06
Niibe Yutaka Niibe Yutaka
Free Software Initiative of Japan
What's Gnuk What's Gnuk
=========== ===========
@@ -14,8 +16,7 @@ processor.
Release notes Release notes
============= =============
This is initial release of Gnuk, and it is experimental yet. This is initial release of Gnuk, and it is experimental.
It is not yet daily use.
Supported and tested features are: Supported and tested features are:
@@ -25,7 +26,7 @@ Supported and tested features are:
* Password handling (PW1, RC, PW3) * Password handling (PW1, RC, PW3)
* Single key import * Single key import for signature.
* PSO: Digital Signature * PSO: Digital Signature
@@ -107,6 +108,13 @@ Type:
$ make $ make
In the make process, it takes time for the command of
dd if=/dev/random bs=1 of=random_bits count=1024
Don't just wait, but do some other work on your PC.
/dev/random needs entropy to finish.
Then, we will have "gnuk.elf". Then, we will have "gnuk.elf".
@@ -134,7 +142,6 @@ virtual COM port by:
and you will see debug output of Gnuk. and you will see debug output of Gnuk.
For libccid, we need following change: For libccid, we need following change:
--- /etc/libccid_Info.plist.dpkg-dist 2009-07-29 06:50:20.000000000 +0900 --- /etc/libccid_Info.plist.dpkg-dist 2009-07-29 06:50:20.000000000 +0900
@@ -171,7 +178,7 @@ Then, try following to see Gnuk runs:
$ gpg --card-status $ gpg --card-status
For more, see doc/HOWTO_GNUK. For more, see doc/HOWTO-GNUK.

30
doc/HACKING Normal file
View File

@@ -0,0 +1,30 @@
* Random Number Generator
RNG is needed for Data Encryption Key to encrypt private key (P and Q).
It is important to collect enough entropy. Perhaps, it would
be possible to get entropy from USB traffic (of other devices).
* RSA
It would be good not to use malloc.
* Manufacture ID
Get it from FSFE.
* Serial number
Currently, aid[] in openpgp-do.c has serial number 00000001.
It would be good to generate (random) number at compile time.
* Flash ROM recover from shutdown
* Flash ROM garbage collection
* Flash ROM protection

View File

@@ -2,21 +2,20 @@ USB communication
================= =================
* No command chaining, but extended APDU and extended Lc and Le * No command chaining, but extended APDU and extended Lc and Le
* dwMaxCCIDMessageLength: 64 * dwMaxCCIDMessageLength: 64
OpenPGP card protocol implementation OpenPGP card protocol implementation
==================================== ====================================
* No clear password(s) I try to follow "no clear password(s)" policy.
After key import, keystrings are also removed.
PW1 But because of this, we only support single key for this version.
* Support of Resetting code
KEY How a private key is stored
======= ===========================
KEYPTR KEYPTR
----> [ P ][ Q ][ N ] ----> [ P ][ Q ][ N ]

View File

@@ -89,7 +89,8 @@ CSRC = $(PORTSRC) \
$(CRYPTSRC) \ $(CRYPTSRC) \
main.c usb_lld.c \ main.c usb_lld.c \
hw_config.c usb_desc.c usb_prop.c \ hw_config.c usb_desc.c usb_prop.c \
usb-icc.c openpgp.c ac.c openpgp-do.c flash.c hardclock.c random.c usb-icc.c openpgp.c ac.c openpgp-do.c flash.c hardclock.c \
random.c
ifneq ($(ENABLE_DEBUG),) ifneq ($(ENABLE_DEBUG),)
CSRC += debug.c CSRC += debug.c
@@ -203,3 +204,17 @@ ifeq ($(USE_FWLIB),yes)
endif endif
include $(CHIBIOS)/os/ports/GCC/ARM/rules.mk include $(CHIBIOS)/os/ports/GCC/ARM/rules.mk
OBJS += random-data.o
OUTFILES += random_bits
random_bits:
dd if=/dev/random bs=1 of=random_bits count=1024
random-data.o: random_bits
$(CP) -I binary $< -O elf32-littlearm -B arm \
--rename-section \
.data=.gnuk_random,alloc,load,readonly,data,contents \
$@
$(PROJECT).elf: random-data.o

View File

@@ -34,6 +34,9 @@ verify_pso_cds (const uint8_t *pw, int pw_len)
|| pw_status_bytes[PW_STATUS_PW1] == 0) /* locked */ || pw_status_bytes[PW_STATUS_PW1] == 0) /* locked */
return 0; return 0;
DEBUG_INFO ("verify_pso_cds\r\n");
DEBUG_BYTE (pw_len);
keystring[0] = pw_len; keystring[0] = pw_len;
sha1 (pw, pw_len, keystring+1); sha1 (pw, pw_len, keystring+1);
memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES); memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES);
@@ -43,7 +46,7 @@ verify_pso_cds (const uint8_t *pw, int pw_len)
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
return r; return r;
} }
else else if (pwsb[PW_STATUS_PW1] != 3)
{ {
pwsb[PW_STATUS_PW1] = 3; pwsb[PW_STATUS_PW1] = 3;
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
@@ -80,7 +83,7 @@ verify_pso_other (const uint8_t *pw, int pw_len)
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
return r; return r;
} }
else else if (pwsb[PW_STATUS_PW1] != 3)
{ {
pwsb[PW_STATUS_PW1] = 3; pwsb[PW_STATUS_PW1] = 3;
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
@@ -162,7 +165,7 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known)
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
return -1; return -1;
} }
else else if (pwsb[PW_STATUS_PW3] != 3)
{ /* OK, the user is now authenticated */ { /* OK, the user is now authenticated */
pwsb[PW_STATUS_PW3] = 3; pwsb[PW_STATUS_PW3] = 3;
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);

View File

@@ -231,7 +231,7 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len)
} }
else else
{ {
hw |= data[0]<<8; hw |= (data[0]<<8);
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
return NULL; return NULL;
addr += 2; addr += 2;

View File

@@ -185,10 +185,10 @@ extern uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE];
#define SIZE_PW_STATUS_BYTES 7 #define SIZE_PW_STATUS_BYTES 7
extern uint8_t *get_data_encryption_key (void); /* 16-byte random bytes */ /* 32-byte random bytes */
extern void dek_free (uint8_t *);
extern uint32_t get_random (void); extern uint32_t get_random (void);
extern void random_init (void); extern const uint8_t *random_bytes_get (void);
extern void random_bytes_free (const uint8_t *);
extern uint32_t hardclock (void); extern uint32_t hardclock (void);

View File

@@ -115,6 +115,11 @@ SECTIONS
PROVIDE(end = .); PROVIDE(end = .);
_end = .; _end = .;
.gnuk_random : ALIGN (1024)
{
*(.gnuk_random)
} > flash
.gnuk_flash : ALIGN (1024) .gnuk_flash : ALIGN (1024)
{ {
_do_pool = .; _do_pool = .;

View File

@@ -173,7 +173,6 @@ main (int argc, char **argv)
{ {
eventmask_t m; eventmask_t m;
int count = 0; int count = 0;
uint8_t once = 0;
(void)argc; (void)argc;
(void)argv; (void)argv;
@@ -200,8 +199,6 @@ main (int argc, char **argv)
while (1) while (1)
{ {
uint32_t r;
#if 0 #if 0
if (palReadPad(IOPORT1, GPIOA_BUTTON)) if (palReadPad(IOPORT1, GPIOA_BUTTON))
palSetPad (IOPORT3, GPIOC_LED); palSetPad (IOPORT3, GPIOC_LED);
@@ -211,23 +208,15 @@ main (int argc, char **argv)
if (m == EV_LED) if (m == EV_LED)
palClearPad (IOPORT3, GPIOC_LED); palClearPad (IOPORT3, GPIOC_LED);
if (once == 0 && bDeviceState == CONFIGURED) #ifdef DEBUG_MORE
{
random_init ();
once = 1;
r = get_random ();
DEBUG_WORD (r);
}
if (bDeviceState == CONFIGURED && (count % 100) == 0) if (bDeviceState == CONFIGURED && (count % 100) == 0)
{ {
r = get_random (); DEBUG_WORD (count / 100);
DEBUG_WORD (r);
_write ("\r\nThis is ChibiOS 2.0.2 on Olimex STM32-H103.\r\n" _write ("\r\nThis is ChibiOS 2.0.2 on Olimex STM32-H103.\r\n"
"Testing USB driver.\n\n" "Testing USB driver.\n\n"
"Hello world\r\n\r\n", 47+21+15); "Hello world\r\n\r\n", 47+21+15);
} }
#endif
m = chEvtWaitOneTimeout (ALL_EVENTS, 100); m = chEvtWaitOneTimeout (ALL_EVENTS, 100);
if (m == EV_LED) if (m == EV_LED)

View File

@@ -38,7 +38,7 @@
*/ */
/* AID */ /* AID */
static const uint8_t const aid[] __attribute__ ((aligned (1))) = { static const uint8_t aid[] __attribute__ ((aligned (1))) = {
16, 16,
0xd2, 0x76, 0x00, 0x01, 0x24, 0x01, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01,
0x02, 0x00, /* Version 2.0 */ 0x02, 0x00, /* Version 2.0 */
@@ -48,7 +48,7 @@ static const uint8_t const aid[] __attribute__ ((aligned (1))) = {
}; };
/* Historical Bytes (template) */ /* Historical Bytes (template) */
static const uint8_t const historical_bytes[] __attribute__ ((aligned (1))) = { static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
10, 10,
0x00, 0x00,
0x31, 0x80, /* Full DF name */ 0x31, 0x80, /* Full DF name */
@@ -61,7 +61,7 @@ static const uint8_t const historical_bytes[] __attribute__ ((aligned (1))) = {
}; };
/* Extended Capabilities */ /* Extended Capabilities */
static const uint8_t const extended_capabilities[] __attribute__ ((aligned (1))) = { static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
10, 10,
0x30, /* 0x30, /*
* No SM, No get challenge, * No SM, No get challenge,
@@ -78,7 +78,7 @@ static const uint8_t const extended_capabilities[] __attribute__ ((aligned (1)))
}; };
/* Algorithm Attributes */ /* Algorithm Attributes */
static const uint8_t const algorithm_attr[] __attribute__ ((aligned (1))) = { static const uint8_t algorithm_attr[] __attribute__ ((aligned (1))) = {
6, 6,
0x01, /* RSA */ 0x01, /* RSA */
0x08, 0x00, /* Length modulus (in bit): 2048 */ 0x08, 0x00, /* Length modulus (in bit): 2048 */
@@ -86,7 +86,7 @@ static const uint8_t const algorithm_attr[] __attribute__ ((aligned (1))) = {
0x00 /* 0: p&q , 3: CRT with N (not yet supported) */ 0x00 /* 0: p&q , 3: CRT with N (not yet supported) */
}; };
static const uint8_t const do_pw_status_bytes_template[] = static const uint8_t do_pw_status_bytes_template[] =
{ {
7, 7,
1, /* PW1 valid for several PSO:CDS commands */ 1, /* PW1 valid for several PSO:CDS commands */
@@ -543,7 +543,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
const uint8_t *modulus; const uint8_t *modulus;
struct prvkey_data *pd; struct prvkey_data *pd;
uint8_t *key_addr; uint8_t *key_addr;
uint8_t *dek; const uint8_t *dek;
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1); const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC); const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
@@ -584,7 +584,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
DEBUG_INFO ("enc..."); DEBUG_INFO ("enc...");
dek = get_data_encryption_key (); /* 16-byte random bytes */ dek = random_bytes_get (); /* 16-byte random bytes */
encrypt (dek, (uint8_t *)&kd, sizeof (struct key_data)); encrypt (dek, (uint8_t *)&kd, sizeof (struct key_data));
DEBUG_INFO ("done\r\n"); DEBUG_INFO ("done\r\n");
@@ -594,7 +594,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
if (r < 0) if (r < 0)
{ {
dek_free (dek); random_bytes_free (dek);
free (pd); free (pd);
return r; return r;
} }
@@ -605,10 +605,12 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
ac_reset_pso_cds (); ac_reset_pso_cds ();
if (ks_pw1) if (ks_pw1)
{ {
uint8_t ks_pw1_len = ks_pw1[0];
memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE); memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE);
encrypt (ks_pw1+1, pd->dek_encrypted_1, DATA_ENCRYPTION_KEY_SIZE); encrypt (ks_pw1+1, pd->dek_encrypted_1, DATA_ENCRYPTION_KEY_SIZE);
/* Only its length */ /* Only its length */
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, ks_pw1, 1); gpg_do_write_simple (NR_DO_KEYSTRING_PW1, &ks_pw1_len, 1);
} }
else else
{ {
@@ -624,10 +626,12 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
if (ks_rc) if (ks_rc)
{ {
uint8_t ks_rc_len = ks_rc[0];
memcpy (pd->dek_encrypted_2, dek, DATA_ENCRYPTION_KEY_SIZE); memcpy (pd->dek_encrypted_2, dek, DATA_ENCRYPTION_KEY_SIZE);
encrypt (ks_rc+1, pd->dek_encrypted_2, DATA_ENCRYPTION_KEY_SIZE); encrypt (ks_rc+1, pd->dek_encrypted_2, DATA_ENCRYPTION_KEY_SIZE);
/* Only its length */ /* Only its length */
gpg_do_write_simple (NR_DO_KEYSTRING_RC, ks_rc, 1); gpg_do_write_simple (NR_DO_KEYSTRING_RC, &ks_rc_len, 1);
} }
else else
memset (pd->dek_encrypted_2, 0, DATA_ENCRYPTION_KEY_SIZE); memset (pd->dek_encrypted_2, 0, DATA_ENCRYPTION_KEY_SIZE);
@@ -638,7 +642,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data)); p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data));
do_ptr[nr] = p; do_ptr[nr] = p;
dek_free (dek); random_bytes_free (dek);
free (pd); free (pd);
if (p == NULL) if (p == NULL)
return -1; return -1;
@@ -1086,9 +1090,10 @@ void
gpg_do_public_key (uint8_t kk_byte) gpg_do_public_key (uint8_t kk_byte)
{ {
const uint8_t *do_data; const uint8_t *do_data;
uint8_t *key_addr; const uint8_t *key_addr;
DEBUG_INFO ("Public key\r\n"); DEBUG_INFO ("Public key\r\n");
DEBUG_BYTE (kk_byte);
if (kk_byte == 0xb6) if (kk_byte == 0xb6)
do_data = do_ptr[NR_DO_PRVKEY_SIG]; do_data = do_ptr[NR_DO_PRVKEY_SIG];
@@ -1104,7 +1109,7 @@ gpg_do_public_key (uint8_t kk_byte)
return; return;
} }
key_addr = *(uint8_t **)&do_data[1]; key_addr = *(const uint8_t **)&do_data[1];
res_p = res_APDU; res_p = res_APDU;
@@ -1200,12 +1205,18 @@ gpg_do_reset_pw_counter (uint8_t which)
if (do_data) if (do_data)
{ {
memcpy (pwsb, &do_data[1], SIZE_PW_STATUS_BYTES); memcpy (pwsb, &do_data[1], SIZE_PW_STATUS_BYTES);
if (pwsb[which] == 3)
return;
pwsb[which] = 3; pwsb[which] = 3;
flash_do_release (do_data); flash_do_release (do_data);
} }
else else
{ {
memcpy (pwsb, PW_STATUS_BYTES_TEMPLATE, SIZE_PW_STATUS_BYTES); memcpy (pwsb, PW_STATUS_BYTES_TEMPLATE, SIZE_PW_STATUS_BYTES);
if (pwsb[which] == 3)
return;
pwsb[which] = 3; pwsb[which] = 3;
} }

View File

@@ -42,7 +42,7 @@
#define INS_PUT_DATA 0xda #define INS_PUT_DATA 0xda
#define INS_PUT_DATA_ODD 0xdb /* For key import */ #define INS_PUT_DATA_ODD 0xdb /* For key import */
static const uint8_t const static const uint8_t
select_file_TOP_result[] __attribute__ ((aligned (1))) = { select_file_TOP_result[] __attribute__ ((aligned (1))) = {
0x00, 0x00, /* unused */ 0x00, 0x00, /* unused */
0x0b, 0x10, /* number of bytes in this directory */ 0x0b, 0x10, /* number of bytes in this directory */
@@ -60,7 +60,7 @@ select_file_TOP_result[] __attribute__ ((aligned (1))) = {
0x00, 0x00 /* PIN status: OK, PIN blocked?: No */ 0x00, 0x00 /* PIN status: OK, PIN blocked?: No */
}; };
static const uint8_t const static const uint8_t
read_binary_result[] __attribute__ ((aligned (1))) = { read_binary_result[] __attribute__ ((aligned (1))) = {
0x5a, 0x4, 0x01, 0x02, 0x03, 0x04 0x5a, 0x4, 0x01, 0x02, 0x03, 0x04
}; };
@@ -89,17 +89,24 @@ cmd_verify (void)
int len; int len;
uint8_t p2 = cmd_APDU[3]; uint8_t p2 = cmd_APDU[3];
int r; int r;
int data_start = 5;
DEBUG_INFO (" - VERIFY\r\n"); DEBUG_INFO (" - VERIFY\r\n");
DEBUG_BYTE (p2); DEBUG_BYTE (p2);
len = cmd_APDU[4]; len = cmd_APDU[4];
if (len == 0) /* extended length */
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
data_start = 7;
}
if (p2 == 0x81) if (p2 == 0x81)
r = verify_pso_cds (&cmd_APDU[5], len); r = verify_pso_cds (&cmd_APDU[data_start], len);
else if (p2 == 0x82) else if (p2 == 0x82)
r = verify_pso_other (&cmd_APDU[5], len); r = verify_pso_other (&cmd_APDU[data_start], len);
else else
r = verify_admin (&cmd_APDU[5], len); r = verify_admin (&cmd_APDU[data_start], len);
if (r < 0) if (r < 0)
{ {
@@ -152,6 +159,12 @@ cmd_change_password (void)
DEBUG_INFO ("Change PW\r\n"); DEBUG_INFO ("Change PW\r\n");
DEBUG_BYTE (who); DEBUG_BYTE (who);
if (len == 0) /* extended length */
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
pw += 2;
}
if (who == 1) /* PW1 */ if (who == 1) /* PW1 */
{ {
const uint8_t *pk = gpg_do_read_simple (NR_DO_KEYSTRING_PW1); const uint8_t *pk = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
@@ -169,6 +182,9 @@ cmd_change_password (void)
pw_len = 6; pw_len = 6;
newpw = pw + pw_len; newpw = pw + pw_len;
newpw_len = len - pw_len; newpw_len = len - pw_len;
sha1 (newpw, newpw_len, new_ks);
new_ks0[0] = newpw_len;
goto no_prvkey; goto no_prvkey;
} }
else else
@@ -244,22 +260,28 @@ static void
cmd_reset_user_password (void) cmd_reset_user_password (void)
{ {
uint8_t p1 = cmd_APDU[2]; uint8_t p1 = cmd_APDU[2];
int len = cmd_APDU[3]; int len = cmd_APDU[4];
const uint8_t *pw = &cmd_APDU[4]; const uint8_t *pw = &cmd_APDU[5];
const uint8_t *newpw; const uint8_t *newpw;
int pw_len, newpw_len; int pw_len, newpw_len;
int r; int r;
uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
uint8_t *new_ks = &new_ks0[1];
DEBUG_INFO ("Reset PW1\r\n"); DEBUG_INFO ("Reset PW1\r\n");
DEBUG_BYTE (p1); DEBUG_BYTE (p1);
if (len == 0) /* extended length */
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
pw += 2;
}
if (p1 == 0x00) /* by User with Reseting Code */ if (p1 == 0x00) /* by User with Reseting Code */
{ {
const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS); const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS);
const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC); const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
uint8_t old_ks[KEYSTRING_MD_SIZE]; uint8_t old_ks[KEYSTRING_MD_SIZE];
uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
uint8_t *new_ks = &new_ks0[1];
if (pw_status_bytes == NULL if (pw_status_bytes == NULL
|| pw_status_bytes[PW_STATUS_PW1] == 0) /* locked */ || pw_status_bytes[PW_STATUS_PW1] == 0) /* locked */
@@ -318,16 +340,14 @@ cmd_reset_user_password (void)
} }
else /* by Admin (p1 == 0x02) */ else /* by Admin (p1 == 0x02) */
{ {
const uint8_t *old_ks = keystring_md_pw3;
if (!ac_check_status (AC_ADMIN_AUTHORIZED)) if (!ac_check_status (AC_ADMIN_AUTHORIZED))
{ {
DEBUG_INFO ("permission denied.\r\n"); DEBUG_INFO ("permission denied.\r\n");
GPG_SECURITY_FAILURE (); GPG_SECURITY_FAILURE ();
return;
} }
else
{
const uint8_t *old_ks = keystring_md_pw3;
uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
uint8_t *new_ks = &new_ks0[1];
newpw_len = len; newpw_len = len;
newpw = pw; newpw = pw;
@@ -359,7 +379,6 @@ cmd_reset_user_password (void)
GPG_SUCCESS (); GPG_SUCCESS ();
} }
} }
}
} }
static void static void
@@ -395,7 +414,7 @@ cmd_pgp_gakp (void)
if (cmd_APDU[2] == 0x81) if (cmd_APDU[2] == 0x81)
/* Get public key */ /* Get public key */
gpg_do_public_key (cmd_APDU[5]); gpg_do_public_key (cmd_APDU[7]);
else else
{ /* Generate key pair */ { /* Generate key pair */
if (!ac_check_status (AC_ADMIN_AUTHORIZED)) if (!ac_check_status (AC_ADMIN_AUTHORIZED))

View File

@@ -1,59 +1,51 @@
/*
* random.c -- get random bytes
*
* Copyright (C) 2010 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
*
* Gnuk is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h" #include "config.h"
#include "ch.h" #include "ch.h"
#include "gnuk.h" #include "gnuk.h"
/* extern void *_binary_random_bits_start;
* XXX: I have tried havege_rand, but it requires too much memory...
*/
/* const uint8_t *
* Multiply-with-carry method by George Marsaglia random_bytes_get (void)
*/ {
static uint32_t m_w; uint32_t addr;
static uint32_t m_z;
addr = (uint32_t)&_binary_random_bits_start + ((hardclock () << 5) & 0x3e0);
return (const uint8_t *)addr;
}
void
random_bytes_free (const uint8_t *p)
{
(void)p;
}
uint32_t uint32_t
get_random (void) get_random (void)
{ {
m_z = 36969 * (m_z & 65535) + (m_z >> 16); const uint32_t *p = (const uint32_t *)random_bytes_get ();
m_w = 18000 * (m_w & 65535) + (m_w >> 16); return *p;
return (m_z << 16) + m_w;
}
void
random_init (void)
{
static uint8_t s = 0;
again:
if ((s & 1))
m_w = (m_w << 8) ^ hardclock ();
else
m_z = (m_z << 8) ^ hardclock ();
s++;
if (m_w == 0 || m_z == 0)
goto again;
}
uint8_t dek[16];
uint8_t *get_data_encryption_key (void)
{
uint32_t r;
r = get_random ();
memcpy (dek, &r, 4);
r = get_random ();
memcpy (dek+4, &r, 4);
r = get_random ();
memcpy (dek+8, &r, 4);
r = get_random ();
memcpy (dek+12, &r, 4);
return dek;
}
void
dek_free (uint8_t *dek)
{
(void)dek;
} }

View File

@@ -221,7 +221,9 @@ icc_send_status (void)
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
DEBUG_INFO ("St\r\n"); DEBUG_INFO ("St\r\n");
#endif
} }
enum icc_state enum icc_state
@@ -267,7 +269,9 @@ icc_send_data_block (uint8_t status, uint8_t error, uint8_t chain,
icc_tx_size = ICC_MSG_DATA_OFFSET + len; icc_tx_size = ICC_MSG_DATA_OFFSET + 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
DEBUG_INFO ("DATA\r\n"); DEBUG_INFO ("DATA\r\n");
#endif
} }
} }