Blame winpr/libwinpr/crypto/test/TestCryptoCipher.c

Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/print.h>
Packit 1fb8d4
#include <winpr/crypto.h>
Packit 1fb8d4
#include <winpr/ssl.h>
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
static BOOL test_crypto_cipher_aes_128_cbc()
Packit 1fb8d4
{
Packit 1fb8d4
	WINPR_CIPHER_CTX* ctx;
Packit 1fb8d4
	BOOL result = FALSE;
Packit 1fb8d4
	BYTE key[] = "0123456789abcdeF";
Packit 1fb8d4
	BYTE iv[] = "1234567887654321";
Packit 1fb8d4
	BYTE ibuf[1024];
Packit 1fb8d4
	BYTE obuf[1024];
Packit 1fb8d4
	size_t ilen;
Packit 1fb8d4
	size_t olen;
Packit 1fb8d4
	size_t xlen;
Packit 1fb8d4
	const char plaintext[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
Packit 1fb8d4
Packit 1fb8d4
	/* encrypt */
Packit 1fb8d4
Packit 1fb8d4
	if (!(ctx = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_ENCRYPT, key, iv)))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_Cipher_New (encrypt) failed\n", __FUNCTION__);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	memset(ibuf, 0, sizeof(ibuf));
Packit 1fb8d4
	memset(obuf, 0, sizeof(obuf));
Packit 1fb8d4
Packit 1fb8d4
	ilen = strlen(plaintext) + 1;
Packit 1fb8d4
	memcpy(ibuf, plaintext, ilen);
Packit 1fb8d4
Packit 1fb8d4
	ilen = ((ilen + 15) / 16) * 16;
Packit 1fb8d4
	olen = 0;
Packit 1fb8d4
	xlen = 0;
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Cipher_Update(ctx, ibuf, ilen, obuf, &olen))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_Cipher_New (encrypt) failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
	xlen += olen;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Cipher_Final(ctx, obuf + xlen, &olen))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_Cipher_Final (encrypt) failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
	xlen += olen;
Packit 1fb8d4
Packit 1fb8d4
	if (xlen != ilen)
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: error, xlen (%"PRIuz") != ilen (%"PRIuz") (encrypt)\n", __FUNCTION__, xlen, ilen);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	winpr_Cipher_Free(ctx);
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
	/* decrypt */
Packit 1fb8d4
Packit 1fb8d4
	if (!(ctx = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, key, iv)))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_Cipher_New (decrypt) failed\n", __FUNCTION__);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	memset(ibuf, 0, sizeof(ibuf));
Packit 1fb8d4
	memcpy(ibuf, obuf, xlen);
Packit 1fb8d4
	memset(obuf, 0, sizeof(obuf));
Packit 1fb8d4
Packit 1fb8d4
	ilen = xlen;
Packit 1fb8d4
	olen = 0;
Packit 1fb8d4
	xlen = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Cipher_Update(ctx, ibuf, ilen, obuf, &olen))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_Cipher_New (decrypt) failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
	xlen += olen;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Cipher_Final(ctx, obuf + xlen, &olen))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_Cipher_Final (decrypt) failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
	xlen += olen;
Packit 1fb8d4
Packit 1fb8d4
	if (xlen != ilen)
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: error, xlen (%"PRIuz") != ilen (%"PRIuz") (decrypt)\n", __FUNCTION__, xlen, ilen);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (strcmp((const char*) obuf, plaintext))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: error, decrypted data does not match plaintext\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	result = TRUE;
Packit 1fb8d4
Packit 1fb8d4
out:
Packit 1fb8d4
	winpr_Cipher_Free(ctx);
Packit 1fb8d4
	return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static const BYTE* TEST_RC4_KEY = (BYTE*) "Key";
