abef1bd6074719c73a0ebb683c998bde988bfc67
3 * @author David Llewellyn-Jones
11 * @section DESCRIPTION
24 #include <openssl/crypto.h>
25 #include <openssl/hmac.h>
26 #include <openssl/err.h>
28 #include "contrac/contrac.h"
29 #include "contrac/utils.h"
30 #include "contrac/log.h"
32 #include "contrac/rpi.h"
36 #define RPI_INFO_PREFIX "CT-RPI"
41 // Rolling proximity identifier
42 unsigned char rpi
[RPI_SIZE
];
43 uint8_t time_interval_number
;
46 // Function prototypes
48 // Function definitions
53 data
= calloc(sizeof(Rpi
), 1);
58 void rpi_delete(Rpi
* data
) {
60 // Clear the data for security
61 memset(data
, 0, sizeof(Rpi
));
67 bool rpi_generate_proximity_id(Rpi
* data
, Dtk
const * dtk
, uint8_t time_interval_number
) {
69 unsigned char encode
[sizeof(RPI_INFO_PREFIX
) + sizeof(time_interval_number
)];
70 unsigned char output
[EVP_MAX_MD_SIZE
];
71 unsigned int out_length
= 0;
74 unsigned char const * daily_key
;
76 // RPI_{i, j} <- Truncate(HMAC(dkt_i, (UTF8("CT-RPI") || TIN_j)), 16)
79 // Produce Info sequence UTF8("CT-DTK") || D_i)
80 // From the spec it's not clear whether this is string or byte concatenation.
81 // Here we use byte, but it might have to be changed
82 memcpy(encode
, RPI_INFO_PREFIX
, sizeof(RPI_INFO_PREFIX
));
83 ((uint8_t *)(encode
+ sizeof(RPI_INFO_PREFIX
)))[0] = time_interval_number
;
84 out_length
= sizeof(output
);
86 daily_key
= dtk_get_daily_key(dtk
);
87 HMAC(EVP_sha256(), daily_key
, DTK_SIZE
, encode
, sizeof(encode
), output
, &out_length
);
89 _Static_assert ((EVP_MAX_MD_SIZE
>= 16), "HMAC buffer size too small");
91 // Truncate and copy the result
92 min
= MIN(out_length
, 16);
93 for (pos
= 0; pos
< min
; ++pos
) {
94 data
->rpi
[pos
] = output
[pos
];
96 // Zero out padding if there is any
97 for (pos
= min
; pos
< 16; ++pos
) {
103 data
->time_interval_number
= time_interval_number
;
107 LOG(LOG_ERR
, "Error generating rolling proximity id: %lu\n", ERR_get_error());
113 const unsigned char * rpi_get_proximity_id(Rpi
const * data
) {
117 uint8_t rpi_get_time_interval_number(Rpi
const * data
) {
118 return data
->time_interval_number
;
122 void rpi_assign(Rpi
* data
, unsigned char const * rpi_bytes
, uint8_t time_interval_number
) {
123 memcpy(data
->rpi
, rpi_bytes
, RPI_SIZE
);
124 data
->time_interval_number
= time_interval_number
;
127 bool rpi_compare(Rpi
const * data
, Rpi
const * comparitor
) {
128 unsigned char left
[RPI_SIZE_BASE64
+ 1];
129 unsigned char right
[RPI_SIZE_BASE64
+ 1];
132 size
= RPI_SIZE_BASE64
+ 1;
133 base64_encode_binary_to_base64(data
->rpi
, RPI_SIZE
, left
, &size
);
135 size
= RPI_SIZE_BASE64
+ 1;
136 base64_encode_binary_to_base64(comparitor
->rpi
, RPI_SIZE
, right
, &size
);
138 return (memcmp(data
, comparitor
, RPI_SIZE
) == 0);