Пример #1
0
size_t Cipher::put(const unsigned char *data, size_t size)
{
    if(size % keys.iosize() || !bufaddr)
        return 0;

    size_t count = 0;

    while(bufsize && size + bufpos > bufsize) {
        size_t diff = bufsize - bufpos;
        count += put(data, diff);
        data += diff;
        size -= diff;
    }

    switch(bufmode) {
    case Cipher::ENCRYPT:
        gnutls_cipher_encrypt2((CIPHER_CTX)context, (void *)data, size, bufaddr + bufpos, size);
        break;
    case Cipher::DECRYPT:
        gnutls_cipher_decrypt2((CIPHER_CTX)context, data, size, bufaddr + bufpos, size);
    }

    count += size;
    if(!count) {
        release();
        return 0;
    }
    bufpos += size;
    if(bufsize && bufpos >= bufsize) {
        push(bufaddr, bufsize);
        bufpos = 0;
    }
    return count;
}
Пример #2
0
static void cipher_bench(int algo, int size, int aead)
{
	int ret;
	gnutls_cipher_hd_t ctx;
	void *_key, *_iv;
	gnutls_datum_t key, iv;
	int ivsize = gnutls_cipher_get_iv_size(algo);
	int keysize = gnutls_cipher_get_key_size(algo);
	int step = size * 1024;
	struct benchmark_st st;

	_key = malloc(keysize);
	if (_key == NULL)
		return;
	memset(_key, 0xf0, keysize);

	_iv = malloc(ivsize);
	if (_iv == NULL)
		return;
	memset(_iv, 0xf0, ivsize);

	iv.data = _iv;
	if (aead)
		iv.size = 12;
	else
		iv.size = ivsize;

	key.data = _key;
	key.size = keysize;

	printf("%16s ", gnutls_cipher_get_name(algo));
	fflush(stdout);

	start_benchmark(&st);

	ret = gnutls_cipher_init(&ctx, algo, &key, &iv);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		goto leave;
	}

	if (aead)
		gnutls_cipher_add_auth(ctx, data, 1024);

	do {
		gnutls_cipher_encrypt2(ctx, data, step, data, step + 64);
		st.size += step;
	}
	while (benchmark_must_finish == 0);

	gnutls_cipher_deinit(ctx);

	stop_benchmark(&st, NULL, 1);

      leave:
	free(_key);
	free(_iv);
}
Пример #3
0
static
int dcrypt_gnutls_ctx_sym_update(struct dcrypt_context_symmetric *ctx, const unsigned char *data, size_t data_len, buffer_t *result, const char **error_r)
{
	int ec;
	size_t outl = gnutls_cipher_get_block_size(ctx->cipher);
	unsigned char buf[outl];
	ec = gnutls_cipher_encrypt2(ctx->ctx, data, data_len, buf, outl);
	if(ec < 0) return dcrypt_gnutls_error(ec, error_r);
	buffer_append(result, buf, outl);
	return ec;
}
Пример #4
0
static gboolean
purple_aes_cipher_gnutls_encrypt(const guchar *input, guchar *output, size_t len,
	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
	PurpleCipherBatchMode batch_mode)
{
	gnutls_cipher_hd_t handle;
	int ret;

	/* We have to simulate ECB mode, which is not supported by GnuTLS. */
	if (batch_mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
		size_t i;
		for (i = 0; i < len / PURPLE_AES_BLOCK_SIZE; i++) {
			int offset = i * PURPLE_AES_BLOCK_SIZE;
			guchar iv_local[PURPLE_AES_BLOCK_SIZE];
			gboolean succ;

			memcpy(iv_local, iv, sizeof(iv_local));
			succ = purple_aes_cipher_gnutls_encrypt(
				input + offset, output + offset,
				PURPLE_AES_BLOCK_SIZE,
				iv_local, key, key_size,
				PURPLE_CIPHER_BATCH_MODE_CBC);
			if (!succ)
				return FALSE;
		}
		return TRUE;
	}

	handle = purple_aes_cipher_gnutls_crypt_init(iv, key, key_size);
	if (handle == NULL)
		return FALSE;

	ret = gnutls_cipher_encrypt2(handle, (guchar *)input, len, output, len);
	gnutls_cipher_deinit(handle);

	if (ret != 0) {
		purple_debug_error("cipher-aes",
			"gnutls_cipher_encrypt2 failed: %d\n", ret);
		return FALSE;
	}

	return TRUE;
}
Пример #5
0
static gboolean
purple_aes_cipher_gnutls_encrypt(const guchar *input, guchar *output, size_t len,
	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size)
{
	gnutls_cipher_hd_t handle;
	int ret;

	handle = purple_aes_cipher_gnutls_crypt_init(iv, key, key_size);
	if (handle == NULL)
		return FALSE;

	ret = gnutls_cipher_encrypt2(handle, (guchar *)input, len, output, len);
	gnutls_cipher_deinit(handle);

	if (ret != 0) {
		purple_debug_error("cipher-aes",
			"gnutls_cipher_encrypt2 failed: %d\n", ret);
		return FALSE;
	}

	return TRUE;
}
Пример #6
0
static void cipher_mac_bench(int algo, int mac_algo, int size)
{
	int ret;
	gnutls_cipher_hd_t ctx;
	gnutls_hmac_hd_t mac_ctx;
	void *_key, *_iv;
	gnutls_datum_t key, iv;
	int ivsize = gnutls_cipher_get_iv_size(algo);
	int keysize = gnutls_cipher_get_key_size(algo);
	int step = size * 1024;
	struct benchmark_st st;
	void *output, *input;
	unsigned char c, *i;

	_key = malloc(keysize);
	if (_key == NULL)
		return;
	memset(_key, 0xf0, keysize);

	_iv = malloc(ivsize);
	if (_iv == NULL) {
		free(_key);
		return;
	}
	memset(_iv, 0xf0, ivsize);

	iv.data = _iv;
	iv.size = ivsize;

	key.data = _key;
	key.size = keysize;

	assert(gnutls_rnd(GNUTLS_RND_NONCE, &c, 1) >= 0);

	printf("%19s-%s ", gnutls_cipher_get_name(algo),
	       gnutls_mac_get_name(mac_algo));
	fflush(stdout);

	ALLOCM(input, MAX_MEM);
	ALLOC(output);
	i = input;

	start_benchmark(&st);

	ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		goto leave;
	}

	ret = gnutls_cipher_init(&ctx, algo, &key, &iv);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		goto leave;
	}

	do {
		gnutls_hmac(mac_ctx, i, step);
		gnutls_cipher_encrypt2(ctx, i, step, output, step + 64);
		st.size += step;
		INC(input, i, step);
	}
	while (benchmark_must_finish == 0);

	gnutls_cipher_deinit(ctx);
	gnutls_hmac_deinit(mac_ctx, NULL);

	stop_benchmark(&st, NULL, 1);

      leave:
	FREE(input);
	FREE(output);
	free(_key);
	free(_iv);
}
Пример #7
0
static void cipher_bench(int algo, int size, int aead)
{
	int ret;
	gnutls_cipher_hd_t ctx;
	void *_key, *_iv;
	gnutls_aead_cipher_hd_t actx;
	gnutls_datum_t key, iv;
	int ivsize = gnutls_cipher_get_iv_size(algo);
	int keysize = gnutls_cipher_get_key_size(algo);
	int step = size * 1024;
	void *input, *output;
	struct benchmark_st st;
	unsigned char c, *i;

	_key = malloc(keysize);
	if (_key == NULL)
		return;
	memset(_key, 0xf0, keysize);

	_iv = malloc(ivsize);
	if (_iv == NULL) {
		free(_key);
		return;
	}
	memset(_iv, 0xf0, ivsize);

	iv.data = _iv;
	iv.size = ivsize;

	key.data = _key;
	key.size = keysize;

	printf("%24s ", gnutls_cipher_get_name(algo));
	fflush(stdout);
	assert(gnutls_rnd(GNUTLS_RND_NONCE, &c, 1) >= 0);

	ALLOCM(input, MAX_MEM);
	ALLOCM(output, step+64);
	i = input;

	start_benchmark(&st);

	if (algo == GNUTLS_CIPHER_NULL) {
		do {
			force_memcpy(output, i, step);
			st.size += step;
			INC(input, i, step);
		}
		while (benchmark_must_finish == 0);
	} else if (aead != 0) {
		unsigned tag_size = gnutls_cipher_get_tag_size(algo);
		size_t out_size;

		ret = gnutls_aead_cipher_init(&actx, algo, &key);
		if (ret < 0) {
			fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
			goto leave;
		}

		do {
			out_size = step+64;
			assert(gnutls_aead_cipher_encrypt(actx, iv.data, iv.size, NULL, 0, tag_size,
				i, step, output, &out_size) >= 0);
			st.size += step;
			INC(input, i, step);
		}
		while (benchmark_must_finish == 0);

		gnutls_aead_cipher_deinit(actx);
	} else {
		ret = gnutls_cipher_init(&ctx, algo, &key, &iv);
		if (ret < 0) {
			fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
			goto leave;
		}

		do {
			gnutls_cipher_encrypt2(ctx, i, step, output, step + 64);
			st.size += step;
			INC(input, i, step);
		}
		while (benchmark_must_finish == 0);

		gnutls_cipher_deinit(ctx);
	}
	stop_benchmark(&st, NULL, 1);

	FREE(input);
	FREE(output);
      leave:
	free(_key);
	free(_iv);
}
Пример #8
0
gchar *password_encrypt_gnutls(const gchar *password,
		const gchar *encryption_passphrase)
{
	/* Another, slightly inferior combination is AES-128-CBC + SHA-256.
	 * Any block cipher in CBC mode with keysize N and a hash algo with
	 * digest length 2*N would do. */
	gnutls_cipher_algorithm_t algo = GNUTLS_CIPHER_AES_256_CBC;
	gnutls_cipher_hd_t handle;
	gnutls_datum_t key, iv;
	int keylen, blocklen, ret;
	unsigned char *buf, *encbuf, *base, *output;
	guint rounds = prefs_common_get_prefs()->master_passphrase_pbkdf2_rounds;

	g_return_val_if_fail(password != NULL, NULL);
	g_return_val_if_fail(encryption_passphrase != NULL, NULL);

/*	ivlen = gnutls_cipher_get_iv_size(algo);*/
	keylen = gnutls_cipher_get_key_size(algo);
	blocklen = gnutls_cipher_get_block_size(algo);
/*	digestlen = gnutls_hash_get_len(digest); */

	/* Take the passphrase and compute a key derivation of suitable
	 * length to be used as encryption key for our block cipher. */
	key.data = _make_key_deriv(encryption_passphrase, rounds, keylen);
	key.size = keylen;

	/* Prepare random IV for cipher */
	iv.data = malloc(IVLEN);
	iv.size = IVLEN;
	if (!get_random_bytes(iv.data, IVLEN)) {
		g_free(key.data);
		g_free(iv.data);
		return NULL;
	}

	/* Initialize the encryption */
	ret = gnutls_cipher_init(&handle, algo, &key, &iv);
	if (ret < 0) {
		g_free(key.data);
		g_free(iv.data);
		return NULL;
	}

	/* Fill buf with one block of random data, our password, pad the
	 * rest with zero bytes. */
	buf = malloc(BUFSIZE + blocklen);
	memset(buf, 0, BUFSIZE);
	if (!get_random_bytes(buf, blocklen)) {
		g_free(buf);
		g_free(key.data);
		g_free(iv.data);
		gnutls_cipher_deinit(handle);
		return NULL;
	}

	memcpy(buf + blocklen, password, strlen(password));

	/* Encrypt into encbuf */
	encbuf = malloc(BUFSIZE + blocklen);
	memset(encbuf, 0, BUFSIZE + blocklen);
	ret = gnutls_cipher_encrypt2(handle, buf, BUFSIZE + blocklen,
			encbuf, BUFSIZE + blocklen);
	if (ret < 0) {
		g_free(key.data);
		g_free(iv.data);
		g_free(buf);
		g_free(encbuf);
		gnutls_cipher_deinit(handle);
		return NULL;
	}

	/* Cleanup */
	gnutls_cipher_deinit(handle);
	g_free(key.data);
	g_free(iv.data);
	g_free(buf);

	/* And finally prepare the resulting string:
	 * "{algorithm,rounds}base64encodedciphertext" */
	base = g_base64_encode(encbuf, BUFSIZE);
	g_free(encbuf);
	output = g_strdup_printf("{%s,%d}%s",
			gnutls_cipher_get_name(algo), rounds, base);
	g_free(base);

	return output;
}
Пример #9
0
char *
crypto_encrypt (const char *cipher,
                const GByteArray *data,
                const char *iv,
                const gsize iv_len,
                const char *key,
                gsize key_len,
                gsize *out_len,
                GError **error)
{
	gnutls_cipher_hd_t ctx;
	gnutls_datum_t key_dt, iv_dt;
	int err;
	int cipher_mech;
	char *output = NULL;
	gboolean success = FALSE;
	gsize padded_buf_len, pad_len, output_len;
	char *padded_buf = NULL;
	guint32 i;
	gsize salt_len;

	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
		cipher_mech = GNUTLS_CIPHER_3DES_CBC;
		salt_len = SALT_LEN;
	} else if (!strcmp (cipher, CIPHER_AES_CBC)) {
		cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
		salt_len = iv_len;
	} else {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_UNKNOWN_CIPHER,
		             _("Private key cipher '%s' was unknown."),
		             cipher);
		return NULL;
	}

	/* If data->len % ivlen == 0, then we add another complete block
	 * onto the end so that the decrypter knows there's padding.
	 */
	pad_len = iv_len - (data->len % iv_len);
	output_len = padded_buf_len = data->len + pad_len;
	padded_buf = g_malloc0 (padded_buf_len);

	memcpy (padded_buf, data->data, data->len);
	for (i = 0; i < pad_len; i++)
		padded_buf[data->len + i] = (guint8) (pad_len & 0xFF);

	output = g_malloc0 (output_len);

	key_dt.data = (unsigned char *) key;
	key_dt.size = key_len;
	iv_dt.data = (unsigned char *) iv;
	iv_dt.size = iv_len;

	err = gnutls_cipher_init (&ctx, cipher_mech, &key_dt, &iv_dt);
	if (err < 0) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_INIT_FAILED,
		             _("Failed to initialize the encryption cipher context: %s (%s)"),
		             gnutls_strerror_name (err), gnutls_strerror (err));
		goto out;
	}

	err = gnutls_cipher_encrypt2 (ctx, padded_buf, padded_buf_len, output, output_len);
	if (err < 0) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
		             _("Failed to encrypt the data: %s (%s)"),
		             gnutls_strerror_name (err), gnutls_strerror (err));
		goto out;
	}

	*out_len = output_len;
	success = TRUE;

out:
	if (padded_buf) {
		memset (padded_buf, 0, padded_buf_len);
		g_free (padded_buf);
		padded_buf = NULL;
	}

	if (!success) {
		if (output) {
			/* Don't expose key material */
			memset (output, 0, output_len);
			g_free (output);
			output = NULL;
		}
	}
	gnutls_cipher_deinit (ctx);
	return output;
}