Skip to content

Commit

Permalink
Merge pull request #111 from solokeys/fido2-ext
Browse files Browse the repository at this point in the history
Fido2 ext
  • Loading branch information
conorpp authored Feb 17, 2019
2 parents c986297 + 46d7be8 commit ed6da0b
Show file tree
Hide file tree
Showing 20 changed files with 212 additions and 55 deletions.
5 changes: 4 additions & 1 deletion 99-solo.rules
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ LABEL="mm_usb_device_blacklist_end"

# Solo

## access
## bootloader + firmware access
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev"

## DFU access
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", TAG+="uaccess", GROUP="plugdev"

## Solo Secure symlink
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo [1-9]*", SYMLINK+="solokey"
## Solo Hacker symlink
Expand Down
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,4 @@ RUN ln -s /opt/conda/bin/python3 /usr/local/bin/python3
RUN ln -s /opt/conda/bin/python3 /usr/local/bin/python

# 3. Source code
RUN git clone --recurse-submodules https://github.com/solokeys/solo /solo

RUN git clone --recurse-submodules https://github.com/solokeys/solo /solo --config core.autocrlf=input
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ fido2-test: venv
venv/bin/python tools/ctap_test.py

DOCKER_IMAGE := "solokeys/solo-firmware:local"
SOLO_VERSION := "master"
SOLO_VERSIONISH := "master"
docker-build:
docker build -t $(DOCKER_IMAGE) .
docker run --rm -v$(PWD)/builds:/builds -v$(PWD)/docker-build.sh:/build.sh $(DOCKER_IMAGE) /build.sh $(SOLO_VERSION)
docker run --rm -v "$(CURDIR)/builds:/builds" \
-v "$(CURDIR)/in-docker-build.sh:/in-docker-build.sh" \
$(DOCKER_IMAGE) /in-docker-build.sh $(SOLO_VERSIONISH)

CPPCHECK_FLAGS=--quiet --error-exitcode=2

Expand Down
21 changes: 0 additions & 21 deletions docker-build.sh

This file was deleted.

43 changes: 39 additions & 4 deletions fido2/ctap.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "device.h"
#include APP_CONFIG
#include "wallet.h"
#include "extensions.h"

#include "device.h"

Expand Down Expand Up @@ -776,7 +777,18 @@ int ctap_filter_invalid_credentials(CTAP_getAssertion * GA)
if (! ctap_authenticate_credential(&GA->rp, &GA->creds[i]))
{
printf1(TAG_GA, "CRED #%d is invalid\n", GA->creds[i].credential.id.count);
GA->creds[i].credential.id.count = 0; // invalidate
#ifdef ENABLE_U2F_EXTENSIONS
if (is_extension_request((uint8_t*)&GA->creds[i].credential.id, sizeof(CredentialId)))
{
printf1(TAG_EXT, "CRED #%d is extension\n", GA->creds[i].credential.id.count);
count++;
}
else
#endif
{
GA->creds[i].credential.id.count = 0; // invalidate
}

}
else
{
Expand Down Expand Up @@ -856,6 +868,7 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
int ret;
uint8_t sigbuf[64];
uint8_t sigder[72];
int sigder_sz;

if (add_user)
{
Expand All @@ -869,7 +882,16 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr

crypto_ecc256_load_key((uint8_t*)&cred->credential.id, sizeof(CredentialId), NULL, 0);

int sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
#ifdef ENABLE_U2F_EXTENSIONS
if ( extend_fido2(&cred->credential.id, sigder) )
{
sigder_sz = 72;
}
else
#endif
{
sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
}

{
ret = cbor_encode_int(map, RESP_signature);
Expand Down Expand Up @@ -988,8 +1010,21 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
ret = cbor_encoder_create_map(encoder, &map, map_size);
check_ret(ret);

ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0,NULL, 0);
check_retr(ret);
#ifdef ENABLE_U2F_EXTENSIONS
if ( is_extension_request((uint8_t*)&GA.creds[validCredCount - 1].credential.id, sizeof(CredentialId)) )
{
ret = cbor_encode_int(&map,RESP_authData);
check_ret(ret);
memset(auth_data_buf,0,sizeof(auth_data_buf));
ret = cbor_encode_byte_string(&map, auth_data_buf, sizeof(auth_data_buf));
check_ret(ret);
}
else
#endif
{
ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0,NULL, 0);
check_retr(ret);
}

/*for (int j = 0; j < GA.credLen; j++)*/
/*{*/
Expand Down
23 changes: 20 additions & 3 deletions fido2/extensions/extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stdint.h>
#include "extensions.h"
#include "u2f.h"
#include "ctap.h"
#include "wallet.h"
#include "solo.h"
#include "device.h"
Expand Down Expand Up @@ -57,7 +58,8 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen
#elif defined(WALLET_EXTENSION)
ret = bridge_u2f_to_wallet(_chal, _appid, klen, keyh);
#else
ret = bridge_u2f_to_solo(_chal, _appid, klen, keyh);
ret = bridge_u2f_to_solo(sig, keyh, klen);
u2f_response_writeback(sig,72);
#endif

if (ret != 0)
Expand All @@ -74,6 +76,21 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen
return U2F_SW_NO_ERROR;
}

