mirror of
https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
synced 2024-09-19 18:30:15 +00:00
Merge rsa-removal branch.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
3b2540bbf6
commit
cd082d4823
2823
ChangeLog-1_2
Normal file
2823
ChangeLog-1_2
Normal file
File diff suppressed because it is too large
Load Diff
@ -105,8 +105,8 @@ itself is needed before compiling reGNUal.
|
||||
upgrade_by_passwd.py
|
||||
--------------------
|
||||
|
||||
In the source code distribution of 1.0.4 (or current development
|
||||
version) of Gnuk, there is a tool named 'upgrade_by_passwd.py'.
|
||||
Since the source code distribution of 1.0.4 of Gnuk, there is a tool
|
||||
named 'upgrade_by_passwd.py'.
|
||||
|
||||
This is an easy tool to hide lengthy steps from user and to allow user
|
||||
firmware upgrade only by password of Gnuk Token.
|
||||
@ -122,15 +122,11 @@ your environment for Gnuk Token.
|
||||
How to run the script: ::
|
||||
|
||||
$ cd tool
|
||||
$ ./upgrade_by_passwd.py ../regnual/regnual.bin ../src/build/gnuk.bin
|
||||
$ ./upgrade_by_passwd.py
|
||||
|
||||
Then, the script on your host PC invoke the steps described above, and
|
||||
you will get new version of Gnuk installed.
|
||||
|
||||
You can also specify -f option to skip entering your password (it
|
||||
assumes the factory setting).
|
||||
|
||||
If you already have configured another upgrade key installed, you can
|
||||
specify different slot by -k ``<slot_no>`` option. SLOT_NO can be 0
|
||||
to 3.
|
||||
--
|
||||
|
@ -5,7 +5,7 @@ PROJECT = gnuk
|
||||
|
||||
CHOPSTX = ../chopstx
|
||||
|
||||
CSRC = main.c call-rsa.c \
|
||||
CSRC = main.c \
|
||||
usb_desc.c usb_ctrl.c \
|
||||
usb-ccid.c openpgp.c ac.c openpgp-do.c flash.c \
|
||||
bn.c mod.c \
|
||||
@ -20,7 +20,7 @@ INCDIR =
|
||||
CRYPTDIR = ../polarssl
|
||||
CRYPTSRCDIR = $(CRYPTDIR)/library
|
||||
CRYPTINCDIR = $(CRYPTDIR)/include
|
||||
CRYPTSRC = $(CRYPTSRCDIR)/bignum.c $(CRYPTSRCDIR)/rsa.c $(CRYPTSRCDIR)/aes.c
|
||||
CRYPTSRC = $(CRYPTSRCDIR)/aes.c
|
||||
|
||||
CSRC += $(CRYPTSRC)
|
||||
INCDIR += $(CRYPTINCDIR)
|
||||
|
274
src/call-rsa.c
274
src/call-rsa.c
@ -1,274 +0,0 @@
|
||||
/*
|
||||
* call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2017
|
||||
* 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 <stdint.h>
|
||||
#include <string.h>
|
||||
#include <chopstx.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gnuk.h"
|
||||
#include "status-code.h"
|
||||
#include "random.h"
|
||||
#include "polarssl/config.h"
|
||||
#include "polarssl/rsa.h"
|
||||
|
||||
static rsa_context rsa_ctx;
|
||||
static struct chx_cleanup clp;
|
||||
|
||||
static void
|
||||
rsa_cleanup (void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
rsa_free (&rsa_ctx);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
|
||||
struct key_data *kd, int pubkey_len)
|
||||
{
|
||||
mpi P1, Q1, H;
|
||||
int ret = 0;
|
||||
unsigned char temp[pubkey_len];
|
||||
|
||||
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
|
||||
|
||||
mpi_init (&P1); mpi_init (&Q1); mpi_init (&H);
|
||||
|
||||
rsa_ctx.len = pubkey_len;
|
||||
MPI_CHK( mpi_lset (&rsa_ctx.E, 0x10001) );
|
||||
MPI_CHK( mpi_read_binary (&rsa_ctx.P, &kd->data[0], pubkey_len / 2) );
|
||||
MPI_CHK( mpi_read_binary (&rsa_ctx.Q, &kd->data[pubkey_len / 2],
|
||||
pubkey_len / 2) );
|
||||
#if 0
|
||||
MPI_CHK( mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q) );
|
||||
#endif
|
||||
MPI_CHK( mpi_sub_int (&P1, &rsa_ctx.P, 1) );
|
||||
MPI_CHK( mpi_sub_int (&Q1, &rsa_ctx.Q, 1) );
|
||||
MPI_CHK( mpi_mul_mpi (&H, &P1, &Q1) );
|
||||
MPI_CHK( mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H) );
|
||||
MPI_CHK( mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1) );
|
||||
MPI_CHK( mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1) );
|
||||
MPI_CHK( mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P) );
|
||||
cleanup:
|
||||
mpi_free (&P1); mpi_free (&Q1); mpi_free (&H);
|
||||
if (ret == 0)
|
||||
{
|
||||
int cs;
|
||||
|
||||
DEBUG_INFO ("RSA sign...");
|
||||
clp.next = NULL;
|
||||
clp.routine = rsa_cleanup;
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
ret = rsa_rsassa_pkcs1_v15_sign (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, SIG_RSA_RAW,
|
||||
msg_len, raw_message, temp);
|
||||
memcpy (output, temp, pubkey_len);
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
}
|
||||
|
||||
rsa_free (&rsa_ctx);
|
||||
if (ret != 0)
|
||||
{
|
||||
DEBUG_INFO ("fail:");
|
||||
DEBUG_SHORT (ret);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_INFO ("done.\r\n");
|
||||
GPG_SUCCESS ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* LEN: length in byte
|
||||
*/
|
||||
int
|
||||
modulus_calc (const uint8_t *p, int len, uint8_t *pubkey)
|
||||
{
|
||||
mpi P, Q, N;
|
||||
int ret;
|
||||
|
||||
mpi_init (&P); mpi_init (&Q); mpi_init (&N);
|
||||
MPI_CHK( mpi_read_binary (&P, p, len / 2) );
|
||||
MPI_CHK( mpi_read_binary (&Q, p + len / 2, len / 2) );
|
||||
MPI_CHK( mpi_mul_mpi (&N, &P, &Q) );
|
||||
MPI_CHK( mpi_write_binary (&N, pubkey, len) );
|
||||
cleanup:
|
||||
mpi_free (&P); mpi_free (&Q); mpi_free (&N);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
struct key_data *kd, unsigned int *output_len_p)
|
||||
{
|
||||
mpi P1, Q1, H;
|
||||
int ret;
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
size_t output_len;
|
||||
#endif
|
||||
|
||||
DEBUG_INFO ("RSA decrypt:");
|
||||
DEBUG_WORD ((uint32_t)&ret);
|
||||
|
||||
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
|
||||
mpi_init (&P1); mpi_init (&Q1); mpi_init (&H);
|
||||
|
||||
rsa_ctx.len = msg_len;
|
||||
DEBUG_WORD (msg_len);
|
||||
|
||||
MPI_CHK( mpi_lset (&rsa_ctx.E, 0x10001) );
|
||||
MPI_CHK( mpi_read_binary (&rsa_ctx.P, &kd->data[0], msg_len / 2) );
|
||||
MPI_CHK( mpi_read_binary (&rsa_ctx.Q, &kd->data[msg_len / 2], msg_len / 2) );
|
||||
#if 0
|
||||
MPI_CHK( mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q) );
|
||||
#endif
|
||||
MPI_CHK( mpi_sub_int (&P1, &rsa_ctx.P, 1) );
|
||||
MPI_CHK( mpi_sub_int (&Q1, &rsa_ctx.Q, 1) );
|
||||
MPI_CHK( mpi_mul_mpi (&H, &P1, &Q1) );
|
||||
MPI_CHK( mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H) );
|
||||
MPI_CHK( mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1) );
|
||||
MPI_CHK( mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1) );
|
||||
MPI_CHK( mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P) );
|
||||
cleanup:
|
||||
mpi_free (&P1); mpi_free (&Q1); mpi_free (&H);
|
||||
if (ret == 0)
|
||||
{
|
||||
int cs;
|
||||
|
||||
DEBUG_INFO ("RSA decrypt ...");
|
||||
clp.next = NULL;
|
||||
clp.routine = rsa_cleanup;
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, &output_len, input,
|
||||
output, MAX_RES_APDU_DATA_SIZE);
|
||||
*output_len_p = (unsigned int)output_len;
|
||||
#else
|
||||
ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
|
||||
RSA_PRIVATE, output_len_p, input,
|
||||
output, MAX_RES_APDU_DATA_SIZE);
|
||||
#endif
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (0);
|
||||
}
|
||||
|
||||
rsa_free (&rsa_ctx);
|
||||
if (ret != 0)
|
||||
{
|
||||
DEBUG_INFO ("fail:");
|
||||
DEBUG_SHORT (ret);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_INFO ("done.\r\n");
|
||||
GPG_SUCCESS ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rsa_verify (const uint8_t *pubkey, int pubkey_len,
|
||||
const uint8_t *hash, const uint8_t *sig)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
|
||||
rsa_ctx.len = pubkey_len;
|
||||
MPI_CHK( mpi_lset (&rsa_ctx.E, 0x10001) );
|
||||
MPI_CHK( mpi_read_binary (&rsa_ctx.N, pubkey, pubkey_len) );
|
||||
|
||||
DEBUG_INFO ("RSA verify...");
|
||||
|
||||
MPI_CHK( rsa_rsassa_pkcs1_v15_verify (&rsa_ctx, NULL, NULL,
|
||||
RSA_PUBLIC, SIG_RSA_SHA256, 32,
|
||||
hash, sig) );
|
||||
cleanup:
|
||||
rsa_free (&rsa_ctx);
|
||||
if (ret != 0)
|
||||
{
|
||||
DEBUG_INFO ("fail:");
|
||||
DEBUG_SHORT (ret);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_INFO ("verified.\r\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define RSA_EXPONENT 0x10001
|
||||
|
||||
int
|
||||
rsa_genkey (int pubkey_len, uint8_t *pubkey, uint8_t *p_q)
|
||||
{
|
||||
int ret;
|
||||
uint8_t index = 0;
|
||||
uint8_t *p = p_q;
|
||||
uint8_t *q = p_q + pubkey_len / 2;
|
||||
int cs;
|
||||
|
||||
extern int prng_seed (int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
extern void neug_flush (void);
|
||||
|
||||
neug_flush ();
|
||||
prng_seed (random_gen, &index);
|
||||
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
|
||||
|
||||
clp.next = NULL;
|
||||
clp.routine = rsa_cleanup;
|
||||
clp.arg = NULL;
|
||||
chopstx_cleanup_push (&clp);
|
||||
cs = chopstx_setcancelstate (0); /* Allow cancellation. */
|
||||
MPI_CHK( rsa_gen_key (&rsa_ctx, random_gen, &index, pubkey_len * 8,
|
||||
RSA_EXPONENT) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.P, p, pubkey_len / 2) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.Q, q, pubkey_len / 2) );
|
||||
MPI_CHK( mpi_write_binary (&rsa_ctx.N, pubkey, pubkey_len) );
|
||||
|
||||
cleanup:
|
||||
chopstx_setcancelstate (cs);
|
||||
chopstx_cleanup_pop (1);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
CRYPTDIR = ../polarssl
|
||||
CRYPTSRCDIR = $(CRYPTDIR)/library
|
||||
CRYPTINCDIR = $(CRYPTDIR)/include
|
||||
CRYPTSRC = $(CRYPTSRCDIR)/bignum.c $(CRYPTSRCDIR)/rsa.c \
|
||||
$(CRYPTSRCDIR)/aes.c \
|
||||
sha256.c call-rsa.c
|
||||
CRYPTSRC = $(CRYPTSRCDIR)/aes.c \
|
||||
sha256.c
|
||||
|
21
src/flash.c
21
src/flash.c
@ -57,8 +57,6 @@
|
||||
* _keystore_pool
|
||||
* Three flash pages for keystore
|
||||
* a page contains a key data of:
|
||||
* For RSA-2048: 512-byte (p, q and N)
|
||||
* For RSA-4096: 1024-byte (p, q and N)
|
||||
* For ECDSA/ECDH and EdDSA, there are padding after public key
|
||||
* _data_pool
|
||||
* <two pages>
|
||||
@ -158,12 +156,6 @@ flash_terminate (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
const uint8_t *p;
|
||||
|
||||
p = gpg_get_firmware_update_key (0);
|
||||
flash_erase_page ((uintptr_t)p);
|
||||
#endif
|
||||
for (i = 0; i < 3; i++)
|
||||
flash_erase_page ((uintptr_t)flash_key_getpage (i));
|
||||
flash_erase_page ((uintptr_t)FLASH_ADDR_DATA_STORAGE_START);
|
||||
@ -711,19 +703,6 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
maxsize = 6;
|
||||
p = &openpgpcard_aid[8];
|
||||
}
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
{
|
||||
maxsize = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
|
||||
if (len == 0 && offset == 0)
|
||||
{ /* This means removal of update key. */
|
||||
if (flash_program_halfword ((uintptr_t)p, 0) != 0)
|
||||
flash_warning ("DO WRITE ERROR");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
else if (file_id == FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Gnuk uses its own malloc functions.
|
||||
*
|
||||
* The intention is no-dependency to C library. But, we provide
|
||||
* malloc and free here, since RSA routines uses malloc/free
|
||||
* internally.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h> /* NULL and size_t */
|
||||
|
||||
#define malloc(size) gnuk_malloc (size)
|
||||
#define free(p) gnuk_free (p)
|
||||
|
||||
void *gnuk_malloc (size_t);
|
||||
void gnuk_free (void *);
|
15
src/gnuk.h
15
src/gnuk.h
@ -112,8 +112,6 @@ void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
|
||||
void gpg_do_public_key (uint8_t kk_byte);
|
||||
void gpg_do_keygen (uint8_t *buf);
|
||||
|
||||
const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
|
||||
|
||||
/* Constants: algo+size */
|
||||
#define ALGO_RSA4K 0
|
||||
/* #define ALGO_NISTP256R1 1 */
|
||||
@ -157,10 +155,6 @@ void flash_increment_counter (uint8_t counter_tag_nr);
|
||||
void flash_reset_counter (uint8_t counter_tag_nr);
|
||||
|
||||
#define FILEID_SERIAL_NO 0
|
||||
#define FILEID_UPDATE_KEY_0 1
|
||||
#define FILEID_UPDATE_KEY_1 2
|
||||
#define FILEID_UPDATE_KEY_2 3
|
||||
#define FILEID_UPDATE_KEY_3 4
|
||||
#define FILEID_CH_CERTIFICATE 5
|
||||
int flash_erase_binary (uint8_t file_id);
|
||||
int flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
@ -171,8 +165,6 @@ int flash_write_binary (uint8_t file_id, const uint8_t *data,
|
||||
/* Linker set these two symbols */
|
||||
extern uint8_t ch_certificate_start;
|
||||
|
||||
#define FIRMWARE_UPDATE_KEY_CONTENT_LEN 256 /* RSA-2048 (p and q) */
|
||||
|
||||
#define INITIAL_VECTOR_SIZE 16
|
||||
#define DATA_ENCRYPTION_KEY_SIZE 16
|
||||
|
||||
@ -264,13 +256,6 @@ void put_binary (const char *s, int len);
|
||||
#define DEBUG_BINARY(s,len)
|
||||
#endif
|
||||
|
||||
int rsa_sign (const uint8_t *, uint8_t *, int, struct key_data *, int);
|
||||
int modulus_calc (const uint8_t *, int, uint8_t *);
|
||||
int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *,
|
||||
unsigned int *);
|
||||
int rsa_verify (const uint8_t *, int, const uint8_t *, const uint8_t *);
|
||||
int rsa_genkey (int, uint8_t *, uint8_t *);
|
||||
|
||||
int ecdsa_sign_p256k1 (const uint8_t *hash, uint8_t *output,
|
||||
const uint8_t *key_data);
|
||||
int ecc_compute_public_p256k1 (const uint8_t *key_data, uint8_t *);
|
||||
|
@ -141,9 +141,6 @@ SECTIONS
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_updatekey_store = .;
|
||||
. += 1024;
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
_data_pool = .;
|
||||
KEEP(*(.gnuk_data))
|
||||
. = ALIGN(@FLASH_PAGE_SIZE@);
|
||||
|
191
src/main.c
191
src/main.c
@ -294,9 +294,6 @@ calculate_regnual_entry_address (const uint8_t *addr)
|
||||
|
||||
extern void *ccid_thread (void *arg);
|
||||
|
||||
static void gnuk_malloc_init (void);
|
||||
|
||||
|
||||
extern uint32_t bDeviceState;
|
||||
|
||||
/*
|
||||
@ -318,8 +315,6 @@ main (int argc, const char *argv[])
|
||||
|
||||
chopstx_conf_idle (1);
|
||||
|
||||
gnuk_malloc_init ();
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define FLASH_IMAGE_NAME ".gnuk-flash-image"
|
||||
|
||||
@ -538,189 +533,3 @@ fatal (uint8_t code)
|
||||
_write ("fatal\r\n", 7);
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/*
|
||||
* Malloc for Gnuk.
|
||||
*
|
||||
* Each memory chunk has header with size information.
|
||||
* The size of chunk is at least 16.
|
||||
*
|
||||
* Free memory is managed by FREE_LIST.
|
||||
*
|
||||
* When it is managed in FREE_LIST, three pointers, ->NEXT, ->PREV,
|
||||
* and ->NEIGHBOR is used. NEXT and PREV is to implement doubly
|
||||
* linked list. NEIGHBOR is to link adjacent memory chunk to be
|
||||
* reclaimed to system.
|
||||
*/
|
||||
|
||||
#ifdef GNU_LINUX_EMULATION
|
||||
#define HEAP_SIZE (32*1024)
|
||||
uint8_t __heap_base__[HEAP_SIZE];
|
||||
|
||||
#define HEAP_START __heap_base__
|
||||
#define HEAP_END (__heap_base__ + HEAP_SIZE)
|
||||
#define HEAP_ALIGNMENT 32
|
||||
#else
|
||||
extern uint8_t __heap_base__[];
|
||||
extern uint8_t __heap_end__[];
|
||||
|
||||
#define HEAP_START __heap_base__
|
||||
#define HEAP_END (__heap_end__)
|
||||
#define HEAP_ALIGNMENT 16
|
||||
#define HEAP_SIZE ((uintptr_t)__heap_end__ - (uintptr_t)__heap_base__)
|
||||
#endif
|
||||
|
||||
#define HEAP_ALIGN(n) (((n) + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT - 1))
|
||||
|
||||
static uint8_t *heap_p;
|
||||
static chopstx_mutex_t malloc_mtx;
|
||||
|
||||
struct mem_head {
|
||||
uintptr_t size;
|
||||
/**/
|
||||
struct mem_head *next, *prev; /* free list chain */
|
||||
struct mem_head *neighbor; /* backlink to neighbor */
|
||||
};
|
||||
|
||||
#define MEM_HEAD_IS_CORRUPT(x) \
|
||||
((x)->size != HEAP_ALIGN((x)->size) || (x)->size > HEAP_SIZE)
|
||||
#define MEM_HEAD_CHECK(x) if (MEM_HEAD_IS_CORRUPT(x)) fatal (FATAL_HEAP)
|
||||
|
||||
static struct mem_head *free_list;
|
||||
|
||||
static void
|
||||
gnuk_malloc_init (void)
|
||||
{
|
||||
chopstx_mutex_init (&malloc_mtx);
|
||||
heap_p = HEAP_START;
|
||||
free_list = NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
gnuk_sbrk (intptr_t size)
|
||||
{
|
||||
void *p = (void *)heap_p;
|
||||
|
||||
if ((HEAP_END - heap_p) < size)
|
||||
return NULL;
|
||||
|
||||
heap_p += size;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_from_free_list (struct mem_head *m)
|
||||
{
|
||||
if (m->prev)
|
||||
m->prev->next = m->next;
|
||||
else
|
||||
free_list = m->next;
|
||||
if (m->next)
|
||||
m->next->prev = m->prev;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
gnuk_malloc (size_t size)
|
||||
{
|
||||
struct mem_head *m;
|
||||
struct mem_head *m0;
|
||||
|
||||
size = HEAP_ALIGN (size + sizeof (uintptr_t));
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
DEBUG_INFO ("malloc: ");
|
||||
DEBUG_SHORT (size);
|
||||
m = free_list;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (m == NULL)
|
||||
{
|
||||
m = (struct mem_head *)gnuk_sbrk (size);
|
||||
if (m)
|
||||
m->size = size;
|
||||
break;
|
||||
}
|
||||
MEM_HEAD_CHECK (m);
|
||||
if (m->size == size)
|
||||
{
|
||||
remove_from_free_list (m);
|
||||
m0 = free_list;
|
||||
while (m0)
|
||||
if (m0->neighbor == m)
|
||||
m0->neighbor = NULL;
|
||||
else
|
||||
m0 = m0->next;
|
||||
break;
|
||||
}
|
||||
|
||||
m = m->next;
|
||||
}
|
||||
|
||||
chopstx_mutex_unlock (&malloc_mtx);
|
||||
if (m == NULL)
|
||||
{
|
||||
DEBUG_WORD (0);
|
||||
return m;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_WORD ((uintptr_t)m + sizeof (uintptr_t));
|
||||
return (void *)m + sizeof (uintptr_t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gnuk_free (void *p)
|
||||
{
|
||||
struct mem_head *m = (struct mem_head *)((void *)p - sizeof (uintptr_t));
|
||||
struct mem_head *m0;
|
||||
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
chopstx_mutex_lock (&malloc_mtx);
|
||||
m0 = free_list;
|
||||
DEBUG_INFO ("free: ");
|
||||
DEBUG_SHORT (m->size);
|
||||
DEBUG_WORD ((uintptr_t)p);
|
||||
|
||||
MEM_HEAD_CHECK (m);
|
||||
m->neighbor = NULL;
|
||||
while (m0)
|
||||
{
|
||||
MEM_HEAD_CHECK (m0);
|
||||
if ((void *)m + m->size == (void *)m0)
|
||||
m0->neighbor = m;
|
||||
else if ((void *)m0 + m0->size == (void *)m)
|
||||
m->neighbor = m0;
|
||||
|
||||
m0 = m0->next;
|
||||
}
|
||||
|
||||
if ((void *)m + m->size == heap_p)
|
||||
{
|
||||
struct mem_head *mn = m->neighbor;
|
||||
|
||||
heap_p -= m->size;
|
||||
while (mn)
|
||||
{
|
||||
MEM_HEAD_CHECK (mn);
|
||||
heap_p -= mn->size;
|
||||
remove_from_free_list (mn);
|
||||
mn = mn->neighbor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m->next = free_list;
|
||||
m->prev = NULL;
|
||||
if (free_list)
|
||||
free_list->prev = m;
|
||||
free_list = m;
|
||||
}
|
||||
|
||||
chopstx_mutex_unlock (&malloc_mtx);
|
||||
}
|
||||
|
167
src/openpgp-do.c
167
src/openpgp-do.c
@ -2,7 +2,7 @@
|
||||
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
|
||||
* 2020, 2021
|
||||
* 2020, 2021, 2022
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@ -146,7 +146,6 @@ static const uint8_t feature_mngmnt[] __attribute__ ((aligned (1))) = {
|
||||
#endif
|
||||
|
||||
/* Algorithm Attributes */
|
||||
#define OPENPGP_ALGO_RSA 0x01
|
||||
#define OPENPGP_ALGO_ECDH 0x12
|
||||
#define OPENPGP_ALGO_ECDSA 0x13
|
||||
#define OPENPGP_ALGO_EDDSA 0x16 /* It catches 22, finally. */
|
||||
@ -165,22 +164,6 @@ static const uint8_t algorithm_attr_x448[] __attribute__ ((aligned (1))) = {
|
||||
0x2b, 0x65, 0x6f
|
||||
};
|
||||
|
||||
static const uint8_t algorithm_attr_rsa2k[] __attribute__ ((aligned (1))) = {
|
||||
6,
|
||||
OPENPGP_ALGO_RSA,
|
||||
0x08, 0x00, /* Length modulus (in bit): 2048 */
|
||||
0x00, 0x20, /* Length exponent (in bit): 32 */
|
||||
0x00 /* 0: Acceptable format is: P and Q */
|
||||
};
|
||||
|
||||
static const uint8_t algorithm_attr_rsa4k[] __attribute__ ((aligned (1))) = {
|
||||
6,
|
||||
OPENPGP_ALGO_RSA,
|
||||
0x10, 0x00, /* Length modulus (in bit): 4096 */
|
||||
0x00, 0x20, /* Length exponent (in bit): 32 */
|
||||
0x00 /* 0: Acceptable format is: P and Q */
|
||||
};
|
||||
|
||||
static const uint8_t algorithm_attr_p256k1[] __attribute__ ((aligned (1))) = {
|
||||
6,
|
||||
OPENPGP_ALGO_ECDSA,
|
||||
@ -264,7 +247,12 @@ gpg_get_algo_attr (enum kind_of_key kk)
|
||||
const uint8_t *algo_attr_p = *get_algo_attr_pointer (kk);
|
||||
|
||||
if (algo_attr_p == NULL)
|
||||
return ALGO_RSA2K;
|
||||
{
|
||||
if (kk == GPG_KEY_FOR_DECRYPTION)
|
||||
return ALGO_CURVE25519;
|
||||
else
|
||||
return ALGO_ED25519;
|
||||
}
|
||||
|
||||
return algo_attr_p[1];
|
||||
}
|
||||
@ -297,12 +285,15 @@ get_algo_attr_data_object (enum kind_of_key kk)
|
||||
const uint8_t *algo_attr_p = *get_algo_attr_pointer (kk);
|
||||
|
||||
if (algo_attr_p == NULL)
|
||||
return algorithm_attr_rsa2k;
|
||||
{
|
||||
if (kk == GPG_KEY_FOR_DECRYPTION)
|
||||
return algorithm_attr_cv25519;
|
||||
else
|
||||
return algorithm_attr_ed25519;
|
||||
}
|
||||
|
||||
switch (algo_attr_p[1])
|
||||
{
|
||||
case ALGO_RSA4K:
|
||||
return algorithm_attr_rsa4k;
|
||||
case ALGO_SECP256K1:
|
||||
return algorithm_attr_p256k1;
|
||||
case ALGO_CURVE25519:
|
||||
@ -314,7 +305,7 @@ get_algo_attr_data_object (enum kind_of_key kk)
|
||||
case ALGO_X448:
|
||||
return algorithm_attr_x448;
|
||||
default:
|
||||
return algorithm_attr_rsa2k;
|
||||
return algorithm_attr_ed25519;
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,16 +314,16 @@ gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s)
|
||||
{
|
||||
const uint8_t *algo_attr_p = *get_algo_attr_pointer (kk);
|
||||
|
||||
if (algo_attr_p == NULL) /* RSA-2048 */
|
||||
goto rsa2k;
|
||||
if (algo_attr_p == NULL)
|
||||
{
|
||||
if (kk == GPG_KEY_FOR_DECRYPTION)
|
||||
goto cv25519;
|
||||
else
|
||||
goto ed25519;
|
||||
}
|
||||
|
||||
switch (algo_attr_p[1])
|
||||
{
|
||||
case ALGO_RSA4K:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 1024;
|
||||
else
|
||||
return 512;
|
||||
case ALGO_SECP256K1:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 128;
|
||||
@ -340,18 +331,12 @@ gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s)
|
||||
return 64;
|
||||
else
|
||||
return 32;
|
||||
cv25519:
|
||||
case ALGO_CURVE25519:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 64;
|
||||
else
|
||||
return 32;
|
||||
case ALGO_ED25519:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 128;
|
||||
else if (s == GPG_KEY_PUBLIC)
|
||||
return 32;
|
||||
else
|
||||
return 64;
|
||||
case ALGO_ED448:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 256;
|
||||
@ -364,12 +349,15 @@ gpg_get_algo_attr_key_size (enum kind_of_key kk, enum size_of_key s)
|
||||
return 112;
|
||||
else
|
||||
return 56;
|
||||
ed25519:
|
||||
default:
|
||||
rsa2k:
|
||||
case ALGO_ED25519:
|
||||
if (s == GPG_KEY_STORAGE)
|
||||
return 512;
|
||||
return 128;
|
||||
else if (s == GPG_KEY_PUBLIC)
|
||||
return 32;
|
||||
else
|
||||
return 256;
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,8 +721,6 @@ do_alg_info (uint16_t tag, int with_tag)
|
||||
{
|
||||
uint16_t tag_algo = GPG_DO_ALG_SIG + i;
|
||||
|
||||
copy_do_1 (tag_algo, algorithm_attr_rsa2k, 1);
|
||||
copy_do_1 (tag_algo, algorithm_attr_rsa4k, 1);
|
||||
copy_do_1 (tag_algo, algorithm_attr_p256k1, 1);
|
||||
if (i == 0 || i == 2)
|
||||
{
|
||||
@ -823,11 +809,7 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
||||
}
|
||||
if (len == 6)
|
||||
{
|
||||
if (memcmp (data, algorithm_attr_rsa2k+1, 6) == 0)
|
||||
algo = ALGO_RSA2K;
|
||||
else if (memcmp (data, algorithm_attr_rsa4k+1, 6) == 0)
|
||||
algo = ALGO_RSA4K;
|
||||
else if ((tag != GPG_DO_ALG_DEC
|
||||
if ((tag != GPG_DO_ALG_DEC
|
||||
&& memcmp (data, algorithm_attr_p256k1+1, 6) == 0)
|
||||
|| (tag == GPG_DO_ALG_DEC && data[0]==OPENPGP_ALGO_ECDH
|
||||
&& memcmp (data+1, algorithm_attr_p256k1+2, 5) == 0))
|
||||
@ -840,7 +822,7 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
||||
|
||||
if (algo < 0)
|
||||
return 0; /* Error. */
|
||||
else if (algo == ALGO_RSA2K && *algo_attr_pp != NULL)
|
||||
else if (algo == ALGO_ED25519 && *algo_attr_pp != NULL)
|
||||
{
|
||||
gpg_reset_algo_attr (kk);
|
||||
/* Read it again, since GC may occur. */
|
||||
@ -849,7 +831,7 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
||||
if (*algo_attr_pp != NULL)
|
||||
return 0;
|
||||
}
|
||||
else if ((algo != ALGO_RSA2K && *algo_attr_pp == NULL) ||
|
||||
else if ((algo != ALGO_ED25519 && *algo_attr_pp == NULL) ||
|
||||
(*algo_attr_pp != NULL && (*algo_attr_pp)[1] != algo))
|
||||
{
|
||||
gpg_reset_algo_attr (kk);
|
||||
@ -1239,7 +1221,7 @@ struct key_data_internal {
|
||||
uint32_t data[(MAX_PRVKEY_LEN+DATA_ENCRYPTION_KEY_SIZE) / sizeof (uint32_t)];
|
||||
/*
|
||||
* Secret key data.
|
||||
* RSA: p and q, ECDSA/ECDH: d, EdDSA: a+seed
|
||||
* ECDSA/ECDH: d, EdDSA: a+seed
|
||||
*/
|
||||
/* Checksum */
|
||||
};
|
||||
@ -1444,14 +1426,8 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
|
||||
if (prvkey_len != 56)
|
||||
return -1;
|
||||
}
|
||||
else /* RSA */
|
||||
{
|
||||
int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
|
||||
|
||||
pubkey_len = prvkey_len;
|
||||
if (prvkey_len + pubkey_len != key_size)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
DEBUG_INFO ("Getting keystore address...\r\n");
|
||||
key_addr = flash_key_alloc (kk);
|
||||
@ -1620,26 +1596,6 @@ kkb_to_kk (uint8_t kk_byte)
|
||||
}
|
||||
|
||||
/*
|
||||
* RSA-2048:
|
||||
* 4d, xx, xx, xx: Extended Header List
|
||||
* b6 00 (SIG) / b8 00 (DEC) / a4 00 (AUT)
|
||||
* 7f48, xx: cardholder private key template
|
||||
* 91 L<E>: 91=tag of E, L<E>: length of E
|
||||
* 92 Lh<P> Ll<P>: 92=tag of P, L<P>: length of P
|
||||
* 93 Lh<Q> Ll<Q>: 93=tag of Q, L<Q>: length of Q
|
||||
* 5f48, xx xx xx: cardholder private key
|
||||
* <E: 4-byte>, <P: 128-byte>, <Q: 128-byte>
|
||||
*
|
||||
* RSA-4096:
|
||||
* 4d, 82, 02, 18: Extended Header List
|
||||
* b6 00 (SIG) / b8 00 (DEC) / a4 00 (AUT)
|
||||
* 7f48, 0a: cardholder private key template
|
||||
* 91 L<E>: 91=tag of E, L<E>: length of E
|
||||
* 92 82 Lh<P> Ll<P>: 92=tag of P, L<P>: length of P
|
||||
* 93 82 Lh<Q> Ll<Q>: 93=tag of Q, L<Q>: length of Q
|
||||
* 5f48, 82 02 04: cardholder private key
|
||||
* <E: 4-byte>, <P: 256-byte>, <Q: 256-byte>
|
||||
*
|
||||
* ECDSA / ECDH / EdDSA:
|
||||
* 4d, 2a: Extended Header List
|
||||
* b6 00 (SIG) / b8 00 (DEC) / a4 00 (AUT)
|
||||
@ -1696,30 +1652,13 @@ proc_key_import (const uint8_t *data, int len)
|
||||
|
||||
if ((len <= 12 && (attr == ALGO_SECP256K1 || attr == ALGO_CURVE25519
|
||||
|| attr == ALGO_ED25519 || attr == ALGO_ED448
|
||||
|| attr == ALGO_X448))
|
||||
|| (len <= 22 && attr == ALGO_RSA2K) || (len <= 24 && attr == ALGO_RSA4K))
|
||||
|| attr == ALGO_X448)))
|
||||
{ /* Deletion of the key */
|
||||
gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (attr == ALGO_RSA2K)
|
||||
{
|
||||
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
|
||||
r = modulus_calc (&data[26], len - 26, pubkey);
|
||||
if (r >= 0)
|
||||
r = gpg_do_write_prvkey (kk, &data[26], len - 26, keystring_admin,
|
||||
pubkey);
|
||||
}
|
||||
else if (attr == ALGO_RSA4K)
|
||||
{
|
||||
/* It should starts with 00 01 00 01 (E), skiping E (4-byte) */
|
||||
r = modulus_calc (&data[28], len - 28, pubkey);
|
||||
if (r >= 0)
|
||||
r = gpg_do_write_prvkey (kk, &data[28], len - 28, keystring_admin,
|
||||
pubkey);
|
||||
}
|
||||
else if (attr == ALGO_SECP256K1)
|
||||
if (attr == ALGO_SECP256K1)
|
||||
{
|
||||
r = ecc_compute_public_p256k1 (&data[12], pubkey);
|
||||
if (r >= 0)
|
||||
@ -2355,7 +2294,6 @@ gpg_do_public_key (uint8_t kk_byte)
|
||||
{
|
||||
enum kind_of_key kk = kkb_to_kk (kk_byte);
|
||||
int attr = gpg_get_algo_attr (kk);
|
||||
int pubkey_len = gpg_get_algo_attr_key_size (kk, GPG_KEY_PUBLIC);
|
||||
const uint8_t *pubkey = kd[kk].pubkey;
|
||||
|
||||
DEBUG_INFO ("Public key\r\n");
|
||||
@ -2423,24 +2361,9 @@ gpg_do_public_key (uint8_t kk_byte)
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* RSA */
|
||||
/* LEN = 9+256or512 */
|
||||
*res_p++ = 0x82; *res_p++ = pubkey_len > 256? 0x02: 0x01; *res_p++ = 0x09;
|
||||
|
||||
{
|
||||
/*TAG*/ /* LEN = 256or512 */
|
||||
*res_p++ = 0x81;
|
||||
*res_p++ = 0x82; *res_p++ = pubkey_len > 256? 0x02: 0x01;*res_p++ = 0x00;
|
||||
/* PUBKEY_LEN-byte binary (big endian) */
|
||||
memcpy (res_p, pubkey, pubkey_len);
|
||||
res_p += pubkey_len;
|
||||
}
|
||||
{
|
||||
/*TAG*/ /* LEN= 3 */
|
||||
*res_p++ = 0x82; *res_p++ = 3;
|
||||
/* 3-byte E=0x10001 (big endian) */
|
||||
*res_p++ = 0x01; *res_p++ = 0x00; *res_p++ = 0x01;
|
||||
}
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
@ -2501,17 +2424,7 @@ gpg_do_keygen (uint8_t *buf)
|
||||
DEBUG_INFO ("Keygen\r\n");
|
||||
DEBUG_BYTE (kk_byte);
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
if (rsa_genkey (prvkey_len, pubkey, p_q) < 0)
|
||||
{
|
||||
GPG_MEMORY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
|
||||
prv = p_q;
|
||||
}
|
||||
else if (attr == ALGO_SECP256K1)
|
||||
if (attr == ALGO_SECP256K1)
|
||||
{
|
||||
const uint8_t *p;
|
||||
int i;
|
||||
|
157
src/openpgp.c
157
src/openpgp.c
@ -2,7 +2,7 @@
|
||||
* openpgp.c -- OpenPGP card protocol support
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||
* 2019, 2021
|
||||
* 2019, 2021, 2022
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@ -64,8 +64,6 @@ static struct eventflag *openpgp_comm;
|
||||
#define INS_PUT_DATA_ODD 0xdb /* For key import */
|
||||
#define INS_TERMINATE_DF 0xe6
|
||||
|
||||
static const uint8_t *challenge; /* Random bytes */
|
||||
|
||||
static const uint8_t
|
||||
select_file_TOP_result[] __attribute__ ((aligned (1))) = {
|
||||
0x00, 0x00, /* unused */
|
||||
@ -747,18 +745,6 @@ cmd_pgp_gakp (struct eventflag *ccid_comm)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
const uint8_t *
|
||||
gpg_get_firmware_update_key (uint8_t keyno)
|
||||
{
|
||||
extern uint8_t _updatekey_store[1024];
|
||||
const uint8_t *p;
|
||||
|
||||
p = _updatekey_store + keyno * FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CERTDO_SUPPORT
|
||||
#define FILEID_CH_CERTIFICATE_IS_VALID 1
|
||||
#else
|
||||
@ -799,22 +785,6 @@ cmd_read_binary (struct eventflag *ccid_comm)
|
||||
}
|
||||
return;
|
||||
}
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
else if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
|
||||
{
|
||||
if (offset != 0)
|
||||
GPG_MEMORY_FAILURE ();
|
||||
else
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
|
||||
res_APDU_size = FIRMWARE_UPDATE_KEY_CONTENT_LEN;
|
||||
memcpy (res_APDU, p, FIRMWARE_UPDATE_KEY_CONTENT_LEN);
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(CERTDO_SUPPORT)
|
||||
else if (file_id == FILEID_CH_CERTIFICATE)
|
||||
{
|
||||
@ -939,7 +909,6 @@ cmd_pso (struct eventflag *ccid_comm)
|
||||
int len = apdu.cmd_apdu_data_len;
|
||||
int r = -1;
|
||||
int attr;
|
||||
int pubkey_len;
|
||||
unsigned int result_len = 0;
|
||||
int cs;
|
||||
|
||||
@ -951,9 +920,6 @@ cmd_pso (struct eventflag *ccid_comm)
|
||||
if (P1 (apdu) == 0x9e && P2 (apdu) == 0x9a)
|
||||
{
|
||||
attr = gpg_get_algo_attr (GPG_KEY_FOR_SIGNING);
|
||||
pubkey_len = gpg_get_algo_attr_key_size (GPG_KEY_FOR_SIGNING,
|
||||
GPG_KEY_PUBLIC);
|
||||
|
||||
if (!ac_check_status (AC_PSO_CDS_AUTHORIZED))
|
||||
{
|
||||
DEBUG_INFO ("security error.");
|
||||
@ -966,28 +932,7 @@ cmd_pso (struct eventflag *ccid_comm)
|
||||
eventflag_signal (ccid_comm, EV_EXEC_ACK_REQUIRED);
|
||||
#endif
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
/* Check size of digestInfo */
|
||||
if (len != 34 /* MD5 */
|
||||
&& len != 35 /* SHA1 / RIPEMD-160 */
|
||||
&& len != 47 /* SHA224 */
|
||||
&& len != 51 /* SHA256 */
|
||||
&& len != 67 /* SHA384 */
|
||||
&& len != 83) /* SHA512 */
|
||||
{
|
||||
DEBUG_INFO (" wrong length");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_BINARY (kd[GPG_KEY_FOR_SIGNING].data, pubkey_len);
|
||||
|
||||
result_len = pubkey_len;
|
||||
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
|
||||
&kd[GPG_KEY_FOR_SIGNING], pubkey_len);
|
||||
}
|
||||
else if (attr == ALGO_SECP256K1)
|
||||
if (attr == ALGO_SECP256K1)
|
||||
{
|
||||
/* ECDSA with p256r1/p256k1 for signature */
|
||||
if (len != ECDSA_HASH_LEN)
|
||||
@ -1044,11 +989,6 @@ cmd_pso (struct eventflag *ccid_comm)
|
||||
else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
|
||||
{
|
||||
attr = gpg_get_algo_attr (GPG_KEY_FOR_DECRYPTION);
|
||||
pubkey_len = gpg_get_algo_attr_key_size (GPG_KEY_FOR_DECRYPTION,
|
||||
GPG_KEY_PUBLIC);
|
||||
|
||||
DEBUG_BINARY (kd[GPG_KEY_FOR_DECRYPTION].data, pubkey_len);
|
||||
|
||||
if (!ac_check_status (AC_OTHER_AUTHORIZED))
|
||||
{
|
||||
DEBUG_INFO ("security error.");
|
||||
@ -1063,19 +1003,7 @@ cmd_pso (struct eventflag *ccid_comm)
|
||||
(void)ccid_comm;
|
||||
#endif
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
/* Skip padding 0x00 */
|
||||
len--;
|
||||
if (len != pubkey_len)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
|
||||
&kd[GPG_KEY_FOR_DECRYPTION], &result_len);
|
||||
}
|
||||
else if (attr == ALGO_SECP256K1)
|
||||
if (attr == ALGO_SECP256K1)
|
||||
{
|
||||
int header = ECC_CIPHER_DO_HEADER_SIZE;
|
||||
|
||||
@ -1149,13 +1077,10 @@ cmd_pso (struct eventflag *ccid_comm)
|
||||
}
|
||||
|
||||
|
||||
#define MAX_RSA_DIGEST_INFO_LEN 102 /* 40% */
|
||||
static void
|
||||
cmd_internal_authenticate (struct eventflag *ccid_comm)
|
||||
{
|
||||
int attr = gpg_get_algo_attr (GPG_KEY_FOR_AUTHENTICATION);
|
||||
int pubkey_len = gpg_get_algo_attr_key_size (GPG_KEY_FOR_AUTHENTICATION,
|
||||
GPG_KEY_PUBLIC);
|
||||
int len = apdu.cmd_apdu_data_len;
|
||||
int r = -1;
|
||||
unsigned int result_len = 0;
|
||||
@ -1188,20 +1113,7 @@ cmd_internal_authenticate (struct eventflag *ccid_comm)
|
||||
(void)ccid_comm;
|
||||
#endif
|
||||
|
||||
if (attr == ALGO_RSA2K || attr == ALGO_RSA4K)
|
||||
{
|
||||
if (len > MAX_RSA_DIGEST_INFO_LEN)
|
||||
{
|
||||
DEBUG_INFO ("input is too long.");
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
result_len = pubkey_len;
|
||||
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
|
||||
&kd[GPG_KEY_FOR_AUTHENTICATION], pubkey_len);
|
||||
}
|
||||
else if (attr == ALGO_SECP256K1)
|
||||
if (attr == ALGO_SECP256K1)
|
||||
{
|
||||
if (len != ECDSA_HASH_LEN)
|
||||
{
|
||||
@ -1324,28 +1236,6 @@ modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FLASH_UPGRADE_SUPPORT
|
||||
if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3
|
||||
&& len == 0 && offset == 0)
|
||||
{
|
||||
int i;
|
||||
const uint8_t *p;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
p = gpg_get_firmware_update_key (i);
|
||||
if (p[0] != 0x00 || p[1] != 0x00) /* still valid */
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 4) /* all update keys are removed */
|
||||
{
|
||||
p = gpg_get_firmware_update_key (0);
|
||||
flash_erase_page ((uintptr_t)p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
|
||||
@ -1380,36 +1270,10 @@ cmd_write_binary (struct eventflag *ccid_comm)
|
||||
static void
|
||||
cmd_external_authenticate (struct eventflag *ccid_comm)
|
||||
{
|
||||
const uint8_t *pubkey;
|
||||
const uint8_t *signature = apdu.cmd_apdu_data;
|
||||
int len = apdu.cmd_apdu_data_len;
|
||||
uint8_t keyno = P2 (apdu);
|
||||
int r;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n");
|
||||
|
||||
if (keyno >= 4)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
pubkey = gpg_get_firmware_update_key (keyno);
|
||||
if (len != 256
|
||||
|| (pubkey[0] == 0xff && pubkey[1] == 0xff) /* not registered */
|
||||
|| (pubkey[0] == 0x00 && pubkey[1] == 0x00) /* removed */)
|
||||
{
|
||||
GPG_CONDITION_NOT_SATISFIED ();
|
||||
return;
|
||||
}
|
||||
|
||||
r = rsa_verify (pubkey, FIRMWARE_UPDATE_KEY_CONTENT_LEN,
|
||||
challenge, signature);
|
||||
random_bytes_free (challenge);
|
||||
challenge = NULL;
|
||||
|
||||
if (r < 0)
|
||||
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
|
||||
{
|
||||
GPG_SECURITY_FAILURE ();
|
||||
return;
|
||||
@ -1425,6 +1289,7 @@ static void
|
||||
cmd_get_challenge (struct eventflag *ccid_comm)
|
||||
{
|
||||
int len = apdu.expected_res_size;
|
||||
const uint8_t *challenge;
|
||||
|
||||
(void)ccid_comm;
|
||||
DEBUG_INFO (" - GET CHALLENGE\r\n");
|
||||
@ -1438,9 +1303,6 @@ cmd_get_challenge (struct eventflag *ccid_comm)
|
||||
/* Le is not specified. Return full-sized challenge by GET_RESPONSE. */
|
||||
len = CHALLENGE_LEN;
|
||||
|
||||
if (challenge)
|
||||
random_bytes_free (challenge);
|
||||
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
if (gpg_do_get_uif (GPG_KEY_FOR_SIGNING)
|
||||
|| gpg_do_get_uif (GPG_KEY_FOR_DECRYPTION)
|
||||
@ -1450,6 +1312,7 @@ cmd_get_challenge (struct eventflag *ccid_comm)
|
||||
|
||||
challenge = random_bytes_get ();
|
||||
memcpy (res_APDU, challenge, len);
|
||||
random_bytes_free (challenge);
|
||||
res_APDU_size = len;
|
||||
GPG_SUCCESS ();
|
||||
DEBUG_INFO ("GET CHALLENGE done.\r\n");
|
||||
@ -1488,13 +1351,13 @@ cmd_terminate_df (struct eventflag *ccid_comm)
|
||||
|
||||
if (p1 != 0 || p2 != 0)
|
||||
{
|
||||
GPG_BAD_P1_P2();
|
||||
GPG_BAD_P1_P2 ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (apdu.cmd_apdu_data_len != 0)
|
||||
{
|
||||
GPG_WRONG_LENGTH();
|
||||
GPG_WRONG_LENGTH ();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1505,7 +1368,7 @@ cmd_terminate_df (struct eventflag *ccid_comm)
|
||||
|| (ks_pw3 == NULL && gpg_pw_locked (PW_ERR_PW1))))
|
||||
{
|
||||
/* Only allow the case admin authorized, or, admin pass is locked. */
|
||||
GPG_SECURITY_FAILURE();
|
||||
GPG_SECURITY_FAILURE ();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
9cf7192b51a574d1ad3ccb08ba09b87f228573893eee355529ff243e90fd4b86f79a82097cc7922c0485bed1616b1656a9b0b19ef78ea8ec34c384019adc5d5bf4db2d2a0a2d9cf14277bdcb7056f48b81214e3f7f7742231e29673966f9b1106862112cc798dba8d4a138bb5abfc6d4c12d53a5d39b2f783da916da20852ee139bbafda61d429caf2a4f30847ce7e7ae32ab4061e27dd9e4d00d60910249db8d8559dd85f7ca59659ef400c8f6318700f4e97f0c6f4165de80641490433c88da8682befe68eb311f54af2b07d97ac74edb5399cf054764211694fbb8d1d333f3269f235abe025067f811ff83a2224826219b309ea3e6c968f42b3e52f245dc9
|
||||
010001
|
||||
b5ab7b159220b18e363258f61ebde08bae83d6ce2dbfe4adc143628c527887acde9de09bf9b49f438019004d71855f30c2d69b6c29bb9882ab641b3387409fe9199464a7faa4b5230c56d9e17cd9ed074bc00180ebed62bae3af28e6ff2ac2654ad968834c5d5c88f8d9d3cc5e167b10453b049d4e454a5761fb0ac717185907
|
||||
dd2fffa9814296156a6926cd17b65564187e424dcadce9b032246ad7e46448bb0f9e0ff3c64f987424b1a40bc694e2e9ac4fb1930d163582d7acf20653a1c44b97846c1c5fd8a7b19bb225fb39c30e25410483deaf8c2538d222b748c4d8103b11cec04f666a5c0dbcbf5d5f625f158f65746c3fafe6418145f7cffa5fadeeaf
|
@ -1,4 +0,0 @@
|
||||
d392714c29738aac6372f2c8654a08c25a1299fed7004bd512cd2452b503ebad6301130816ac525ba528dc155be6347a5c70407fb4fbdaed751dfc0a7cd5e3910272ff236c4ed1ce5de6620b191a172e5b247347b8cab73a43d79221708755c959a2f83f486439da30917384554331532aabc8326db48866f8c91198834a86ab94679f6175db737bdf399e3f0b737dcb1f4208279d3e1cc694e78686785e4f363a377dec912b7c2f757b1422d866fb9fa85c96b83adfd6a223989a9a02988bdee81ad17eff6385e7b38cec8611fdf367ba4ac8e90d5f48ac7715c5f47aea06a4a37cdaa3029ce59d29bc66853bf6758ef4a7da5a5953f5e557a5a22f67c368c3
|
||||
010001
|
||||
dae085952c5beee38f25f09bc37a4ca2434c31f78055469d0d5f0bf3337e3a70ba6c91734f195b742e211a5fe283befdf66820008e6ef2c8ca54a91922838fce07d9e33a331ce20dac36803e777d5ee2195ed28d6a4045e28623a6a60b0661e45f7c4f84ae2b1dfad0cf1ec30605158323382a819e730c09a33fad704dd67501
|
||||
f774be43ea198aa2f089274e4fffd7d0092ee7b35a1d2f854cdb166f698caab72fdeb099e690e78438b2e043e452d4d2f19d7f44ba6b286642f0ce5204966ff98ecd9e3b448877324631365dc860797429b9414a21a7e166d504cace156588b9a145657eeb1afb43b8ff65d8d6d93cea2ba4ef8aab047885c4de64ffef0b49c3
|
@ -1,4 +0,0 @@
|
||||
c6c877dfd3b441f8fb1b8dc504093a51c2efe4883fe0a6379205acc6e673709905e4d767ddf46143c535cc6d7f10b616f520d8346320ef69ff4a2c4f4a148edc65f7ad24ed7d4fe23bb862a0ae71f4f7904abac0397abf3213df91326b1a25554b3b18cf54584d8bf220169fc92b2aa511e8313983e72b4c9110b3a1aea087aebef95873865608e8faea9ef10e7f7f3a66ca8def2d499c3149c127491e0e4339fd6abe10bfc6c13e43d522004f1485767328eabe35d6ffa8df4c15f0fbcd4eb1c07cc6d85e275139ac69e2962273ae987236926dd6c1144fce3e7ae567fa58ea60620dfafc52f95299fea601739fce27ee71eea978d0074f21e7086f60ba8331
|
||||
010001
|
||||
cc365b5702714bf203e8c49b0b8afa8dad586e929cf5edca38ad07fa45efd5c2d89022d29f40283a57e50ca24c5f28c8e911a74faaf796f112e7e48195956f9a4df7668a5342523b27179cec958f363211ee11d0ec0e0e1b92ca007a61e8c9ac14e00229b9a7624850199e6667afa1a44db8f3c5de0a8eef0e6de050ac0ac633
|
||||
f931a3c12f0e3a5276f712b7706590ba02e14a97ff9b8ce3152af0fc4d9cdc690ea9bc4c82cb16c7d23136cbdab58fbec69880a88bca85c4214df01045082cbe9f4192e3e39c79896533c37dad9eb9e73c2643b9c0a704a4f93d81573537963d6b6e5140a24c702d9f26e06a2095de906daa8824172a6b39f563b7153907050b
|
@ -468,14 +468,8 @@ class gnuk_token(object):
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
return self.cmd_get_response(sw[1])
|
||||
|
||||
def cmd_external_authenticate(self, keyno, signed):
|
||||
cmd_data = iso7816_compose(0x82, 0x00, keyno, signed[0:128], cls=0x10)
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
raise ValueError(sw)
|
||||
if not (sw[0] == 0x90 and sw[1] == 0x00):
|
||||
raise ValueError("%02x%02x" % (sw[0], sw[1]))
|
||||
cmd_data = iso7816_compose(0x82, 0x00, keyno, signed[128:])
|
||||
def cmd_external_authenticate(self):
|
||||
cmd_data = iso7816_compose(0x82, 0x00, 0x00, b"", cls=0x10)
|
||||
sw = self.icc_send_cmd(cmd_data)
|
||||
if len(sw) != 2:
|
||||
raise ValueError(sw)
|
||||
|
@ -3,7 +3,8 @@
|
||||
"""
|
||||
gnuk_upgrade.py - a tool to upgrade firmware of Gnuk Token
|
||||
|
||||
Copyright (C) 2012, 2015, 2021 Free Software Initiative of Japan
|
||||
Copyright (C) 2012, 2015, 2021, 2022
|
||||
Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -35,42 +36,7 @@ from gnuk_token import *
|
||||
|
||||
from subprocess import check_output
|
||||
|
||||
SHA256_OID_PREFIX="3031300d060960864801650304020105000420"
|
||||
|
||||
# When user specify KEYGRIP, use it. Or else, connect to SCD directly.
|
||||
def gpg_sign(keygrip, hash):
|
||||
if keygrip:
|
||||
result = check_output(["gpg-connect-agent",
|
||||
"SIGKEY %s" % keygrip,
|
||||
"SETHASH --hash=sha256 %s" % hash,
|
||||
"PKSIGN --hash=sha256", "/bye"])
|
||||
else:
|
||||
result = check_output(["gpg-connect-agent",
|
||||
"SCD SETDATA " + SHA256_OID_PREFIX + hash,
|
||||
"SCD PKAUTH OPENPGP.3",
|
||||
"/bye"])
|
||||
signed = ""
|
||||
while True:
|
||||
i = result.find('%')
|
||||
if i < 0:
|
||||
signed += result
|
||||
break
|
||||
hex_str = result[i+1:i+3]
|
||||
signed += result[0:i]
|
||||
signed += chr(int(hex_str,16))
|
||||
result = result[i+3:]
|
||||
|
||||
if keygrip:
|
||||
pos = signed.index("D (7:sig-val(3:rsa(1:s256:") + 26
|
||||
signed = signed[pos:-7]
|
||||
else:
|
||||
pos = signed.index("D ") + 2
|
||||
signed = signed[pos:-4] # \nOK\n
|
||||
if len(signed) != 256:
|
||||
raise ValueError(binascii.hexlify(signed))
|
||||
return signed
|
||||
|
||||
def main(keyno, keygrip, data_regnual, data_upgrade):
|
||||
def main(data_regnual, data_upgrade):
|
||||
l = len(data_regnual)
|
||||
if (l & 0x03) != 0:
|
||||
data_regnual = data_regnual.ljust(l + 4 - (l & 0x03), b'\x00')
|
||||
@ -91,9 +57,7 @@ def main(keyno, keygrip, data_regnual, data_upgrade):
|
||||
elif icc.icc_get_status() == 1:
|
||||
icc.icc_power_on()
|
||||
icc.cmd_select_openpgp()
|
||||
challenge = icc.cmd_get_challenge().tobytes()
|
||||
signed = gpg_sign(keygrip, binascii.hexlify(challenge))
|
||||
icc.cmd_external_authenticate(keyno, signed)
|
||||
icc.cmd_external_authenticate()
|
||||
icc.stop_gnuk()
|
||||
mem_info = icc.mem_info()
|
||||
print("%08x:%08x" % mem_info)
|
||||
@ -131,12 +95,6 @@ def main(keyno, keygrip, data_regnual, data_upgrade):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
keyno = 0
|
||||
keygrip = None
|
||||
if sys.argv[1] == '-k':
|
||||
sys.argv.pop(1)
|
||||
keygrip = sys.argv[1]
|
||||
sys.argv.pop(1)
|
||||
filename_regnual = sys.argv[1]
|
||||
filename_upgrade = sys.argv[2]
|
||||
f = open(filename_regnual, "rb")
|
||||
@ -147,4 +105,4 @@ if __name__ == '__main__':
|
||||
data_upgrade = f.read()
|
||||
f.close()
|
||||
print("%s: %d" % (filename_upgrade, len(data_upgrade)))
|
||||
main(keyno, keygrip, data_regnual, data_upgrade[4096:])
|
||||
main(data_regnual, data_upgrade[4096:])
|
||||
|
@ -4,7 +4,7 @@
|
||||
upgrade_by_passwd.py - a tool to install another firmware for Gnuk Token
|
||||
which is just shipped from factory
|
||||
|
||||
Copyright (C) 2012, 2013, 2015, 2018, 2021
|
||||
Copyright (C) 2012, 2013, 2015, 2018, 2021, 2022
|
||||
Free Software Initiative of Japan
|
||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
@ -29,15 +29,12 @@ from gnuk_token import get_gnuk_device, gnuk_devices_by_vidpid, \
|
||||
from kdf_calc import kdf_calc
|
||||
|
||||
import sys, binascii, time, os
|
||||
import rsa
|
||||
from struct import pack
|
||||
|
||||
DEFAULT_PW3 = "12345678"
|
||||
BY_ADMIN = 3
|
||||
|
||||
KEYNO_FOR_AUTH=2
|
||||
|
||||
def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
|
||||
def main(wait_e, passwd, data_regnual, data_upgrade):
|
||||
l = len(data_regnual)
|
||||
if (l & 0x03) != 0:
|
||||
data_regnual = data_regnual.ljust(l + 4 - (l & 0x03), chr(0))
|
||||
@ -45,9 +42,6 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
|
||||
print("CRC32: %04x\n" % crc32code)
|
||||
data_regnual += pack('<I', crc32code)
|
||||
|
||||
rsa_key = rsa.read_key_from_file('rsa_example.key')
|
||||
rsa_raw_pubkey = rsa.get_raw_pubkey(rsa_key)
|
||||
|
||||
gnuk = get_gnuk_device()
|
||||
gnuk.cmd_select_openpgp()
|
||||
# Compute passwd data
|
||||
@ -67,14 +61,9 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
|
||||
passwd_data = kdf_calc(passwd, salt, iters)
|
||||
# And authenticate with the passwd data
|
||||
gnuk.cmd_verify(BY_ADMIN, passwd_data)
|
||||
gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
|
||||
|
||||
gnuk.cmd_select_openpgp()
|
||||
challenge = gnuk.cmd_get_challenge().tobytes()
|
||||
digestinfo = binascii.unhexlify(SHA256_OID_PREFIX) + challenge
|
||||
signed = rsa.compute_signature(rsa_key, digestinfo)
|
||||
signed_bytes = rsa.integer_to_bytes_256(signed)
|
||||
gnuk.cmd_external_authenticate(keyno, signed_bytes)
|
||||
gnuk.cmd_external_authenticate()
|
||||
gnuk.stop_gnuk()
|
||||
mem_info = gnuk.mem_info()
|
||||
print("%08x:%08x" % mem_info)
|
||||
@ -125,7 +114,6 @@ if __name__ == '__main__':
|
||||
print("Please change working directory to: %s" % os.path.dirname(os.path.abspath(__file__)))
|
||||
exit(1)
|
||||
|
||||
keyno = 0
|
||||
passwd = None
|
||||
wait_e = DEFAULT_WAIT_FOR_REENUMERATION
|
||||
skip_check = False
|
||||
@ -138,10 +126,6 @@ if __name__ == '__main__':
|
||||
sys.argv.pop(1)
|
||||
wait_e = int(sys.argv[1])
|
||||
sys.argv.pop(1)
|
||||
elif option == '-k': # K for Key number
|
||||
sys.argv.pop(1)
|
||||
keyno = int(sys.argv[1])
|
||||
sys.argv.pop(1)
|
||||
elif option == '-s': # S for skip the check of target
|
||||
sys.argv.pop(1)
|
||||
skip_check = True
|
||||
@ -184,4 +168,4 @@ if __name__ == '__main__':
|
||||
f.close()
|
||||
print("%s: %d" % (filename_upgrade, len(data_upgrade)))
|
||||
# First 4096-byte in data_upgrade is SYS, so, skip it.
|
||||
main(wait_e, keyno, passwd, data_regnual, data_upgrade[4096:])
|
||||
main(wait_e, passwd, data_regnual, data_upgrade[4096:])
|
||||
|
Loading…
Reference in New Issue
Block a user