Merge branch 'master' into license-change

This commit is contained in:
Conor Patrick 2019-02-12 17:47:28 -05:00 committed by GitHub
commit 894f6f7ee1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 215 additions and 42 deletions

View File

@ -4,10 +4,12 @@
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdint.h>
#include "extensions.h"
#include "u2f.h"
#include "wallet.h"
#include "solo.h"
#include "device.h"
#include "log.h"
@ -54,6 +56,8 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen
ret = bootloader_bridge(klen, keyh);
#elif defined(WALLET_EXTENSION)
ret = bridge_u2f_to_wallet(_chal, _appid, klen, keyh);
#else
ret = bridge_u2f_to_solo(_chal, _appid, klen, keyh);
#endif
if (ret != 0)

77
fido2/extensions/solo.c Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include <stdint.h>
#include "extensions.h"
#include "u2f.h"
#include "wallet.h"
#include "device.h"
#include "ctap.h"
#include "ctap_errors.h"
#include "log.h"
#include APP_CONFIG
int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint8_t * keyh)
{
static uint8_t msg_buf[72];
int reqlen = klen;
int i;
int8_t ret = 0;
wallet_request * req = (wallet_request *) keyh;
printf1(TAG_WALLET, "u2f-solo [%d]: ", reqlen); dump_hex1(TAG_WALLET, keyh, reqlen);
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);
break;
case WalletRng:
printf1(TAG_WALLET,"SoloRng\n");
ret = ctap_generate_rng(msg_buf, 72);
if (ret != 1)
{
printf1(TAG_WALLET,"Rng failed\n");
ret = CTAP2_ERR_PROCESSING;
goto cleanup;
}
ret = 0;
u2f_response_writeback((uint8_t *)msg_buf,72);
break;
default:
printf2(TAG_ERR,"Invalid wallet command: %x\n",req->operation);
ret = CTAP1_ERR_INVALID_COMMAND;
break;
}
cleanup:
return ret;
}

27
fido2/extensions/solo.h Normal file
View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#ifndef SOLO_H_
#define SOLO_H_
int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint8_t * keyh);
#endif

View File

@ -2,30 +2,33 @@ ifndef DEBUG
DEBUG=0
endif
APPMAKE=build/application.mk
BOOTMAKE=build/application.mk
merge_hex=python ../../tools/solotool.py mergehex
all:
$(MAKE) -f application.mk -j8 solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DFLASH_ROP=1'
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DFLASH_ROP=1'
all-hacker:
$(MAKE) -f application.mk -j8 solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'
all-locked:
$(MAKE) -f application.mk -j8 solo.hex PREFIX=$(PREFIX) EXTRA_DEFINES='-DFLASH_ROP=2'
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) EXTRA_DEFINES='-DFLASH_ROP=2'
debugboot-app:
$(MAKE) -f application.mk -j8 solo.hex DEBUG=2 PREFIX=$(PREFIX)\
$(MAKE) -f $(APPMAKE) -j8 solo.hex DEBUG=2 PREFIX=$(PREFIX)\
LDSCRIPT=linker/stm32l4xx_extra.ld EXTRA_DEFINES='-DAPPLICATION_START_PAGE=16 -DSOLO_HACKER'
debugboot-boot:
$(MAKE) -f bootloader.mk -j8 bootloader.hex PREFIX=$(PREFIX) DEBUG=1 \
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) DEBUG=1 \
LDSCRIPT=linker/bootloader_stm32l4xx_extra.ld EXTRA_DEFINES='-DAPPLICATION_START_PAGE=16 -DSOLO_HACKER'
boot-sig-checking:
$(MAKE) -f bootloader.mk -j8 bootloader.hex PREFIX=$(PREFIX) DEBUG=0
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) DEBUG=0
boot-no-sig:
$(MAKE) -f bootloader.mk -j8 bootloader.hex PREFIX=$(PREFIX) EXTRA_DEFINES='-DSOLO_HACKER' DEBUG=0
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) EXTRA_DEFINES='-DSOLO_HACKER' DEBUG=0
build-release-locked: clean2 boot-sig-checking clean all-locked
$(merge_hex) solo.hex bootloader.hex all.hex
@ -38,12 +41,12 @@ build-hacker: clean2 boot-no-sig clean all-hacker
$(merge_hex) solo.hex bootloader.hex all.hex
clean:
$(MAKE) -f application.mk clean
$(MAKE) -f bootloader.mk clean
$(MAKE) -f $(APPMAKE) clean
$(MAKE) -f $(BOOTMAKE) clean
clean2:
rm -f solo.hex bootloader.hex all.hex
$(MAKE) -f application.mk clean
$(MAKE) -f bootloader.mk clean
$(MAKE) -f $(APPMAKE) clean
$(MAKE) -f $(BOOTMAKE) clean
flash: solo.hex bootloader.hex