// Returns 1 if this is a extension request.
// Else 0 if nothing is done.
int16_t extend_fido2(CredentialId * credid, uint8_t * output)
{
if (is_extension_request((uint8_t*)credid, sizeof(CredentialId)))
{
output[0] = bridge_u2f_to_solo(output+1, (uint8_t*)credid, sizeof(CredentialId));
return 1;
}
else
{
return 0;
}
}

int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
{

Expand All @@ -93,7 +110,7 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
{
rcode = U2F_SW_WRONG_DATA;
}
printf1(TAG_EXT,"Ignoring U2F request\n");
printf1(TAG_EXT,"Ignoring U2F check request\n");
dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl);
goto end;
}
Expand All @@ -102,7 +119,7 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
if ( ! is_extension_request((uint8_t *) &auth->kh, auth->khl)) // Pin requests
{
rcode = U2F_SW_WRONG_PAYLOAD;
printf1(TAG_EXT, "Ignoring U2F request\n");
printf1(TAG_EXT, "Ignoring U2F auth request\n");
dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl);
goto end;
}
Expand Down
4 changes: 4 additions & 0 deletions fido2/extensions/extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len);

int16_t extend_fido2(CredentialId * credid, uint8_t * output);

int bootloader_bridge(int klen, uint8_t * keyh);

int is_extension_request(uint8_t * kh, int len);

#endif /* EXTENSIONS_H_ */
16 changes: 7 additions & 9 deletions fido2/extensions/solo.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,26 @@
#include "log.h"
#include APP_CONFIG

int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint8_t * keyh)
// output must be at least 71 bytes
int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen)
{
static uint8_t msg_buf[72];
int8_t ret = 0;

wallet_request * req = (wallet_request *) keyh;

printf1(TAG_WALLET, "u2f-solo [%d]: ", klen); dump_hex1(TAG_WALLET, keyh, klen);
printf1(TAG_WALLET, "u2f-solo [%d]: ", keylen); dump_hex1(TAG_WALLET, keyh, keylen);

switch(req->operation)
{
case WalletVersion:
msg_buf[0] = SOLO_VERSION_MAJ;
msg_buf[1] = SOLO_VERSION_MIN;
msg_buf[2] = SOLO_VERSION_PATCH;
u2f_response_writeback(msg_buf, 3);
output[0] = SOLO_VERSION_MAJ;
output[1] = SOLO_VERSION_MIN;
output[2] = SOLO_VERSION_PATCH;
break;
case WalletRng:
printf1(TAG_WALLET,"SoloRng\n");

ret = ctap_generate_rng(msg_buf, 72);
ret = ctap_generate_rng(output, 71);
if (ret != 1)
{
printf1(TAG_WALLET,"Rng failed\n");
Expand All @@ -60,7 +59,6 @@ int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint
}
ret = 0;

u2f_response_writeback((uint8_t *)msg_buf,72);
break;

default:
Expand Down
2 changes: 1 addition & 1 deletion fido2/extensions/solo.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
#ifndef SOLO_H_
#define SOLO_H_

int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint8_t * keyh);
int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen);

#endif
2 changes: 1 addition & 1 deletion fido2/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct logtag tagtable[] = {
{TAG_WALLET,"WALLET"},
{TAG_STOR,"STOR"},
{TAG_BOOT,"BOOT"},
{TAG_BOOT,"[1;37mEXT[0m"},
{TAG_EXT,"[1;37mEXT[0m"},
};


