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