summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c')
-rw-r--r--src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c582
1 files changed, 280 insertions, 302 deletions
diff --git a/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c b/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c
index 9b858e53430..8fc355c9d6c 100644
--- a/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c
+++ b/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c
@@ -66,71 +66,69 @@
/* Local encryptor structure. */
typedef struct {
- WT_ENCRYPTOR encryptor; /* Must come first */
+ WT_ENCRYPTOR encryptor; /* Must come first */
- WT_EXTENSION_API *wt_api; /* Extension API */
+ WT_EXTENSION_API *wt_api; /* Extension API */
- int rot_N; /* rotN value */
- char *keyid; /* Saved keyid */
- char *secretkey; /* Saved secretkey */
- u_char *shift_forw; /* Encrypt shift data from secretkey */
- u_char *shift_back; /* Decrypt shift data from secretkey */
- size_t shift_len; /* Length of shift* byte arrays */
- bool force_error; /* Force a decrypt error for testing */
+ int rot_N; /* rotN value */
+ char *keyid; /* Saved keyid */
+ char *secretkey; /* Saved secretkey */
+ u_char *shift_forw; /* Encrypt shift data from secretkey */
+ u_char *shift_back; /* Decrypt shift data from secretkey */
+ size_t shift_len; /* Length of shift* byte arrays */
+ bool force_error; /* Force a decrypt error for testing */
} ROTN_ENCRYPTOR;
/*! [WT_ENCRYPTOR initialization structure] */
-#define CHKSUM_LEN 4
-#define IV_LEN 16
+#define CHKSUM_LEN 4
+#define IV_LEN 16
/*
* rotn_error --
- * Display an error from this module in a standard way.
+ * Display an error from this module in a standard way.
*/
static int
-rotn_error(
- ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err, const char *msg)
+rotn_error(ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err, const char *msg)
{
- WT_EXTENSION_API *wt_api;
+ WT_EXTENSION_API *wt_api;
- wt_api = encryptor->wt_api;
- (void)wt_api->err_printf(wt_api, session,
- "rotn encryption: %s: %s",
- msg, wt_api->strerror(wt_api, NULL, err));
- return (err);
+ wt_api = encryptor->wt_api;
+ (void)wt_api->err_printf(
+ wt_api, session, "rotn encryption: %s: %s", msg, wt_api->strerror(wt_api, NULL, err));
+ return (err);
}
/*
* make_checksum --
- * This is where one would call a checksum function on the encrypted
- * buffer. Here we just put a constant value in it.
+ * This is where one would call a checksum function on the encrypted buffer. Here we just put a
+ * constant value in it.
*/
static void
make_checksum(uint8_t *dst)
{
- int i;
- /*
- * Assume array is big enough for the checksum.
- */
- for (i = 0; i < CHKSUM_LEN; i++)
- dst[i] = 'C';
+ int i;
+ /*
+ * Assume array is big enough for the checksum.
+ */
+ for (i = 0; i < CHKSUM_LEN; i++)
+ dst[i] = 'C';
}
/*
* make_iv --
- * This is where one would generate the initialization vector.
- * Here we just put a constant value in it.
+ * This is where one would generate the initialization vector. Here we just put a constant value
+ * in it.
*/
static void
make_iv(uint8_t *dst)
{
- int i;
- /*
- * Assume array is big enough for the initialization vector.
- */
- for (i = 0; i < IV_LEN; i++)
- dst[i] = 'I';
+ int i;
+ /*
+ * Assume array is big enough for the initialization vector.
+ */
+ for (i = 0; i < IV_LEN; i++)
+ dst[i] = 'I';
}
/*
@@ -138,352 +136,332 @@ make_iv(uint8_t *dst)
*/
/*
* do_rotate --
- * Perform rot-N on the buffer given.
+ * Perform rot-N on the buffer given.
*/
static void
do_rotate(char *buf, size_t len, int rotn)
{
- uint32_t i;
- /*
- * Now rotate.
- *
- * Avoid ctype functions because they behave in unexpected ways,
- * particularly when the locale is not "C".
- */
- for (i = 0; i < len; i++) {
- if ('a' <= buf[i] && buf[i] <= 'z')
- buf[i] = ((buf[i] - 'a') + rotn) % 26 + 'a';
- else if ('A' <= buf[i] && buf[i] <= 'Z')
- buf[i] = ((buf[i] - 'A') + rotn) % 26 + 'A';
- }
+ uint32_t i;
+ /*
+ * Now rotate.
+ *
+ * Avoid ctype functions because they behave in unexpected ways,
+ * particularly when the locale is not "C".
+ */
+ for (i = 0; i < len; i++) {
+ if ('a' <= buf[i] && buf[i] <= 'z')
+ buf[i] = ((buf[i] - 'a') + rotn) % 26 + 'a';
+ else if ('A' <= buf[i] && buf[i] <= 'Z')
+ buf[i] = ((buf[i] - 'A') + rotn) % 26 + 'A';
+ }
}
/*
* do_shift --
- * Perform a Vigenere cipher
+ * Perform a Vigenere cipher
*/
static void
do_shift(uint8_t *buf, size_t len, u_char *shift, size_t shiftlen)
{
- uint32_t i;
- /*
- * Now shift.
- */
- for (i = 0; i < len; i++)
- buf[i] += shift[i % shiftlen];
+ uint32_t i;
+ /*
+ * Now shift.
+ */
+ for (i = 0; i < len; i++)
+ buf[i] += shift[i % shiftlen];
}
/*! [WT_ENCRYPTOR encrypt] */
/*
* rotn_encrypt --
- * A simple encryption example that passes data through unchanged.
+ * A simple encryption example that passes data through unchanged.
*/
static int
-rotn_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)
+rotn_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)
{
- ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
- uint32_t i;
-
- (void)session; /* Unused */
-
- if (dst_len < src_len + CHKSUM_LEN + IV_LEN)
- return (rotn_error(rotn_encryptor, session,
- ENOMEM, "encrypt buffer not big enough"));
-
- /*
- * !!! Most implementations would verify any needed
- * checksum and initialize the IV here.
- */
- i = CHKSUM_LEN + IV_LEN;
- memcpy(&dst[i], &src[0], src_len);
- /*
- * Depending on whether we have a secret key or not,
- * call the common rotate or shift function on the text portion
- * of the destination buffer. Send in src_len as the length of
- * the text.
- */
- if (rotn_encryptor->shift_len == 0)
- do_rotate((char *)dst + i, src_len, rotn_encryptor->rot_N);
- else
- do_shift(&dst[i], src_len,
- rotn_encryptor->shift_forw, rotn_encryptor->shift_len);
- /*
- * Checksum the encrypted buffer and add the IV.
- */
- i = 0;
- make_checksum(&dst[i]);
- i += CHKSUM_LEN;
- make_iv(&dst[i]);
- *result_lenp = dst_len;
- return (0);
+ ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
+ uint32_t i;
+
+ (void)session; /* Unused */
+
+ if (dst_len < src_len + CHKSUM_LEN + IV_LEN)
+ return (rotn_error(rotn_encryptor, session, ENOMEM, "encrypt buffer not big enough"));
+
+ /*
+ * !!! Most implementations would verify any needed
+ * checksum and initialize the IV here.
+ */
+ i = CHKSUM_LEN + IV_LEN;
+ memcpy(&dst[i], &src[0], src_len);
+ /*
+ * Depending on whether we have a secret key or not, call the common rotate or shift function on
+ * the text portion of the destination buffer. Send in src_len as the length of the text.
+ */
+ if (rotn_encryptor->shift_len == 0)
+ do_rotate((char *)dst + i, src_len, rotn_encryptor->rot_N);
+ else
+ do_shift(&dst[i], src_len, rotn_encryptor->shift_forw, rotn_encryptor->shift_len);
+ /*
+ * Checksum the encrypted buffer and add the IV.
+ */
+ i = 0;
+ make_checksum(&dst[i]);
+ i += CHKSUM_LEN;
+ make_iv(&dst[i]);
+ *result_lenp = dst_len;
+ return (0);
}
/*! [WT_ENCRYPTOR encrypt] */
/*! [WT_ENCRYPTOR decrypt] */
/*
* rotn_decrypt --
- * A simple decryption example that passes data through unchanged.
+ * A simple decryption example that passes data through unchanged.
*/
static int
-rotn_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)
+rotn_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)
{
- ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
- size_t mylen;
- uint32_t i;
-
- (void)session; /* Unused */
-
- /*
- * For certain tests, force an error we can recognize.
- */
- if (rotn_encryptor->force_error)
- return (-1000);
-
- /*
- * Make sure it is big enough.
- */
- mylen = src_len - (CHKSUM_LEN + IV_LEN);
- if (dst_len < mylen)
- return (rotn_error(rotn_encryptor, session,
- ENOMEM, "decrypt buffer not big enough"));
-
- /*
- * !!! Most implementations would verify the checksum here.
- */
- /*
- * Copy the encrypted data to the destination buffer and then
- * decrypt the destination buffer.
- */
- i = CHKSUM_LEN + IV_LEN;
- memcpy(&dst[0], &src[i], mylen);
- /*
- * Depending on whether we have a secret key or not,
- * call the common rotate or shift function on the text portion
- * of the destination buffer. Send in dst_len as the length of
- * the text.
- */
- /*
- * !!! Most implementations would need the IV too.
- */
- if (rotn_encryptor->shift_len == 0)
- do_rotate((char *)dst, mylen, 26 - rotn_encryptor->rot_N);
- else
- do_shift(&dst[0], mylen,
- rotn_encryptor->shift_back, rotn_encryptor->shift_len);
- *result_lenp = mylen;
- return (0);
+ ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
+ size_t mylen;
+ uint32_t i;
+
+ (void)session; /* Unused */
+
+ /*
+ * For certain tests, force an error we can recognize.
+ */
+ if (rotn_encryptor->force_error)
+ return (-1000);
+
+ /*
+ * Make sure it is big enough.
+ */
+ mylen = src_len - (CHKSUM_LEN + IV_LEN);
+ if (dst_len < mylen)
+ return (rotn_error(rotn_encryptor, session, ENOMEM, "decrypt buffer not big enough"));
+
+ /*
+ * !!! Most implementations would verify the checksum here.
+ */
+ /*
+ * Copy the encrypted data to the destination buffer and then decrypt the destination buffer.
+ */
+ i = CHKSUM_LEN + IV_LEN;
+ memcpy(&dst[0], &src[i], mylen);
+ /*
+ * Depending on whether we have a secret key or not, call the common rotate or shift function on
+ * the text portion of the destination buffer. Send in dst_len as the length of the text.
+ */
+ /*
+ * !!! Most implementations would need the IV too.
+ */
+ if (rotn_encryptor->shift_len == 0)
+ do_rotate((char *)dst, mylen, 26 - rotn_encryptor->rot_N);
+ else
+ do_shift(&dst[0], mylen, rotn_encryptor->shift_back, rotn_encryptor->shift_len);
+ *result_lenp = mylen;
+ return (0);
}
/*! [WT_ENCRYPTOR decrypt] */
/*! [WT_ENCRYPTOR postsize] */
/*
* rotn_sizing --
- * A sizing example that returns the header size needed.
+ * A sizing example that returns the header size needed.
*/
static int
-rotn_sizing(WT_ENCRYPTOR *encryptor, WT_SESSION *session,
- size_t *expansion_constantp)
+rotn_sizing(WT_ENCRYPTOR *encryptor, WT_SESSION *session, size_t *expansion_constantp)
{
- (void)encryptor; /* Unused parameters */
- (void)session; /* Unused parameters */
+ (void)encryptor; /* Unused parameters */
+ (void)session; /* Unused parameters */
- *expansion_constantp = CHKSUM_LEN + IV_LEN;
- return (0);
+ *expansion_constantp = CHKSUM_LEN + IV_LEN;
+ return (0);
}
/*! [WT_ENCRYPTOR postsize] */
/*! [WT_ENCRYPTOR customize] */
/*
* rotn_customize --
- * The customize function creates a customized encryptor
+ * The customize function creates a customized encryptor
*/
static int
-rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session,
- WT_CONFIG_ARG *encrypt_config, WT_ENCRYPTOR **customp)
+rotn_customize(WT_ENCRYPTOR *encryptor, WT_SESSION *session, WT_CONFIG_ARG *encrypt_config,
+ WT_ENCRYPTOR **customp)
{
- const ROTN_ENCRYPTOR *orig;
- ROTN_ENCRYPTOR *rotn_encryptor;
- WT_CONFIG_ITEM keyid, secret;
- WT_EXTENSION_API *wt_api;
- size_t i, len;
- int ret, keyid_val;
- u_char base;
-
- ret = 0;
- keyid_val = 0;
-
- orig = (const ROTN_ENCRYPTOR *)encryptor;
- wt_api = orig->wt_api;
-
- if ((rotn_encryptor = calloc(1, sizeof(ROTN_ENCRYPTOR))) == NULL)
- return (errno);
- *rotn_encryptor = *orig;
- rotn_encryptor->keyid = rotn_encryptor->secretkey = NULL;
-
- /*
- * Stash the keyid from the configuration string.
- */
- if ((ret = wt_api->config_get(wt_api, session, encrypt_config,
- "keyid", &keyid)) == 0 && keyid.len != 0) {
- /*
- * In this demonstration, we expect keyid to be a number.
- */
- if ((keyid_val = atoi(keyid.str)) < 0) {
- ret = rotn_error(rotn_encryptor,
- NULL, EINVAL, "rotn_customize: invalid keyid");
- goto err;
- }
- if ((rotn_encryptor->keyid = malloc(keyid.len + 1)) == NULL) {
- ret = errno;
- goto err;
- }
- strncpy(rotn_encryptor->keyid, keyid.str, keyid.len + 1);
- rotn_encryptor->keyid[keyid.len] = '\0';
- }
-
- /*
- * In this demonstration, the secret key must be alphabetic characters.
- * We stash the secret key from the configuration string
- * and build some shift bytes to make encryption/decryption easy.
- */
- if ((ret = wt_api->config_get(wt_api, session, encrypt_config,
- "secretkey", &secret)) == 0 && secret.len != 0) {
- len = secret.len;
- if ((rotn_encryptor->secretkey = malloc(len + 1)) == NULL ||
- (rotn_encryptor->shift_forw = malloc(len)) == NULL ||
- (rotn_encryptor->shift_back = malloc(len)) == NULL) {
- ret = errno;
- goto err;
- }
- for (i = 0; i < len; i++) {
- if ('a' <= secret.str[i] && secret.str[i] <= 'z')
- base = 'a';
- else if ('A' <= secret.str[i] && secret.str[i] <= 'Z')
- base = 'A';
- else {
- ret = rotn_error(rotn_encryptor, NULL,
- EINVAL, "rotn_customize: invalid key");
- goto err;
- }
- base -= (u_char)keyid_val;
- rotn_encryptor->shift_forw[i] =
- (u_char)secret.str[i] - base;
- rotn_encryptor->shift_back[i] =
- base - (u_char)secret.str[i];
- }
- rotn_encryptor->shift_len = len;
- strncpy(rotn_encryptor->secretkey, secret.str, secret.len + 1);
- rotn_encryptor->secretkey[secret.len] = '\0';
- }
-
- /*
- * In a real encryptor, we could use some sophisticated key management
- * here to map the keyid onto a secret key.
- */
- rotn_encryptor->rot_N = keyid_val;
-
- *customp = (WT_ENCRYPTOR *)rotn_encryptor;
- return (0);
-
-err: free(rotn_encryptor->keyid);
- free(rotn_encryptor->secretkey);
- free(rotn_encryptor->shift_forw);
- free(rotn_encryptor->shift_back);
- free(rotn_encryptor);
- return (ret);
+ const ROTN_ENCRYPTOR *orig;
+ ROTN_ENCRYPTOR *rotn_encryptor;
+ WT_CONFIG_ITEM keyid, secret;
+ WT_EXTENSION_API *wt_api;
+ size_t i, len;
+ int ret, keyid_val;
+ u_char base;
+
+ ret = 0;
+ keyid_val = 0;
+
+ orig = (const ROTN_ENCRYPTOR *)encryptor;
+ wt_api = orig->wt_api;
+
+ if ((rotn_encryptor = calloc(1, sizeof(ROTN_ENCRYPTOR))) == NULL)
+ return (errno);
+ *rotn_encryptor = *orig;
+ rotn_encryptor->keyid = rotn_encryptor->secretkey = NULL;
+
+ /*
+ * Stash the keyid from the configuration string.
+ */
+ if ((ret = wt_api->config_get(wt_api, session, encrypt_config, "keyid", &keyid)) == 0 &&
+ keyid.len != 0) {
+ /*
+ * In this demonstration, we expect keyid to be a number.
+ */
+ if ((keyid_val = atoi(keyid.str)) < 0) {
+ ret = rotn_error(rotn_encryptor, NULL, EINVAL, "rotn_customize: invalid keyid");
+ goto err;
+ }
+ if ((rotn_encryptor->keyid = malloc(keyid.len + 1)) == NULL) {
+ ret = errno;
+ goto err;
+ }
+ strncpy(rotn_encryptor->keyid, keyid.str, keyid.len + 1);
+ rotn_encryptor->keyid[keyid.len] = '\0';
+ }
+
+ /*
+ * In this demonstration, the secret key must be alphabetic characters. We stash the secret key
+ * from the configuration string and build some shift bytes to make encryption/decryption easy.
+ */
+ if ((ret = wt_api->config_get(wt_api, session, encrypt_config, "secretkey", &secret)) == 0 &&
+ secret.len != 0) {
+ len = secret.len;
+ if ((rotn_encryptor->secretkey = malloc(len + 1)) == NULL ||
+ (rotn_encryptor->shift_forw = malloc(len)) == NULL ||
+ (rotn_encryptor->shift_back = malloc(len)) == NULL) {
+ ret = errno;
+ goto err;
+ }
+ for (i = 0; i < len; i++) {
+ if ('a' <= secret.str[i] && secret.str[i] <= 'z')
+ base = 'a';
+ else if ('A' <= secret.str[i] && secret.str[i] <= 'Z')
+ base = 'A';
+ else {
+ ret = rotn_error(rotn_encryptor, NULL, EINVAL, "rotn_customize: invalid key");
+ goto err;
+ }
+ base -= (u_char)keyid_val;
+ rotn_encryptor->shift_forw[i] = (u_char)secret.str[i] - base;
+ rotn_encryptor->shift_back[i] = base - (u_char)secret.str[i];
+ }
+ rotn_encryptor->shift_len = len;
+ strncpy(rotn_encryptor->secretkey, secret.str, secret.len + 1);
+ rotn_encryptor->secretkey[secret.len] = '\0';
+ }
+
+ /*
+ * In a real encryptor, we could use some sophisticated key management here to map the keyid
+ * onto a secret key.
+ */
+ rotn_encryptor->rot_N = keyid_val;
+
+ *customp = (WT_ENCRYPTOR *)rotn_encryptor;
+ return (0);
+
+err:
+ free(rotn_encryptor->keyid);
+ free(rotn_encryptor->secretkey);
+ free(rotn_encryptor->shift_forw);
+ free(rotn_encryptor->shift_back);
+ free(rotn_encryptor);
+ return (ret);
}
/*! [WT_ENCRYPTOR presize] */
/*! [WT_ENCRYPTOR terminate] */
/*
* rotn_terminate --
- * WiredTiger no-op encryption termination.
+ * WiredTiger no-op encryption termination.
*/
static int
rotn_terminate(WT_ENCRYPTOR *encryptor, WT_SESSION *session)
{
- ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
+ ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;
- (void)session; /* Unused parameters */
+ (void)session; /* Unused parameters */
- /* Free the allocated memory. */
- free(rotn_encryptor->secretkey);
- free(rotn_encryptor->keyid);
- free(rotn_encryptor->shift_forw);
- free(rotn_encryptor->shift_back);
- free(encryptor);
- return (0);
+ /* Free the allocated memory. */
+ free(rotn_encryptor->secretkey);
+ free(rotn_encryptor->keyid);
+ free(rotn_encryptor->shift_forw);
+ free(rotn_encryptor->shift_back);
+ free(encryptor);
+ return (0);
}
/*! [WT_ENCRYPTOR terminate] */
/*
* rotn_configure --
- * WiredTiger no-op encryption configuration.
+ * WiredTiger no-op encryption configuration.
*/
static int
rotn_configure(ROTN_ENCRYPTOR *rotn_encryptor, WT_CONFIG_ARG *config)
{
- WT_CONFIG_ITEM v;
- WT_EXTENSION_API *wt_api; /* Extension API */
- int ret;
+ WT_CONFIG_ITEM v;
+ WT_EXTENSION_API *wt_api; /* Extension API */
+ int ret;
- wt_api = rotn_encryptor->wt_api;
+ wt_api = rotn_encryptor->wt_api;
- /* Get the configuration string. */
- if ((ret = wt_api->config_get(
- wt_api, NULL, config, "rotn_force_error", &v)) == 0)
- rotn_encryptor->force_error = v.val != 0;
- else if (ret != WT_NOTFOUND)
- return (rotn_error(rotn_encryptor, NULL, EINVAL,
- "error parsing config"));
+ /* Get the configuration string. */
+ if ((ret = wt_api->config_get(wt_api, NULL, config, "rotn_force_error", &v)) == 0)
+ rotn_encryptor->force_error = v.val != 0;
+ else if (ret != WT_NOTFOUND)
+ return (rotn_error(rotn_encryptor, NULL, EINVAL, "error parsing config"));
- return (0);
+ return (0);
}
/*! [WT_ENCRYPTOR initialization function] */
/*
* wiredtiger_extension_init --
- * A simple shared library encryption example.
+ * A simple shared library encryption example.
*/
int
wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config)
{
- ROTN_ENCRYPTOR *rotn_encryptor;
- int ret;
-
- if ((rotn_encryptor = calloc(1, sizeof(ROTN_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.
- */
- rotn_encryptor->encryptor.encrypt = rotn_encrypt;
- rotn_encryptor->encryptor.decrypt = rotn_decrypt;
- rotn_encryptor->encryptor.sizing = rotn_sizing;
- rotn_encryptor->encryptor.customize = rotn_customize;
- rotn_encryptor->encryptor.terminate = rotn_terminate;
- rotn_encryptor->wt_api = connection->get_extension_api(connection);
-
- if ((ret = rotn_configure(rotn_encryptor, config)) != 0) {
- free(rotn_encryptor);
- return (ret);
- }
- /* Load the encryptor */
- if ((ret = connection->add_encryptor(
- connection, "rotn", (WT_ENCRYPTOR *)rotn_encryptor, NULL)) == 0)
- return (0);
-
- free(rotn_encryptor);
- return (ret);
+ ROTN_ENCRYPTOR *rotn_encryptor;
+ int ret;
+
+ if ((rotn_encryptor = calloc(1, sizeof(ROTN_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.
+ */
+ rotn_encryptor->encryptor.encrypt = rotn_encrypt;
+ rotn_encryptor->encryptor.decrypt = rotn_decrypt;
+ rotn_encryptor->encryptor.sizing = rotn_sizing;
+ rotn_encryptor->encryptor.customize = rotn_customize;
+ rotn_encryptor->encryptor.terminate = rotn_terminate;
+ rotn_encryptor->wt_api = connection->get_extension_api(connection);
+
+ if ((ret = rotn_configure(rotn_encryptor, config)) != 0) {
+ free(rotn_encryptor);
+ return (ret);
+ }
+ /* Load the encryptor */
+ if ((ret = connection->add_encryptor(
+ connection, "rotn", (WT_ENCRYPTOR *)rotn_encryptor, NULL)) == 0)
+ return (0);
+
+ free(rotn_encryptor);
+ return (ret);
}
/*! [WT_ENCRYPTOR initialization function] */