Version 10.0.2
All Classes Functions Variables Typedefs Enumerations Enumerator Modules Pages
WT_ENCRYPTOR Struct Reference

The interface implemented by applications to provide custom encryption. More...

Public Attributes

int(* encrypt )(WT_ENCRYPTOR *encryptor, WT_SESSION *session, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, size_t *result_lenp)
 Callback to encrypt a chunk of data. More...
 
int(* decrypt )(WT_ENCRYPTOR *encryptor, WT_SESSION *session, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, size_t *result_lenp)
 Callback to decrypt a chunk of data. More...
 
int(* sizing )(WT_ENCRYPTOR *encryptor, WT_SESSION *session, size_t *expansion_constantp)
 Callback to size a destination buffer for encryption. More...
 
int(* customize )(WT_ENCRYPTOR *encryptor, WT_SESSION *session, WT_CONFIG_ARG *encrypt_config, WT_ENCRYPTOR **customp)
 If non-NULL, this callback is called to load keys into the encryptor. More...
 
int(* terminate )(WT_ENCRYPTOR *encryptor, WT_SESSION *session)
 If non-NULL, a callback performed when the database is closed. More...
 

Detailed Description

The interface implemented by applications to provide custom encryption.

Encryptors must implement the WT_ENCRYPTOR interface: the WT_ENCRYPTOR::encrypt, WT_ENCRYPTOR::decrypt and WT_ENCRYPTOR::sizing callbacks must be specified, WT_ENCRYPTOR::customize and WT_ENCRYPTOR::terminate are optional. To build your own encryptor, use one of the encryptors in ext/encryptors as a template: ext/encryptors/sodium_encrypt uses the open-source libsodium cryptographic library, and ext/encryptors/nop_encrypt is a simple template that passes through data unchanged, and is a reasonable starting point. ext/encryptors/rotn_encrypt is an encryptor implementing a simple (insecure) rotation cipher meant for testing. See the encryptors page for further information.

Applications register their implementation with WiredTiger by calling WT_CONNECTION::add_encryptor.

/* Local encryptor structure. */
typedef struct {
WT_ENCRYPTOR encryptor; /* Must come first */
WT_EXTENSION_API *wt_api; /* Extension API */
unsigned long nop_calls; /* Count of calls */
} NOP_ENCRYPTOR;
/*
* wiredtiger_extension_init --
* A simple shared library encryption example.
*/
int
{
NOP_ENCRYPTOR *nop_encryptor;
int ret;
(void)config; /* Unused parameters */
if ((nop_encryptor = calloc(1, sizeof(NOP_ENCRYPTOR))) == NULL)
return (errno);
/*
* Allocate a local encryptor structure, with a WT_ENCRYPTOR structure as the first field,
* allowing us to treat references to either type of structure as a reference to the other type.
*
* Heap memory (not static), because it can support multiple databases.
*/
nop_encryptor->encryptor.encrypt = nop_encrypt;
nop_encryptor->encryptor.decrypt = nop_decrypt;
nop_encryptor->encryptor.sizing = nop_sizing;
nop_encryptor->encryptor.customize = nop_customize;
nop_encryptor->encryptor.terminate = nop_terminate;
nop_encryptor->wt_api = connection->get_extension_api(connection);
/* Load the encryptor */
if ((ret = connection->add_encryptor(connection, "nop", (WT_ENCRYPTOR *)nop_encryptor, NULL)) ==
0)
return (0);
free(nop_encryptor);
return (ret);
}
Examples
ex_encrypt.c, nop_encrypt.c, rotn_encrypt.c, and sodium_encrypt.c.

Member Data Documentation

◆ customize

int(* WT_ENCRYPTOR::customize) (WT_ENCRYPTOR *encryptor, WT_SESSION *session, WT_CONFIG_ARG *encrypt_config, WT_ENCRYPTOR **customp)

If non-NULL, this callback is called to load keys into the encryptor.

(That is, "customize" it for a given key.) The customize function is called whenever a new keyid is used for the first time with this encryptor, whether it be in the wiredtiger_open call or the WT_SESSION::create call. This should create a new encryptor instance and insert the requested key in it.

