/*
 * Copyright (c) 2026 Andrian Budantsov
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "crypto/des-rfb.h"

#include <string.h>
#include <nettle/des.h>

static void des_rfb_reverse_bits(uint8_t* dst, const char* src)
{
	for (int i = 0; i < 8; i++) {
		uint8_t b = (uint8_t)src[i];
		b = ((b & 0xf0) >> 4) | ((b & 0x0f) << 4);
		b = ((b & 0xcc) >> 2) | ((b & 0x33) << 2);
		b = ((b & 0xaa) >> 1) | ((b & 0x55) << 1);
		dst[i] = b;
	}
}

void crypto_des_rfb_encrypt(uint8_t* dst, const uint8_t* src,
		const char* password)
{
	char key[8] = {};
	size_t len = strlen(password);
	if (len > 8)
		len = 8;
	memcpy(key, password, len);

	uint8_t vnc_key[8];
	des_rfb_reverse_bits(vnc_key, key);

	struct des_ctx ctx;
	des_set_key(&ctx, vnc_key);
	des_encrypt(&ctx, 8, dst, src);
	des_encrypt(&ctx, 8, dst + 8, src + 8);
}