Expand Down
2 changes: 1 addition & 1 deletion fido2/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ typedef enum
TAG_STOR = (1 << 15),
TAG_DUMP2 = (1 << 16),
TAG_BOOT = (1 << 17),
TAG_EXT = (1 << 17),
TAG_EXT = (1 << 18),

TAG_FILENO = (1u << 31)
} LOG_TAG;
Expand Down
6 changes: 3 additions & 3 deletions fido2/u2f.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp)
#ifdef ENABLE_U2F_EXTENSIONS
rcode = extend_u2f(req, len);
#endif
if (rcode != U2F_SW_NO_ERROR) // If the extension didn't do anything...
if (rcode != U2F_SW_NO_ERROR && rcode != U2F_SW_CONDITIONS_NOT_SATISFIED) // If the extension didn't do anything...
{
#ifdef ENABLE_U2F
switch(req->ins)
Expand Down Expand Up @@ -224,7 +224,7 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
}

count = ctap_atomic_count(0);
hash[0] = (count >> 24) & 0xff;
hash[0] = 0xff;
hash[1] = (count >> 16) & 0xff;
hash[2] = (count >> 8) & 0xff;
hash[3] = (count >> 0) & 0xff;
Expand All @@ -241,7 +241,7 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
crypto_ecc256_sign(hash, 32, sig);

u2f_response_writeback(&up,1);
hash[0] = (count >> 24) & 0xff;
hash[0] = 0xff;
hash[1] = (count >> 16) & 0xff;
hash[2] = (count >> 8) & 0xff;
hash[3] = (count >> 0) & 0xff;
Expand Down
37 changes: 37 additions & 0 deletions in-docker-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash -xe

version=${1:-master}

export PREFIX=/opt/gcc-arm-none-eabi-8-2018-q4-major/bin/

cd /solo/targets/stm32l432
git fetch
git checkout ${version}
version=$(git describe)

make cbor

out_dir="/builds"

function build() {
part=${1}
variant=${2}
output=${3:-${part}}
what="${part}-${variant}"

make full-clean

make ${what}

out_hex="${what}-${version}.hex"
out_sha2="${what}-${version}.sha2"

mv ${output}.hex ${out_hex}
sha256sum ${out_hex} > ${out_sha2}
cp ${out_hex} ${out_sha2} ${out_dir}
}

build bootloader nonverifying
build bootloader verifying
build firmware hacker solo
build firmware secure solo
19 changes: 19 additions & 0 deletions targets/stm32l432/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ merge_hex=../../tools/solotool.py mergehex

.PHONY: all all-hacker all-locked debugboot-app debugboot-boot boot-sig-checking boot-no-sig build-release-locked build-release build-release build-hacker build-debugboot clean clean2 flash flash_dfu flashboot detach cbor test


# The following are the main targets for reproducible builds.
# TODO: better explanation
firmware-hacker:
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'

firmware-secure:
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DUSE_SOLOKEYS_CERT -DFLASH_ROP=2'

bootloader-nonverifying:
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) EXTRA_DEFINES='-DSOLO_HACKER' DEBUG=0

bootloader-verifying:
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) DEBUG=0

full-clean: clean2


# The older targets, may be re-organised
all:
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DFLASH_ROP=1'

Expand Down
2 changes: 1 addition & 1 deletion targets/stm32l432/build/application.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include build/common.mk
SRC = src/main.c src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c
SRC += src/fifo.c src/crypto.c src/attestation.c
SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c
SRC += $(wildcard lib/*.c) $(wildcard lib/usbd/*.c)
SRC += $(DRIVER_LIBS) $(USB_LIB)

# FIDO2 lib
SRC += ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
Expand Down
2 changes: 1 addition & 1 deletion targets/stm32l432/build/bootloader.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SRC = bootloader/main.c bootloader/bootloader.c
SRC += src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c
SRC += src/fifo.c src/crypto.c src/attestation.c
SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c
SRC += $(wildcard lib/*.c) $(wildcard lib/usbd/*.c)
SRC += $(DRIVER_LIBS) $(USB_LIB)

# FIDO2 lib
SRC += ../../fido2/util.c ../../fido2/u2f.c ../../fido2/extensions/extensions.c
Expand Down
Loading

0 comments on commit ed6da0b

Please sign in to comment.