mirror of
https://github.com/CovidBraceletPrj/CovidBracelet.git
synced 2025-01-08 04:14:25 +01:00
Use PlatformIO Exposure Notification Library
This commit is contained in:
parent
af833f58d2
commit
8dc0dd74e4
@ -1,52 +0,0 @@
|
|||||||
#include "exposure-notification.h"
|
|
||||||
#include "time.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
|
|
||||||
// first init everything
|
|
||||||
// TODO: More randomization, we init with NULL to let en init mbdet entropy for us
|
|
||||||
en_init(NULL);
|
|
||||||
|
|
||||||
// get the currentTime
|
|
||||||
time_t currentTime = time(NULL);
|
|
||||||
|
|
||||||
// The periodKey changes each EN_TEK_ROLLING_PERIOD intervals
|
|
||||||
ENIntervalNumber periodInterval = en_get_interval_number_at_period_start(currentTime);
|
|
||||||
|
|
||||||
ENPeriodKey periodKey;
|
|
||||||
ENPeriodIdentifierKey periodIdentifierKey;
|
|
||||||
ENPeriodMetadataEncryptionKey periodMetadaEncryptionKey;
|
|
||||||
|
|
||||||
// setup period keys at the beginning
|
|
||||||
// in theory you could let them generate automatically setting periodInterval to 0
|
|
||||||
en_generate_and_derive_period_keys(&periodKey, &periodIdentifierKey, &periodMetadaEncryptionKey);
|
|
||||||
|
|
||||||
char metadata[128] = "";
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
// we check the current time to know if we actually need to regenerate anything
|
|
||||||
currentTime = time(NULL);
|
|
||||||
ENIntervalNumber currentInterval = en_get_interval_number(currentTime);
|
|
||||||
|
|
||||||
// we check if we need to generate new keys
|
|
||||||
if (currentInterval - periodInterval >= EN_TEK_ROLLING_PERIOD) {
|
|
||||||
periodInterval = en_get_interval_number_at_period_start(currentTime);
|
|
||||||
en_generate_and_derive_period_keys(&periodKey, &periodIdentifierKey, &periodMetadaEncryptionKey);
|
|
||||||
// TODO: Store new periodKey with periodInterval
|
|
||||||
}
|
|
||||||
|
|
||||||
// we now generate the new interval identifier and re-encrypt the metadata
|
|
||||||
ENIntervalIdentifier intervalIdentifier;
|
|
||||||
en_derive_interval_identifier(&intervalIdentifier, &periodIdentifierKey, currentInterval);
|
|
||||||
|
|
||||||
char encryptedMetadata[sizeof(metadata)];
|
|
||||||
en_encrypt_interval_metadata(&periodMetadaEncryptionKey, &intervalIdentifier, metadata, encryptedMetadata, sizeof(metadata));
|
|
||||||
|
|
||||||
// broadcast intervalIdentifier plus encryptedMetada according to specs
|
|
||||||
// TODO: receive packets and store them
|
|
||||||
// repeat for 10-20 minutes
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,170 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Patrick Rathje
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EXPOSURE_NOTIFICATION_H
|
|
||||||
#define EXPOSURE_NOTIFICATION_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifndef EN_TEK_ROLLING_PERIOD
|
|
||||||
#define EN_TEK_ROLLING_PERIOD 144
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef EN_INTERVAL_LENGTH
|
|
||||||
#define EN_INTERVAL_LENGTH 600
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EN_INIT_MBEDTLS_ENTROPY
|
|
||||||
#define EN_INIT_MBEDTLS_ENTROPY 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type: _ENBaseKey
|
|
||||||
* --------------------
|
|
||||||
* 16 Byte base key definition
|
|
||||||
*/
|
|
||||||
typedef struct _ENBaseKey { unsigned char b[16];} _ENBaseKey;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type: ENIntervalNumber
|
|
||||||
* --------------------
|
|
||||||
* The number of the 10 minute interval
|
|
||||||
*/
|
|
||||||
typedef uint32_t ENIntervalNumber;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type: ENPeriodKey
|
|
||||||
* --------------------
|
|
||||||
* 16 Byte temporary exposure key used throughout a rolling period (one day)
|
|
||||||
*/
|
|
||||||
typedef struct _ENBaseKey ENPeriodKey;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type: ENPeriodIdentifierKey
|
|
||||||
* --------------------
|
|
||||||
* 16 Byte key used throughout each period to encrypt the identifier for each interval
|
|
||||||
*/
|
|
||||||
typedef struct _ENBaseKey ENPeriodIdentifierKey;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type: ENIntervalIdentifier
|
|
||||||
* --------------------
|
|
||||||
* 16 Byte identifier used within the packet
|
|
||||||
*/
|
|
||||||
typedef struct _ENBaseKey ENIntervalIdentifier;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type: ENPeriodMetadataEncryptionKey
|
|
||||||
* --------------------
|
|
||||||
* 16 Byte key used throughout each interval to encrypt the metadata within one period
|
|
||||||
*/
|
|
||||||
typedef struct _ENBaseKey ENPeriodMetadataEncryptionKey;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type: ENPeriodMetadataEncryptionKey
|
|
||||||
* --------------------
|
|
||||||
* 16 Byte key used throughout each interval to encrypt the metadata within one period
|
|
||||||
*/
|
|
||||||
typedef struct _ENBaseKey ENPeriodMetadataEncryptionKey;
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (*ENRandomBytesCallback)(void *buf, size_t len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_init
|
|
||||||
* --------------------
|
|
||||||
* Initializes the random number generator. Use NULL to initialize with the fallback random_bytes_func
|
|
||||||
*/
|
|
||||||
int en_init(ENRandomBytesCallback user_random_bytes_callback);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_get_interval_number
|
|
||||||
* --------------------
|
|
||||||
* computes the interval number according to the given unix timestamp. Each interval lasts for EN_INTERVAL_LENGTH secs (defaults to 10 minutes).
|
|
||||||
*/
|
|
||||||
ENIntervalNumber en_get_interval_number(time_t timestamp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_get_period_start_interval_number
|
|
||||||
* --------------------
|
|
||||||
* computes the first interval number for the period given by the unix timestamp.
|
|
||||||
*/
|
|
||||||
ENIntervalNumber en_get_interval_number_at_period_start(time_t timestamp);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_generate_period_key
|
|
||||||
* --------------------
|
|
||||||
* Generates a new period key using a cryptographic number generator. Used when the next period is dues (once a day).
|
|
||||||
*/
|
|
||||||
void en_generate_period_key(ENPeriodKey* periodKey);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_derive_period_identifier_key
|
|
||||||
* --------------------
|
|
||||||
* Derives the interval identifier key based on the current period key
|
|
||||||
*/
|
|
||||||
void en_derive_period_identifier_key(ENPeriodIdentifierKey *periodIdentifierKey, const ENPeriodKey *periodKey);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_derive_interval_identifier
|
|
||||||
* --------------------
|
|
||||||
* Get the identifier for a specific interval based on the identifierKey
|
|
||||||
*/
|
|
||||||
void en_derive_interval_identifier(ENIntervalIdentifier *intervalIdentifier, const ENPeriodIdentifierKey *periodIdentifierKey, const ENIntervalNumber intervalNumber);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_derive_period_metadata_encryption_key
|
|
||||||
* --------------------
|
|
||||||
* Derives the interval metadata encryption key based on the current period key
|
|
||||||
*/
|
|
||||||
void en_derive_period_metadata_encryption_key(ENPeriodMetadataEncryptionKey *periodMetadataEncryptionKey, const ENPeriodKey *periodKey);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_encrypt_interval_metadata
|
|
||||||
* --------------------
|
|
||||||
* Encrypts the metadata.
|
|
||||||
*/
|
|
||||||
void en_encrypt_interval_metadata(const ENPeriodMetadataEncryptionKey *periodMetadataEncryptionKey, const ENIntervalIdentifier *intervalIdentifier, unsigned char *input, unsigned char *output, size_t inputSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_decrypt_interval_metadata
|
|
||||||
* --------------------
|
|
||||||
* Decrypts the metadata.
|
|
||||||
*/
|
|
||||||
void en_decrypt_interval_metadata(const ENPeriodMetadataEncryptionKey *periodMetadataEncryptionKey, const ENIntervalIdentifier *intervalIdentifier, unsigned char *input, unsigned char *output, size_t inputSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: en_generate_period_relevant_keys()
|
|
||||||
* --------------------
|
|
||||||
* This function generates all period keys at once (convenient right?)
|
|
||||||
*/
|
|
||||||
static inline void en_generate_and_derive_period_keys(ENPeriodKey *periodKey, ENPeriodIdentifierKey *periodIdentifierKey, ENPeriodMetadataEncryptionKey *periodMetadataEncryptionKey) {
|
|
||||||
en_generate_period_key(periodKey);
|
|
||||||
en_derive_period_identifier_key(periodIdentifierKey, periodKey);
|
|
||||||
en_derive_period_metadata_encryption_key(periodMetadataEncryptionKey, periodKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"description": "exposure-notification",
|
|
||||||
"frameworks": "*",
|
|
||||||
"keywords": "exposure, notification, contact, tracking, tracing",
|
|
||||||
"name": "exposure-notification",
|
|
||||||
"platforms": "*",
|
|
||||||
"version": "0.1",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "mbedtls",
|
|
||||||
"version": "^2.16.4"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Patrick Rathje
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#if EN_INCLUDE_ZEPHYR_DEPS
|
|
||||||
#include <zephyr.h>
|
|
||||||
#include <zephyr/types.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <sys/printk.h>
|
|
||||||
#include <sys/util.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "mbedtls/entropy.h"
|
|
||||||
#include "mbedtls/ctr_drbg.h"
|
|
||||||
#include "mbedtls/hkdf.h"
|
|
||||||
#include "mbedtls/sha256.h"
|
|
||||||
#include "mbedtls/aes.h"
|
|
||||||
|
|
||||||
#include "exposure-notification.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static mbedtls_ctr_drbg_context ctr_drbg;
|
|
||||||
static ENRandomBytesCallback random_bytes_callback = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
int en_mbedtls_random_bytes_fallback(void *buf, size_t len) {
|
|
||||||
return mbedtls_ctr_drbg_random(&ctr_drbg, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if EN_INIT_MBEDTLS_ENTROPY
|
|
||||||
int init_mbedtls_entropy() {
|
|
||||||
mbedtls_entropy_context entropy;
|
|
||||||
mbedtls_entropy_init( &entropy );
|
|
||||||
|
|
||||||
static char *personalization = "exposure-notification";
|
|
||||||
|
|
||||||
mbedtls_ctr_drbg_init( &ctr_drbg );
|
|
||||||
|
|
||||||
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, &entropy,
|
|
||||||
(const unsigned char *) personalization,
|
|
||||||
strlen( personalization ) );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
int en_init(ENRandomBytesCallback user_random_bytes_callback) {
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
|
|
||||||
#if EN_INIT_MBEDTLS_ENTROPY
|
|
||||||
ret = init_mbedtls_entropy();
|
|
||||||
#endif
|
|
||||||
// Fallback to mbedtls random bytes implementation and init the entropy
|
|
||||||
if (user_random_bytes_callback == NULL) {
|
|
||||||
random_bytes_callback = en_mbedtls_random_bytes_fallback;
|
|
||||||
} else {
|
|
||||||
random_bytes_callback = user_random_bytes_callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ENIntervalNumber en_get_interval_number(time_t timestamp) {
|
|
||||||
return timestamp / EN_INTERVAL_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
ENIntervalNumber en_get_interval_number_at_period_start(time_t timestamp) {
|
|
||||||
ENIntervalNumber current = en_get_interval_number(timestamp);
|
|
||||||
// round to period start
|
|
||||||
return (current/EN_TEK_ROLLING_PERIOD)*EN_TEK_ROLLING_PERIOD;
|
|
||||||
}
|
|
||||||
|
|
||||||
void en_generate_period_key(ENPeriodKey* periodKey) {
|
|
||||||
// TODO: error handling
|
|
||||||
random_bytes_callback(periodKey->b, sizeof(periodKey->b));
|
|
||||||
}
|
|
||||||
|
|
||||||
void en_derive_period_identifier_key(ENPeriodIdentifierKey *periodIdentifierKey, const ENPeriodKey *periodKey) {
|
|
||||||
|
|
||||||
const mbedtls_md_info_t *sha256_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
|
||||||
// TODO: Include \0 in the string?
|
|
||||||
// TODO: Check return value
|
|
||||||
// TODO: Is this utf-8 info correct?
|
|
||||||
// TODO: Correct erros in en_get_period_metadata_encryption_key as well!
|
|
||||||
const unsigned char info[7] = "EN-RPIK";
|
|
||||||
mbedtls_hkdf(sha256_info, 0, 0, periodKey->b, sizeof(periodKey->b), info, sizeof(info), periodIdentifierKey->b, sizeof(periodIdentifierKey->b));
|
|
||||||
}
|
|
||||||
|
|
||||||
void en_derive_interval_identifier(ENIntervalIdentifier *intervalIdentifier, const ENPeriodIdentifierKey *periodIdentifierKey, const ENIntervalNumber intervalNumber) {
|
|
||||||
unsigned char paddedData[16] = "EN-RPI";
|
|
||||||
|
|
||||||
// copy intervalNumber in little endian format
|
|
||||||
paddedData[12] = (intervalNumber >> 0) &0xFF;
|
|
||||||
paddedData[13] = (intervalNumber >> 8) &0xFF;
|
|
||||||
paddedData[14] = (intervalNumber >> 16) &0xFF;
|
|
||||||
paddedData[15] = (intervalNumber >> 24) &0xFF;
|
|
||||||
|
|
||||||
mbedtls_aes_context aes;
|
|
||||||
mbedtls_aes_init( &aes );
|
|
||||||
|
|
||||||
// Encrypt the padded data to get the identifier
|
|
||||||
mbedtls_aes_setkey_enc( &aes, (const unsigned char*) periodIdentifierKey->b, sizeof(periodIdentifierKey->b) * 8 );
|
|
||||||
mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, paddedData, intervalIdentifier->b);
|
|
||||||
mbedtls_aes_free( &aes );
|
|
||||||
}
|
|
||||||
|
|
||||||
void en_derive_period_metadata_encryption_key(ENPeriodMetadataEncryptionKey *periodMetadataEncryptionKey, const ENPeriodKey *periodKey) {
|
|
||||||
const mbedtls_md_info_t *sha256_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
|
||||||
const unsigned char info[7] = "EN-AEMK";
|
|
||||||
mbedtls_hkdf(sha256_info, 0, 0, periodKey->b, sizeof(periodKey->b), info, sizeof(info), periodMetadataEncryptionKey->b, sizeof(periodMetadataEncryptionKey->b));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void en_encrypt_interval_metadata(const ENPeriodMetadataEncryptionKey *periodMetadataEncryptionKey, const ENIntervalIdentifier *intervalIdentifier, unsigned char *input, unsigned char *output, size_t inputSize) {
|
|
||||||
|
|
||||||
mbedtls_aes_context aes;
|
|
||||||
mbedtls_aes_init( &aes );
|
|
||||||
|
|
||||||
// Encrypt the padded data to get the identifier
|
|
||||||
size_t nonceOffset = 0;
|
|
||||||
unsigned char nonceCounter[16];
|
|
||||||
unsigned char streamBlock[16];
|
|
||||||
|
|
||||||
// init nonce/IV to intervalIdentifer
|
|
||||||
memcpy(nonceCounter, intervalIdentifier->b, sizeof(nonceCounter));
|
|
||||||
memset(streamBlock, 0, sizeof(streamBlock));
|
|
||||||
|
|
||||||
mbedtls_aes_setkey_enc( &aes, (const unsigned char*) periodMetadataEncryptionKey->b, sizeof(periodMetadataEncryptionKey->b) * 8 );
|
|
||||||
mbedtls_aes_crypt_ctr(&aes, inputSize, &nonceOffset, nonceCounter, streamBlock, input, output);
|
|
||||||
mbedtls_aes_free( &aes );
|
|
||||||
}
|
|
||||||
|
|
||||||
void en_decrypt_interval_metadata(const ENPeriodMetadataEncryptionKey *periodMetadataEncryptionKey, const ENIntervalIdentifier *intervalIdentifier, unsigned char *input, unsigned char *output, size_t inputSize) {
|
|
||||||
en_encrypt_interval_metadata(periodMetadataEncryptionKey, intervalIdentifier, input, output, inputSize);
|
|
||||||
}
|
|
@ -22,14 +22,16 @@ build_flags =
|
|||||||
# For testing: -DUNITY_EXCLUDE_SETJMP_H=1
|
# For testing: -DUNITY_EXCLUDE_SETJMP_H=1
|
||||||
-DEN_INCLUDE_ZEPHYR_DEPS=1
|
-DEN_INCLUDE_ZEPHYR_DEPS=1
|
||||||
-DEN_INIT_MBEDTLS_ENTROPY=0
|
-DEN_INIT_MBEDTLS_ENTROPY=0
|
||||||
lib_deps = exposure-notification
|
lib_deps =
|
||||||
|
prathje/exposure-notification @ ^0.1
|
||||||
|
|
||||||
[env:desktop]
|
[env:desktop]
|
||||||
platform = native
|
platform = native
|
||||||
test_ignore = test_embedded
|
test_ignore = test_embedded
|
||||||
lib_compat_mode = off
|
lib_compat_mode = off
|
||||||
lib_deps = mbedtls@~2
|
lib_deps =
|
||||||
|
mbedtls@~2
|
||||||
|
prathje/exposure-notification @ ^0.1
|
||||||
build_flags =
|
build_flags =
|
||||||
-Iinclude/desktop
|
-Iinclude/desktop
|
||||||
-Iinclude/tls_config
|
-Iinclude/tls_config
|
||||||
|
Loading…
x
Reference in New Issue
Block a user