bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
a81d5c3f5a4ad5d100b258d10d4c75f4a02ab1f6Stephan Bosch
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "lib.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "module-dir.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "dcrypt.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi#include "dcrypt-private.h"
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic struct module *dcrypt_module = NULL;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomistatic struct dcrypt_vfs *dcrypt_vfs = NULL;
3f6149c3fd34f54ab33415bf7141e33fc9822e23Aki Tuomistatic const struct dcrypt_settings dcrypt_default_set = {
3f6149c3fd34f54ab33415bf7141e33fc9822e23Aki Tuomi .module_dir = DCRYPT_MODULE_DIR,
3f6149c3fd34f54ab33415bf7141e33fc9822e23Aki Tuomi};
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainenbool dcrypt_initialize(const char *backend, const struct dcrypt_settings *set, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi struct module_dir_load_settings mod_set;
a7ad754fca008f60d348f4296e5831e31ce8cc71Timo Sirainen const char *error;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
f86bd28cf4dadc4de794eebf34b28aefc8a3fc3aAki Tuomi if (dcrypt_vfs != NULL) {
f86bd28cf4dadc4de794eebf34b28aefc8a3fc3aAki Tuomi return TRUE;
f86bd28cf4dadc4de794eebf34b28aefc8a3fc3aAki Tuomi }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi if (backend == NULL) backend = "openssl"; /* default for now */
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen if (set == NULL)
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen set = &dcrypt_default_set;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const char *implementation = t_strconcat("dcrypt_",backend,NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&mod_set);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi mod_set.abi_version = DOVECOT_ABI_VERSION;
a7ad754fca008f60d348f4296e5831e31ce8cc71Timo Sirainen mod_set.require_init_funcs = TRUE;
3f6149c3fd34f54ab33415bf7141e33fc9822e23Aki Tuomi if (module_dir_try_load_missing(&dcrypt_module, set->module_dir,
a7ad754fca008f60d348f4296e5831e31ce8cc71Timo Sirainen implementation, &mod_set, &error) < 0) {
d86910a95633a25cf7577ea2dff0472b5a489bc3Teemu Huovila if (error_r != NULL)
a7ad754fca008f60d348f4296e5831e31ce8cc71Timo Sirainen *error_r = error;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return FALSE;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi }
a7ad754fca008f60d348f4296e5831e31ce8cc71Timo Sirainen module_dir_init(dcrypt_module);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi i_assert(dcrypt_vfs != NULL);
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen if (dcrypt_vfs->initialize != NULL) {
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen if (!dcrypt_vfs->initialize(set, error_r)) {
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen dcrypt_deinitialize();
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen return FALSE;
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen }
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen }
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi /* Destroy SSL module after(most of) the others. Especially lib-fs
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi backends may still want to access SSL module in their own
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi atexit-callbacks. */
f86bd28cf4dadc4de794eebf34b28aefc8a3fc3aAki Tuomi lib_atexit_priority(dcrypt_deinitialize, LIB_ATEXIT_PRIORITY_LOW);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return TRUE;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_deinitialize(void)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
a7ad754fca008f60d348f4296e5831e31ce8cc71Timo Sirainen module_dir_unload(&dcrypt_module);
a62dad9ec88bb112079dd95be456d258c6c86369Timo Sirainen dcrypt_vfs = NULL;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_set_vfs(struct dcrypt_vfs *vfs)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs = vfs;
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_create(const char *algorithm, enum dcrypt_sym_mode mode, struct dcrypt_context_symmetric **ctx_r, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_create(algorithm, mode, ctx_r, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_sym_destroy(struct dcrypt_context_symmetric **ctx)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_sym_destroy(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_sym_set_key(struct dcrypt_context_symmetric *ctx, const unsigned char *key, size_t key_len)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_sym_set_key(ctx, key, key_len);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_sym_set_iv(struct dcrypt_context_symmetric *ctx, const unsigned char *iv, size_t iv_len)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_sym_set_iv(ctx, iv, iv_len);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_sym_set_key_iv_random(struct dcrypt_context_symmetric *ctx)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_sym_set_key_iv_random(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_get_key(struct dcrypt_context_symmetric *ctx, buffer_t *key)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_get_key(ctx, key);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_get_iv(struct dcrypt_context_symmetric *ctx, buffer_t *iv)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_get_iv(ctx, iv);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomiunsigned int dcrypt_ctx_sym_get_key_length(struct dcrypt_context_symmetric *ctx)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_get_key_length(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomiunsigned int dcrypt_ctx_sym_get_iv_length(struct dcrypt_context_symmetric *ctx)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_get_iv_length(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_sym_set_aad(struct dcrypt_context_symmetric *ctx, const unsigned char *aad, size_t aad_len)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_sym_set_aad(ctx, aad, aad_len);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_get_aad(struct dcrypt_context_symmetric *ctx, buffer_t *aad)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_get_aad(ctx, aad);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_sym_set_tag(struct dcrypt_context_symmetric *ctx, const unsigned char *tag, size_t tag_len)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_sym_set_tag(ctx, tag, tag_len);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_get_tag(struct dcrypt_context_symmetric *ctx, buffer_t *tag)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_get_tag(ctx, tag);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomiunsigned int dcrypt_ctx_sym_get_block_size(struct dcrypt_context_symmetric *ctx) {
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_get_block_size(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_init(struct dcrypt_context_symmetric *ctx, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_init(ctx, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_update(struct dcrypt_context_symmetric *ctx, const unsigned char *data, size_t data_len, buffer_t *result, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_update(ctx, data, data_len, result, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_sym_final(struct dcrypt_context_symmetric *ctx, buffer_t *result, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_sym_final(ctx, result, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_sym_set_padding(struct dcrypt_context_symmetric *ctx, bool padding)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
3ba8511f99ae2c2b45c26a4eb74482a59385d0ffTimo Sirainen dcrypt_vfs->ctx_sym_set_padding(ctx, padding);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_hmac_create(const char *algorithm, struct dcrypt_context_hmac **ctx_r, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_hmac_create(algorithm, ctx_r, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_hmac_destroy(struct dcrypt_context_hmac **ctx)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_hmac_destroy(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_hmac_set_key(struct dcrypt_context_hmac *ctx, const unsigned char *key, size_t key_len)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_hmac_set_key(ctx, key, key_len);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_hmac_get_key(struct dcrypt_context_hmac *ctx, buffer_t *key)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_hmac_get_key(ctx, key);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomivoid dcrypt_ctx_hmac_set_key_random(struct dcrypt_context_hmac *ctx)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi dcrypt_vfs->ctx_hmac_set_key_random(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomiunsigned int dcrypt_ctx_hmac_get_digest_length(struct dcrypt_context_hmac *ctx)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_hmac_get_digest_length(ctx);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_hmac_init(struct dcrypt_context_hmac *ctx, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_hmac_init(ctx, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_hmac_update(struct dcrypt_context_hmac *ctx, const unsigned char *data, size_t data_len, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_hmac_update(ctx, data, data_len, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ctx_hmac_final(struct dcrypt_context_hmac *ctx, buffer_t *result, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ctx_hmac_final(ctx, result, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ecdh_derive_secret_local(struct dcrypt_private_key *local_key, buffer_t *R, buffer_t *S, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ecdh_derive_secret_local(local_key, R, S, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_ecdh_derive_secret_peer(struct dcrypt_public_key *peer_key, buffer_t *R, buffer_t *S, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->ecdh_derive_secret_peer(peer_key, R, S, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_pbkdf2(const unsigned char *password, size_t password_len, const unsigned char *salt, size_t salt_len,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const char *hash, unsigned int rounds, buffer_t *result, unsigned int result_len, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->pbkdf2(password, password_len, salt, salt_len, hash, rounds, result, result_len, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_keypair_generate(struct dcrypt_keypair *pair_r, enum dcrypt_key_type kind, unsigned int bits, const char *curve, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(pair_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->generate_keypair(pair_r, kind, bits, curve, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
401160c5ca4c3c8f122f437d00f5e4498243d7bfMartti Rannanjärvibool dcrypt_key_load_private(struct dcrypt_private_key **key_r, const char *data,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const char *password, struct dcrypt_private_key *dec_key, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
401160c5ca4c3c8f122f437d00f5e4498243d7bfMartti Rannanjärvi return dcrypt_vfs->load_private_key(key_r, data, password, dec_key, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
fadd4c92940c10a01556e1ebcb2f17890b35d7bcMartti Rannanjärvibool dcrypt_key_load_public(struct dcrypt_public_key **key_r, const char *data, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
fadd4c92940c10a01556e1ebcb2f17890b35d7bcMartti Rannanjärvi return dcrypt_vfs->load_public_key(key_r, data, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_key_store_private(struct dcrypt_private_key *key, enum dcrypt_key_format format, const char *cipher, buffer_t *destination,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const char *password, struct dcrypt_public_key *enc_key, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->store_private_key(key, format, cipher, destination, password, enc_key, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_key_store_public(struct dcrypt_public_key *key, enum dcrypt_key_format format, buffer_t *destination, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->store_public_key(key, format, destination, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
955c276b9de538cfbfe4cff19f2a610f57e8d5c7Timo Sirainenvoid dcrypt_key_convert_private_to_public(struct dcrypt_private_key *priv_key, struct dcrypt_public_key **pub_key_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
955c276b9de538cfbfe4cff19f2a610f57e8d5c7Timo Sirainen dcrypt_vfs->private_to_public_key(priv_key, pub_key_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_key_string_get_info(const char *key_data, enum dcrypt_key_format *format_r, enum dcrypt_key_version *version_r,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi enum dcrypt_key_kind *kind_r, enum dcrypt_key_encryption_type *encryption_type_r, const char **encryption_key_hash_r,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi const char **key_hash_r, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->key_string_get_info(key_data, format_r, version_r, kind_r, encryption_type_r,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi encryption_key_hash_r, key_hash_r, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
394391e78f26cba1d7fca19d4b8617453a7041b8Timo Sirainenenum dcrypt_key_type dcrypt_key_type_private(struct dcrypt_private_key *key)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
394391e78f26cba1d7fca19d4b8617453a7041b8Timo Sirainen return dcrypt_vfs->private_key_type(key);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
394391e78f26cba1d7fca19d4b8617453a7041b8Timo Sirainenenum dcrypt_key_type dcrypt_key_type_public(struct dcrypt_public_key *key)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
394391e78f26cba1d7fca19d4b8617453a7041b8Timo Sirainen return dcrypt_vfs->public_key_type(key);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_key_id_public(struct dcrypt_public_key *key, const char *algorithm, buffer_t *result, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->public_key_id(key, algorithm, result, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_key_id_public_old(struct dcrypt_public_key *key, buffer_t *result, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->public_key_id_old(key, result, error_r);
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi}
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomibool dcrypt_key_id_private(struct dcrypt_private_key *key, const char *algorithm, buffer_t *result, const char **error_r)
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi return dcrypt_vfs->private_key_id(key, algorithm, result, error_r);
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi}
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomibool dcrypt_key_id_private_old(struct dcrypt_private_key *key, buffer_t *result, const char **error_r)
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi return dcrypt_vfs->private_key_id_old(key, result, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomivoid dcrypt_keypair_unref(struct dcrypt_keypair *keypair)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi dcrypt_vfs->unref_keypair(keypair);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomivoid dcrypt_key_ref_public(struct dcrypt_public_key *key)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi dcrypt_vfs->ref_public_key(key);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomivoid dcrypt_key_ref_private(struct dcrypt_private_key *key)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi dcrypt_vfs->ref_private_key(key);
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi}
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomivoid dcrypt_key_unref_public(struct dcrypt_public_key **key)
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi dcrypt_vfs->unref_public_key(key);
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi}
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomivoid dcrypt_key_unref_private(struct dcrypt_private_key **key)
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
a53b81d08bf21d802705f6ff2df70cdf0e39e61dAki Tuomi dcrypt_vfs->unref_private_key(key);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_rsa_encrypt(struct dcrypt_public_key *key, const unsigned char *data, size_t data_len, buffer_t *result, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->rsa_encrypt(key, data, data_len, result, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_rsa_decrypt(struct dcrypt_private_key *key, const unsigned char *data, size_t data_len, buffer_t *result, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->rsa_decrypt(key, data, data_len, result, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomiconst char *dcrypt_oid2name(const unsigned char *oid, size_t oid_len, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->oid2name(oid, oid_len, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomibool dcrypt_name2oid(const char *name, buffer_t *oid, const char **error_r)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi{
3c503fa10d3d0fe2abb1767caf217b0a770dc6aaAki Tuomi i_assert(dcrypt_vfs != NULL);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return dcrypt_vfs->name2oid(name, oid, error_r);
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi}
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi