예제 #1
0
themis_status_t secure_session_wrap(secure_session_t *session_ctx, const void *message, size_t message_length, void *wrapped_message, size_t *wrapped_message_length)
{
	uint32_t *session_id = (uint32_t *)wrapped_message;
	uint8_t *iv = (uint8_t *)(session_id + 1);
	uint32_t *length = (uint32_t *)(iv + CIPHER_MAX_BLOCK_SIZE);
	uint32_t *seq = length + 1;
	uint8_t *ts = (uint8_t *)(seq + 1);

	uint64_t curr_time;
	themis_status_t res;

	if ((NULL == session_ctx) || (NULL == message) || (0 == message_length) || (NULL == wrapped_message_length))
	{
		return THEMIS_INVALID_PARAMETER;
	}

	if ((NULL == wrapped_message) || (WRAPPED_SIZE(message_length) > *wrapped_message_length))
	{
		*wrapped_message_length = WRAPPED_SIZE(message_length);
		return THEMIS_BUFFER_TOO_SMALL;
	}

	curr_time = time(NULL);
	if (-1 == curr_time)
	{
		return THEMIS_FAIL;
	}

	*((uint64_t *)ts) = htobe64(curr_time);

	*wrapped_message_length = WRAPPED_SIZE(message_length);
	memmove(ts + 8, message, message_length);

	*seq = htonl(session_ctx->out_seq);
	*length = htonl(message_length + sizeof(uint32_t) + sizeof(uint64_t));

	res = soter_rand(iv, CIPHER_MAX_BLOCK_SIZE);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	res = encrypt_gcm(session_ctx->out_cipher_key, sizeof(session_ctx->out_cipher_key), iv, CIPHER_MAX_BLOCK_SIZE, length, message_length + sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint32_t), length, message_length + sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint32_t) + CIPHER_AUTH_TAG_SIZE);
	if (THEMIS_SUCCESS != res)
	{
		return res;
	}

	*session_id = htonl(session_ctx->session_id);
	session_ctx->out_seq++;

	return THEMIS_SUCCESS;
}
예제 #2
0
void encrypt_box(uint8_t *keys, box *outer, size_t len) {
    box *inner = (box *) outer->data;

    uint8_t *outer_key = keys;
    uint8_t *inner_key = keys + BOX_KEY_LEN;

    randombytes(outer->iv, BOX_IV_LEN);
    randombytes(inner->iv, BOX_IV_LEN);

    uint8_t *data = inner->tag;
    size_t inner_len = len + crypto_secretbox_ZEROBYTES;
    memset(data, 0, crypto_secretbox_ZEROBYTES);
    assert(crypto_secretbox(data, data, inner_len, inner->iv, inner_key) == 0);

    encrypt_gcm(outer_key, outer->iv, outer->data, sizeof(box) + len, outer->tag);
}