Пример #1
0
//
// Flatten the valid iolist to the buffer of
// appropriate size pointed to by ptr
//
uint8_t *iolist_flatten(term_t l, uint8_t *ptr)
{
	if (is_nil(l))
		return ptr;

	if (is_cons(l))
	{
		do {
			uint32_t *term_data = peel_cons(l);
			term_t e = term_data[0];
			if (is_int(e))
				*ptr++ = int_value(e);
			else
			{
				assert(is_list(e) || (is_boxed(e) && is_binary(peel_boxed(e))));
				ptr = iolist_flatten(e, ptr);
			}
			l = term_data[1];
			if (is_boxed(l) && is_binary(peel_boxed(l)))
				return iolist_flatten(l, ptr);
		} while (is_cons(l));

		assert(is_nil(l));
	}
	else // is_binary()
	{
		bits_t bs, to;
		bits_get_real(peel_boxed(l), &bs);
		bits_init_buf(ptr, (bs.ends +7) /8, &to);
		ptr += (bs.ends - bs.starts) /8;
		bits_copy(&bs, &to);
		assert(bs.starts == bs.ends);
	}
	return ptr;
}
Пример #2
0
term_t cbif_exor2(proc_t *proc, term_t *regs)
{
	term_t Bin1 = regs[0];
	term_t Bin2 = regs[1];

	if (!is_list(Bin1) && !is_boxed_binary(Bin1))
		badarg(Bin1);
	if (!is_list(Bin2) && !is_boxed_binary(Bin2))
		badarg(Bin2);

	int sz1 = iolist_size(Bin1);
	if (sz1 < 0)
		badarg(Bin1);
	int sz2 = iolist_size(Bin2);
	if (sz2 != sz1)
		badarg(Bin2);
	assert(sz1 <= 65536);	//TODO: use heap_tmp_buf for larger binaries
	uint8_t data1[sz1];
	iolist_flatten(Bin1, data1);
	uint8_t data2[sz2];
	iolist_flatten(Bin2, data2);

	uint8_t *data3;
	term_t result = heap_make_bin(&proc->hp, sz1, &data3);
	for (int i = 0; i < sz1; i++)
		data3[i] = data1[i] ^ data2[i];

	return result;
}
Пример #3
0
term_t cbif_aes_cbc_crypt4(proc_t *proc, term_t *regs)
{
	term_t Key = regs[0];
	term_t IVec = regs[1];
	term_t Data = regs[2];
	term_t Dir = regs[3];

	if (!is_list(Key) && !is_boxed_binary(Key))
		badarg(Key);
	if (!is_boxed_binary(IVec))
		badarg(IVec);
	if (!is_list(Data) && !is_boxed_binary(Data))
		badarg(Data);
	if (!is_bool(Dir))
		badarg(Dir);

	int key_size = iolist_size(Key);
	if (key_size < AES_MIN_KEY_SIZE || key_size > AES_MAX_KEY_SIZE)
		badarg(Key);
	uint8_t key_buf[key_size];
	iolist_flatten(Key, key_buf);

	bits_t src, dst;
	bits_get_real(peel_boxed(IVec), &src);
	if (src.ends -src.starts != AES_BLOCK_SIZE *8)
		badarg(IVec);
	uint8_t ivec_buf[AES_BLOCK_SIZE];
	bits_init_buf(ivec_buf, AES_BLOCK_SIZE, &dst);
	bits_copy(&src, &dst);

	int data_size = iolist_size(Data);
	if (data_size < 0)
		badarg(Data);
	assert(data_size <= 65536);		//TODO: use heap_tmp_buf for larger Data
	uint8_t data_buf[data_size];
	iolist_flatten(Data, data_buf);

	struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) ctx;

	if (Dir == A_TRUE)
		aes_set_encrypt_key((struct aes_ctx *)&ctx, key_size, key_buf);
	else
		aes_set_decrypt_key((struct aes_ctx *)&ctx, key_size, key_buf);

	CBC_SET_IV(&ctx, ivec_buf);

	uint8_t *ptr;
	term_t cipher_text = heap_make_bin(&proc->hp, data_size, &ptr);

	if (Dir == A_TRUE)
		CBC_ENCRYPT(&ctx, aes_encrypt, data_size, ptr, data_buf);
	else
		CBC_DECRYPT(&ctx, aes_decrypt, data_size, ptr, data_buf);

	return cipher_text;
}
Пример #4
0
term_t cbif_sha_update2(proc_t *proc, term_t *regs)
{
	term_t Context = regs[0];
	term_t Data = regs[1];

	if (!is_boxed_binary(Context))
		badarg(Context);

	bits_t bs, dst;
	bits_get_real(peel_boxed(Context), &bs);
	if (bs.ends -bs.starts != sizeof(struct sha1_ctx) *8)
		badarg(Context);

	struct sha1_ctx ctx;
	bits_init_buf((uint8_t *)&ctx, sizeof(ctx), &dst);
	bits_copy(&bs, &dst);

	if (!is_boxed_binary(Data) && !is_list(Data))
		badarg(Data);

	int sz = iolist_size(Data);
	if (sz < 0)
		badarg(Data);
	assert(sz <= 65536);	//TODO: use heap_tmp_buf for larger Data
	uint8_t buf[sz];
	iolist_flatten(Data, buf);

	sha1_update(&ctx, sz, buf);

	uint8_t *ptr;
	term_t bin = heap_make_bin(&proc->hp, sizeof(ctx), &ptr);
	memcpy(ptr, &ctx, sizeof(ctx));

	return bin;
}
Пример #5
0
term_t cbif_sha_mac_n3(proc_t *proc, term_t *regs)
{
	term_t Key = regs[0];
	term_t Data = regs[1];
	term_t Size = regs[2];

	if (!is_list(Key) && !is_boxed_binary(Key))
		badarg(Key);
	if (!is_list(Data) && !is_boxed_binary(Data))
		badarg(Data);
	if (!is_int(Size))
		badarg(Size);

	int trunc_size = int_value(Size);
	if (trunc_size < 1 || trunc_size > SHA1_DIGEST_SIZE)
		badarg(Size);

	int key_size = iolist_size(Key);
	if (key_size < 0)
		badarg(Key);
	assert(key_size <= 65536);	// TODO: use heap_tmp_buf for a longer Key
	uint8_t key_buf[key_size];
	iolist_flatten(Key, key_buf);

	int data_size = iolist_size(Data);
	if (data_size < 0)
		badarg(Data);
	assert(data_size <= 65536);	// TODO: use heap_tmp_buf for larger Data
	uint8_t data_buf[data_size];
	iolist_flatten(Data, data_buf);

	struct hmac_sha1_ctx ctx;
	hmac_sha1_set_key(&ctx, key_size, key_buf);
	hmac_sha1_update(&ctx, data_size, data_buf);

	uint8_t *ptr;
	term_t mac = heap_make_bin(&proc->hp, trunc_size, &ptr);
	hmac_sha1_digest(&ctx, trunc_size, ptr);

	return mac;
}
Пример #6
0
term_t cbif_sha1(proc_t *proc, term_t *regs)
{
	term_t Data = regs[0];

	if (!is_boxed_binary(Data) && !is_list(Data))
		badarg(Data);

	int sz = iolist_size(Data);
	if (sz < 0)
		badarg(Data);
	assert(sz <= 65536);	//TODO: use heap_tmp_buf for larger Data
	uint8_t buf[sz];
	iolist_flatten(Data, buf);

	struct sha1_ctx ctx;
	sha1_init(&ctx);
	sha1_update(&ctx, sz, buf);

	uint8_t *ptr;
	term_t bin = heap_make_bin(&proc->hp, SHA1_DIGEST_SIZE, &ptr);
	sha1_digest(&ctx, SHA1_DIGEST_SIZE, ptr);

	return bin;
}