+ /*
+ * Print algorithm details.
+ */
+ if (verbose) {
+ fprintf(stderr, "Algorithms:\n");
+ if (cc->iaes_cbcenc != 0) {
+ fprintf(stderr, " AES/CBC (enc): %s\n",
+ get_algo_name(cc->iaes_cbcenc, 0));
+ }
+ if (cc->iaes_cbcdec != 0) {
+ fprintf(stderr, " AES/CBC (dec): %s\n",
+ get_algo_name(cc->iaes_cbcdec, 0));
+ }
+ if (cc->iaes_ctr != 0) {
+ fprintf(stderr, " AES/CTR: %s\n",
+ get_algo_name(cc->iaes_cbcdec, 0));
+ }
+ if (cc->ides_cbcenc != 0) {
+ fprintf(stderr, " DES/CBC (enc): %s\n",
+ get_algo_name(cc->ides_cbcenc, 0));
+ }
+ if (cc->ides_cbcdec != 0) {
+ fprintf(stderr, " DES/CBC (dec): %s\n",
+ get_algo_name(cc->ides_cbcdec, 0));
+ }
+ if (cc->ighash != 0) {
+ fprintf(stderr, " GHASH (GCM): %s\n",
+ get_algo_name(cc->ighash, 0));
+ }
+ if (cc->ichacha != 0) {
+ fprintf(stderr, " ChaCha20: %s\n",
+ get_algo_name(cc->ichacha, 0));
+ }
+ if (cc->ipoly != 0) {
+ fprintf(stderr, " Poly1305: %s\n",
+ get_algo_name(cc->ipoly, 0));
+ }
+ if (cc->iec != 0) {
+ fprintf(stderr, " EC: %s\n",
+ get_algo_name(cc->iec, 0));
+ }
+ if (cc->iecdsa != 0) {
+ fprintf(stderr, " ECDSA: %s\n",
+ get_algo_name(cc->iecdsa, 0));
+ }
+ if (cc->irsavrfy != 0) {
+ fprintf(stderr, " RSA (vrfy): %s\n",
+ get_algo_name(cc->irsavrfy, 0));
+ }
+ }
+
+#ifdef _WIN32
+ fd_event = WSA_INVALID_EVENT;
+ can_send = 0;
+ can_recv = 0;
+ bb.ptr = bb.len = 0;
+#endif
+
+ /*
+ * On Unix systems, we need to follow three descriptors:
+ * standard input (0), standard output (1), and the socket
+ * itself (for both read and write). This is done with a poll()
+ * call.
+ *
+ * On Windows systems, we use WSAEventSelect() to associate
+ * an event handle with the network activity, and we use
+ * WaitForMultipleObjectsEx() on that handle and the standard
+ * input handle, when appropriate. Standard output is assumed
+ * to be always writeable, and standard input to be the console;
+ * this does not work well (or at all) with redirections (to
+ * pipes or files) but it should be enough for a debug tool
+ * (TODO: make something that handles redirections as well).
+ */
+
+#ifdef _WIN32
+ fd_event = WSACreateEvent();
+ if (fd_event == WSA_INVALID_EVENT) {
+ fprintf(stderr, "ERROR: WSACreateEvent() failed with %d\n",
+ WSAGetLastError());
+ retcode = -2;
+ goto engine_exit;
+ }
+ WSAEventSelect(fd, fd_event, FD_READ | FD_WRITE | FD_CLOSE);
+ h_in = GetStdHandle(STD_INPUT_HANDLE);
+ h_out = GetStdHandle(STD_OUTPUT_HANDLE);
+ SetConsoleMode(h_in, ENABLE_ECHO_INPUT
+ | ENABLE_LINE_INPUT
+ | ENABLE_PROCESSED_INPUT
+ | ENABLE_PROCESSED_OUTPUT
+ | ENABLE_WRAP_AT_EOL_OUTPUT);
+#else