all core functionality *works*

This commit is contained in:
Conor Patrick
2018-07-11 21:55:20 -04:00
parent 156dc3163a
commit eaa7e15499
15 changed files with 850 additions and 63 deletions

View File

@@ -17,6 +17,27 @@
#include "uECC.h"
#include "aes.h"
#include "ctap.h"
#include "device.h"
#include "app.h"
#ifdef USING_PC
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0,
MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */
MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */
MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */
MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */
MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */
MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */
MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */
MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */
MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */
MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */
} mbedtls_ecp_group_id;
#endif
const uint8_t attestation_cert_der[];
@@ -29,6 +50,7 @@ const uint16_t attestation_key_size;
static SHA256_CTX sha256_ctx;
static const struct uECC_Curve_t * _es256_curve = NULL;
static const uint8_t * _signing_key = NULL;
static int _key_len = 0;
// Secrets for testing only
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
@@ -136,6 +158,7 @@ void crypto_ecc256_init()
void crypto_ecc256_load_attestation_key()
{
_signing_key = attestation_key;
_key_len = 32;
}
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
@@ -147,6 +170,55 @@ void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
}
}
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
{
static uint8_t privkey[32];
generate_private_key(data,len,data2,len2,privkey);
_signing_key = privkey;
_key_len = 32;
}
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
{
const struct uECC_Curve_t * curve = NULL;
switch(MBEDTLS_ECP_ID)
{
case MBEDTLS_ECP_DP_SECP192R1:
curve = uECC_secp192r1();
if (_key_len != 24) goto fail;
break;
case MBEDTLS_ECP_DP_SECP224R1:
curve = uECC_secp224r1();
if (_key_len != 28) goto fail;
break;
case MBEDTLS_ECP_DP_SECP256R1:
curve = uECC_secp256r1();
if (_key_len != 32) goto fail;
break;
case MBEDTLS_ECP_DP_SECP256K1:
curve = uECC_secp256k1();
if (_key_len != 32) goto fail;
break;
default:
printf("error, invalid ECDSA alg specifier\n");
exit(1);
}
if ( uECC_sign(_signing_key, data, len, sig, curve) == 0)
{
printf("error, uECC failed\n");
exit(1);
}
return;
fail:
printf("error, invalid key length\n");
exit(1);
}
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
{
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
@@ -171,13 +243,13 @@ void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8
memmove(y,pubkey+32,32);
}
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
void crypto_load_external_key(uint8_t * key, int len)
{
static uint8_t privkey[32];
generate_private_key(data,len,data2,len2,privkey);
_signing_key = privkey;
_signing_key = key;
_key_len = len;
}
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey)
{
if (uECC_make_key(pubkey, privkey, _es256_curve) != 1)

View File

@@ -19,7 +19,9 @@ void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2);
void crypto_ecc256_load_attestation_key();
void crypto_load_external_key(uint8_t * key, int len);
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig);
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID);
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey);

View File

