FreeRDP
Loading...
Searching...
No Matches
TestCryptoCipher.c
1
2#include <winpr/crt.h>
3#include <winpr/print.h>
4#include <winpr/crypto.h>
5#include <winpr/ssl.h>
6
7static BOOL test_crypto_cipher_aes_128_cbc(BOOL ex)
8{
9 BOOL result = FALSE;
10 BYTE key[16] = "0123456789abcdeF";
11 BYTE iv[16] = "1234567887654321";
12 BYTE ibuf[1024] = WINPR_C_ARRAY_INIT;
13 BYTE obuf[1024] = WINPR_C_ARRAY_INIT;
14 size_t ilen = 0;
15 size_t olen = 0;
16 size_t xlen = 0;
17 const char plaintext[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
18 "eiusmod tempor incididunt ut labore et dolore magna aliqua.";
19
20 /* encrypt */
21
22 WINPR_CIPHER_CTX* ctx = nullptr;
23 if (ex)
24 ctx = winpr_Cipher_NewEx(WINPR_CIPHER_AES_128_CBC, WINPR_ENCRYPT, key, sizeof(key), iv,
25 sizeof(iv));
26 else
27 {
28#if !defined(WITHOUT_WINPR_3x_DEPRECATED)
29 ctx = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_ENCRYPT, key, iv);
30#else
31 printf("%s: Function winpr_Cipher_New deprectated, build with WITHOUT_WINPR_3x_DEPRECATED, "
32 "skipping test\n",
33 __func__);
34 return TRUE;
35#endif
36 }
37 if (!ctx)
38 {
39 (void)fprintf(stderr, "%s: winpr_Cipher_New (encrypt) failed\n", __func__);
40 return FALSE;
41 }
42
43 ilen = strnlen(plaintext, sizeof(plaintext)) + 1;
44 memcpy(ibuf, plaintext, ilen);
45
46 ilen = ((ilen + 15) / 16) * 16;
47 olen = 0;
48 xlen = 0;
49
50 if (!winpr_Cipher_Update(ctx, ibuf, ilen, obuf, &olen))
51 {
52 (void)fprintf(stderr, "%s: winpr_Cipher_New (encrypt) failed\n", __func__);
53 goto out;
54 }
55 xlen += olen;
56
57 if (!winpr_Cipher_Final(ctx, obuf + xlen, &olen))
58 {
59 (void)fprintf(stderr, "%s: winpr_Cipher_Final (encrypt) failed\n", __func__);
60 goto out;
61 }
62 xlen += olen;
63
64 if (xlen != ilen)
65 {
66 (void)fprintf(stderr, "%s: error, xlen (%" PRIuz ") != ilen (%" PRIuz ") (encrypt)\n",
67 __func__, xlen, ilen);
68 goto out;
69 }
70
71 winpr_Cipher_Free(ctx);
72 ctx = nullptr;
73
74 /* decrypt */
75
76 if (ex)
77 ctx = winpr_Cipher_NewEx(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, key, sizeof(key), iv,
78 sizeof(iv));
79 else
80 {
81#if !defined(WITHOUT_WINPR_3x_DEPRECATED)
82
83 ctx = winpr_Cipher_New(WINPR_CIPHER_AES_128_CBC, WINPR_DECRYPT, key, iv);
84#else
85 printf("%s: Function winpr_Cipher_New deprectated, build with WITHOUT_WINPR_3x_DEPRECATED, "
86 "skipping test\n",
87 __func__);
88 return TRUE;
89#endif
90 }
91
92 if (!ctx)
93 {
94 (void)fprintf(stderr, "%s: winpr_Cipher_New (decrypt) failed\n", __func__);
95 return FALSE;
96 }
97
98 memset(ibuf, 0, sizeof(ibuf));
99 memcpy(ibuf, obuf, xlen);
100 memset(obuf, 0, sizeof(obuf));
101
102 ilen = xlen;
103 olen = 0;
104 xlen = 0;
105
106 if (!winpr_Cipher_Update(ctx, ibuf, ilen, obuf, &olen))
107 {
108 (void)fprintf(stderr, "%s: winpr_Cipher_New (decrypt) failed\n", __func__);
109 goto out;
110 }
111 xlen += olen;
112
113 if (!winpr_Cipher_Final(ctx, obuf + xlen, &olen))
114 {
115 (void)fprintf(stderr, "%s: winpr_Cipher_Final (decrypt) failed\n", __func__);
116 goto out;
117 }
118 xlen += olen;
119
120 if (xlen != ilen)
121 {
122 (void)fprintf(stderr, "%s: error, xlen (%" PRIuz ") != ilen (%" PRIuz ") (decrypt)\n",
123 __func__, xlen, ilen);
124 goto out;
125 }
126
127 if (strcmp((const char*)obuf, plaintext) != 0)
128 {
129 (void)fprintf(stderr, "%s: error, decrypted data does not match plaintext\n", __func__);
130 goto out;
131 }
132
133 result = TRUE;
134
135out:
136 winpr_Cipher_Free(ctx);
137 return result;
138}
139
140static const char TEST_RC4_KEY[] = "Key";
141static const char TEST_RC4_PLAINTEXT[] = "Plaintext";
142static const char TEST_RC4_CIPHERTEXT[] = "\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3";
143
144static BOOL test_crypto_cipher_rc4(void)
145{
146 BOOL rc = FALSE;
147 WINPR_RC4_CTX* ctx = nullptr;
148
149 const size_t len = strnlen(TEST_RC4_PLAINTEXT, sizeof(TEST_RC4_PLAINTEXT));
150 BYTE* text = (BYTE*)calloc(1, len);
151 if (!text)
152 {
153 (void)fprintf(stderr, "%s: failed to allocate text buffer (len=%" PRIuz ")\n", __func__,
154 len);
155 goto out;
156 }
157
158 if ((ctx = winpr_RC4_New(TEST_RC4_KEY, strnlen(TEST_RC4_KEY, sizeof(TEST_RC4_KEY)))) == nullptr)
159 {
160 (void)fprintf(stderr, "%s: winpr_RC4_New failed\n", __func__);
161 goto out;
162 }
163 rc = winpr_RC4_Update(ctx, len, (const BYTE*)TEST_RC4_PLAINTEXT, text);
164 winpr_RC4_Free(ctx);
165 if (!rc)
166 {
167 (void)fprintf(stderr, "%s: winpr_RC4_Update failed\n", __func__);
168 goto out;
169 }
170
171 if (memcmp(text, TEST_RC4_CIPHERTEXT, len) != 0)
172 {
173 char* actual = nullptr;
174 char* expected = nullptr;
175
176 actual = winpr_BinToHexString(text, len, FALSE);
177 expected = winpr_BinToHexString(TEST_RC4_CIPHERTEXT, len, FALSE);
178
179 (void)fprintf(stderr, "%s: unexpected RC4 ciphertext: Actual: %s Expected: %s\n", __func__,
180 actual, expected);
181
182 free(actual);
183 free(expected);
184 goto out;
185 }
186
187 rc = TRUE;
188
189out:
190 free(text);
191 return rc;
192}
193
194static const BYTE* TEST_RAND_DATA =
195 (BYTE*)"\x1F\xC2\xEE\x4C\xA3\x66\x80\xA2\xCE\xFE\x56\xB4\x9E\x08\x30\x96"
196 "\x33\x6A\xA9\x6D\x36\xFD\x3C\xB7\x83\x04\x4E\x5E\xDC\x22\xCD\xF3"
197 "\x48\xDF\x3A\x2A\x61\xF1\xA8\xFA\x1F\xC6\xC7\x1B\x81\xB4\xE1\x0E"
198 "\xCB\xA2\xEF\xA1\x12\x4A\x83\xE5\x1D\x72\x1D\x2D\x26\xA8\x6B\xC0";
199
200static const BYTE* TEST_CIPHER_KEY =
201 (BYTE*)"\x9D\x7C\xC0\xA1\x94\x3B\x07\x67\x2F\xD3\x83\x10\x51\x83\x38\x0E"
202 "\x1C\x74\x8C\x4E\x15\x79\xD6\xFF\xE2\xF0\x37\x7F\x8C\xD7\xD2\x13";
203
204static const BYTE* TEST_CIPHER_IV =
205 (BYTE*)"\xFE\xE3\x9F\xF0\xD1\x5E\x37\x0C\xAB\xAB\x9B\x04\xF3\xDB\x99\x15";
206
207static BOOL test_crypto_cipher_key(void)
208{
209 int status = 0;
210 BYTE key[32] = WINPR_C_ARRAY_INIT;
211 BYTE iv[16] = WINPR_C_ARRAY_INIT;
212 BYTE salt[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
213
214 status = winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, salt, TEST_RAND_DATA,
215 64, 4, key, iv);
216
217 if (status != 32 || memcmp(key, TEST_CIPHER_KEY, 32) != 0 ||
218 memcmp(iv, TEST_CIPHER_IV, 16) != 0)
219 {
220 char* akstr = nullptr;
221 char* ekstr = nullptr;
222 char* aivstr = nullptr;
223 char* eivstr = nullptr;
224
225 akstr = winpr_BinToHexString(key, 32, 0);
226 ekstr = winpr_BinToHexString(TEST_CIPHER_KEY, 32, 0);
227
228 aivstr = winpr_BinToHexString(iv, 16, 0);
229 eivstr = winpr_BinToHexString(TEST_CIPHER_IV, 16, 0);
230
231 (void)fprintf(stderr, "Unexpected EVP_BytesToKey Key: Actual: %s, Expected: %s\n", akstr,
232 ekstr);
233 (void)fprintf(stderr, "Unexpected EVP_BytesToKey IV : Actual: %s, Expected: %s\n", aivstr,
234 eivstr);
235
236 free(akstr);
237 free(ekstr);
238 free(aivstr);
239 free(eivstr);
240 }
241
242 return TRUE;
243}
244
245int TestCryptoCipher(int argc, char* argv[])
246{
247
248 WINPR_UNUSED(argc);
249 WINPR_UNUSED(argv);
250
251 if (!winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT))
252 return -1;
253
254 if (!test_crypto_cipher_aes_128_cbc(TRUE))
255 return -1;
256
257 if (!test_crypto_cipher_aes_128_cbc(FALSE))
258 return -1;
259
260 if (!test_crypto_cipher_rc4())
261 return -1;
262
263 if (!test_crypto_cipher_key())
264 return -1;
265
266 return 0;
267}