X-Git-Url: https://www.flypig.org.uk/git/?p=libcontrac.git;a=blobdiff_plain;f=src%2Frpi.c;fp=src%2Frpi.c;h=7523ba4c6e4d31b139b6258f07f5a661bad245a5;hp=0000000000000000000000000000000000000000;hb=8515bbba069347de07a452586d7e49a2e8bdf151;hpb=79942abab927241b65a29a8a30d71b8efe6b6d94 diff --git a/src/rpi.c b/src/rpi.c new file mode 100644 index 0000000..7523ba4 --- /dev/null +++ b/src/rpi.c @@ -0,0 +1,141 @@ +/** \ingroup contrac + * @file + * @author David Llewellyn-Jones + * @version $(VERSION) + * + * @section LICENSE + * + * + * + * @brief + * @section DESCRIPTION + * + * + * + */ + +// Includes + +#include +#include +#include +#include + +#include +#include +#include + +#include "contrac/contrac.h" +#include "contrac/utils.h" +#include "contrac/log.h" + +#include "contrac/rpi.h" + +// Defines + +#define RPI_INFO_PREFIX "CT-RPI" + +// Structures + +struct _Rpi { + // Rolling proximity identifier + unsigned char rpi[RPI_SIZE]; + uint8_t time_interval_number; +}; + +// Function prototypes + +// Function definitions + +Rpi * rpi_new() { + Rpi * data; + + data = calloc(sizeof(Rpi), 1); + + return data; +} + +void rpi_delete(Rpi * data) { + if (data) { + // Clear the data for security + memset(data, 0, sizeof(Rpi)); + + free(data); + } +} + +bool rpi_generate_proximity_id(Rpi * data, Dtk const * dtk, uint8_t time_interval_number) { + int result = 1; + unsigned char encode[sizeof(RPI_INFO_PREFIX) + sizeof(uint16_t)]; + unsigned char output[EVP_MAX_MD_SIZE]; + unsigned int out_length = 0; + unsigned int pos; + unsigned int min; + unsigned char const * daily_key; + + // RPI_{i, j} <- Truncate(HMAC(dkt_i, (UTF8("CT-RPI") || TIN_j)), 16) + + if (result > 0) { + // Produce Info sequence UTF8("CT-DTK") || D_i) + // From the spec it's not clear whether this is string or byte concatenation. + // Here we use byte, but it might have to be changed + memcpy(encode, RPI_INFO_PREFIX, sizeof(RPI_INFO_PREFIX)); + ((uint8_t *)(encode + sizeof(RPI_INFO_PREFIX)))[0] = time_interval_number; + out_length = sizeof(output); + + daily_key = dtk_get_daily_key(dtk); + HMAC(EVP_sha256(), daily_key, DTK_SIZE, encode, sizeof(encode), output, &out_length); + + _Static_assert ((EVP_MAX_MD_SIZE >= 16), "HMAC buffer size too small"); + + // Truncate and copy the result + min = MIN(out_length, 16); + for (pos = 0; pos < min; ++pos) { + data->rpi[pos] = output[pos]; + } + // Zero out padding if there is any + for (pos = min; pos < 16; ++pos) { + data->rpi[pos] = 0; + } + } + + if (result > 0) { + data->time_interval_number = time_interval_number; + } + + if (result <= 0) { + LOG(LOG_ERR, "Error generating rolling proximity id: %lu\n", ERR_get_error()); + } + + return (result > 0); +} + +const unsigned char * rpi_get_proximity_id(Rpi const * data) { + return data->rpi; +} + +uint8_t rpi_get_time_interval_number(Rpi const * data) { + return data->time_interval_number; +} + + +void rpi_assign(Rpi * data, unsigned char const * rpi_bytes, uint8_t time_interval_number) { + memcpy(data->rpi, rpi_bytes, RPI_SIZE); + data->time_interval_number = time_interval_number; +} + +bool rpi_compare(Rpi const * data, Rpi const * comparitor) { + unsigned char left[RPI_SIZE_BASE64 + 1]; + unsigned char right[RPI_SIZE_BASE64 + 1]; + size_t size; + + size = RPI_SIZE_BASE64 + 1; + base64_encode_binary_to_base64(data->rpi, RPI_SIZE, left, &size); + + size = RPI_SIZE_BASE64 + 1; + base64_encode_binary_to_base64(comparitor->rpi, RPI_SIZE, right, &size); + + return (memcmp(data, comparitor, RPI_SIZE) == 0); +} + +