sc-hsm-tool: add support for initializing biometry

This commit is contained in:
Frank Morgner 2018-12-04 00:31:43 +01:00
parent 3611b5c9f2
commit 1eda4c1795
4 changed files with 76 additions and 5 deletions

View File

@ -151,7 +151,25 @@
<para>Define number of PIN retries for user PIN during initialization. Default is 3.</para> <para>Define number of PIN retries for user PIN during initialization. Default is 3.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--bio-server1</option> <replaceable>value</replaceable>
</term>
<listitem>
<para>The hexadecimal AID of of the biometric server for template 1. Switches on the use of the user PIN as session PIN.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--bio-server2</option> <replaceable>value</replaceable>
</term>
<listitem>
<para>The hexadecimal AID of of the biometric server for template 2. Switches on the use of the user PIN as session PIN.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>--password</option> <replaceable>value</replaceable> <option>--password</option> <replaceable>value</replaceable>

View File

@ -1233,7 +1233,7 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa
int r; int r;
size_t tilen; size_t tilen;
sc_apdu_t apdu; sc_apdu_t apdu;
u8 ibuff[50+0xFF], *p; u8 ibuff[64+0xFF], *p;
LOG_FUNC_CALLED(card->ctx); LOG_FUNC_CALLED(card->ctx);
@ -1266,6 +1266,19 @@ static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *pa
*p++ = (u8)params->dkek_shares; *p++ = (u8)params->dkek_shares;
} }
if (params->bio1.len) {
*p++ = 0x95;
*p++ = params->bio1.len;
memcpy(p, params->bio1.value, params->bio1.len);
p += params->bio1.len;
}
if (params->bio2.len) {
*p++ = 0x96;
*p++ = params->bio2.len;
memcpy(p, params->bio2.value, params->bio2.len);
p += params->bio2.len;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x50, 0x00, 0x00); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x50, 0x00, 0x00);
apdu.cla = 0x80; apdu.cla = 0x80;
apdu.data = ibuff; apdu.data = ibuff;

View File

