Make vault iteration count adaptible to hardware
We want to specify a real time for key derivation and let it figure out by itself how many iterations it needs.
This commit is contained in:
parent
1312bce9af
commit
d8208fbab5
90
vault.c
90
vault.c
@ -24,12 +24,56 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include "vault.h"
|
#include "vault.h"
|
||||||
|
|
||||||
struct vault_t * vault_init(void *inner_data, unsigned int data_length) {
|
static bool vault_derive_key(const struct vault_t *vault, uint8_t key[static 32]) {
|
||||||
|
/* Derive the AES key from it */
|
||||||
|
if (PKCS5_PBKDF2_HMAC((char*)vault->key, vault->key_length, NULL, 0, vault->iteration_cnt, EVP_sha256(), 32, key) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double now(void) {
|
||||||
|
struct timeval tv;
|
||||||
|
if (gettimeofday(&tv, NULL) == 0) {
|
||||||
|
return tv.tv_sec + (1e-6 * tv.tv_usec);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static double vault_measure_key_derivation_time(struct vault_t *vault, unsigned int new_iteration_count) {
|
||||||
|
uint8_t dkey[32];
|
||||||
|
double t0, t1;
|
||||||
|
vault->iteration_cnt = new_iteration_count;
|
||||||
|
t0 = now();
|
||||||
|
vault_derive_key(vault, dkey);
|
||||||
|
t1 = now();
|
||||||
|
OPENSSL_cleanse(dkey, sizeof(dkey));
|
||||||
|
return t1 - t0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vault_calibrate_derivation_time(struct vault_t *vault, double target_derivation_time) {
|
||||||
|
unsigned int iteration_cnt = 1;
|
||||||
|
while (iteration_cnt < 100000000) {
|
||||||
|
double current_time = vault_measure_key_derivation_time(vault, iteration_cnt);
|
||||||
|
// fprintf(stderr, "%d: %f %f\n", iteration_cnt, current_time, target_derivation_time);
|
||||||
|
if (current_time * 10 < target_derivation_time) {
|
||||||
|
iteration_cnt *= 2;
|
||||||
|
} else if (current_time * 1.1 < target_derivation_time) {
|
||||||
|
iteration_cnt = iteration_cnt * target_derivation_time / current_time;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vault_t* vault_init(unsigned int data_length, double target_derivation_time) {
|
||||||
struct vault_t *vault;
|
struct vault_t *vault;
|
||||||
|
|
||||||
vault = calloc(1, sizeof(struct vault_t));
|
vault = calloc(1, sizeof(struct vault_t));
|
||||||
@ -44,19 +88,14 @@ struct vault_t * vault_init(void *inner_data, unsigned int data_length) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inner_data) {
|
vault->data = calloc(data_length, 1);
|
||||||
vault->data = inner_data;
|
if (!vault->data) {
|
||||||
vault->free_data = false;
|
vault_free(vault);
|
||||||
} else {
|
return NULL;
|
||||||
vault->free_data = true;
|
|
||||||
vault->data = malloc(data_length);
|
|
||||||
if (!vault->data) {
|
|
||||||
vault_free(vault);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
vault->is_open = true;
|
vault->is_open = true;
|
||||||
vault->data_length = data_length;
|
vault->data_length = data_length;
|
||||||
|
vault_calibrate_derivation_time(vault, target_derivation_time);
|
||||||
|
|
||||||
return vault;
|
return vault;
|
||||||
}
|
}
|
||||||
@ -70,21 +109,13 @@ static void vault_destroy_content(struct vault_t *vault) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vault_derive_key(const struct vault_t *vault, uint8_t key[static 32]) {
|
|
||||||
/* Derive the AES key from it */
|
|
||||||
if (PKCS5_PBKDF2_HMAC((char*)vault->key, vault->key_length, NULL, 0, VAULT_PBKDF2_ITERATIONS, EVP_sha256(), 32, key) != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vault_open(struct vault_t *vault) {
|
bool vault_open(struct vault_t *vault) {
|
||||||
if (vault->is_open) {
|
if (vault->is_open) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t key[32];
|
uint8_t dkey[32];
|
||||||
if (!vault_derive_key(vault, key)) {
|
if (!vault_derive_key(vault, dkey)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +136,7 @@ bool vault_open(struct vault_t *vault) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, (unsigned char*)&vault->iv) != 1) {
|
if (EVP_DecryptInit_ex(ctx, NULL, NULL, dkey, (unsigned char*)&vault->iv) != 1) {
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -138,7 +169,7 @@ bool vault_open(struct vault_t *vault) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
OPENSSL_cleanse(key, sizeof(key));
|
OPENSSL_cleanse(dkey, sizeof(dkey));
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,9 +245,7 @@ bool vault_close(struct vault_t *vault) {
|
|||||||
|
|
||||||
void vault_free(struct vault_t *vault) {
|
void vault_free(struct vault_t *vault) {
|
||||||
vault_destroy_content(vault);
|
vault_destroy_content(vault);
|
||||||
if (vault->free_data) {
|
free(vault->data);
|
||||||
free(vault->data);
|
|
||||||
}
|
|
||||||
free(vault->key);
|
free(vault->key);
|
||||||
free(vault);
|
free(vault);
|
||||||
}
|
}
|
||||||
@ -233,19 +262,18 @@ static void dump(const uint8_t *data, unsigned int length) {
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
/* gcc -Wall -std=c11 -Wmissing-prototypes -Wstrict-prototypes -Werror=implicit-function-declaration -Wimplicit-fallthrough -Wshadow -pie -fPIE -fsanitize=address -fsanitize=undefined -fsanitize=leak -o vault vault.c -lasan -lubsan -lcrypto
|
/* gcc -Wall -std=c11 -Wmissing-prototypes -Wstrict-prototypes -Werror=implicit-function-declaration -Wimplicit-fallthrough -Wshadow -pie -fPIE -fsanitize=address -fsanitize=undefined -fsanitize=leak -o vault vault.c -lasan -lubsan -lcrypto
|
||||||
*/
|
*/
|
||||||
uint8_t data[64];
|
struct vault_t *vault = vault_init(64, 0.1);
|
||||||
dump(data, sizeof(data));
|
dump(vault->data, vault->data_length);
|
||||||
struct vault_t *vault = vault_init(data, sizeof(data));
|
|
||||||
if (!vault_close(vault)) {
|
if (!vault_close(vault)) {
|
||||||
fprintf(stderr, "vault close failed.\n");
|
fprintf(stderr, "vault close failed.\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
dump(data, sizeof(data));
|
dump(vault->data, vault->data_length);
|
||||||
if (!vault_open(vault)) {
|
if (!vault_open(vault)) {
|
||||||
fprintf(stderr, "vault open failed.\n");
|
fprintf(stderr, "vault open failed.\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
dump(data, sizeof(data));
|
dump(vault->data, vault->data_length);
|
||||||
vault_free(vault);
|
vault_free(vault);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
5
vault.h
5
vault.h
@ -31,18 +31,17 @@ struct vault_t {
|
|||||||
bool is_open;
|
bool is_open;
|
||||||
void *data;
|
void *data;
|
||||||
unsigned int data_length;
|
unsigned int data_length;
|
||||||
bool free_data;
|
|
||||||
uint8_t *key;
|
uint8_t *key;
|
||||||
unsigned int key_length;
|
unsigned int key_length;
|
||||||
uint8_t auth_tag[16];
|
uint8_t auth_tag[16];
|
||||||
uint64_t iv;
|
uint64_t iv;
|
||||||
|
unsigned int iteration_cnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_KEY_LENGTH_BYTES (1024 * 1024)
|
#define DEFAULT_KEY_LENGTH_BYTES (1024 * 1024)
|
||||||
#define VAULT_PBKDF2_ITERATIONS 50000
|
|
||||||
|
|
||||||
/*************** AUTO GENERATED SECTION FOLLOWS ***************/
|
/*************** AUTO GENERATED SECTION FOLLOWS ***************/
|
||||||
struct vault_t * vault_init(void *inner_data, unsigned int data_length);
|
struct vault_t* vault_init(unsigned int data_length, double target_derivation_time);
|
||||||
bool vault_open(struct vault_t *vault);
|
bool vault_open(struct vault_t *vault);
|
||||||
bool vault_close(struct vault_t *vault);
|
bool vault_close(struct vault_t *vault);
|
||||||
void vault_free(struct vault_t *vault);
|
void vault_free(struct vault_t *vault);
|
||||||
|
Loading…
Reference in New Issue
Block a user