View File

@ -4,6 +4,7 @@
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdint.h>
#include <stdlib.h>
@ -176,8 +177,12 @@ int bootloader_bridge(int klen, uint8_t * keyh)
case BootVersion:
has_erased = 0;
printf1(TAG_BOOT, "BootVersion.\r\n");
version = BOOT_VERSION_MAJ;
u2f_response_writeback(&version,1);
version = BOOT_VERSION_MIN;
u2f_response_writeback(&version,1);
version = BOOT_VERSION_PATCH;
u2f_response_writeback(&version,1);
return 0;
break;
case BootReboot:
printf1(TAG_BOOT, "BootReboot.\r\n");

View File

@ -4,9 +4,11 @@
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#ifndef _APP_H_
#define _APP_H_
#include <stdint.h>
#include "version.h"
#define DEBUG_UART USART1
@ -50,6 +52,8 @@
#define SKIP_BUTTON_CHECK_WITH_DELAY 0
#define SKIP_BUTTON_CHECK_FAST 1
#define SOLO_PRODUCT_NAME "Solo Bootloader " VERSION
void printing_init();
void hw_init(void);

View File

@ -1,7 +1,4 @@
CC=$(PREFIX)arm-none-eabi-gcc
CP=$(PREFIX)arm-none-eabi-objcopy
SZ=$(PREFIX)arm-none-eabi-size
AR=$(PREFIX)arm-none-eabi-ar
include build/common.mk
# ST related
SRC = src/main.c src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c
@ -13,6 +10,7 @@ SRC += $(wildcard lib/*.c) $(wildcard lib/usbd/*.c)
SRC += ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c
SRC += ../../fido2/ctap_parse.c ../../fido2/main.c
SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c
# Crypto libs
SRC += ../../crypto/sha256/sha256.c ../../crypto/micro-ecc/uECC.c ../../crypto/tiny-AES-c/aes.c
@ -45,7 +43,7 @@ endif
DEFINES = -DDEBUG_LEVEL=$(DEBUG) -D$(CHIP) -DAES256=1 -DUSE_FULL_LL_DRIVER -DAPP_CONFIG=\"app.h\" $(EXTRA_DEFINES)
# DEFINES += -DTEST_SOLO_STM32 -DTEST -DTEST_FIFO=1
CFLAGS=$(INC) -c $(DEFINES) -Wall -fdata-sections -ffunction-sections $(HW) -g
CFLAGS=$(INC) -c $(DEFINES) -Wall -fdata-sections -ffunction-sections $(HW) -g $(VERSION_FLAGS)
LDFLAGS_LIB=$(HW) $(SEARCH) -specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -u _printf_float -lnosys
LDFLAGS=$(HW) $(LDFLAGS_LIB) -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref -Wl,-Bstatic -ltinycbor

View File

@ -1,7 +1,4 @@
CC=$(PREFIX)arm-none-eabi-gcc
CP=$(PREFIX)arm-none-eabi-objcopy
SZ=$(PREFIX)arm-none-eabi-size
AR=$(PREFIX)arm-none-eabi-ar
include build/common.mk
# ST related
SRC = bootloader/main.c bootloader/bootloader.c
@ -44,9 +41,9 @@ endif
DEFINES = -DDEBUG_LEVEL=$(DEBUG) -D$(CHIP) -DAES256=1 -DUSE_FULL_LL_DRIVER -DAPP_CONFIG=\"bootloader.h\" $(EXTRA_DEFINES)
# DEFINES += -DTEST_SOLO_STM32 -DTEST -DTEST_FIFO=1
CFLAGS=$(INC) -c $(DEFINES) -Wall -fdata-sections -ffunction-sections $(HW) -g
CFLAGS=$(INC) -c $(DEFINES) -Wall -fdata-sections -ffunction-sections $(HW) -g $(VERSION_FLAGS)
LDFLAGS_LIB=$(HW) $(SEARCH) -specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -lnosys
LDFLAGS=$(HW) $(LDFLAGS_LIB) -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref -Wl,-Bstatic
LDFLAGS=$(HW) $(LDFLAGS_LIB) -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref -Wl,-Bstatic
.PRECIOUS: %.o

View File

@ -0,0 +1,19 @@
CC=$(PREFIX)arm-none-eabi-gcc
CP=$(PREFIX)arm-none-eabi-objcopy
SZ=$(PREFIX)arm-none-eabi-size
AR=$(PREFIX)arm-none-eabi-ar
VERSION=$(shell git describe --abbrev=0 )
VERSION_FULL=$(shell git describe)
VERSION_MAJ=$(shell python -c 'print("$(VERSION)".split(".")[0])')
VERSION_MIN=$(shell python -c 'print("$(VERSION)".split(".")[1])')
VERSION_PAT=$(shell python -c 'print("$(VERSION)".split(".")[2])')
VERSION_FLAGS= -DSOLO_VERSION_MAJ=$(VERSION_MAJ) -DSOLO_VERSION_MIN=$(VERSION_MIN) \
-DSOLO_VERSION_PATCH=$(VERSION_PAT) -DVERSION=\"$(VERSION_FULL)\"
_all:
echo $(VERSION_FULL)
echo $(VERSION_MAJ)
echo $(VERSION_MIN)
echo $(VERSION_PAT)

View File

@ -53,19 +53,10 @@
#define USBD_VID 0x0483
#define USBD_PID 0xA2CA
#define USBD_LANGID_STRING 0x409
#ifndef SOLO_HACKER
#define USBD_MANUFACTURER_STRING "Solo Keys"
#define USBD_PRODUCT_FS_STRING "Solo"
#ifndef USBD_SERIAL_NUM
#define USBD_MANUFACTURER_STRING "SoloKeys"
#define USBD_PRODUCT_FS_STRING SOLO_PRODUCT_NAME
#define USBD_SERIAL_NUM "0123456789ABCDEF"
#endif
#else
#define USBD_MANUFACTURER_STRING "Solo Keys"
#define USBD_PRODUCT_FS_STRING "Solo HACKER (Unlocked)"
#ifndef USBD_SERIAL_NUM
#define USBD_SERIAL_NUM "0123456789ABCDEF"
#endif
#endif
uint8_t *USBD_HID_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_HID_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);

View File

@ -7,6 +7,7 @@
#ifndef _APP_H_
#define _APP_H_
#include <stdint.h>
#include "version.h"
#define DEBUG_UART USART1
@ -21,7 +22,7 @@
//#define USING_DEV_BOARD
//#define ENABLE_U2F_EXTENSIONS
#define ENABLE_U2F_EXTENSIONS
#define ENABLE_U2F
@ -29,6 +30,13 @@
// #define DISABLE_CTAPHID_WINK
// #define DISABLE_CTAPHID_CBOR
#if defined(SOLO_HACKER)
#define SOLO_PRODUCT_NAME "Solo Hacker " VERSION
#else
#define SOLO_PRODUCT_NAME "Solo " VERSION
#endif
void printing_init();
void hw_init(void);

View File

@ -0,0 +1,21 @@
#ifndef _VERSION_H_
#define _VERSION_H_
#ifndef SOLO_VERSION_MAJ
#define SOLO_VERSION_MAJ 0
#define SOLO_VERSION_MIN 0
#define SOLO_VERSION_PATCH 0
#endif
#define __STR_HELPER(x) #x
#define __STR(x) __STR_HELPER(x)
#ifndef VERSION
#define VERSION __STR(SOLO_VERSION_MAJ) "." __STR(SOLO_VERSION_MIN) "." __STR(SOLO_VERSION_PATCH)
#endif
#endif

View File

@ -90,6 +90,9 @@ def get_firmware_object(sk_name, hex_file):
msg = {'firmware': fw, 'signature': sig}
return msg
class SoloExtension:
version= 0x14
rng = 0x15
class SoloBootloader:
write = 0x40
@ -196,10 +199,16 @@ class SoloClient:
return res.signature[1:]
def version(self,):
def bootloader_version(self,):
data = self.exchange(SoloBootloader.version)
if len(data) > 2:
return (data[0],data[1],data[2])
return data[0]
def solo_version(self,):
data = self.exchange_u2f(SoloExtension.version)
return (data[0],data[1],data[2])
def write_flash(self, addr, data):
self.exchange(SoloBootloader.write, addr, data)
@ -256,7 +265,7 @@ class SoloClient:
def is_solo_bootloader(self,):
try:
self.version()
self.bootloader_version()
return True
except CtapError as e:
if e.code == CtapError.ERR.INVALID_COMMAND:
@ -583,7 +592,7 @@ def solo_main():
)
parser.add_argument("--wink", action="store_true", help='HID Wink command.')
parser.add_argument("--reset", action="store_true", help='Issue a FIDO2 reset command. Warning: your credentials will be lost.')
parser.add_argument("--verify-solo", action="store_true", help='Verify that the Solo firmware is from SoloKeys.')
parser.add_argument("--verify-solo", action="store_true", help='Verify that the Solo firmware is from SoloKeys. Check firmware version.')
args = parser.parse_args()
p = SoloClient()
@ -604,12 +613,22 @@ def solo_main():
if args.verify_solo:
cert = p.make_credential()
solo_fingerprint = b'r\xd5\x831&\xac\xfc\xe9\xa8\xe8&`\x18\xe6AI4\xc8\xbeJ\xb8h_\x91\xb0\x99!\x13\xbb\xd42\x95'
hacker_fingerprint = b"\xd0ml\xcb\xda}\xe5j\x16'\xc2\xa7\x89\x9c5\xa2\xa3\x16\xc8Q\xb3j\xd8\xed~\xd7\x84y\xbbx~\xf7"
if (cert.fingerprint(hashes.SHA256()) == solo_fingerprint):
print('Valid firmware from SoloKeys')
print('Valid SOLO firmware from SoloKeys')
elif (cert.fingerprint(hashes.SHA256()) == hacker_fingerprint):
print('Valid HACKER firmware')
else:
print('This is either a Solo Hacker or a invalid Solo.')
print('Unknown fingerprint! ', cert.fingerprint(hashes.SHA256()))
try:
v = p.solo_version()
print('Version: ', v)
except ApduError:
print('Firmware is out of date.')
def asked_for_help():
@ -909,7 +928,7 @@ def programmer_main():
sys.exit(1)
try:
p.version()
p.bootloader_version()
except CtapError as e:
if e.code == CtapError.ERR.INVALID_COMMAND:
print('Bootloader not active. Attempting to boot into bootloader mode...')