@@ -15,15 +15,15 @@
#include "app.h"
#include "wallet.h"
#include "device.h"
#define PIN_TOKEN_SIZE 16
uint8_t PIN_TOKEN[PIN_TOKEN_SIZE];
uint8_t KEY_AGREEMENT_PUB[64];
static uint8_t KEY_AGREEMENT_PRIV[32];
static uint8_t PIN_CODE_SET = 0;
uint8_t PIN_CODE[NEW_PIN_ENC_MAX_SIZE];
static uint8_t PIN_CODE_HASH[32];
static uint8_t DEVICE_LOCKOUT = 0;
AuthenticatorState STATE;
static struct {
CTAP_authDataHeader authData;
@@ -766,7 +766,7 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
return ret;
}
if (PIN_CODE_SET == 1 && GA.pinAuthPresent == 0)
if (ctap_is_pin_set() && GA.pinAuthPresent == 0)
{
printf2(TAG_ERR,"pinAuth is required\n");
return CTAP2_ERR_PIN_REQUIRED;
@@ -851,6 +851,14 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor
return CTAP1_ERR_OTHER;
}
if (ctap_is_pin_set()) // Check first, prevent SCA
{
if (ctap_device_locked())
{
return CTAP2_ERR_OPERATION_DENIED;
}
}
crypto_ecc256_shared_secret(platform_pubkey, KEY_AGREEMENT_PRIV, shared_secret);
crypto_sha256_init();
@@ -898,6 +906,10 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor
if (ctap_is_pin_set())
{
if (ctap_device_locked())
{
return CTAP2_ERR_OPERATION_DENIED;
}
crypto_aes256_reset_iv(NULL);
crypto_aes256_decrypt(pinHashEnc, 16);
if (memcmp(pinHashEnc, PIN_CODE_HASH, 16) != 0)
@@ -1111,7 +1123,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)
case CTAP_CLIENT_PIN:
if (ctap_device_locked())
{
status = CTAP2_ERR_NOT_ALLOWED;
status = CTAP2_ERR_OPERATION_DENIED;
goto done;
}
break;
@@ -1207,12 +1219,69 @@ done:
return status;
}
void ctap_flush_state(int backup)
{
authenticator_write_state(&STATE, 0);
if (backup)
{
authenticator_write_state(&STATE, 1);
}
}
static void ctap_state_init()
{
// Set to 0xff instead of 0x00 to be easier on flash
memset(&STATE, 0xff, sizeof(AuthenticatorState));
STATE.is_initialized = INITIALIZED_MARKER;
STATE.remaining_tries = PIN_LOCKOUT_ATTEMPTS;
STATE.is_pin_set = 0;
}
void ctap_init()
{
crypto_ecc256_init();
ctap_reset_pin_attempts();
DEVICE_LOCKOUT = 0;
authenticator_read_state(&STATE);
if (STATE.is_initialized == INITIALIZED_MARKER)
{
printf1(TAG_STOR,"Auth state is initialized\n");
}
else
{
printf1(TAG_STOR,"Auth state is NOT initialized. Initializing..\n");
if (authenticator_is_backup_initialized())
{
printf1(TAG_ERR,"Warning: memory corruption detected. restoring from backup..\n");
authenticator_read_backup_state(&STATE);
authenticator_write_state(&STATE, 0);
}
else
{
ctap_state_init();
authenticator_write_state(&STATE, 0);
authenticator_write_state(&STATE, 1);
}
}
if (ctap_is_pin_set())
{
printf1(TAG_STOR,"pin code: \"%s\"\n", STATE.pin_code);
crypto_sha256_init();
crypto_sha256_update(STATE.pin_code, strnlen(STATE.pin_code, NEW_PIN_ENC_MAX_SIZE));
crypto_sha256_final(PIN_CODE_HASH);
printf1(TAG_STOR, "attempts_left: %d\n", STATE.remaining_tries);
}
else
{
printf1(TAG_STOR,"pin not set.\n");
}
if (ctap_device_locked())
{
printf1(TAG_ERR, "DEVICE LOCKED!\n");
}
if (ctap_generate_rng(PIN_TOKEN, PIN_TOKEN_SIZE) != 1)
{
@@ -1230,12 +1299,12 @@ void ctap_init()
uint8_t ctap_is_pin_set()
{
return PIN_CODE_SET == 1;
return STATE.is_pin_set == 1;
}
uint8_t ctap_pin_matches(uint8_t * pin, int len)
{
return memcmp(pin, PIN_CODE, len) == 0;
return memcmp(pin, STATE.pin_code, len) == 0;
}
@@ -1247,30 +1316,35 @@ void ctap_update_pin(uint8_t * pin, int len)
printf2(TAG_ERR, "Update pin fail length\n");
exit(1);
}
memset(PIN_CODE,0,sizeof(PIN_CODE));
memmove(PIN_CODE, pin, len);
memset(STATE.pin_code, 0, NEW_PIN_ENC_MAX_SIZE);
memmove(STATE.pin_code, pin, len);
crypto_sha256_init();
crypto_sha256_update(PIN_CODE, len);
crypto_sha256_update(STATE.pin_code, len);
crypto_sha256_final(PIN_CODE_HASH);
PIN_CODE_SET = 1;
STATE.is_pin_set = 1;
printf1(TAG_CTAP, "New pin set: %s\n", PIN_CODE);
printf1(TAG_CTAP, "New pin set: %s\n", STATE.pin_code);
}
// TODO flash
static int8_t _flash_tries;
uint8_t ctap_decrement_pin_attempts()
{
if (_flash_tries > 0)
if (STATE.remaining_tries > 0)
{
_flash_tries--;
printf1(TAG_CP, "ATTEMPTS left: %d\n", _flash_tries);
STATE.remaining_tries--;
ctap_flush_state(0);
printf1(TAG_CP, "ATTEMPTS left: %d\n", STATE.remaining_tries);
if (STATE.remaining_tries == 0)
{
memset(PIN_TOKEN,0,sizeof(PIN_TOKEN));
memset(PIN_CODE_HASH,0,sizeof(PIN_CODE_HASH));
printf1(TAG_CP, "Device locked!\n");
}
}
else
{
DEVICE_LOCKOUT = 1;
printf1(TAG_CP, "Device locked!\n");
return -1;
}
@@ -1279,17 +1353,18 @@ uint8_t ctap_decrement_pin_attempts()
int8_t ctap_device_locked()
{
return DEVICE_LOCKOUT == 1;
return STATE.remaining_tries == 0;
}
int8_t ctap_leftover_pin_attempts()
{
return _flash_tries;
return STATE.remaining_tries;
}
void ctap_reset_pin_attempts()
{
_flash_tries = 8;
STATE.remaining_tries = PIN_LOCKOUT_ATTEMPTS;
ctap_flush_state(0);
}
void ctap_reset_state()
@@ -1297,15 +1372,119 @@ void ctap_reset_state()
memset(&getAssertionState, 0, sizeof(getAssertionState));
}
void ctap_reset()
uint16_t ctap_keys_stored()
{
_flash_tries = 8;
PIN_CODE_SET = 0;
DEVICE_LOCKOUT = 0;
ctap_reset_state();
memset(PIN_CODE,0,sizeof(PIN_CODE));
memset(PIN_CODE_HASH,0,sizeof(PIN_CODE_HASH));
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
crypto_reset_master_secret();
int total = 0;
int i;
for (i = 0; i < MAX_KEYS; i++)
{
if (STATE.key_lens[i] != 0xffff)
{
total += 1;
}
else
{
break;
}
}
return total;
}
static uint16_t key_addr_offset(int index)
{
uint16_t offset = 0;
int i;
for (i = 0; i < index; i++)
{
if (STATE.key_lens[i] != 0xffff) offset += STATE.key_lens[i];
}
return offset;
}
uint16_t ctap_key_len(uint8_t index)
{
int i = ctap_keys_stored();
uint16_t offset;
if (i >= MAX_KEYS || index >= MAX_KEYS)
{
return 0;
}
if (STATE.key_lens[index] == 0xffff) return 0;
return STATE.key_lens[index];
}
int8_t ctap_store_key(uint8_t index, uint8_t * key, uint16_t len)
{
int i = ctap_keys_stored();
uint16_t offset;
if (i >= MAX_KEYS || index >= MAX_KEYS || !len)
{
return ERR_NO_KEY_SPACE;
}
if (STATE.key_lens[index] != 0xffff)
{
return ERR_KEY_SPACE_TAKEN;
}
offset = key_addr_offset(index);
if ((offset + len) > KEY_SPACE_BYTES)
{
return ERR_NO_KEY_SPACE;
}
STATE.key_lens[index] = len;
memmove(STATE.key_space + offset, key, len);
ctap_flush_state(0);
ctap_flush_state(1);
return 0;
}
int8_t ctap_load_key(uint8_t index, uint8_t * key)
{
int i = ctap_keys_stored();
uint16_t offset;
uint16_t len;
if (i >= MAX_KEYS || index >= MAX_KEYS)
{
return ERR_NO_KEY_SPACE;
}
if (STATE.key_lens[index] == 0)
{
return ERR_KEY_SPACE_EMPTY;
}
offset = key_addr_offset(index);
len = ctap_key_len(index);
if ((offset + len) > KEY_SPACE_BYTES)
{
return ERR_NO_KEY_SPACE;
}
memmove(key, STATE.key_space + offset, len);
return 0;
}
void ctap_reset()
{
ctap_state_init();
authenticator_write_state(&STATE, 0);
authenticator_write_state(&STATE, 1);
ctap_reset_state();
memset(PIN_CODE_HASH,0,sizeof(PIN_CODE_HASH));
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
crypto_reset_master_secret(); // Not sure what the significance of this is??
}

