Add support for persistentPinUvAuthToken.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -105,11 +105,7 @@ int regenerate() {
|
|||||||
mbedtls_ecdh_init(&hkey);
|
mbedtls_ecdh_init(&hkey);
|
||||||
hkey_init = true;
|
hkey_init = true;
|
||||||
mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1);
|
mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1);
|
||||||
int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp,
|
int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_gen, NULL);
|
||||||
&hkey.ctx.mbed_ecdh.d,
|
|
||||||
&hkey.ctx.mbed_ecdh.Q,
|
|
||||||
random_gen,
|
|
||||||
NULL);
|
|
||||||
mbedtls_mpi_lset(&hkey.ctx.mbed_ecdh.Qp.Z, 1);
|
mbedtls_mpi_lset(&hkey.ctx.mbed_ecdh.Qp.Z, 1);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -125,34 +121,15 @@ int kdf(uint8_t protocol, const mbedtls_mpi *z, uint8_t *sharedSecret) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (protocol == 1) {
|
if (protocol == 1) {
|
||||||
return mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
|
return mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), buf, sizeof(buf), sharedSecret);
|
||||||
buf,
|
|
||||||
sizeof(buf),
|
|
||||||
sharedSecret);
|
|
||||||
}
|
}
|
||||||
else if (protocol == 2) {
|
else if (protocol == 2) {
|
||||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||||
ret = mbedtls_hkdf(md_info,
|
ret = mbedtls_hkdf(md_info, NULL, 0, buf, sizeof(buf), (uint8_t *) "CTAP2 HMAC key", 14, sharedSecret, 32);
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
buf,
|
|
||||||
sizeof(buf),
|
|
||||||
(uint8_t *) "CTAP2 HMAC key",
|
|
||||||
14,
|
|
||||||
sharedSecret,
|
|
||||||
32);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return mbedtls_hkdf(md_info,
|
return mbedtls_hkdf(md_info, NULL, 0, buf, sizeof(buf), (uint8_t *) "CTAP2 AES key", 13, sharedSecret + 32, 32);
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
buf,
|
|
||||||
sizeof(buf),
|
|
||||||
(uint8_t *) "CTAP2 AES key",
|
|
||||||
13,
|
|
||||||
sharedSecret + 32,
|
|
||||||
32);
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -160,26 +137,38 @@ int kdf(uint8_t protocol, const mbedtls_mpi *z, uint8_t *sharedSecret) {
|
|||||||
int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret) {
|
int ecdh(uint8_t protocol, const mbedtls_ecp_point *Q, uint8_t *sharedSecret) {
|
||||||
mbedtls_mpi z;
|
mbedtls_mpi z;
|
||||||
mbedtls_mpi_init(&z);
|
mbedtls_mpi_init(&z);
|
||||||
int ret = mbedtls_ecdh_compute_shared(&hkey.ctx.mbed_ecdh.grp,
|
int ret = mbedtls_ecdh_compute_shared(&hkey.ctx.mbed_ecdh.grp, &z, Q, &hkey.ctx.mbed_ecdh.d, random_gen, NULL);
|
||||||
&z,
|
|
||||||
Q,
|
|
||||||
&hkey.ctx.mbed_ecdh.d,
|
|
||||||
random_gen,
|
|
||||||
NULL);
|
|
||||||
ret = kdf(protocol, &z, sharedSecret);
|
ret = kdf(protocol, &z, sharedSecret);
|
||||||
mbedtls_mpi_free(&z);
|
mbedtls_mpi_free(&z);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resetPinUvAuthToken() {
|
void resetAuthToken(bool persistent) {
|
||||||
|
uint16_t fid = EF_AUTHTOKEN;
|
||||||
|
if (persistent) {
|
||||||
|
fid = EF_PAUTHTOKEN;
|
||||||
|
}
|
||||||
|
file_t *ef = search_by_fid(fid, NULL, SPECIFY_EF);
|
||||||
uint8_t t[32];
|
uint8_t t[32];
|
||||||
random_gen(NULL, t, sizeof(t));
|
random_gen(NULL, t, sizeof(t));
|
||||||
file_put_data(ef_authtoken, t, sizeof(t));
|
file_put_data(ef, t, sizeof(t));
|
||||||
|
low_flash_available();
|
||||||
|
}
|
||||||
|
|
||||||
|
int resetPinUvAuthToken() {
|
||||||
|
resetAuthToken(false);
|
||||||
paut.permissions = 0;
|
paut.permissions = 0;
|
||||||
paut.data = file_get_data(ef_authtoken);
|
paut.data = file_get_data(ef_authtoken);
|
||||||
paut.len = file_get_size(ef_authtoken);
|
paut.len = file_get_size(ef_authtoken);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
low_flash_available();
|
int resetPersistentPinUvAuthToken() {
|
||||||
|
resetAuthToken(true);
|
||||||
|
file_t *ef_pauthtoken = search_by_fid(EF_PAUTHTOKEN, NULL, SPECIFY_EF);
|
||||||
|
ppaut.permissions = 0;
|
||||||
|
ppaut.data = file_get_data(ef_pauthtoken);
|
||||||
|
ppaut.len = file_get_size(ef_pauthtoken);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,6 +567,7 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
|
|||||||
}
|
}
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
resetPinUvAuthToken();
|
resetPinUvAuthToken();
|
||||||
|
resetPersistentPinUvAuthToken();
|
||||||
goto err; // No return
|
goto err; // No return
|
||||||
}
|
}
|
||||||
else if (subcommand == 0x9 || subcommand == 0x5) { //getPinUvAuthTokenUsingPinWithPermissions
|
else if (subcommand == 0x9 || subcommand == 0x5) { //getPinUvAuthTokenUsingPinWithPermissions
|
||||||
@@ -598,7 +588,9 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
|
|||||||
if ((permissions & CTAP_PERMISSION_BE)) { // Not supported yet
|
if ((permissions & CTAP_PERMISSION_BE)) { // Not supported yet
|
||||||
CBOR_ERROR(CTAP2_ERR_UNAUTHORIZED_PERMISSION);
|
CBOR_ERROR(CTAP2_ERR_UNAUTHORIZED_PERMISSION);
|
||||||
}
|
}
|
||||||
|
if ((permissions & CTAP_PERMISSION_PCMR) && permissions != CTAP_PERMISSION_PCMR) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_UNAUTHORIZED_PERMISSION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!file_has_data(ef_pin)) {
|
if (!file_has_data(ef_pin)) {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_NOT_SET);
|
CBOR_ERROR(CTAP2_ERR_PIN_NOT_SET);
|
||||||
@@ -664,21 +656,29 @@ int cbor_client_pin(const uint8_t *data, size_t len) {
|
|||||||
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) {
|
if (file_has_data(ef_minpin) && file_get_data(ef_minpin)[1] == 1) {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
|
CBOR_ERROR(CTAP2_ERR_PIN_INVALID);
|
||||||
}
|
}
|
||||||
resetPinUvAuthToken();
|
uint8_t pinUvAuthToken_enc[32 + IV_SIZE], *pdata = NULL;
|
||||||
beginUsingPinUvAuthToken(false);
|
;
|
||||||
if (subcommand == 0x05) {
|
if (permissions & CTAP_PERMISSION_PCMR) {
|
||||||
permissions = CTAP_PERMISSION_MC | CTAP_PERMISSION_GA;
|
ppaut.permissions = CTAP_PERMISSION_PCMR;
|
||||||
}
|
pdata = ppaut.data;
|
||||||
paut.permissions = (uint8_t)permissions;
|
|
||||||
if (rpId.present == true) {
|
|
||||||
mbedtls_sha256((uint8_t *) rpId.data, rpId.len, paut.rp_id_hash, 0);
|
|
||||||
paut.has_rp_id = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
paut.has_rp_id = false;
|
resetPinUvAuthToken();
|
||||||
|
beginUsingPinUvAuthToken(false);
|
||||||
|
if (subcommand == 0x05) {
|
||||||
|
permissions = CTAP_PERMISSION_MC | CTAP_PERMISSION_GA;
|
||||||
|
}
|
||||||
|
paut.permissions = (uint8_t)permissions;
|
||||||
|
if (rpId.present == true) {
|
||||||
|
mbedtls_sha256((uint8_t *) rpId.data, rpId.len, paut.rp_id_hash, 0);
|
||||||
|
paut.has_rp_id = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
paut.has_rp_id = false;
|
||||||
|
}
|
||||||
|
pdata = paut.data;
|
||||||
}
|
}
|
||||||
uint8_t pinUvAuthToken_enc[32 + IV_SIZE];
|
encrypt((uint8_t)pinUvAuthProtocol, sharedSecret, pdata, 32, pinUvAuthToken_enc);
|
||||||
encrypt((uint8_t)pinUvAuthProtocol, sharedSecret, paut.data, 32, pinUvAuthToken_enc);
|
|
||||||
CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1));
|
CBOR_CHECK(cbor_encoder_create_map(&encoder, &mapEncoder, 1));
|
||||||
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x02));
|
CBOR_CHECK(cbor_encode_uint(&mapEncoder, 0x02));
|
||||||
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, pinUvAuthToken_enc, 32 + poff));
|
CBOR_CHECK(cbor_encode_byte_string(&mapEncoder, pinUvAuthToken_enc, 32 + poff));
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
extern uint8_t keydev_dec[32];
|
extern uint8_t keydev_dec[32];
|
||||||
extern bool has_keydev_dec;
|
extern bool has_keydev_dec;
|
||||||
|
extern void resetPersistentPinUvAuthToken();
|
||||||
|
extern void resetPinUvAuthToken();
|
||||||
|
|
||||||
int cbor_config(const uint8_t *data, size_t len) {
|
int cbor_config(const uint8_t *data, size_t len) {
|
||||||
CborParser parser;
|
CborParser parser;
|
||||||
@@ -207,6 +209,10 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
if (file_has_data(ef_pin) && file_get_data(ef_pin)[1] < newMinPinLength) {
|
if (file_has_data(ef_pin) && file_get_data(ef_pin)[1] < newMinPinLength) {
|
||||||
forceChangePin = ptrue;
|
forceChangePin = ptrue;
|
||||||
}
|
}
|
||||||
|
if (forceChangePin) {
|
||||||
|
resetPersistentPinUvAuthToken();
|
||||||
|
resetPinUvAuthToken();
|
||||||
|
}
|
||||||
uint8_t *dataf = (uint8_t *) calloc(1, 2 + minPinLengthRPIDs_len * 32);
|
uint8_t *dataf = (uint8_t *) calloc(1, 2 + minPinLengthRPIDs_len * 32);
|
||||||
dataf[0] = (uint8_t)newMinPinLength;
|
dataf[0] = (uint8_t)newMinPinLength;
|
||||||
dataf[1] = forceChangePin == ptrue ? 1 : 0;
|
dataf[1] = forceChangePin == ptrue ? 1 : 0;
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
|
|||||||
if (strcmp(_fd3, "transports") == 0) {
|
if (strcmp(_fd3, "transports") == 0) {
|
||||||
CBOR_PARSE_ARRAY_START(_f3, 4)
|
CBOR_PARSE_ARRAY_START(_f3, 4)
|
||||||
{
|
{
|
||||||
CBOR_FIELD_GET_TEXT(credentialId.transports[credentialId.
|
CBOR_FIELD_GET_TEXT(credentialId.transports[credentialId.transports_len], 4);
|
||||||
transports_len], 4);
|
|
||||||
credentialId.transports_len++;
|
credentialId.transports_len++;
|
||||||
}
|
}
|
||||||
CBOR_PARSE_ARRAY_END(_f3, 4);
|
CBOR_PARSE_ARRAY_END(_f3, 4);
|
||||||
@@ -122,12 +121,19 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
|
|||||||
|
|
||||||
cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_CBOR_PAYLOAD, 0);
|
cbor_encoder_init(&encoder, ctap_resp->init.data + 1, CTAP_MAX_CBOR_PAYLOAD, 0);
|
||||||
if (subcommand == 0x01) {
|
if (subcommand == 0x01) {
|
||||||
if (verify((uint8_t)pinUvAuthProtocol, paut.data, (const uint8_t *) "\x01", 1, pinUvAuthParam.data) != CborNoError) {
|
if (verify((uint8_t)pinUvAuthProtocol, ppaut.data, (const uint8_t *) "\x01", 1, pinUvAuthParam.data) == CborNoError) {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
if (!(ppaut.permissions & CTAP_PERMISSION_PCMR)) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (is_preview == false &&
|
else {
|
||||||
(!(paut.permissions & CTAP_PERMISSION_CM) || paut.has_rp_id == true)) {
|
if (verify((uint8_t)pinUvAuthProtocol, paut.data, (const uint8_t *) "\x01", 1, pinUvAuthParam.data) != CborNoError) {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
|
if (is_preview == false &&
|
||||||
|
(!(paut.permissions & CTAP_PERMISSION_CM) || paut.has_rp_id == true)) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uint8_t existing = 0;
|
uint8_t existing = 0;
|
||||||
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
|
for (int i = 0; i < MAX_RESIDENT_CREDENTIALS; i++) {
|
||||||
@@ -144,11 +150,18 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
|
|||||||
else if (subcommand == 0x02 || subcommand == 0x03) {
|
else if (subcommand == 0x02 || subcommand == 0x03) {
|
||||||
file_t *rp_ef = NULL;
|
file_t *rp_ef = NULL;
|
||||||
if (subcommand == 0x02) {
|
if (subcommand == 0x02) {
|
||||||
if (verify((uint8_t)pinUvAuthProtocol, paut.data, (const uint8_t *) "\x02", 1, pinUvAuthParam.data) != CborNoError) {
|
if (verify((uint8_t)pinUvAuthProtocol, ppaut.data, (const uint8_t *) "\x02", 1, pinUvAuthParam.data) == CborNoError) {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
if (!(ppaut.permissions & CTAP_PERMISSION_PCMR)) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (is_preview == false && (!(paut.permissions & CTAP_PERMISSION_CM) || paut.has_rp_id == true)) {
|
else {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
if (verify((uint8_t)pinUvAuthProtocol, paut.data, (const uint8_t *) "\x02", 1, pinUvAuthParam.data) != CborNoError) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
|
if (is_preview == false && (!(paut.permissions & CTAP_PERMISSION_CM) || paut.has_rp_id == true)) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rp_counter = 1;
|
rp_counter = 1;
|
||||||
rp_total = 0;
|
rp_total = 0;
|
||||||
@@ -199,13 +212,20 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) {
|
|||||||
}
|
}
|
||||||
if (subcommand == 0x04) {
|
if (subcommand == 0x04) {
|
||||||
*(raw_subpara - 1) = 0x04;
|
*(raw_subpara - 1) = 0x04;
|
||||||
if (verify((uint8_t)pinUvAuthProtocol, paut.data, raw_subpara - 1, (uint16_t)(raw_subpara_len + 1), pinUvAuthParam.data) != CborNoError) {
|
if (verify((uint8_t)pinUvAuthProtocol, ppaut.data, raw_subpara - 1, (uint16_t)(raw_subpara_len + 1), pinUvAuthParam.data) == CborNoError) {
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
if (!(ppaut.permissions & CTAP_PERMISSION_PCMR)) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (is_preview == false &&
|
else {
|
||||||
(!(paut.permissions & CTAP_PERMISSION_CM) ||
|
if (verify((uint8_t)pinUvAuthProtocol, paut.data, raw_subpara - 1, (uint16_t)(raw_subpara_len + 1), pinUvAuthParam.data) != CborNoError) {
|
||||||
(paut.has_rp_id == true && memcmp(paut.rp_id_hash, rpIdHash.data, 32) != 0))) {
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
}
|
||||||
|
if (is_preview == false &&
|
||||||
|
(!(paut.permissions & CTAP_PERMISSION_CM) ||
|
||||||
|
(paut.has_rp_id == true && memcmp(paut.rp_id_hash, rpIdHash.data, 32) != 0))) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_PIN_AUTH_INVALID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cred_counter = 1;
|
cred_counter = 1;
|
||||||
cred_total = 0;
|
cred_total = 0;
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ typedef struct {
|
|||||||
#define CTAP_PERMISSION_BE 0x08 // BioEnrollment
|
#define CTAP_PERMISSION_BE 0x08 // BioEnrollment
|
||||||
#define CTAP_PERMISSION_LBW 0x10 // LargeBlobWrite
|
#define CTAP_PERMISSION_LBW 0x10 // LargeBlobWrite
|
||||||
#define CTAP_PERMISSION_ACFG 0x20 // AuthenticatorConfiguration
|
#define CTAP_PERMISSION_ACFG 0x20 // AuthenticatorConfiguration
|
||||||
|
#define CTAP_PERMISSION_PCMR 0x40 // PerCredentialManagementReadOnly
|
||||||
|
|
||||||
typedef struct mse {
|
typedef struct mse {
|
||||||
uint8_t Qpt[65];
|
uint8_t Qpt[65];
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ int fido_process_apdu();
|
|||||||
int fido_unload();
|
int fido_unload();
|
||||||
|
|
||||||
pinUvAuthToken_t paut = { 0 };
|
pinUvAuthToken_t paut = { 0 };
|
||||||
|
persistentPinUvAuthToken_t ppaut = { 0 };
|
||||||
|
|
||||||
uint8_t keydev_dec[32];
|
uint8_t keydev_dec[32];
|
||||||
bool has_keydev_dec = false;
|
bool has_keydev_dec = false;
|
||||||
@@ -419,6 +420,19 @@ int scan_files_fido() {
|
|||||||
else {
|
else {
|
||||||
printf("FATAL ERROR: Auth Token not found in memory!\r\n");
|
printf("FATAL ERROR: Auth Token not found in memory!\r\n");
|
||||||
}
|
}
|
||||||
|
file_t *ef_pauthtoken = search_by_fid(EF_PAUTHTOKEN, NULL, SPECIFY_EF);
|
||||||
|
if (ef_pauthtoken) {
|
||||||
|
if (!file_has_data(ef_pauthtoken)) {
|
||||||
|
uint8_t t[32];
|
||||||
|
random_gen(NULL, t, sizeof(t));
|
||||||
|
file_put_data(ef_pauthtoken, t, sizeof(t));
|
||||||
|
}
|
||||||
|
ppaut.data = file_get_data(ef_pauthtoken);
|
||||||
|
ppaut.len = file_get_size(ef_pauthtoken);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("FATAL ERROR: Persistent Auth Token not found in memory!\r\n");
|
||||||
|
}
|
||||||
ef_largeblob = search_by_fid(EF_LARGEBLOB, NULL, SPECIFY_EF);
|
ef_largeblob = search_by_fid(EF_LARGEBLOB, NULL, SPECIFY_EF);
|
||||||
if (!file_has_data(ef_largeblob)) {
|
if (!file_has_data(ef_largeblob)) {
|
||||||
file_put_data(ef_largeblob, (const uint8_t *) "\x80\x76\xbe\x8b\x52\x8d\x00\x75\xf7\xaa\xe9\x8d\x6f\xa5\x7a\x6d\x3c", 17);
|
file_put_data(ef_largeblob, (const uint8_t *) "\x80\x76\xbe\x8b\x52\x8d\x00\x75\xf7\xaa\xe9\x8d\x6f\xa5\x7a\x6d\x3c", 17);
|
||||||
|
|||||||
@@ -129,9 +129,17 @@ typedef struct pinUvAuthToken {
|
|||||||
bool user_verified;
|
bool user_verified;
|
||||||
} pinUvAuthToken_t;
|
} pinUvAuthToken_t;
|
||||||
|
|
||||||
|
typedef struct persistentPinUvAuthToken {
|
||||||
|
uint8_t *data;
|
||||||
|
size_t len;
|
||||||
|
uint8_t permissions;
|
||||||
|
} persistentPinUvAuthToken_t;
|
||||||
|
|
||||||
extern uint32_t user_present_time_limit;
|
extern uint32_t user_present_time_limit;
|
||||||
|
|
||||||
extern pinUvAuthToken_t paut;
|
extern pinUvAuthToken_t paut;
|
||||||
|
extern persistentPinUvAuthToken_t ppaut;
|
||||||
|
|
||||||
extern int verify(uint8_t protocol, const uint8_t *key, const uint8_t *data, uint16_t len, uint8_t *sign);
|
extern int verify(uint8_t protocol, const uint8_t *key, const uint8_t *data, uint16_t len, uint8_t *sign);
|
||||||
|
|
||||||
extern uint8_t session_pin[32];
|
extern uint8_t session_pin[32];
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ file_t file_entries[] = {
|
|||||||
{ .fid = EF_COUNTER, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Global counter
|
{ .fid = EF_COUNTER, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Global counter
|
||||||
{ .fid = EF_PIN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // PIN
|
{ .fid = EF_PIN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // PIN
|
||||||
{ .fid = EF_AUTHTOKEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // AUTH TOKEN
|
{ .fid = EF_AUTHTOKEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // AUTH TOKEN
|
||||||
|
{ .fid = EF_PAUTHTOKEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // PERSISTENT AUTH TOKEN
|
||||||
{ .fid = EF_MINPINLEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // MIN PIN LENGTH
|
{ .fid = EF_MINPINLEN, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // MIN PIN LENGTH
|
||||||
{ .fid = EF_OPTS, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Global options
|
{ .fid = EF_OPTS, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Global options
|
||||||
{ .fid = EF_LARGEBLOB, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Large Blob
|
{ .fid = EF_LARGEBLOB, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, // Large Blob
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#define EF_OPTS 0xC001
|
#define EF_OPTS 0xC001
|
||||||
#define EF_PIN 0x1080
|
#define EF_PIN 0x1080
|
||||||
#define EF_AUTHTOKEN 0x1090
|
#define EF_AUTHTOKEN 0x1090
|
||||||
|
#define EF_PAUTHTOKEN 0x1091
|
||||||
#define EF_MINPINLEN 0x1100
|
#define EF_MINPINLEN 0x1100
|
||||||
#define EF_DEV_CONF 0x1122
|
#define EF_DEV_CONF 0x1122
|
||||||
#define EF_CRED 0xCF00 // Creds at 0xCF00 - 0xCFFF
|
#define EF_CRED 0xCF00 // Creds at 0xCF00 - 0xCFFF
|
||||||
|
|||||||
Reference in New Issue
Block a user