Skip to content

Commit

Permalink
Merge pull request #478 from enrikb/feature/ed25519-poc
Browse files Browse the repository at this point in the history
POC: add ed25519 support based on libsodium (PC) or salty (solo).
  • Loading branch information
conorpp authored Jan 28, 2021
2 parents b4b0a05 + 867d5f1 commit 3a21661
Show file tree
Hide file tree
Showing 15 changed files with 240 additions and 56 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "crypto/cifra"]
path = crypto/cifra
url = https://github.com/solokeys/cifra.git
[submodule "crypto/salty"]
path = crypto/salty
url = https://github.com/ycrypto/salty.git
18 changes: 15 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,25 @@ addons:
packages:
- gcc-8
- cppcheck
- libsodium-dev
services:
- docker
before_install:
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
- sudo apt-get update -q
- sudo apt-get install -y gcc-arm-embedded python3-venv
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
- sudo apt-get update -q
- sudo apt-get install -y gcc-arm-embedded python3-venv
- >
set -eu;
url="https://raw.githubusercontent.com/rust-lang/rustup/1.22.1/rustup-init.sh";
wget -O rustup-init.sh "$url";
echo "b273275cf4d83cb6b991c1090baeca54 rustup-init.sh" | md5sum -c -;
echo "8928261388c8fae83bfd79b08d9030dfe21d17a8b59e9dcabda779213f6a3d14 rustup-init.sh" | sha256sum -c -;
bash ./rustup-init.sh --profile=minimal -y -t thumbv7em-none-eabihf;
rm rustup-init.sh;
set +eu
script:
- export CC=gcc-8
- source ${HOME}/.cargo/env
- pyenv shell 3.6.7
- make travis
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ RUN apt-get update \
wget \
bzip2 \
git \
gcc \
libc6-dev \
&& rm -rf /var/lib/apt/lists/*

# Install ARM compiler
Expand Down Expand Up @@ -38,3 +40,16 @@ RUN set -eux; \

# solo-python (Python3.7 script for merging etc.)
RUN pip install -U solo-python

# Rust for salty
ENV RUSTUP_HOME=/rust/rustup
ENV CARGO_HOME=/rust/cargo
RUN set -eux; \
url="https://raw.githubusercontent.com/rust-lang/rustup/1.22.1/rustup-init.sh"; \
wget -O rustup-init.sh "$url"; \
echo "b273275cf4d83cb6b991c1090baeca54 rustup-init.sh" | md5sum -c -; \
echo "8928261388c8fae83bfd79b08d9030dfe21d17a8b59e9dcabda779213f6a3d14 rustup-init.sh" | sha256sum -c -; \
bash ./rustup-init.sh --profile=minimal -y -t thumbv7em-none-eabihf; \
rm rustup-init.sh; \
chmod -R go+rwX /rust

10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ifeq ($(shell uname -s),Darwin)
else
export LDFLAGS = -Wl,--gc-sections
endif
LDFLAGS += $(LIBSOLO) $(LIBCBOR)
LDFLAGS += $(LIBSOLO) $(LIBCBOR) -lsodium


CFLAGS = -O2 -fdata-sections -ffunction-sections -g
Expand All @@ -41,9 +41,12 @@ all: main
tinycbor/Makefile crypto/tiny-AES-c/aes.c:
git submodule update --init

.PHONY: cbor
.PHONY: cbor cborclean
cbor: $(LIBCBOR)

cborclean:
cd tinycbor && $(MAKE) clean

$(LIBCBOR):
cd tinycbor/ && $(MAKE) LDFLAGS='' -j8

Expand All @@ -54,6 +57,7 @@ version:
@git describe

test: venv
$(MAKE) cborclean
$(MAKE) clean
$(MAKE) -C . main
$(MAKE) clean
Expand Down Expand Up @@ -136,4 +140,4 @@ test-docker:
travis:
$(MAKE) test VENV=". ../../venv/bin/activate;"
$(MAKE) test-docker
$(MAKE) black
$(MAKE) black
1 change: 1 addition & 0 deletions crypto/salty
Submodule salty added at 809cdf
4 changes: 4 additions & 0 deletions fido2/cose_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
#define COSE_KEY_LABEL_X -2
#define COSE_KEY_LABEL_Y -3

#define COSE_KEY_KTY_OKP 1
#define COSE_KEY_KTY_EC2 2

#define COSE_KEY_CRV_P256 1
#define COSE_KEY_CRV_ED25519 6

#define COSE_ALG_ES256 -7
#define COSE_ALG_EDDSA -8
#define COSE_ALG_ECDH_ES_HKDF_256 -25

#endif
84 changes: 83 additions & 1 deletion fido2/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// copied, modified, or distributed except according to those terms.
/*
* Wrapper for crypto implementation on device.
*
*
* Can be replaced with different crypto implementation by
* defining EXTERNAL_SOLO_CRYPTO
*
Expand All @@ -31,6 +31,11 @@
#include APP_CONFIG
#include "log.h"

#if defined(STM32L432xx)
#include "salty.h"
#else
#include <sodium/crypto_sign_ed25519.h>
#endif

typedef enum
{
Expand Down Expand Up @@ -358,5 +363,82 @@ void crypto_aes256_encrypt(uint8_t * buf, int length)
AES_CBC_encrypt_buffer(&aes_ctx, buf, length);
}

void crypto_ed25519_derive_public_key(uint8_t * data, int len, uint8_t * x)
{
#if defined(STM32L432xx)

uint8_t seed[salty_SECRETKEY_SEED_LENGTH];

generate_private_key(data, len, NULL, 0, seed);
salty_public_key(&seed, (uint8_t (*)[salty_PUBLICKEY_SERIALIZED_LENGTH])x);

#else

uint8_t seed[crypto_sign_ed25519_SEEDBYTES];
uint8_t sk[crypto_sign_ed25519_SECRETKEYBYTES];

generate_private_key(data, len, NULL, 0, seed);
crypto_sign_ed25519_seed_keypair(x, sk, seed);

#endif
}

void crypto_ed25519_load_key(uint8_t * data, int len)
{
#if defined(STM32L432xx)

static uint8_t seed[salty_SECRETKEY_SEED_LENGTH];

generate_private_key(data, len, NULL, 0, seed);

_signing_key = seed;
_key_len = salty_SECRETKEY_SEED_LENGTH;

#else

uint8_t seed[crypto_sign_ed25519_SEEDBYTES];
uint8_t pk[crypto_sign_ed25519_PUBLICKEYBYTES];
static uint8_t sk[crypto_sign_ed25519_SECRETKEYBYTES];

generate_private_key(data, len, NULL, 0, seed);
crypto_sign_ed25519_seed_keypair(pk, sk, seed);

_signing_key = sk;
_key_len = crypto_sign_ed25519_SECRETKEYBYTES;

#endif
}

void crypto_ed25519_sign(uint8_t * data1, int len1, uint8_t * data2, int len2, uint8_t * sig)
{
// ed25519 signature APIs need the message at once (by design!) and in one
// contiguous buffer (could be changed).

// 512 is an arbitrary sanity limit, could be less
if (len1 < 0 || len2 < 0 || len1 > 512 || len2 > 512)
{
memset(sig, 0, 64); // ed25519 signature len is 64 bytes
return;
}
// XXX: dynamically sized allocation on the stack
const int len = len1 + len2; // 0 <= len <= 1024
uint8_t data[len1 + len2];

memcpy(data, data1, len1);
memcpy(data + len1, data2, len2);

#if defined(STM32L432xx)

// TODO: check that correct load_key() had been called?
salty_sign((uint8_t (*)[salty_SECRETKEY_SEED_LENGTH])_signing_key, data, len,
(uint8_t (*)[salty_SIGNATURE_SERIALIZED_LENGTH])sig);

#else

// TODO: check that correct load_key() had been called?
crypto_sign_ed25519_detached(sig, NULL, data, len, _signing_key);

#endif
}

#endif
3 changes: 3 additions & 0 deletions fido2/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ 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 crypto_ed25519_derive_public_key(uint8_t * data, int len, uint8_t * x);
void crypto_ed25519_sign(uint8_t * data1, int len1, uint8_t * data2, int len2, uint8_t * sig);
void crypto_ed25519_load_key(uint8_t * data, int len);

void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey);
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey);
Expand Down
Loading

0 comments on commit 3a21661

Please sign in to comment.