Packit 1fb8d4
static const char* TEST_RC4_PLAINTEXT = "Plaintext";
Packit 1fb8d4
static const BYTE* TEST_RC4_CIPHERTEXT = (BYTE*) "\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3";
Packit 1fb8d4
Packit 1fb8d4
static BOOL test_crypto_cipher_rc4()
Packit 1fb8d4
{
Packit 1fb8d4
	size_t len;
Packit 1fb8d4
	BOOL rc = FALSE;
Packit 1fb8d4
	BYTE* text = NULL;
Packit 1fb8d4
	WINPR_RC4_CTX* ctx;
Packit 1fb8d4
Packit 1fb8d4
	len = strlen(TEST_RC4_PLAINTEXT);
Packit 1fb8d4
Packit 1fb8d4
	if (!(text = (BYTE*) calloc(1, len)))
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: failed to allocate text buffer (len=%"PRIuz")\n", __FUNCTION__, len);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if ((ctx = winpr_RC4_New(TEST_RC4_KEY, strlen((char*) TEST_RC4_KEY))) == NULL)
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_RC4_New failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
	rc = winpr_RC4_Update(ctx, len, (BYTE*) TEST_RC4_PLAINTEXT, text);
Packit 1fb8d4
	winpr_RC4_Free(ctx);
Packit 1fb8d4
	if (!rc)
Packit 1fb8d4
	{
Packit 1fb8d4
		fprintf(stderr, "%s: winpr_RC4_Update failed\n", __FUNCTION__);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (memcmp(text, TEST_RC4_CIPHERTEXT, len) != 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		char* actual;
Packit 1fb8d4
		char* expected;
Packit 1fb8d4
Packit 1fb8d4
		actual = winpr_BinToHexString(text, len, FALSE);
Packit 1fb8d4
		expected = winpr_BinToHexString(TEST_RC4_CIPHERTEXT, len, FALSE);
Packit 1fb8d4
Packit 1fb8d4
		fprintf(stderr, "%s: unexpected RC4 ciphertext: Actual: %s Expected: %s\n", __FUNCTION__, actual, expected);
Packit 1fb8d4
Packit 1fb8d4
		free(actual);
Packit 1fb8d4
		free(expected);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	rc = TRUE;
Packit 1fb8d4
Packit 1fb8d4
out:
Packit 1fb8d4
	free(text);
Packit 1fb8d4
	return rc;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static const BYTE* TEST_RAND_DATA = (BYTE*)
Packit 1fb8d4
	"\x1F\xC2\xEE\x4C\xA3\x66\x80\xA2\xCE\xFE\x56\xB4\x9E\x08\x30\x96"
Packit 1fb8d4
	"\x33\x6A\xA9\x6D\x36\xFD\x3C\xB7\x83\x04\x4E\x5E\xDC\x22\xCD\xF3"
Packit 1fb8d4
	"\x48\xDF\x3A\x2A\x61\xF1\xA8\xFA\x1F\xC6\xC7\x1B\x81\xB4\xE1\x0E"
Packit 1fb8d4
	"\xCB\xA2\xEF\xA1\x12\x4A\x83\xE5\x1D\x72\x1D\x2D\x26\xA8\x6B\xC0";
Packit 1fb8d4
Packit 1fb8d4
static const BYTE* TEST_CIPHER_KEY = (BYTE*)
Packit 1fb8d4
	"\x9D\x7C\xC0\xA1\x94\x3B\x07\x67\x2F\xD3\x83\x10\x51\x83\x38\x0E"
Packit 1fb8d4
	"\x1C\x74\x8C\x4E\x15\x79\xD6\xFF\xE2\xF0\x37\x7F\x8C\xD7\xD2\x13";
Packit 1fb8d4
Packit 1fb8d4
static const BYTE* TEST_CIPHER_IV = (BYTE*)
Packit 1fb8d4
	"\xFE\xE3\x9F\xF0\xD1\x5E\x37\x0C\xAB\xAB\x9B\x04\xF3\xDB\x99\x15";
Packit 1fb8d4
Packit 1fb8d4
static BOOL test_crypto_cipher_key()
Packit 1fb8d4
{
Packit 1fb8d4
	int status;
Packit 1fb8d4
	BYTE key[32];
Packit 1fb8d4
	BYTE iv[16];
Packit 1fb8d4
	BYTE salt[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(key, sizeof(key));
Packit 1fb8d4
	ZeroMemory(iv, sizeof(iv));
Packit 1fb8d4
Packit 1fb8d4
	status = winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1,
Packit 1fb8d4
			salt, TEST_RAND_DATA, 64, 4, key, iv);
Packit 1fb8d4
Packit 1fb8d4
	if (status != 32 || memcmp(key, TEST_CIPHER_KEY, 32) || memcmp(iv, TEST_CIPHER_IV, 16))
Packit 1fb8d4
	{
Packit 1fb8d4
		char* akstr;
Packit 1fb8d4
		char* ekstr;
Packit 1fb8d4
		char* aivstr;
Packit 1fb8d4
		char* eivstr;
Packit 1fb8d4
Packit 1fb8d4
		akstr = winpr_BinToHexString(key, 32, 0);
Packit 1fb8d4
		ekstr = winpr_BinToHexString(TEST_CIPHER_KEY, 32, 0);
Packit 1fb8d4
Packit 1fb8d4
		aivstr = winpr_BinToHexString(iv, 16, 0);
Packit 1fb8d4
		eivstr = winpr_BinToHexString(TEST_CIPHER_IV, 16, 0);
Packit 1fb8d4
Packit 1fb8d4
		fprintf(stderr, "Unexpected EVP_BytesToKey Key: Actual: %s, Expected: %s\n", akstr, ekstr);
Packit 1fb8d4
		fprintf(stderr, "Unexpected EVP_BytesToKey IV : Actual: %s, Expected: %s\n", aivstr, eivstr);
Packit 1fb8d4
Packit 1fb8d4
		free(akstr);
Packit 1fb8d4
		free(ekstr);
Packit 1fb8d4
		free(aivstr);
Packit 1fb8d4
		free(eivstr);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int TestCryptoCipher(int argc, char* argv[])
Packit 1fb8d4
{
Packit 1fb8d4
	winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
Packit 1fb8d4
Packit 1fb8d4
	if (!test_crypto_cipher_aes_128_cbc())
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	if (!test_crypto_cipher_rc4())
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	if (!test_crypto_cipher_key())
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}