View File

@@ -2,7 +2,6 @@
#define _CTAP_H
#include "cbor.h"
#include "device.h"
#define CTAP_MAKE_CREDENTIAL 0x01
#define CTAP_GET_ASSERTION 0x02
@@ -109,6 +108,8 @@
#define CTAP_RESPONSE_BUFFER_SIZE 1024
#define PIN_LOCKOUT_ATTEMPTS 8
typedef struct
{
uint8_t id[USER_ID_MAX_SIZE];
@@ -260,10 +261,19 @@ uint8_t ctap_pin_matches(uint8_t * pin, int len);
void ctap_reset();
int8_t ctap_device_locked();
// Key storage API
// Return length of key at index. 0 if not exist.
uint16_t ctap_key_len(uint8_t index);
// See error codes in storage.h
int8_t ctap_store_key(uint8_t index, uint8_t * key, uint16_t len);
int8_t ctap_load_key(uint8_t index, uint8_t * key);
uint16_t ctap_key_len(uint8_t index);
#define PIN_TOKEN_SIZE 16
extern uint8_t PIN_TOKEN[PIN_TOKEN_SIZE];
extern uint8_t KEY_AGREEMENT_PUB[64];
extern uint8_t PIN_CODE[NEW_PIN_ENC_MAX_SIZE];
#endif

View File

@@ -1,6 +1,8 @@
#ifndef _DEVICE_H
#define _DEVICE_H
#include "storage.h"
void device_init();
uint32_t millis();
@@ -20,6 +22,16 @@ void main_loop_delay();
void heartbeat();
void authenticator_read_state(AuthenticatorState * );
void authenticator_read_backup_state(AuthenticatorState * );
// Return 1 yes backup is init'd, else 0
//void authenticator_initialize()
int authenticator_is_backup_initialized();
void authenticator_write_state(AuthenticatorState *, int backup);
// Test for user presence
// Return 1 for user is present, 0 user not present

View File

@@ -32,6 +32,7 @@ struct logtag tagtable[] = {
{TAG_RED,"DEBUG"},
{TAG_TIME,"TIME"},
{TAG_WALLET,"WALLET"},
{TAG_STOR,"STOR"},
};

View File

@@ -26,6 +26,7 @@ typedef enum
TAG_HID = (1 << 12),
TAG_USB = (1 << 13),
TAG_WALLET = (1 << 14),
TAG_STOR = (1 << 15),
TAG_FILENO = (1<<31)
} LOG_TAG;

