This source file includes following definitions.
- PHP_INI_BEGIN
- PHP_GINIT_FUNCTION
- PHP_GSHUTDOWN_FUNCTION
- PHP_MINIT_FUNCTION
- PHP_MSHUTDOWN_FUNCTION
- PHP_MINFO_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- php_mcrypt_get_key_size_str
- php_mcrypt_is_valid_key_size
- php_mcrypt_ensure_valid_key_size
- php_mcrypt_ensure_valid_iv
- php_mcrypt_do_crypt
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "php.h"
26
27 #if HAVE_LIBMCRYPT
28
29 #if PHP_WIN32
30 # include "win32/winutil.h"
31 #endif
32
33 #include "php_mcrypt.h"
34 #include "fcntl.h"
35
36 #define NON_FREE
37 #define MCRYPT2
38 #include "mcrypt.h"
39 #include "php_ini.h"
40 #include "php_globals.h"
41 #include "ext/standard/info.h"
42 #include "ext/standard/php_rand.h"
43 #include "ext/standard/php_smart_str.h"
44 #include "php_mcrypt_filter.h"
45
46 static int le_mcrypt;
47
48 typedef struct _php_mcrypt {
49 MCRYPT td;
50 zend_bool init;
51 } php_mcrypt;
52
53
54 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_open, 0, 0, 4)
55 ZEND_ARG_INFO(0, cipher)
56 ZEND_ARG_INFO(0, cipher_directory)
57 ZEND_ARG_INFO(0, mode)
58 ZEND_ARG_INFO(0, mode_directory)
59 ZEND_END_ARG_INFO()
60
61 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_generic_init, 0, 0, 3)
62 ZEND_ARG_INFO(0, td)
63 ZEND_ARG_INFO(0, key)
64 ZEND_ARG_INFO(0, iv)
65 ZEND_END_ARG_INFO()
66
67 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_generic, 0, 0, 2)
68 ZEND_ARG_INFO(0, td)
69 ZEND_ARG_INFO(0, data)
70 ZEND_END_ARG_INFO()
71
72 ZEND_BEGIN_ARG_INFO_EX(arginfo_mdecrypt_generic, 0, 0, 2)
73 ZEND_ARG_INFO(0, td)
74 ZEND_ARG_INFO(0, data)
75 ZEND_END_ARG_INFO()
76
77 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_supported_key_sizes, 0, 0, 1)
78 ZEND_ARG_INFO(0, td)
79 ZEND_END_ARG_INFO()
80
81 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_self_test, 0, 0, 1)
82 ZEND_ARG_INFO(0, td)
83 ZEND_END_ARG_INFO()
84
85 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_close, 0, 0, 1)
86 ZEND_ARG_INFO(0, td)
87 ZEND_END_ARG_INFO()
88
89 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_generic_deinit, 0, 0, 1)
90 ZEND_ARG_INFO(0, td)
91 ZEND_END_ARG_INFO()
92
93 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_is_block_algorithm_mode, 0, 0, 1)
94 ZEND_ARG_INFO(0, td)
95 ZEND_END_ARG_INFO()
96
97 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_is_block_algorithm, 0, 0, 1)
98 ZEND_ARG_INFO(0, td)
99 ZEND_END_ARG_INFO()
100
101 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_is_block_mode, 0, 0, 1)
102 ZEND_ARG_INFO(0, td)
103 ZEND_END_ARG_INFO()
104
105 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_block_size, 0, 0, 1)
106 ZEND_ARG_INFO(0, td)
107 ZEND_END_ARG_INFO()
108
109 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_key_size, 0, 0, 1)
110 ZEND_ARG_INFO(0, td)
111 ZEND_END_ARG_INFO()
112
113 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_iv_size, 0, 0, 1)
114 ZEND_ARG_INFO(0, td)
115 ZEND_END_ARG_INFO()
116
117 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_algorithms_name, 0, 0, 1)
118 ZEND_ARG_INFO(0, td)
119 ZEND_END_ARG_INFO()
120
121 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_modes_name, 0, 0, 1)
122 ZEND_ARG_INFO(0, td)
123 ZEND_END_ARG_INFO()
124
125 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_self_test, 0, 0, 1)
126 ZEND_ARG_INFO(0, algorithm)
127 ZEND_ARG_INFO(0, lib_dir)
128 ZEND_END_ARG_INFO()
129
130 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_is_block_algorithm_mode, 0, 0, 1)
131 ZEND_ARG_INFO(0, mode)
132 ZEND_ARG_INFO(0, lib_dir)
133 ZEND_END_ARG_INFO()
134
135 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_is_block_algorithm, 0, 0, 1)
136 ZEND_ARG_INFO(0, algorithm)
137 ZEND_ARG_INFO(0, lib_dir)
138 ZEND_END_ARG_INFO()
139
140 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_is_block_mode, 0, 0, 1)
141 ZEND_ARG_INFO(0, mode)
142 ZEND_ARG_INFO(0, lib_dir)
143 ZEND_END_ARG_INFO()
144
145 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_get_algo_block_size, 0, 0, 1)
146 ZEND_ARG_INFO(0, algorithm)
147 ZEND_ARG_INFO(0, lib_dir)
148 ZEND_END_ARG_INFO()
149
150 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_get_algo_key_size, 0, 0, 1)
151 ZEND_ARG_INFO(0, algorithm)
152 ZEND_ARG_INFO(0, lib_dir)
153 ZEND_END_ARG_INFO()
154
155 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_get_supported_key_sizes, 0, 0, 1)
156 ZEND_ARG_INFO(0, algorithm)
157 ZEND_ARG_INFO(0, lib_dir)
158 ZEND_END_ARG_INFO()
159
160 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_list_algorithms, 0, 0, 0)
161 ZEND_ARG_INFO(0, lib_dir)
162 ZEND_END_ARG_INFO()
163
164 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_list_modes, 0, 0, 0)
165 ZEND_ARG_INFO(0, lib_dir)
166 ZEND_END_ARG_INFO()
167
168 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_key_size, 0, 0, 2)
169 ZEND_ARG_INFO(0, cipher)
170 ZEND_ARG_INFO(0, module)
171 ZEND_END_ARG_INFO()
172
173 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_block_size, 0, 0, 2)
174 ZEND_ARG_INFO(0, cipher)
175 ZEND_ARG_INFO(0, module)
176 ZEND_END_ARG_INFO()
177
178 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_iv_size, 0, 0, 2)
179 ZEND_ARG_INFO(0, cipher)
180 ZEND_ARG_INFO(0, module)
181 ZEND_END_ARG_INFO()
182
183 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_cipher_name, 0, 0, 1)
184 ZEND_ARG_INFO(0, cipher)
185 ZEND_END_ARG_INFO()
186
187 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_encrypt, 0, 0, 5)
188 ZEND_ARG_INFO(0, cipher)
189 ZEND_ARG_INFO(0, key)
190 ZEND_ARG_INFO(0, data)
191 ZEND_ARG_INFO(0, mode)
192 ZEND_ARG_INFO(0, iv)
193 ZEND_END_ARG_INFO()
194
195 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_decrypt, 0, 0, 5)
196 ZEND_ARG_INFO(0, cipher)
197 ZEND_ARG_INFO(0, key)
198 ZEND_ARG_INFO(0, data)
199 ZEND_ARG_INFO(0, mode)
200 ZEND_ARG_INFO(0, iv)
201 ZEND_END_ARG_INFO()
202
203 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_ecb, 0, 0, 5)
204 ZEND_ARG_INFO(0, cipher)
205 ZEND_ARG_INFO(0, key)
206 ZEND_ARG_INFO(0, data)
207 ZEND_ARG_INFO(0, mode)
208 ZEND_ARG_INFO(0, iv)
209 ZEND_END_ARG_INFO()
210
211 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_cbc, 0, 0, 5)
212 ZEND_ARG_INFO(0, cipher)
213 ZEND_ARG_INFO(0, key)
214 ZEND_ARG_INFO(0, data)
215 ZEND_ARG_INFO(0, mode)
216 ZEND_ARG_INFO(0, iv)
217 ZEND_END_ARG_INFO()
218
219 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_cfb, 0, 0, 5)
220 ZEND_ARG_INFO(0, cipher)
221 ZEND_ARG_INFO(0, key)
222 ZEND_ARG_INFO(0, data)
223 ZEND_ARG_INFO(0, mode)
224 ZEND_ARG_INFO(0, iv)
225 ZEND_END_ARG_INFO()
226
227 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_ofb, 0, 0, 5)
228 ZEND_ARG_INFO(0, cipher)
229 ZEND_ARG_INFO(0, key)
230 ZEND_ARG_INFO(0, data)
231 ZEND_ARG_INFO(0, mode)
232 ZEND_ARG_INFO(0, iv)
233 ZEND_END_ARG_INFO()
234
235 ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_create_iv, 0, 0, 1)
236 ZEND_ARG_INFO(0, size)
237 ZEND_ARG_INFO(0, source)
238 ZEND_END_ARG_INFO()
239
240
241 const zend_function_entry mcrypt_functions[] = {
242 PHP_DEP_FE(mcrypt_ecb, arginfo_mcrypt_ecb)
243 PHP_DEP_FE(mcrypt_cbc, arginfo_mcrypt_cbc)
244 PHP_DEP_FE(mcrypt_cfb, arginfo_mcrypt_cfb)
245 PHP_DEP_FE(mcrypt_ofb, arginfo_mcrypt_ofb)
246 PHP_FE(mcrypt_get_key_size, arginfo_mcrypt_get_key_size)
247 PHP_FE(mcrypt_get_block_size, arginfo_mcrypt_get_block_size)
248 PHP_FE(mcrypt_get_cipher_name, arginfo_mcrypt_get_cipher_name)
249 PHP_FE(mcrypt_create_iv, arginfo_mcrypt_create_iv)
250
251 PHP_FE(mcrypt_list_algorithms, arginfo_mcrypt_list_algorithms)
252 PHP_FE(mcrypt_list_modes, arginfo_mcrypt_list_modes)
253 PHP_FE(mcrypt_get_iv_size, arginfo_mcrypt_get_iv_size)
254 PHP_FE(mcrypt_encrypt, arginfo_mcrypt_encrypt)
255 PHP_FE(mcrypt_decrypt, arginfo_mcrypt_decrypt)
256
257 PHP_FE(mcrypt_module_open, arginfo_mcrypt_module_open)
258 PHP_FE(mcrypt_generic_init, arginfo_mcrypt_generic_init)
259 PHP_FE(mcrypt_generic, arginfo_mcrypt_generic)
260 PHP_FE(mdecrypt_generic, arginfo_mdecrypt_generic)
261 PHP_DEP_FALIAS(mcrypt_generic_end, mcrypt_generic_deinit, arginfo_mcrypt_generic_deinit)
262 PHP_FE(mcrypt_generic_deinit, arginfo_mcrypt_generic_deinit)
263
264 PHP_FE(mcrypt_enc_self_test, arginfo_mcrypt_enc_self_test)
265 PHP_FE(mcrypt_enc_is_block_algorithm_mode, arginfo_mcrypt_enc_is_block_algorithm_mode)
266 PHP_FE(mcrypt_enc_is_block_algorithm, arginfo_mcrypt_enc_is_block_algorithm)
267 PHP_FE(mcrypt_enc_is_block_mode, arginfo_mcrypt_enc_is_block_mode)
268 PHP_FE(mcrypt_enc_get_block_size, arginfo_mcrypt_enc_get_block_size)
269 PHP_FE(mcrypt_enc_get_key_size, arginfo_mcrypt_enc_get_key_size)
270 PHP_FE(mcrypt_enc_get_supported_key_sizes, arginfo_mcrypt_enc_get_supported_key_sizes)
271 PHP_FE(mcrypt_enc_get_iv_size, arginfo_mcrypt_enc_get_iv_size)
272 PHP_FE(mcrypt_enc_get_algorithms_name, arginfo_mcrypt_enc_get_algorithms_name)
273 PHP_FE(mcrypt_enc_get_modes_name, arginfo_mcrypt_enc_get_modes_name)
274 PHP_FE(mcrypt_module_self_test, arginfo_mcrypt_module_self_test)
275
276 PHP_FE(mcrypt_module_is_block_algorithm_mode, arginfo_mcrypt_module_is_block_algorithm_mode)
277 PHP_FE(mcrypt_module_is_block_algorithm, arginfo_mcrypt_module_is_block_algorithm)
278 PHP_FE(mcrypt_module_is_block_mode, arginfo_mcrypt_module_is_block_mode)
279 PHP_FE(mcrypt_module_get_algo_block_size, arginfo_mcrypt_module_get_algo_block_size)
280 PHP_FE(mcrypt_module_get_algo_key_size, arginfo_mcrypt_module_get_algo_key_size)
281 PHP_FE(mcrypt_module_get_supported_key_sizes, arginfo_mcrypt_module_get_supported_key_sizes)
282
283 PHP_FE(mcrypt_module_close, arginfo_mcrypt_module_close)
284 PHP_FE_END
285 };
286
287
288 static PHP_MINFO_FUNCTION(mcrypt);
289 static PHP_MINIT_FUNCTION(mcrypt);
290 static PHP_MSHUTDOWN_FUNCTION(mcrypt);
291 static PHP_GINIT_FUNCTION(mcrypt);
292 static PHP_GSHUTDOWN_FUNCTION(mcrypt);
293
294 ZEND_DECLARE_MODULE_GLOBALS(mcrypt)
295
296 zend_module_entry mcrypt_module_entry = {
297 STANDARD_MODULE_HEADER,
298 "mcrypt",
299 mcrypt_functions,
300 PHP_MINIT(mcrypt), PHP_MSHUTDOWN(mcrypt),
301 NULL, NULL,
302 PHP_MINFO(mcrypt),
303 NO_VERSION_YET,
304 PHP_MODULE_GLOBALS(mcrypt),
305 PHP_GINIT(mcrypt),
306 PHP_GSHUTDOWN(mcrypt),
307 NULL,
308 STANDARD_MODULE_PROPERTIES_EX
309 };
310
311 #ifdef COMPILE_DL_MCRYPT
312 ZEND_GET_MODULE(mcrypt)
313 #endif
314
315 #define MCRYPT_ENCRYPT 0
316 #define MCRYPT_DECRYPT 1
317
318 typedef enum {
319 RANDOM = 0,
320 URANDOM,
321 RAND
322 } iv_source;
323
324 #define MCRYPT_GET_INI \
325 cipher_dir_string = MCG(algorithms_dir); \
326 module_dir_string = MCG(modes_dir);
327
328
329
330
331
332
333
334 #define MCRYPT_GET_CRYPT_ARGS \
335 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssZ|s", \
336 &cipher, &cipher_len, &key, &key_len, &data, &data_len, &mode, &iv, &iv_len) == FAILURE) { \
337 return; \
338 }
339
340 #define MCRYPT_GET_TD_ARG \
341 zval *mcryptind; \
342 php_mcrypt *pm; \
343 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mcryptind) == FAILURE) { \
344 return; \
345 } \
346 ZEND_FETCH_RESOURCE (pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);
347
348 #define MCRYPT_GET_MODE_DIR_ARGS(DIRECTORY) \
349 char *dir = NULL; \
350 int dir_len; \
351 char *module; \
352 int module_len; \
353 if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, \
354 "s|s", &module, &module_len, &dir, &dir_len) == FAILURE) { \
355 return; \
356 }
357
358 #define MCRYPT_OPEN_MODULE_FAILED "Module initialization failed"
359
360 #define MCRYPT_ENTRY2_2_4(a,b) REGISTER_STRING_CONSTANT("MCRYPT_" #a, b, CONST_PERSISTENT)
361 #define MCRYPT_ENTRY2_4(a) MCRYPT_ENTRY_NAMED(a, a)
362
363 #define PHP_MCRYPT_INIT_CHECK \
364 if (!pm->init) { \
365 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Operation disallowed prior to mcrypt_generic_init()."); \
366 RETURN_FALSE; \
367 } \
368
369 PHP_INI_BEGIN()
370 STD_PHP_INI_ENTRY("mcrypt.algorithms_dir", NULL, PHP_INI_ALL, OnUpdateString, algorithms_dir, zend_mcrypt_globals, mcrypt_globals)
371 STD_PHP_INI_ENTRY("mcrypt.modes_dir", NULL, PHP_INI_ALL, OnUpdateString, modes_dir, zend_mcrypt_globals, mcrypt_globals)
372 PHP_INI_END()
373
374 static void php_mcrypt_module_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
375 {
376 php_mcrypt *pm = (php_mcrypt *) rsrc->ptr;
377 if (pm) {
378 mcrypt_generic_deinit(pm->td);
379 mcrypt_module_close(pm->td);
380 efree(pm);
381 pm = NULL;
382 }
383 }
384
385
386 static PHP_GINIT_FUNCTION(mcrypt)
387 {
388 mcrypt_globals->fd[RANDOM] = -1;
389 mcrypt_globals->fd[URANDOM] = -1;
390 }
391
392 static PHP_GSHUTDOWN_FUNCTION(mcrypt)
393 {
394 if (mcrypt_globals->fd[RANDOM] > 0) {
395 close(mcrypt_globals->fd[RANDOM]);
396 mcrypt_globals->fd[RANDOM] = -1;
397 }
398
399 if (mcrypt_globals->fd[URANDOM] > 0) {
400 close(mcrypt_globals->fd[URANDOM]);
401 mcrypt_globals->fd[URANDOM] = -1;
402 }
403 }
404
405 static PHP_MINIT_FUNCTION(mcrypt)
406 {
407 le_mcrypt = zend_register_list_destructors_ex(php_mcrypt_module_dtor, NULL, "mcrypt", module_number);
408
409
410 REGISTER_LONG_CONSTANT("MCRYPT_ENCRYPT", 0, CONST_PERSISTENT);
411 REGISTER_LONG_CONSTANT("MCRYPT_DECRYPT", 1, CONST_PERSISTENT);
412
413
414 REGISTER_LONG_CONSTANT("MCRYPT_DEV_RANDOM", RANDOM, CONST_PERSISTENT);
415 REGISTER_LONG_CONSTANT("MCRYPT_DEV_URANDOM", URANDOM, CONST_PERSISTENT);
416 REGISTER_LONG_CONSTANT("MCRYPT_RAND", RAND, CONST_PERSISTENT);
417
418
419 MCRYPT_ENTRY2_2_4(3DES, "tripledes");
420 MCRYPT_ENTRY2_2_4(ARCFOUR_IV, "arcfour-iv");
421 MCRYPT_ENTRY2_2_4(ARCFOUR, "arcfour");
422 MCRYPT_ENTRY2_2_4(BLOWFISH, "blowfish");
423 MCRYPT_ENTRY2_2_4(BLOWFISH_COMPAT, "blowfish-compat");
424 MCRYPT_ENTRY2_2_4(CAST_128, "cast-128");
425 MCRYPT_ENTRY2_2_4(CAST_256, "cast-256");
426 MCRYPT_ENTRY2_2_4(CRYPT, "crypt");
427 MCRYPT_ENTRY2_2_4(DES, "des");
428 MCRYPT_ENTRY2_2_4(ENIGNA, "crypt");
429 MCRYPT_ENTRY2_2_4(GOST, "gost");
430 MCRYPT_ENTRY2_2_4(LOKI97, "loki97");
431 MCRYPT_ENTRY2_2_4(PANAMA, "panama");
432 MCRYPT_ENTRY2_2_4(RC2, "rc2");
433 MCRYPT_ENTRY2_2_4(RIJNDAEL_128, "rijndael-128");
434 MCRYPT_ENTRY2_2_4(RIJNDAEL_192, "rijndael-192");
435 MCRYPT_ENTRY2_2_4(RIJNDAEL_256, "rijndael-256");
436 MCRYPT_ENTRY2_2_4(SAFER64, "safer-sk64");
437 MCRYPT_ENTRY2_2_4(SAFER128, "safer-sk128");
438 MCRYPT_ENTRY2_2_4(SAFERPLUS, "saferplus");
439 MCRYPT_ENTRY2_2_4(SERPENT, "serpent");
440 MCRYPT_ENTRY2_2_4(THREEWAY, "threeway");
441 MCRYPT_ENTRY2_2_4(TRIPLEDES, "tripledes");
442 MCRYPT_ENTRY2_2_4(TWOFISH, "twofish");
443 MCRYPT_ENTRY2_2_4(WAKE, "wake");
444 MCRYPT_ENTRY2_2_4(XTEA, "xtea");
445
446 MCRYPT_ENTRY2_2_4(IDEA, "idea");
447 MCRYPT_ENTRY2_2_4(MARS, "mars");
448 MCRYPT_ENTRY2_2_4(RC6, "rc6");
449 MCRYPT_ENTRY2_2_4(SKIPJACK, "skipjack");
450
451 MCRYPT_ENTRY2_2_4(MODE_CBC, "cbc");
452 MCRYPT_ENTRY2_2_4(MODE_CFB, "cfb");
453 MCRYPT_ENTRY2_2_4(MODE_ECB, "ecb");
454 MCRYPT_ENTRY2_2_4(MODE_NOFB, "nofb");
455 MCRYPT_ENTRY2_2_4(MODE_OFB, "ofb");
456 MCRYPT_ENTRY2_2_4(MODE_STREAM, "stream");
457 REGISTER_INI_ENTRIES();
458
459 php_stream_filter_register_factory("mcrypt.*", &php_mcrypt_filter_factory TSRMLS_CC);
460 php_stream_filter_register_factory("mdecrypt.*", &php_mcrypt_filter_factory TSRMLS_CC);
461
462 return SUCCESS;
463 }
464
465
466 static PHP_MSHUTDOWN_FUNCTION(mcrypt)
467 {
468 php_stream_filter_unregister_factory("mcrypt.*" TSRMLS_CC);
469 php_stream_filter_unregister_factory("mdecrypt.*" TSRMLS_CC);
470
471 UNREGISTER_INI_ENTRIES();
472 return SUCCESS;
473 }
474
475
476 #include "ext/standard/php_smart_str.h"
477
478 PHP_MINFO_FUNCTION(mcrypt)
479 {
480 char **modules;
481 char mcrypt_api_no[16];
482 int i, count;
483 smart_str tmp1 = {0};
484 smart_str tmp2 = {0};
485
486 modules = mcrypt_list_algorithms(MCG(algorithms_dir), &count);
487 if (count == 0) {
488 smart_str_appends(&tmp1, "none");
489 }
490 for (i = 0; i < count; i++) {
491 smart_str_appends(&tmp1, modules[i]);
492 smart_str_appendc(&tmp1, ' ');
493 }
494 smart_str_0(&tmp1);
495 mcrypt_free_p(modules, count);
496
497 modules = mcrypt_list_modes(MCG(modes_dir), &count);
498 if (count == 0) {
499 smart_str_appends(&tmp2, "none");
500 }
501 for (i = 0; i < count; i++) {
502 smart_str_appends(&tmp2, modules[i]);
503 smart_str_appendc(&tmp2, ' ');
504 }
505 smart_str_0 (&tmp2);
506 mcrypt_free_p (modules, count);
507
508 snprintf (mcrypt_api_no, 16, "%d", MCRYPT_API_VERSION);
509
510 php_info_print_table_start();
511 php_info_print_table_header(2, "mcrypt support", "enabled");
512 php_info_print_table_header(2, "mcrypt_filter support", "enabled");
513 php_info_print_table_row(2, "Version", LIBMCRYPT_VERSION);
514 php_info_print_table_row(2, "Api No", mcrypt_api_no);
515 php_info_print_table_row(2, "Supported ciphers", tmp1.c);
516 php_info_print_table_row(2, "Supported modes", tmp2.c);
517 smart_str_free(&tmp1);
518 smart_str_free(&tmp2);
519 php_info_print_table_end();
520
521 DISPLAY_INI_ENTRIES();
522 }
523
524
525
526
527 PHP_FUNCTION(mcrypt_module_open)
528 {
529 char *cipher, *cipher_dir;
530 char *mode, *mode_dir;
531 int cipher_len, cipher_dir_len;
532 int mode_len, mode_dir_len;
533 MCRYPT td;
534 php_mcrypt *pm;
535
536 if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "ssss",
537 &cipher, &cipher_len, &cipher_dir, &cipher_dir_len,
538 &mode, &mode_len, &mode_dir, &mode_dir_len)) {
539 return;
540 }
541
542 td = mcrypt_module_open (
543 cipher,
544 cipher_dir_len > 0 ? cipher_dir : MCG(algorithms_dir),
545 mode,
546 mode_dir_len > 0 ? mode_dir : MCG(modes_dir)
547 );
548
549 if (td == MCRYPT_FAILED) {
550 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open encryption module");
551 RETURN_FALSE;
552 } else {
553 pm = emalloc(sizeof(php_mcrypt));
554 pm->td = td;
555 pm->init = 0;
556 ZEND_REGISTER_RESOURCE(return_value, pm, le_mcrypt);
557 }
558 }
559
560
561
562
563 PHP_FUNCTION(mcrypt_generic_init)
564 {
565 char *key, *iv;
566 int key_len, iv_len;
567 zval *mcryptind;
568 unsigned char *key_s, *iv_s;
569 int max_key_size, key_size, iv_size;
570 php_mcrypt *pm;
571 int result = 0;
572
573 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &mcryptind, &key, &key_len, &iv, &iv_len) == FAILURE) {
574 return;
575 }
576
577 ZEND_FETCH_RESOURCE(pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);
578
579 max_key_size = mcrypt_enc_get_key_size(pm->td);
580 iv_size = mcrypt_enc_get_iv_size(pm->td);
581
582 if (key_len == 0) {
583 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size is 0");
584 }
585
586 key_s = emalloc(key_len);
587 memset(key_s, 0, key_len);
588
589 iv_s = emalloc(iv_size + 1);
590 memset(iv_s, 0, iv_size + 1);
591
592 if (key_len > max_key_size) {
593 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size too large; supplied length: %d, max: %d", key_len, max_key_size);
594 key_size = max_key_size;
595 } else {
596 key_size = key_len;
597 }
598 memcpy(key_s, key, key_len);
599
600 if (iv_len != iv_size) {
601 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Iv size incorrect; supplied length: %d, needed: %d", iv_len, iv_size);
602 if (iv_len > iv_size) {
603 iv_len = iv_size;
604 }
605 }
606 memcpy(iv_s, iv, iv_len);
607
608 mcrypt_generic_deinit(pm->td);
609 result = mcrypt_generic_init(pm->td, key_s, key_size, iv_s);
610
611
612
613 if (result < 0) {
614 zend_list_delete(Z_LVAL_P(mcryptind));
615 switch (result) {
616 case -3:
617 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key length incorrect");
618 break;
619 case -4:
620 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation error");
621 break;
622 case -1:
623 default:
624 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error");
625 break;
626 }
627 } else {
628 pm->init = 1;
629 }
630 RETVAL_LONG(result);
631
632 efree(iv_s);
633 efree(key_s);
634 }
635
636
637
638
639 PHP_FUNCTION(mcrypt_generic)
640 {
641 zval *mcryptind;
642 char *data;
643 int data_len;
644 php_mcrypt *pm;
645 char* data_s;
646 int block_size, data_size;
647
648 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) {
649 return;
650 }
651
652 ZEND_FETCH_RESOURCE(pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);
653 PHP_MCRYPT_INIT_CHECK
654
655 if (data_len == 0) {
656 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An empty string was passed");
657 RETURN_FALSE
658 }
659
660
661 if (mcrypt_enc_is_block_mode(pm->td) == 1) {
662 block_size = mcrypt_enc_get_block_size(pm->td);
663 data_size = (((data_len - 1) / block_size) + 1) * block_size;
664 data_s = emalloc(data_size + 1);
665 memset(data_s, 0, data_size);
666 memcpy(data_s, data, data_len);
667 } else {
668 data_size = data_len;
669 data_s = emalloc(data_size + 1);
670 memset(data_s, 0, data_size);
671 memcpy(data_s, data, data_len);
672 }
673
674 mcrypt_generic(pm->td, data_s, data_size);
675 data_s[data_size] = '\0';
676
677 RETVAL_STRINGL(data_s, data_size, 1);
678 efree(data_s);
679 }
680
681
682
683
684 PHP_FUNCTION(mdecrypt_generic)
685 {
686 zval *mcryptind;
687 char *data;
688 int data_len;
689 php_mcrypt *pm;
690 char* data_s;
691 int block_size, data_size;
692
693 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) {
694 return;
695 }
696
697 ZEND_FETCH_RESOURCE(pm, php_mcrypt * , &mcryptind, -1, "MCrypt", le_mcrypt);
698 PHP_MCRYPT_INIT_CHECK
699
700 if (data_len == 0) {
701 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An empty string was passed");
702 RETURN_FALSE
703 }
704
705
706 if (mcrypt_enc_is_block_mode(pm->td) == 1) {
707 block_size = mcrypt_enc_get_block_size(pm->td);
708 data_size = (((data_len - 1) / block_size) + 1) * block_size;
709 data_s = emalloc(data_size + 1);
710 memset(data_s, 0, data_size);
711 memcpy(data_s, data, data_len);
712 } else {
713 data_size = data_len;
714 data_s = emalloc(data_size + 1);
715 memset(data_s, 0, data_size);
716 memcpy(data_s, data, data_len);
717 }
718
719 mdecrypt_generic(pm->td, data_s, data_size);
720
721 RETVAL_STRINGL(data_s, data_size, 1);
722 efree(data_s);
723 }
724
725
726
727
728 PHP_FUNCTION(mcrypt_enc_get_supported_key_sizes)
729 {
730 int i, count = 0;
731 int *key_sizes;
732
733 MCRYPT_GET_TD_ARG
734 array_init(return_value);
735
736 key_sizes = mcrypt_enc_get_supported_key_sizes(pm->td, &count);
737
738 for (i = 0; i < count; i++) {
739 add_index_long(return_value, i, key_sizes[i]);
740 }
741
742 mcrypt_free(key_sizes);
743 }
744
745
746
747
748 PHP_FUNCTION(mcrypt_enc_self_test)
749 {
750 MCRYPT_GET_TD_ARG
751 RETURN_LONG(mcrypt_enc_self_test(pm->td));
752 }
753
754
755
756
757 PHP_FUNCTION(mcrypt_module_close)
758 {
759 MCRYPT_GET_TD_ARG
760 zend_list_delete(Z_LVAL_P(mcryptind));
761 RETURN_TRUE;
762 }
763
764
765
766
767 PHP_FUNCTION(mcrypt_generic_deinit)
768 {
769 MCRYPT_GET_TD_ARG
770
771 if (mcrypt_generic_deinit(pm->td) < 0) {
772 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not terminate encryption specifier");
773 RETURN_FALSE
774 }
775 pm->init = 0;
776 RETURN_TRUE
777 }
778
779
780
781
782 PHP_FUNCTION(mcrypt_enc_is_block_algorithm_mode)
783 {
784 MCRYPT_GET_TD_ARG
785
786 if (mcrypt_enc_is_block_algorithm_mode(pm->td) == 1) {
787 RETURN_TRUE
788 } else {
789 RETURN_FALSE
790 }
791 }
792
793
794
795
796 PHP_FUNCTION(mcrypt_enc_is_block_algorithm)
797 {
798 MCRYPT_GET_TD_ARG
799
800 if (mcrypt_enc_is_block_algorithm(pm->td) == 1) {
801 RETURN_TRUE
802 } else {
803 RETURN_FALSE
804 }
805 }
806
807
808
809
810 PHP_FUNCTION(mcrypt_enc_is_block_mode)
811 {
812 MCRYPT_GET_TD_ARG
813
814 if (mcrypt_enc_is_block_mode(pm->td) == 1) {
815 RETURN_TRUE
816 } else {
817 RETURN_FALSE
818 }
819 }
820
821
822
823
824 PHP_FUNCTION(mcrypt_enc_get_block_size)
825 {
826 MCRYPT_GET_TD_ARG
827 RETURN_LONG(mcrypt_enc_get_block_size(pm->td));
828 }
829
830
831
832
833 PHP_FUNCTION(mcrypt_enc_get_key_size)
834 {
835 MCRYPT_GET_TD_ARG
836 RETURN_LONG(mcrypt_enc_get_key_size(pm->td));
837 }
838
839
840
841
842 PHP_FUNCTION(mcrypt_enc_get_iv_size)
843 {
844 MCRYPT_GET_TD_ARG
845 RETURN_LONG(mcrypt_enc_get_iv_size(pm->td));
846 }
847
848
849
850
851 PHP_FUNCTION(mcrypt_enc_get_algorithms_name)
852 {
853 char *name;
854 MCRYPT_GET_TD_ARG
855
856 name = mcrypt_enc_get_algorithms_name(pm->td);
857 RETVAL_STRING(name, 1);
858 mcrypt_free(name);
859 }
860
861
862
863
864 PHP_FUNCTION(mcrypt_enc_get_modes_name)
865 {
866 char *name;
867 MCRYPT_GET_TD_ARG
868
869 name = mcrypt_enc_get_modes_name(pm->td);
870 RETVAL_STRING(name, 1);
871 mcrypt_free(name);
872 }
873
874
875
876
877 PHP_FUNCTION(mcrypt_module_self_test)
878 {
879 MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir);
880
881 if (mcrypt_module_self_test(module, dir) == 0) {
882 RETURN_TRUE;
883 } else {
884 RETURN_FALSE;
885 }
886 }
887
888
889
890
891 PHP_FUNCTION(mcrypt_module_is_block_algorithm_mode)
892 {
893 MCRYPT_GET_MODE_DIR_ARGS(modes_dir)
894
895 if (mcrypt_module_is_block_algorithm_mode(module, dir) == 1) {
896 RETURN_TRUE;
897 } else {
898 RETURN_FALSE;
899 }
900 }
901
902
903
904
905 PHP_FUNCTION(mcrypt_module_is_block_algorithm)
906 {
907 MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
908
909 if (mcrypt_module_is_block_algorithm(module, dir) == 1) {
910 RETURN_TRUE;
911 } else {
912 RETURN_FALSE;
913 }
914 }
915
916
917
918
919 PHP_FUNCTION(mcrypt_module_is_block_mode)
920 {
921 MCRYPT_GET_MODE_DIR_ARGS(modes_dir)
922
923 if (mcrypt_module_is_block_mode(module, dir) == 1) {
924 RETURN_TRUE;
925 } else {
926 RETURN_FALSE;
927 }
928 }
929
930
931
932
933 PHP_FUNCTION(mcrypt_module_get_algo_block_size)
934 {
935 MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
936
937 RETURN_LONG(mcrypt_module_get_algo_block_size(module, dir));
938 }
939
940
941
942
943 PHP_FUNCTION(mcrypt_module_get_algo_key_size)
944 {
945 MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir);
946
947 RETURN_LONG(mcrypt_module_get_algo_key_size(module, dir));
948 }
949
950
951
952
953 PHP_FUNCTION(mcrypt_module_get_supported_key_sizes)
954 {
955 int i, count = 0;
956 int *key_sizes;
957
958 MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
959 array_init(return_value);
960
961 key_sizes = mcrypt_module_get_algo_supported_key_sizes(module, dir, &count);
962
963 for (i = 0; i < count; i++) {
964 add_index_long(return_value, i, key_sizes[i]);
965 }
966 mcrypt_free(key_sizes);
967 }
968
969
970
971
972 PHP_FUNCTION(mcrypt_list_algorithms)
973 {
974 char **modules;
975 char *lib_dir = MCG(algorithms_dir);
976 int lib_dir_len;
977 int i, count;
978
979 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",
980 &lib_dir, &lib_dir_len) == FAILURE) {
981 return;
982 }
983
984 array_init(return_value);
985 modules = mcrypt_list_algorithms(lib_dir, &count);
986
987 if (count == 0) {
988 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No algorithms found in module dir");
989 }
990 for (i = 0; i < count; i++) {
991 add_index_string(return_value, i, modules[i], 1);
992 }
993 mcrypt_free_p(modules, count);
994 }
995
996
997
998
999 PHP_FUNCTION(mcrypt_list_modes)
1000 {
1001 char **modules;
1002 char *lib_dir = MCG(modes_dir);
1003 int lib_dir_len;
1004 int i, count;
1005
1006 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",
1007 &lib_dir, &lib_dir_len) == FAILURE) {
1008 return;
1009 }
1010
1011 array_init(return_value);
1012 modules = mcrypt_list_modes(lib_dir, &count);
1013
1014 if (count == 0) {
1015 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No modes found in module dir");
1016 }
1017 for (i = 0; i < count; i++) {
1018 add_index_string(return_value, i, modules[i], 1);
1019 }
1020 mcrypt_free_p(modules, count);
1021 }
1022
1023
1024
1025
1026 PHP_FUNCTION(mcrypt_get_key_size)
1027 {
1028 char *cipher;
1029 char *module;
1030 int cipher_len, module_len;
1031 char *cipher_dir_string;
1032 char *module_dir_string;
1033 MCRYPT td;
1034
1035 MCRYPT_GET_INI
1036
1037 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
1038 &cipher, &cipher_len, &module, &module_len) == FAILURE) {
1039 return;
1040 }
1041
1042 td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
1043 if (td != MCRYPT_FAILED) {
1044 RETVAL_LONG(mcrypt_enc_get_key_size(td));
1045 mcrypt_module_close(td);
1046 } else {
1047 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
1048 RETURN_FALSE;
1049 }
1050 }
1051
1052
1053
1054
1055 PHP_FUNCTION(mcrypt_get_block_size)
1056 {
1057 char *cipher;
1058 char *module;
1059 int cipher_len, module_len;
1060 char *cipher_dir_string;
1061 char *module_dir_string;
1062 MCRYPT td;
1063
1064 MCRYPT_GET_INI
1065
1066 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
1067 &cipher, &cipher_len, &module, &module_len) == FAILURE) {
1068 return;
1069 }
1070
1071 td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
1072 if (td != MCRYPT_FAILED) {
1073 RETVAL_LONG(mcrypt_enc_get_block_size(td));
1074 mcrypt_module_close(td);
1075 } else {
1076 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
1077 RETURN_FALSE;
1078 }
1079 }
1080
1081
1082
1083
1084 PHP_FUNCTION(mcrypt_get_iv_size)
1085 {
1086 char *cipher;
1087 char *module;
1088 int cipher_len, module_len;
1089 char *cipher_dir_string;
1090 char *module_dir_string;
1091 MCRYPT td;
1092
1093 MCRYPT_GET_INI
1094
1095 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
1096 &cipher, &cipher_len, &module, &module_len) == FAILURE) {
1097 return;
1098 }
1099
1100 td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
1101 if (td != MCRYPT_FAILED) {
1102 RETVAL_LONG(mcrypt_enc_get_iv_size(td));
1103 mcrypt_module_close(td);
1104 } else {
1105 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
1106 RETURN_FALSE;
1107 }
1108 }
1109
1110
1111
1112
1113 PHP_FUNCTION(mcrypt_get_cipher_name)
1114 {
1115 char *cipher_dir_string;
1116 char *module_dir_string;
1117 char *cipher_name;
1118 char *cipher;
1119 int cipher_len;
1120 MCRYPT td;
1121
1122 MCRYPT_GET_INI
1123
1124 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
1125 &cipher, &cipher_len) == FAILURE) {
1126 return;
1127 }
1128
1129
1130
1131 td = mcrypt_module_open(cipher, cipher_dir_string, "ecb", module_dir_string);
1132 if (td != MCRYPT_FAILED) {
1133 cipher_name = mcrypt_enc_get_algorithms_name(td);
1134 mcrypt_module_close(td);
1135 RETVAL_STRING(cipher_name,1);
1136 mcrypt_free(cipher_name);
1137 } else {
1138 td = mcrypt_module_open(cipher, cipher_dir_string, "stream", module_dir_string);
1139 if (td != MCRYPT_FAILED) {
1140 cipher_name = mcrypt_enc_get_algorithms_name(td);
1141 mcrypt_module_close(td);
1142 RETVAL_STRING(cipher_name,1);
1143 mcrypt_free(cipher_name);
1144 } else {
1145 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
1146 RETURN_FALSE;
1147 }
1148 }
1149 }
1150
1151
1152 static char *php_mcrypt_get_key_size_str(
1153 int max_key_size, const int *key_sizes, int key_size_count)
1154 {
1155 if (key_size_count == 0) {
1156 char *str;
1157 spprintf(&str, 0, "Only keys of size 1 to %d supported", max_key_size);
1158 return str;
1159 } else if (key_size_count == 1) {
1160 char *str;
1161 spprintf(&str, 0, "Only keys of size %d supported", key_sizes[0]);
1162 return str;
1163 } else {
1164 int i;
1165 smart_str str = {0};
1166 smart_str_appends(&str, "Only keys of sizes ");
1167
1168 for (i = 0; i < key_size_count; ++i) {
1169 if (i == key_size_count - 1) {
1170 smart_str_appends(&str, " or ");
1171 } else if (i != 0) {
1172 smart_str_appends(&str, ", ");
1173 }
1174
1175 smart_str_append_long(&str, key_sizes[i]);
1176 }
1177
1178 smart_str_appends(&str, " supported");
1179 smart_str_0(&str);
1180 return str.c;
1181 }
1182 }
1183
1184
1185 static zend_bool php_mcrypt_is_valid_key_size(
1186 int key_size, int max_key_size, int *key_sizes, int key_size_count)
1187 {
1188 int i;
1189
1190 if (key_size <= 0 || key_size > max_key_size) {
1191 return 0;
1192 }
1193
1194 if (key_size_count == 0) {
1195
1196 return 1;
1197 }
1198
1199 for (i = 0; i < key_size_count; i++) {
1200 if (key_sizes[i] == key_size) {
1201 return 1;
1202 }
1203 }
1204
1205 return 0;
1206 }
1207
1208
1209 static int php_mcrypt_ensure_valid_key_size(MCRYPT td, int key_size TSRMLS_DC)
1210 {
1211 int key_size_count;
1212 int max_key_size = mcrypt_enc_get_key_size(td);
1213 int *key_sizes = mcrypt_enc_get_supported_key_sizes(td, &key_size_count);
1214
1215 zend_bool is_valid_key_size = php_mcrypt_is_valid_key_size(
1216 key_size, max_key_size, key_sizes, key_size_count
1217 );
1218 if (!is_valid_key_size) {
1219 char *key_size_str = php_mcrypt_get_key_size_str(
1220 max_key_size, key_sizes, key_size_count
1221 );
1222 php_error_docref(NULL TSRMLS_CC, E_WARNING,
1223 "Key of size %d not supported by this algorithm. %s", key_size, key_size_str
1224 );
1225 efree(key_size_str);
1226 }
1227
1228 if (key_sizes) {
1229 mcrypt_free(key_sizes);
1230 }
1231
1232 return is_valid_key_size ? SUCCESS : FAILURE;
1233 }
1234
1235
1236 static int php_mcrypt_ensure_valid_iv(MCRYPT td, const char *iv, int iv_size TSRMLS_DC)
1237 {
1238 if (mcrypt_enc_mode_has_iv(td) == 1) {
1239 int expected_iv_size = mcrypt_enc_get_iv_size(td);
1240 if (expected_iv_size == 0) {
1241
1242 return SUCCESS;
1243 }
1244
1245 if (!iv) {
1246 php_error_docref(NULL TSRMLS_CC, E_WARNING,
1247 "Encryption mode requires an initialization vector of size %d", expected_iv_size
1248 );
1249 return FAILURE;
1250 }
1251
1252 if (iv_size != expected_iv_size) {
1253 php_error_docref(NULL TSRMLS_CC, E_WARNING,
1254 "Received initialization vector of size %d, but size %d is required "
1255 "for this encryption mode", iv_size, expected_iv_size
1256 );
1257 return FAILURE;
1258 }
1259 }
1260
1261 return SUCCESS;
1262 }
1263
1264
1265 static void php_mcrypt_do_crypt(char* cipher, const char *key, int key_len, const char *data, int data_len, char *mode, const char *iv, int iv_len, int dencrypt, zval* return_value TSRMLS_DC)
1266 {
1267 char *cipher_dir_string;
1268 char *module_dir_string;
1269 unsigned long int data_size;
1270 char *data_s;
1271 MCRYPT td;
1272
1273 MCRYPT_GET_INI
1274
1275 td = mcrypt_module_open(cipher, cipher_dir_string, mode, module_dir_string);
1276 if (td == MCRYPT_FAILED) {
1277 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
1278 RETURN_FALSE;
1279 }
1280
1281 if (php_mcrypt_ensure_valid_key_size(td, key_len TSRMLS_CC) == FAILURE) {
1282 mcrypt_module_close(td);
1283 RETURN_FALSE;
1284 }
1285
1286 if (php_mcrypt_ensure_valid_iv(td, iv, iv_len TSRMLS_CC) == FAILURE) {
1287 mcrypt_module_close(td);
1288 RETURN_FALSE;
1289 }
1290
1291
1292 if (mcrypt_enc_is_block_mode(td) == 1) {
1293 int block_size = mcrypt_enc_get_block_size(td);
1294 data_size = (((data_len - 1) / block_size) + 1) * block_size;
1295 data_s = emalloc(data_size + 1);
1296 memset(data_s, 0, data_size);
1297 memcpy(data_s, data, data_len);
1298 } else {
1299 data_size = data_len;
1300 data_s = emalloc(data_size + 1);
1301 memcpy(data_s, data, data_len);
1302 }
1303
1304 if (mcrypt_generic_init(td, (void *) key, key_len, (void *) iv) < 0) {
1305 php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Mcrypt initialisation failed");
1306 mcrypt_module_close(td);
1307 RETURN_FALSE;
1308 }
1309
1310 if (dencrypt == MCRYPT_ENCRYPT) {
1311 mcrypt_generic(td, data_s, data_size);
1312 } else {
1313 mdecrypt_generic(td, data_s, data_size);
1314 }
1315
1316 data_s[data_size] = 0;
1317 RETVAL_STRINGL(data_s, data_size, 0);
1318
1319
1320 mcrypt_generic_end(td);
1321 }
1322
1323
1324
1325
1326 PHP_FUNCTION(mcrypt_encrypt)
1327 {
1328 char *cipher, *key, *data, *mode, *iv = NULL;
1329 int cipher_len, key_len, data_len, mode_len, iv_len = 0;
1330
1331 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssss|s", &cipher, &cipher_len,
1332 &key, &key_len, &data, &data_len, &mode, &mode_len, &iv, &iv_len) == FAILURE) {
1333 return;
1334 }
1335
1336 php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, mode, iv, iv_len, MCRYPT_ENCRYPT, return_value TSRMLS_CC);
1337 }
1338
1339
1340
1341
1342 PHP_FUNCTION(mcrypt_decrypt)
1343 {
1344 char *cipher, *key, *data, *mode, *iv = NULL;
1345 int cipher_len, key_len, data_len, mode_len, iv_len = 0;
1346
1347 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssss|s", &cipher, &cipher_len,
1348 &key, &key_len, &data, &data_len, &mode, &mode_len, &iv, &iv_len) == FAILURE) {
1349 return;
1350 }
1351
1352 php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, mode, iv, iv_len, MCRYPT_DECRYPT, return_value TSRMLS_CC);
1353 }
1354
1355
1356
1357
1358 PHP_FUNCTION(mcrypt_ecb)
1359 {
1360 zval **mode;
1361 char *cipher, *key, *data, *iv = NULL;
1362 int cipher_len, key_len, data_len, iv_len = 0;
1363
1364 MCRYPT_GET_CRYPT_ARGS
1365
1366 convert_to_long_ex(mode);
1367
1368 php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "ecb", iv, iv_len, Z_LVAL_PP(mode), return_value TSRMLS_CC);
1369 }
1370
1371
1372
1373
1374 PHP_FUNCTION(mcrypt_cbc)
1375 {
1376 zval **mode;
1377 char *cipher, *key, *data, *iv = NULL;
1378 int cipher_len, key_len, data_len, iv_len = 0;
1379
1380 MCRYPT_GET_CRYPT_ARGS
1381
1382 convert_to_long_ex(mode);
1383
1384 php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "cbc", iv, iv_len, Z_LVAL_PP(mode), return_value TSRMLS_CC);
1385 }
1386
1387
1388
1389
1390 PHP_FUNCTION(mcrypt_cfb)
1391 {
1392 zval **mode;
1393 char *cipher, *key, *data, *iv = NULL;
1394 int cipher_len, key_len, data_len, iv_len = 0;
1395
1396 MCRYPT_GET_CRYPT_ARGS
1397
1398 convert_to_long_ex(mode);
1399
1400 php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "cfb", iv, iv_len, Z_LVAL_PP(mode), return_value TSRMLS_CC);
1401 }
1402
1403
1404
1405
1406 PHP_FUNCTION(mcrypt_ofb)
1407 {
1408 zval **mode;
1409 char *cipher, *key, *data, *iv = NULL;
1410 int cipher_len, key_len, data_len, iv_len = 0;
1411
1412 MCRYPT_GET_CRYPT_ARGS
1413
1414 convert_to_long_ex(mode);
1415
1416 php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "ofb", iv, iv_len, Z_LVAL_PP(mode), return_value TSRMLS_CC);
1417 }
1418
1419
1420
1421
1422 PHP_FUNCTION(mcrypt_create_iv)
1423 {
1424 char *iv;
1425 long source = URANDOM;
1426 long size;
1427 int n = 0;
1428
1429 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &size, &source) == FAILURE) {
1430 return;
1431 }
1432
1433 if (size <= 0 || size >= INT_MAX) {
1434 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create an IV with a size of less than 1 or greater than %d", INT_MAX);
1435 RETURN_FALSE;
1436 }
1437
1438 iv = ecalloc(size + 1, 1);
1439
1440 if (source == RANDOM || source == URANDOM) {
1441 #if PHP_WIN32
1442
1443 BYTE *iv_b = (BYTE *) iv;
1444 if (php_win32_get_random_bytes(iv_b, (size_t) size) == FAILURE){
1445 efree(iv);
1446 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not gather sufficient random data");
1447 RETURN_FALSE;
1448 }
1449 n = size;
1450 #else
1451 int *fd = &MCG(fd[source]);
1452 size_t read_bytes = 0;
1453
1454 if (*fd < 0) {
1455 *fd = open(source == RANDOM ? "/dev/random" : "/dev/urandom", O_RDONLY);
1456 if (*fd < 0) {
1457 efree(iv);
1458 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open source device");
1459 RETURN_FALSE;
1460 }
1461 }
1462
1463 while (read_bytes < size) {
1464 n = read(*fd, iv + read_bytes, size - read_bytes);
1465 if (n < 0) {
1466 break;
1467 }
1468 read_bytes += n;
1469 }
1470 n = read_bytes;
1471
1472 if (n < size) {
1473 efree(iv);
1474 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not gather sufficient random data");
1475 RETURN_FALSE;
1476 }
1477 #endif
1478 } else {
1479 n = size;
1480 while (size) {
1481 iv[--size] = (char) (255.0 * php_rand(TSRMLS_C) / RAND_MAX);
1482 }
1483 }
1484 RETURN_STRINGL(iv, n, 0);
1485 }
1486
1487
1488 #endif
1489
1490
1491
1492
1493
1494
1495
1496
1497