diff --git a/fido2/crypto.c b/fido2/crypto.c index 67796d7..9dee0d1 100644 --- a/fido2/crypto.c +++ b/fido2/crypto.c @@ -409,8 +409,24 @@ void crypto_ed25519_load_key(uint8_t * data, int len) #endif } -void crypto_ed25519_sign(uint8_t * data, int len, uint8_t * sig) +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? diff --git a/fido2/crypto.h b/fido2/crypto.h index b68df65..e06fc7a 100644 --- a/fido2/crypto.h +++ b/fido2/crypto.h @@ -32,7 +32,7 @@ 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 * sig); +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); diff --git a/fido2/ctap.c b/fido2/ctap.c index 9b89e5f..0a0a65c 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -793,9 +793,7 @@ int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHa // calculate attestation sig if (alg == COSE_ALG_EDDSA) { - // ED25519 signing needs message in one chunk - memmove(data + datalen, clientDataHash, CLIENT_DATA_HASH_SIZE); - crypto_ed25519_sign(data, datalen + CLIENT_DATA_HASH_SIZE, sigder); // not DER, just plain binary! + crypto_ed25519_sign(data, datalen, clientDataHash, CLIENT_DATA_HASH_SIZE, sigder); // not DER, just plain binary! return 64; } else @@ -903,7 +901,7 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt CTAP_makeCredential MC; int ret; unsigned int i; - uint8_t auth_data_buf[310 + CLIENT_DATA_HASH_SIZE]; + uint8_t auth_data_buf[310]; CTAP_credentialDescriptor * excl_cred = (CTAP_credentialDescriptor *) auth_data_buf; uint8_t * sigbuf = auth_data_buf + 32; uint8_t * sigder = auth_data_buf + 32 + 64; diff --git a/fido2/ctap.h b/fido2/ctap.h index 4d06980..c08f936 100644 --- a/fido2/ctap.h +++ b/fido2/ctap.h @@ -360,10 +360,10 @@ typedef struct struct _getAssertionState { - // Room for both authData struct and extensions + clientDataHash for efficient ED25519 signature generation + // Room for both authData struct and extensions struct { CTAP_authDataHeader authData; - uint8_t extensions[80 + CLIENT_DATA_HASH_SIZE]; + uint8_t extensions[80]; } __attribute__((packed)) buf; CTAP_extensions extensions; uint8_t clientDataHash[CLIENT_DATA_HASH_SIZE];