View File

@@ -28,6 +28,7 @@ int main(int argc, char * argv[])
/*TAG_MC |*/
/*TAG_GA |*/
TAG_WALLET |
TAG_STOR |
/*TAG_CP |*/
// TAG_CTAP|
// TAG_HID|

38
fido2/storage.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef _STORAGE_H
#define _STORAGE_H
#include "ctap.h"
#define KEY_SPACE_BYTES 128
#define MAX_KEYS (KEY_SPACE_BYTES/1)
#define BACKUP_MARKER 0x5A
#define INITIALIZED_MARKER 0xA5
#define ERR_NO_KEY_SPACE (-1)
#define ERR_KEY_SPACE_TAKEN (-2)
#define ERR_KEY_SPACE_EMPTY (-2)
typedef struct
{
// Pin information
uint8_t is_initialized;
uint8_t is_pin_set;
uint8_t pin_code[NEW_PIN_ENC_MAX_SIZE];
uint8_t remaining_tries;
uint16_t key_lens[MAX_KEYS];
uint8_t key_space[KEY_SPACE_BYTES];
} AuthenticatorState;
typedef struct
{
uint32_t addr;
uint8_t * filename;
uint32_t count;
} AuthenticatorCounter;
extern AuthenticatorState STATE;
#endif

View File

