예제 #1
0
/*
 * rotn_decrypt --
 *	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_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);
}
예제 #2
0
/*
 * rotn_configure --
 *	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_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"));

	return (0);
}
예제 #3
0
/*
 * rotn_encrypt --
 *	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_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);
}
예제 #4
0
/*
 * rotn_configure --
 *	WiredTiger no-op encryption configuration.
 */
static int
rotn_configure(ROTN_ENCRYPTOR *rotn_encryptor, WT_CONFIG_ARG *config)
{
	WT_CONFIG_ITEM k, v;
	WT_CONFIG_PARSER *config_parser;
	WT_EXTENSION_API *wtext;	/* Extension API */
	int ret, t_ret;

	wtext = rotn_encryptor->wtext;

	/* Get the configuration string. */
	if ((ret = wtext->config_get(wtext, NULL, config, "config", &v)) != 0)
		return (rotn_error(rotn_encryptor, NULL, ret,
		    "WT_EXTENSION_API.config_get"));

	/* Step through the list of configuration options. */
	if ((ret = wtext->config_parser_open(
	    wtext, NULL, v.str, v.len, &config_parser)) != 0)
		return (rotn_error(rotn_encryptor, NULL, ret,
		    "WT_EXTENSION_API.config_parser_open"));

	while ((ret = config_parser->next(config_parser, &k, &v)) == 0) {
		if (strncmp("rotn_force_error", k.str, k.len) == 0 &&
		    strlen("rotn_force_error") == k.len) {
			rotn_encryptor->force_error = v.val == 0 ? 0 : 1;
			continue;
		} else {
			if ((ret = config_parser->close(config_parser)) != 0)
				return (rotn_error(rotn_encryptor,
				    NULL, ret, "WT_CONFIG_PARSER.close"));
			return (rotn_error(rotn_encryptor, NULL, EINVAL,
			    "unknown config key"));
		}
	}
	if ((t_ret = config_parser->close(config_parser)) != 0)
		return (rotn_error(rotn_encryptor, NULL, t_ret,
		    "WT_CONFIG_PARSER.close"));
	if (ret != WT_NOTFOUND)
		return (rotn_error(rotn_encryptor, NULL, ret,
		    "WT_CONFIG_PARSER.next"));

	return (0);
}
예제 #5
0
/*
 * rotn_customize --
 *	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)
{
	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);
}