@ -1008,6 +1008,8 @@ typedef struct sc_cardctl_sc_hsm_init_param {
u8 *user_pin; /* Initial user PIN */ u8 *user_pin; /* Initial user PIN */
size_t user_pin_len; /* Length of user PIN */ size_t user_pin_len; /* Length of user PIN */
u8 user_pin_retry_counter; /* Retry counter default value */ u8 user_pin_retry_counter; /* Retry counter default value */
struct sc_aid bio1; /* AID of biometric server for template 1 */
struct sc_aid bio2; /* AID of biometric server for template 2 */
u8 options[2]; /* Initialization options */ u8 options[2]; /* Initialization options */
signed char dkek_shares; /* Number of DKEK shares, 0 for card generated, -1 for none */ signed char dkek_shares; /* Number of DKEK shares, 0 for card generated, -1 for none */
char *label; /* Token label to be set in EF.TokenInfo (2F03) */ char *label; /* Token label to be set in EF.TokenInfo (2F03) */

View File

@ -72,6 +72,8 @@ enum {
OPT_SO_PIN = 0x100, OPT_SO_PIN = 0x100,
OPT_PIN, OPT_PIN,
OPT_RETRY, OPT_RETRY,
OPT_BIO1,
OPT_BIO2,
OPT_PASSWORD, OPT_PASSWORD,
OPT_PASSWORD_SHARES_THRESHOLD, OPT_PASSWORD_SHARES_THRESHOLD,
OPT_PASSWORD_SHARES_TOTAL OPT_PASSWORD_SHARES_TOTAL
@ -90,6 +92,8 @@ static const struct option options[] = {
{ "so-pin", 1, NULL, OPT_SO_PIN }, { "so-pin", 1, NULL, OPT_SO_PIN },
{ "pin", 1, NULL, OPT_PIN }, { "pin", 1, NULL, OPT_PIN },
{ "pin-retry", 1, NULL, OPT_RETRY }, { "pin-retry", 1, NULL, OPT_RETRY },
{ "bio-server1", 1, NULL, OPT_BIO1 },
{ "bio-server2", 1, NULL, OPT_BIO2 },
{ "password", 1, NULL, OPT_PASSWORD }, { "password", 1, NULL, OPT_PASSWORD },
{ "pwd-shares-threshold", 1, NULL, OPT_PASSWORD_SHARES_THRESHOLD }, { "pwd-shares-threshold", 1, NULL, OPT_PASSWORD_SHARES_THRESHOLD },
{ "pwd-shares-total", 1, NULL, OPT_PASSWORD_SHARES_TOTAL }, { "pwd-shares-total", 1, NULL, OPT_PASSWORD_SHARES_TOTAL },
@ -115,6 +119,8 @@ static const char *option_help[] = {
"Define security officer PIN (SO-PIN)", "Define security officer PIN (SO-PIN)",
"Define user PIN", "Define user PIN",
"Define user PIN retry counter", "Define user PIN retry counter",
"AID of biometric server for template 1 (hex)",
"AID of biometric server for template 2 (hex)",
"Define password for DKEK share", "Define password for DKEK share",
"Define threshold for number of password shares required for reconstruction", "Define threshold for number of password shares required for reconstruction",
"Define number of password shares", "Define number of password shares",
@ -558,7 +564,7 @@ static void print_info(sc_card_t *card, sc_file_t *file)
static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, int retry_counter, int dkek_shares, const char *label) static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, int retry_counter, const char *bio1, const char *bio2, int dkek_shares, const char *label)
{ {
sc_cardctl_sc_hsm_init_param_t param; sc_cardctl_sc_hsm_init_param_t param;
size_t len; size_t len;
@ -624,8 +630,32 @@ static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin,
param.user_pin_retry_counter = (u8)retry_counter; param.user_pin_retry_counter = (u8)retry_counter;
if (bio1) {
param.bio1.len = sizeof(param.bio1.value);
r = sc_hex_to_bin(bio1, param.bio1.value, &param.bio1.len);
if (r < 0) {
fprintf(stderr, "Error decoding AID of biometric server for template 1 (%s)\n", sc_strerror(r));
return -1;
}
} else {
param.bio1.len = 0;
}
if (bio2) {
param.bio2.len = sizeof(param.bio2.value);
r = sc_hex_to_bin(bio2, param.bio2.value, &param.bio2.len);
if (r < 0) {
fprintf(stderr, "Error decoding AID of biometric server for template 2 (%s)\n", sc_strerror(r));
return -1;
}
} else {
param.bio2.len = 0;
}
param.options[0] = 0x00; param.options[0] = 0x00;
param.options[1] = 0x01; param.options[1] = 0x01; /* RESET RETRY COUNTER enabled */
if (param.bio1.len || param.bio2.len) {
param.options[1] |= 0x04; /* Session-PIN enabled with clear on reset */
}
param.dkek_shares = (char)dkek_shares; param.dkek_shares = (char)dkek_shares;
param.label = (char *)label; param.label = (char *)label;
@ -1666,6 +1696,8 @@ int main(int argc, char *argv[])
const char *opt_pin = NULL; const char *opt_pin = NULL;
const char *opt_filename = NULL; const char *opt_filename = NULL;
const char *opt_password = NULL; const char *opt_password = NULL;
const char *opt_bio1 = NULL;
const char *opt_bio2 = NULL;
int opt_retry_counter = 3; int opt_retry_counter = 3;
int opt_dkek_shares = -1; int opt_dkek_shares = -1;
int opt_key_reference = -1; int opt_key_reference = -1;
@ -1723,6 +1755,12 @@ int main(int argc, char *argv[])
case OPT_RETRY: case OPT_RETRY:
opt_retry_counter = atol(optarg); opt_retry_counter = atol(optarg);
break; break;
case OPT_BIO1:
opt_bio1 = optarg;
break;
case OPT_BIO2:
opt_bio2 = optarg;
break;
case OPT_PASSWORD_SHARES_THRESHOLD: case OPT_PASSWORD_SHARES_THRESHOLD:
opt_password_shares_threshold = atol(optarg); opt_password_shares_threshold = atol(optarg);
break; break;
@ -1789,7 +1827,7 @@ int main(int argc, char *argv[])
goto fail; goto fail;
} }
if (do_initialize && initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_dkek_shares, opt_label)) if (do_initialize && initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_bio1, opt_bio2, opt_dkek_shares, opt_label))
goto fail; goto fail;
if (do_create_dkek_share && create_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_threshold, opt_password_shares_total)) if (do_create_dkek_share && create_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_threshold, opt_password_shares_total))