The key may be specified either via keyid or secretkey in the encrypt_config parameter. In the former case, the encryptor should look up the requested key ID with whatever key management service is in use and install it in the new encryptor. In the latter case, the encryptor should save the provided secret key (or some transformation of it) in the new encryptor. Further encryption with the same keyid will use this new encryptor instance. (In the case of secretkey, only one key can be configured, for the system encryption, and the new encryptor will be used for all encryption involving it.) See Encryptors for more information.

This callback may return NULL as the new encryptor, in which case the original encryptor will be used for further operations on the selected key. Unless this happens, the original encryptor structure created during extension initialization will never be used for encryption or decryption.

This callback may itself be NULL, in which case it is not called, but in that case there is no way to configure a key. This may be suitable for an environment where a key management service returns a single key under a well-known name that can be compiled in, but in a more general environment is not a useful approach. One should of course never compile in actual keys!

Parameters
[in]encrypt_configthe "encryption" portion of the configuration from the wiredtiger_open or WT_SESSION::create call, containing the keyid or secretkey setting.
[out]custompthe new modified encryptor, or NULL.
Returns
zero for success, non-zero to indicate an error.
Examples
ex_encrypt.c.

◆ decrypt

int(* WT_ENCRYPTOR::decrypt) (WT_ENCRYPTOR *encryptor, WT_SESSION *session, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, size_t *result_lenp)

Callback to decrypt a chunk of data.

WT_ENCRYPTOR::decrypt takes a source buffer and a destination buffer. The contents are switched from encrypt: the source buffer is the encrypted value, and the destination buffer is sized to be the original size of the decrypted data. If the callback successfully decrypts the source buffer to the destination buffer, it returns 0. If an error occurs, it returns an errno or WiredTiger error code.

On entry, src will point to memory, with the length of the memory in src_len. After successful completion, the callback should return 0 and set result_lenp to the number of bytes required for the decrypted representation.

If the dst buffer is not big enough to hold the decrypted data, the callback should return an error.

This callback cannot be NULL.

Parameters
[in]srcthe data to decrypt
[in]src_lenthe length of the data to decrypt
[in]dstthe destination buffer
[in]dst_lenthe length of the destination buffer
[out]result_lenpthe length of the decrypted data
Returns
zero for success, non-zero to indicate an error.
/*
* nop_decrypt --
* A simple decryption example that passes data through unchanged.
*/
static int
nop_decrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, uint8_t *src, size_t src_len,
uint8_t *dst, size_t dst_len, size_t *result_lenp)
{
NOP_ENCRYPTOR *nop_encryptor = (NOP_ENCRYPTOR *)encryptor;
(void)session; /* Unused parameters */
(void)src_len;
++nop_encryptor->nop_calls; /* Call count */
/*
* The destination length is the number of unencrypted bytes we're expected to return.
*/
memcpy(dst, src, dst_len);
*result_lenp = dst_len;
return (0);
}
Examples
ex_encrypt.c.

◆ encrypt

int(* WT_ENCRYPTOR::encrypt) (WT_ENCRYPTOR *encryptor, WT_SESSION *session, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, size_t *result_lenp)

Callback to encrypt a chunk of data.

WT_ENCRYPTOR::encrypt takes a source buffer and a destination buffer. The callback encrypts the source buffer (plain text) into the destination buffer.

On entry, src will point to a block of memory to encrypt, with the length of the block in src_len.

On entry, dst points to the destination buffer with a length of dst_len. The destination buffer will be at least src_len plus the size returned by that WT_ENCRYPT::sizing.

After successful completion, the callback should return 0 and set result_lenp to the number of bytes required for the encrypted representation, which should be less than or equal to dst_len.

This callback cannot be NULL.

Parameters
[in]srcthe data to encrypt
[in]src_lenthe length of the data to encrypt
[in]dstthe destination buffer
[in]dst_lenthe length of the destination buffer
[out]result_lenpthe length of the encrypted data
Returns
zero for success, non-zero to indicate an error.
/*
* nop_encrypt --
* A simple encryption example that passes data through unchanged.
*/
static int
nop_encrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, uint8_t *src, size_t src_len,
uint8_t *dst, size_t dst_len, size_t *result_lenp)
{
NOP_ENCRYPTOR *nop_encryptor = (NOP_ENCRYPTOR *)encryptor;
(void)session; /* Unused parameters */
++nop_encryptor->nop_calls; /* Call count */
if (dst_len < src_len)
return (nop_error(nop_encryptor, session, ENOMEM, "encrypt buffer not big enough"));
memcpy(dst, src, src_len);
*result_lenp = src_len;
return (0);
}
Examples
ex_encrypt.c.

