3 * @author David Llewellyn-Jones
11 * @section DESCRIPTION
24 #include <openssl/crypto.h>
25 #include <openssl/kdf.h>
26 #include <openssl/err.h>
27 #include <openssl/evp.h>
29 #include "contrac/contrac.h"
30 #include "contrac/utils.h"
31 #include "contrac/log.h"
33 #include "contrac/dtk.h"
37 #define DTK_INFO_PREFIX "CT-DTK"
43 unsigned char dtk
[DTK_SIZE
];
47 // Function prototypes
49 // Function definitions
54 data
= calloc(sizeof(Dtk
), 1);
59 void dtk_delete(Dtk
* data
) {
61 // Clear the data for security
62 memset(data
, 0, sizeof(Dtk
));
68 bool contrac_generate_daily_key(Dtk
* data
, Contrac
const * contrac
, uint32_t day_number
) {
70 char encode
[sizeof(DTK_INFO_PREFIX
) + sizeof(day_number
)];
71 size_t out_length
= 0;
72 EVP_PKEY_CTX
*pctx
= NULL
;
73 const unsigned char * tk
;
75 // dtk_i <- HKDF(tk, NULL, (UTF8("CT-DTK") || D_i), 16)
78 // Produce Info sequence UTF8("CT-DTK") || D_i)
79 // From the spec it's not clear whether this is string or byte concatenation.
80 // Here we use byte, but it might have to be changed
81 memcpy(encode
, DTK_INFO_PREFIX
, sizeof(DTK_INFO_PREFIX
));
82 ((uint32_t *)(encode
+ sizeof(DTK_INFO_PREFIX
)))[0] = day_number
;
84 pctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF
, NULL
);
86 result
= EVP_PKEY_derive_init(pctx
);
90 result
= EVP_PKEY_CTX_set_hkdf_md(pctx
, EVP_sha256());
94 result
= EVP_PKEY_CTX_set1_hkdf_salt(pctx
, NULL
, 4);
98 tk
= contrac_get_tracing_key(contrac
);
99 result
= EVP_PKEY_CTX_set1_hkdf_key(pctx
, tk
, TK_SIZE
);
103 result
= EVP_PKEY_CTX_add1_hkdf_info(pctx
, encode
, sizeof(encode
));
107 out_length
= DTK_SIZE
;
108 result
= EVP_PKEY_derive(pctx
, data
->dtk
, &out_length
);
111 if ((result
> 0) && (out_length
== DTK_SIZE
)) {
112 data
->day_number
= day_number
;
117 LOG(LOG_ERR
, "Error generating daily key: %lu\n", ERR_get_error());
120 // Freeing a NULL value is safe
121 EVP_PKEY_CTX_free(pctx
);
126 const unsigned char * dtk_get_daily_key(Dtk
const * data
) {
130 uint32_t dtk_get_day_number(Dtk
const * data
) {
131 return data
->day_number
;
134 void dtk_assign(Dtk
* data
, unsigned char const * dtk_bytes
, uint32_t day_number
) {
135 memcpy(data
->dtk
, dtk_bytes
, DTK_SIZE
);
136 data
->day_number
= day_number
;