Compare commits
6 Commits
master
...
master-old
Author | SHA1 | Date | |
---|---|---|---|
3de4d0155e | |||
5f9537bccc | |||
967e35472f | |||
78f7a7a979 | |||
72063049a7 | |||
4743fd2326 |
24
default.nix
Normal file
24
default.nix
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
let
|
||||||
|
pkgs = import (fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/20.03.tar.gz"; sha256 = "0182ys095dfx02vl2a20j1hz92dx3mfgz2a6fhn31bqlp1wa8hlq"; }) {};
|
||||||
|
pyPackages = (python-packages: with python-packages; ([
|
||||||
|
solo-python pytest
|
||||||
|
] ++ (with builtins; map (d: getAttr d python-packages) (filter (d: stringLength d > 0) (pkgs.lib.splitString "\n" (builtins.readFile ./tools/requirements.txt))))));
|
||||||
|
python-with-my-packages = pkgs.python3.withPackages pyPackages;
|
||||||
|
src = ./.;
|
||||||
|
in
|
||||||
|
with pkgs; stdenv.mkDerivation {
|
||||||
|
name = "solo";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
src = with lib; builtins.filterSource (path: type: !(hasSuffix path "hex" || hasSuffix path "sha256")) src;
|
||||||
|
buildInputs = [ gnumake gcc gcc-arm-embedded-8 git python-with-my-packages ];
|
||||||
|
phases = [ "unpackPhase" "configurePhase" "buildPhase" "installPhase" ];
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/firmware $out
|
||||||
|
cd targets/stm32l432
|
||||||
|
make cbor
|
||||||
|
make build-hacker
|
||||||
|
cp *.hex *.sha256 *.elf cubeconfig_stm32l442.ioc $out/firmware/
|
||||||
|
'';
|
||||||
|
keepDebugInfo = true;
|
||||||
|
}
|
||||||
|
|
54
fido2/ctap.c
54
fido2/ctap.c
@ -461,7 +461,10 @@ static int ctap_make_extensions(CTAP_extensions * ext, uint8_t * ext_encoder_buf
|
|||||||
// Generate credRandom
|
// Generate credRandom
|
||||||
crypto_sha256_hmac_init(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
crypto_sha256_hmac_init(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
||||||
crypto_sha256_update((uint8_t*)&ext->hmac_secret.credential->id, sizeof(CredentialId));
|
crypto_sha256_update((uint8_t*)&ext->hmac_secret.credential->id, sizeof(CredentialId));
|
||||||
|
// using user_verified as len means it won't be included when false
|
||||||
|
if (getAssertionState.user_verified == 1) {
|
||||||
crypto_sha256_update(&getAssertionState.user_verified, 1);
|
crypto_sha256_update(&getAssertionState.user_verified, 1);
|
||||||
|
}
|
||||||
crypto_sha256_hmac_final(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
crypto_sha256_hmac_final(CRYPTO_TRANSPORT_KEY2, 0, credRandom);
|
||||||
|
|
||||||
// Decrypt saltEnc
|
// Decrypt saltEnc
|
||||||
@ -566,10 +569,10 @@ static unsigned int get_credential_id_size(int type)
|
|||||||
return sizeof(CredentialId);
|
return sizeof(CredentialId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ctap2_user_presence_test()
|
static int ctap2_user_presence_test(uint32_t colour)
|
||||||
{
|
{
|
||||||
device_set_status(CTAPHID_STATUS_UPNEEDED);
|
device_set_status(CTAPHID_STATUS_UPNEEDED);
|
||||||
int ret = ctap_user_presence_test(CTAP2_UP_DELAY_MS);
|
int ret = ctap_user_presence_test_colour(CTAP2_UP_DELAY_MS, colour);
|
||||||
if ( ret > 1 )
|
if ( ret > 1 )
|
||||||
{
|
{
|
||||||
return CTAP2_ERR_PROCESSING;
|
return CTAP2_ERR_PROCESSING;
|
||||||
@ -587,6 +590,33 @@ static int ctap2_user_presence_test()
|
|||||||
return CTAP2_ERR_ACTION_TIMEOUT;
|
return CTAP2_ERR_ACTION_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static uint32_t ctap_assertion_led_colour(uint8_t * seed, uint32_t slen)
|
||||||
|
{
|
||||||
|
uint8_t hmac[32];
|
||||||
|
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 32, hmac);
|
||||||
|
crypto_sha256_hmac_final(seed, slen, hmac);
|
||||||
|
uint32_t colour = 0;
|
||||||
|
uint32_t backlist[] = {0x00FF00};
|
||||||
|
int dist = 0;
|
||||||
|
int min_dist = 50*50*3;
|
||||||
|
for(int i=0; i<32-3 && (dist < min_dist || i == 0);i++) {
|
||||||
|
uint8_t* rgb = &hmac[i];
|
||||||
|
colour = ((uint32_t*) rgb)[0] & 0x0000ffffff;
|
||||||
|
int r, g, b = 0;
|
||||||
|
r = colour & 0x0000ff0000 >> 16;
|
||||||
|
g = colour & 0x000000ff00 >> 8;
|
||||||
|
b = colour & 0x00000000ff;
|
||||||
|
for(int j=0; j < 1 && dist < min_dist; j++) {
|
||||||
|
int br, bg, bb = 0;
|
||||||
|
br = backlist[j] & 0x0000ff0000 >> 16;
|
||||||
|
bg = backlist[j] & 0x000000ff00 >> 8;
|
||||||
|
bb = backlist[j] & 0x00000000ff;
|
||||||
|
dist = ((int) r - br)*(r - br) + ((int)g - bg)*((int)g - bg) + ((int)b - bb)*((int)b - bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return colour;
|
||||||
|
}
|
||||||
|
|
||||||
static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, uint32_t * len, CTAP_credInfo * credInfo, CTAP_extensions * extensions)
|
static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, uint32_t * len, CTAP_credInfo * credInfo, CTAP_extensions * extensions)
|
||||||
{
|
{
|
||||||
@ -617,7 +647,7 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
|
|||||||
|
|
||||||
int but;
|
int but;
|
||||||
|
|
||||||
but = ctap2_user_presence_test();
|
but = ctap2_user_presence_test(ctap_assertion_led_colour(authData->head.rpIdHash, 32));
|
||||||
if (CTAP2_ERR_PROCESSING == but)
|
if (CTAP2_ERR_PROCESSING == but)
|
||||||
{
|
{
|
||||||
authData->head.flags = (0 << 0); // User presence disabled
|
authData->head.flags = (0 << 0); // User presence disabled
|
||||||
@ -880,7 +910,7 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt
|
|||||||
}
|
}
|
||||||
if (MC.pinAuthEmpty)
|
if (MC.pinAuthEmpty)
|
||||||
{
|
{
|
||||||
ret = ctap2_user_presence_test();
|
ret = ctap2_user_presence_test(0);
|
||||||
check_retr(ret);
|
check_retr(ret);
|
||||||
return ctap_is_pin_set() == 1 ? CTAP2_ERR_PIN_AUTH_INVALID : CTAP2_ERR_PIN_NOT_SET;
|
return ctap_is_pin_set() == 1 ? CTAP2_ERR_PIN_AUTH_INVALID : CTAP2_ERR_PIN_NOT_SET;
|
||||||
}
|
}
|
||||||
@ -925,7 +955,7 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt
|
|||||||
{
|
{
|
||||||
if ( check_credential_metadata(&excl_cred->credential.id, MC.pinAuthPresent, 1) == 0)
|
if ( check_credential_metadata(&excl_cred->credential.id, MC.pinAuthPresent, 1) == 0)
|
||||||
{
|
{
|
||||||
ret = ctap2_user_presence_test();
|
ret = ctap2_user_presence_test(0);
|
||||||
check_retr(ret);
|
check_retr(ret);
|
||||||
printf1(TAG_MC, "Cred %d failed!\r\n",i);
|
printf1(TAG_MC, "Cred %d failed!\r\n",i);
|
||||||
return CTAP2_ERR_CREDENTIAL_EXCLUDED;
|
return CTAP2_ERR_CREDENTIAL_EXCLUDED;
|
||||||
@ -1738,6 +1768,7 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||||
{
|
{
|
||||||
CTAP_getAssertion GA;
|
CTAP_getAssertion GA;
|
||||||
@ -1752,7 +1783,8 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
|||||||
|
|
||||||
if (GA.pinAuthEmpty)
|
if (GA.pinAuthEmpty)
|
||||||
{
|
{
|
||||||
ret = ctap2_user_presence_test();
|
uint32_t colour = ctap_assertion_led_colour(GA.clientDataHash, 32);
|
||||||
|
ret = ctap2_user_presence_test(colour);
|
||||||
check_retr(ret);
|
check_retr(ret);
|
||||||
return ctap_is_pin_set() == 1 ? CTAP2_ERR_PIN_AUTH_INVALID : CTAP2_ERR_PIN_NOT_SET;
|
return ctap_is_pin_set() == 1 ? CTAP2_ERR_PIN_AUTH_INVALID : CTAP2_ERR_PIN_NOT_SET;
|
||||||
}
|
}
|
||||||
@ -2285,7 +2317,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)
|
|||||||
break;
|
break;
|
||||||
case CTAP_RESET:
|
case CTAP_RESET:
|
||||||
printf1(TAG_CTAP,"CTAP_RESET\n");
|
printf1(TAG_CTAP,"CTAP_RESET\n");
|
||||||
status = ctap2_user_presence_test();
|
status = ctap2_user_presence_test(0);
|
||||||
if (status == CTAP1_ERR_SUCCESS)
|
if (status == CTAP1_ERR_SUCCESS)
|
||||||
{
|
{
|
||||||
ctap_reset();
|
ctap_reset();
|
||||||
@ -2318,6 +2350,9 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)
|
|||||||
|
|
||||||
dump_hex1(TAG_DUMP,buf, resp->length);
|
dump_hex1(TAG_DUMP,buf, resp->length);
|
||||||
break;
|
break;
|
||||||
|
case CTAP_VENDOR_LOAD:
|
||||||
|
//TODO: load secret
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
status = CTAP1_ERR_INVALID_COMMAND;
|
status = CTAP1_ERR_INVALID_COMMAND;
|
||||||
printf2(TAG_ERR,"error, invalid cmd: 0x%02x\n", cmd);
|
printf2(TAG_ERR,"error, invalid cmd: 0x%02x\n", cmd);
|
||||||
@ -2443,6 +2478,11 @@ uint8_t ctap_is_pin_set()
|
|||||||
*/
|
*/
|
||||||
void ctap_update_pin(uint8_t * pin, int len)
|
void ctap_update_pin(uint8_t * pin, int len)
|
||||||
{
|
{
|
||||||
|
if(len == 0 || strncmp(pin, "4321", len) == 0) {
|
||||||
|
STATE.is_pin_set = 0;
|
||||||
|
authenticator_write_state(&STATE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (len >= NEW_PIN_ENC_MIN_SIZE || len < 4)
|
if (len >= NEW_PIN_ENC_MIN_SIZE || len < 4)
|
||||||
{
|
{
|
||||||
printf2(TAG_ERR, "Update pin fail length\n");
|
printf2(TAG_ERR, "Update pin fail length\n");
|
||||||
|
@ -87,6 +87,24 @@ int device_is_button_pressed();
|
|||||||
*/
|
*/
|
||||||
int ctap_user_presence_test(uint32_t delay);
|
int ctap_user_presence_test(uint32_t delay);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return 2 for disabled, 1 for user is present, 0 user not present, -1 if cancel is requested.
|
||||||
|
/** Test for user presence.
|
||||||
|
* Perform test that user is present. Returns status on user presence. This is used by FIDO and U2F layer
|
||||||
|
* to check if an operation should continue, or if the UP flag should be set.
|
||||||
|
*
|
||||||
|
* @param delay number of milliseconds to delay waiting for user before timeout.
|
||||||
|
* @param button_confirm_colour LED colour while waiting for confirmation.
|
||||||
|
*
|
||||||
|
* @return 2 - User presence is disabled. Operation should continue, but UP flag not set.
|
||||||
|
* 1 - User presence confirmed. Operation should continue, and UP flag is set.
|
||||||
|
* 0 - User presence is not confirmed. Operation should be denied.
|
||||||
|
* -1 - Operation was canceled. Do not continue, reset transaction state.
|
||||||
|
*
|
||||||
|
* *Optional*, the default implementation will return 1, unless a FIDO2 operation calls for no UP, where this will then return 2.
|
||||||
|
*/
|
||||||
|
int ctap_user_presence_test_colour(uint32_t delay, uint32_t button_confirm_colour);
|
||||||
|
|
||||||
/** Disable the next user presence test. This is called by FIDO2 layer when a transaction
|
/** Disable the next user presence test. This is called by FIDO2 layer when a transaction
|
||||||
* requests UP to be disabled. The next call to ctap_user_presence_test should return 2,
|
* requests UP to be disabled. The next call to ctap_user_presence_test should return 2,
|
||||||
* and then UP should be enabled again.
|
* and then UP should be enabled again.
|
||||||
|
13
shell.nix
Normal file
13
shell.nix
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
let
|
||||||
|
nixpkgs_tar = fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/20.03.tar.gz"; sha256 = "0182ys095dfx02vl2a20j1hz92dx3mfgz2a6fhn31bqlp1wa8hlq"; };
|
||||||
|
pkgs = import "${nixpkgs_tar}" {};
|
||||||
|
pyPackages = (python-packages: with python-packages; ([
|
||||||
|
solo-python pytest
|
||||||
|
] ++ (with builtins; map (d: getAttr d python-packages) (filter (d: stringLength d > 0) (pkgs.lib.splitString "\n" (builtins.readFile ./tools/requirements.txt))))));
|
||||||
|
python-with-my-packages = pkgs.python3.withPackages pyPackages;
|
||||||
|
in
|
||||||
|
with pkgs;
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "solo";
|
||||||
|
buildInputs = [ gnumake gcc gcc-arm-embedded-8 python-with-my-packages ];
|
||||||
|
}
|
@ -704,6 +704,10 @@ static int wait_for_button_release(uint32_t wait)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ctap_user_presence_test(uint32_t up_delay)
|
int ctap_user_presence_test(uint32_t up_delay)
|
||||||
|
{
|
||||||
|
return ctap_user_presence_test_colour(up_delay, 0);
|
||||||
|
}
|
||||||
|
int ctap_user_presence_test_colour(uint32_t up_delay, uint32_t button_confirm_colour)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -741,8 +745,7 @@ int ctap_user_presence_test(uint32_t up_delay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set LED status and wait.
|
// Set LED status and wait.
|
||||||
led_rgb(0xff3520);
|
led_rgb(button_confirm_colour==0?0xff3520:button_confirm_colour);
|
||||||
|
|
||||||
// Block and wait for some time.
|
// Block and wait for some time.
|
||||||
ret = wait_for_button_activate(up_delay);
|
ret = wait_for_button_activate(up_delay);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user