◆ sizing

int(* WT_ENCRYPTOR::sizing) (WT_ENCRYPTOR *encryptor, WT_SESSION *session, size_t *expansion_constantp)

Callback to size a destination buffer for encryption.

WT_ENCRYPTOR::sizing is an callback that returns the number of additional bytes that is needed when encrypting a data block. This is always necessary, since encryptors should always generate some sort of cryptographic checksum as well as the ciphertext. Without such a call, WiredTiger would have no way to know the worst case for the encrypted buffer size.

The WiredTiger encryption infrastructure assumes that buffer sizing is not dependent on the number of bytes of input, that there is a one-to-one relationship in number of bytes needed between input and output. This means that if the encryption uses a block cipher in such a way that the input size needs to be padded to the cipher block size, the sizing method should return the worst case to ensure enough space is available.

This callback cannot be NULL.

The callback should set expansion_constantp to the additional number of bytes needed.

Parameters
[out]expansion_constantpthe additional number of bytes needed when encrypting.
Returns
zero for success, non-zero to indicate an error.
/*
* nop_sizing --
* A simple sizing example that tells wiredtiger that the encrypted buffer is always the same as
* the source buffer.
*/
static int
nop_sizing(WT_ENCRYPTOR *encryptor, WT_SESSION *session, size_t *expansion_constantp)
{
NOP_ENCRYPTOR *nop_encryptor = (NOP_ENCRYPTOR *)encryptor;
(void)session; /* Unused parameters */
++nop_encryptor->nop_calls; /* Call count */
*expansion_constantp = 0;
return (0);
}
Examples
ex_encrypt.c.

◆ terminate

int(* WT_ENCRYPTOR::terminate) (WT_ENCRYPTOR *encryptor, WT_SESSION *session)

If non-NULL, a callback performed when the database is closed.

It is called for each encryptor that was added using WT_CONNECTION::add_encryptor or returned by the WT_ENCRYPTOR::customize callback.

The WT_ENCRYPTOR::terminate callback is intended to allow cleanup; the handle will not be subsequently accessed by WiredTiger.

/*
* nop_terminate --
* WiredTiger no-op encryption termination.
*/
static int
nop_terminate(WT_ENCRYPTOR *encryptor, WT_SESSION *session)
{
NOP_ENCRYPTOR *nop_encryptor = (NOP_ENCRYPTOR *)encryptor;
(void)session; /* Unused parameters */
++nop_encryptor->nop_calls; /* Call count */
/* Free the allocated memory. */
free(encryptor);
return (0);
}
Examples
ex_encrypt.c.
WT_ENCRYPTOR::encrypt
int(* encrypt)(WT_ENCRYPTOR *encryptor, WT_SESSION *session, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, size_t *result_lenp)
Callback to encrypt a chunk of data.
Definition: wiredtiger.in:4154
WT_EXTENSION_API
Table of WiredTiger extension methods.
Definition: wiredtiger_ext.h:94
WT_CONFIG_ARG
struct WT_CONFIG_ARG WT_CONFIG_ARG
Definition: wiredtiger.in:3771
WT_CONNECTION::get_extension_api
WT_EXTENSION_API * get_extension_api(WT_CONNECTION *wt_conn)
Return a reference to the WiredTiger extension functions.
WT_ENCRYPTOR
The interface implemented by applications to provide custom encryption.
Definition: wiredtiger.in:4125
wiredtiger_extension_init
int wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
Entry point to an extension, called when the extension is loaded.
WT_CONNECTION
A connection to a WiredTiger database.
Definition: wiredtiger.in:1991
WT_CONNECTION::add_encryptor
int add_encryptor(WT_CONNECTION *connection, const char *name, WT_ENCRYPTOR *encryptor, const char *config)
Add an encryption function.
WT_SESSION
All data operations are performed in the context of a WT_SESSION.
Definition: wiredtiger.in:761