@@ -5,12 +5,34 @@
* Author: conor
*/
#include "wallet.h"
#include "app.h"
#include "ctap.h"
#include "ctap_errors.h"
#include "crypto.h"
#include "u2f.h"
#include "log.h"
#include "util.h"
#include "storage.h"
#include "device.h"
#ifdef USING_PC
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0,
MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */
MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */
MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */
MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */
MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */
MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */
MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */
MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */
MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */
MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */
} mbedtls_ecp_group_id;
#endif
typedef enum
{
@@ -43,9 +65,7 @@ void wallet_init()
// TODO dont leave this
printf1(TAG_WALLET,"Wallet is ready\n");
/*ctap_update_pin("1234", 4);*/
}
int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * arg2, uint8_t * arg3, int len)
@@ -58,6 +78,11 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a
case CP_cmdGetKeyAgreement:
printf1(TAG_WALLET,"cmdGetKeyAgreement\n");
if ( ctap_device_locked() )
{
return CTAP2_ERR_OPERATION_DENIED;
}
u2f_response_writeback(KEY_AGREEMENT_PUB,sizeof(KEY_AGREEMENT_PUB));
printf1(TAG_WALLET,"pubkey: "); dump_hex1(TAG_WALLET,KEY_AGREEMENT_PUB,64);
@@ -80,17 +105,22 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a
if (ret != 0)
return ret;
printf1(TAG_WALLET,"Success. Pin = %s\n",PIN_CODE);
printf1(TAG_WALLET,"Success. Pin = %s\n", STATE.pin_code);
break;
case CP_cmdChangePin:
printf1(TAG_WALLET,"cmdChangePin\n");
if (! ctap_is_pin_set())
if (! ctap_is_pin_set() )
{
return CTAP2_ERR_PIN_NOT_SET;
}
if ( ctap_device_locked() )
{
return CTAP2_ERR_OPERATION_DENIED;
}
//pinEnc // plat_pubkey // pinHashEnc
ret = ctap_update_pin_if_verified( arg2, len, arg1, pinAuth, arg3);
if (ret != 0)
@@ -100,6 +130,11 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a
case CP_cmdGetPinToken:
printf1(TAG_WALLET,"cmdGetPinToken\n");
if ( ctap_device_locked() )
{
return CTAP2_ERR_OPERATION_DENIED;
}
ret = ctap_add_pin_if_verified(pinTokenEnc, arg1, pinAuth); // pubkey, pinHashEnc
if (ret != 0)
return ret;
@@ -132,6 +167,12 @@ int16_t bridge_u2f_to_wallet(uint8_t * _chal, uint8_t * _appid, uint8_t klen, ui
uint8_t * args[5] = {NULL,NULL,NULL,NULL,NULL};
uint8_t lens[5];
uint8_t key[256];
uint8_t shasum[32];
uint8_t chksum[4];
int keysize = sizeof(key);
for (i = 0; i < sizeof(sig); i++)
{
@@ -177,7 +218,7 @@ int16_t bridge_u2f_to_wallet(uint8_t * _chal, uint8_t * _appid, uint8_t klen, ui
printf1(TAG_WALLET,"WalletSign\n");
printf1(TAG_WALLET,"pinAuth:"); dump_hex1(TAG_WALLET, req->pinAuth, 16);
if (args[0] == NULL)
if (args[0] == NULL || lens[0] == 0)
{
ret = CTAP2_ERR_MISSING_PARAMETER;
printf2(TAG_ERR,"Missing parameter for WalletSign\n");
@@ -208,9 +249,91 @@ int16_t bridge_u2f_to_wallet(uint8_t * _chal, uint8_t * _appid, uint8_t klen, ui
{
printf1(TAG_WALLET,"Warning: no pin is set. Ignoring pinAuth\n");
}
ret = ctap_load_key(0, key);
if (ret != 0)
{
ret = CTAP2_ERR_NO_CREDENTIALS;
goto cleanup;
}
keysize = ctap_key_len(0);
crypto_load_external_key(key, keysize);
crypto_ecdsa_sign(args[0], lens[0], sig, MBEDTLS_ECP_DP_SECP256R1);
u2f_response_writeback(sig,64);
break;
case WalletRegister:
printf1(TAG_WALLET,"WalletRegister\n");
if (args[0] == NULL)
{
ret = CTAP2_ERR_MISSING_PARAMETER;
printf2(TAG_ERR,"Missing parameter for WalletReg\n");
goto cleanup;
}
if (lens[0] < 8 || lens[0] > keysize)
{
ret = CTAP1_ERR_INVALID_LENGTH;
printf2(TAG_ERR,"Invalid length for WalletReg\n");
goto cleanup;
}
if (ctap_is_pin_set())
{
if (check_pinhash(req->pinAuth, msg_buf, reqlen))
{
printf1(TAG_WALLET,"pinAuth is valid\n");
}
else
{
printf1(TAG_WALLET,"pinAuth is NOT valid\n");
ret = CTAP2_ERR_PIN_AUTH_INVALID;
goto cleanup;
}
}
else
{
printf1(TAG_WALLET,"Warning: no pin is set. Ignoring pinAuth\n");
}
memmove(chksum, args[0] + lens[0] - 4, 4);
lens[0] -= 4;
// perform integrity check
printf1(TAG_WALLET,"shasum on [%d]: ",lens[0]); dump_hex1(TAG_WALLET, args[0], lens[0]);
crypto_sha256_init();
crypto_sha256_update(args[0], lens[0]);
crypto_sha256_final(shasum);
crypto_sha256_init();
crypto_sha256_update(shasum, 32);
crypto_sha256_final(shasum);
if (memcmp(shasum, chksum, 4) != 0)
{
ret = CTAP2_ERR_CREDENTIAL_NOT_VALID;
printf2(TAG_ERR,"Integrity fail for WalletReg\n");
dump_hex1(TAG_ERR, chksum, sizeof(chksum));
goto cleanup;
}
// drop the first byte
args[0]++;
lens[0]--;
printf1(TAG_WALLET,"adding key [%d]: ",lens[0]); dump_hex1(TAG_WALLET, args[0], lens[0]);
ret = ctap_store_key(0, args[0], lens[0]);
if (ret == ERR_NO_KEY_SPACE || ret == ERR_KEY_SPACE_TAKEN)
{
ret = CTAP2_ERR_KEY_STORE_FULL;
goto cleanup;
}
break;
case WalletPin:
printf1(TAG_WALLET,"WalletPin\n");