fuzz_early_setup:
   23|      2|void fuzz_early_setup(void) {
   24|       |    /* Set stderr to point to normal stderr by default */
   25|       |    fuzz.fake_stderr = stderr;
   26|      2|}
fuzz_common_setup:
   28|      1|void fuzz_common_setup(void) {
   29|      1|	disallow_core();
   30|      1|    fuzz.fuzzing = 1;
   31|      1|    fuzz.wrapfds = 1;
   32|      1|    fuzz.do_jmp = 1;
   33|      1|    fuzz.input = m_malloc(sizeof(buffer));
   34|      1|    _dropbear_log = fuzz_dropbear_log;
   35|      1|    crypto_init();
   36|      1|    fuzz_seed("start", 5);
   37|       |    /* let any messages get flushed */
   38|      1|    setlinebuf(stdout);
   39|       |#if DEBUG_TRACE
   40|       |    if (debug_trace)
   41|       |    {
   42|       |        fprintf(stderr, "Dropbear fuzzer: -v specified, not disabling stderr output\n");
   43|       |    }
   44|       |    else
   45|       |#endif
   46|      1|    if (getenv("DROPBEAR_KEEP_STDERR")) {
  ------------------
  |  Branch (46:9): [True: 0, False: 1]
  ------------------
   47|      0|        fprintf(stderr, "Dropbear fuzzer: DROPBEAR_KEEP_STDERR, not disabling stderr output\n");
   48|      0|    } 
   49|      1|    else 
   50|      1|    {
   51|      1|        fprintf(stderr, "Dropbear fuzzer: Disabling stderr output\n");
   52|      1|        fuzz.fake_stderr = fopen("/dev/null", "w");
   53|       |        assert(fuzz.fake_stderr);
  ------------------
  |  Branch (53:9): [True: 0, False: 1]
  |  Branch (53:9): [True: 1, False: 0]
  ------------------
   54|      1|    }
   55|      1|}
fuzz_set_input:
   57|  4.58k|int fuzz_set_input(const uint8_t *Data, size_t Size) {
   58|       |
   59|  4.58k|    fuzz.input->data = (unsigned char*)Data;
   60|  4.58k|    fuzz.input->size = Size;
   61|  4.58k|    fuzz.input->len = Size;
   62|  4.58k|    fuzz.input->pos = 0;
   63|       |
   64|  4.58k|    memset(&ses, 0x0, sizeof(ses));
   65|  4.58k|    memset(&svr_ses, 0x0, sizeof(svr_ses));
   66|  4.58k|    memset(&cli_ses, 0x0, sizeof(cli_ses));
   67|  4.58k|    wrapfd_setup(fuzz.input);
   68|       |    // printhex("input", fuzz.input->data, fuzz.input->len);
   69|       |
   70|  4.58k|    fuzz_seed(fuzz.input->data, MIN(fuzz.input->len, 16));
  ------------------
  |  Branch (70:33): [True: 267, False: 4.31k]
  ------------------
   71|       |
   72|  4.58k|    return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|  4.58k|#define DROPBEAR_SUCCESS 0
  ------------------
   73|  4.58k|}
fuzz_svr_setup:
   89|      1|void fuzz_svr_setup(void) {
   90|      1|    fuzz_common_setup();
   91|       |    
   92|      1|    _dropbear_exit = svr_dropbear_exit;
   93|       |
   94|      1|    char *argv[] = { 
   95|      1|		"dropbear",
   96|      1|        "-E", 
   97|      1|    };
   98|       |
   99|      1|    int argc = sizeof(argv) / sizeof(*argv);
  100|      1|    svr_getopts(argc, argv);
  101|       |
  102|      1|    load_fixed_hostkeys();
  103|      1|}
fuzz_svr_hook_preloop:
  105|  4.58k|void fuzz_svr_hook_preloop() {
  106|  4.58k|    if (fuzz.svr_postauth) {
  ------------------
  |  Branch (106:9): [True: 4.58k, False: 0]
  ------------------
  107|  4.58k|        ses.authstate.authdone = 1;
  108|  4.58k|        fill_passwd("root");
  109|  4.58k|    }
  110|  4.58k|}
fuzz_kex_fakealgos:
  197|  6.79k|void fuzz_kex_fakealgos(void) {
  198|  6.79k|    ses.newkeys->recv.crypt_mode = &dropbear_mode_none;
  199|  6.79k|    ses.newkeys->recv.algo_mac = &dropbear_nohash;
  200|  6.79k|}
fuzz_get_socket_address:
  203|  10.2k|                        char **remote_host, char **remote_port, int UNUSED(host_lookup)) {
  204|  10.2k|    if (local_host) {
  ------------------
  |  Branch (204:9): [True: 1.09k, False: 9.16k]
  ------------------
  205|  1.09k|        *local_host = m_strdup("fuzzlocalhost");
  206|  1.09k|    }
  207|  10.2k|    if (local_port) {
  ------------------
  |  Branch (207:9): [True: 1.09k, False: 9.16k]
  ------------------
  208|  1.09k|        *local_port = m_strdup("1234");
  209|  1.09k|    }
  210|  10.2k|    if (remote_host) {
  ------------------
  |  Branch (210:9): [True: 10.2k, False: 0]
  ------------------
  211|  10.2k|        *remote_host = m_strdup("fuzzremotehost");
  212|  10.2k|    }
  213|  10.2k|    if (remote_port) {
  ------------------
  |  Branch (213:9): [True: 5.67k, False: 4.58k]
  ------------------
  214|  5.67k|        *remote_port = m_strdup("9876");
  215|  5.67k|    }
  216|  10.2k|}
fuzz_fake_send_kexdh_reply:
  219|  6.45k|void fuzz_fake_send_kexdh_reply(void) {
  220|  6.45k|    assert(!ses.dh_K);
  ------------------
  |  Branch (220:5): [True: 0, False: 6.45k]
  |  Branch (220:5): [True: 6.45k, False: 0]
  ------------------
  221|  6.45k|    m_mp_alloc_init_multi(&ses.dh_K, NULL);
  222|  6.45k|    mp_set_ul(ses.dh_K, 12345678uL);
  223|  6.45k|    finish_kexhashbuf();
  224|  6.45k|}
fuzz_spawn_command:
  227|  1.02k|int fuzz_spawn_command(int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) {
  228|  1.02k|    *ret_writefd = wrapfd_new_dummy();
  229|  1.02k|    *ret_readfd = wrapfd_new_dummy();
  230|  1.02k|    if (ret_errfd) {
  ------------------
  |  Branch (230:9): [True: 1.02k, False: 0]
  ------------------
  231|  1.02k|        *ret_errfd = wrapfd_new_dummy();
  232|  1.02k|    }
  233|  1.02k|    if (*ret_writefd == -1 || *ret_readfd == -1 || (ret_errfd && *ret_errfd == -1)) {
  ------------------
  |  Branch (233:9): [True: 0, False: 1.02k]
  |  Branch (233:31): [True: 0, False: 1.02k]
  |  Branch (233:53): [True: 1.02k, False: 0]
  |  Branch (233:66): [True: 0, False: 1.02k]
  ------------------
  234|      0|        m_close(*ret_writefd);
  235|      0|        m_close(*ret_readfd);
  236|      0|        if (ret_errfd) {
  ------------------
  |  Branch (236:13): [True: 0, False: 0]
  ------------------
  237|      0|            m_close(*ret_errfd);
  238|      0|        }
  239|      0|        return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  240|  1.02k|    } else {
  241|  1.02k|        *ret_pid = 999;
  242|  1.02k|        return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|  1.02k|#define DROPBEAR_SUCCESS 0
  ------------------
  243|       |
  244|  1.02k|    }
  245|  1.02k|}
fuzz_dropbear_listen:
  257|    209|        int *UNUSED(socks), unsigned int UNUSED(sockcount), char **errstring, int *UNUSED(maxfd)) {
  258|    209|    if (errstring) {
  ------------------
  |  Branch (258:9): [True: 209, False: 0]
  ------------------
  259|    209|        *errstring = m_strdup("fuzzing can't listen (yet)");
  260|    209|    }
  261|    209|    return -1;
  262|    209|}
fuzz_run_server:
  264|  4.58k|int fuzz_run_server(const uint8_t *Data, size_t Size, int skip_kexmaths, int postauth) {
  265|  4.58k|    static int once = 0;
  266|  4.58k|    if (!once) {
  ------------------
  |  Branch (266:9): [True: 1, False: 4.58k]
  ------------------
  267|      1|        fuzz_svr_setup();
  268|      1|        fuzz.skip_kexmaths = skip_kexmaths;
  269|      1|        once = 1;
  270|      1|    }
  271|       |
  272|  4.58k|    fuzz.svr_postauth = postauth;
  273|       |
  274|  4.58k|    if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|  4.58k|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (274:9): [True: 0, False: 4.58k]
  ------------------
  275|      0|        return 0;
  276|      0|    }
  277|       |
  278|  4.58k|    uint32_t wrapseed;
  279|  4.58k|    genrandom((void*)&wrapseed, sizeof(wrapseed));
  280|  4.58k|    wrapfd_setseed(wrapseed);
  281|       |
  282|  4.58k|    int fakesock = wrapfd_new_fuzzinput();
  283|       |
  284|  4.58k|    m_malloc_set_epoch(1);
  285|  4.58k|    fuzz.do_jmp = 1;
  286|  4.58k|    if (setjmp(fuzz.jmp) == 0) {
  ------------------
  |  Branch (286:9): [True: 4.58k, False: 0]
  ------------------
  287|  4.58k|        svr_session(fakesock, fakesock);
  288|      0|        m_malloc_free_epoch(1, 0);
  289|      0|    } else {
  290|      0|        fuzz.do_jmp = 0;
  291|      0|        m_malloc_free_epoch(1, 1);
  292|      0|        TRACE(("dropbear_exit longjmped"))
  293|       |        /* dropbear_exit jumped here */
  294|      0|    }
  295|       |
  296|      0|    return 0;
  297|  4.58k|}
fuzz_dump:
  345|   122k|void fuzz_dump(const unsigned char* data, size_t len) {
  346|   122k|    if (fuzz.dumping) {
  ------------------
  |  Branch (346:9): [True: 0, False: 122k]
  ------------------
  347|      0|        TRACE(("dump %zu", len))
  348|       |        assert(atomicio(vwrite, fuzz.recv_dumpfd, (void*)data, len) == len);
  ------------------
  |  Branch (348:9): [True: 0, False: 0]
  |  Branch (348:9): [True: 0, False: 0]
  ------------------
  349|      0|    }
  350|   122k|}
fuzz_getpwnam:
  373|  4.59k|struct passwd* fuzz_getpwnam(const char *login) {
  374|  4.59k|    if (!fuzz.fuzzing) {
  ------------------
  |  Branch (374:9): [True: 0, False: 4.59k]
  ------------------
  375|      0|        return getpwnam(login);
  376|      0|    }
  377|  4.59k|    if (strcmp(login, pwd_other.pw_name) == 0) {
  ------------------
  |  Branch (377:9): [True: 0, False: 4.59k]
  ------------------
  378|      0|        return &pwd_other;
  379|      0|    }
  380|  4.59k|    if (strcmp(login, pwd_root.pw_name) == 0) {
  ------------------
  |  Branch (380:9): [True: 4.59k, False: 0]
  ------------------
  381|  4.59k|        return &pwd_root;
  382|  4.59k|    }
  383|      0|    return NULL;
  384|  4.59k|}
fuzz-common.c:fuzz_dropbear_log:
   84|  4.87k|static void fuzz_dropbear_log(int UNUSED(priority), const char* UNUSED(format), va_list UNUSED(param)) {
   85|       |    /* No print */
   86|  4.87k|}
fuzz-common.c:load_fixed_hostkeys:
  153|      1|static void load_fixed_hostkeys(void) {
  154|       |
  155|      1|    buffer *b = buf_new(3000);
  156|      1|    enum signkey_type type;
  157|       |
  158|      1|    TRACE(("load fixed hostkeys"))
  159|       |
  160|      1|    svr_opts.hostkey = new_sign_key();
  161|       |
  162|      1|    buf_setlen(b, 0);
  163|      1|    buf_putbytes(b, keyr, keyr_len);
  164|      1|    buf_setpos(b, 0);
  165|      1|    type = DROPBEAR_SIGNKEY_RSA;
  166|      1|    if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (166:9): [True: 0, False: 1]
  ------------------
  167|      0|        dropbear_exit("failed fixed rsa hostkey");
  168|      0|    }
  169|       |
  170|      1|    buf_setlen(b, 0);
  171|      1|    buf_putbytes(b, keyd, keyd_len);
  172|      1|    buf_setpos(b, 0);
  173|      1|    type = DROPBEAR_SIGNKEY_DSS;
  174|      1|    if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (174:9): [True: 0, False: 1]
  ------------------
  175|      0|        dropbear_exit("failed fixed dss hostkey");
  176|      0|    }
  177|       |
  178|      1|    buf_setlen(b, 0);
  179|      1|    buf_putbytes(b, keye, keye_len);
  180|      1|    buf_setpos(b, 0);
  181|      1|    type = DROPBEAR_SIGNKEY_ECDSA_NISTP256;
  182|      1|    if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (182:9): [True: 0, False: 1]
  ------------------
  183|      0|        dropbear_exit("failed fixed ecdsa hostkey");
  184|      0|    }
  185|       |
  186|      1|    buf_setlen(b, 0);
  187|      1|    buf_putbytes(b, keyed25519, keyed25519_len);
  188|      1|    buf_setpos(b, 0);
  189|      1|    type = DROPBEAR_SIGNKEY_ED25519;
  190|      1|    if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (190:9): [True: 0, False: 1]
  ------------------
  191|      0|        dropbear_exit("failed fixed ed25519 hostkey");
  192|      0|    }
  193|       |
  194|      1|    buf_free(b);
  195|      1|}

fuzz-sshpacketmutator.c:alloc_static_buffers:
  126|      2|static void alloc_static_buffers() {
  127|       |
  128|      2|    int i;
  129|      2|    oup = buf_new(MAX_OUT_SIZE);
  130|      2|    alloc_packetA = buf_new(RECV_MAX_PACKET_LEN);
  ------------------
  |  |  243|      2|#define RECV_MAX_PACKET_LEN (MAX(35000, ((RECV_MAX_PAYLOAD_LEN)+100)))
  ------------------
  |  Branch (130:29): [True: 2, Folded]
  ------------------
  131|      2|    alloc_packetB = buf_new(RECV_MAX_PACKET_LEN);
  ------------------
  |  |  243|      2|#define RECV_MAX_PACKET_LEN (MAX(35000, ((RECV_MAX_PAYLOAD_LEN)+100)))
  ------------------
  |  Branch (131:29): [True: 2, Folded]
  ------------------
  132|       |
  133|  1.00k|    for (i = 0; i < MAX_FUZZ_PACKETS; i++) {
  ------------------
  |  |   20|  1.00k|#define MAX_FUZZ_PACKETS 500
  ------------------
  |  Branch (133:17): [True: 1.00k, False: 2]
  ------------------
  134|  1.00k|        packets1[i] = buf_new(RECV_MAX_PACKET_LEN);
  ------------------
  |  |  243|  1.00k|#define RECV_MAX_PACKET_LEN (MAX(35000, ((RECV_MAX_PAYLOAD_LEN)+100)))
  ------------------
  |  Branch (134:31): [True: 1.00k, Folded]
  ------------------
  135|  1.00k|    }
  136|  1.00k|    for (i = 0; i < MAX_FUZZ_PACKETS; i++) {
  ------------------
  |  |   20|  1.00k|#define MAX_FUZZ_PACKETS 500
  ------------------
  |  Branch (136:17): [True: 1.00k, False: 2]
  ------------------
  137|       |        packets2[i] = buf_new(RECV_MAX_PACKET_LEN);
  ------------------
  |  |  243|  1.00k|#define RECV_MAX_PACKET_LEN (MAX(35000, ((RECV_MAX_PAYLOAD_LEN)+100)))
  ------------------
  |  Branch (137:31): [True: 1.00k, Folded]
  ------------------
  138|  1.00k|    }
  139|      2|}

wrapfd_setup:
   32|  4.58k|void wrapfd_setup(buffer *buf) {
   33|  4.58k|	TRACE(("wrapfd_setup"))
   34|       |
   35|       |	// clean old ones
   36|  4.58k|	int i;
   37|  46.5k|	for (i = 0; i <= wrapfd_maxfd; i++) {
  ------------------
  |  Branch (37:14): [True: 41.9k, False: 4.58k]
  ------------------
   38|  41.9k|		if (wrap_fds[i].mode != UNUSED) {
  ------------------
  |  Branch (38:7): [True: 1.88k, False: 40.0k]
  ------------------
   39|  1.88k|			wrapfd_remove(i);
   40|  1.88k|		}
   41|  41.9k|	}
   42|  4.58k|	wrapfd_maxfd = -1;
   43|       |
   44|  4.58k|	memset(rand_state, 0x0, sizeof(rand_state));
   45|  4.58k|	wrapfd_setseed(50);
   46|  4.58k|	input_buf = buf;
   47|  4.58k|}
wrapfd_setseed:
   49|  9.16k|void wrapfd_setseed(uint32_t seed) {
   50|  9.16k|	memcpy(rand_state, &seed, sizeof(seed));
   51|  9.16k|	nrand48(rand_state);
   52|  9.16k|}
wrapfd_new_fuzzinput:
   54|  4.58k|int wrapfd_new_fuzzinput() {
   55|  4.58k|	if (devnull_fd == -1) {
  ------------------
  |  Branch (55:6): [True: 1, False: 4.58k]
  ------------------
   56|      1|		devnull_fd = open("/dev/null", O_RDONLY);
   57|      1|		assert(devnull_fd != -1);
  ------------------
  |  Branch (57:3): [True: 0, False: 1]
  |  Branch (57:3): [True: 1, False: 0]
  ------------------
   58|      1|	}
   59|       |
   60|  4.58k|	int fd = dup(devnull_fd);
   61|  4.58k|	assert(fd != -1);
  ------------------
  |  Branch (61:2): [True: 0, False: 4.58k]
  |  Branch (61:2): [True: 4.58k, False: 0]
  ------------------
   62|  4.58k|	assert(wrap_fds[fd].mode == UNUSED);
  ------------------
  |  Branch (62:2): [True: 0, False: 4.58k]
  |  Branch (62:2): [True: 4.58k, False: 0]
  ------------------
   63|  4.58k|	wrap_fds[fd].mode = COMMONBUF;
   64|  4.58k|	wrap_fds[fd].closein = 0;
   65|  4.58k|	wrap_fds[fd].closeout = 0;
   66|  4.58k|	wrapfd_maxfd = MAX(fd, wrapfd_maxfd);
  ------------------
  |  Branch (66:17): [True: 4.58k, False: 0]
  ------------------
   67|       |
   68|  4.58k|	return fd;
   69|  4.58k|}
wrapfd_new_dummy:
   71|  3.28k|int wrapfd_new_dummy() {
   72|  3.28k|	if (devnull_fd == -1) {
  ------------------
  |  Branch (72:6): [True: 0, False: 3.28k]
  ------------------
   73|      0|		devnull_fd = open("/dev/null", O_RDONLY);
   74|      0|		assert(devnull_fd != -1);
  ------------------
  |  Branch (74:3): [True: 0, False: 0]
  |  Branch (74:3): [True: 0, False: 0]
  ------------------
   75|      0|	}
   76|       |
   77|  3.28k|	int fd = dup(devnull_fd);
   78|  3.28k|	if (fd == -1) {
  ------------------
  |  Branch (78:6): [True: 0, False: 3.28k]
  ------------------
   79|      0|		return -1;
   80|      0|	}
   81|  3.28k|	if (fd > IOWRAP_MAXFD) {
  ------------------
  |  |    9|  3.28k|#define IOWRAP_MAXFD (FD_SETSIZE-1)
  ------------------
  |  Branch (81:6): [True: 0, False: 3.28k]
  ------------------
   82|      0|		close(fd);
   83|      0|		errno = EMFILE;
   84|      0|		return -1;
   85|      0|	}
   86|  3.28k|	assert(wrap_fds[fd].mode == UNUSED);
  ------------------
  |  Branch (86:2): [True: 0, False: 3.28k]
  |  Branch (86:2): [True: 3.28k, False: 0]
  ------------------
   87|  3.28k|	wrap_fds[fd].mode = DUMMY;
   88|  3.28k|	wrap_fds[fd].closein = 0;
   89|  3.28k|	wrap_fds[fd].closeout = 0;
   90|  3.28k|	wrapfd_maxfd = MAX(fd, wrapfd_maxfd);
  ------------------
  |  Branch (90:17): [True: 2.66k, False: 627]
  ------------------
   91|       |
   92|  3.28k|	return fd;
   93|  3.28k|}
wrapfd_close:
  105|  5.98k|int wrapfd_close(int fd) {
  106|  5.98k|	if (fd >= 0 && fd <= IOWRAP_MAXFD && wrap_fds[fd].mode != UNUSED) {
  ------------------
  |  |    9|  11.9k|#define IOWRAP_MAXFD (FD_SETSIZE-1)
  ------------------
  |  Branch (106:6): [True: 5.98k, False: 0]
  |  Branch (106:17): [True: 5.98k, False: 0]
  |  Branch (106:39): [True: 5.98k, False: 0]
  ------------------
  107|  5.98k|		wrapfd_remove(fd);
  108|  5.98k|		return 0;
  109|  5.98k|	} else {
  110|      0|		return close(fd);
  111|      0|	}
  112|  5.98k|}
wrapfd_read:
  114|   398k|int wrapfd_read(int fd, void *out, size_t count) {
  115|   398k|	size_t maxread;
  116|       |
  117|   398k|	if (!fuzz.wrapfds) {
  ------------------
  |  Branch (117:6): [True: 0, False: 398k]
  ------------------
  118|      0|		return read(fd, out, count);
  119|      0|	}
  120|       |
  121|   398k|	if (fd < 0 || fd > IOWRAP_MAXFD || wrap_fds[fd].mode == UNUSED) {
  ------------------
  |  |    9|   796k|#define IOWRAP_MAXFD (FD_SETSIZE-1)
  ------------------
  |  Branch (121:6): [True: 0, False: 398k]
  |  Branch (121:16): [True: 0, False: 398k]
  |  Branch (121:37): [True: 0, False: 398k]
  ------------------
  122|       |		/* XXX - assertion failure? */
  123|      0|		TRACE(("Bad read descriptor %d\n", fd))
  124|      0|		errno = EBADF;
  125|      0|		return -1;
  126|      0|	}
  127|       |
  128|   398k|	assert(count != 0);
  ------------------
  |  Branch (128:2): [True: 0, False: 398k]
  |  Branch (128:2): [True: 398k, False: 0]
  ------------------
  129|       |
  130|   398k|	if (wrap_fds[fd].closein || erand48(rand_state) < CHANCE_CLOSE) {
  ------------------
  |  Branch (130:6): [True: 0, False: 398k]
  |  Branch (130:30): [True: 141, False: 398k]
  ------------------
  131|    141|		wrap_fds[fd].closein = 1;
  132|    141|		errno = ECONNRESET;
  133|    141|		return -1;
  134|    141|	}
  135|       |
  136|   398k|	if (erand48(rand_state) < CHANCE_INTR) {
  ------------------
  |  Branch (136:6): [True: 286, False: 397k]
  ------------------
  137|    286|		errno = EINTR;
  138|    286|		return -1;
  139|    286|	}
  140|       |
  141|   397k|	if (input_buf && wrap_fds[fd].mode == COMMONBUF) {
  ------------------
  |  Branch (141:6): [True: 397k, False: 0]
  |  Branch (141:19): [True: 338k, False: 59.1k]
  ------------------
  142|   338k|		maxread = MIN(input_buf->len - input_buf->pos, count);
  ------------------
  |  Branch (142:13): [True: 3.65k, False: 335k]
  ------------------
  143|       |		/* returns 0 if buf is EOF, as intended */
  144|   338k|		if (maxread > 0) {
  ------------------
  |  Branch (144:7): [True: 336k, False: 2.65k]
  ------------------
  145|   336k|			maxread = nrand48(rand_state) % maxread + 1;
  146|   336k|		}
  147|   338k|		memcpy(out, buf_getptr(input_buf, maxread), maxread);
  148|   338k|		buf_incrpos(input_buf, maxread);
  149|   338k|		return maxread;
  150|   338k|	}
  151|       |
  152|       |	// return fixed output, of random length
  153|  59.1k|	maxread = MIN(MAX_RANDOM_IN, count);
  ------------------
  |  Branch (153:12): [True: 0, False: 59.1k]
  ------------------
  154|  59.1k|	maxread = nrand48(rand_state) % maxread + 1;
  155|  59.1k|	memset(out, 0xef, maxread);
  156|  59.1k|	return maxread;
  157|   397k|}
wrapfd_select:
  196|   384k|	fd_set *exceptfds, struct timeval *timeout) {
  197|   384k|	int i, nset, sel;
  198|   384k|	int ret = 0;
  199|   384k|	int fdlist[IOWRAP_MAXFD+1];
  200|       |
  201|   384k|	if (!fuzz.wrapfds) {
  ------------------
  |  Branch (201:6): [True: 0, False: 384k]
  ------------------
  202|      0|		return select(nfds, readfds, writefds, exceptfds, timeout);
  203|      0|	}
  204|       |
  205|   384k|	assert(nfds <= IOWRAP_MAXFD+1);
  ------------------
  |  Branch (205:2): [True: 0, False: 384k]
  |  Branch (205:2): [True: 384k, False: 0]
  ------------------
  206|       |
  207|   384k|	if (erand48(rand_state) < CHANCE_INTR) {
  ------------------
  |  Branch (207:6): [True: 336, False: 383k]
  ------------------
  208|    336|		errno = EINTR;
  209|    336|		return -1;
  210|    336|	}
  211|       |
  212|       |	/* read */
  213|   383k|	if (readfds != NULL && erand48(rand_state) < CHANCE_READ1) {
  ------------------
  |  Branch (213:6): [True: 383k, False: 0]
  |  Branch (213:25): [True: 357k, False: 26.7k]
  ------------------
  214|  4.71M|		for (i = 0, nset = 0; i < nfds; i++) {
  ------------------
  |  Branch (214:25): [True: 4.35M, False: 357k]
  ------------------
  215|  4.35M|			if (FD_ISSET(i, readfds)) {
  ------------------
  |  Branch (215:8): [True: 521k, False: 3.83M]
  ------------------
  216|   521k|				assert(wrap_fds[i].mode != UNUSED);
  ------------------
  |  Branch (216:5): [True: 0, False: 521k]
  |  Branch (216:5): [True: 521k, False: 0]
  ------------------
  217|   521k|				fdlist[nset] = i;
  218|   521k|				nset++;
  219|   521k|			}
  220|  4.35M|		}
  221|   357k|		DROPBEAR_FD_ZERO(readfds);
  ------------------
  |  |  106|   357k|#define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds)
  ------------------
  |  Branch (221:3): [Folded, False: 357k]
  ------------------
  222|       |
  223|   357k|		if (nset > 0) {
  ------------------
  |  Branch (223:7): [True: 342k, False: 14.9k]
  ------------------
  224|       |			/* set one */
  225|   342k|			sel = fdlist[nrand48(rand_state) % nset];
  226|   342k|			FD_SET(sel, readfds);
  227|   342k|			ret++;
  228|       |
  229|   342k|			if (erand48(rand_state) < CHANCE_READ2) {
  ------------------
  |  Branch (229:8): [True: 163k, False: 178k]
  ------------------
  230|   163k|				sel = fdlist[nrand48(rand_state) % nset];
  231|   163k|				if (!FD_ISSET(sel, readfds)) {
  ------------------
  |  Branch (231:9): [True: 23.5k, False: 139k]
  ------------------
  232|  23.5k|					FD_SET(sel, readfds);
  233|  23.5k|					ret++;
  234|  23.5k|				}
  235|   163k|			}
  236|   342k|		}
  237|   357k|	}
  238|       |
  239|       |	/* write */
  240|   383k|	if (writefds != NULL && erand48(rand_state) < CHANCE_WRITE1) {
  ------------------
  |  Branch (240:6): [True: 302k, False: 81.5k]
  |  Branch (240:26): [True: 287k, False: 14.8k]
  ------------------
  241|  4.14M|		for (i = 0, nset = 0; i < nfds; i++) {
  ------------------
  |  Branch (241:25): [True: 3.85M, False: 287k]
  ------------------
  242|  3.85M|			if (FD_ISSET(i, writefds)) {
  ------------------
  |  Branch (242:8): [True: 54.1k, False: 3.80M]
  ------------------
  243|  54.1k|				assert(wrap_fds[i].mode != UNUSED);
  ------------------
  |  Branch (243:5): [True: 0, False: 54.1k]
  |  Branch (243:5): [True: 54.1k, False: 0]
  ------------------
  244|  54.1k|				fdlist[nset] = i;
  245|  54.1k|				nset++;
  246|  54.1k|			}
  247|  3.85M|		}
  248|   287k|		DROPBEAR_FD_ZERO(writefds);
  ------------------
  |  |  106|   287k|#define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds)
  ------------------
  |  Branch (248:3): [Folded, False: 287k]
  ------------------
  249|       |
  250|       |		/* set one */
  251|   287k|		if (nset > 0) {
  ------------------
  |  Branch (251:7): [True: 54.1k, False: 233k]
  ------------------
  252|  54.1k|			sel = fdlist[nrand48(rand_state) % nset];
  253|  54.1k|			FD_SET(sel, writefds);
  254|  54.1k|			ret++;
  255|       |
  256|  54.1k|			if (erand48(rand_state) < CHANCE_WRITE2) {
  ------------------
  |  Branch (256:8): [True: 24.5k, False: 29.6k]
  ------------------
  257|  24.5k|				sel = fdlist[nrand48(rand_state) % nset];
  258|  24.5k|				if (!FD_ISSET(sel, writefds)) {
  ------------------
  |  Branch (258:9): [True: 0, False: 24.5k]
  ------------------
  259|      0|					FD_SET(sel, writefds);
  260|      0|					ret++;
  261|      0|				}
  262|  24.5k|			}
  263|  54.1k|		}
  264|   287k|	}
  265|   383k|	return ret;
  266|   383k|}
fuzz_kill:
  268|    275|int fuzz_kill(pid_t pid, int sig) {
  269|    275|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (269:6): [True: 275, False: 0]
  ------------------
  270|    275|		TRACE(("fuzz_kill ignoring pid %d signal %d", (pid), sig))
  271|    275|		if (sig >= 0) {
  ------------------
  |  Branch (271:7): [True: 275, False: 0]
  ------------------
  272|    275|			return 0;
  273|    275|		} else {
  274|      0|			errno = EINVAL;
  275|      0|			return -1;
  276|      0|		}
  277|    275|	}
  278|      0|	return kill(pid, sig);
  279|    275|}
fuzz-wrapfd.c:wrapfd_remove:
   96|  7.86k|static void wrapfd_remove(int fd) {
   97|  7.86k|	TRACE(("wrapfd_remove %d", fd))
   98|  7.86k|	assert(fd >= 0);
  ------------------
  |  Branch (98:2): [True: 0, False: 7.86k]
  |  Branch (98:2): [True: 7.86k, False: 0]
  ------------------
   99|  7.86k|	assert(fd <= IOWRAP_MAXFD);
  ------------------
  |  Branch (99:2): [True: 0, False: 7.86k]
  |  Branch (99:2): [True: 7.86k, False: 0]
  ------------------
  100|  7.86k|	assert(wrap_fds[fd].mode != UNUSED);
  ------------------
  |  Branch (100:2): [True: 0, False: 7.86k]
  |  Branch (100:2): [True: 7.86k, False: 0]
  ------------------
  101|  7.86k|	wrap_fds[fd].mode = UNUSED;
  102|  7.86k|	close(fd);
  103|  7.86k|}

LLVMFuzzerTestOneInput:
    3|  4.58k|int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
    4|  4.58k|	return fuzz_run_server(Data, Size, 1, 1);
    5|  4.58k|}

rijndael_setup:
  123|  6.01k|{
  124|  6.01k|    int i;
  125|  6.01k|    ulong32 temp, *rk;
  126|  6.01k|#ifndef ENCRYPT_ONLY
  127|  6.01k|    ulong32 *rrk;
  128|  6.01k|#endif
  129|  6.01k|    LTC_ARGCHK(key  != NULL);
  ------------------
  |  |   32|  6.01k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 6.01k]
  |  |  |  Branch (32:87): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
  130|  6.01k|    LTC_ARGCHK(skey != NULL);
  ------------------
  |  |   32|  6.01k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 6.01k]
  |  |  |  Branch (32:87): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
  131|       |
  132|  6.01k|    if (keylen != 16 && keylen != 24 && keylen != 32) {
  ------------------
  |  Branch (132:9): [True: 753, False: 5.26k]
  |  Branch (132:25): [True: 753, False: 0]
  |  Branch (132:41): [True: 0, False: 753]
  ------------------
  133|      0|       return CRYPT_INVALID_KEYSIZE;
  134|      0|    }
  135|       |
  136|  6.01k|    if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
  ------------------
  |  Branch (136:9): [True: 0, False: 6.01k]
  |  Branch (136:28): [True: 0, False: 0]
  ------------------
  137|      0|       return CRYPT_INVALID_ROUNDS;
  138|      0|    }
  139|       |
  140|  6.01k|    skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
  141|       |
  142|       |    /* setup the forward key */
  143|  6.01k|    i                 = 0;
  144|  6.01k|    rk                = skey->rijndael.eK;
  145|  6.01k|    LOAD32H(rk[0], key     );
  ------------------
  |  |   66|  6.01k|#define LOAD32H(x, y)                           \
  |  |   67|  6.01k|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  6.01k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  6.01k|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
  146|  6.01k|    LOAD32H(rk[1], key +  4);
  ------------------
  |  |   66|  6.01k|#define LOAD32H(x, y)                           \
  |  |   67|  6.01k|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  6.01k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  6.01k|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
  147|  6.01k|    LOAD32H(rk[2], key +  8);
  ------------------
  |  |   66|  6.01k|#define LOAD32H(x, y)                           \
  |  |   67|  6.01k|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  6.01k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  6.01k|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
  148|  6.01k|    LOAD32H(rk[3], key + 12);
  ------------------
  |  |   66|  6.01k|#define LOAD32H(x, y)                           \
  |  |   67|  6.01k|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  6.01k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  6.01k|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
  149|  6.01k|    if (keylen == 16) {
  ------------------
  |  Branch (149:9): [True: 5.26k, False: 753]
  ------------------
  150|  52.6k|        for (;;) {
  151|  52.6k|            temp  = rk[3];
  152|  52.6k|            rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
  153|  52.6k|            rk[5] = rk[1] ^ rk[4];
  154|  52.6k|            rk[6] = rk[2] ^ rk[5];
  155|  52.6k|            rk[7] = rk[3] ^ rk[6];
  156|  52.6k|            if (++i == 10) {
  ------------------
  |  Branch (156:17): [True: 5.26k, False: 47.3k]
  ------------------
  157|  5.26k|               break;
  158|  5.26k|            }
  159|  47.3k|            rk += 4;
  160|  47.3k|        }
  161|  5.26k|    } else if (keylen == 24) {
  ------------------
  |  Branch (161:16): [True: 0, False: 753]
  ------------------
  162|      0|        LOAD32H(rk[4], key + 16);
  ------------------
  |  |   66|      0|#define LOAD32H(x, y)                           \
  |  |   67|      0|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|      0|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|      0|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 0]
  |  |  ------------------
  ------------------
  163|      0|        LOAD32H(rk[5], key + 20);
  ------------------
  |  |   66|      0|#define LOAD32H(x, y)                           \
  |  |   67|      0|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|      0|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|      0|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 0]
  |  |  ------------------
  ------------------
  164|      0|        for (;;) {
  165|       |        #ifdef _MSC_VER
  166|       |            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
  167|       |        #else
  168|      0|            temp = rk[5];
  169|      0|        #endif
  170|      0|            rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
  171|      0|            rk[ 7] = rk[ 1] ^ rk[ 6];
  172|      0|            rk[ 8] = rk[ 2] ^ rk[ 7];
  173|      0|            rk[ 9] = rk[ 3] ^ rk[ 8];
  174|      0|            if (++i == 8) {
  ------------------
  |  Branch (174:17): [True: 0, False: 0]
  ------------------
  175|      0|                break;
  176|      0|            }
  177|      0|            rk[10] = rk[ 4] ^ rk[ 9];
  178|      0|            rk[11] = rk[ 5] ^ rk[10];
  179|      0|            rk += 6;
  180|      0|        }
  181|    753|    } else if (keylen == 32) {
  ------------------
  |  Branch (181:16): [True: 753, False: 0]
  ------------------
  182|    753|        LOAD32H(rk[4], key + 16);
  ------------------
  |  |   66|    753|#define LOAD32H(x, y)                           \
  |  |   67|    753|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|    753|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|    753|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 753]
  |  |  ------------------
  ------------------
  183|    753|        LOAD32H(rk[5], key + 20);
  ------------------
  |  |   66|    753|#define LOAD32H(x, y)                           \
  |  |   67|    753|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|    753|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|    753|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 753]
  |  |  ------------------
  ------------------
  184|    753|        LOAD32H(rk[6], key + 24);
  ------------------
  |  |   66|    753|#define LOAD32H(x, y)                           \
  |  |   67|    753|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|    753|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|    753|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 753]
  |  |  ------------------
  ------------------
  185|    753|        LOAD32H(rk[7], key + 28);
  ------------------
  |  |   66|    753|#define LOAD32H(x, y)                           \
  |  |   67|    753|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|    753|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|    753|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 753]
  |  |  ------------------
  ------------------
  186|  5.27k|        for (;;) {
  187|       |        #ifdef _MSC_VER
  188|       |            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
  189|       |        #else
  190|  5.27k|            temp = rk[7];
  191|  5.27k|        #endif
  192|  5.27k|            rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
  193|  5.27k|            rk[ 9] = rk[ 1] ^ rk[ 8];
  194|  5.27k|            rk[10] = rk[ 2] ^ rk[ 9];
  195|  5.27k|            rk[11] = rk[ 3] ^ rk[10];
  196|  5.27k|            if (++i == 7) {
  ------------------
  |  Branch (196:17): [True: 753, False: 4.51k]
  ------------------
  197|    753|                break;
  198|    753|            }
  199|  4.51k|            temp = rk[11];
  200|  4.51k|            rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
  ------------------
  |  |  283|  4.51k|#define RORc(word,i) ({ \
  |  |  284|  4.51k|   ulong32 __RORc_tmp = (word); \
  |  |  285|  4.51k|   __asm__ ("rorl %2, %0" : \
  |  |  286|  4.51k|            "=r" (__RORc_tmp) : \
  |  |  287|  4.51k|            "0" (__RORc_tmp), \
  |  |  288|  4.51k|            "I" (i)); \
  |  |  289|  4.51k|            __RORc_tmp; \
  |  |  290|  4.51k|   })
  ------------------
  201|  4.51k|            rk[13] = rk[ 5] ^ rk[12];
  202|  4.51k|            rk[14] = rk[ 6] ^ rk[13];
  203|  4.51k|            rk[15] = rk[ 7] ^ rk[14];
  204|  4.51k|            rk += 8;
  205|  4.51k|        }
  206|    753|    } else {
  207|       |       /* this can't happen */
  208|       |       /* coverity[dead_error_line] */
  209|      0|       return CRYPT_ERROR;
  210|      0|    }
  211|       |
  212|  6.01k|#ifndef ENCRYPT_ONLY
  213|       |    /* setup the inverse key now */
  214|  6.01k|    rk   = skey->rijndael.dK;
  215|  6.01k|    rrk  = skey->rijndael.eK + (28 + keylen) - 4;
  216|       |
  217|       |    /* apply the inverse MixColumn transform to all round keys but the first and the last: */
  218|       |    /* copy first */
  219|  6.01k|    *rk++ = *rrk++;
  220|  6.01k|    *rk++ = *rrk++;
  221|  6.01k|    *rk++ = *rrk++;
  222|  6.01k|    *rk   = *rrk;
  223|  6.01k|    rk -= 3; rrk -= 3;
  224|       |
  225|  63.1k|    for (i = 1; i < skey->rijndael.Nr; i++) {
  ------------------
  |  Branch (225:17): [True: 57.1k, False: 6.01k]
  ------------------
  226|  57.1k|        rrk -= 4;
  227|  57.1k|        rk  += 4;
  228|  57.1k|    #ifdef LTC_SMALL_CODE
  229|  57.1k|        temp = rrk[0];
  230|  57.1k|        rk[0] = setup_mix2(temp);
  231|  57.1k|        temp = rrk[1];
  232|  57.1k|        rk[1] = setup_mix2(temp);
  233|  57.1k|        temp = rrk[2];
  234|  57.1k|        rk[2] = setup_mix2(temp);
  235|  57.1k|        temp = rrk[3];
  236|  57.1k|        rk[3] = setup_mix2(temp);
  237|       |     #else
  238|       |        temp = rrk[0];
  239|       |        rk[0] =
  240|       |            Tks0[byte(temp, 3)] ^
  241|       |            Tks1[byte(temp, 2)] ^
  242|       |            Tks2[byte(temp, 1)] ^
  243|       |            Tks3[byte(temp, 0)];
  244|       |        temp = rrk[1];
  245|       |        rk[1] =
  246|       |            Tks0[byte(temp, 3)] ^
  247|       |            Tks1[byte(temp, 2)] ^
  248|       |            Tks2[byte(temp, 1)] ^
  249|       |            Tks3[byte(temp, 0)];
  250|       |        temp = rrk[2];
  251|       |        rk[2] =
  252|       |            Tks0[byte(temp, 3)] ^
  253|       |            Tks1[byte(temp, 2)] ^
  254|       |            Tks2[byte(temp, 1)] ^
  255|       |            Tks3[byte(temp, 0)];
  256|       |        temp = rrk[3];
  257|       |        rk[3] =
  258|       |            Tks0[byte(temp, 3)] ^
  259|       |            Tks1[byte(temp, 2)] ^
  260|       |            Tks2[byte(temp, 1)] ^
  261|       |            Tks3[byte(temp, 0)];
  262|       |      #endif
  263|       |
  264|  57.1k|    }
  265|       |
  266|       |    /* copy last */
  267|  6.01k|    rrk -= 4;
  268|  6.01k|    rk  += 4;
  269|  6.01k|    *rk++ = *rrk++;
  270|  6.01k|    *rk++ = *rrk++;
  271|  6.01k|    *rk++ = *rrk++;
  272|  6.01k|    *rk   = *rrk;
  273|  6.01k|#endif /* ENCRYPT_ONLY */
  274|       |
  275|  6.01k|    return CRYPT_OK;
  276|  6.01k|}
rijndael_ecb_encrypt:
  290|  10.8M|{
  291|  10.8M|    ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
  292|  10.8M|    int Nr, r;
  293|       |
  294|  10.8M|    LTC_ARGCHK(pt != NULL);
  ------------------
  |  |   32|  10.8M|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 10.8M]
  |  |  |  Branch (32:87): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  295|  10.8M|    LTC_ARGCHK(ct != NULL);
  ------------------
  |  |   32|  10.8M|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 10.8M]
  |  |  |  Branch (32:87): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  296|  10.8M|    LTC_ARGCHK(skey != NULL);
  ------------------
  |  |   32|  10.8M|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 10.8M]
  |  |  |  Branch (32:87): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  297|       |
  298|  10.8M|    Nr = skey->rijndael.Nr;
  299|  10.8M|    rk = skey->rijndael.eK;
  300|       |
  301|       |    /*
  302|       |     * map byte array block to cipher state
  303|       |     * and add initial round key:
  304|       |     */
  305|  10.8M|    LOAD32H(s0, pt      ); s0 ^= rk[0];
  ------------------
  |  |   66|  10.8M|#define LOAD32H(x, y)                           \
  |  |   67|  10.8M|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  10.8M|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  306|  10.8M|    LOAD32H(s1, pt  +  4); s1 ^= rk[1];
  ------------------
  |  |   66|  10.8M|#define LOAD32H(x, y)                           \
  |  |   67|  10.8M|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  10.8M|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  307|  10.8M|    LOAD32H(s2, pt  +  8); s2 ^= rk[2];
  ------------------
  |  |   66|  10.8M|#define LOAD32H(x, y)                           \
  |  |   67|  10.8M|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  10.8M|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  308|  10.8M|    LOAD32H(s3, pt  + 12); s3 ^= rk[3];
  ------------------
  |  |   66|  10.8M|#define LOAD32H(x, y)                           \
  |  |   67|  10.8M|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  10.8M|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  309|       |
  310|  10.8M|#ifdef LTC_SMALL_CODE
  311|       |
  312|  98.2M|    for (r = 0; ; r++) {
  313|  98.2M|        rk += 4;
  314|  98.2M|        t0 =
  315|  98.2M|            Te0(byte(s0, 3)) ^
  ------------------
  |  |  306|  98.2M|#define Te0(x) TE0[x]
  ------------------
  316|  98.2M|            Te1(byte(s1, 2)) ^
  ------------------
  |  |  307|  98.2M|#define Te1(x) RORc(TE0[x], 8)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  317|  98.2M|            Te2(byte(s2, 1)) ^
  ------------------
  |  |  308|  98.2M|#define Te2(x) RORc(TE0[x], 16)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  318|  98.2M|            Te3(byte(s3, 0)) ^
  ------------------
  |  |  309|  98.2M|#define Te3(x) RORc(TE0[x], 24)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  319|  98.2M|            rk[0];
  320|  98.2M|        t1 =
  321|  98.2M|            Te0(byte(s1, 3)) ^
  ------------------
  |  |  306|  98.2M|#define Te0(x) TE0[x]
  ------------------
  322|  98.2M|            Te1(byte(s2, 2)) ^
  ------------------
  |  |  307|  98.2M|#define Te1(x) RORc(TE0[x], 8)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  323|  98.2M|            Te2(byte(s3, 1)) ^
  ------------------
  |  |  308|  98.2M|#define Te2(x) RORc(TE0[x], 16)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  324|  98.2M|            Te3(byte(s0, 0)) ^
  ------------------
  |  |  309|  98.2M|#define Te3(x) RORc(TE0[x], 24)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  325|  98.2M|            rk[1];
  326|  98.2M|        t2 =
  327|  98.2M|            Te0(byte(s2, 3)) ^
  ------------------
  |  |  306|  98.2M|#define Te0(x) TE0[x]
  ------------------
  328|  98.2M|            Te1(byte(s3, 2)) ^
  ------------------
  |  |  307|  98.2M|#define Te1(x) RORc(TE0[x], 8)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  329|  98.2M|            Te2(byte(s0, 1)) ^
  ------------------
  |  |  308|  98.2M|#define Te2(x) RORc(TE0[x], 16)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  330|  98.2M|            Te3(byte(s1, 0)) ^
  ------------------
  |  |  309|  98.2M|#define Te3(x) RORc(TE0[x], 24)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  331|  98.2M|            rk[2];
  332|  98.2M|        t3 =
  333|  98.2M|            Te0(byte(s3, 3)) ^
  ------------------
  |  |  306|  98.2M|#define Te0(x) TE0[x]
  ------------------
  334|  98.2M|            Te1(byte(s0, 2)) ^
  ------------------
  |  |  307|  98.2M|#define Te1(x) RORc(TE0[x], 8)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  335|  98.2M|            Te2(byte(s1, 1)) ^
  ------------------
  |  |  308|  98.2M|#define Te2(x) RORc(TE0[x], 16)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  336|  98.2M|            Te3(byte(s2, 0)) ^
  ------------------
  |  |  309|  98.2M|#define Te3(x) RORc(TE0[x], 24)
  |  |  ------------------
  |  |  |  |  283|  98.2M|#define RORc(word,i) ({ \
  |  |  |  |  284|  98.2M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|  98.2M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|  98.2M|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|  98.2M|            "0" (__RORc_tmp), \
  |  |  |  |  288|  98.2M|            "I" (i)); \
  |  |  |  |  289|  98.2M|            __RORc_tmp; \
  |  |  |  |  290|  98.2M|   })
  |  |  ------------------
  ------------------
  337|  98.2M|            rk[3];
  338|  98.2M|        if (r == Nr-2) {
  ------------------
  |  Branch (338:13): [True: 10.8M, False: 87.4M]
  ------------------
  339|  10.8M|           break;
  340|  10.8M|        }
  341|  87.4M|        s0 = t0; s1 = t1; s2 = t2; s3 = t3;
  342|  87.4M|    }
  343|  10.8M|    rk += 4;
  344|       |
  345|       |#else
  346|       |
  347|       |    /*
  348|       |     * Nr - 1 full rounds:
  349|       |     */
  350|       |    r = Nr >> 1;
  351|       |    for (;;) {
  352|       |        t0 =
  353|       |            Te0(byte(s0, 3)) ^
  354|       |            Te1(byte(s1, 2)) ^
  355|       |            Te2(byte(s2, 1)) ^
  356|       |            Te3(byte(s3, 0)) ^
  357|       |            rk[4];
  358|       |        t1 =
  359|       |            Te0(byte(s1, 3)) ^
  360|       |            Te1(byte(s2, 2)) ^
  361|       |            Te2(byte(s3, 1)) ^
  362|       |            Te3(byte(s0, 0)) ^
  363|       |            rk[5];
  364|       |        t2 =
  365|       |            Te0(byte(s2, 3)) ^
  366|       |            Te1(byte(s3, 2)) ^
  367|       |            Te2(byte(s0, 1)) ^
  368|       |            Te3(byte(s1, 0)) ^
  369|       |            rk[6];
  370|       |        t3 =
  371|       |            Te0(byte(s3, 3)) ^
  372|       |            Te1(byte(s0, 2)) ^
  373|       |            Te2(byte(s1, 1)) ^
  374|       |            Te3(byte(s2, 0)) ^
  375|       |            rk[7];
  376|       |
  377|       |        rk += 8;
  378|       |        if (--r == 0) {
  379|       |            break;
  380|       |        }
  381|       |
  382|       |        s0 =
  383|       |            Te0(byte(t0, 3)) ^
  384|       |            Te1(byte(t1, 2)) ^
  385|       |            Te2(byte(t2, 1)) ^
  386|       |            Te3(byte(t3, 0)) ^
  387|       |            rk[0];
  388|       |        s1 =
  389|       |            Te0(byte(t1, 3)) ^
  390|       |            Te1(byte(t2, 2)) ^
  391|       |            Te2(byte(t3, 1)) ^
  392|       |            Te3(byte(t0, 0)) ^
  393|       |            rk[1];
  394|       |        s2 =
  395|       |            Te0(byte(t2, 3)) ^
  396|       |            Te1(byte(t3, 2)) ^
  397|       |            Te2(byte(t0, 1)) ^
  398|       |            Te3(byte(t1, 0)) ^
  399|       |            rk[2];
  400|       |        s3 =
  401|       |            Te0(byte(t3, 3)) ^
  402|       |            Te1(byte(t0, 2)) ^
  403|       |            Te2(byte(t1, 1)) ^
  404|       |            Te3(byte(t2, 0)) ^
  405|       |            rk[3];
  406|       |    }
  407|       |
  408|       |#endif
  409|       |
  410|       |    /*
  411|       |     * apply last round and
  412|       |     * map cipher state to byte array block:
  413|       |     */
  414|  10.8M|    s0 =
  415|  10.8M|        (Te4_3[byte(t0, 3)]) ^
  ------------------
  |  |  319|  10.8M|#define Te4_3 0xFF000000 & Te4
  ------------------
                      (Te4_3[byte(t0, 3)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  416|  10.8M|        (Te4_2[byte(t1, 2)]) ^
  ------------------
  |  |  318|  10.8M|#define Te4_2 0x00FF0000 & Te4
  ------------------
                      (Te4_2[byte(t1, 2)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  417|  10.8M|        (Te4_1[byte(t2, 1)]) ^
  ------------------
  |  |  317|  10.8M|#define Te4_1 0x0000FF00 & Te4
  ------------------
                      (Te4_1[byte(t2, 1)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  418|  10.8M|        (Te4_0[byte(t3, 0)]) ^
  ------------------
  |  |  316|  10.8M|#define Te4_0 0x000000FF & Te4
  ------------------
                      (Te4_0[byte(t3, 0)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  419|  10.8M|        rk[0];
  420|  10.8M|    STORE32H(s0, ct);
  ------------------
  |  |   62|  10.8M|#define STORE32H(x, y)                          \
  |  |   63|  10.8M|do { ulong32 __t = __builtin_bswap32 ((x));     \
  |  |   64|  10.8M|      XMEMCPY ((y), &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (64:39): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  421|  10.8M|    s1 =
  422|  10.8M|        (Te4_3[byte(t1, 3)]) ^
  ------------------
  |  |  319|  10.8M|#define Te4_3 0xFF000000 & Te4
  ------------------
                      (Te4_3[byte(t1, 3)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  423|  10.8M|        (Te4_2[byte(t2, 2)]) ^
  ------------------
  |  |  318|  10.8M|#define Te4_2 0x00FF0000 & Te4
  ------------------
                      (Te4_2[byte(t2, 2)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  424|  10.8M|        (Te4_1[byte(t3, 1)]) ^
  ------------------
  |  |  317|  10.8M|#define Te4_1 0x0000FF00 & Te4
  ------------------
                      (Te4_1[byte(t3, 1)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  425|  10.8M|        (Te4_0[byte(t0, 0)]) ^
  ------------------
  |  |  316|  10.8M|#define Te4_0 0x000000FF & Te4
  ------------------
                      (Te4_0[byte(t0, 0)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  426|  10.8M|        rk[1];
  427|  10.8M|    STORE32H(s1, ct+4);
  ------------------
  |  |   62|  10.8M|#define STORE32H(x, y)                          \
  |  |   63|  10.8M|do { ulong32 __t = __builtin_bswap32 ((x));     \
  |  |   64|  10.8M|      XMEMCPY ((y), &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (64:39): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  428|  10.8M|    s2 =
  429|  10.8M|        (Te4_3[byte(t2, 3)]) ^
  ------------------
  |  |  319|  10.8M|#define Te4_3 0xFF000000 & Te4
  ------------------
                      (Te4_3[byte(t2, 3)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  430|  10.8M|        (Te4_2[byte(t3, 2)]) ^
  ------------------
  |  |  318|  10.8M|#define Te4_2 0x00FF0000 & Te4
  ------------------
                      (Te4_2[byte(t3, 2)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  431|  10.8M|        (Te4_1[byte(t0, 1)]) ^
  ------------------
  |  |  317|  10.8M|#define Te4_1 0x0000FF00 & Te4
  ------------------
                      (Te4_1[byte(t0, 1)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  432|  10.8M|        (Te4_0[byte(t1, 0)]) ^
  ------------------
  |  |  316|  10.8M|#define Te4_0 0x000000FF & Te4
  ------------------
                      (Te4_0[byte(t1, 0)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  433|  10.8M|        rk[2];
  434|  10.8M|    STORE32H(s2, ct+8);
  ------------------
  |  |   62|  10.8M|#define STORE32H(x, y)                          \
  |  |   63|  10.8M|do { ulong32 __t = __builtin_bswap32 ((x));     \
  |  |   64|  10.8M|      XMEMCPY ((y), &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (64:39): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  435|  10.8M|    s3 =
  436|  10.8M|        (Te4_3[byte(t3, 3)]) ^
  ------------------
  |  |  319|  10.8M|#define Te4_3 0xFF000000 & Te4
  ------------------
                      (Te4_3[byte(t3, 3)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  437|  10.8M|        (Te4_2[byte(t0, 2)]) ^
  ------------------
  |  |  318|  10.8M|#define Te4_2 0x00FF0000 & Te4
  ------------------
                      (Te4_2[byte(t0, 2)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  438|  10.8M|        (Te4_1[byte(t1, 1)]) ^
  ------------------
  |  |  317|  10.8M|#define Te4_1 0x0000FF00 & Te4
  ------------------
                      (Te4_1[byte(t1, 1)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  439|  10.8M|        (Te4_0[byte(t2, 0)]) ^
  ------------------
  |  |  316|  10.8M|#define Te4_0 0x000000FF & Te4
  ------------------
                      (Te4_0[byte(t2, 0)]) ^
  ------------------
  |  |  436|  10.8M|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  440|  10.8M|        rk[3];
  441|  10.8M|    STORE32H(s3, ct+12);
  ------------------
  |  |   62|  10.8M|#define STORE32H(x, y)                          \
  |  |   63|  10.8M|do { ulong32 __t = __builtin_bswap32 ((x));     \
  |  |   64|  10.8M|      XMEMCPY ((y), &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  10.8M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (64:39): [Folded, False: 10.8M]
  |  |  ------------------
  ------------------
  442|       |
  443|  10.8M|    return CRYPT_OK;
  444|  10.8M|}
aes.c:setup_mix:
   95|  62.4k|{
   96|  62.4k|   return (Te4_3[byte(temp, 2)]) ^
  ------------------
  |  |  319|  62.4k|#define Te4_3 0xFF000000 & Te4
  ------------------
                 return (Te4_3[byte(temp, 2)]) ^
  ------------------
  |  |  436|  62.4k|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
   97|  62.4k|          (Te4_2[byte(temp, 1)]) ^
  ------------------
  |  |  318|  62.4k|#define Te4_2 0x00FF0000 & Te4
  ------------------
                        (Te4_2[byte(temp, 1)]) ^
  ------------------
  |  |  436|  62.4k|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
   98|  62.4k|          (Te4_1[byte(temp, 0)]) ^
  ------------------
  |  |  317|  62.4k|#define Te4_1 0x0000FF00 & Te4
  ------------------
                        (Te4_1[byte(temp, 0)]) ^
  ------------------
  |  |  436|  62.4k|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
   99|  62.4k|          (Te4_0[byte(temp, 3)]);
  ------------------
  |  |  316|  62.4k|#define Te4_0 0x000000FF & Te4
  ------------------
                        (Te4_0[byte(temp, 3)]);
  ------------------
  |  |  436|  62.4k|   #define byte(x, n) (((x) >> (8 * (n))) & 255)
  ------------------
  100|  62.4k|}
aes.c:setup_mix2:
  105|   228k|{
  106|   228k|   return Td0(255 & Te4[byte(temp, 3)]) ^
  ------------------
  |  |  311|   228k|#define Td0(x) TD0[x]
  ------------------
  107|   228k|          Td1(255 & Te4[byte(temp, 2)]) ^
  ------------------
  |  |  312|   228k|#define Td1(x) RORc(TD0[x], 8)
  |  |  ------------------
  |  |  |  |  283|   228k|#define RORc(word,i) ({ \
  |  |  |  |  284|   228k|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|   228k|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|   228k|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|   228k|            "0" (__RORc_tmp), \
  |  |  |  |  288|   228k|            "I" (i)); \
  |  |  |  |  289|   228k|            __RORc_tmp; \
  |  |  |  |  290|   228k|   })
  |  |  ------------------
  ------------------
  108|   228k|          Td2(255 & Te4[byte(temp, 1)]) ^
  ------------------
  |  |  313|   228k|#define Td2(x) RORc(TD0[x], 16)
  |  |  ------------------
  |  |  |  |  283|   228k|#define RORc(word,i) ({ \
  |  |  |  |  284|   228k|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|   228k|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|   228k|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|   228k|            "0" (__RORc_tmp), \
  |  |  |  |  288|   228k|            "I" (i)); \
  |  |  |  |  289|   228k|            __RORc_tmp; \
  |  |  |  |  290|   228k|   })
  |  |  ------------------
  ------------------
  109|   228k|          Td3(255 & Te4[byte(temp, 0)]);
  ------------------
  |  |  314|   228k|#define Td3(x) RORc(TD0[x], 24)
  |  |  ------------------
  |  |  |  |  283|   228k|#define RORc(word,i) ({ \
  |  |  |  |  284|   228k|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  285|   228k|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  286|   228k|            "=r" (__RORc_tmp) : \
  |  |  |  |  287|   228k|            "0" (__RORc_tmp), \
  |  |  |  |  288|   228k|            "I" (i)); \
  |  |  |  |  289|   228k|            __RORc_tmp; \
  |  |  |  |  290|   228k|   })
  |  |  ------------------
  ------------------
  110|   228k|}

sha256_init:
  205|   213k|{
  206|   213k|    LTC_ARGCHK(md != NULL);
  ------------------
  |  |   32|   213k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 213k]
  |  |  |  Branch (32:87): [Folded, False: 213k]
  |  |  ------------------
  ------------------
  207|       |
  208|   213k|    md->sha256.curlen = 0;
  209|   213k|    md->sha256.length = 0;
  210|   213k|    md->sha256.state[0] = 0x6A09E667UL;
  211|   213k|    md->sha256.state[1] = 0xBB67AE85UL;
  212|   213k|    md->sha256.state[2] = 0x3C6EF372UL;
  213|   213k|    md->sha256.state[3] = 0xA54FF53AUL;
  214|   213k|    md->sha256.state[4] = 0x510E527FUL;
  215|   213k|    md->sha256.state[5] = 0x9B05688CUL;
  216|   213k|    md->sha256.state[6] = 0x1F83D9ABUL;
  217|   213k|    md->sha256.state[7] = 0x5BE0CD19UL;
  218|   213k|    return CRYPT_OK;
  219|   213k|}
sha256_done:
  237|   235k|{
  238|   235k|    int i;
  239|       |
  240|   235k|    LTC_ARGCHK(md  != NULL);
  ------------------
  |  |   32|   235k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 235k]
  |  |  |  Branch (32:87): [Folded, False: 235k]
  |  |  ------------------
  ------------------
  241|   235k|    LTC_ARGCHK(out != NULL);
  ------------------
  |  |   32|   235k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 235k]
  |  |  |  Branch (32:87): [Folded, False: 235k]
  |  |  ------------------
  ------------------
  242|       |
  243|   235k|    if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
  ------------------
  |  Branch (243:9): [True: 0, False: 235k]
  ------------------
  244|      0|       return CRYPT_INVALID_ARG;
  245|      0|    }
  246|       |
  247|       |
  248|       |    /* increase the length of the message */
  249|   235k|    md->sha256.length += md->sha256.curlen * 8;
  250|       |
  251|       |    /* append the '1' bit */
  252|   235k|    md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
  253|       |
  254|       |    /* if the length is currently above 56 bytes we append zeros
  255|       |     * then compress.  Then we can fall back to padding zeros and length
  256|       |     * encoding like normal.
  257|       |     */
  258|   235k|    if (md->sha256.curlen > 56) {
  ------------------
  |  Branch (258:9): [True: 202, False: 235k]
  ------------------
  259|    553|        while (md->sha256.curlen < 64) {
  ------------------
  |  Branch (259:16): [True: 351, False: 202]
  ------------------
  260|    351|            md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
  261|    351|        }
  262|    202|        sha256_compress(md, md->sha256.buf);
  263|    202|        md->sha256.curlen = 0;
  264|    202|    }
  265|       |
  266|       |    /* pad upto 56 bytes of zeroes */
  267|  5.97M|    while (md->sha256.curlen < 56) {
  ------------------
  |  Branch (267:12): [True: 5.74M, False: 235k]
  ------------------
  268|  5.74M|        md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
  269|  5.74M|    }
  270|       |
  271|       |    /* store length */
  272|   235k|    STORE64H(md->sha256.length, md->sha256.buf+56);
  ------------------
  |  |  101|   235k|#define STORE64H(x, y)                          \
  |  |  102|   235k|do { ulong64 __t = __builtin_bswap64 ((x));     \
  |  |  103|   235k|      XMEMCPY ((y), &__t, 8); } while(0)
  |  |  ------------------
  |  |  |  |   39|   235k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (103:39): [Folded, False: 235k]
  |  |  ------------------
  ------------------
  273|   235k|    sha256_compress(md, md->sha256.buf);
  274|       |
  275|       |    /* copy output */
  276|  2.11M|    for (i = 0; i < 8; i++) {
  ------------------
  |  Branch (276:17): [True: 1.88M, False: 235k]
  ------------------
  277|  1.88M|        STORE32H(md->sha256.state[i], out+(4*i));
  ------------------
  |  |   62|  1.88M|#define STORE32H(x, y)                          \
  |  |   63|  1.88M|do { ulong32 __t = __builtin_bswap32 ((x));     \
  |  |   64|  1.88M|      XMEMCPY ((y), &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  1.88M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (64:39): [Folded, False: 1.88M]
  |  |  ------------------
  ------------------
  278|  1.88M|    }
  279|       |#ifdef LTC_CLEAN_STACK
  280|       |    zeromem(md, sizeof(hash_state));
  281|       |#endif
  282|   235k|    return CRYPT_OK;
  283|   235k|}
sha256.c:sha256_compress:
   71|  3.08M|{
   72|  3.08M|    ulong32 S[8], W[64], t0, t1;
   73|  3.08M|#ifdef LTC_SMALL_CODE
   74|  3.08M|    ulong32 t;
   75|  3.08M|#endif
   76|  3.08M|    int i;
   77|       |
   78|       |    /* copy state into S */
   79|  27.7M|    for (i = 0; i < 8; i++) {
  ------------------
  |  Branch (79:17): [True: 24.6M, False: 3.08M]
  ------------------
   80|  24.6M|        S[i] = md->sha256.state[i];
   81|  24.6M|    }
   82|       |
   83|       |    /* copy the state into 512-bits into W[0..15] */
   84|  52.4M|    for (i = 0; i < 16; i++) {
  ------------------
  |  Branch (84:17): [True: 49.3M, False: 3.08M]
  ------------------
   85|  49.3M|        LOAD32H(W[i], buf + (4*i));
  ------------------
  |  |   66|  49.3M|#define LOAD32H(x, y)                           \
  |  |   67|  49.3M|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|  49.3M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|  49.3M|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 49.3M]
  |  |  ------------------
  ------------------
   86|  49.3M|    }
   87|       |
   88|       |    /* fill W[16..63] */
   89|   151M|    for (i = 16; i < 64; i++) {
  ------------------
  |  Branch (89:18): [True: 148M, False: 3.08M]
  ------------------
   90|   148M|        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
  ------------------
  |  |   63|   148M|#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
  |  |  ------------------
  |  |  |  |   58|   148M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  ------------------
  |  |  |  |  |  |  283|   148M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  284|   148M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  285|   148M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  286|   148M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  287|   148M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  288|   148M|            "I" (i)); \
  |  |  |  |  |  |  289|   148M|            __RORc_tmp; \
  |  |  |  |  |  |  290|   148M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
  |  |  ------------------
  |  |  |  |   58|   148M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  ------------------
  |  |  |  |  |  |  283|   148M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  284|   148M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  285|   148M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  286|   148M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  287|   148M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  288|   148M|            "I" (i)); \
  |  |  |  |  |  |  289|   148M|            __RORc_tmp; \
  |  |  |  |  |  |  290|   148M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
  |  |  ------------------
  |  |  |  |   59|   148M|#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
  |  |  ------------------
  ------------------
                      W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
  ------------------
  |  |   62|   148M|#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
  |  |  ------------------
  |  |  |  |   58|   148M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  ------------------
  |  |  |  |  |  |  283|   148M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  284|   148M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  285|   148M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  286|   148M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  287|   148M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  288|   148M|            "I" (i)); \
  |  |  |  |  |  |  289|   148M|            __RORc_tmp; \
  |  |  |  |  |  |  290|   148M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
  |  |  ------------------
  |  |  |  |   58|   148M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  ------------------
  |  |  |  |  |  |  283|   148M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  284|   148M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  285|   148M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  286|   148M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  287|   148M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  288|   148M|            "I" (i)); \
  |  |  |  |  |  |  289|   148M|            __RORc_tmp; \
  |  |  |  |  |  |  290|   148M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
  |  |  ------------------
  |  |  |  |   59|   148M|#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))
  |  |  ------------------
  ------------------
   91|   148M|    }
   92|       |
   93|       |    /* Compress */
   94|  3.08M|#ifdef LTC_SMALL_CODE
   95|  3.08M|#define RND(a,b,c,d,e,f,g,h,i)                         \
   96|  3.08M|     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
   97|  3.08M|     t1 = Sigma0(a) + Maj(a, b, c);                    \
   98|  3.08M|     d += t0;                                          \
   99|  3.08M|     h  = t0 + t1;
  100|       |
  101|   200M|     for (i = 0; i < 64; ++i) {
  ------------------
  |  Branch (101:18): [True: 197M, False: 3.08M]
  ------------------
  102|   197M|         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
  ------------------
  |  |   96|   197M|     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
  |  |  ------------------
  |  |  |  |   61|   197M|#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
  |  |  |  |  ------------------
  |  |  |  |  |  |   58|   197M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  283|   197M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  |  |  284|   197M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  |  |  285|   197M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  |  |  286|   197M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  |  |  287|   197M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  |  |  288|   197M|            "I" (i)); \
  |  |  |  |  |  |  |  |  289|   197M|            __RORc_tmp; \
  |  |  |  |  |  |  |  |  290|   197M|   })
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |               #define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
  |  |  |  |  ------------------
  |  |  |  |  |  |   58|   197M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  283|   197M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  |  |  284|   197M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  |  |  285|   197M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  |  |  286|   197M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  |  |  287|   197M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  |  |  288|   197M|            "I" (i)); \
  |  |  |  |  |  |  |  |  289|   197M|            __RORc_tmp; \
  |  |  |  |  |  |  |  |  290|   197M|   })
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |               #define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
  |  |  |  |  ------------------
  |  |  |  |  |  |   58|   197M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  283|   197M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  |  |  284|   197M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  |  |  285|   197M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  |  |  286|   197M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  |  |  287|   197M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  |  |  288|   197M|            "I" (i)); \
  |  |  |  |  |  |  |  |  289|   197M|            __RORc_tmp; \
  |  |  |  |  |  |  |  |  290|   197M|   })
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                    t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
  |  |  ------------------
  |  |  |  |   56|   197M|#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
  |  |  ------------------
  |  |   97|   197M|     t1 = Sigma0(a) + Maj(a, b, c);                    \
  |  |  ------------------
  |  |  |  |   60|   197M|#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
  |  |  |  |  ------------------
  |  |  |  |  |  |   58|   197M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  283|   197M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  |  |  284|   197M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  |  |  285|   197M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  |  |  286|   197M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  |  |  287|   197M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  |  |  288|   197M|            "I" (i)); \
  |  |  |  |  |  |  |  |  289|   197M|            __RORc_tmp; \
  |  |  |  |  |  |  |  |  290|   197M|   })
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |               #define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
  |  |  |  |  ------------------
  |  |  |  |  |  |   58|   197M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  283|   197M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  |  |  284|   197M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  |  |  285|   197M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  |  |  286|   197M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  |  |  287|   197M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  |  |  288|   197M|            "I" (i)); \
  |  |  |  |  |  |  |  |  289|   197M|            __RORc_tmp; \
  |  |  |  |  |  |  |  |  290|   197M|   })
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |               #define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
  |  |  |  |  ------------------
  |  |  |  |  |  |   58|   197M|#define S(x, n)         RORc((x),(n))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  283|   197M|#define RORc(word,i) ({ \
  |  |  |  |  |  |  |  |  284|   197M|   ulong32 __RORc_tmp = (word); \
  |  |  |  |  |  |  |  |  285|   197M|   __asm__ ("rorl %2, %0" : \
  |  |  |  |  |  |  |  |  286|   197M|            "=r" (__RORc_tmp) : \
  |  |  |  |  |  |  |  |  287|   197M|            "0" (__RORc_tmp), \
  |  |  |  |  |  |  |  |  288|   197M|            "I" (i)); \
  |  |  |  |  |  |  |  |  289|   197M|            __RORc_tmp; \
  |  |  |  |  |  |  |  |  290|   197M|   })
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                    t1 = Sigma0(a) + Maj(a, b, c);                    \
  |  |  ------------------
  |  |  |  |   57|   197M|#define Maj(x,y,z)      (((x | y) & z) | (x & y))
  |  |  ------------------
  |  |   98|   197M|     d += t0;                                          \
  |  |   99|   197M|     h  = t0 + t1;
  ------------------
  103|   197M|         t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
  104|   197M|         S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
  105|   197M|     }
  106|       |#else
  107|       |#define RND(a,b,c,d,e,f,g,h,i,ki)                    \
  108|       |     t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \
  109|       |     t1 = Sigma0(a) + Maj(a, b, c);                  \
  110|       |     d += t0;                                        \
  111|       |     h  = t0 + t1;
  112|       |
  113|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
  114|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
  115|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
  116|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
  117|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
  118|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
  119|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
  120|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
  121|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
  122|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
  123|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
  124|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
  125|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
  126|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
  127|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
  128|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
  129|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
  130|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
  131|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
  132|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
  133|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
  134|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
  135|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
  136|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
  137|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
  138|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
  139|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
  140|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
  141|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
  142|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
  143|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
  144|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
  145|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
  146|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
  147|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
  148|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
  149|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
  150|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
  151|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
  152|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
  153|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
  154|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
  155|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
  156|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
  157|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
  158|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
  159|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
  160|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
  161|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
  162|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
  163|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
  164|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
  165|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
  166|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
  167|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
  168|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
  169|       |    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
  170|       |    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
  171|       |    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
  172|       |    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
  173|       |    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
  174|       |    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
  175|       |    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
  176|       |    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
  177|       |
  178|       |#undef RND
  179|       |
  180|       |#endif
  181|       |
  182|       |    /* feedback */
  183|  27.7M|    for (i = 0; i < 8; i++) {
  ------------------
  |  Branch (183:17): [True: 24.6M, False: 3.08M]
  ------------------
  184|  24.6M|        md->sha256.state[i] = md->sha256.state[i] + S[i];
  185|  24.6M|    }
  186|  3.08M|    return CRYPT_OK;
  187|  3.08M|}

sha384_init:
   42|    804|{
   43|    804|    LTC_ARGCHK(md != NULL);
  ------------------
  |  |   32|    804|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 804]
  |  |  |  Branch (32:87): [Folded, False: 804]
  |  |  ------------------
  ------------------
   44|       |
   45|    804|    md->sha512.curlen = 0;
   46|    804|    md->sha512.length = 0;
   47|    804|    md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   48|    804|    md->sha512.state[1] = CONST64(0x629a292a367cd507);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   49|    804|    md->sha512.state[2] = CONST64(0x9159015a3070dd17);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   50|    804|    md->sha512.state[3] = CONST64(0x152fecd8f70e5939);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   51|    804|    md->sha512.state[4] = CONST64(0x67332667ffc00b31);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   52|    804|    md->sha512.state[5] = CONST64(0x8eb44a8768581511);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   53|    804|    md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   54|    804|    md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4);
  ------------------
  |  |  200|    804|   #define CONST64(n) n ## ULL
  ------------------
   55|    804|    return CRYPT_OK;
   56|    804|}
sha384_done:
   65|  3.17k|{
   66|  3.17k|   unsigned char buf[64];
   67|       |
   68|  3.17k|   LTC_ARGCHK(md  != NULL);
  ------------------
  |  |   32|  3.17k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 3.17k]
  |  |  |  Branch (32:87): [Folded, False: 3.17k]
  |  |  ------------------
  ------------------
   69|  3.17k|   LTC_ARGCHK(out != NULL);
  ------------------
  |  |   32|  3.17k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 3.17k]
  |  |  |  Branch (32:87): [Folded, False: 3.17k]
  |  |  ------------------
  ------------------
   70|       |
   71|  3.17k|    if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
  ------------------
  |  Branch (71:9): [True: 0, False: 3.17k]
  ------------------
   72|      0|       return CRYPT_INVALID_ARG;
   73|      0|    }
   74|       |
   75|  3.17k|   sha512_done(md, buf);
   76|  3.17k|   XMEMCPY(out, buf, 48);
  ------------------
  |  |   39|  3.17k|#define XMEMCPY  memcpy
  ------------------
   77|       |#ifdef LTC_CLEAN_STACK
   78|       |   zeromem(buf, sizeof(buf));
   79|       |#endif
   80|  3.17k|   return CRYPT_OK;
   81|  3.17k|}

sha512_init:
  174|  4.58k|{
  175|  4.58k|    LTC_ARGCHK(md != NULL);
  ------------------
  |  |   32|  4.58k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 4.58k]
  |  |  |  Branch (32:87): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  176|  4.58k|    md->sha512.curlen = 0;
  177|  4.58k|    md->sha512.length = 0;
  178|  4.58k|    md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  179|  4.58k|    md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  180|  4.58k|    md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  181|  4.58k|    md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  182|  4.58k|    md->sha512.state[4] = CONST64(0x510e527fade682d1);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  183|  4.58k|    md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  184|  4.58k|    md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  185|  4.58k|    md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
  ------------------
  |  |  200|  4.58k|   #define CONST64(n) n ## ULL
  ------------------
  186|  4.58k|    return CRYPT_OK;
  187|  4.58k|}
sha512_done:
  205|  16.9k|{
  206|  16.9k|    int i;
  207|       |
  208|  16.9k|    LTC_ARGCHK(md  != NULL);
  ------------------
  |  |   32|  16.9k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 16.9k]
  |  |  |  Branch (32:87): [Folded, False: 16.9k]
  |  |  ------------------
  ------------------
  209|  16.9k|    LTC_ARGCHK(out != NULL);
  ------------------
  |  |   32|  16.9k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 16.9k]
  |  |  |  Branch (32:87): [Folded, False: 16.9k]
  |  |  ------------------
  ------------------
  210|       |
  211|  16.9k|    if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
  ------------------
  |  Branch (211:9): [True: 0, False: 16.9k]
  ------------------
  212|      0|       return CRYPT_INVALID_ARG;
  213|      0|    }
  214|       |
  215|       |    /* increase the length of the message */
  216|  16.9k|    md->sha512.length += md->sha512.curlen * CONST64(8);
  ------------------
  |  |  200|  16.9k|   #define CONST64(n) n ## ULL
  ------------------
  217|       |
  218|       |    /* append the '1' bit */
  219|  16.9k|    md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
  220|       |
  221|       |    /* if the length is currently above 112 bytes we append zeros
  222|       |     * then compress.  Then we can fall back to padding zeros and length
  223|       |     * encoding like normal.
  224|       |     */
  225|  16.9k|    if (md->sha512.curlen > 112) {
  ------------------
  |  Branch (225:9): [True: 1.26k, False: 15.6k]
  ------------------
  226|  8.75k|        while (md->sha512.curlen < 128) {
  ------------------
  |  Branch (226:16): [True: 7.49k, False: 1.26k]
  ------------------
  227|  7.49k|            md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
  228|  7.49k|        }
  229|  1.26k|        sha512_compress(md, md->sha512.buf);
  230|  1.26k|        md->sha512.curlen = 0;
  231|  1.26k|    }
  232|       |
  233|       |    /* pad upto 120 bytes of zeroes
  234|       |     * note: that from 112 to 120 is the 64 MSB of the length.  We assume that you won't hash
  235|       |     * > 2^64 bits of data... :-)
  236|       |     */
  237|  1.05M|    while (md->sha512.curlen < 120) {
  ------------------
  |  Branch (237:12): [True: 1.03M, False: 16.9k]
  ------------------
  238|  1.03M|        md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
  239|  1.03M|    }
  240|       |
  241|       |    /* store length */
  242|  16.9k|    STORE64H(md->sha512.length, md->sha512.buf+120);
  ------------------
  |  |  101|  16.9k|#define STORE64H(x, y)                          \
  |  |  102|  16.9k|do { ulong64 __t = __builtin_bswap64 ((x));     \
  |  |  103|  16.9k|      XMEMCPY ((y), &__t, 8); } while(0)
  |  |  ------------------
  |  |  |  |   39|  16.9k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (103:39): [Folded, False: 16.9k]
  |  |  ------------------
  ------------------
  243|  16.9k|    sha512_compress(md, md->sha512.buf);
  244|       |
  245|       |    /* copy output */
  246|   152k|    for (i = 0; i < 8; i++) {
  ------------------
  |  Branch (246:17): [True: 135k, False: 16.9k]
  ------------------
  247|   135k|        STORE64H(md->sha512.state[i], out+(8*i));
  ------------------
  |  |  101|   135k|#define STORE64H(x, y)                          \
  |  |  102|   135k|do { ulong64 __t = __builtin_bswap64 ((x));     \
  |  |  103|   135k|      XMEMCPY ((y), &__t, 8); } while(0)
  |  |  ------------------
  |  |  |  |   39|   135k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (103:39): [Folded, False: 135k]
  |  |  ------------------
  ------------------
  248|   135k|    }
  249|       |#ifdef LTC_CLEAN_STACK
  250|       |    zeromem(md, sizeof(hash_state));
  251|       |#endif
  252|  16.9k|    return CRYPT_OK;
  253|  16.9k|}
sha512.c:sha512_compress:
   96|  40.7k|{
   97|  40.7k|    ulong64 S[8], W[80], t0, t1;
   98|  40.7k|    int i;
   99|       |
  100|       |    /* copy state into S */
  101|   366k|    for (i = 0; i < 8; i++) {
  ------------------
  |  Branch (101:17): [True: 325k, False: 40.7k]
  ------------------
  102|   325k|        S[i] = md->sha512.state[i];
  103|   325k|    }
  104|       |
  105|       |    /* copy the state into 1024-bits into W[0..15] */
  106|   692k|    for (i = 0; i < 16; i++) {
  ------------------
  |  Branch (106:17): [True: 651k, False: 40.7k]
  ------------------
  107|   651k|        LOAD64H(W[i], buf + (8*i));
  ------------------
  |  |  105|   651k|#define LOAD64H(x, y)                           \
  |  |  106|   651k|do { XMEMCPY (&(x), (y), 8);                    \
  |  |  ------------------
  |  |  |  |   39|   651k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  107|   651k|      (x) = __builtin_bswap64 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (107:46): [Folded, False: 651k]
  |  |  ------------------
  ------------------
  108|   651k|    }
  109|       |
  110|       |    /* fill W[16..79] */
  111|  2.64M|    for (i = 16; i < 80; i++) {
  ------------------
  |  Branch (111:18): [True: 2.60M, False: 40.7k]
  ------------------
  112|  2.60M|        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
  ------------------
  |  |   88|  2.60M|#define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
  |  |  ------------------
  |  |  |  |   83|  2.60M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  2.60M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  2.60M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  2.60M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  2.60M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  2.60M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  2.60M|            "J" (i)); \
  |  |  |  |  |  |  390|  2.60M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  2.60M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
  |  |  ------------------
  |  |  |  |   83|  2.60M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  2.60M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  2.60M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  2.60M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  2.60M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  2.60M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  2.60M|            "J" (i)); \
  |  |  |  |  |  |  390|  2.60M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  2.60M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
  |  |  ------------------
  |  |  |  |   84|  2.60M|#define R(x, n)         (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
  |  |  |  |  ------------------
  |  |  |  |  |  |  200|  2.60M|   #define CONST64(n) n ## ULL
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
                      W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
  ------------------
  |  |   87|  2.60M|#define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
  |  |  ------------------
  |  |  |  |   83|  2.60M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  2.60M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  2.60M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  2.60M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  2.60M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  2.60M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  2.60M|            "J" (i)); \
  |  |  |  |  |  |  390|  2.60M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  2.60M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
  |  |  ------------------
  |  |  |  |   83|  2.60M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  2.60M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  2.60M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  2.60M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  2.60M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  2.60M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  2.60M|            "J" (i)); \
  |  |  |  |  |  |  390|  2.60M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  2.60M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
  |  |  ------------------
  |  |  |  |   84|  2.60M|#define R(x, n)         (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
  |  |  |  |  ------------------
  |  |  |  |  |  |  200|  2.60M|   #define CONST64(n) n ## ULL
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  113|  2.60M|    }
  114|       |
  115|       |    /* Compress */
  116|  40.7k|#ifdef LTC_SMALL_CODE
  117|  3.30M|    for (i = 0; i < 80; i++) {
  ------------------
  |  Branch (117:17): [True: 3.25M, False: 40.7k]
  ------------------
  118|  3.25M|        t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
  ------------------
  |  |   86|  3.25M|#define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
  |  |  ------------------
  |  |  |  |   83|  3.25M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  3.25M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  3.25M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  3.25M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  3.25M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  3.25M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  3.25M|            "J" (i)); \
  |  |  |  |  |  |  390|  3.25M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  3.25M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
  |  |  ------------------
  |  |  |  |   83|  3.25M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  3.25M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  3.25M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  3.25M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  3.25M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  3.25M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  3.25M|            "J" (i)); \
  |  |  |  |  |  |  390|  3.25M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  3.25M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
  |  |  ------------------
  |  |  |  |   83|  3.25M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  3.25M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  3.25M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  3.25M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  3.25M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  3.25M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  3.25M|            "J" (i)); \
  |  |  |  |  |  |  390|  3.25M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  3.25M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
                      t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
  ------------------
  |  |   81|  3.25M|#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
  ------------------
  119|  3.25M|        t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
  ------------------
  |  |   85|  3.25M|#define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
  |  |  ------------------
  |  |  |  |   83|  3.25M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  3.25M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  3.25M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  3.25M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  3.25M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  3.25M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  3.25M|            "J" (i)); \
  |  |  |  |  |  |  390|  3.25M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  3.25M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
  |  |  ------------------
  |  |  |  |   83|  3.25M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  3.25M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  3.25M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  3.25M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  3.25M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  3.25M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  3.25M|            "J" (i)); \
  |  |  |  |  |  |  390|  3.25M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  3.25M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
  |  |  ------------------
  |  |  |  |   83|  3.25M|#define S(x, n)         ROR64c(x, n)
  |  |  |  |  ------------------
  |  |  |  |  |  |  384|  3.25M|#define ROR64c(word,i) ({ \
  |  |  |  |  |  |  385|  3.25M|   ulong64 __ROR64c_tmp = word; \
  |  |  |  |  |  |  386|  3.25M|   __asm__ ("rorq %2, %0" : \
  |  |  |  |  |  |  387|  3.25M|            "=r" (__ROR64c_tmp) : \
  |  |  |  |  |  |  388|  3.25M|            "0" (__ROR64c_tmp), \
  |  |  |  |  |  |  389|  3.25M|            "J" (i)); \
  |  |  |  |  |  |  390|  3.25M|            __ROR64c_tmp; \
  |  |  |  |  |  |  391|  3.25M|   })
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
                      t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
  ------------------
  |  |   82|  3.25M|#define Maj(x,y,z)      (((x | y) & z) | (x & y))
  ------------------
  120|  3.25M|        S[7] = S[6];
  121|  3.25M|        S[6] = S[5];
  122|  3.25M|        S[5] = S[4];
  123|  3.25M|        S[4] = S[3] + t0;
  124|  3.25M|        S[3] = S[2];
  125|  3.25M|        S[2] = S[1];
  126|  3.25M|        S[1] = S[0];
  127|  3.25M|        S[0] = t0 + t1;
  128|  3.25M|    }
  129|       |#else
  130|       |#define RND(a,b,c,d,e,f,g,h,i)                    \
  131|       |     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
  132|       |     t1 = Sigma0(a) + Maj(a, b, c);                  \
  133|       |     d += t0;                                        \
  134|       |     h  = t0 + t1;
  135|       |
  136|       |    for (i = 0; i < 80; i += 8) {
  137|       |        RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
  138|       |        RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
  139|       |        RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
  140|       |        RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
  141|       |        RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
  142|       |        RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
  143|       |        RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
  144|       |        RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
  145|       |    }
  146|       |#endif
  147|       |
  148|       |
  149|       |    /* feedback */
  150|   366k|    for (i = 0; i < 8; i++) {
  ------------------
  |  Branch (150:17): [True: 325k, False: 40.7k]
  ------------------
  151|   325k|        md->sha512.state[i] = md->sha512.state[i] + S[i];
  152|   325k|    }
  153|       |
  154|  40.7k|    return CRYPT_OK;
  155|  40.7k|}

sha256_process:
  491|   516k|int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)               \
  492|   516k|{                                                                                           \
  493|   516k|    unsigned long n;                                                                        \
  494|   516k|    int           err;                                                                      \
  495|   516k|    LTC_ARGCHK(md != NULL);                                                                 \
  ------------------
  |  |   32|   516k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 516k]
  |  |  |  Branch (32:87): [Folded, False: 516k]
  |  |  ------------------
  ------------------
  496|   516k|    LTC_ARGCHK(in != NULL);                                                                 \
  ------------------
  |  |   32|   516k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 516k]
  |  |  |  Branch (32:87): [Folded, False: 516k]
  |  |  ------------------
  ------------------
  497|   516k|    if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
  ------------------
  |  Branch (497:9): [True: 0, False: 516k]
  ------------------
  498|      0|       return CRYPT_INVALID_ARG;                                                            \
  499|      0|    }                                                                                       \
  500|   516k|    if ((md-> state_var .length + inlen) < md-> state_var .length) {                        \
  ------------------
  |  Branch (500:9): [True: 0, False: 516k]
  ------------------
  501|      0|      return CRYPT_HASH_OVERFLOW;                                                           \
  502|      0|    }                                                                                       \
  503|  3.78M|    while (inlen > 0) {                                                                     \
  ------------------
  |  Branch (503:12): [True: 3.26M, False: 516k]
  ------------------
  504|  3.26M|        if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
  ------------------
  |  Branch (504:13): [True: 3.06M, False: 204k]
  |  Branch (504:44): [True: 2.79M, False: 268k]
  ------------------
  505|  2.79M|           if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) {               \
  ------------------
  |  Branch (505:16): [True: 0, False: 2.79M]
  ------------------
  506|      0|              return err;                                                                   \
  507|      0|           }                                                                                \
  508|  2.79M|           md-> state_var .length += block_size * 8;                                        \
  509|  2.79M|           in             += block_size;                                                    \
  510|  2.79M|           inlen          -= block_size;                                                    \
  511|  2.79M|        } else {                                                                            \
  512|   473k|           n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
  ------------------
  |  |  425|   473k|   #define MIN(x, y) ( ((x)<(y))?(x):(y) )
  |  |  ------------------
  |  |  |  Branch (425:24): [True: 417k, False: 55.7k]
  |  |  ------------------
  ------------------
  513|   473k|           XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
  ------------------
  |  |   39|   473k|#define XMEMCPY  memcpy
  ------------------
  514|   473k|           md-> state_var .curlen += n;                                                     \
  515|   473k|           in             += n;                                                             \
  516|   473k|           inlen          -= n;                                                             \
  517|   473k|           if (md-> state_var .curlen == block_size) {                                      \
  ------------------
  |  Branch (517:16): [True: 55.7k, False: 417k]
  ------------------
  518|  55.7k|              if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {            \
  ------------------
  |  Branch (518:19): [True: 0, False: 55.7k]
  ------------------
  519|      0|                 return err;                                                                \
  520|      0|              }                                                                             \
  521|  55.7k|              md-> state_var .length += 8*block_size;                                       \
  522|  55.7k|              md-> state_var .curlen = 0;                                                   \
  523|  55.7k|           }                                                                                \
  524|   473k|       }                                                                                    \
  525|  3.26M|    }                                                                                       \
  526|   516k|    return CRYPT_OK;                                                                        \
  527|   516k|}
sha512_process:
  491|  35.7k|int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)               \
  492|  35.7k|{                                                                                           \
  493|  35.7k|    unsigned long n;                                                                        \
  494|  35.7k|    int           err;                                                                      \
  495|  35.7k|    LTC_ARGCHK(md != NULL);                                                                 \
  ------------------
  |  |   32|  35.7k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 35.7k]
  |  |  |  Branch (32:87): [Folded, False: 35.7k]
  |  |  ------------------
  ------------------
  496|  35.7k|    LTC_ARGCHK(in != NULL);                                                                 \
  ------------------
  |  |   32|  35.7k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 35.7k]
  |  |  |  Branch (32:87): [Folded, False: 35.7k]
  |  |  ------------------
  ------------------
  497|  35.7k|    if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
  ------------------
  |  Branch (497:9): [True: 0, False: 35.7k]
  ------------------
  498|      0|       return CRYPT_INVALID_ARG;                                                            \
  499|      0|    }                                                                                       \
  500|  35.7k|    if ((md-> state_var .length + inlen) < md-> state_var .length) {                        \
  ------------------
  |  Branch (500:9): [True: 0, False: 35.7k]
  ------------------
  501|      0|      return CRYPT_HASH_OVERFLOW;                                                           \
  502|      0|    }                                                                                       \
  503|  93.9k|    while (inlen > 0) {                                                                     \
  ------------------
  |  Branch (503:12): [True: 58.2k, False: 35.7k]
  ------------------
  504|  58.2k|        if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
  ------------------
  |  Branch (504:13): [True: 27.9k, False: 30.3k]
  |  Branch (504:44): [True: 17.3k, False: 10.5k]
  ------------------
  505|  17.3k|           if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) {               \
  ------------------
  |  Branch (505:16): [True: 0, False: 17.3k]
  ------------------
  506|      0|              return err;                                                                   \
  507|      0|           }                                                                                \
  508|  17.3k|           md-> state_var .length += block_size * 8;                                        \
  509|  17.3k|           in             += block_size;                                                    \
  510|  17.3k|           inlen          -= block_size;                                                    \
  511|  40.8k|        } else {                                                                            \
  512|  40.8k|           n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
  ------------------
  |  |  425|  40.8k|   #define MIN(x, y) ( ((x)<(y))?(x):(y) )
  |  |  ------------------
  |  |  |  Branch (425:24): [True: 35.7k, False: 5.18k]
  |  |  ------------------
  ------------------
  513|  40.8k|           XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
  ------------------
  |  |   39|  40.8k|#define XMEMCPY  memcpy
  ------------------
  514|  40.8k|           md-> state_var .curlen += n;                                                     \
  515|  40.8k|           in             += n;                                                             \
  516|  40.8k|           inlen          -= n;                                                             \
  517|  40.8k|           if (md-> state_var .curlen == block_size) {                                      \
  ------------------
  |  Branch (517:16): [True: 5.18k, False: 35.7k]
  ------------------
  518|  5.18k|              if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {            \
  ------------------
  |  Branch (518:19): [True: 0, False: 5.18k]
  ------------------
  519|      0|                 return err;                                                                \
  520|      0|              }                                                                             \
  521|  5.18k|              md-> state_var .length += 8*block_size;                                       \
  522|  5.18k|              md-> state_var .curlen = 0;                                                   \
  523|  5.18k|           }                                                                                \
  524|  40.8k|       }                                                                                    \
  525|  58.2k|    }                                                                                       \
  526|  35.7k|    return CRYPT_OK;                                                                        \
  527|  35.7k|}

chacha_crypt.c:ROL:
  258|   730M|{
  259|   730M|   asm ("roll %%cl,%0"
  260|   730M|      :"=r" (word)
  261|   730M|      :"0" (word),"c" (i));
  262|   730M|   return word;
  263|   730M|}

hmac_done:
   28|  49.3k|{
   29|  49.3k|    unsigned char buf[MAXBLOCKSIZE], isha[MAXBLOCKSIZE];
   30|  49.3k|    unsigned long hashsize, i;
   31|  49.3k|    int hash, err;
   32|       |
   33|  49.3k|    LTC_ARGCHK(hmac  != NULL);
  ------------------
  |  |   32|  49.3k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 49.3k]
  |  |  |  Branch (32:87): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
   34|  49.3k|    LTC_ARGCHK(out   != NULL);
  ------------------
  |  |   32|  49.3k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 49.3k]
  |  |  |  Branch (32:87): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
   35|       |
   36|       |    /* test hash */
   37|  49.3k|    hash = hmac->hash;
   38|  49.3k|    if((err = hash_is_valid(hash)) != CRYPT_OK) {
  ------------------
  |  Branch (38:8): [True: 0, False: 49.3k]
  ------------------
   39|      0|        return err;
   40|      0|    }
   41|       |
   42|       |    /* get the hash message digest size */
   43|  49.3k|    hashsize = hash_descriptor[hash].hashsize;
   44|       |
   45|  49.3k|    if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
  ------------------
  |  Branch (45:9): [True: 0, False: 49.3k]
  ------------------
   46|      0|       goto LBL_ERR;
   47|      0|    }
   48|       |
   49|       |    /* Create the second HMAC vector vector for step (3) */
   50|  3.21M|    for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) {
  ------------------
  |  |   18|  3.21M|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
  |  Branch (50:14): [True: 3.16M, False: 49.3k]
  ------------------
   51|  3.16M|        buf[i] = hmac->key[i] ^ 0x5C;
   52|  3.16M|    }
   53|       |
   54|       |    /* Now calculate the "outer" hash for step (5), (6), and (7) */
   55|  49.3k|    if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
  ------------------
  |  Branch (55:9): [True: 0, False: 49.3k]
  ------------------
   56|      0|       goto LBL_ERR;
   57|      0|    }
   58|  49.3k|    if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) {
  ------------------
  |  |   18|  49.3k|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
  |  Branch (58:9): [True: 0, False: 49.3k]
  ------------------
   59|      0|       goto LBL_ERR;
   60|      0|    }
   61|  49.3k|    if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) {
  ------------------
  |  Branch (61:9): [True: 0, False: 49.3k]
  ------------------
   62|      0|       goto LBL_ERR;
   63|      0|    }
   64|  49.3k|    if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) {
  ------------------
  |  Branch (64:9): [True: 0, False: 49.3k]
  ------------------
   65|      0|       goto LBL_ERR;
   66|      0|    }
   67|       |
   68|       |    /* copy to output  */
   69|  1.62M|    for (i = 0; i < hashsize && i < *outlen; i++) {
  ------------------
  |  Branch (69:17): [True: 1.58M, False: 49.3k]
  |  Branch (69:33): [True: 1.58M, False: 0]
  ------------------
   70|  1.58M|        out[i] = buf[i];
   71|  1.58M|    }
   72|  49.3k|    *outlen = i;
   73|       |
   74|  49.3k|    err = CRYPT_OK;
   75|  49.3k|LBL_ERR:
   76|  49.3k|    XFREE(hmac->key);
  ------------------
  |  |   17|  49.3k|#define XFREE m_free_direct
  ------------------
   77|       |#ifdef LTC_CLEAN_STACK
   78|       |    zeromem(isha, hashsize);
   79|       |    zeromem(buf,  hashsize);
   80|       |    zeromem(hmac, sizeof(*hmac));
   81|       |#endif
   82|       |
   83|  49.3k|    return err;
   84|  49.3k|}

hmac_init:
   29|  49.3k|{
   30|  49.3k|    unsigned char buf[MAXBLOCKSIZE];
   31|  49.3k|    unsigned long hashsize;
   32|  49.3k|    unsigned long i, z;
   33|  49.3k|    int err;
   34|       |
   35|  49.3k|    LTC_ARGCHK(hmac != NULL);
  ------------------
  |  |   32|  49.3k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 49.3k]
  |  |  |  Branch (32:87): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
   36|  49.3k|    LTC_ARGCHK(key  != NULL);
  ------------------
  |  |   32|  49.3k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 49.3k]
  |  |  |  Branch (32:87): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
   37|       |
   38|       |    /* valid hash? */
   39|  49.3k|    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
  ------------------
  |  Branch (39:9): [True: 0, False: 49.3k]
  ------------------
   40|      0|        return err;
   41|      0|    }
   42|  49.3k|    hmac->hash = hash;
   43|  49.3k|    hashsize   = hash_descriptor[hash].hashsize;
   44|       |
   45|       |    /* valid key length? */
   46|  49.3k|    if (keylen == 0) {
  ------------------
  |  Branch (46:9): [True: 0, False: 49.3k]
  ------------------
   47|      0|        return CRYPT_INVALID_KEYSIZE;
   48|      0|    }
   49|       |
   50|       |    /* allocate memory for key */
   51|  49.3k|    hmac->key = XMALLOC(LTC_HMAC_BLOCKSIZE);
  ------------------
  |  |   16|  49.3k|#define XMALLOC m_malloc
  ------------------
                  hmac->key = XMALLOC(LTC_HMAC_BLOCKSIZE);
  ------------------
  |  |   18|  49.3k|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
   52|  49.3k|    if (hmac->key == NULL) {
  ------------------
  |  Branch (52:9): [True: 0, False: 49.3k]
  ------------------
   53|      0|       return CRYPT_MEM;
   54|      0|    }
   55|       |
   56|       |    /* (1) make sure we have a large enough key */
   57|  49.3k|    if(keylen > LTC_HMAC_BLOCKSIZE) {
  ------------------
  |  |   18|  49.3k|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
  |  Branch (57:8): [True: 0, False: 49.3k]
  ------------------
   58|      0|        z = LTC_HMAC_BLOCKSIZE;
  ------------------
  |  |   18|      0|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
   59|      0|        if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
  ------------------
  |  Branch (59:13): [True: 0, False: 0]
  ------------------
   60|      0|           goto LBL_ERR;
   61|      0|        }
   62|      0|        keylen = hashsize;
   63|  49.3k|    } else {
   64|  49.3k|        XMEMCPY(hmac->key, key, (size_t)keylen);
  ------------------
  |  |   39|  49.3k|#define XMEMCPY  memcpy
  ------------------
   65|  49.3k|    }
   66|       |
   67|  49.3k|    if(keylen < LTC_HMAC_BLOCKSIZE) {
  ------------------
  |  |   18|  49.3k|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
  |  Branch (67:8): [True: 49.3k, False: 0]
  ------------------
   68|  49.3k|       zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen));
  ------------------
  |  |   18|  49.3k|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
   69|  49.3k|    }
   70|       |
   71|       |    /* Create the initialization vector for step (3) */
   72|  3.21M|    for(i=0; i < LTC_HMAC_BLOCKSIZE;   i++) {
  ------------------
  |  |   18|  3.21M|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
  |  Branch (72:14): [True: 3.16M, False: 49.3k]
  ------------------
   73|  3.16M|       buf[i] = hmac->key[i] ^ 0x36;
   74|  3.16M|    }
   75|       |
   76|       |    /* Pre-pend that to the hash data */
   77|  49.3k|    if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
  ------------------
  |  Branch (77:9): [True: 0, False: 49.3k]
  ------------------
   78|      0|       goto LBL_ERR;
   79|      0|    }
   80|       |
   81|  49.3k|    if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) {
  ------------------
  |  |   18|  49.3k|#define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
  ------------------
  |  Branch (81:9): [True: 0, False: 49.3k]
  ------------------
   82|      0|       goto LBL_ERR;
   83|      0|    }
   84|  49.3k|    goto done;
   85|  49.3k|LBL_ERR:
   86|       |    /* free the key since we failed */
   87|      0|    XFREE(hmac->key);
  ------------------
  |  |   17|      0|#define XFREE m_free_direct
  ------------------
   88|  49.3k|done:
   89|       |#ifdef LTC_CLEAN_STACK
   90|       |   zeromem(buf, LTC_HMAC_BLOCKSIZE);
   91|       |#endif
   92|       |
   93|  49.3k|   return err;
   94|      0|}

hmac_process:
   26|  98.7k|{
   27|  98.7k|    int err;
   28|  98.7k|    LTC_ARGCHK(hmac != NULL);
  ------------------
  |  |   32|  98.7k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 98.7k]
  |  |  |  Branch (32:87): [Folded, False: 98.7k]
  |  |  ------------------
  ------------------
   29|  98.7k|    LTC_ARGCHK(in != NULL);
  ------------------
  |  |   32|  98.7k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 98.7k]
  |  |  |  Branch (32:87): [Folded, False: 98.7k]
  |  |  ------------------
  ------------------
   30|  98.7k|    if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) {
  ------------------
  |  Branch (30:9): [True: 0, False: 98.7k]
  ------------------
   31|      0|        return err;
   32|      0|    }
   33|  98.7k|    return hash_descriptor[hmac->hash].process(&hmac->md, in, inlen);
   34|  98.7k|}

poly1305_init:
   90|  27.8k|{
   91|  27.8k|   LTC_ARGCHK(st  != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   92|  27.8k|   LTC_ARGCHK(key != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   93|  27.8k|   LTC_ARGCHK(keylen == 32);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   94|       |
   95|       |   /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
   96|  27.8k|   LOAD32L(st->r[0], key +  0); st->r[0] = (st->r[0]     ) & 0x3ffffff;
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   97|  27.8k|   LOAD32L(st->r[1], key +  3); st->r[1] = (st->r[1] >> 2) & 0x3ffff03;
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   98|  27.8k|   LOAD32L(st->r[2], key +  6); st->r[2] = (st->r[2] >> 4) & 0x3ffc0ff;
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   99|  27.8k|   LOAD32L(st->r[3], key +  9); st->r[3] = (st->r[3] >> 6) & 0x3f03fff;
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  100|  27.8k|   LOAD32L(st->r[4], key + 12); st->r[4] = (st->r[4] >> 8) & 0x00fffff;
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  101|       |
  102|       |   /* h = 0 */
  103|  27.8k|   st->h[0] = 0;
  104|  27.8k|   st->h[1] = 0;
  105|  27.8k|   st->h[2] = 0;
  106|  27.8k|   st->h[3] = 0;
  107|  27.8k|   st->h[4] = 0;
  108|       |
  109|       |   /* save pad for later */
  110|  27.8k|   LOAD32L(st->pad[0], key + 16);
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  111|  27.8k|   LOAD32L(st->pad[1], key + 20);
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  112|  27.8k|   LOAD32L(st->pad[2], key + 24);
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  113|  27.8k|   LOAD32L(st->pad[3], key + 28);
  ------------------
  |  |  167|  27.8k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  114|       |
  115|  27.8k|   st->leftover = 0;
  116|  27.8k|   st->final = 0;
  117|  27.8k|   return CRYPT_OK;
  118|  27.8k|}
poly1305_process:
  128|  27.8k|{
  129|  27.8k|   unsigned long i;
  130|       |
  131|  27.8k|   if (inlen == 0) return CRYPT_OK; /* nothing to do */
  ------------------
  |  Branch (131:8): [True: 0, False: 27.8k]
  ------------------
  132|  27.8k|   LTC_ARGCHK(st != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  133|  27.8k|   LTC_ARGCHK(in != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  134|       |
  135|       |   /* handle leftover */
  136|  27.8k|   if (st->leftover) {
  ------------------
  |  Branch (136:8): [True: 0, False: 27.8k]
  ------------------
  137|      0|      unsigned long want = (16 - st->leftover);
  138|      0|      if (want > inlen) want = inlen;
  ------------------
  |  Branch (138:11): [True: 0, False: 0]
  ------------------
  139|      0|      for (i = 0; i < want; i++) st->buffer[st->leftover + i] = in[i];
  ------------------
  |  Branch (139:19): [True: 0, False: 0]
  ------------------
  140|      0|      inlen -= want;
  141|      0|      in += want;
  142|      0|      st->leftover += want;
  143|      0|      if (st->leftover < 16) return CRYPT_OK;
  ------------------
  |  Branch (143:11): [True: 0, False: 0]
  ------------------
  144|      0|      _poly1305_block(st, st->buffer, 16);
  145|      0|      st->leftover = 0;
  146|      0|   }
  147|       |
  148|       |   /* process full blocks */
  149|  27.8k|   if (inlen >= 16) {
  ------------------
  |  Branch (149:8): [True: 27.8k, False: 0]
  ------------------
  150|  27.8k|      unsigned long want = (inlen & ~(16 - 1));
  151|  27.8k|      _poly1305_block(st, in, want);
  152|  27.8k|      in += want;
  153|  27.8k|      inlen -= want;
  154|  27.8k|   }
  155|       |
  156|       |   /* store leftover */
  157|  27.8k|   if (inlen) {
  ------------------
  |  Branch (157:8): [True: 27.8k, False: 0]
  ------------------
  158|   251k|      for (i = 0; i < inlen; i++) st->buffer[st->leftover + i] = in[i];
  ------------------
  |  Branch (158:19): [True: 223k, False: 27.8k]
  ------------------
  159|  27.8k|      st->leftover += inlen;
  160|  27.8k|   }
  161|  27.8k|   return CRYPT_OK;
  162|  27.8k|}
poly1305_done:
  172|  27.8k|{
  173|  27.8k|   ulong32 h0,h1,h2,h3,h4,c;
  174|  27.8k|   ulong32 g0,g1,g2,g3,g4;
  175|  27.8k|   ulong64 f;
  176|  27.8k|   ulong32 mask;
  177|       |
  178|  27.8k|   LTC_ARGCHK(st     != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  179|  27.8k|   LTC_ARGCHK(mac    != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  180|  27.8k|   LTC_ARGCHK(maclen != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  181|  27.8k|   LTC_ARGCHK(*maclen >= 16);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  182|       |
  183|       |   /* process the remaining block */
  184|  27.8k|   if (st->leftover) {
  ------------------
  |  Branch (184:8): [True: 27.8k, False: 0]
  ------------------
  185|  27.8k|      unsigned long i = st->leftover;
  186|  27.8k|      st->buffer[i++] = 1;
  187|   222k|      for (; i < 16; i++) st->buffer[i] = 0;
  ------------------
  |  Branch (187:14): [True: 194k, False: 27.8k]
  ------------------
  188|  27.8k|      st->final = 1;
  189|  27.8k|      _poly1305_block(st, st->buffer, 16);
  190|  27.8k|   }
  191|       |
  192|       |   /* fully carry h */
  193|  27.8k|   h0 = st->h[0];
  194|  27.8k|   h1 = st->h[1];
  195|  27.8k|   h2 = st->h[2];
  196|  27.8k|   h3 = st->h[3];
  197|  27.8k|   h4 = st->h[4];
  198|       |
  199|  27.8k|                c = h1 >> 26; h1 = h1 & 0x3ffffff;
  200|  27.8k|   h2 +=     c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
  201|  27.8k|   h3 +=     c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
  202|  27.8k|   h4 +=     c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
  203|  27.8k|   h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
  204|  27.8k|   h1 +=     c;
  205|       |
  206|       |   /* compute h + -p */
  207|  27.8k|   g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
  208|  27.8k|   g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
  209|  27.8k|   g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
  210|  27.8k|   g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
  211|  27.8k|   g4 = h4 + c - (1UL << 26);
  212|       |
  213|       |   /* select h if h < p, or h + -p if h >= p */
  214|  27.8k|   mask = (g4 >> 31) - 1;
  215|  27.8k|   g0 &= mask;
  216|  27.8k|   g1 &= mask;
  217|  27.8k|   g2 &= mask;
  218|  27.8k|   g3 &= mask;
  219|  27.8k|   g4 &= mask;
  220|  27.8k|   mask = ~mask;
  221|  27.8k|   h0 = (h0 & mask) | g0;
  222|  27.8k|   h1 = (h1 & mask) | g1;
  223|  27.8k|   h2 = (h2 & mask) | g2;
  224|  27.8k|   h3 = (h3 & mask) | g3;
  225|  27.8k|   h4 = (h4 & mask) | g4;
  226|       |
  227|       |   /* h = h % (2^128) */
  228|  27.8k|   h0 = ((h0      ) | (h1 << 26)) & 0xffffffff;
  229|  27.8k|   h1 = ((h1 >>  6) | (h2 << 20)) & 0xffffffff;
  230|  27.8k|   h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
  231|  27.8k|   h3 = ((h3 >> 18) | (h4 <<  8)) & 0xffffffff;
  232|       |
  233|       |   /* mac = (h + pad) % (2^128) */
  234|  27.8k|   f = (ulong64)h0 + st->pad[0]            ; h0 = (ulong32)f;
  235|  27.8k|   f = (ulong64)h1 + st->pad[1] + (f >> 32); h1 = (ulong32)f;
  236|  27.8k|   f = (ulong64)h2 + st->pad[2] + (f >> 32); h2 = (ulong32)f;
  237|  27.8k|   f = (ulong64)h3 + st->pad[3] + (f >> 32); h3 = (ulong32)f;
  238|       |
  239|  27.8k|   STORE32L(h0, mac +  0);
  ------------------
  |  |  164|  27.8k|  do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (164:56): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  240|  27.8k|   STORE32L(h1, mac +  4);
  ------------------
  |  |  164|  27.8k|  do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (164:56): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  241|  27.8k|   STORE32L(h2, mac +  8);
  ------------------
  |  |  164|  27.8k|  do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (164:56): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  242|  27.8k|   STORE32L(h3, mac + 12);
  ------------------
  |  |  164|  27.8k|  do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (164:56): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
  243|       |
  244|       |   /* zero out the state */
  245|  27.8k|   st->h[0] = 0;
  246|  27.8k|   st->h[1] = 0;
  247|  27.8k|   st->h[2] = 0;
  248|  27.8k|   st->h[3] = 0;
  249|  27.8k|   st->h[4] = 0;
  250|  27.8k|   st->r[0] = 0;
  251|  27.8k|   st->r[1] = 0;
  252|  27.8k|   st->r[2] = 0;
  253|  27.8k|   st->r[3] = 0;
  254|  27.8k|   st->r[4] = 0;
  255|  27.8k|   st->pad[0] = 0;
  256|  27.8k|   st->pad[1] = 0;
  257|  27.8k|   st->pad[2] = 0;
  258|  27.8k|   st->pad[3] = 0;
  259|       |
  260|  27.8k|   *maclen = 16;
  261|  27.8k|   return CRYPT_OK;
  262|  27.8k|}
poly1305.c:_poly1305_block:
   21|  55.6k|{
   22|  55.6k|   const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */
  ------------------
  |  Branch (22:32): [True: 27.8k, False: 27.8k]
  ------------------
   23|  55.6k|   ulong32 r0,r1,r2,r3,r4;
   24|  55.6k|   ulong32 s1,s2,s3,s4;
   25|  55.6k|   ulong32 h0,h1,h2,h3,h4;
   26|  55.6k|   ulong32 tmp;
   27|  55.6k|   ulong64 d0,d1,d2,d3,d4;
   28|  55.6k|   ulong32 c;
   29|       |
   30|  55.6k|   r0 = st->r[0];
   31|  55.6k|   r1 = st->r[1];
   32|  55.6k|   r2 = st->r[2];
   33|  55.6k|   r3 = st->r[3];
   34|  55.6k|   r4 = st->r[4];
   35|       |
   36|  55.6k|   s1 = r1 * 5;
   37|  55.6k|   s2 = r2 * 5;
   38|  55.6k|   s3 = r3 * 5;
   39|  55.6k|   s4 = r4 * 5;
   40|       |
   41|  55.6k|   h0 = st->h[0];
   42|  55.6k|   h1 = st->h[1];
   43|  55.6k|   h2 = st->h[2];
   44|  55.6k|   h3 = st->h[3];
   45|  55.6k|   h4 = st->h[4];
   46|       |
   47|  8.93M|   while (inlen >= 16) {
  ------------------
  |  Branch (47:11): [True: 8.88M, False: 55.6k]
  ------------------
   48|       |      /* h += in[i] */
   49|  8.88M|      LOAD32L(tmp, in+ 0); h0 += (tmp     ) & 0x3ffffff;
  ------------------
  |  |  167|  8.88M|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  8.88M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 8.88M]
  |  |  ------------------
  ------------------
   50|  8.88M|      LOAD32L(tmp, in+ 3); h1 += (tmp >> 2) & 0x3ffffff;
  ------------------
  |  |  167|  8.88M|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  8.88M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 8.88M]
  |  |  ------------------
  ------------------
   51|  8.88M|      LOAD32L(tmp, in+ 6); h2 += (tmp >> 4) & 0x3ffffff;
  ------------------
  |  |  167|  8.88M|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  8.88M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 8.88M]
  |  |  ------------------
  ------------------
   52|  8.88M|      LOAD32L(tmp, in+ 9); h3 += (tmp >> 6) & 0x3ffffff;
  ------------------
  |  |  167|  8.88M|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  8.88M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 8.88M]
  |  |  ------------------
  ------------------
   53|  8.88M|      LOAD32L(tmp, in+12); h4 += (tmp >> 8) | hibit;
  ------------------
  |  |  167|  8.88M|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  8.88M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 8.88M]
  |  |  ------------------
  ------------------
   54|       |
   55|       |      /* h *= r */
   56|  8.88M|      d0 = ((ulong64)h0 * r0) + ((ulong64)h1 * s4) + ((ulong64)h2 * s3) + ((ulong64)h3 * s2) + ((ulong64)h4 * s1);
   57|  8.88M|      d1 = ((ulong64)h0 * r1) + ((ulong64)h1 * r0) + ((ulong64)h2 * s4) + ((ulong64)h3 * s3) + ((ulong64)h4 * s2);
   58|  8.88M|      d2 = ((ulong64)h0 * r2) + ((ulong64)h1 * r1) + ((ulong64)h2 * r0) + ((ulong64)h3 * s4) + ((ulong64)h4 * s3);
   59|  8.88M|      d3 = ((ulong64)h0 * r3) + ((ulong64)h1 * r2) + ((ulong64)h2 * r1) + ((ulong64)h3 * r0) + ((ulong64)h4 * s4);
   60|  8.88M|      d4 = ((ulong64)h0 * r4) + ((ulong64)h1 * r3) + ((ulong64)h2 * r2) + ((ulong64)h3 * r1) + ((ulong64)h4 * r0);
   61|       |
   62|       |      /* (partial) h %= p */
   63|  8.88M|                    c = (ulong32)(d0 >> 26); h0 = (ulong32)d0 & 0x3ffffff;
   64|  8.88M|      d1 += c;      c = (ulong32)(d1 >> 26); h1 = (ulong32)d1 & 0x3ffffff;
   65|  8.88M|      d2 += c;      c = (ulong32)(d2 >> 26); h2 = (ulong32)d2 & 0x3ffffff;
   66|  8.88M|      d3 += c;      c = (ulong32)(d3 >> 26); h3 = (ulong32)d3 & 0x3ffffff;
   67|  8.88M|      d4 += c;      c = (ulong32)(d4 >> 26); h4 = (ulong32)d4 & 0x3ffffff;
   68|  8.88M|      h0 += c * 5;  c =          (h0 >> 26); h0 =          h0 & 0x3ffffff;
   69|  8.88M|      h1 += c;
   70|       |
   71|  8.88M|      in += 16;
   72|  8.88M|      inlen -= 16;
   73|  8.88M|   }
   74|       |
   75|  55.6k|   st->h[0] = h0;
   76|  55.6k|   st->h[1] = h1;
   77|  55.6k|   st->h[2] = h2;
   78|  55.6k|   st->h[3] = h3;
   79|  55.6k|   st->h[4] = h4;
   80|  55.6k|}

cipher_is_valid:
   22|  55.4k|{
   23|  55.4k|   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
   24|  55.4k|   if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
  ------------------
  |  |   14|   110k|#define TAB_SIZE      5
  ------------------
  |  Branch (24:8): [True: 0, False: 55.4k]
  |  Branch (24:19): [True: 0, False: 55.4k]
  |  Branch (24:38): [True: 0, False: 55.4k]
  ------------------
   25|      0|      LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
   26|      0|      return CRYPT_INVALID_CIPHER;
   27|      0|   }
   28|  55.4k|   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
   29|  55.4k|   return CRYPT_OK;
   30|  55.4k|}

find_cipher:
   22|  12.0k|{
   23|  12.0k|   int x;
   24|  12.0k|   LTC_ARGCHK(name != NULL);
  ------------------
  |  |   32|  12.0k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 12.0k]
  |  |  |  Branch (32:87): [Folded, False: 12.0k]
  |  |  ------------------
  ------------------
   25|  12.0k|   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
   26|  12.0k|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|  12.0k|#define TAB_SIZE      5
  ------------------
  |  Branch (26:16): [True: 12.0k, False: 0]
  ------------------
   27|  12.0k|       if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) {
  ------------------
  |  |   54|  12.0k|#define XSTRCMP strcmp
  ------------------
  |  Branch (27:12): [True: 12.0k, False: 0]
  |  Branch (27:49): [True: 12.0k, False: 0]
  ------------------
   28|  12.0k|          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
   29|  12.0k|          return x;
   30|  12.0k|       }
   31|  12.0k|   }
   32|      0|   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
   33|      0|   return -1;
   34|  12.0k|}

find_hash:
   22|  6.01k|{
   23|  6.01k|   int x;
   24|  6.01k|   LTC_ARGCHK(name != NULL);
  ------------------
  |  |   32|  6.01k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 6.01k]
  |  |  |  Branch (32:87): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
   25|  6.01k|   LTC_MUTEX_LOCK(&ltc_hash_mutex);
   26|  6.01k|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|  6.01k|#define TAB_SIZE      5
  ------------------
  |  Branch (26:16): [True: 6.01k, False: 0]
  ------------------
   27|  6.01k|       if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) {
  ------------------
  |  |   54|  6.01k|#define XSTRCMP strcmp
  ------------------
  |  Branch (27:12): [True: 6.01k, False: 0]
  |  Branch (27:47): [True: 6.01k, False: 0]
  ------------------
   28|  6.01k|          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
   29|  6.01k|          return x;
   30|  6.01k|       }
   31|  6.01k|   }
   32|      0|   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
   33|      0|   return -1;
   34|  6.01k|}

hash_is_valid:
   22|   197k|{
   23|   197k|   LTC_MUTEX_LOCK(&ltc_hash_mutex);
   24|   197k|   if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
  ------------------
  |  |   14|   395k|#define TAB_SIZE      5
  ------------------
  |  Branch (24:8): [True: 0, False: 197k]
  |  Branch (24:19): [True: 0, False: 197k]
  |  Branch (24:38): [True: 0, False: 197k]
  ------------------
   25|      0|      LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
   26|      0|      return CRYPT_INVALID_HASH;
   27|      0|   }
   28|   197k|   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
   29|   197k|   return CRYPT_OK;
   30|   197k|}

register_cipher:
   22|      1|{
   23|      1|   int x;
   24|       |
   25|      1|   LTC_ARGCHK(cipher != NULL);
  ------------------
  |  |   32|      1|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 1]
  |  |  |  Branch (32:87): [Folded, False: 1]
  |  |  ------------------
  ------------------
   26|       |
   27|       |   /* is it already registered? */
   28|      1|   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
   29|      6|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|      6|#define TAB_SIZE      5
  ------------------
  |  Branch (29:16): [True: 5, False: 1]
  ------------------
   30|      5|       if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
  ------------------
  |  Branch (30:12): [True: 0, False: 5]
  |  Branch (30:49): [True: 0, False: 0]
  ------------------
   31|      0|          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
   32|      0|          return x;
   33|      0|       }
   34|      5|   }
   35|       |
   36|       |   /* find a blank spot */
   37|      1|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|      1|#define TAB_SIZE      5
  ------------------
  |  Branch (37:16): [True: 1, False: 0]
  ------------------
   38|      1|       if (cipher_descriptor[x].name == NULL) {
  ------------------
  |  Branch (38:12): [True: 1, False: 0]
  ------------------
   39|      1|          XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor));
  ------------------
  |  |   39|      1|#define XMEMCPY  memcpy
  ------------------
   40|      1|          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
   41|      1|          return x;
   42|      1|       }
   43|      1|   }
   44|       |
   45|       |   /* no spot */
   46|      0|   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
   47|      0|   return -1;
   48|      1|}

register_hash:
   22|      3|{
   23|      3|   int x;
   24|       |
   25|      3|   LTC_ARGCHK(hash != NULL);
  ------------------
  |  |   32|      3|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 3]
  |  |  |  Branch (32:87): [Folded, False: 3]
  |  |  ------------------
  ------------------
   26|       |
   27|       |   /* is it already registered? */
   28|      3|   LTC_MUTEX_LOCK(&ltc_hash_mutex);
   29|     18|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|     18|#define TAB_SIZE      5
  ------------------
  |  Branch (29:16): [True: 15, False: 3]
  ------------------
   30|     15|       if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
  ------------------
  |  |   45|     15|#define XMEMCMP  memcmp
  ------------------
  |  Branch (30:12): [True: 0, False: 15]
  ------------------
   31|      0|          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
   32|      0|          return x;
   33|      0|       }
   34|     15|   }
   35|       |
   36|       |   /* find a blank spot */
   37|      6|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|      6|#define TAB_SIZE      5
  ------------------
  |  Branch (37:16): [True: 6, False: 0]
  ------------------
   38|      6|       if (hash_descriptor[x].name == NULL) {
  ------------------
  |  Branch (38:12): [True: 3, False: 3]
  ------------------
   39|      3|          XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
  ------------------
  |  |   39|      3|#define XMEMCPY  memcpy
  ------------------
   40|      3|          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
   41|      3|          return x;
   42|      3|       }
   43|      6|   }
   44|       |
   45|       |   /* no spot */
   46|      0|   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
   47|      0|   return -1;
   48|      3|}

register_prng:
   22|      1|{
   23|      1|   int x;
   24|       |
   25|      1|   LTC_ARGCHK(prng != NULL);
  ------------------
  |  |   32|      1|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 1]
  |  |  |  Branch (32:87): [Folded, False: 1]
  |  |  ------------------
  ------------------
   26|       |
   27|       |   /* is it already registered? */
   28|      1|   LTC_MUTEX_LOCK(&ltc_prng_mutex);
   29|      6|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|      6|#define TAB_SIZE      5
  ------------------
  |  Branch (29:16): [True: 5, False: 1]
  ------------------
   30|      5|       if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
  ------------------
  |  |   45|      5|#define XMEMCMP  memcmp
  ------------------
  |  Branch (30:12): [True: 0, False: 5]
  ------------------
   31|      0|          LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
   32|      0|          return x;
   33|      0|       }
   34|      5|   }
   35|       |
   36|       |   /* find a blank spot */
   37|      1|   for (x = 0; x < TAB_SIZE; x++) {
  ------------------
  |  |   14|      1|#define TAB_SIZE      5
  ------------------
  |  Branch (37:16): [True: 1, False: 0]
  ------------------
   38|      1|       if (prng_descriptor[x].name == NULL) {
  ------------------
  |  Branch (38:12): [True: 1, False: 0]
  ------------------
   39|      1|          XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
  ------------------
  |  |   39|      1|#define XMEMCPY  memcpy
  ------------------
   40|      1|          LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
   41|      1|          return x;
   42|      1|       }
   43|      1|   }
   44|       |
   45|       |   /* no spot */
   46|      0|   LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
   47|      0|   return -1;
   48|      1|}

zeromem:
   23|  49.3k|{
   24|  49.3k|   m_burn((void*)out, outlen);
   25|  49.3k|}

ctr_encrypt:
   87|  49.3k|{
   88|  49.3k|   int err, fr;
   89|       |
   90|  49.3k|   LTC_ARGCHK(pt != NULL);
  ------------------
  |  |   32|  49.3k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 49.3k]
  |  |  |  Branch (32:87): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
   91|  49.3k|   LTC_ARGCHK(ct != NULL);
  ------------------
  |  |   32|  49.3k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 49.3k]
  |  |  |  Branch (32:87): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
   92|  49.3k|   LTC_ARGCHK(ctr != NULL);
  ------------------
  |  |   32|  49.3k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 49.3k]
  |  |  |  Branch (32:87): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
   93|       |
   94|  49.3k|   if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
  ------------------
  |  Branch (94:8): [True: 0, False: 49.3k]
  ------------------
   95|      0|       return err;
   96|      0|   }
   97|       |
   98|       |   /* is blocklen/padlen valid? */
   99|  49.3k|   if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) ||
  ------------------
  |  Branch (99:8): [True: 0, False: 49.3k]
  |  Branch (99:31): [True: 0, False: 49.3k]
  ------------------
  100|  49.3k|       (ctr->padlen   < 0) || (ctr->padlen   > (int)sizeof(ctr->pad))) {
  ------------------
  |  Branch (100:8): [True: 0, False: 49.3k]
  |  Branch (100:31): [True: 0, False: 49.3k]
  ------------------
  101|      0|      return CRYPT_INVALID_ARG;
  102|      0|   }
  103|       |
  104|  49.3k|#ifdef LTC_FAST
  105|  49.3k|   if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
  ------------------
  |  Branch (105:8): [True: 0, False: 49.3k]
  ------------------
  106|      0|      return CRYPT_INVALID_ARG;
  107|      0|   }
  108|  49.3k|#endif
  109|       |
  110|       |   /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
  111|  49.3k|   if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) {
  ------------------
  |  Branch (111:8): [True: 0, False: 49.3k]
  |  Branch (111:70): [True: 0, False: 0]
  ------------------
  112|      0|     if (ctr->padlen < ctr->blocklen) {
  ------------------
  |  Branch (112:10): [True: 0, False: 0]
  ------------------
  113|      0|       fr = ctr->blocklen - ctr->padlen;
  114|      0|       if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) {
  ------------------
  |  Branch (114:12): [True: 0, False: 0]
  ------------------
  115|      0|          return err;
  116|      0|       }
  117|      0|       pt += fr;
  118|      0|       ct += fr;
  119|      0|       len -= fr;
  120|      0|     }
  121|       |
  122|      0|     if (len >= (unsigned long)ctr->blocklen) {
  ------------------
  |  Branch (122:10): [True: 0, False: 0]
  ------------------
  123|      0|       if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
  ------------------
  |  Branch (123:12): [True: 0, False: 0]
  ------------------
  124|      0|          return err;
  125|      0|       }
  126|      0|       pt += (len / ctr->blocklen) * ctr->blocklen;
  127|      0|       ct += (len / ctr->blocklen) * ctr->blocklen;
  128|      0|       len %= ctr->blocklen;
  129|      0|     }
  130|      0|   }
  131|       |
  132|  49.3k|   return _ctr_encrypt(pt, ct, len, ctr);
  133|  49.3k|}
ctr_encrypt.c:_ctr_encrypt:
   28|  49.3k|{
   29|  49.3k|   int x, err;
   30|       |
   31|  10.8M|   while (len) {
  ------------------
  |  Branch (31:11): [True: 10.8M, False: 49.3k]
  ------------------
   32|       |      /* is the pad empty? */
   33|  10.8M|      if (ctr->padlen == ctr->blocklen) {
  ------------------
  |  Branch (33:11): [True: 10.8M, False: 5.07k]
  ------------------
   34|       |         /* increment counter */
   35|  10.8M|         if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
  ------------------
  |  |  859|  10.8M|#define CTR_COUNTER_LITTLE_ENDIAN    0x0000
  ------------------
  |  Branch (35:14): [True: 0, False: 10.8M]
  ------------------
   36|       |            /* little-endian */
   37|      0|            for (x = 0; x < ctr->ctrlen; x++) {
  ------------------
  |  Branch (37:25): [True: 0, False: 0]
  ------------------
   38|      0|               ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
   39|      0|               if (ctr->ctr[x] != (unsigned char)0) {
  ------------------
  |  Branch (39:20): [True: 0, False: 0]
  ------------------
   40|      0|                  break;
   41|      0|               }
   42|      0|            }
   43|  10.8M|         } else {
   44|       |            /* big-endian */
   45|  10.8M|            for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
  ------------------
  |  Branch (45:39): [True: 10.8M, False: 0]
  ------------------
   46|  10.8M|               ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
   47|  10.8M|               if (ctr->ctr[x] != (unsigned char)0) {
  ------------------
  |  Branch (47:20): [True: 10.8M, False: 42.3k]
  ------------------
   48|  10.8M|                  break;
   49|  10.8M|               }
   50|  10.8M|            }
   51|  10.8M|         }
   52|       |
   53|       |         /* encrypt it */
   54|  10.8M|         if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
  ------------------
  |  Branch (54:14): [True: 0, False: 10.8M]
  ------------------
   55|      0|            return err;
   56|      0|         }
   57|  10.8M|         ctr->padlen = 0;
   58|  10.8M|      }
   59|  10.8M|#ifdef LTC_FAST
   60|  10.8M|      if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) {
  ------------------
  |  Branch (60:11): [True: 10.8M, False: 0]
  |  Branch (60:33): [True: 10.8M, False: 0]
  ------------------
   61|  32.4M|         for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
  ------------------
  |  Branch (61:22): [True: 21.6M, False: 10.8M]
  ------------------
   62|  21.6M|            *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^
  ------------------
  |  |  244|  21.6M|   #define LTC_FAST_TYPE_PTR_CAST(x) ((LTC_FAST_TYPE*)(void*)(x))
  ------------------
                          *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^
  ------------------
  |  |  244|  21.6M|   #define LTC_FAST_TYPE_PTR_CAST(x) ((LTC_FAST_TYPE*)(void*)(x))
  ------------------
   63|  21.6M|                                                           *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));
  ------------------
  |  |  244|  21.6M|   #define LTC_FAST_TYPE_PTR_CAST(x) ((LTC_FAST_TYPE*)(void*)(x))
  ------------------
   64|  21.6M|         }
   65|  10.8M|       pt         += ctr->blocklen;
   66|  10.8M|       ct         += ctr->blocklen;
   67|  10.8M|       len        -= ctr->blocklen;
   68|  10.8M|       ctr->padlen = ctr->blocklen;
   69|  10.8M|       continue;
   70|  10.8M|      }
   71|      0|#endif
   72|      0|      *ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
   73|      0|      --len;
   74|      0|   }
   75|  49.3k|   return CRYPT_OK;
   76|  49.3k|}

ctr_start:
   35|  6.01k|{
   36|  6.01k|   int x, err;
   37|       |
   38|  6.01k|   LTC_ARGCHK(IV  != NULL);
  ------------------
  |  |   32|  6.01k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 6.01k]
  |  |  |  Branch (32:87): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
   39|  6.01k|   LTC_ARGCHK(key != NULL);
  ------------------
  |  |   32|  6.01k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 6.01k]
  |  |  |  Branch (32:87): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
   40|  6.01k|   LTC_ARGCHK(ctr != NULL);
  ------------------
  |  |   32|  6.01k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 6.01k]
  |  |  |  Branch (32:87): [Folded, False: 6.01k]
  |  |  ------------------
  ------------------
   41|       |
   42|       |   /* bad param? */
   43|  6.01k|   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
  ------------------
  |  Branch (43:8): [True: 0, False: 6.01k]
  ------------------
   44|      0|      return err;
   45|      0|   }
   46|       |
   47|       |   /* ctrlen == counter width */
   48|  6.01k|   ctr->ctrlen   = (ctr_mode & 255) ? (ctr_mode & 255) : cipher_descriptor[cipher].block_length;
  ------------------
  |  Branch (48:20): [True: 0, False: 6.01k]
  ------------------
   49|  6.01k|   if (ctr->ctrlen > cipher_descriptor[cipher].block_length) {
  ------------------
  |  Branch (49:8): [True: 0, False: 6.01k]
  ------------------
   50|      0|      return CRYPT_INVALID_ARG;
   51|      0|   }
   52|       |
   53|  6.01k|   if ((ctr_mode & 0x1000) == CTR_COUNTER_BIG_ENDIAN) {
  ------------------
  |  |  860|  6.01k|#define CTR_COUNTER_BIG_ENDIAN       0x1000
  ------------------
  |  Branch (53:8): [True: 6.01k, False: 0]
  ------------------
   54|  6.01k|      ctr->ctrlen = cipher_descriptor[cipher].block_length - ctr->ctrlen;
   55|  6.01k|   }
   56|       |
   57|       |   /* setup cipher */
   58|  6.01k|   if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {
  ------------------
  |  Branch (58:8): [True: 0, False: 6.01k]
  ------------------
   59|      0|      return err;
   60|      0|   }
   61|       |
   62|       |   /* copy ctr */
   63|  6.01k|   ctr->blocklen = cipher_descriptor[cipher].block_length;
   64|  6.01k|   ctr->cipher   = cipher;
   65|  6.01k|   ctr->padlen   = 0;
   66|  6.01k|   ctr->mode     = ctr_mode & 0x1000;
   67|   102k|   for (x = 0; x < ctr->blocklen; x++) {
  ------------------
  |  Branch (67:16): [True: 96.2k, False: 6.01k]
  ------------------
   68|  96.2k|       ctr->ctr[x] = IV[x];
   69|  96.2k|   }
   70|       |
   71|  6.01k|   if (ctr_mode & LTC_CTR_RFC3686) {
  ------------------
  |  |  861|  6.01k|#define LTC_CTR_RFC3686              0x2000
  ------------------
  |  Branch (71:8): [True: 0, False: 6.01k]
  ------------------
   72|       |      /* increment the IV as per RFC 3686 */
   73|      0|      if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
  ------------------
  |  |  859|      0|#define CTR_COUNTER_LITTLE_ENDIAN    0x0000
  ------------------
  |  Branch (73:11): [True: 0, False: 0]
  ------------------
   74|       |         /* little-endian */
   75|      0|         for (x = 0; x < ctr->ctrlen; x++) {
  ------------------
  |  Branch (75:22): [True: 0, False: 0]
  ------------------
   76|      0|             ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
   77|      0|             if (ctr->ctr[x] != (unsigned char)0) {
  ------------------
  |  Branch (77:18): [True: 0, False: 0]
  ------------------
   78|      0|                break;
   79|      0|             }
   80|      0|         }
   81|      0|      } else {
   82|       |         /* big-endian */
   83|      0|         for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {
  ------------------
  |  Branch (83:36): [True: 0, False: 0]
  ------------------
   84|      0|             ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
   85|      0|             if (ctr->ctr[x] != (unsigned char)0) {
  ------------------
  |  Branch (85:18): [True: 0, False: 0]
  ------------------
   86|      0|                break;
   87|      0|             }
   88|      0|         }
   89|      0|      }
   90|      0|   }
   91|       |
   92|  6.01k|   return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
   93|  6.01k|}

chacha_crypt:
   55|  83.5k|{
   56|  83.5k|   unsigned char buf[64];
   57|  83.5k|   unsigned long i, j;
   58|       |
   59|  83.5k|   if (inlen == 0) return CRYPT_OK; /* nothing to do */
  ------------------
  |  Branch (59:8): [True: 0, False: 83.5k]
  ------------------
   60|       |
   61|  83.5k|   LTC_ARGCHK(st        != NULL);
  ------------------
  |  |   32|  83.5k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 83.5k]
  |  |  |  Branch (32:87): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   62|  83.5k|   LTC_ARGCHK(in        != NULL);
  ------------------
  |  |   32|  83.5k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 83.5k]
  |  |  |  Branch (32:87): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   63|  83.5k|   LTC_ARGCHK(out       != NULL);
  ------------------
  |  |   32|  83.5k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 83.5k]
  |  |  |  Branch (32:87): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   64|  83.5k|   LTC_ARGCHK(st->ivlen != 0);
  ------------------
  |  |   32|  83.5k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 83.5k]
  |  |  |  Branch (32:87): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   65|       |
   66|  83.5k|   if (st->ksleft > 0) {
  ------------------
  |  Branch (66:8): [True: 0, False: 83.5k]
  ------------------
   67|      0|      j = MIN(st->ksleft, inlen);
  ------------------
  |  |  425|      0|   #define MIN(x, y) ( ((x)<(y))?(x):(y) )
  |  |  ------------------
  |  |  |  Branch (425:24): [True: 0, False: 0]
  |  |  ------------------
  ------------------
   68|      0|      for (i = 0; i < j; ++i, st->ksleft--) out[i] = in[i] ^ st->kstream[64 - st->ksleft];
  ------------------
  |  Branch (68:19): [True: 0, False: 0]
  ------------------
   69|      0|      inlen -= j;
   70|      0|      if (inlen == 0) return CRYPT_OK;
  ------------------
  |  Branch (70:11): [True: 0, False: 0]
  ------------------
   71|      0|      out += j;
   72|      0|      in  += j;
   73|      0|   }
   74|  2.28M|   for (;;) {
   75|  2.28M|     _chacha_block(buf, st->input, st->rounds);
   76|  2.28M|     if (st->ivlen == 8) {
  ------------------
  |  Branch (76:10): [True: 2.28M, False: 0]
  ------------------
   77|       |       /* IV-64bit, increment 64bit counter */
   78|  2.28M|       if (0 == ++st->input[12] && 0 == ++st->input[13]) return CRYPT_OVERFLOW;
  ------------------
  |  Branch (78:12): [True: 0, False: 2.28M]
  |  Branch (78:36): [True: 0, False: 0]
  ------------------
   79|  2.28M|     }
   80|      0|     else {
   81|       |       /* IV-96bit, increment 32bit counter */
   82|      0|       if (0 == ++st->input[12]) return CRYPT_OVERFLOW;
  ------------------
  |  Branch (82:12): [True: 0, False: 0]
  ------------------
   83|      0|     }
   84|  2.28M|     if (inlen <= 64) {
  ------------------
  |  Branch (84:10): [True: 83.5k, False: 2.20M]
  ------------------
   85|  2.05M|       for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
  ------------------
  |  Branch (85:20): [True: 1.96M, False: 83.5k]
  ------------------
   86|  83.5k|       st->ksleft = 64 - inlen;
   87|  3.46M|       for (i = inlen; i < 64; ++i) st->kstream[i] = buf[i];
  ------------------
  |  Branch (87:24): [True: 3.37M, False: 83.5k]
  ------------------
   88|  83.5k|       return CRYPT_OK;
   89|  83.5k|     }
   90|   143M|     for (i = 0; i < 64; ++i) out[i] = in[i] ^ buf[i];
  ------------------
  |  Branch (90:18): [True: 140M, False: 2.20M]
  ------------------
   91|  2.20M|     inlen -= 64;
   92|  2.20M|     out += 64;
   93|  2.20M|     in  += 64;
   94|  2.20M|   }
   95|  83.5k|}
chacha_crypt.c:_chacha_block:
   26|  2.28M|{
   27|  2.28M|   ulong32 x[16];
   28|  2.28M|   int i;
   29|  2.28M|   XMEMCPY(x, input, sizeof(x));
  ------------------
  |  |   39|  2.28M|#define XMEMCPY  memcpy
  ------------------
   30|  25.1M|   for (i = rounds; i > 0; i -= 2) {
  ------------------
  |  Branch (30:21): [True: 22.8M, False: 2.28M]
  ------------------
   31|  22.8M|      QUARTERROUND(0, 4, 8,12)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   32|  22.8M|      QUARTERROUND(1, 5, 9,13)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   33|  22.8M|      QUARTERROUND(2, 6,10,14)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   34|  22.8M|      QUARTERROUND(3, 7,11,15)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   35|  22.8M|      QUARTERROUND(0, 5,10,15)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   36|  22.8M|      QUARTERROUND(1, 6,11,12)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   37|  22.8M|      QUARTERROUND(2, 7, 8,13)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   38|  22.8M|      QUARTERROUND(3, 4, 9,14)
  ------------------
  |  |   20|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \
  |  |   21|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \
  |  |   22|  22.8M|  x[a] += x[b]; x[d] = ROL(x[d] ^ x[a],  8); \
  |  |   23|  22.8M|  x[c] += x[d]; x[b] = ROL(x[b] ^ x[c],  7);
  ------------------
   39|  22.8M|   }
   40|  38.8M|   for (i = 0; i < 16; ++i) {
  ------------------
  |  Branch (40:16): [True: 36.5M, False: 2.28M]
  ------------------
   41|  36.5M|     x[i] += input[i];
   42|  36.5M|     STORE32L(x[i], output + 4 * i);
  ------------------
  |  |  164|  36.5M|  do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  36.5M|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (164:56): [Folded, False: 36.5M]
  |  |  ------------------
  ------------------
   43|  36.5M|   }
   44|  2.28M|}

chacha_ivctr64:
   28|  83.5k|{
   29|  83.5k|   LTC_ARGCHK(st != NULL);
  ------------------
  |  |   32|  83.5k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 83.5k]
  |  |  |  Branch (32:87): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   30|  83.5k|   LTC_ARGCHK(iv != NULL);
  ------------------
  |  |   32|  83.5k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 83.5k]
  |  |  |  Branch (32:87): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   31|       |   /* 64bit IV + 64bit counter */
   32|  83.5k|   LTC_ARGCHK(ivlen == 8);
  ------------------
  |  |   32|  83.5k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 83.5k]
  |  |  |  Branch (32:87): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   33|       |
   34|  83.5k|   st->input[12] = (ulong32)(counter & 0xFFFFFFFF);
   35|  83.5k|   st->input[13] = (ulong32)(counter >> 32);
   36|  83.5k|   LOAD32L(st->input[14], iv + 0);
  ------------------
  |  |  167|  83.5k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  83.5k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   37|  83.5k|   LOAD32L(st->input[15], iv + 4);
  ------------------
  |  |  167|  83.5k|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|  83.5k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 83.5k]
  |  |  ------------------
  ------------------
   38|  83.5k|   st->ksleft = 0;
   39|  83.5k|   st->ivlen = ivlen;
   40|  83.5k|   return CRYPT_OK;
   41|  83.5k|}

chacha_keystream:
   27|  27.8k|{
   28|  27.8k|   if (outlen == 0) return CRYPT_OK; /* nothing to do */
  ------------------
  |  Branch (28:8): [True: 0, False: 27.8k]
  ------------------
   29|  27.8k|   LTC_ARGCHK(out != NULL);
  ------------------
  |  |   32|  27.8k|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 27.8k]
  |  |  |  Branch (32:87): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   30|  27.8k|   XMEMSET(out, 0, outlen);
  ------------------
  |  |   36|  27.8k|#define XMEMSET  memset
  ------------------
   31|  27.8k|   return chacha_crypt(st, out, outlen, out);
   32|  27.8k|}

chacha_setup:
   31|    876|{
   32|    876|   const char *constants;
   33|       |
   34|    876|   LTC_ARGCHK(st  != NULL);
  ------------------
  |  |   32|    876|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 876]
  |  |  |  Branch (32:87): [Folded, False: 876]
  |  |  ------------------
  ------------------
   35|    876|   LTC_ARGCHK(key != NULL);
  ------------------
  |  |   32|    876|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:32): [True: 0, False: 876]
  |  |  |  Branch (32:87): [Folded, False: 876]
  |  |  ------------------
  ------------------
   36|    876|   LTC_ARGCHK(keylen == 32 || keylen == 16);
  ------------------
  |  |   32|    876|#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
  |  |  ------------------
  |  |  |  Branch (32:34): [True: 876, False: 0]
  |  |  |  Branch (32:34): [True: 0, False: 0]
  |  |  |  Branch (32:87): [Folded, False: 876]
  |  |  ------------------
  ------------------
   37|       |
   38|    876|   if (rounds == 0) rounds = 20;
  ------------------
  |  Branch (38:8): [True: 0, False: 876]
  ------------------
   39|       |
   40|    876|   LOAD32L(st->input[4], key + 0);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   41|    876|   LOAD32L(st->input[5], key + 4);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   42|    876|   LOAD32L(st->input[6], key + 8);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   43|    876|   LOAD32L(st->input[7], key + 12);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   44|    876|   if (keylen == 32) { /* 256bit */
  ------------------
  |  Branch (44:8): [True: 876, False: 0]
  ------------------
   45|    876|      key += 16;
   46|    876|      constants = sigma;
   47|    876|   } else { /* 128bit */
   48|      0|      constants = tau;
   49|      0|   }
   50|    876|   LOAD32L(st->input[8],  key + 0);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   51|    876|   LOAD32L(st->input[9],  key + 4);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   52|    876|   LOAD32L(st->input[10], key + 8);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   53|    876|   LOAD32L(st->input[11], key + 12);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   54|    876|   LOAD32L(st->input[0],  constants + 0);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   55|    876|   LOAD32L(st->input[1],  constants + 4);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   56|    876|   LOAD32L(st->input[2],  constants + 8);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   57|    876|   LOAD32L(st->input[3],  constants + 12);
  ------------------
  |  |  167|    876|  do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
  |  |  ------------------
  |  |  |  |   39|    876|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (167:54): [Folded, False: 876]
  |  |  ------------------
  ------------------
   58|    876|   st->rounds = rounds; /* e.g. 20 for chacha20 */
   59|    876|   st->ivlen = 0; /* will be set later by chacha_ivctr(32|64) */
   60|    876|   return CRYPT_OK;
   61|    876|}

mp_add:
    8|      3|{
    9|      3|   mp_sign sa, sb;
   10|      3|   mp_err err;
   11|       |
   12|       |   /* get sign of both inputs */
   13|      3|   sa = a->sign;
   14|      3|   sb = b->sign;
   15|       |
   16|       |   /* handle two cases, not four */
   17|      3|   if (sa == sb) {
  ------------------
  |  Branch (17:8): [True: 3, False: 0]
  ------------------
   18|       |      /* both positive or both negative */
   19|       |      /* add their magnitudes, copy the sign */
   20|      3|      c->sign = sa;
   21|      3|      err = s_mp_add(a, b, c);
   22|      3|   } else {
   23|       |      /* one positive, the other negative */
   24|       |      /* subtract the one with the greater magnitude from */
   25|       |      /* the one of the lesser magnitude.  The result gets */
   26|       |      /* the sign of the one with the greater magnitude. */
   27|      0|      if (mp_cmp_mag(a, b) == MP_LT) {
  ------------------
  |  |  154|      0|#define MP_LT        -1   /* less than */
  ------------------
  |  Branch (27:11): [True: 0, False: 0]
  ------------------
   28|      0|         c->sign = sb;
   29|      0|         err = s_mp_sub(b, a, c);
   30|      0|      } else {
   31|      0|         c->sign = sa;
   32|      0|         err = s_mp_sub(a, b, c);
   33|      0|      }
   34|      0|   }
   35|      3|   return err;
   36|      3|}

mp_add_d:
    8|    128|{
    9|    128|   mp_err     err;
   10|    128|   int ix, oldused;
   11|    128|   mp_digit *tmpa, *tmpc;
   12|       |
   13|       |   /* grow c as required */
   14|    128|   if (c->alloc < (a->used + 1)) {
  ------------------
  |  Branch (14:8): [True: 0, False: 128]
  ------------------
   15|      0|      if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (15:11): [True: 0, False: 0]
  ------------------
   16|      0|         return err;
   17|      0|      }
   18|      0|   }
   19|       |
   20|       |   /* if a is negative and |a| >= b, call c = |a| - b */
   21|    128|   if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
  ------------------
  |  |  152|    128|#define MP_NEG        1   /* negative */
  ------------------
  |  Branch (21:8): [True: 0, False: 128]
  |  Branch (21:32): [True: 0, False: 0]
  |  Branch (21:49): [True: 0, False: 0]
  ------------------
   22|      0|      mp_int a_ = *a;
   23|       |      /* temporarily fix sign of a */
   24|      0|      a_.sign = MP_ZPOS;
  ------------------
  |  |  151|      0|#define MP_ZPOS       0   /* positive integer */
  ------------------
   25|       |
   26|       |      /* c = |a| - b */
   27|      0|      err = mp_sub_d(&a_, b, c);
   28|       |
   29|       |      /* fix sign  */
   30|      0|      c->sign = MP_NEG;
  ------------------
  |  |  152|      0|#define MP_NEG        1   /* negative */
  ------------------
   31|       |
   32|       |      /* clamp */
   33|      0|      mp_clamp(c);
   34|       |
   35|      0|      return err;
   36|      0|   }
   37|       |
   38|       |   /* old number of used digits in c */
   39|    128|   oldused = c->used;
   40|       |
   41|       |   /* source alias */
   42|    128|   tmpa    = a->dp;
   43|       |
   44|       |   /* destination alias */
   45|    128|   tmpc    = c->dp;
   46|       |
   47|       |   /* if a is positive */
   48|    128|   if (a->sign == MP_ZPOS) {
  ------------------
  |  |  151|    128|#define MP_ZPOS       0   /* positive integer */
  ------------------
  |  Branch (48:8): [True: 128, False: 0]
  ------------------
   49|       |      /* add digits, mu is carry */
   50|    128|      mp_digit mu = b;
   51|    466|      for (ix = 0; ix < a->used; ix++) {
  ------------------
  |  Branch (51:20): [True: 338, False: 128]
  ------------------
   52|    338|         *tmpc   = *tmpa++ + mu;
   53|    338|         mu      = *tmpc >> MP_DIGIT_BIT;
  ------------------
  |  |   82|    338|#   define MP_DIGIT_BIT 60
  ------------------
   54|    338|         *tmpc++ &= MP_MASK;
  ------------------
  |  |  106|    338|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|    338|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   55|    338|      }
   56|       |      /* set final carry */
   57|    128|      ix++;
   58|    128|      *tmpc++  = mu;
   59|       |
   60|       |      /* setup size */
   61|    128|      c->used = a->used + 1;
   62|    128|   } else {
   63|       |      /* a was negative and |a| < b */
   64|      0|      c->used  = 1;
   65|       |
   66|       |      /* the result is a single digit */
   67|      0|      if (a->used == 1) {
  ------------------
  |  Branch (67:11): [True: 0, False: 0]
  ------------------
   68|      0|         *tmpc++  =  b - a->dp[0];
   69|      0|      } else {
   70|      0|         *tmpc++  =  b;
   71|      0|      }
   72|       |
   73|       |      /* setup count so the clearing of oldused
   74|       |       * can fall through correctly
   75|       |       */
   76|      0|      ix       = 1;
   77|      0|   }
   78|       |
   79|       |   /* sign always positive */
   80|    128|   c->sign = MP_ZPOS;
  ------------------
  |  |  151|    128|#define MP_ZPOS       0   /* positive integer */
  ------------------
   81|       |
   82|       |   /* now zero to oldused */
   83|    128|   MP_ZERO_DIGITS(tmpc, oldused - ix);
  ------------------
  |  |   89|    128|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|    128|do {                                                    \
  |  |   91|    128|   int zd_ = (digits);                                  \
  |  |   92|    128|   mp_digit* zm_ = (mem);                               \
  |  |   93|    128|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 0, False: 128]
  |  |  ------------------
  |  |   94|      0|      *zm_++ = 0;                                       \
  |  |   95|      0|   }                                                    \
  |  |   96|    128|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 128]
  |  |  ------------------
  ------------------
   84|    128|   mp_clamp(c);
   85|       |
   86|    128|   return MP_OKAY;
  ------------------
  |  |  161|    128|#define MP_OKAY       0   /* no error */
  ------------------
   87|    128|}

mp_clamp:
   14|  31.3k|{
   15|       |   /* decrease used while the most significant digit is
   16|       |    * zero.
   17|       |    */
   18|  48.1k|   while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) {
  ------------------
  |  Branch (18:11): [True: 41.1k, False: 6.96k]
  |  Branch (18:28): [True: 16.7k, False: 24.4k]
  ------------------
   19|  16.7k|      --(a->used);
   20|  16.7k|   }
   21|       |
   22|       |   /* reset the sign flag if used == 0 */
   23|  31.3k|   if (a->used == 0) {
  ------------------
  |  Branch (23:8): [True: 6.96k, False: 24.4k]
  ------------------
   24|  6.96k|      a->sign = MP_ZPOS;
  ------------------
  |  |  151|  6.96k|#define MP_ZPOS       0   /* positive integer */
  ------------------
   25|  6.96k|   }
   26|  31.3k|}

mp_clear:
    8|  19.3k|{
    9|       |   /* only do anything if a hasn't been freed previously */
   10|  19.3k|   if (a->dp != NULL) {
  ------------------
  |  Branch (10:8): [True: 12.9k, False: 6.39k]
  ------------------
   11|       |      /* free ram */
   12|  12.9k|      MP_FREE_DIGITS(a->dp, a->alloc);
  ------------------
  |  |   58|  12.9k|#  define MP_FREE_DIGITS(mem, digits)                   \
  |  |   59|  12.9k|do {                                                    \
  |  |   60|  12.9k|   int fd_ = (digits);                                  \
  |  |   61|  12.9k|   void* fm_ = (mem);                                   \
  |  |   62|  12.9k|   if (fm_ != NULL) {                                   \
  |  |  ------------------
  |  |  |  Branch (62:8): [True: 12.9k, False: 0]
  |  |  ------------------
  |  |   63|  12.9k|      size_t fs_ = sizeof (mp_digit) * (size_t)fd_;     \
  |  |   64|  12.9k|      MP_ZERO_BUFFER(fm_, fs_);                         \
  |  |  ------------------
  |  |  |  |   81|  12.9k|#  define MP_ZERO_BUFFER(mem, size)                     \
  |  |  |  |   82|  12.9k|do {                                                    \
  |  |  |  |   83|  12.9k|   size_t zs_ = (size);                                 \
  |  |  |  |   84|  12.9k|   char* zm_ = (char*)(mem);                            \
  |  |  |  |   85|  1.78M|   while (zs_-- > 0u) {                                 \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (85:11): [True: 1.77M, False: 12.9k]
  |  |  |  |  ------------------
  |  |  |  |   86|  1.77M|      *zm_++ = '\0';                                    \
  |  |  |  |   87|  1.77M|   }                                                    \
  |  |  |  |   88|  12.9k|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (88:10): [Folded, False: 12.9k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   65|  12.9k|      MP_FREE(fm_, fs_);                                \
  |  |  ------------------
  |  |  |  | 1324|  12.9k|#define MP_FREE      m_free_ltm
  |  |  ------------------
  |  |   66|  12.9k|   }                                                    \
  |  |   67|  12.9k|} while (0)
  |  |  ------------------
  |  |  |  Branch (67:10): [Folded, False: 12.9k]
  |  |  ------------------
  ------------------
   13|       |
   14|       |      /* reset members to make debugging easier */
   15|  12.9k|      a->dp    = NULL;
   16|  12.9k|      a->alloc = a->used = 0;
   17|  12.9k|      a->sign  = MP_ZPOS;
  ------------------
  |  |  151|  12.9k|#define MP_ZPOS       0   /* positive integer */
  ------------------
   18|  12.9k|   }
   19|  19.3k|}

mp_clear_multi:
    9|      1|{
   10|      1|   mp_int *next_mp = mp;
   11|      1|   va_list args;
   12|      1|   va_start(args, mp);
   13|      5|   while (next_mp != NULL) {
  ------------------
  |  Branch (13:11): [True: 4, False: 1]
  ------------------
   14|      4|      mp_clear(next_mp);
   15|      4|      next_mp = va_arg(args, mp_int *);
   16|      4|   }
   17|       |   va_end(args);
   18|      1|}

mp_cmp:
    8|      5|{
    9|       |   /* compare based on sign */
   10|      5|   if (a->sign != b->sign) {
  ------------------
  |  Branch (10:8): [True: 0, False: 5]
  ------------------
   11|      0|      if (a->sign == MP_NEG) {
  ------------------
  |  |  152|      0|#define MP_NEG        1   /* negative */
  ------------------
  |  Branch (11:11): [True: 0, False: 0]
  ------------------
   12|      0|         return MP_LT;
  ------------------
  |  |  154|      0|#define MP_LT        -1   /* less than */
  ------------------
   13|      0|      } else {
   14|      0|         return MP_GT;
  ------------------
  |  |  156|      0|#define MP_GT         1   /* greater than */
  ------------------
   15|      0|      }
   16|      0|   }
   17|       |
   18|       |   /* compare digits */
   19|      5|   if (a->sign == MP_NEG) {
  ------------------
  |  |  152|      5|#define MP_NEG        1   /* negative */
  ------------------
  |  Branch (19:8): [True: 0, False: 5]
  ------------------
   20|       |      /* if negative compare opposite direction */
   21|      0|      return mp_cmp_mag(b, a);
   22|      5|   } else {
   23|      5|      return mp_cmp_mag(a, b);
   24|      5|   }
   25|      5|}

mp_cmp_d:
    8|      4|{
    9|       |   /* compare based on sign */
   10|      4|   if (a->sign == MP_NEG) {
  ------------------
  |  |  152|      4|#define MP_NEG        1   /* negative */
  ------------------
  |  Branch (10:8): [True: 0, False: 4]
  ------------------
   11|      0|      return MP_LT;
  ------------------
  |  |  154|      0|#define MP_LT        -1   /* less than */
  ------------------
   12|      0|   }
   13|       |
   14|       |   /* compare based on magnitude */
   15|      4|   if (a->used > 1) {
  ------------------
  |  Branch (15:8): [True: 4, False: 0]
  ------------------
   16|      4|      return MP_GT;
  ------------------
  |  |  156|      4|#define MP_GT         1   /* greater than */
  ------------------
   17|      4|   }
   18|       |
   19|       |   /* compare the only digit of a to b */
   20|      0|   if (a->dp[0] > b) {
  ------------------
  |  Branch (20:8): [True: 0, False: 0]
  ------------------
   21|      0|      return MP_GT;
  ------------------
  |  |  156|      0|#define MP_GT         1   /* greater than */
  ------------------
   22|      0|   } else if (a->dp[0] < b) {
  ------------------
  |  Branch (22:15): [True: 0, False: 0]
  ------------------
   23|      0|      return MP_LT;
  ------------------
  |  |  154|      0|#define MP_LT        -1   /* less than */
  ------------------
   24|      0|   } else {
   25|      0|      return MP_EQ;
  ------------------
  |  |  155|      0|#define MP_EQ         0   /* equal to */
  ------------------
   26|      0|   }
   27|      0|}

mp_cmp_mag:
    8|     28|{
    9|     28|   int     n;
   10|     28|   const mp_digit *tmpa, *tmpb;
   11|       |
   12|       |   /* compare based on # of non-zero digits */
   13|     28|   if (a->used > b->used) {
  ------------------
  |  Branch (13:8): [True: 2, False: 26]
  ------------------
   14|      2|      return MP_GT;
  ------------------
  |  |  156|      2|#define MP_GT         1   /* greater than */
  ------------------
   15|      2|   }
   16|       |
   17|     26|   if (a->used < b->used) {
  ------------------
  |  Branch (17:8): [True: 0, False: 26]
  ------------------
   18|      0|      return MP_LT;
  ------------------
  |  |  154|      0|#define MP_LT        -1   /* less than */
  ------------------
   19|      0|   }
   20|       |
   21|       |   /* alias for a */
   22|     26|   tmpa = a->dp + (a->used - 1);
   23|       |
   24|       |   /* alias for b */
   25|     26|   tmpb = b->dp + (a->used - 1);
   26|       |
   27|       |   /* compare based on digits  */
   28|     43|   for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
  ------------------
  |  Branch (28:16): [True: 42, False: 1]
  ------------------
   29|     42|      if (*tmpa > *tmpb) {
  ------------------
  |  Branch (29:11): [True: 11, False: 31]
  ------------------
   30|     11|         return MP_GT;
  ------------------
  |  |  156|     11|#define MP_GT         1   /* greater than */
  ------------------
   31|     11|      }
   32|       |
   33|     31|      if (*tmpa < *tmpb) {
  ------------------
  |  Branch (33:11): [True: 14, False: 17]
  ------------------
   34|     14|         return MP_LT;
  ------------------
  |  |  154|     14|#define MP_LT        -1   /* less than */
  ------------------
   35|     14|      }
   36|     31|   }
   37|      1|   return MP_EQ;
  ------------------
  |  |  155|      1|#define MP_EQ         0   /* equal to */
  ------------------
   38|     26|}

mp_copy:
    8|  25.8k|{
    9|  25.8k|   int n;
   10|  25.8k|   mp_digit *tmpa, *tmpb;
   11|  25.8k|   mp_err err;
   12|       |
   13|       |   /* if dst == src do nothing */
   14|  25.8k|   if (a == b) {
  ------------------
  |  Branch (14:8): [True: 19.3k, False: 6.45k]
  ------------------
   15|  19.3k|      return MP_OKAY;
  ------------------
  |  |  161|  19.3k|#define MP_OKAY       0   /* no error */
  ------------------
   16|  19.3k|   }
   17|       |
   18|       |   /* grow dest */
   19|  6.45k|   if (b->alloc < a->used) {
  ------------------
  |  Branch (19:8): [True: 0, False: 6.45k]
  ------------------
   20|      0|      if ((err = mp_grow(b, a->used)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (20:11): [True: 0, False: 0]
  ------------------
   21|      0|         return err;
   22|      0|      }
   23|      0|   }
   24|       |
   25|       |   /* zero b and copy the parameters over */
   26|       |   /* pointer aliases */
   27|       |
   28|       |   /* source */
   29|  6.45k|   tmpa = a->dp;
   30|       |
   31|       |   /* destination */
   32|  6.45k|   tmpb = b->dp;
   33|       |
   34|       |   /* copy all the digits */
   35|  12.9k|   for (n = 0; n < a->used; n++) {
  ------------------
  |  Branch (35:16): [True: 6.48k, False: 6.45k]
  ------------------
   36|  6.48k|      *tmpb++ = *tmpa++;
   37|  6.48k|   }
   38|       |
   39|       |   /* clear high digits */
   40|  6.45k|   MP_ZERO_DIGITS(tmpb, b->used - n);
  ------------------
  |  |   89|  6.45k|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|  6.45k|do {                                                    \
  |  |   91|  6.45k|   int zd_ = (digits);                                  \
  |  |   92|  6.45k|   mp_digit* zm_ = (mem);                               \
  |  |   93|  6.45k|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 0, False: 6.45k]
  |  |  ------------------
  |  |   94|      0|      *zm_++ = 0;                                       \
  |  |   95|      0|   }                                                    \
  |  |   96|  6.45k|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 6.45k]
  |  |  ------------------
  ------------------
   41|       |
   42|       |   /* copy used count and sign */
   43|  6.45k|   b->used = a->used;
   44|  6.45k|   b->sign = a->sign;
   45|  6.45k|   return MP_OKAY;
  ------------------
  |  |  161|  6.45k|#define MP_OKAY       0   /* no error */
  ------------------
   46|  6.45k|}

mp_count_bits:
    8|  12.9k|{
    9|  12.9k|   int     r;
   10|  12.9k|   mp_digit q;
   11|       |
   12|       |   /* shortcut */
   13|  12.9k|   if (MP_IS_ZERO(a)) {
  ------------------
  |  |  163|  12.9k|#define MP_IS_ZERO(a) ((a)->used == 0)
  |  |  ------------------
  |  |  |  Branch (163:23): [True: 0, False: 12.9k]
  |  |  ------------------
  ------------------
   14|      0|      return 0;
   15|      0|   }
   16|       |
   17|       |   /* get number of digits and add that */
   18|  12.9k|   r = (a->used - 1) * MP_DIGIT_BIT;
  ------------------
  |  |   82|  12.9k|#   define MP_DIGIT_BIT 60
  ------------------
   19|       |
   20|       |   /* take the last digit and count the bits in it */
   21|  12.9k|   q = a->dp[a->used - 1];
   22|   322k|   while (q > 0u) {
  ------------------
  |  Branch (22:11): [True: 309k, False: 12.9k]
  ------------------
   23|   309k|      ++r;
   24|   309k|      q >>= 1u;
   25|   309k|   }
   26|  12.9k|   return r;
   27|  12.9k|}

mp_div:
   87|      2|{
   88|      2|   mp_int  q, x, y, t1, t2;
   89|      2|   int     n, t, i, norm;
   90|      2|   mp_sign neg;
   91|      2|   mp_err  err;
   92|       |
   93|       |   /* is divisor zero ? */
   94|      2|   if (MP_IS_ZERO(b)) {
  ------------------
  |  |  163|      2|#define MP_IS_ZERO(a) ((a)->used == 0)
  |  |  ------------------
  |  |  |  Branch (163:23): [True: 0, False: 2]
  |  |  ------------------
  ------------------
   95|      0|      return MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   96|      0|   }
   97|       |
   98|       |   /* if a < b then q=0, r = a */
   99|      2|   if (mp_cmp_mag(a, b) == MP_LT) {
  ------------------
  |  |  154|      2|#define MP_LT        -1   /* less than */
  ------------------
  |  Branch (99:8): [True: 0, False: 2]
  ------------------
  100|      0|      if (d != NULL) {
  ------------------
  |  Branch (100:11): [True: 0, False: 0]
  ------------------
  101|      0|         err = mp_copy(a, d);
  102|      0|      } else {
  103|      0|         err = MP_OKAY;
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  104|      0|      }
  105|      0|      if (c != NULL) {
  ------------------
  |  Branch (105:11): [True: 0, False: 0]
  ------------------
  106|      0|         mp_zero(c);
  107|      0|      }
  108|      0|      return err;
  109|      0|   }
  110|       |
  111|      2|   if ((err = mp_init_size(&q, a->used + 2)) != MP_OKAY) {
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (111:8): [True: 0, False: 2]
  ------------------
  112|      0|      return err;
  113|      0|   }
  114|      2|   q.used = a->used + 2;
  115|       |
  116|      2|   if ((err = mp_init(&t1)) != MP_OKAY)                           goto LBL_Q;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (116:8): [True: 0, False: 2]
  ------------------
  117|       |
  118|      2|   if ((err = mp_init(&t2)) != MP_OKAY)                           goto LBL_T1;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (118:8): [True: 0, False: 2]
  ------------------
  119|       |
  120|      2|   if ((err = mp_init_copy(&x, a)) != MP_OKAY)                    goto LBL_T2;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (120:8): [True: 0, False: 2]
  ------------------
  121|       |
  122|      2|   if ((err = mp_init_copy(&y, b)) != MP_OKAY)                    goto LBL_X;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (122:8): [True: 0, False: 2]
  ------------------
  123|       |
  124|       |   /* fix the sign */
  125|      2|   neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
  ------------------
  |  |  151|      2|#define MP_ZPOS       0   /* positive integer */
  ------------------
                 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
  ------------------
  |  |  152|      2|#define MP_NEG        1   /* negative */
  ------------------
  |  Branch (125:10): [True: 2, False: 0]
  ------------------
  126|      2|   x.sign = y.sign = MP_ZPOS;
  ------------------
  |  |  151|      2|#define MP_ZPOS       0   /* positive integer */
  ------------------
  127|       |
  128|       |   /* normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT] */
  129|      2|   norm = mp_count_bits(&y) % MP_DIGIT_BIT;
  ------------------
  |  |   82|      2|#   define MP_DIGIT_BIT 60
  ------------------
  130|      2|   if (norm < (MP_DIGIT_BIT - 1)) {
  ------------------
  |  |   82|      2|#   define MP_DIGIT_BIT 60
  ------------------
  |  Branch (130:8): [True: 2, False: 0]
  ------------------
  131|      2|      norm = (MP_DIGIT_BIT - 1) - norm;
  ------------------
  |  |   82|      2|#   define MP_DIGIT_BIT 60
  ------------------
  132|      2|      if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY)             goto LBL_Y;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (132:11): [True: 0, False: 2]
  ------------------
  133|      2|      if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY)             goto LBL_Y;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (133:11): [True: 0, False: 2]
  ------------------
  134|      2|   } else {
  135|      0|      norm = 0;
  136|      0|   }
  137|       |
  138|       |   /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
  139|      2|   n = x.used - 1;
  140|      2|   t = y.used - 1;
  141|       |
  142|       |   /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
  143|       |   /* y = y*b**{n-t} */
  144|      2|   if ((err = mp_lshd(&y, n - t)) != MP_OKAY)                     goto LBL_Y;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (144:8): [True: 0, False: 2]
  ------------------
  145|       |
  146|      2|   while (mp_cmp(&x, &y) != MP_LT) {
  ------------------
  |  |  154|      2|#define MP_LT        -1   /* less than */
  ------------------
  |  Branch (146:11): [True: 0, False: 2]
  ------------------
  147|      0|      ++(q.dp[n - t]);
  148|      0|      if ((err = mp_sub(&x, &y, &x)) != MP_OKAY)                  goto LBL_Y;
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (148:11): [True: 0, False: 0]
  ------------------
  149|      0|   }
  150|       |
  151|       |   /* reset y by shifting it back down */
  152|      2|   mp_rshd(&y, n - t);
  153|       |
  154|       |   /* step 3. for i from n down to (t + 1) */
  155|     12|   for (i = n; i >= (t + 1); i--) {
  ------------------
  |  Branch (155:16): [True: 10, False: 2]
  ------------------
  156|     10|      if (i > x.used) {
  ------------------
  |  Branch (156:11): [True: 0, False: 10]
  ------------------
  157|      0|         continue;
  158|      0|      }
  159|       |
  160|       |      /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
  161|       |       * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
  162|     10|      if (x.dp[i] == y.dp[t]) {
  ------------------
  |  Branch (162:11): [True: 0, False: 10]
  ------------------
  163|      0|         q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)MP_DIGIT_BIT) - (mp_digit)1;
  ------------------
  |  |   82|      0|#   define MP_DIGIT_BIT 60
  ------------------
  164|     10|      } else {
  165|     10|         mp_word tmp;
  166|     10|         tmp = (mp_word)x.dp[i] << (mp_word)MP_DIGIT_BIT;
  ------------------
  |  |   82|     10|#   define MP_DIGIT_BIT 60
  ------------------
  167|     10|         tmp |= (mp_word)x.dp[i - 1];
  168|     10|         tmp /= (mp_word)y.dp[t];
  169|     10|         if (tmp > (mp_word)MP_MASK) {
  ------------------
  |  |  106|     10|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     10|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  |  Branch (169:14): [True: 0, False: 10]
  ------------------
  170|      0|            tmp = MP_MASK;
  ------------------
  |  |  106|      0|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|      0|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  171|      0|         }
  172|     10|         q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)MP_MASK);
  ------------------
  |  |  106|     10|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     10|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  173|     10|      }
  174|       |
  175|       |      /* while (q{i-t-1} * (yt * b + y{t-1})) >
  176|       |               xi * b**2 + xi-1 * b + xi-2
  177|       |
  178|       |         do q{i-t-1} -= 1;
  179|       |      */
  180|     10|      q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1uL) & (mp_digit)MP_MASK;
  ------------------
  |  |  106|     10|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     10|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  181|     10|      do {
  182|     10|         q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & (mp_digit)MP_MASK;
  ------------------
  |  |  106|     10|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     10|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  183|       |
  184|       |         /* find left hand */
  185|     10|         mp_zero(&t1);
  186|     10|         t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1];
  ------------------
  |  Branch (186:21): [True: 0, False: 10]
  ------------------
  187|     10|         t1.dp[1] = y.dp[t];
  188|     10|         t1.used = 2;
  189|     10|         if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
  ------------------
  |  |  161|     10|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (189:14): [True: 0, False: 10]
  ------------------
  190|       |
  191|       |         /* find right hand */
  192|     10|         t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2];
  ------------------
  |  Branch (192:21): [True: 0, False: 10]
  ------------------
  193|     10|         t2.dp[1] = x.dp[i - 1]; /* i >= 1 always holds */
  194|     10|         t2.dp[2] = x.dp[i];
  195|     10|         t2.used = 3;
  196|     10|      } while (mp_cmp_mag(&t1, &t2) == MP_GT);
  ------------------
  |  |  156|     10|#define MP_GT         1   /* greater than */
  ------------------
  |  Branch (196:16): [True: 0, False: 10]
  ------------------
  197|       |
  198|       |      /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
  199|     10|      if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
  ------------------
  |  |  161|     10|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (199:11): [True: 0, False: 10]
  ------------------
  200|       |
  201|     10|      if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY)           goto LBL_Y;
  ------------------
  |  |  161|     10|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (201:11): [True: 0, False: 10]
  ------------------
  202|       |
  203|     10|      if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY)                 goto LBL_Y;
  ------------------
  |  |  161|     10|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (203:11): [True: 0, False: 10]
  ------------------
  204|       |
  205|       |      /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
  206|     10|      if (x.sign == MP_NEG) {
  ------------------
  |  |  152|     10|#define MP_NEG        1   /* negative */
  ------------------
  |  Branch (206:11): [True: 0, False: 10]
  ------------------
  207|      0|         if ((err = mp_copy(&y, &t1)) != MP_OKAY)                 goto LBL_Y;
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (207:14): [True: 0, False: 0]
  ------------------
  208|      0|         if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY)        goto LBL_Y;
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (208:14): [True: 0, False: 0]
  ------------------
  209|      0|         if ((err = mp_add(&x, &t1, &x)) != MP_OKAY)              goto LBL_Y;
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (209:14): [True: 0, False: 0]
  ------------------
  210|       |
  211|      0|         q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK;
  ------------------
  |  |  106|      0|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|      0|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  212|      0|      }
  213|     10|   }
  214|       |
  215|       |   /* now q is the quotient and x is the remainder
  216|       |    * [which we have to normalize]
  217|       |    */
  218|       |
  219|       |   /* get sign before writing to c */
  220|      2|   x.sign = (x.used == 0) ? MP_ZPOS : a->sign;
  ------------------
  |  |  151|      0|#define MP_ZPOS       0   /* positive integer */
  ------------------
  |  Branch (220:13): [True: 0, False: 2]
  ------------------
  221|       |
  222|      2|   if (c != NULL) {
  ------------------
  |  Branch (222:8): [True: 0, False: 2]
  ------------------
  223|      0|      mp_clamp(&q);
  224|      0|      mp_exch(&q, c);
  225|      0|      c->sign = neg;
  226|      0|   }
  227|       |
  228|      2|   if (d != NULL) {
  ------------------
  |  Branch (228:8): [True: 2, False: 0]
  ------------------
  229|      2|      if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY)       goto LBL_Y;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (229:11): [True: 0, False: 2]
  ------------------
  230|      2|      mp_exch(&x, d);
  231|      2|   }
  232|       |
  233|      2|   err = MP_OKAY;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  234|       |
  235|      2|LBL_Y:
  236|      2|   mp_clear(&y);
  237|      2|LBL_X:
  238|      2|   mp_clear(&x);
  239|      2|LBL_T2:
  240|      2|   mp_clear(&t2);
  241|      2|LBL_T1:
  242|      2|   mp_clear(&t1);
  243|      2|LBL_Q:
  244|      2|   mp_clear(&q);
  245|      2|   return err;
  246|      2|}

mp_div_2d:
    8|  19.3k|{
    9|  19.3k|   mp_digit D, r, rr;
   10|  19.3k|   int     x;
   11|  19.3k|   mp_err err;
   12|       |
   13|       |   /* if the shift count is <= 0 then we do no work */
   14|  19.3k|   if (b <= 0) {
  ------------------
  |  Branch (14:8): [True: 0, False: 19.3k]
  ------------------
   15|      0|      err = mp_copy(a, c);
   16|      0|      if (d != NULL) {
  ------------------
  |  Branch (16:11): [True: 0, False: 0]
  ------------------
   17|      0|         mp_zero(d);
   18|      0|      }
   19|      0|      return err;
   20|      0|   }
   21|       |
   22|       |   /* copy */
   23|  19.3k|   if ((err = mp_copy(a, c)) != MP_OKAY) {
  ------------------
  |  |  161|  19.3k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (23:8): [True: 0, False: 19.3k]
  ------------------
   24|      0|      return err;
   25|      0|   }
   26|       |   /* 'a' should not be used after here - it might be the same as d */
   27|       |
   28|       |   /* get the remainder */
   29|  19.3k|   if (d != NULL) {
  ------------------
  |  Branch (29:8): [True: 0, False: 19.3k]
  ------------------
   30|      0|      if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (30:11): [True: 0, False: 0]
  ------------------
   31|      0|         return err;
   32|      0|      }
   33|      0|   }
   34|       |
   35|       |   /* shift by as many digits in the bit count */
   36|  19.3k|   if (b >= MP_DIGIT_BIT) {
  ------------------
  |  |   82|  19.3k|#   define MP_DIGIT_BIT 60
  ------------------
  |  Branch (36:8): [True: 0, False: 19.3k]
  ------------------
   37|      0|      mp_rshd(c, b / MP_DIGIT_BIT);
  ------------------
  |  |   82|      0|#   define MP_DIGIT_BIT 60
  ------------------
   38|      0|   }
   39|       |
   40|       |   /* shift any bit count < MP_DIGIT_BIT */
   41|  19.3k|   D = (mp_digit)(b % MP_DIGIT_BIT);
  ------------------
  |  |   82|  19.3k|#   define MP_DIGIT_BIT 60
  ------------------
   42|  19.3k|   if (D != 0u) {
  ------------------
  |  Branch (42:8): [True: 19.3k, False: 0]
  ------------------
   43|  19.3k|      mp_digit *tmpc, mask, shift;
   44|       |
   45|       |      /* mask */
   46|  19.3k|      mask = ((mp_digit)1 << D) - 1uL;
   47|       |
   48|       |      /* shift for lsb */
   49|  19.3k|      shift = (mp_digit)MP_DIGIT_BIT - D;
  ------------------
  |  |   82|  19.3k|#   define MP_DIGIT_BIT 60
  ------------------
   50|       |
   51|       |      /* alias */
   52|  19.3k|      tmpc = c->dp + (c->used - 1);
   53|       |
   54|       |      /* carry */
   55|  19.3k|      r = 0;
   56|  38.7k|      for (x = c->used - 1; x >= 0; x--) {
  ------------------
  |  Branch (56:29): [True: 19.3k, False: 19.3k]
  ------------------
   57|       |         /* get the lower  bits of this word in a temp */
   58|  19.3k|         rr = *tmpc & mask;
   59|       |
   60|       |         /* shift the current word and mix in the carry bits from the previous word */
   61|  19.3k|         *tmpc = (*tmpc >> D) | (r << shift);
   62|  19.3k|         --tmpc;
   63|       |
   64|       |         /* set the carry to the carry bits of the current word found above */
   65|  19.3k|         r = rr;
   66|  19.3k|      }
   67|  19.3k|   }
   68|  19.3k|   mp_clamp(c);
   69|  19.3k|   return MP_OKAY;
  ------------------
  |  |  161|  19.3k|#define MP_OKAY       0   /* no error */
  ------------------
   70|  19.3k|}

mp_exch:
   10|      4|{
   11|      4|   mp_int  t;
   12|       |
   13|      4|   t  = *a;
   14|      4|   *a = *b;
   15|      4|   *b = t;
   16|      4|}

mp_from_ubin:
    8|    120|{
    9|    120|   mp_err err;
   10|       |
   11|       |   /* make sure there are at least two digits */
   12|    120|   if (a->alloc < 2) {
  ------------------
  |  Branch (12:8): [True: 0, False: 120]
  ------------------
   13|      0|      if ((err = mp_grow(a, 2)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (13:11): [True: 0, False: 0]
  ------------------
   14|      0|         return err;
   15|      0|      }
   16|      0|   }
   17|       |
   18|       |   /* zero the int */
   19|    120|   mp_zero(a);
   20|       |
   21|       |   /* read the bytes in */
   22|  11.7k|   while (size-- > 0u) {
  ------------------
  |  Branch (22:11): [True: 11.5k, False: 120]
  ------------------
   23|  11.5k|      if ((err = mp_mul_2d(a, 8, a)) != MP_OKAY) {
  ------------------
  |  |  161|  11.5k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (23:11): [True: 0, False: 11.5k]
  ------------------
   24|      0|         return err;
   25|      0|      }
   26|       |
   27|  11.5k|#ifndef MP_8BIT
   28|  11.5k|      a->dp[0] |= *buf++;
   29|  11.5k|      a->used += 1;
   30|       |#else
   31|       |      a->dp[0] = (*buf & MP_MASK);
   32|       |      a->dp[1] |= ((*buf++ >> 7) & 1u);
   33|       |      a->used += 2;
   34|       |#endif
   35|  11.5k|   }
   36|    120|   mp_clamp(a);
   37|    120|   return MP_OKAY;
  ------------------
  |  |  161|    120|#define MP_OKAY       0   /* no error */
  ------------------
   38|    120|}

mp_grow:
    8|    572|{
    9|    572|   int     i;
   10|    572|   mp_digit *tmp;
   11|       |
   12|    572|   if (size < 0) {
  ------------------
  |  Branch (12:8): [True: 0, False: 572]
  ------------------
   13|      0|      return MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   14|      0|   }
   15|       |
   16|       |   /* if the alloc size is smaller alloc more ram */
   17|    572|   if (a->alloc < size) {
  ------------------
  |  Branch (17:8): [True: 572, False: 0]
  ------------------
   18|       |      /* reallocate the array a->dp
   19|       |       *
   20|       |       * We store the return in a temporary variable
   21|       |       * in case the operation failed we don't want
   22|       |       * to overwrite the dp member of a.
   23|       |       */
   24|    572|      tmp = (mp_digit *) MP_REALLOC(a->dp,
  ------------------
  |  | 1325|    572|#define MP_REALLOC   m_realloc_ltm
  ------------------
   25|    572|                                    (size_t)a->alloc * sizeof(mp_digit),
   26|    572|                                    (size_t)size * sizeof(mp_digit));
   27|    572|      if (tmp == NULL) {
  ------------------
  |  Branch (27:11): [True: 0, False: 572]
  ------------------
   28|       |         /* reallocation failed but "a" is still valid [can be freed] */
   29|      0|         return MP_MEM;
  ------------------
  |  |  163|      0|#define MP_MEM        -2  /* out of mem */
  ------------------
   30|      0|      }
   31|       |
   32|       |      /* reallocation succeeded so set a->dp */
   33|    572|      a->dp = tmp;
   34|       |
   35|       |      /* zero excess digits */
   36|    572|      i        = a->alloc;
   37|    572|      a->alloc = size;
   38|    572|      MP_ZERO_DIGITS(a->dp + i, a->alloc - i);
  ------------------
  |  |   89|    572|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|    572|do {                                                    \
  |  |   91|    572|   int zd_ = (digits);                                  \
  |  |   92|    572|   mp_digit* zm_ = (mem);                               \
  |  |   93|  1.15k|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 578, False: 572]
  |  |  ------------------
  |  |   94|    578|      *zm_++ = 0;                                       \
  |  |   95|    578|   }                                                    \
  |  |   96|    572|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 572]
  |  |  ------------------
  ------------------
   39|    572|   }
   40|    572|   return MP_OKAY;
  ------------------
  |  |  161|    572|#define MP_OKAY       0   /* no error */
  ------------------
   41|    572|}

mp_init:
    8|  6.67k|{
    9|       |   /* allocate memory required and clear it */
   10|  6.67k|   a->dp = (mp_digit *) MP_CALLOC((size_t)MP_PREC, sizeof(mp_digit));
  ------------------
  |  | 1326|  6.67k|#define MP_CALLOC    m_calloc
  ------------------
                 a->dp = (mp_digit *) MP_CALLOC((size_t)MP_PREC, sizeof(mp_digit));
  ------------------
  |  |  177|  6.67k|#   define MP_PREC PRIVATE_MP_PREC
  |  |  ------------------
  |  |  |  |  193|  6.67k|#      define PRIVATE_MP_PREC 32        /* default digits of precision */
  |  |  ------------------
  ------------------
   11|  6.67k|   if (a->dp == NULL) {
  ------------------
  |  Branch (11:8): [True: 0, False: 6.67k]
  ------------------
   12|      0|      return MP_MEM;
  ------------------
  |  |  163|      0|#define MP_MEM        -2  /* out of mem */
  ------------------
   13|      0|   }
   14|       |
   15|       |   /* set the used to zero, allocated digits to the default precision
   16|       |    * and sign to positive */
   17|  6.67k|   a->used  = 0;
   18|  6.67k|   a->alloc = MP_PREC;
  ------------------
  |  |  177|  6.67k|#   define MP_PREC PRIVATE_MP_PREC
  |  |  ------------------
  |  |  |  |  193|  6.67k|#      define PRIVATE_MP_PREC 32        /* default digits of precision */
  |  |  ------------------
  ------------------
   19|  6.67k|   a->sign  = MP_ZPOS;
  ------------------
  |  |  151|  6.67k|#define MP_ZPOS       0   /* positive integer */
  ------------------
   20|       |
   21|  6.67k|   return MP_OKAY;
  ------------------
  |  |  161|  6.67k|#define MP_OKAY       0   /* no error */
  ------------------
   22|  6.67k|}

mp_init_copy:
    8|  6.45k|{
    9|  6.45k|   mp_err     err;
   10|       |
   11|  6.45k|   if ((err = mp_init_size(a, b->used)) != MP_OKAY) {
  ------------------
  |  |  161|  6.45k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (11:8): [True: 0, False: 6.45k]
  ------------------
   12|      0|      return err;
   13|      0|   }
   14|       |
   15|  6.45k|   if ((err = mp_copy(b, a)) != MP_OKAY) {
  ------------------
  |  |  161|  6.45k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (15:8): [True: 0, False: 6.45k]
  ------------------
   16|      0|      mp_clear(a);
   17|      0|   }
   18|       |
   19|  6.45k|   return err;
   20|  6.45k|}

mp_init_size:
    8|  6.46k|{
    9|       |
   10|  6.46k|   if (size < 0) {
  ------------------
  |  Branch (10:8): [True: 0, False: 6.46k]
  ------------------
   11|      0|      return MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   12|      0|   }
   13|       |
   14|  6.46k|   size = MP_MAX(MP_MIN_PREC, size);
  ------------------
  |  |  157|  6.46k|#define MP_MAX(x, y) (((x) > (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (157:23): [True: 6.45k, False: 8]
  |  |  ------------------
  ------------------
   15|       |
   16|       |   /* alloc mem */
   17|  6.46k|   a->dp = (mp_digit *) MP_CALLOC((size_t)size, sizeof(mp_digit));
  ------------------
  |  | 1326|  6.46k|#define MP_CALLOC    m_calloc
  ------------------
   18|  6.46k|   if (a->dp == NULL) {
  ------------------
  |  Branch (18:8): [True: 0, False: 6.46k]
  ------------------
   19|      0|      return MP_MEM;
  ------------------
  |  |  163|      0|#define MP_MEM        -2  /* out of mem */
  ------------------
   20|      0|   }
   21|       |
   22|       |   /* set the members */
   23|  6.46k|   a->used  = 0;
   24|  6.46k|   a->alloc = size;
   25|  6.46k|   a->sign  = MP_ZPOS;
  ------------------
  |  |  151|  6.46k|#define MP_ZPOS       0   /* positive integer */
  ------------------
   26|       |
   27|  6.46k|   return MP_OKAY;
  ------------------
  |  |  161|  6.46k|#define MP_OKAY       0   /* no error */
  ------------------
   28|  6.46k|}

mp_lshd:
    8|     12|{
    9|     12|   int x;
   10|     12|   mp_err err;
   11|     12|   mp_digit *top, *bottom;
   12|       |
   13|       |   /* if its less than zero return */
   14|     12|   if (b <= 0) {
  ------------------
  |  Branch (14:8): [True: 2, False: 10]
  ------------------
   15|      2|      return MP_OKAY;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
   16|      2|   }
   17|       |   /* no need to shift 0 around */
   18|     10|   if (MP_IS_ZERO(a)) {
  ------------------
  |  |  163|     10|#define MP_IS_ZERO(a) ((a)->used == 0)
  |  |  ------------------
  |  |  |  Branch (163:23): [True: 0, False: 10]
  |  |  ------------------
  ------------------
   19|      0|      return MP_OKAY;
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
   20|      0|   }
   21|       |
   22|       |   /* grow to fit the new digits */
   23|     10|   if (a->alloc < (a->used + b)) {
  ------------------
  |  Branch (23:8): [True: 2, False: 8]
  ------------------
   24|      2|      if ((err = mp_grow(a, a->used + b)) != MP_OKAY) {
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (24:11): [True: 0, False: 2]
  ------------------
   25|      0|         return err;
   26|      0|      }
   27|      2|   }
   28|       |
   29|       |   /* increment the used by the shift amount then copy upwards */
   30|     10|   a->used += b;
   31|       |
   32|       |   /* top */
   33|     10|   top = a->dp + a->used - 1;
   34|       |
   35|       |   /* base */
   36|     10|   bottom = (a->dp + a->used - 1) - b;
   37|       |
   38|       |   /* much like mp_rshd this is implemented using a sliding window
   39|       |    * except the window goes the otherway around.  Copying from
   40|       |    * the bottom to the top.  see bn_mp_rshd.c for more info.
   41|       |    */
   42|     68|   for (x = a->used - 1; x >= b; x--) {
  ------------------
  |  Branch (42:26): [True: 58, False: 10]
  ------------------
   43|     58|      *top-- = *bottom--;
   44|     58|   }
   45|       |
   46|       |   /* zero the lower digits */
   47|     10|   MP_ZERO_DIGITS(a->dp, b);
  ------------------
  |  |   89|     10|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|     10|do {                                                    \
  |  |   91|     10|   int zd_ = (digits);                                  \
  |  |   92|     10|   mp_digit* zm_ = (mem);                               \
  |  |   93|     40|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 30, False: 10]
  |  |  ------------------
  |  |   94|     30|      *zm_++ = 0;                                       \
  |  |   95|     30|   }                                                    \
  |  |   96|     10|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 10]
  |  |  ------------------
  ------------------
   48|       |
   49|     10|   return MP_OKAY;
  ------------------
  |  |  161|     10|#define MP_OKAY       0   /* no error */
  ------------------
   50|     10|}

mp_mod:
    8|      2|{
    9|      2|   mp_int  t;
   10|      2|   mp_err  err;
   11|       |
   12|      2|   if ((err = mp_init_size(&t, b->used)) != MP_OKAY) {
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (12:8): [True: 0, False: 2]
  ------------------
   13|      0|      return err;
   14|      0|   }
   15|       |
   16|      2|   if ((err = mp_div(a, b, NULL, &t)) != MP_OKAY) {
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (16:8): [True: 0, False: 2]
  ------------------
   17|      0|      goto LBL_ERR;
   18|      0|   }
   19|       |
   20|      2|   if (MP_IS_ZERO(&t) || (t.sign == b->sign)) {
  ------------------
  |  |  163|      4|#define MP_IS_ZERO(a) ((a)->used == 0)
  |  |  ------------------
  |  |  |  Branch (163:23): [True: 0, False: 2]
  |  |  ------------------
  ------------------
  |  Branch (20:26): [True: 2, False: 0]
  ------------------
   21|      2|      err = MP_OKAY;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
   22|      2|      mp_exch(&t, c);
   23|      2|   } else {
   24|      0|      err = mp_add(b, &t, c);
   25|      0|   }
   26|       |
   27|      2|LBL_ERR:
   28|      2|   mp_clear(&t);
   29|      2|   return err;
   30|      2|}

mp_mul:
    8|      1|{
    9|      1|   mp_err err;
   10|      1|   int min_len = MP_MIN(a->used, b->used),
  ------------------
  |  |  156|      1|#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (156:23): [True: 0, False: 1]
  |  |  ------------------
  ------------------
   11|      1|       max_len = MP_MAX(a->used, b->used),
  ------------------
  |  |  157|      1|#define MP_MAX(x, y) (((x) > (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (157:23): [True: 0, False: 1]
  |  |  ------------------
  ------------------
   12|      1|       digs = a->used + b->used + 1;
   13|      1|   mp_sign neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
  ------------------
  |  |  151|      1|#define MP_ZPOS       0   /* positive integer */
  ------------------
                 mp_sign neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
  ------------------
  |  |  152|      0|#define MP_NEG        1   /* negative */
  ------------------
  |  Branch (13:18): [True: 1, False: 0]
  ------------------
   14|       |
   15|      1|   if (MP_HAS(S_MP_BALANCE_MUL) &&
  ------------------
  |  |  150|      2|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      1|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      1|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [True: 1, Folded]
  |  |  ------------------
  ------------------
   16|       |       /* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off.
   17|       |        * The bigger one needs to be at least about one MP_KARATSUBA_MUL_CUTOFF bigger
   18|       |        * to make some sense, but it depends on architecture, OS, position of the
   19|       |        * stars... so YMMV.
   20|       |        * Using it to cut the input into slices small enough for fast_s_mp_mul_digs
   21|       |        * was actually slower on the author's machine, but YMMV.
   22|       |        */
   23|      1|       (min_len >= MP_KARATSUBA_MUL_CUTOFF) &&
  ------------------
  |  |  121|      1|#  define MP_KARATSUBA_MUL_CUTOFF KARATSUBA_MUL_CUTOFF
  ------------------
  |  Branch (23:8): [True: 0, False: 1]
  ------------------
   24|      0|       ((max_len / 2) >= MP_KARATSUBA_MUL_CUTOFF) &&
  ------------------
  |  |  121|      0|#  define MP_KARATSUBA_MUL_CUTOFF KARATSUBA_MUL_CUTOFF
  ------------------
  |  Branch (24:8): [True: 0, False: 0]
  ------------------
   25|       |       /* Not much effect was observed below a ratio of 1:2, but again: YMMV. */
   26|      0|       (max_len >= (2 * min_len))) {
  ------------------
  |  Branch (26:8): [True: 0, False: 0]
  ------------------
   27|      0|      err = s_mp_balance_mul(a,b,c);
   28|      1|   } else if (MP_HAS(S_MP_TOOM_MUL) &&
  ------------------
  |  |  150|      2|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      1|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      1|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [Folded, False: 1]
  |  |  ------------------
  ------------------
   29|      0|              (min_len >= MP_TOOM_MUL_CUTOFF)) {
  ------------------
  |  |  123|      0|#  define MP_TOOM_MUL_CUTOFF      TOOM_MUL_CUTOFF
  ------------------
  |  Branch (29:15): [True: 0, False: 0]
  ------------------
   30|      0|      err = s_mp_toom_mul(a, b, c);
   31|      1|   } else if (MP_HAS(S_MP_KARATSUBA_MUL) &&
  ------------------
  |  |  150|      2|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      1|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      1|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [Folded, False: 1]
  |  |  ------------------
  ------------------
   32|      0|              (min_len >= MP_KARATSUBA_MUL_CUTOFF)) {
  ------------------
  |  |  121|      0|#  define MP_KARATSUBA_MUL_CUTOFF KARATSUBA_MUL_CUTOFF
  ------------------
  |  Branch (32:15): [True: 0, False: 0]
  ------------------
   33|      0|      err = s_mp_karatsuba_mul(a, b, c);
   34|      1|   } else if (MP_HAS(S_MP_MUL_DIGS_FAST) &&
  ------------------
  |  |  150|      2|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      1|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      1|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [True: 1, Folded]
  |  |  ------------------
  ------------------
   35|       |              /* can we use the fast multiplier?
   36|       |               *
   37|       |               * The fast multiplier can be used if the output will
   38|       |               * have less than MP_WARRAY digits and the number of
   39|       |               * digits won't affect carry propagation
   40|       |               */
   41|      1|              (digs < MP_WARRAY) &&
  ------------------
  |  |  172|      1|#define MP_WARRAY PRIVATE_MP_WARRAY
  |  |  ------------------
  |  |  |  |  203|      1|#define PRIVATE_MP_WARRAY (int)(1uLL << (((CHAR_BIT * sizeof(private_mp_word)) - (2 * MP_DIGIT_BIT)) + 1))
  |  |  |  |  ------------------
  |  |  |  |  |  |   82|      1|#   define MP_DIGIT_BIT 60
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (41:15): [True: 1, False: 0]
  ------------------
   42|      1|              (min_len <= MP_MAXFAST)) {
  ------------------
  |  |  168|      1|#define MP_MAXFAST              (int)(1uL << (MP_SIZEOF_BITS(mp_word) - (2u * (size_t)MP_DIGIT_BIT)))
  |  |  ------------------
  |  |  |  |  167|      1|#define MP_SIZEOF_BITS(type)    ((size_t)CHAR_BIT * sizeof(type))
  |  |  ------------------
  |  |               #define MP_MAXFAST              (int)(1uL << (MP_SIZEOF_BITS(mp_word) - (2u * (size_t)MP_DIGIT_BIT)))
  |  |  ------------------
  |  |  |  |   82|      1|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  |  Branch (42:15): [True: 1, False: 0]
  ------------------
   43|      1|      err = s_mp_mul_digs_fast(a, b, c, digs);
   44|      1|   } else if (MP_HAS(S_MP_MUL_DIGS)) {
  ------------------
  |  |  150|      0|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      0|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      0|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [True: 0, Folded]
  |  |  ------------------
  ------------------
   45|      0|      err = s_mp_mul_digs(a, b, c, digs);
   46|      0|   } else {
   47|      0|      err = MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   48|      0|   }
   49|      1|   c->sign = (c->used > 0) ? neg : MP_ZPOS;
  ------------------
  |  |  151|      1|#define MP_ZPOS       0   /* positive integer */
  ------------------
  |  Branch (49:14): [True: 1, False: 0]
  ------------------
   50|      1|   return err;
   51|      1|}

mp_mul_2d:
    8|  11.5k|{
    9|  11.5k|   mp_digit d;
   10|  11.5k|   mp_err   err;
   11|       |
   12|  11.5k|   if (b < 0) {
  ------------------
  |  Branch (12:8): [True: 0, False: 11.5k]
  ------------------
   13|      0|      return MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   14|      0|   }
   15|       |
   16|       |   /* copy */
   17|  11.5k|   if (a != c) {
  ------------------
  |  Branch (17:8): [True: 0, False: 11.5k]
  ------------------
   18|      0|      if ((err = mp_copy(a, c)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (18:11): [True: 0, False: 0]
  ------------------
   19|      0|         return err;
   20|      0|      }
   21|      0|   }
   22|       |
   23|  11.5k|   if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) {
  ------------------
  |  |   82|  11.5k|#   define MP_DIGIT_BIT 60
  ------------------
  |  Branch (23:8): [True: 569, False: 11.0k]
  ------------------
   24|    569|      if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
  ------------------
  |  |   82|    569|#   define MP_DIGIT_BIT 60
  ------------------
                    if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
  ------------------
  |  |  161|    569|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (24:11): [True: 0, False: 569]
  ------------------
   25|      0|         return err;
   26|      0|      }
   27|    569|   }
   28|       |
   29|       |   /* shift by as many digits in the bit count */
   30|  11.5k|   if (b >= MP_DIGIT_BIT) {
  ------------------
  |  |   82|  11.5k|#   define MP_DIGIT_BIT 60
  ------------------
  |  Branch (30:8): [True: 0, False: 11.5k]
  ------------------
   31|      0|      if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) {
  ------------------
  |  |   82|      0|#   define MP_DIGIT_BIT 60
  ------------------
                    if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (31:11): [True: 0, False: 0]
  ------------------
   32|      0|         return err;
   33|      0|      }
   34|      0|   }
   35|       |
   36|       |   /* shift any bit count < MP_DIGIT_BIT */
   37|  11.5k|   d = (mp_digit)(b % MP_DIGIT_BIT);
  ------------------
  |  |   82|  11.5k|#   define MP_DIGIT_BIT 60
  ------------------
   38|  11.5k|   if (d != 0u) {
  ------------------
  |  Branch (38:8): [True: 11.5k, False: 0]
  ------------------
   39|  11.5k|      mp_digit *tmpc, shift, mask, r, rr;
   40|  11.5k|      int x;
   41|       |
   42|       |      /* bitmask for carries */
   43|  11.5k|      mask = ((mp_digit)1 << d) - (mp_digit)1;
   44|       |
   45|       |      /* shift for msbs */
   46|  11.5k|      shift = (mp_digit)MP_DIGIT_BIT - d;
  ------------------
  |  |   82|  11.5k|#   define MP_DIGIT_BIT 60
  ------------------
   47|       |
   48|       |      /* alias */
   49|  11.5k|      tmpc = c->dp;
   50|       |
   51|       |      /* carry */
   52|  11.5k|      r    = 0;
   53|   387k|      for (x = 0; x < c->used; x++) {
  ------------------
  |  Branch (53:19): [True: 376k, False: 11.5k]
  ------------------
   54|       |         /* get the higher bits of the current word */
   55|   376k|         rr = (*tmpc >> shift) & mask;
   56|       |
   57|       |         /* shift the current word and OR in the carry */
   58|   376k|         *tmpc = ((*tmpc << d) | r) & MP_MASK;
  ------------------
  |  |  106|   376k|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|   376k|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   59|   376k|         ++tmpc;
   60|       |
   61|       |         /* set the carry to the carry bits of the current word */
   62|   376k|         r = rr;
   63|   376k|      }
   64|       |
   65|       |      /* set final carry */
   66|  11.5k|      if (r != 0u) {
  ------------------
  |  Branch (66:11): [True: 2, False: 11.5k]
  ------------------
   67|      2|         c->dp[(c->used)++] = r;
   68|      2|      }
   69|  11.5k|   }
   70|  11.5k|   mp_clamp(c);
   71|  11.5k|   return MP_OKAY;
  ------------------
  |  |  161|  11.5k|#define MP_OKAY       0   /* no error */
  ------------------
   72|  11.5k|}

mp_mul_d:
    8|    148|{
    9|    148|   mp_digit u, *tmpa, *tmpc;
   10|    148|   mp_word  r;
   11|    148|   mp_err   err;
   12|    148|   int      ix, olduse;
   13|       |
   14|       |   /* make sure c is big enough to hold a*b */
   15|    148|   if (c->alloc < (a->used + 1)) {
  ------------------
  |  Branch (15:8): [True: 0, False: 148]
  ------------------
   16|      0|      if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (16:11): [True: 0, False: 0]
  ------------------
   17|      0|         return err;
   18|      0|      }
   19|      0|   }
   20|       |
   21|       |   /* get the original destinations used count */
   22|    148|   olduse = c->used;
   23|       |
   24|       |   /* set the sign */
   25|    148|   c->sign = a->sign;
   26|       |
   27|       |   /* alias for a->dp [source] */
   28|    148|   tmpa = a->dp;
   29|       |
   30|       |   /* alias for c->dp [dest] */
   31|    148|   tmpc = c->dp;
   32|       |
   33|       |   /* zero carry */
   34|    148|   u = 0;
   35|       |
   36|       |   /* compute columns */
   37|    548|   for (ix = 0; ix < a->used; ix++) {
  ------------------
  |  Branch (37:17): [True: 400, False: 148]
  ------------------
   38|       |      /* compute product and carry sum for this term */
   39|    400|      r       = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b);
   40|       |
   41|       |      /* mask off higher bits to get a single digit */
   42|    400|      *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK);
  ------------------
  |  |  106|    400|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|    400|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   43|       |
   44|       |      /* send carry into next iteration */
   45|    400|      u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
  ------------------
  |  |   82|    400|#   define MP_DIGIT_BIT 60
  ------------------
   46|    400|   }
   47|       |
   48|       |   /* store final carry [if any] and increment ix offset  */
   49|    148|   *tmpc++ = u;
   50|    148|   ++ix;
   51|       |
   52|       |   /* now zero digits above the top */
   53|    148|   MP_ZERO_DIGITS(tmpc, olduse - ix);
  ------------------
  |  |   89|    148|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|    148|do {                                                    \
  |  |   91|    148|   int zd_ = (digits);                                  \
  |  |   92|    148|   mp_digit* zm_ = (mem);                               \
  |  |   93|    148|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 0, False: 148]
  |  |  ------------------
  |  |   94|      0|      *zm_++ = 0;                                       \
  |  |   95|      0|   }                                                    \
  |  |   96|    148|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 148]
  |  |  ------------------
  ------------------
   54|       |
   55|       |   /* set used count */
   56|    148|   c->used = a->used + 1;
   57|    148|   mp_clamp(c);
   58|       |
   59|    148|   return MP_OKAY;
  ------------------
  |  |  161|    148|#define MP_OKAY       0   /* no error */
  ------------------
   60|    148|}

mp_rand_source:
   10|      1|{
   11|       |   /* Dropbear, don't reset to platform if source==NULL */
   12|      1|   s_mp_rand_source = source;
   13|      1|}

mp_read_radix:
   10|      2|{
   11|      2|   mp_err   err;
   12|      2|   int      y;
   13|      2|   mp_sign  neg;
   14|      2|   unsigned pos;
   15|      2|   char     ch;
   16|       |
   17|       |   /* zero the digit bignum */
   18|      2|   mp_zero(a);
   19|       |
   20|       |   /* make sure the radix is ok */
   21|      2|   if ((radix < 2) || (radix > 64)) {
  ------------------
  |  Branch (21:8): [True: 0, False: 2]
  |  Branch (21:23): [True: 0, False: 2]
  ------------------
   22|      0|      return MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   23|      0|   }
   24|       |
   25|       |   /* if the leading digit is a
   26|       |    * minus set the sign to negative.
   27|       |    */
   28|      2|   if (*str == '-') {
  ------------------
  |  Branch (28:8): [True: 0, False: 2]
  ------------------
   29|      0|      ++str;
   30|      0|      neg = MP_NEG;
  ------------------
  |  |  152|      0|#define MP_NEG        1   /* negative */
  ------------------
   31|      2|   } else {
   32|      2|      neg = MP_ZPOS;
  ------------------
  |  |  151|      2|#define MP_ZPOS       0   /* positive integer */
  ------------------
   33|      2|   }
   34|       |
   35|       |   /* set the integer to the default of zero */
   36|      2|   mp_zero(a);
   37|       |
   38|       |   /* process each digit of the string */
   39|    130|   while (*str != '\0') {
  ------------------
  |  Branch (39:11): [True: 128, False: 2]
  ------------------
   40|       |      /* if the radix <= 36 the conversion is case insensitive
   41|       |       * this allows numbers like 1AB and 1ab to represent the same  value
   42|       |       * [e.g. in hex]
   43|       |       */
   44|    128|      ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str;
  ------------------
  |  |    6|    128|#define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c))
  |  |  ------------------
  |  |  |  Branch (6:25): [True: 0, False: 128]
  |  |  |  Branch (6:41): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (44:12): [True: 128, False: 0]
  ------------------
   45|    128|      pos = (unsigned)(ch - '(');
   46|    128|      if (mp_s_rmap_reverse_sz < pos) {
  ------------------
  |  Branch (46:11): [True: 0, False: 128]
  ------------------
   47|      0|         break;
   48|      0|      }
   49|    128|      y = (int)mp_s_rmap_reverse[pos];
   50|       |
   51|       |      /* if the char was found in the map
   52|       |       * and is less than the given radix add it
   53|       |       * to the number, otherwise exit the loop.
   54|       |       */
   55|    128|      if ((y == 0xff) || (y >= radix)) {
  ------------------
  |  Branch (55:11): [True: 0, False: 128]
  |  Branch (55:26): [True: 0, False: 128]
  ------------------
   56|      0|         break;
   57|      0|      }
   58|    128|      if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
  ------------------
  |  |  161|    128|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (58:11): [True: 0, False: 128]
  ------------------
   59|      0|         return err;
   60|      0|      }
   61|    128|      if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
  ------------------
  |  |  161|    128|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (61:11): [True: 0, False: 128]
  ------------------
   62|      0|         return err;
   63|      0|      }
   64|    128|      ++str;
   65|    128|   }
   66|       |
   67|       |   /* if an illegal character was found, fail. */
   68|      2|   if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) {
  ------------------
  |  Branch (68:10): [True: 2, False: 0]
  |  Branch (68:28): [True: 0, False: 0]
  |  Branch (68:46): [True: 0, False: 0]
  ------------------
   69|      0|      mp_zero(a);
   70|      0|      return MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   71|      0|   }
   72|       |
   73|       |   /* set the sign only if a != 0 */
   74|      2|   if (!MP_IS_ZERO(a)) {
  ------------------
  |  |  163|      2|#define MP_IS_ZERO(a) ((a)->used == 0)
  ------------------
  |  Branch (74:8): [True: 2, False: 0]
  ------------------
   75|      2|      a->sign = neg;
   76|      2|   }
   77|      2|   return MP_OKAY;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
   78|      2|}

mp_rshd:
    8|      2|{
    9|      2|   int     x;
   10|      2|   mp_digit *bottom, *top;
   11|       |
   12|       |   /* if b <= 0 then ignore it */
   13|      2|   if (b <= 0) {
  ------------------
  |  Branch (13:8): [True: 0, False: 2]
  ------------------
   14|      0|      return;
   15|      0|   }
   16|       |
   17|       |   /* if b > used then simply zero it and return */
   18|      2|   if (a->used <= b) {
  ------------------
  |  Branch (18:8): [True: 0, False: 2]
  ------------------
   19|      0|      mp_zero(a);
   20|      0|      return;
   21|      0|   }
   22|       |
   23|       |   /* shift the digits down */
   24|       |
   25|       |   /* bottom */
   26|      2|   bottom = a->dp;
   27|       |
   28|       |   /* top [offset into digits] */
   29|      2|   top = a->dp + b;
   30|       |
   31|       |   /* this is implemented as a sliding window where
   32|       |    * the window is b-digits long and digits from
   33|       |    * the top of the window are copied to the bottom
   34|       |    *
   35|       |    * e.g.
   36|       |
   37|       |    b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
   38|       |                /\                   |      ---->
   39|       |                 \-------------------/      ---->
   40|       |    */
   41|     12|   for (x = 0; x < (a->used - b); x++) {
  ------------------
  |  Branch (41:16): [True: 10, False: 2]
  ------------------
   42|     10|      *bottom++ = *top++;
   43|     10|   }
   44|       |
   45|       |   /* zero the top digits */
   46|      2|   MP_ZERO_DIGITS(bottom, a->used - x);
  ------------------
  |  |   89|      2|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|      2|do {                                                    \
  |  |   91|      2|   int zd_ = (digits);                                  \
  |  |   92|      2|   mp_digit* zm_ = (mem);                               \
  |  |   93|     12|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 10, False: 2]
  |  |  ------------------
  |  |   94|     10|      *zm_++ = 0;                                       \
  |  |   95|     10|   }                                                    \
  |  |   96|      2|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 2]
  |  |  ------------------
  ------------------
   47|       |
   48|       |   /* remove excess digits */
   49|      2|   a->used -= b;
   50|      2|}

mp_set:
    8|      1|{
    9|      1|   a->dp[0] = b & MP_MASK;
  ------------------
  |  |  106|      1|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|      1|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   10|      1|   a->sign  = MP_ZPOS;
  ------------------
  |  |  151|      1|#define MP_ZPOS       0   /* positive integer */
  ------------------
   11|      1|   a->used  = (a->dp[0] != 0u) ? 1 : 0;
  ------------------
  |  Branch (11:15): [True: 1, False: 0]
  ------------------
   12|      1|   MP_ZERO_DIGITS(a->dp + a->used, a->alloc - a->used);
  ------------------
  |  |   89|      1|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|      1|do {                                                    \
  |  |   91|      1|   int zd_ = (digits);                                  \
  |  |   92|      1|   mp_digit* zm_ = (mem);                               \
  |  |   93|     32|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 31, False: 1]
  |  |  ------------------
  |  |   94|     31|      *zm_++ = 0;                                       \
  |  |   95|     31|   }                                                    \
  |  |   96|      1|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 1]
  |  |  ------------------
  ------------------
   13|      1|}

mp_sqr:
    8|      2|{
    9|      2|   mp_err err;
   10|      2|   if (MP_HAS(S_MP_TOOM_SQR) && /* use Toom-Cook? */
  ------------------
  |  |  150|      4|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      2|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      2|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [Folded, False: 2]
  |  |  ------------------
  ------------------
   11|      0|       (a->used >= MP_TOOM_SQR_CUTOFF)) {
  ------------------
  |  |  124|      0|#  define MP_TOOM_SQR_CUTOFF      TOOM_SQR_CUTOFF
  ------------------
  |  Branch (11:8): [True: 0, False: 0]
  ------------------
   12|      0|      err = s_mp_toom_sqr(a, b);
   13|      2|   } else if (MP_HAS(S_MP_KARATSUBA_SQR) &&  /* Karatsuba? */
  ------------------
  |  |  150|      4|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      2|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      2|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [Folded, False: 2]
  |  |  ------------------
  ------------------
   14|      0|              (a->used >= MP_KARATSUBA_SQR_CUTOFF)) {
  ------------------
  |  |  122|      0|#  define MP_KARATSUBA_SQR_CUTOFF KARATSUBA_SQR_CUTOFF
  ------------------
  |  Branch (14:15): [True: 0, False: 0]
  ------------------
   15|      0|      err = s_mp_karatsuba_sqr(a, b);
   16|      2|   } else if (MP_HAS(S_MP_SQR_FAST) && /* can we use the fast comba multiplier? */
  ------------------
  |  |  150|      4|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      2|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      2|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [True: 2, Folded]
  |  |  ------------------
  ------------------
   17|      2|              (((a->used * 2) + 1) < MP_WARRAY) &&
  ------------------
  |  |  172|      2|#define MP_WARRAY PRIVATE_MP_WARRAY
  |  |  ------------------
  |  |  |  |  203|      2|#define PRIVATE_MP_WARRAY (int)(1uLL << (((CHAR_BIT * sizeof(private_mp_word)) - (2 * MP_DIGIT_BIT)) + 1))
  |  |  |  |  ------------------
  |  |  |  |  |  |   82|      2|#   define MP_DIGIT_BIT 60
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (17:15): [True: 2, False: 0]
  ------------------
   18|      2|              (a->used < (MP_MAXFAST / 2))) {
  ------------------
  |  |  168|      2|#define MP_MAXFAST              (int)(1uL << (MP_SIZEOF_BITS(mp_word) - (2u * (size_t)MP_DIGIT_BIT)))
  |  |  ------------------
  |  |  |  |  167|      2|#define MP_SIZEOF_BITS(type)    ((size_t)CHAR_BIT * sizeof(type))
  |  |  ------------------
  |  |               #define MP_MAXFAST              (int)(1uL << (MP_SIZEOF_BITS(mp_word) - (2u * (size_t)MP_DIGIT_BIT)))
  |  |  ------------------
  |  |  |  |   82|      2|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
  |  Branch (18:15): [True: 2, False: 0]
  ------------------
   19|      2|      err = s_mp_sqr_fast(a, b);
   20|      2|   } else if (MP_HAS(S_MP_SQR)) {
  ------------------
  |  |  150|      0|#define MP_HAS(x)        (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  |  |  ------------------
  |  |  |  |  148|      0|#define MP_STRINGIZE(x)  MP__STRINGIZE(x)
  |  |  |  |  ------------------
  |  |  |  |  |  |  149|      0|#define MP__STRINGIZE(x) ""#x""
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (150:26): [True: 0, Folded]
  |  |  ------------------
  ------------------
   21|      0|      err = s_mp_sqr(a, b);
   22|      0|   } else {
   23|      0|      err = MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   24|      0|   }
   25|      2|   b->sign = MP_ZPOS;
  ------------------
  |  |  151|      2|#define MP_ZPOS       0   /* positive integer */
  ------------------
   26|      2|   return err;
   27|      2|}

mp_sub:
    8|     11|{
    9|     11|   mp_sign sa = a->sign, sb = b->sign;
   10|     11|   mp_err err;
   11|       |
   12|     11|   if (sa != sb) {
  ------------------
  |  Branch (12:8): [True: 0, False: 11]
  ------------------
   13|       |      /* subtract a negative from a positive, OR */
   14|       |      /* subtract a positive from a negative. */
   15|       |      /* In either case, ADD their magnitudes, */
   16|       |      /* and use the sign of the first number. */
   17|      0|      c->sign = sa;
   18|      0|      err = s_mp_add(a, b, c);
   19|     11|   } else {
   20|       |      /* subtract a positive from a positive, OR */
   21|       |      /* subtract a negative from a negative. */
   22|       |      /* First, take the difference between their */
   23|       |      /* magnitudes, then... */
   24|     11|      if (mp_cmp_mag(a, b) != MP_LT) {
  ------------------
  |  |  154|     11|#define MP_LT        -1   /* less than */
  ------------------
  |  Branch (24:11): [True: 11, False: 0]
  ------------------
   25|       |         /* Copy the sign from the first */
   26|     11|         c->sign = sa;
   27|       |         /* The first has a larger or equal magnitude */
   28|     11|         err = s_mp_sub(a, b, c);
   29|     11|      } else {
   30|       |         /* The result has the *opposite* sign from */
   31|       |         /* the first number. */
   32|      0|         c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
  ------------------
  |  |  151|      0|#define MP_ZPOS       0   /* positive integer */
  ------------------
                       c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
  ------------------
  |  |  152|      0|#define MP_NEG        1   /* negative */
  ------------------
                       c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
  ------------------
  |  |  151|      0|#define MP_ZPOS       0   /* positive integer */
  ------------------
  |  Branch (32:20): [True: 0, False: 0]
  ------------------
   33|       |         /* The second has a larger magnitude */
   34|      0|         err = s_mp_sub(b, a, c);
   35|      0|      }
   36|     11|   }
   37|     11|   return err;
   38|     11|}

mp_to_ubin:
    8|  6.45k|{
    9|  6.45k|   size_t  x, count;
   10|  6.45k|   mp_err  err;
   11|  6.45k|   mp_int  t;
   12|       |
   13|  6.45k|   count = mp_ubin_size(a);
   14|  6.45k|   if (count > maxlen) {
  ------------------
  |  Branch (14:8): [True: 0, False: 6.45k]
  ------------------
   15|      0|      return MP_BUF;
  ------------------
  |  |  167|      0|#define MP_BUF        -5  /* buffer overflow, supplied buffer too small */
  ------------------
   16|      0|   }
   17|       |
   18|  6.45k|   if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
  ------------------
  |  |  161|  6.45k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (18:8): [True: 0, False: 6.45k]
  ------------------
   19|      0|      return err;
   20|      0|   }
   21|       |
   22|  25.8k|   for (x = count; x --> 0u;) {
  ------------------
  |  Branch (22:20): [True: 19.3k, False: 6.45k]
  ------------------
   23|  19.3k|#ifndef MP_8BIT
   24|  19.3k|      buf[x] = (unsigned char)(t.dp[0] & 255u);
   25|       |#else
   26|       |      buf[x] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7));
   27|       |#endif
   28|  19.3k|      if ((err = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) {
  ------------------
  |  |  161|  19.3k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (28:11): [True: 0, False: 19.3k]
  ------------------
   29|      0|         goto LBL_ERR;
   30|      0|      }
   31|  19.3k|   }
   32|       |
   33|  6.45k|   if (written != NULL) {
  ------------------
  |  Branch (33:8): [True: 6.45k, False: 0]
  ------------------
   34|  6.45k|      *written = count;
   35|  6.45k|   }
   36|       |
   37|  6.45k|LBL_ERR:
   38|  6.45k|   mp_clear(&t);
   39|  6.45k|   return err;
   40|  6.45k|}

mp_ubin_size:
    8|  6.45k|{
    9|  6.45k|   size_t size = (size_t)mp_count_bits(a);
   10|  6.45k|   return (size / 8u) + (((size & 7u) != 0u) ? 1u : 0u);
  ------------------
  |  Branch (10:26): [True: 0, False: 6.45k]
  ------------------
   11|  6.45k|}

mp_zero:
    8|    144|{
    9|    144|   a->sign = MP_ZPOS;
  ------------------
  |  |  151|    144|#define MP_ZPOS       0   /* positive integer */
  ------------------
   10|    144|   a->used = 0;
   11|    144|   MP_ZERO_DIGITS(a->dp, a->alloc);
  ------------------
  |  |   89|    144|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|    144|do {                                                    \
  |  |   91|    144|   int zd_ = (digits);                                  \
  |  |   92|    144|   mp_digit* zm_ = (mem);                               \
  |  |   93|  4.75k|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 4.60k, False: 144]
  |  |  ------------------
  |  |   94|  4.60k|      *zm_++ = 0;                                       \
  |  |   95|  4.60k|   }                                                    \
  |  |   96|    144|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 144]
  |  |  ------------------
  ------------------
   12|    144|}

s_mp_add:
    8|      3|{
    9|      3|   const mp_int *x;
   10|      3|   mp_err err;
   11|      3|   int     olduse, min, max;
   12|       |
   13|       |   /* find sizes, we let |a| <= |b| which means we have to sort
   14|       |    * them.  "x" will point to the input with the most digits
   15|       |    */
   16|      3|   if (a->used > b->used) {
  ------------------
  |  Branch (16:8): [True: 3, False: 0]
  ------------------
   17|      3|      min = b->used;
   18|      3|      max = a->used;
   19|      3|      x = a;
   20|      3|   } else {
   21|      0|      min = a->used;
   22|      0|      max = b->used;
   23|      0|      x = b;
   24|      0|   }
   25|       |
   26|       |   /* init result */
   27|      3|   if (c->alloc < (max + 1)) {
  ------------------
  |  Branch (27:8): [True: 0, False: 3]
  ------------------
   28|      0|      if ((err = mp_grow(c, max + 1)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (28:11): [True: 0, False: 0]
  ------------------
   29|      0|         return err;
   30|      0|      }
   31|      0|   }
   32|       |
   33|       |   /* get old used digit count and set new one */
   34|      3|   olduse = c->used;
   35|      3|   c->used = max + 1;
   36|       |
   37|      3|   {
   38|      3|      mp_digit u, *tmpa, *tmpb, *tmpc;
   39|      3|      int i;
   40|       |
   41|       |      /* alias for digit pointers */
   42|       |
   43|       |      /* first input */
   44|      3|      tmpa = a->dp;
   45|       |
   46|       |      /* second input */
   47|      3|      tmpb = b->dp;
   48|       |
   49|       |      /* destination */
   50|      3|      tmpc = c->dp;
   51|       |
   52|       |      /* zero the carry */
   53|      3|      u = 0;
   54|     18|      for (i = 0; i < min; i++) {
  ------------------
  |  Branch (54:19): [True: 15, False: 3]
  ------------------
   55|       |         /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
   56|     15|         *tmpc = *tmpa++ + *tmpb++ + u;
   57|       |
   58|       |         /* U = carry bit of T[i] */
   59|     15|         u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
  ------------------
  |  |   82|     15|#   define MP_DIGIT_BIT 60
  ------------------
   60|       |
   61|       |         /* take away carry bit from T[i] */
   62|     15|         *tmpc++ &= MP_MASK;
  ------------------
  |  |  106|     15|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     15|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   63|     15|      }
   64|       |
   65|       |      /* now copy higher words if any, that is in A+B
   66|       |       * if A or B has more digits add those in
   67|       |       */
   68|      3|      if (min != max) {
  ------------------
  |  Branch (68:11): [True: 3, False: 0]
  ------------------
   69|     15|         for (; i < max; i++) {
  ------------------
  |  Branch (69:17): [True: 12, False: 3]
  ------------------
   70|       |            /* T[i] = X[i] + U */
   71|     12|            *tmpc = x->dp[i] + u;
   72|       |
   73|       |            /* U = carry bit of T[i] */
   74|     12|            u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
  ------------------
  |  |   82|     12|#   define MP_DIGIT_BIT 60
  ------------------
   75|       |
   76|       |            /* take away carry bit from T[i] */
   77|     12|            *tmpc++ &= MP_MASK;
  ------------------
  |  |  106|     12|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     12|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   78|     12|         }
   79|      3|      }
   80|       |
   81|       |      /* add carry */
   82|      3|      *tmpc++ = u;
   83|       |
   84|       |      /* clear digits above oldused */
   85|      3|      MP_ZERO_DIGITS(tmpc, olduse - c->used);
  ------------------
  |  |   89|      3|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|      3|do {                                                    \
  |  |   91|      3|   int zd_ = (digits);                                  \
  |  |   92|      3|   mp_digit* zm_ = (mem);                               \
  |  |   93|      3|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 0, False: 3]
  |  |  ------------------
  |  |   94|      0|      *zm_++ = 0;                                       \
  |  |   95|      0|   }                                                    \
  |  |   96|      3|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 3]
  |  |  ------------------
  ------------------
   86|      3|   }
   87|       |
   88|      3|   mp_clamp(c);
   89|      3|   return MP_OKAY;
  ------------------
  |  |  161|      3|#define MP_OKAY       0   /* no error */
  ------------------
   90|      3|}

s_mp_mul_digs_fast:
   23|      1|{
   24|      1|   int      olduse, pa, ix, iz;
   25|      1|   mp_err   err;
   26|      1|   mp_digit W[MP_WARRAY];
   27|      1|   mp_word  _W;
   28|       |
   29|      1|   if (digs < 0) {
  ------------------
  |  Branch (29:8): [True: 0, False: 1]
  ------------------
   30|      0|      return MP_VAL;
  ------------------
  |  |  164|      0|#define MP_VAL        -3  /* invalid input */
  ------------------
   31|      0|   }
   32|       |
   33|       |   /* grow the destination as required */
   34|      1|   if (c->alloc < digs) {
  ------------------
  |  Branch (34:8): [True: 1, False: 0]
  ------------------
   35|      1|      if ((err = mp_grow(c, digs)) != MP_OKAY) {
  ------------------
  |  |  161|      1|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (35:11): [True: 0, False: 1]
  ------------------
   36|      0|         return err;
   37|      0|      }
   38|      1|   }
   39|       |
   40|       |   /* number of output digits to produce */
   41|      1|   pa = MP_MIN(digs, a->used + b->used);
  ------------------
  |  |  156|      1|#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (156:23): [True: 0, False: 1]
  |  |  ------------------
  ------------------
   42|       |
   43|       |   /* clear the carry */
   44|      1|   _W = 0;
   45|     11|   for (ix = 0; ix < pa; ix++) {
  ------------------
  |  Branch (45:17): [True: 10, False: 1]
  ------------------
   46|     10|      int      tx, ty;
   47|     10|      int      iy;
   48|     10|      mp_digit *tmpx, *tmpy;
   49|       |
   50|       |      /* get offsets into the two bignums */
   51|     10|      ty = MP_MIN(b->used-1, ix);
  ------------------
  |  |  156|     10|#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (156:23): [True: 5, False: 5]
  |  |  ------------------
  ------------------
   52|     10|      tx = ix - ty;
   53|       |
   54|       |      /* setup temp aliases */
   55|     10|      tmpx = a->dp + tx;
   56|     10|      tmpy = b->dp + ty;
   57|       |
   58|       |      /* this is the number of times the loop will iterrate, essentially
   59|       |         while (tx++ < a->used && ty-- >= 0) { ... }
   60|       |       */
   61|     10|      iy = MP_MIN(a->used-tx, ty+1);
  ------------------
  |  |  156|     10|#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (156:23): [True: 5, False: 5]
  |  |  ------------------
  ------------------
   62|       |
   63|       |      /* execute loop */
   64|     35|      for (iz = 0; iz < iy; ++iz) {
  ------------------
  |  Branch (64:20): [True: 25, False: 10]
  ------------------
   65|     25|         _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
   66|       |
   67|     25|      }
   68|       |
   69|       |      /* store term */
   70|     10|      W[ix] = (mp_digit)_W & MP_MASK;
  ------------------
  |  |  106|     10|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     10|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   71|       |
   72|       |      /* make next carry */
   73|     10|      _W = _W >> (mp_word)MP_DIGIT_BIT;
  ------------------
  |  |   82|     10|#   define MP_DIGIT_BIT 60
  ------------------
   74|     10|   }
   75|       |
   76|       |   /* setup dest */
   77|      1|   olduse  = c->used;
   78|      1|   c->used = pa;
   79|       |
   80|      1|   {
   81|      1|      mp_digit *tmpc;
   82|      1|      tmpc = c->dp;
   83|     11|      for (ix = 0; ix < pa; ix++) {
  ------------------
  |  Branch (83:20): [True: 10, False: 1]
  ------------------
   84|       |         /* now extract the previous digit [below the carry] */
   85|     10|         *tmpc++ = W[ix];
   86|     10|      }
   87|       |
   88|       |      /* clear unused digits [that existed in the old copy of c] */
   89|      1|      MP_ZERO_DIGITS(tmpc, olduse - ix);
  ------------------
  |  |   89|      1|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|      1|do {                                                    \
  |  |   91|      1|   int zd_ = (digits);                                  \
  |  |   92|      1|   mp_digit* zm_ = (mem);                               \
  |  |   93|      1|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 0, False: 1]
  |  |  ------------------
  |  |   94|      0|      *zm_++ = 0;                                       \
  |  |   95|      0|   }                                                    \
  |  |   96|      1|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 1]
  |  |  ------------------
  ------------------
   90|      1|   }
   91|      1|   mp_clamp(c);
   92|      1|   return MP_OKAY;
  ------------------
  |  |  161|      1|#define MP_OKAY       0   /* no error */
  ------------------
   93|      1|}

s_mp_sqr_fast:
   17|      2|{
   18|      2|   int       olduse, pa, ix, iz;
   19|      2|   mp_digit  W[MP_WARRAY], *tmpx;
   20|      2|   mp_word   W1;
   21|      2|   mp_err    err;
   22|       |
   23|       |   /* grow the destination as required */
   24|      2|   pa = a->used + a->used;
   25|      2|   if (b->alloc < pa) {
  ------------------
  |  Branch (25:8): [True: 0, False: 2]
  ------------------
   26|      0|      if ((err = mp_grow(b, pa)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (26:11): [True: 0, False: 0]
  ------------------
   27|      0|         return err;
   28|      0|      }
   29|      0|   }
   30|       |
   31|       |   /* number of output digits to produce */
   32|      2|   W1 = 0;
   33|     22|   for (ix = 0; ix < pa; ix++) {
  ------------------
  |  Branch (33:17): [True: 20, False: 2]
  ------------------
   34|     20|      int      tx, ty, iy;
   35|     20|      mp_word  _W;
   36|     20|      mp_digit *tmpy;
   37|       |
   38|       |      /* clear counter */
   39|     20|      _W = 0;
   40|       |
   41|       |      /* get offsets into the two bignums */
   42|     20|      ty = MP_MIN(a->used-1, ix);
  ------------------
  |  |  156|     20|#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (156:23): [True: 10, False: 10]
  |  |  ------------------
  ------------------
   43|     20|      tx = ix - ty;
   44|       |
   45|       |      /* setup temp aliases */
   46|     20|      tmpx = a->dp + tx;
   47|     20|      tmpy = a->dp + ty;
   48|       |
   49|       |      /* this is the number of times the loop will iterrate, essentially
   50|       |         while (tx++ < a->used && ty-- >= 0) { ... }
   51|       |       */
   52|     20|      iy = MP_MIN(a->used-tx, ty+1);
  ------------------
  |  |  156|     20|#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (156:23): [True: 10, False: 10]
  |  |  ------------------
  ------------------
   53|       |
   54|       |      /* now for squaring tx can never equal ty
   55|       |       * we halve the distance since they approach at a rate of 2x
   56|       |       * and we have to round because odd cases need to be executed
   57|       |       */
   58|     20|      iy = MP_MIN(iy, ((ty-tx)+1)>>1);
  ------------------
  |  |  156|     20|#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (156:23): [True: 0, False: 20]
  |  |  ------------------
  ------------------
   59|       |
   60|       |      /* execute loop */
   61|     40|      for (iz = 0; iz < iy; iz++) {
  ------------------
  |  Branch (61:20): [True: 20, False: 20]
  ------------------
   62|     20|         _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
   63|     20|      }
   64|       |
   65|       |      /* double the inner product and add carry */
   66|     20|      _W = _W + _W + W1;
   67|       |
   68|       |      /* even columns have the square term in them */
   69|     20|      if (((unsigned)ix & 1u) == 0u) {
  ------------------
  |  Branch (69:11): [True: 10, False: 10]
  ------------------
   70|     10|         _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1];
   71|     10|      }
   72|       |
   73|       |      /* store it */
   74|     20|      W[ix] = (mp_digit)_W & MP_MASK;
  ------------------
  |  |  106|     20|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     20|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   75|       |
   76|       |      /* make next carry */
   77|     20|      W1 = _W >> (mp_word)MP_DIGIT_BIT;
  ------------------
  |  |   82|     20|#   define MP_DIGIT_BIT 60
  ------------------
   78|     20|   }
   79|       |
   80|       |   /* setup dest */
   81|      2|   olduse  = b->used;
   82|      2|   b->used = a->used+a->used;
   83|       |
   84|      2|   {
   85|      2|      mp_digit *tmpb;
   86|      2|      tmpb = b->dp;
   87|     22|      for (ix = 0; ix < pa; ix++) {
  ------------------
  |  Branch (87:20): [True: 20, False: 2]
  ------------------
   88|     20|         *tmpb++ = W[ix] & MP_MASK;
  ------------------
  |  |  106|     20|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     20|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   89|     20|      }
   90|       |
   91|       |      /* clear unused digits [that existed in the old copy of c] */
   92|      2|      MP_ZERO_DIGITS(tmpb, olduse - ix);
  ------------------
  |  |   89|      2|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|      2|do {                                                    \
  |  |   91|      2|   int zd_ = (digits);                                  \
  |  |   92|      2|   mp_digit* zm_ = (mem);                               \
  |  |   93|      2|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 0, False: 2]
  |  |  ------------------
  |  |   94|      0|      *zm_++ = 0;                                       \
  |  |   95|      0|   }                                                    \
  |  |   96|      2|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 2]
  |  |  ------------------
  ------------------
   93|      2|   }
   94|      2|   mp_clamp(b);
   95|      2|   return MP_OKAY;
  ------------------
  |  |  161|      2|#define MP_OKAY       0   /* no error */
  ------------------
   96|      2|}

s_mp_sub:
    8|     11|{
    9|     11|   int    olduse, min, max;
   10|     11|   mp_err err;
   11|       |
   12|       |   /* find sizes */
   13|     11|   min = b->used;
   14|     11|   max = a->used;
   15|       |
   16|       |   /* init result */
   17|     11|   if (c->alloc < max) {
  ------------------
  |  Branch (17:8): [True: 0, False: 11]
  ------------------
   18|      0|      if ((err = mp_grow(c, max)) != MP_OKAY) {
  ------------------
  |  |  161|      0|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (18:11): [True: 0, False: 0]
  ------------------
   19|      0|         return err;
   20|      0|      }
   21|      0|   }
   22|     11|   olduse = c->used;
   23|     11|   c->used = max;
   24|       |
   25|     11|   {
   26|     11|      mp_digit u, *tmpa, *tmpb, *tmpc;
   27|     11|      int i;
   28|       |
   29|       |      /* alias for digit pointers */
   30|     11|      tmpa = a->dp;
   31|     11|      tmpb = b->dp;
   32|     11|      tmpc = c->dp;
   33|       |
   34|       |      /* set carry to zero */
   35|     11|      u = 0;
   36|    100|      for (i = 0; i < min; i++) {
  ------------------
  |  Branch (36:19): [True: 89, False: 11]
  ------------------
   37|       |         /* T[i] = A[i] - B[i] - U */
   38|     89|         *tmpc = (*tmpa++ - *tmpb++) - u;
   39|       |
   40|       |         /* U = carry bit of T[i]
   41|       |          * Note this saves performing an AND operation since
   42|       |          * if a carry does occur it will propagate all the way to the
   43|       |          * MSB.  As a result a single shift is enough to get the carry
   44|       |          */
   45|     89|         u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
  ------------------
  |  |  167|     89|#define MP_SIZEOF_BITS(type)    ((size_t)CHAR_BIT * sizeof(type))
  ------------------
   46|       |
   47|       |         /* Clear carry from T[i] */
   48|     89|         *tmpc++ &= MP_MASK;
  ------------------
  |  |  106|     89|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|     89|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   49|     89|      }
   50|       |
   51|       |      /* now copy higher words if any, e.g. if A has more digits than B  */
   52|     11|      for (; i < max; i++) {
  ------------------
  |  Branch (52:14): [True: 0, False: 11]
  ------------------
   53|       |         /* T[i] = A[i] - U */
   54|      0|         *tmpc = *tmpa++ - u;
   55|       |
   56|       |         /* U = carry bit of T[i] */
   57|      0|         u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
  ------------------
  |  |  167|      0|#define MP_SIZEOF_BITS(type)    ((size_t)CHAR_BIT * sizeof(type))
  ------------------
   58|       |
   59|       |         /* Clear carry from T[i] */
   60|      0|         *tmpc++ &= MP_MASK;
  ------------------
  |  |  106|      0|#define MP_MASK          ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1))
  |  |  ------------------
  |  |  |  |   82|      0|#   define MP_DIGIT_BIT 60
  |  |  ------------------
  ------------------
   61|      0|      }
   62|       |
   63|       |      /* clear digits above used (since we may not have grown result above) */
   64|     11|      MP_ZERO_DIGITS(tmpc, olduse - c->used);
  ------------------
  |  |   89|     11|#  define MP_ZERO_DIGITS(mem, digits)                   \
  |  |   90|     11|do {                                                    \
  |  |   91|     11|   int zd_ = (digits);                                  \
  |  |   92|     11|   mp_digit* zm_ = (mem);                               \
  |  |   93|     11|   while (zd_-- > 0) {                                  \
  |  |  ------------------
  |  |  |  Branch (93:11): [True: 0, False: 11]
  |  |  ------------------
  |  |   94|      0|      *zm_++ = 0;                                       \
  |  |   95|      0|   }                                                    \
  |  |   96|     11|} while (0)
  |  |  ------------------
  |  |  |  Branch (96:10): [Folded, False: 11]
  |  |  ------------------
  ------------------
   65|     11|   }
   66|       |
   67|     11|   mp_clamp(c);
   68|     11|   return MP_OKAY;
  ------------------
  |  |  161|     11|#define MP_OKAY       0   /* no error */
  ------------------
   69|     11|}

m_mp_init:
   31|    199|void m_mp_init(mp_int *mp) {
   32|       |
   33|    199|	if (mp_init(mp) != MP_OKAY) {
  ------------------
  |  |  161|    199|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (33:6): [True: 0, False: 199]
  ------------------
   34|      0|		dropbear_exit("Mem alloc error");
   35|      0|	}
   36|    199|}
m_mp_alloc_init_multi:
   56|  6.46k|{
   57|  6.46k|	mp_int** cur_arg = mp;
   58|  6.46k|	va_list args;
   59|       |
   60|  6.46k|	va_start(args, mp);        /* init args to next argument from caller */
   61|  12.9k|	while (cur_arg != NULL) {
  ------------------
  |  Branch (61:9): [True: 6.47k, False: 6.46k]
  ------------------
   62|  6.47k|		*cur_arg = m_malloc(sizeof(mp_int));
   63|  6.47k|		if (mp_init(*cur_arg) != MP_OKAY) {
  ------------------
  |  |  161|  6.47k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (63:7): [True: 0, False: 6.47k]
  ------------------
   64|      0|			dropbear_exit("Mem alloc error");
   65|      0|		}
   66|  6.47k|		cur_arg = va_arg(args, mp_int**);
   67|  6.47k|	}
   68|  6.46k|	va_end(args);
   69|  6.46k|}
hash_process_mp:
   96|  6.45k|				hash_state *hs, const mp_int *mp) {
   97|  6.45k|	buffer * buf;
   98|       |
   99|  6.45k|	buf = buf_new(512 + 20); /* max buffer is a 4096 bit key, 
  100|       |								plus header + some leeway*/
  101|  6.45k|	buf_putmpint(buf, mp);
  102|  6.45k|	hash_desc->process(hs, buf->data, buf->len);
  103|  6.45k|	buf_burn_free(buf);
  104|  6.45k|}

buf_new:
   41|   182k|buffer* buf_new(unsigned int size) {
   42|   182k|	buffer* buf;
   43|   182k|	if (size > BUF_MAX_SIZE) {
  ------------------
  |  |   35|   182k|#define BUF_MAX_SIZE 1000000000
  ------------------
  |  Branch (43:6): [True: 0, False: 182k]
  ------------------
   44|      0|		dropbear_exit("buf->size too big");
   45|      0|	}
   46|       |
   47|   182k|	buf = (buffer*)m_malloc(sizeof(buffer)+size);
   48|   182k|	buf->data = (unsigned char*)buf + sizeof(buffer);
   49|   182k|	buf->size = size;
   50|   182k|	return buf;
   51|   182k|}
buf_free:
   54|   147k|void buf_free(buffer* buf) {
   55|       |	m_free(buf);
  ------------------
  |  |   24|   147k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 147k]
  |  |  ------------------
  ------------------
   56|   147k|}
buf_burn_free:
   59|  33.5k|void buf_burn_free(buffer* buf) {
   60|  33.5k|	m_burn(buf->data, buf->size);
   61|       |	m_free(buf);
  ------------------
  |  |   24|  33.5k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 33.5k]
  |  |  ------------------
  ------------------
   62|  33.5k|}
buf_resize:
   67|  8.28k|buffer* buf_resize(buffer *buf, unsigned int newsize) {
   68|  8.28k|	if (newsize > BUF_MAX_SIZE) {
  ------------------
  |  |   35|  8.28k|#define BUF_MAX_SIZE 1000000000
  ------------------
  |  Branch (68:6): [True: 0, False: 8.28k]
  ------------------
   69|      0|		dropbear_exit("buf->size too big");
   70|      0|	}
   71|       |
   72|  8.28k|	buf = m_realloc(buf, sizeof(buffer)+newsize);
   73|  8.28k|	buf->data = (unsigned char*)buf + sizeof(buffer);
   74|  8.28k|	buf->size = newsize;
   75|  8.28k|	buf->len = MIN(newsize, buf->len);
  ------------------
  |  Branch (75:13): [True: 0, False: 8.28k]
  ------------------
   76|       |	buf->pos = MIN(newsize, buf->pos);
  ------------------
  |  Branch (76:13): [True: 0, False: 8.28k]
  ------------------
   77|  8.28k|	return buf;
   78|  8.28k|}
buf_newcopy:
   82|  11.2k|buffer* buf_newcopy(const buffer* buf) {
   83|       |	
   84|  11.2k|	buffer* ret;
   85|       |
   86|  11.2k|	ret = buf_new(buf->len);
   87|  11.2k|	ret->len = buf->len;
   88|  11.2k|	if (buf->len > 0) {
  ------------------
  |  Branch (88:6): [True: 11.2k, False: 0]
  ------------------
   89|  11.2k|		memcpy(ret->data, buf->data, buf->len);
   90|  11.2k|	}
   91|  11.2k|	return ret;
   92|  11.2k|}
buf_setlen:
   95|   268k|void buf_setlen(buffer* buf, unsigned int len) {
   96|   268k|	if (len > buf->size) {
  ------------------
  |  Branch (96:6): [True: 0, False: 268k]
  ------------------
   97|      0|		dropbear_exit("Bad buf_setlen");
   98|      0|	}
   99|   268k|	buf->len = len;
  100|       |	buf->pos = MIN(buf->pos, buf->len);
  ------------------
  |  Branch (100:13): [True: 178k, False: 90.0k]
  ------------------
  101|   268k|}
buf_incrlen:
  104|   344k|void buf_incrlen(buffer* buf, unsigned int incr) {
  105|   344k|	if (incr > BUF_MAX_INCR || buf->len + incr > buf->size) {
  ------------------
  |  |   34|   688k|#define BUF_MAX_INCR 1000000000
  ------------------
  |  Branch (105:6): [True: 0, False: 344k]
  |  Branch (105:29): [True: 0, False: 344k]
  ------------------
  106|      0|		dropbear_exit("Bad buf_incrlen");
  107|      0|	}
  108|   344k|	buf->len += incr;
  109|   344k|}
buf_setpos:
  111|  1.17M|void buf_setpos(buffer* buf, unsigned int pos) {
  112|       |
  113|  1.17M|	if (pos > buf->len) {
  ------------------
  |  Branch (113:6): [True: 0, False: 1.17M]
  ------------------
  114|      0|		dropbear_exit("Bad buf_setpos");
  115|      0|	}
  116|  1.17M|	buf->pos = pos;
  117|  1.17M|}
buf_incrwritepos:
  120|  1.14M|void buf_incrwritepos(buffer* buf, unsigned int incr) {
  121|  1.14M|	if (incr > BUF_MAX_INCR || buf->pos + incr > buf->size) {
  ------------------
  |  |   34|  2.29M|#define BUF_MAX_INCR 1000000000
  ------------------
  |  Branch (121:6): [True: 0, False: 1.14M]
  |  Branch (121:29): [True: 0, False: 1.14M]
  ------------------
  122|      0|		dropbear_exit("Bad buf_incrwritepos");
  123|      0|	}
  124|  1.14M|	buf->pos += incr;
  125|  1.14M|	if (buf->pos > buf->len) {
  ------------------
  |  Branch (125:6): [True: 845k, False: 304k]
  ------------------
  126|   845k|		buf->len = buf->pos;
  127|   845k|	}
  128|  1.14M|}
buf_incrpos:
  131|   889k|void buf_incrpos(buffer* buf, unsigned int incr) {
  132|   889k|	if (incr > BUF_MAX_INCR 
  ------------------
  |  |   34|  1.77M|#define BUF_MAX_INCR 1000000000
  ------------------
  |  Branch (132:6): [True: 10, False: 889k]
  ------------------
  133|   889k|		|| (buf->pos + incr) > buf->len) {
  ------------------
  |  Branch (133:6): [True: 102, False: 889k]
  ------------------
  134|    112|		dropbear_exit("Bad buf_incrpos");
  135|    112|	}
  136|   889k|	buf->pos += incr;
  137|   889k|}
buf_decrpos:
  140|      4|void buf_decrpos(buffer* buf, unsigned int decr) {
  141|      4|	if (decr > buf->pos) {
  ------------------
  |  Branch (141:6): [True: 0, False: 4]
  ------------------
  142|      0|		dropbear_exit("Bad buf_decrpos");
  143|      0|	}
  144|      4|	buf->pos -= decr;
  145|      4|}
buf_getbyte:
  148|   184k|unsigned char buf_getbyte(buffer* buf) {
  149|       |
  150|       |	/* This check is really just ==, but the >= allows us to check for the
  151|       |	 * bad case of pos > len, which should _never_ happen. */
  152|   184k|	if (buf->pos >= buf->len) {
  ------------------
  |  Branch (152:6): [True: 1, False: 184k]
  ------------------
  153|      1|		dropbear_exit("Bad buf_getbyte");
  154|      1|	}
  155|   184k|	return buf->data[buf->pos++];
  156|   184k|}
buf_getbool:
  159|  12.9k|unsigned char buf_getbool(buffer* buf) {
  160|       |
  161|  12.9k|	unsigned char b;
  162|  12.9k|	b = buf_getbyte(buf);
  163|  12.9k|	if (b != 0)
  ------------------
  |  Branch (163:6): [True: 5.34k, False: 7.57k]
  ------------------
  164|  5.34k|		b = 1;
  165|  12.9k|	return b;
  166|  12.9k|}
buf_putbyte:
  169|   309k|void buf_putbyte(buffer* buf, unsigned char val) {
  170|       |
  171|   309k|	if (buf->pos >= buf->len) {
  ------------------
  |  Branch (171:6): [True: 220k, False: 89.8k]
  ------------------
  172|   220k|		buf_incrlen(buf, 1);
  173|   220k|	}
  174|   309k|	buf->data[buf->pos] = val;
  175|   309k|	buf->pos++;
  176|   309k|}
buf_getptr:
  180|  1.59M|unsigned char* buf_getptr(const buffer* buf, unsigned int len) {
  181|       |
  182|  1.59M|	if (len > BUF_MAX_INCR || buf->pos + len > buf->len) {
  ------------------
  |  |   34|  3.18M|#define BUF_MAX_INCR 1000000000
  ------------------
  |  Branch (182:6): [True: 0, False: 1.59M]
  |  Branch (182:28): [True: 227, False: 1.59M]
  ------------------
  183|    227|		dropbear_exit("Bad buf_getptr");
  184|    227|	}
  185|  1.59M|	return &buf->data[buf->pos];
  186|  1.59M|}
buf_getwriteptr:
  190|  1.27M|unsigned char* buf_getwriteptr(const buffer* buf, unsigned int len) {
  191|       |
  192|  1.27M|	if (len > BUF_MAX_INCR || buf->pos + len > buf->size) {
  ------------------
  |  |   34|  2.55M|#define BUF_MAX_INCR 1000000000
  ------------------
  |  Branch (192:6): [True: 0, False: 1.27M]
  |  Branch (192:28): [True: 0, False: 1.27M]
  ------------------
  193|      0|		dropbear_exit("Bad buf_getwriteptr");
  194|      0|	}
  195|  1.27M|	return &buf->data[buf->pos];
  196|  1.27M|}
buf_getstring:
  201|  85.7k|char* buf_getstring(buffer* buf, unsigned int *retlen) {
  202|       |
  203|  85.7k|	unsigned int len;
  204|  85.7k|	char* ret;
  205|  85.7k|	void* src = NULL;
  206|  85.7k|	len = buf_getint(buf);
  207|  85.7k|	if (len > MAX_STRING_LEN) {
  ------------------
  |  |  253|  85.7k|#define MAX_STRING_LEN (MAX(MAX_CMD_LEN, 2400)) /* Sun SSH needs 2400 for algos,
  ------------------
  |  Branch (207:6): [True: 64, False: 85.6k]
  |  Branch (207:12): [True: 85.6k, Folded]
  ------------------
  208|     64|		dropbear_exit("String too long");
  209|     64|	}
  210|       |
  211|  85.6k|	if (retlen != NULL) {
  ------------------
  |  Branch (211:6): [True: 84.6k, False: 978]
  ------------------
  212|  84.6k|		*retlen = len;
  213|  84.6k|	}
  214|  85.6k|	src = buf_getptr(buf, len);
  215|  85.6k|	ret = m_malloc(len+1);
  216|  85.6k|	memcpy(ret, src, len);
  217|  85.6k|	buf_incrpos(buf, len);
  218|  85.6k|	ret[len] = '\0';
  219|       |
  220|  85.6k|	return ret;
  221|  85.7k|}
buf_getstringbuf:
  246|  6.48k|buffer * buf_getstringbuf(buffer *buf) {
  247|  6.48k|	return buf_getstringbuf_int(buf, 0);
  248|  6.48k|}
buf_eatstring:
  266|  13.6k|void buf_eatstring(buffer *buf) {
  267|       |
  268|  13.6k|	buf_incrpos( buf, buf_getint(buf) );
  269|  13.6k|}
buf_getint:
  272|   176k|unsigned int buf_getint(buffer* buf) {
  273|   176k|	unsigned int ret;
  274|       |
  275|   176k|	LOAD32H(ret, buf_getptr(buf, 4));
  ------------------
  |  |   66|   176k|#define LOAD32H(x, y)                           \
  |  |   67|   176k|do { XMEMCPY (&(x), (y), 4);                    \
  |  |  ------------------
  |  |  |  |   39|   176k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |   68|   176k|      (x) = __builtin_bswap32 ((x)); } while(0)
  |  |  ------------------
  |  |  |  Branch (68:46): [Folded, False: 176k]
  |  |  ------------------
  ------------------
  276|   176k|	buf_incrpos(buf, 4);
  277|   176k|	return ret;
  278|   176k|}
buf_putint:
  281|   508k|void buf_putint(buffer* buf, int unsigned val) {
  282|       |
  283|   508k|	STORE32H(val, buf_getwriteptr(buf, 4));
  ------------------
  |  |   62|   508k|#define STORE32H(x, y)                          \
  |  |   63|   508k|do { ulong32 __t = __builtin_bswap32 ((x));     \
  |  |   64|   508k|      XMEMCPY ((y), &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|   508k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (64:39): [Folded, False: 508k]
  |  |  ------------------
  ------------------
  284|   508k|	buf_incrwritepos(buf, 4);
  285|       |
  286|   508k|}
buf_putstring:
  289|  45.9k|void buf_putstring(buffer* buf, const char* str, unsigned int len) {
  290|       |	
  291|  45.9k|	buf_putint(buf, len);
  292|  45.9k|	buf_putbytes(buf, (const unsigned char*)str, len);
  293|       |
  294|  45.9k|}
buf_putbytes:
  303|   290k|void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len) {
  304|   290k|	memcpy(buf_getwriteptr(buf, len), bytes, len);
  305|   290k|	buf_incrwritepos(buf, len);
  306|   290k|}
buf_putmpint:
  311|  6.45k|void buf_putmpint(buffer* buf, const mp_int * mp) {
  312|  6.45k|	size_t written;
  313|  6.45k|	unsigned int len, pad = 0;
  314|  6.45k|	TRACE2(("enter buf_putmpint"))
  315|       |
  316|  6.45k|	dropbear_assert(mp != NULL);
  ------------------
  |  |   84|  6.45k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 6.45k]
  |  |  |  Branch (84:93): [Folded, False: 6.45k]
  |  |  ------------------
  ------------------
  317|       |
  318|  6.45k|	if (mp_isneg(mp)) {
  ------------------
  |  |  295|  6.45k|#define mp_isneg(a)  (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
  |  |  ------------------
  |  |  |  |  151|  6.45k|#define MP_ZPOS       0   /* positive integer */
  |  |  ------------------
  |  |               #define mp_isneg(a)  (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
  |  |  ------------------
  |  |  |  |  158|      0|#define MP_YES        1
  |  |  ------------------
  |  |               #define mp_isneg(a)  (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
  |  |  ------------------
  |  |  |  |  159|  6.45k|#define MP_NO         0
  |  |  ------------------
  |  |  |  Branch (295:22): [True: 0, False: 6.45k]
  |  |  |  Branch (295:23): [True: 0, False: 6.45k]
  |  |  ------------------
  ------------------
  319|      0|		dropbear_exit("negative bignum");
  320|      0|	}
  321|       |
  322|       |	/* zero check */
  323|  6.45k|	if (mp_iszero(mp)) {
  ------------------
  |  |  292|  6.45k|#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
  |  |  ------------------
  |  |  |  |  158|      0|#define MP_YES        1
  |  |  ------------------
  |  |               #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
  |  |  ------------------
  |  |  |  |  159|  6.45k|#define MP_NO         0
  |  |  ------------------
  |  |  |  Branch (292:22): [True: 0, False: 6.45k]
  |  |  |  Branch (292:23): [True: 0, False: 6.45k]
  |  |  ------------------
  ------------------
  324|      0|		len = 0;
  325|  6.45k|	} else {
  326|       |		/* SSH spec requires padding for mpints with the MSB set, this code
  327|       |		 * implements it */
  328|  6.45k|		len = mp_count_bits(mp);
  329|       |		/* if the top bit of MSB is set, we need to pad */
  330|  6.45k|		pad = (len%8 == 0) ? 1 : 0;
  ------------------
  |  Branch (330:9): [True: 6.45k, False: 0]
  ------------------
  331|  6.45k|		len = len / 8 + 1; /* don't worry about rounding, we need it for
  332|       |							  padding anyway when len%8 == 0 */
  333|       |
  334|  6.45k|	}
  335|       |
  336|       |	/* store the length */
  337|  6.45k|	buf_putint(buf, len);
  338|       |	
  339|       |	/* store the actual value */
  340|  6.45k|	if (len > 0) {
  ------------------
  |  Branch (340:6): [True: 6.45k, False: 0]
  ------------------
  341|  6.45k|		if (pad) {
  ------------------
  |  Branch (341:7): [True: 6.45k, False: 0]
  ------------------
  342|  6.45k|			buf_putbyte(buf, 0x00);
  343|  6.45k|		}
  344|  6.45k|		if (mp_to_ubin(mp, buf_getwriteptr(buf, len-pad), len-pad, &written) != MP_OKAY) {
  ------------------
  |  |  161|  6.45k|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (344:7): [True: 0, False: 6.45k]
  ------------------
  345|      0|			dropbear_exit("mpint error");
  346|      0|		}
  347|  6.45k|		buf_incrwritepos(buf, written);
  348|  6.45k|	}
  349|       |
  350|  6.45k|	TRACE2(("leave buf_putmpint"))
  351|  6.45k|}
buf_getmpint:
  356|    210|int buf_getmpint(buffer* buf, mp_int* mp) {
  357|       |
  358|    210|	unsigned int len;
  359|    210|	len = buf_getint(buf);
  360|       |	
  361|    210|	if (len == 0) {
  ------------------
  |  Branch (361:6): [True: 10, False: 200]
  ------------------
  362|     10|		mp_zero(mp);
  363|     10|		return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|     10|#define DROPBEAR_SUCCESS 0
  ------------------
  364|     10|	}
  365|       |
  366|    200|	if (len > BUF_MAX_MPINT) {
  ------------------
  |  |   38|    200|#define BUF_MAX_MPINT (8240 / 8)
  ------------------
  |  Branch (366:6): [True: 53, False: 147]
  ------------------
  367|     53|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|     53|#define DROPBEAR_FAILURE -1
  ------------------
  368|     53|	}
  369|       |
  370|       |	/* check for negative */
  371|    147|	if (*buf_getptr(buf, 1) & (1 << (CHAR_BIT-1))) {
  ------------------
  |  Branch (371:6): [True: 10, False: 137]
  ------------------
  372|     10|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|     10|#define DROPBEAR_FAILURE -1
  ------------------
  373|     10|	}
  374|       |
  375|    137|	if (mp_from_ubin(mp, buf_getptr(buf, len), len) != MP_OKAY) {
  ------------------
  |  |  161|    137|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (375:6): [True: 0, False: 137]
  ------------------
  376|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  377|      0|	}
  378|       |
  379|    137|	buf_incrpos(buf, len);
  380|    137|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|    137|#define DROPBEAR_SUCCESS 0
  ------------------
  381|    137|}
buffer.c:buf_getstringbuf_int:
  224|  6.48k|static buffer * buf_getstringbuf_int(buffer *buf, int incllen) {
  225|  6.48k|	buffer *ret = NULL;
  226|  6.48k|	unsigned int len = buf_getint(buf);
  227|  6.48k|	int extra = 0;
  228|  6.48k|	if (len > MAX_STRING_LEN) {
  ------------------
  |  |  253|  6.48k|#define MAX_STRING_LEN (MAX(MAX_CMD_LEN, 2400)) /* Sun SSH needs 2400 for algos,
  ------------------
  |  Branch (228:6): [True: 35, False: 6.45k]
  |  Branch (228:12): [True: 6.48k, Folded]
  ------------------
  229|     35|		dropbear_exit("String too long");
  230|     35|	}
  231|  6.45k|	if (incllen) {
  ------------------
  |  Branch (231:6): [True: 0, False: 6.45k]
  ------------------
  232|      0|		extra = 4;
  233|      0|	}
  234|  6.45k|	ret = buf_new(len+extra);
  235|  6.45k|	if (incllen) {
  ------------------
  |  Branch (235:6): [True: 0, False: 6.45k]
  ------------------
  236|      0|		buf_putint(ret, len);
  237|      0|	}
  238|  6.45k|	memcpy(buf_getwriteptr(ret, len), buf_getptr(buf, len), len);
  239|  6.45k|	buf_incrpos(buf, len);
  240|  6.45k|	buf_incrlen(ret, len);
  241|  6.45k|	buf_setpos(ret, 0);
  242|  6.45k|	return ret;
  243|  6.48k|}

chachapoly.c:dropbear_chachapoly_start:
   48|    438|			int UNUSED(num_rounds), dropbear_chachapoly_state *state) {
   49|    438|	int err;
   50|       |
   51|    438|	TRACE2(("enter dropbear_chachapoly_start"))
   52|       |
   53|    438|	if (keylen != CHACHA20_KEY_LEN*2) {
  ------------------
  |  |   33|    438|#define CHACHA20_KEY_LEN 32
  ------------------
  |  Branch (53:6): [True: 0, False: 438]
  ------------------
   54|      0|		return CRYPT_ERROR;
   55|      0|	}
   56|       |
   57|    438|	if ((err = chacha_setup(&state->chacha, key,
  ------------------
  |  Branch (57:6): [True: 0, False: 438]
  ------------------
   58|    438|				CHACHA20_KEY_LEN, 20)) != CRYPT_OK) {
  ------------------
  |  |   33|    438|#define CHACHA20_KEY_LEN 32
  ------------------
   59|      0|		return err;
   60|      0|	}
   61|       |
   62|    438|	if ((err = chacha_setup(&state->header, key + CHACHA20_KEY_LEN,
  ------------------
  |  |   33|    438|#define CHACHA20_KEY_LEN 32
  ------------------
  |  Branch (62:6): [True: 0, False: 438]
  ------------------
   63|    438|				CHACHA20_KEY_LEN, 20) != CRYPT_OK)) {
  ------------------
  |  |   33|    438|#define CHACHA20_KEY_LEN 32
  ------------------
   64|      0|		return err;
   65|      0|	}
   66|       |
   67|    438|	TRACE2(("leave dropbear_chachapoly_start"))
   68|    438|	return CRYPT_OK;
   69|    438|}
chachapoly.c:dropbear_chachapoly_crypt:
   74|  27.8k|			dropbear_chachapoly_state *state, int direction) {
   75|  27.8k|	poly1305_state poly;
   76|  27.8k|	unsigned char seqbuf[8], key[POLY1305_KEY_LEN], tag[POLY1305_TAG_LEN];
   77|  27.8k|	int err;
   78|       |
   79|  27.8k|	TRACE2(("enter dropbear_chachapoly_crypt"))
   80|       |
   81|  27.8k|	if (len < 4 || taglen != POLY1305_TAG_LEN) {
  ------------------
  |  |   36|  27.8k|#define POLY1305_TAG_LEN 16
  ------------------
  |  Branch (81:6): [True: 0, False: 27.8k]
  |  Branch (81:17): [True: 0, False: 27.8k]
  ------------------
   82|      0|		return CRYPT_ERROR;
   83|      0|	}
   84|       |
   85|  27.8k|	STORE64H((uint64_t)seq, seqbuf);
  ------------------
  |  |  101|  27.8k|#define STORE64H(x, y)                          \
  |  |  102|  27.8k|do { ulong64 __t = __builtin_bswap64 ((x));     \
  |  |  103|  27.8k|      XMEMCPY ((y), &__t, 8); } while(0)
  |  |  ------------------
  |  |  |  |   39|  27.8k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (103:39): [Folded, False: 27.8k]
  |  |  ------------------
  ------------------
   86|  27.8k|	chacha_ivctr64(&state->chacha, seqbuf, sizeof(seqbuf), 0);
   87|  27.8k|	if ((err = chacha_keystream(&state->chacha, key, sizeof(key))) != CRYPT_OK) {
  ------------------
  |  Branch (87:6): [True: 0, False: 27.8k]
  ------------------
   88|      0|		return err;
   89|      0|	}
   90|       |
   91|  27.8k|	poly1305_init(&poly, key, sizeof(key));
   92|  27.8k|	if (direction == LTC_DECRYPT) {
  ------------------
  |  |   70|  27.8k|#define LTC_DECRYPT 1
  ------------------
  |  Branch (92:6): [True: 0, False: 27.8k]
  ------------------
   93|      0|		poly1305_process(&poly, in, len);
   94|      0|		poly1305_done(&poly, tag, &taglen);
   95|      0|		if (constant_time_memcmp(in + len, tag, taglen) != 0) {
  ------------------
  |  Branch (95:7): [True: 0, False: 0]
  ------------------
   96|      0|			return CRYPT_ERROR;
   97|      0|		}
   98|      0|	}
   99|       |
  100|  27.8k|	chacha_ivctr64(&state->header, seqbuf, sizeof(seqbuf), 0);
  101|  27.8k|	if ((err = chacha_crypt(&state->header, in, 4, out)) != CRYPT_OK) {
  ------------------
  |  Branch (101:6): [True: 0, False: 27.8k]
  ------------------
  102|      0|		return err;
  103|      0|	}
  104|       |
  105|  27.8k|	chacha_ivctr64(&state->chacha, seqbuf, sizeof(seqbuf), 1);
  106|  27.8k|	if ((err = chacha_crypt(&state->chacha, in + 4, len - 4, out + 4)) != CRYPT_OK) {
  ------------------
  |  Branch (106:6): [True: 0, False: 27.8k]
  ------------------
  107|      0|		return err;
  108|      0|	}
  109|       |
  110|  27.8k|	if (direction == LTC_ENCRYPT) {
  ------------------
  |  |   68|  27.8k|#define LTC_ENCRYPT 0
  ------------------
  |  Branch (110:6): [True: 27.8k, False: 0]
  ------------------
  111|  27.8k|		poly1305_process(&poly, out, len);
  112|  27.8k|		poly1305_done(&poly, out + len, &taglen);
  113|  27.8k|	}
  114|       |
  115|  27.8k|	TRACE2(("leave dropbear_chachapoly_crypt"))
  116|  27.8k|	return CRYPT_OK;
  117|  27.8k|}

cbuf_new:
   31|  3.87k|circbuffer * cbuf_new(unsigned int size) {
   32|       |
   33|  3.87k|	circbuffer *cbuf = NULL;
   34|       |
   35|  3.87k|	if (size > MAX_CBUF_SIZE) {
  ------------------
  |  |   29|  3.87k|#define MAX_CBUF_SIZE 100000000
  ------------------
  |  Branch (35:6): [True: 0, False: 3.87k]
  ------------------
   36|      0|		dropbear_exit("Bad cbuf size");
   37|      0|	}
   38|       |
   39|  3.87k|	cbuf = (circbuffer*)m_malloc(sizeof(circbuffer));
   40|       |	/* data is malloced on first write */
   41|  3.87k|	cbuf->data = NULL;
   42|  3.87k|	cbuf->used = 0;
   43|  3.87k|	cbuf->readpos = 0;
   44|  3.87k|	cbuf->writepos = 0;
   45|  3.87k|	cbuf->size = size;
   46|       |
   47|  3.87k|	return cbuf;
   48|  3.87k|}
cbuf_free:
   50|  3.87k|void cbuf_free(circbuffer * cbuf) {
   51|       |
   52|  3.87k|	if (cbuf->data) {
  ------------------
  |  Branch (52:6): [True: 0, False: 3.87k]
  ------------------
   53|      0|		m_burn(cbuf->data, cbuf->size);
   54|      0|		m_free(cbuf->data);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
   55|      0|	}
   56|       |	m_free(cbuf);
  ------------------
  |  |   24|  3.87k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 3.87k]
  |  |  ------------------
  ------------------
   57|  3.87k|}
cbuf_getused:
   59|   106k|unsigned int cbuf_getused(const circbuffer * cbuf) {
   60|       |
   61|   106k|	return cbuf->used;
   62|       |
   63|   106k|}
cbuf_getavail:
   65|    111|unsigned int cbuf_getavail(const circbuffer * cbuf) {
   66|       |
   67|    111|	return cbuf->size - cbuf->used;
   68|       |
   69|    111|}
cbuf_readptrs:
   91|     18|	unsigned char **p2, unsigned int *len2) {
   92|     18|	*p1 = &cbuf->data[cbuf->readpos];
   93|     18|	*len1 = MIN(cbuf->used, cbuf->size - cbuf->readpos);
  ------------------
  |  Branch (93:10): [True: 18, False: 0]
  ------------------
   94|       |
   95|     18|	if (*len1 < cbuf->used) {
  ------------------
  |  Branch (95:6): [True: 0, False: 18]
  ------------------
   96|      0|		*p2 = cbuf->data;
   97|      0|		*len2 = cbuf->used - *len1;
   98|     18|	} else {
   99|       |		*p2 = NULL;
  100|     18|		*len2 = 0;
  101|     18|	}
  102|     18|}

buf_put_algolist_all:
  361|  62.5k|void buf_put_algolist_all(buffer * buf, const algo_type localalgos[], int useall) {
  362|  62.5k|	unsigned int i, len;
  363|  62.5k|	unsigned int donefirst = 0;
  364|  62.5k|	unsigned int startpos;
  365|       |
  366|  62.5k|	startpos = buf->pos;
  367|       |	/* Placeholder for length */
  368|  62.5k|	buf_putint(buf, 0); 
  369|   312k|	for (i = 0; localalgos[i].name != NULL; i++) {
  ------------------
  |  Branch (369:14): [True: 250k, False: 62.5k]
  ------------------
  370|   250k|		if (localalgos[i].usable || useall) {
  ------------------
  |  Branch (370:7): [True: 178k, False: 71.9k]
  |  Branch (370:31): [True: 72, False: 71.8k]
  ------------------
  371|   178k|			if (donefirst) {
  ------------------
  |  Branch (371:8): [True: 115k, False: 62.5k]
  ------------------
  372|   115k|				buf_putbyte(buf, ',');
  373|   115k|			}
  374|   178k|			donefirst = 1;
  375|   178k|			len = strlen(localalgos[i].name);
  376|   178k|			buf_putbytes(buf, (const unsigned char *) localalgos[i].name, len);
  377|   178k|		}
  378|   250k|	}
  379|       |	/* Fill out the length */
  380|  62.5k|	len = buf->pos - startpos - 4;
  381|  62.5k|	buf_setpos(buf, startpos);
  382|  62.5k|	buf_putint(buf, len);
  383|  62.5k|	TRACE(("algolist add %d '%.*s'", len, len, buf_getptr(buf, len)))
  384|  62.5k|	buf_incrwritepos(buf, len);
  385|  62.5k|}
buf_put_algolist:
  387|  62.5k|void buf_put_algolist(buffer * buf, const algo_type localalgos[]) {
  388|  62.5k|	buf_put_algolist_all(buf, localalgos, 0);
  389|  62.5k|}
buf_has_algo:
  433|  15.2k|int buf_has_algo(buffer *buf, const char *algo) {
  434|  15.2k|	unsigned char* algolist = NULL;
  435|  15.2k|	unsigned int orig_pos = buf->pos;
  436|  15.2k|	unsigned int len, remotecount, i;
  437|  15.2k|	const char *remotenames[MAX_PROPOSED_ALGO];
  438|  15.2k|	int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|  15.2k|#define DROPBEAR_FAILURE -1
  ------------------
  439|       |
  440|  15.2k|	algolist = buf_getstring(buf, &len);
  441|  15.2k|	remotecount = MAX_PROPOSED_ALGO;
  ------------------
  |  |  237|  15.2k|#define MAX_PROPOSED_ALGO 50
  ------------------
  442|  15.2k|	get_algolist(algolist, len, remotenames, &remotecount);
  443|  45.5k|	for (i = 0; i < remotecount; i++)
  ------------------
  |  Branch (443:14): [True: 30.2k, False: 15.2k]
  ------------------
  444|  30.2k|	{
  445|  30.2k|		if (strcmp(remotenames[i], algo) == 0) {
  ------------------
  |  Branch (445:7): [True: 24, False: 30.2k]
  ------------------
  446|     24|			ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|     24|#define DROPBEAR_SUCCESS 0
  ------------------
  447|     24|			break;
  448|     24|		}
  449|  30.2k|	}
  450|  15.2k|	if (algolist) {
  ------------------
  |  Branch (450:6): [True: 15.2k, False: 63]
  ------------------
  451|       |		m_free(algolist);
  ------------------
  |  |   24|  15.2k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 15.2k]
  |  |  ------------------
  ------------------
  452|  15.2k|	}
  453|  15.2k|	buf_setpos(buf, orig_pos);
  454|  15.2k|	return ret;
  455|  15.2k|}
buf_match_algo:
  473|  55.7k|		int kexguess2, int *goodguess) {
  474|  55.7k|	char * algolist = NULL;
  475|  55.7k|	const char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO];
  476|  55.7k|	unsigned int len;
  477|  55.7k|	unsigned int remotecount, localcount, clicount, servcount, i, j;
  478|  55.7k|	algo_type * ret = NULL;
  479|  55.7k|	const char **clinames, **servnames;
  480|       |
  481|  55.7k|	if (goodguess) {
  ------------------
  |  Branch (481:6): [True: 14.2k, False: 41.5k]
  ------------------
  482|  14.2k|		*goodguess = 0;
  483|  14.2k|	}
  484|       |
  485|       |	/* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */
  486|  55.7k|	algolist = buf_getstring(buf, &len);
  487|  55.7k|	DEBUG3(("buf_match_algo: %s", algolist))
  488|  55.7k|	remotecount = MAX_PROPOSED_ALGO;
  ------------------
  |  |  237|  55.7k|#define MAX_PROPOSED_ALGO 50
  ------------------
  489|  55.7k|	get_algolist(algolist, len, remotenames, &remotecount);
  490|       |
  491|   281k|	for (i = 0; localalgos[i].name != NULL; i++) {
  ------------------
  |  Branch (491:14): [True: 225k, False: 55.7k]
  ------------------
  492|   225k|		if (localalgos[i].usable) {
  ------------------
  |  Branch (492:7): [True: 156k, False: 69.2k]
  ------------------
  493|   156k|			localnames[i] = localalgos[i].name;
  494|   156k|		} else {
  495|  69.2k|			localnames[i] = NULL;
  496|  69.2k|		}
  497|   225k|	}
  498|  55.7k|	localcount = i;
  499|       |
  500|  55.7k|	if (IS_DROPBEAR_SERVER) {
  ------------------
  |  |  381|  55.7k|#define IS_DROPBEAR_SERVER (ses.isserver == 1)
  |  |  ------------------
  |  |  |  Branch (381:28): [True: 55.6k, False: 47]
  |  |  ------------------
  ------------------
  501|  55.6k|		clinames = remotenames;
  502|  55.6k|		clicount = remotecount;
  503|  55.6k|		servnames = localnames;
  504|  55.6k|		servcount = localcount;
  505|  55.6k|	} else {
  506|     47|		clinames = localnames;
  507|     47|		clicount = localcount;
  508|     47|		servnames = remotenames;
  509|     47|		servcount = remotecount;
  510|     47|	}
  511|       |
  512|       |	/* iterate and find the first match */
  513|  59.7k|	for (i = 0; i < clicount; i++) {
  ------------------
  |  Branch (513:14): [True: 58.6k, False: 1.18k]
  ------------------
  514|   197k|		for (j = 0; j < servcount; j++) {
  ------------------
  |  Branch (514:15): [True: 193k, False: 4.07k]
  ------------------
  515|   193k|			if (!(servnames[j] && clinames[i])) {
  ------------------
  |  Branch (515:10): [True: 133k, False: 59.5k]
  |  Branch (515:26): [True: 133k, False: 0]
  ------------------
  516|       |				/* unusable algos are NULL */
  517|  59.5k|				continue;
  518|  59.5k|			}
  519|   133k|			if (strcmp(servnames[j], clinames[i]) == 0) {
  ------------------
  |  Branch (519:8): [True: 54.5k, False: 79.2k]
  ------------------
  520|       |				/* set if it was a good guess */
  521|  54.5k|				if (goodguess != NULL) {
  ------------------
  |  Branch (521:9): [True: 13.9k, False: 40.5k]
  ------------------
  522|  13.9k|					if (kexguess2) {
  ------------------
  |  Branch (522:10): [True: 10, False: 13.9k]
  ------------------
  523|     10|						if (i == 0) {
  ------------------
  |  Branch (523:11): [True: 3, False: 7]
  ------------------
  524|      3|							*goodguess = 1;
  525|      3|						}
  526|  13.9k|					} else {
  527|  13.9k|						if (i == 0 && j == 0) {
  ------------------
  |  Branch (527:11): [True: 13.5k, False: 370]
  |  Branch (527:21): [True: 28, False: 13.5k]
  ------------------
  528|     28|							*goodguess = 1;
  529|     28|						}
  530|  13.9k|					}
  531|  13.9k|				}
  532|       |				/* set the algo to return */
  533|  54.5k|				if (IS_DROPBEAR_SERVER) {
  ------------------
  |  |  381|  54.5k|#define IS_DROPBEAR_SERVER (ses.isserver == 1)
  |  |  ------------------
  |  |  |  Branch (381:28): [True: 54.5k, False: 0]
  |  |  ------------------
  ------------------
  534|  54.5k|					ret = &localalgos[j];
  535|  54.5k|				} else {
  536|      0|					ret = &localalgos[i];
  537|      0|				}
  538|  54.5k|				goto out;
  539|  54.5k|			}
  540|   133k|		}
  541|  58.6k|	}
  542|       |
  543|  55.6k|out:
  544|       |	m_free(algolist);
  ------------------
  |  |   24|  55.6k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 55.6k]
  |  |  ------------------
  ------------------
  545|  55.6k|	return ret;
  546|  55.7k|}
common-algo.c:void_start:
   52|  6.45k|			int UNUSED(keylen), int UNUSED(num_rounds), void* UNUSED(cipher_state)) {
   53|  6.45k|	return CRYPT_OK;
   54|  6.45k|}
common-algo.c:void_cipher:
   43|  95.1k|		unsigned long len, void* UNUSED(cipher_state)) {
   44|  95.1k|	if (in != out) {
  ------------------
  |  Branch (44:6): [True: 0, False: 95.1k]
  ------------------
   45|      0|		memmove(out, in, len);
   46|      0|	}
   47|  95.1k|	return CRYPT_OK;
   48|  95.1k|}
common-algo.c:dropbear_big_endian_ctr_start:
   93|  6.01k|		int num_rounds, symmetric_CTR *ctr) {
   94|  6.01k|	return ctr_start(cipher, IV, key, keylen, num_rounds, CTR_COUNTER_BIG_ENDIAN, ctr);
  ------------------
  |  |  860|  6.01k|#define CTR_COUNTER_BIG_ENDIAN       0x1000
  ------------------
   95|  6.01k|}
common-algo.c:get_algolist:
  396|  70.8k|				const char* *ret_list, unsigned int *ret_count) {
  397|  70.8k|	unsigned int max_count = *ret_count;
  398|  70.8k|	unsigned int i;
  399|       |
  400|  70.8k|	if (*ret_count == 0) {
  ------------------
  |  Branch (400:6): [True: 0, False: 70.8k]
  ------------------
  401|      0|		return;
  402|      0|	}
  403|  70.8k|	if (algolist_len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
  ------------------
  |  |  237|  70.8k|#define MAX_PROPOSED_ALGO 50
  ------------------
              	if (algolist_len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
  ------------------
  |  |  233|  70.8k|#define MAX_NAME_LEN 64 /* maximum length of a protocol name, isn't
  ------------------
  |  Branch (403:6): [True: 8, False: 70.8k]
  ------------------
  404|      8|		*ret_count = 0;
  405|      8|	}
  406|       |
  407|       |	/* ret_list will contain a list of the strings parsed out.
  408|       |	   We will have at least one string (even if it's just "") */
  409|  70.8k|	ret_list[0] = algolist;
  410|  70.8k|	*ret_count = 1;
  411|   978k|	for (i = 0; i < algolist_len; i++) {
  ------------------
  |  Branch (411:14): [True: 907k, False: 70.7k]
  ------------------
  412|   907k|		if (algolist[i] == '\0') {
  ------------------
  |  Branch (412:7): [True: 132, False: 907k]
  ------------------
  413|       |			/* someone is trying something strange */
  414|    132|			*ret_count = 0;
  415|    132|			return;
  416|    132|		}
  417|       |
  418|   907k|		if (algolist[i] == ',') {
  ------------------
  |  Branch (418:7): [True: 24.2k, False: 883k]
  ------------------
  419|  24.2k|			if (*ret_count >= max_count) {
  ------------------
  |  Branch (419:8): [True: 6, False: 24.2k]
  ------------------
  420|      6|				dropbear_exit("Too many remote algorithms");
  421|      0|				*ret_count = 0;
  422|      0|				return;
  423|      6|			}
  424|  24.2k|			algolist[i] = '\0';
  425|  24.2k|			ret_list[*ret_count] = &algolist[i+1];
  426|  24.2k|			(*ret_count)++;
  427|  24.2k|		}
  428|   907k|	}
  429|  70.8k|}

chaninitialise:
   70|  4.58k|void chaninitialise(const struct ChanType *chantypes[]) {
   71|       |
   72|       |	/* may as well create space for a single channel */
   73|  4.58k|	ses.channels = (struct Channel**)m_malloc(sizeof(struct Channel*));
   74|  4.58k|	ses.chansize = 1;
   75|  4.58k|	ses.channels[0] = NULL;
   76|  4.58k|	ses.chancount = 0;
   77|       |
   78|  4.58k|	ses.chantypes = chantypes;
   79|       |
   80|  4.58k|#if DROPBEAR_LISTENERS
   81|  4.58k|	listeners_initialise();
   82|  4.58k|#endif
   83|       |
   84|  4.58k|}
chancleanup:
   87|  4.58k|void chancleanup() {
   88|       |
   89|  4.58k|	unsigned int i;
   90|       |
   91|  4.58k|	TRACE(("enter chancleanup"))
   92|  11.1k|	for (i = 0; i < ses.chansize; i++) {
  ------------------
  |  Branch (92:14): [True: 6.60k, False: 4.58k]
  ------------------
   93|  6.60k|		if (ses.channels[i] != NULL) {
  ------------------
  |  Branch (93:7): [True: 3.01k, False: 3.59k]
  ------------------
   94|  3.01k|			TRACE(("channel %d closing", i))
   95|  3.01k|			remove_channel(ses.channels[i]);
   96|  3.01k|		}
   97|  6.60k|	}
   98|       |	m_free(ses.channels);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
   99|  4.58k|	TRACE(("leave chancleanup"))
  100|  4.58k|}
getchannel:
  194|  5.35k|struct Channel* getchannel() {
  195|       |	return getchannel_msg(NULL);
  196|  5.35k|}
channelio:
  199|   298k|void channelio(const fd_set *readfds, const fd_set *writefds) {
  200|       |
  201|       |	/* Listeners such as TCP, X11, agent-auth */
  202|   298k|	struct Channel *channel;
  203|   298k|	unsigned int i;
  204|       |
  205|       |	/* foreach channel */
  206|  1.25M|	for (i = 0; i < ses.chansize; i++) {
  ------------------
  |  Branch (206:14): [True: 956k, False: 298k]
  ------------------
  207|       |		/* Close checking only needs to occur for channels that had IO events */
  208|   956k|		int do_check_close = 0;
  209|       |
  210|   956k|		channel = ses.channels[i];
  211|   956k|		if (channel == NULL) {
  ------------------
  |  Branch (211:7): [True: 261k, False: 694k]
  ------------------
  212|       |			/* only process in-use channels */
  213|   261k|			continue;
  214|   261k|		}
  215|       |
  216|       |		/* read data and send it over the wire */
  217|   694k|		if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) {
  ------------------
  |  Branch (217:7): [True: 116k, False: 578k]
  |  Branch (217:31): [True: 30.4k, False: 85.7k]
  ------------------
  218|  30.4k|			TRACE(("send normal readfd"))
  219|  30.4k|			send_msg_channel_data(channel, 0);
  220|  30.4k|			do_check_close = 1;
  221|  30.4k|		}
  222|       |
  223|       |		/* read stderr data and send it over the wire */
  224|   694k|		if (ERRFD_IS_READ(channel) && channel->errfd >= 0 
  ------------------
  |  |   59|  1.38M|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (59:32): [True: 694k, False: 3]
  |  |  ------------------
  ------------------
  |  Branch (224:33): [True: 114k, False: 580k]
  ------------------
  225|   694k|			&& FD_ISSET(channel->errfd, readfds)) {
  ------------------
  |  Branch (225:7): [True: 30.5k, False: 83.6k]
  ------------------
  226|  30.5k|				TRACE(("send normal errfd"))
  227|  30.5k|				send_msg_channel_data(channel, 1);
  228|  30.5k|			do_check_close = 1;
  229|  30.5k|		}
  230|       |
  231|       |		/* write to program/pipe stdin */
  232|   694k|		if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
  ------------------
  |  Branch (232:7): [True: 106k, False: 588k]
  |  Branch (232:32): [True: 0, False: 106k]
  ------------------
  233|      0|			writechannel(channel, channel->writefd, channel->writebuf, NULL, NULL);
  234|      0|			do_check_close = 1;
  235|      0|		}
  236|       |		
  237|       |		/* stderr for client mode */
  238|   694k|		if (ERRFD_IS_WRITE(channel)
  ------------------
  |  |   60|  1.38M|#define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel))
  |  |  ------------------
  |  |  |  |   59|   694k|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (60:33): [True: 0, False: 694k]
  |  |  ------------------
  ------------------
  239|   694k|				&& channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
  ------------------
  |  Branch (239:8): [True: 0, False: 0]
  |  Branch (239:31): [True: 0, False: 0]
  ------------------
  240|      0|			writechannel(channel, channel->errfd, channel->extrabuf, NULL, NULL);
  241|      0|			do_check_close = 1;
  242|      0|		}
  243|       |
  244|   694k|		if (ses.channel_signal_pending) {
  ------------------
  |  Branch (244:7): [True: 0, False: 694k]
  ------------------
  245|       |			/* SIGCHLD can change channel state for server sessions */
  246|      0|			do_check_close = 1;
  247|      0|		}
  248|       |	
  249|       |		/* handle any channel closing etc */
  250|   694k|		if (do_check_close) {
  ------------------
  |  Branch (250:7): [True: 54.0k, False: 640k]
  ------------------
  251|  54.0k|			check_close(channel);
  252|  54.0k|		}
  253|   694k|	}
  254|       |
  255|   298k|#if DROPBEAR_LISTENERS
  256|   298k|	handle_listeners(readfds);
  257|   298k|#endif
  258|   298k|}
channel_connect_done:
  348|    137|void channel_connect_done(int result, int sock, void* user_data, const char* errstring) {
  349|    137|	struct Channel *channel = user_data;
  350|       |
  351|    137|	TRACE(("enter channel_connect_done"))
  352|       |
  353|    137|	if (result == DROPBEAR_SUCCESS)
  ------------------
  |  |  111|    137|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (353:6): [True: 0, False: 137]
  ------------------
  354|      0|	{
  355|      0|		channel->readfd = channel->writefd = sock;
  356|      0|		channel->bidir_fd = 1;
  357|      0|		channel->conn_pending = NULL;
  358|      0|		send_msg_channel_open_confirmation(channel, channel->recvwindow,
  359|      0|				channel->recvmaxpacket);
  360|      0|		TRACE(("leave channel_connect_done: success"))
  361|      0|	}
  362|    137|	else
  363|    137|	{
  364|    137|		send_msg_channel_open_failure(channel->remotechan,
  365|    137|				SSH_OPEN_CONNECT_FAILED, errstring, "");
  ------------------
  |  |   34|    137|#define SSH_OPEN_CONNECT_FAILED                 2
  ------------------
  366|    137|		remove_channel(channel);
  367|    137|		TRACE(("leave check_in_progress: fail. internal errstring: %s", errstring))
  368|    137|	}
  369|    137|}
setchannelfds:
  542|   302k|void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads) {
  543|       |	
  544|   302k|	unsigned int i;
  545|   302k|	struct Channel * channel;
  546|       |	
  547|  1.26M|	for (i = 0; i < ses.chansize; i++) {
  ------------------
  |  Branch (547:14): [True: 960k, False: 302k]
  ------------------
  548|       |
  549|   960k|		channel = ses.channels[i];
  550|   960k|		if (channel == NULL) {
  ------------------
  |  Branch (550:7): [True: 266k, False: 694k]
  ------------------
  551|   266k|			continue;
  552|   266k|		}
  553|       |
  554|       |		/* Stuff to put over the wire. 
  555|       |		Avoid queueing data to send if we're in the middle of a 
  556|       |		key re-exchange (!dataallowed), but still read from the 
  557|       |		FD if there's the possibility of "~."" to kill an 
  558|       |		interactive session (the read_mangler) */
  559|   694k|		if (channel->transwindow > 0
  ------------------
  |  Branch (559:7): [True: 501k, False: 193k]
  ------------------
  560|   501k|		   && ((ses.dataallowed && allow_reads) || channel->read_mangler)) {
  ------------------
  |  Branch (560:11): [True: 486k, False: 14.5k]
  |  Branch (560:30): [True: 470k, False: 16.4k]
  |  Branch (560:46): [True: 0, False: 30.9k]
  ------------------
  561|       |
  562|   470k|			if (channel->readfd >= 0) {
  ------------------
  |  Branch (562:8): [True: 85.2k, False: 384k]
  ------------------
  563|  85.2k|				FD_SET(channel->readfd, readfds);
  564|  85.2k|			}
  565|       |			
  566|   470k|			if (ERRFD_IS_READ(channel) && channel->errfd >= 0) {
  ------------------
  |  |   59|   940k|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (59:32): [True: 470k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (566:34): [True: 83.9k, False: 386k]
  ------------------
  567|  83.9k|					FD_SET(channel->errfd, readfds);
  568|  83.9k|			}
  569|   470k|		}
  570|       |
  571|       |		/* Stuff from the wire */
  572|   694k|		if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) {
  ------------------
  |  Branch (572:7): [True: 106k, False: 588k]
  |  Branch (572:32): [True: 0, False: 106k]
  ------------------
  573|      0|				FD_SET(channel->writefd, writefds);
  574|      0|		}
  575|       |
  576|   694k|		if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0 
  ------------------
  |  |   60|  1.38M|#define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel))
  |  |  ------------------
  |  |  |  |   59|   694k|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (60:33): [True: 0, False: 694k]
  |  |  ------------------
  ------------------
  |  Branch (576:34): [True: 0, False: 0]
  ------------------
  577|      0|				&& cbuf_getused(channel->extrabuf) > 0) {
  ------------------
  |  Branch (577:8): [True: 0, False: 0]
  ------------------
  578|      0|				FD_SET(channel->errfd, writefds);
  579|      0|		}
  580|       |
  581|   694k|	} /* foreach channel */
  582|       |
  583|   302k|#if DROPBEAR_LISTENERS
  584|   302k|	set_listener_fds(readfds);
  585|   302k|#endif
  586|       |
  587|   302k|}
recv_msg_channel_eof:
  592|    747|void recv_msg_channel_eof() {
  593|       |
  594|    747|	struct Channel * channel;
  595|       |
  596|    747|	TRACE(("enter recv_msg_channel_eof"))
  597|       |
  598|    747|	channel = getchannel_msg("EOF");
  599|       |
  600|    747|	channel->recv_eof = 1;
  601|       |
  602|    747|	check_close(channel);
  603|    747|	TRACE(("leave recv_msg_channel_eof"))
  604|    747|}
recv_msg_channel_close:
  608|    824|void recv_msg_channel_close() {
  609|       |
  610|    824|	struct Channel * channel;
  611|       |
  612|    824|	TRACE(("enter recv_msg_channel_close"))
  613|       |
  614|    824|	channel = getchannel_msg("Close");
  615|       |
  616|    824|	channel->recv_eof = 1;
  617|    824|	channel->recv_close = 1;
  618|       |
  619|    824|	check_close(channel);
  620|    824|	TRACE(("leave recv_msg_channel_close"))
  621|    824|}
recv_msg_channel_request:
  669|  4.77k|void recv_msg_channel_request() {
  670|       |
  671|  4.77k|	struct Channel *channel;
  672|       |
  673|  4.77k|	channel = getchannel();
  674|       |
  675|  4.77k|	TRACE(("enter recv_msg_channel_request %p", (void*)channel))
  676|       |
  677|  4.77k|	if (channel->type->reqhandler) {
  ------------------
  |  Branch (677:6): [True: 4.72k, False: 51]
  ------------------
  678|  4.72k|		channel->type->reqhandler(channel);
  679|  4.72k|	} else {
  680|     51|		int wantreply;
  681|     51|		buf_eatstring(ses.payload);
  682|     51|		wantreply = buf_getbool(ses.payload);
  683|     51|		if (wantreply) {
  ------------------
  |  Branch (683:7): [True: 0, False: 51]
  ------------------
  684|      0|			send_msg_channel_failure(channel);
  685|      0|		}
  686|     51|	}
  687|       |
  688|  4.77k|	TRACE(("leave recv_msg_channel_request"))
  689|       |
  690|  4.77k|}
recv_msg_channel_data:
  776|    348|void recv_msg_channel_data() {
  777|       |
  778|    348|	struct Channel *channel;
  779|       |
  780|    348|	channel = getchannel();
  781|       |
  782|    348|	common_recv_msg_channel_data(channel, channel->writefd, channel->writebuf);
  783|    348|}
common_recv_msg_channel_data:
  788|    293|		circbuffer * cbuf) {
  789|       |
  790|    293|	unsigned int datalen;
  791|    293|	unsigned int maxdata;
  792|    293|	unsigned int buflen;
  793|    293|	unsigned int len;
  794|    293|	unsigned int consumed;
  795|    293|	int res;
  796|       |
  797|    293|	TRACE(("enter recv_msg_channel_data"))
  798|       |
  799|    293|	if (channel->recv_eof) {
  ------------------
  |  Branch (799:6): [True: 1, False: 292]
  ------------------
  800|      1|		dropbear_exit("Received data after eof");
  801|      1|	}
  802|       |
  803|    292|	if (fd < 0 || !cbuf) {
  ------------------
  |  Branch (803:6): [True: 198, False: 94]
  |  Branch (803:16): [True: 0, False: 94]
  ------------------
  804|       |		/* If we have encountered failed write, the far side might still
  805|       |		 * be sending data without having yet received our close notification.
  806|       |		 * We just drop the data. */
  807|    198|		return;
  808|    198|	}
  809|       |
  810|     94|	datalen = buf_getint(ses.payload);
  811|     94|	TRACE(("length %d", datalen))
  812|       |
  813|     94|	maxdata = cbuf_getavail(cbuf);
  814|       |
  815|       |	/* Whilst the spec says we "MAY ignore data past the end" this could
  816|       |	 * lead to corrupted file transfers etc (chunks missed etc). It's better to
  817|       |	 * just die horribly */
  818|     94|	if (datalen > maxdata) {
  ------------------
  |  Branch (818:6): [True: 42, False: 52]
  ------------------
  819|     42|		dropbear_exit("Oversized packet");
  820|     42|	}
  821|       |
  822|     52|	dropbear_assert(channel->recvwindow >= datalen);
  ------------------
  |  |   84|     52|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 52]
  |  |  |  Branch (84:93): [Folded, False: 52]
  |  |  ------------------
  ------------------
  823|     52|	channel->recvwindow -= datalen;
  824|     52|	dropbear_assert(channel->recvwindow <= opts.recv_window);
  ------------------
  |  |   84|     52|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 52]
  |  |  |  Branch (84:93): [Folded, False: 52]
  |  |  ------------------
  ------------------
  825|       |
  826|       |	/* Attempt to write the data immediately without having to put it in the circular buffer */
  827|     52|	consumed = datalen;
  828|     52|	res = writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed);
  829|       |
  830|     52|	datalen -= consumed;
  831|     52|	buf_incrpos(ses.payload, consumed);
  832|       |
  833|       |
  834|       |	/* We may have to run throught twice, if the buffer wraps around. Can't
  835|       |	 * just "leave it for next time" like with writechannel, since this
  836|       |	 * is payload data.
  837|       |	 * If the writechannel() failed then remaining data is discarded */
  838|     52|	if (res == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|     52|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (838:6): [True: 0, False: 52]
  ------------------
  839|      0|		len = datalen;
  840|      0|		while (len > 0) {
  ------------------
  |  Branch (840:10): [True: 0, False: 0]
  ------------------
  841|      0|			buflen = cbuf_writelen(cbuf);
  842|      0|			buflen = MIN(buflen, len);
  ------------------
  |  Branch (842:13): [True: 0, False: 0]
  ------------------
  843|       |
  844|      0|			memcpy(cbuf_writeptr(cbuf, buflen), 
  845|      0|					buf_getptr(ses.payload, buflen), buflen);
  846|      0|			cbuf_incrwrite(cbuf, buflen);
  847|      0|			buf_incrpos(ses.payload, buflen);
  848|      0|			len -= buflen;
  849|      0|		}
  850|      0|	}
  851|       |
  852|     52|	TRACE(("leave recv_msg_channel_data"))
  853|     52|}
recv_msg_channel_window_adjust:
  858|    134|void recv_msg_channel_window_adjust() {
  859|       |
  860|    134|	struct Channel * channel;
  861|    134|	unsigned int incr, newwin;
  862|       |	
  863|    134|	channel = getchannel();
  864|       |	
  865|    134|	incr = buf_getint(ses.payload);
  866|    134|	TRACE(("received window increment %u", incr))
  867|       |	
  868|    134|	newwin = channel->transwindow + incr;
  869|    134|	if (newwin < channel->transwindow) {
  ------------------
  |  Branch (869:6): [True: 36, False: 98]
  ------------------
  870|       |		/* Integer overflow, clamp it at maximum.
  871|       |		 * Behaviour may be unexpected, senders MUST NOT overflow per rfc4254. */
  872|     36|		TRACE(("overflow window, prev %u", channel->transwindow));
  873|     36|		newwin = 0xffffffff;
  874|     36|	}
  875|    134|	channel->transwindow = newwin;
  876|    134|}
recv_msg_channel_open:
  894|  4.72k|void recv_msg_channel_open() {
  895|       |
  896|  4.72k|	char *type;
  897|  4.72k|	unsigned int typelen;
  898|  4.72k|	unsigned int remotechan, transwindow, transmaxpacket;
  899|  4.72k|	struct Channel *channel;
  900|  4.72k|	const struct ChanType **cp;
  901|  4.72k|	const struct ChanType *chantype;
  902|  4.72k|	unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE;
  ------------------
  |  |   35|  4.72k|#define SSH_OPEN_UNKNOWN_CHANNEL_TYPE           3
  ------------------
  903|  4.72k|	int ret;
  904|       |
  905|       |
  906|  4.72k|	TRACE(("enter recv_msg_channel_open"))
  907|       |
  908|       |	/* get the packet contents */
  909|  4.72k|	type = buf_getstring(ses.payload, &typelen);
  910|       |
  911|  4.72k|	remotechan = buf_getint(ses.payload);
  912|  4.72k|	transwindow = buf_getint(ses.payload);
  913|  4.72k|	transmaxpacket = buf_getint(ses.payload);
  914|  4.72k|	transmaxpacket = MIN(transmaxpacket, TRANS_MAX_PAYLOAD_LEN);
  ------------------
  |  Branch (914:19): [True: 1.22k, False: 3.49k]
  ------------------
  915|       |
  916|       |	/* figure what type of packet it is */
  917|  4.72k|	if (typelen > MAX_NAME_LEN) {
  ------------------
  |  |  233|  4.72k|#define MAX_NAME_LEN 64 /* maximum length of a protocol name, isn't
  ------------------
  |  Branch (917:6): [True: 73, False: 4.64k]
  ------------------
  918|     73|		goto failure;
  919|     73|	}
  920|       |
  921|       |	/* Get the channel type. Client and server style invokation will set up a
  922|       |	 * different list for ses.chantypes at startup. We just iterate through
  923|       |	 * this list and find the matching name */
  924|  4.64k|	for (cp = &ses.chantypes[0], chantype = (*cp); 
  925|  7.51k|			chantype != NULL;
  ------------------
  |  Branch (925:4): [True: 6.73k, False: 776]
  ------------------
  926|  6.73k|			cp++, chantype = (*cp)) {
  927|  6.73k|		if (strcmp(type, chantype->name) == 0) {
  ------------------
  |  Branch (927:7): [True: 3.87k, False: 2.86k]
  ------------------
  928|  3.87k|			break;
  929|  3.87k|		}
  930|  6.73k|	}
  931|       |
  932|  4.64k|	if (chantype == NULL) {
  ------------------
  |  Branch (932:6): [True: 756, False: 3.89k]
  ------------------
  933|    756|		TRACE(("No matching type for '%s'", type))
  934|    756|		goto failure;
  935|    756|	}
  936|       |
  937|  3.89k|	TRACE(("matched type '%s'", type))
  938|       |
  939|       |	/* create the channel */
  940|  3.89k|	channel = newchannel(remotechan, chantype, transwindow, transmaxpacket);
  941|       |
  942|  3.89k|	if (channel == NULL) {
  ------------------
  |  Branch (942:6): [True: 0, False: 3.89k]
  ------------------
  943|      0|		TRACE(("newchannel returned NULL"))
  944|      0|		errtype = SSH_OPEN_RESOURCE_SHORTAGE;
  ------------------
  |  |   36|      0|#define SSH_OPEN_RESOURCE_SHORTAGE              4
  ------------------
  945|      0|		goto failure;
  946|      0|	}
  947|       |
  948|  3.89k|	if (channel->type->inithandler) {
  ------------------
  |  Branch (948:6): [True: 3.87k, False: 20]
  ------------------
  949|  3.87k|		ret = channel->type->inithandler(channel);
  950|  3.87k|		if (ret == SSH_OPEN_IN_PROGRESS) {
  ------------------
  |  |   39|  3.87k|#define SSH_OPEN_IN_PROGRESS					99
  ------------------
  |  Branch (950:7): [True: 137, False: 3.73k]
  ------------------
  951|       |			/* We'll send the confirmation later */
  952|    137|			goto cleanup;
  953|    137|		}
  954|  3.73k|		if (ret > 0) {
  ------------------
  |  Branch (954:7): [True: 292, False: 3.44k]
  ------------------
  955|    292|			errtype = ret;
  956|    292|			remove_channel(channel);
  957|    292|			TRACE(("inithandler returned failure %d", ret))
  958|    292|			goto failure;
  959|    292|		}
  960|  3.73k|	}
  961|       |
  962|  3.46k|	update_channel_prio();
  963|       |
  964|       |	/* success */
  965|  3.46k|	send_msg_channel_open_confirmation(channel, channel->recvwindow,
  966|  3.46k|			channel->recvmaxpacket);
  967|  3.46k|	goto cleanup;
  968|       |
  969|  1.12k|failure:
  970|  1.12k|	TRACE(("recv_msg_channel_open failure"))
  971|  1.12k|	send_msg_channel_open_failure(remotechan, errtype, "", "");
  972|       |
  973|  4.68k|cleanup:
  974|  4.68k|	m_free(type);
  ------------------
  |  |   24|  4.68k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.68k]
  |  |  ------------------
  ------------------
  975|       |
  976|  4.68k|	TRACE(("leave recv_msg_channel_open"))
  977|  4.68k|}
send_msg_channel_failure:
  980|  2.76k|void send_msg_channel_failure(const struct Channel *channel) {
  981|       |
  982|  2.76k|	TRACE(("enter send_msg_channel_failure"))
  983|       |
  984|  2.76k|	if (channel->sent_close) {
  ------------------
  |  Branch (984:6): [True: 99, False: 2.66k]
  ------------------
  985|     99|		TRACE(("Skipping sending msg_channel_failure for closed channel"))
  986|     99|		return;
  987|     99|	}
  988|  2.66k|	CHECKCLEARTOWRITE();
  989|       |
  990|  2.66k|	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
  ------------------
  |  |   76|  2.66k|#define SSH_MSG_CHANNEL_FAILURE                 100
  ------------------
  991|  2.66k|	buf_putint(ses.writepayload, channel->remotechan);
  992|       |
  993|  2.66k|	encrypt_packet();
  994|  2.66k|	TRACE(("leave send_msg_channel_failure"))
  995|  2.66k|}
send_msg_channel_success:
  998|  1.32k|void send_msg_channel_success(const struct Channel *channel) {
  999|       |
 1000|  1.32k|	TRACE(("enter send_msg_channel_success"))
 1001|  1.32k|	if (channel->sent_close) {
  ------------------
  |  Branch (1001:6): [True: 77, False: 1.24k]
  ------------------
 1002|     77|		TRACE(("Skipping sending msg_channel_success for closed channel"))
 1003|     77|		return;
 1004|     77|	}
 1005|  1.24k|	CHECKCLEARTOWRITE();
 1006|       |
 1007|  1.24k|	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
  ------------------
  |  |   75|  1.24k|#define SSH_MSG_CHANNEL_SUCCESS                 99
  ------------------
 1008|  1.24k|	buf_putint(ses.writepayload, channel->remotechan);
 1009|       |
 1010|  1.24k|	encrypt_packet();
 1011|  1.24k|	TRACE(("leave send_msg_channel_success"))
 1012|  1.24k|}
recv_msg_channel_open_confirmation:
 1138|     49|void recv_msg_channel_open_confirmation() {
 1139|       |
 1140|     49|	struct Channel * channel;
 1141|     49|	int ret;
 1142|       |
 1143|     49|	TRACE(("enter recv_msg_channel_open_confirmation"))
 1144|       |
 1145|     49|	channel = getchannel();
 1146|       |
 1147|     49|	if (!channel->await_open) {
  ------------------
  |  Branch (1147:6): [True: 1, False: 48]
  ------------------
 1148|      1|		dropbear_exit("Unexpected channel reply");
 1149|      1|	}
 1150|     48|	channel->await_open = 0;
 1151|       |
 1152|     48|	channel->remotechan =  buf_getint(ses.payload);
 1153|     48|	channel->transwindow = buf_getint(ses.payload);
 1154|     48|	channel->transmaxpacket = buf_getint(ses.payload);
 1155|       |	
 1156|     48|	TRACE(("new chan remote %d local %d", 
 1157|     48|				channel->remotechan, channel->index))
 1158|       |
 1159|       |	/* Run the inithandler callback */
 1160|     48|	if (channel->type->inithandler) {
  ------------------
  |  Branch (1160:6): [True: 0, False: 48]
  ------------------
 1161|      0|		ret = channel->type->inithandler(channel);
 1162|      0|		if (ret > 0) {
  ------------------
  |  Branch (1162:7): [True: 0, False: 0]
  ------------------
 1163|      0|			remove_channel(channel);
 1164|      0|			TRACE(("inithandler returned failure %d", ret))
 1165|      0|			return;
 1166|      0|		}
 1167|      0|	}
 1168|       |
 1169|     48|	update_channel_prio();
 1170|       |
 1171|     48|	TRACE(("leave recv_msg_channel_open_confirmation"))
 1172|     48|}
recv_msg_channel_open_failure:
 1175|     49|void recv_msg_channel_open_failure() {
 1176|       |
 1177|     49|	struct Channel * channel;
 1178|       |
 1179|     49|	channel = getchannel();
 1180|       |
 1181|     49|	if (!channel->await_open) {
  ------------------
  |  Branch (1181:6): [True: 1, False: 48]
  ------------------
 1182|      1|		dropbear_exit("Unexpected channel reply");
 1183|      1|	}
 1184|     48|	channel->await_open = 0;
 1185|       |
 1186|     48|	remove_channel(channel);
 1187|     48|}
send_msg_request_failure:
 1196|    798|void send_msg_request_failure() {
 1197|    798|	CHECKCLEARTOWRITE();
 1198|    798|	buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_FAILURE);
  ------------------
  |  |   65|    798|#define SSH_MSG_REQUEST_FAILURE                 82
  ------------------
 1199|    798|	encrypt_packet();
 1200|    798|}
common-channel.c:getchannel_msg:
  179|  6.93k|static struct Channel* getchannel_msg(const char* kind) {
  180|       |
  181|  6.93k|	unsigned int chan;
  182|       |
  183|  6.93k|	chan = buf_getint(ses.payload);
  184|  6.93k|	if (chan >= ses.chansize || ses.channels[chan] == NULL) {
  ------------------
  |  Branch (184:6): [True: 346, False: 6.58k]
  |  Branch (184:30): [True: 9, False: 6.57k]
  ------------------
  185|    355|		if (kind) {
  ------------------
  |  Branch (185:7): [True: 105, False: 250]
  ------------------
  186|    105|			dropbear_exit("%s for unknown channel %d", kind, chan);
  187|    250|		} else {
  188|    250|			dropbear_exit("Unknown channel %d", chan);
  189|    250|		}
  190|    355|	}
  191|  6.57k|	return ses.channels[chan];
  192|  6.93k|}
common-channel.c:check_close:
  276|  55.4k|static void check_close(struct Channel *channel) {
  277|  55.4k|	int close_allowed = 0;
  278|       |
  279|  55.4k|	TRACE2(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d",
  280|  55.4k|				channel->writefd, channel->readfd,
  281|  55.4k|				channel->errfd, channel->sent_close, channel->recv_close))
  282|  55.4k|	TRACE2(("writebuf size %d extrabuf size %d",
  283|  55.4k|				channel->writebuf ? cbuf_getused(channel->writebuf) : 0,
  284|  55.4k|				channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
  285|       |
  286|       |	/* if a type-specific check_close is defined we will only exit
  287|       |	   once that has been triggered. this is only used for a server "session"
  288|       |	   channel, to ensure that the shell has exited (and the exit status
  289|       |	   retrieved) before we close things up. */
  290|  55.4k|	if (!channel->type->check_close
  ------------------
  |  Branch (290:6): [True: 0, False: 55.4k]
  ------------------
  291|  55.4k|		|| channel->sent_close
  ------------------
  |  Branch (291:6): [True: 375, False: 55.0k]
  ------------------
  292|  55.0k|		|| channel->type->check_close(channel)) {
  ------------------
  |  Branch (292:6): [True: 472, False: 54.6k]
  ------------------
  293|    847|		close_allowed = 1;
  294|    847|	}
  295|       |
  296|       |	/* In flushing mode we close FDs as soon as pipes are empty.
  297|       |	This is used to drain out FDs when the process exits, in the case
  298|       |	where the FD doesn't have EOF - "sleep 10&echo hello" case */
  299|  55.4k|	if (channel->flushing) {
  ------------------
  |  Branch (299:6): [True: 0, False: 55.4k]
  ------------------
  300|      0|		if (channel->readfd >= 0 && !fd_read_pending(channel->readfd)) {
  ------------------
  |  Branch (300:7): [True: 0, False: 0]
  |  Branch (300:31): [True: 0, False: 0]
  ------------------
  301|      0|			close_chan_fd(channel, channel->readfd, SHUT_RD);
  302|      0|		}
  303|      0|		if (ERRFD_IS_READ(channel)
  ------------------
  |  |   59|      0|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (59:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  304|      0|			&& channel->errfd >= 0 && !fd_read_pending(channel->errfd)) {
  ------------------
  |  Branch (304:7): [True: 0, False: 0]
  |  Branch (304:30): [True: 0, False: 0]
  ------------------
  305|      0|			close_chan_fd(channel, channel->errfd, SHUT_RD);
  306|      0|		}
  307|      0|	}
  308|       |
  309|  55.4k|	if (channel->recv_close && !write_pending(channel) && close_allowed) {
  ------------------
  |  Branch (309:6): [True: 7.33k, False: 48.1k]
  |  Branch (309:29): [True: 7.33k, False: 0]
  |  Branch (309:56): [True: 428, False: 6.90k]
  ------------------
  310|    428|		if (!channel->sent_close) {
  ------------------
  |  Branch (310:7): [True: 240, False: 188]
  ------------------
  311|    240|			TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
  312|    240|			send_msg_channel_close(channel);
  313|    240|		}
  314|    428|		remove_channel(channel);
  315|    428|		return;
  316|    428|	}
  317|       |
  318|  55.0k|	if ((channel->recv_eof && !write_pending(channel))
  ------------------
  |  Branch (318:7): [True: 9.43k, False: 45.6k]
  |  Branch (318:28): [True: 9.43k, False: 0]
  ------------------
  319|       |		/* have a server "session" and child has exited */
  320|  45.6k|		|| (channel->writefd != FD_UNINIT
  ------------------
  |  |   56|  91.2k|#define FD_UNINIT (-2)
  ------------------
  |  Branch (320:7): [True: 45.6k, False: 0]
  ------------------
  321|  45.6k|			&& channel->type->check_close && close_allowed)) {
  ------------------
  |  Branch (321:7): [True: 45.6k, False: 0]
  |  Branch (321:37): [True: 0, False: 45.6k]
  ------------------
  322|  9.43k|		close_chan_fd(channel, channel->writefd, SHUT_WR);
  323|  9.43k|	}
  324|       |
  325|       |	/* If we're not going to send any more data, send EOF */
  326|  55.0k|	if (!channel->sent_eof
  ------------------
  |  Branch (326:6): [True: 54.7k, False: 308]
  ------------------
  327|  54.7k|			&& channel->readfd == FD_CLOSED 
  ------------------
  |  |   57|   109k|#define FD_CLOSED (-1)
  ------------------
  |  Branch (327:7): [True: 5.41k, False: 49.3k]
  ------------------
  328|  5.41k|			&& (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) {
  ------------------
  |  |   60|  10.8k|#define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel))
  |  |  ------------------
  |  |  |  |   59|  5.41k|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (60:33): [True: 0, False: 5.41k]
  |  |  ------------------
  ------------------
              			&& (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) {
  ------------------
  |  |   57|  5.41k|#define FD_CLOSED (-1)
  ------------------
  |  Branch (328:35): [True: 257, False: 5.16k]
  ------------------
  329|    257|		send_msg_channel_eof(channel);
  330|    257|	}
  331|       |
  332|       |	/* And if we can't receive any more data from them either, close up */
  333|  55.0k|	if (channel->readfd == FD_CLOSED
  ------------------
  |  |   57|   110k|#define FD_CLOSED (-1)
  ------------------
  |  Branch (333:6): [True: 5.71k, False: 49.3k]
  ------------------
  334|  5.71k|			&& channel->writefd == FD_CLOSED
  ------------------
  |  |   57|  60.7k|#define FD_CLOSED (-1)
  ------------------
  |  Branch (334:7): [True: 2.64k, False: 3.07k]
  ------------------
  335|  2.64k|			&& (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)
  ------------------
  |  |   60|  5.28k|#define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel))
  |  |  ------------------
  |  |  |  |   59|  2.64k|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (60:33): [True: 0, False: 2.64k]
  |  |  ------------------
  ------------------
              			&& (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)
  ------------------
  |  |   57|  2.64k|#define FD_CLOSED (-1)
  ------------------
  |  Branch (335:35): [True: 547, False: 2.09k]
  ------------------
  336|    547|			&& !channel->sent_close
  ------------------
  |  Branch (336:7): [True: 368, False: 179]
  ------------------
  337|    368|			&& close_allowed
  ------------------
  |  Branch (337:7): [True: 232, False: 136]
  ------------------
  338|    232|			&& !write_pending(channel)) {
  ------------------
  |  Branch (338:7): [True: 232, False: 0]
  ------------------
  339|    232|		TRACE(("sending close, readfd is closed"))
  340|    232|		send_msg_channel_close(channel);
  341|    232|	}
  342|  55.0k|}
common-channel.c:close_chan_fd:
 1052|  10.9k|static void close_chan_fd(struct Channel *channel, int fd, int how) {
 1053|       |
 1054|  10.9k|	int closein = 0, closeout = 0;
 1055|       |
 1056|  10.9k|	if (channel->bidir_fd) {
  ------------------
  |  Branch (1056:6): [True: 0, False: 10.9k]
  ------------------
 1057|      0|		TRACE(("SHUTDOWN(%d, %d)", fd, how))
 1058|      0|		shutdown(fd, how);
 1059|      0|		if (how == 0) {
  ------------------
  |  Branch (1059:7): [True: 0, False: 0]
  ------------------
 1060|      0|			closeout = 1;
 1061|      0|		} else {
 1062|      0|			closein = 1;
 1063|      0|		}
 1064|  10.9k|	} else {
 1065|  10.9k|		TRACE(("CLOSE some fd %d", fd))
 1066|  10.9k|		m_close(fd);
 1067|  10.9k|		closein = closeout = 1;
 1068|  10.9k|	}
 1069|       |
 1070|  10.9k|	if (closeout && (fd == channel->readfd)) {
  ------------------
  |  Branch (1070:6): [True: 10.9k, False: 0]
  |  Branch (1070:18): [True: 4.11k, False: 6.88k]
  ------------------
 1071|  4.11k|		channel->readfd = FD_CLOSED;
  ------------------
  |  |   57|  4.11k|#define FD_CLOSED (-1)
  ------------------
 1072|  4.11k|	}
 1073|  10.9k|	if (closeout && ERRFD_IS_READ(channel) && (fd == channel->errfd)) {
  ------------------
  |  |   59|  21.9k|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (59:32): [True: 10.9k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1073:6): [True: 10.9k, False: 0]
  |  Branch (1073:44): [True: 4.27k, False: 6.72k]
  ------------------
 1074|  4.27k|		channel->errfd = FD_CLOSED;
  ------------------
  |  |   57|  4.27k|#define FD_CLOSED (-1)
  ------------------
 1075|  4.27k|	}
 1076|       |
 1077|  10.9k|	if (closein && fd == channel->writefd) {
  ------------------
  |  Branch (1077:6): [True: 10.9k, False: 0]
  |  Branch (1077:17): [True: 10.8k, False: 132]
  ------------------
 1078|  10.8k|		channel->writefd = FD_CLOSED;
  ------------------
  |  |   57|  10.8k|#define FD_CLOSED (-1)
  ------------------
 1079|  10.8k|	}
 1080|  10.9k|	if (closein && ERRFD_IS_WRITE(channel) && (fd == channel->errfd)) {
  ------------------
  |  |   60|  21.9k|#define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel))
  |  |  ------------------
  |  |  |  |   59|  10.9k|#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
  |  |  ------------------
  |  |  |  Branch (60:33): [True: 0, False: 10.9k]
  |  |  ------------------
  ------------------
  |  Branch (1080:6): [True: 10.9k, False: 0]
  |  Branch (1080:44): [True: 0, False: 0]
  ------------------
 1081|      0|		channel->errfd = FD_CLOSED;
  ------------------
  |  |   57|      0|#define FD_CLOSED (-1)
  ------------------
 1082|      0|	}
 1083|       |
 1084|       |	/* if we called shutdown on it and all references are gone, then we 
 1085|       |	 * need to close() it to stop it lingering */
 1086|  10.9k|	if (channel->bidir_fd && channel->readfd == FD_CLOSED 
  ------------------
  |  |   57|  10.9k|#define FD_CLOSED (-1)
  ------------------
  |  Branch (1086:6): [True: 0, False: 10.9k]
  |  Branch (1086:27): [True: 0, False: 0]
  ------------------
 1087|      0|		&& channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) {
  ------------------
  |  |   57|  10.9k|#define FD_CLOSED (-1)
  ------------------
              		&& channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) {
  ------------------
  |  |   57|      0|#define FD_CLOSED (-1)
  ------------------
  |  Branch (1087:6): [True: 0, False: 0]
  |  Branch (1087:39): [True: 0, False: 0]
  ------------------
 1088|      0|		TRACE(("CLOSE (finally) of %d", fd))
 1089|      0|		m_close(fd);
 1090|      0|	}
 1091|  10.9k|}
common-channel.c:write_pending:
  263|  16.9k|static unsigned int write_pending(const struct Channel * channel) {
  264|       |
  265|  16.9k|	if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) {
  ------------------
  |  Branch (265:6): [True: 332, False: 16.6k]
  |  Branch (265:31): [True: 0, False: 332]
  ------------------
  266|      0|		return 1;
  267|  16.9k|	} else if (channel->errfd >= 0 && channel->extrabuf && 
  ------------------
  |  Branch (267:13): [True: 10.6k, False: 6.36k]
  |  Branch (267:36): [True: 0, False: 10.6k]
  ------------------
  268|      0|			cbuf_getused(channel->extrabuf) > 0) {
  ------------------
  |  Branch (268:4): [True: 0, False: 0]
  ------------------
  269|      0|		return 1;
  270|      0|	}
  271|  16.9k|	return 0;
  272|  16.9k|}
common-channel.c:send_msg_channel_close:
  373|    472|static void send_msg_channel_close(struct Channel *channel) {
  374|       |
  375|    472|	TRACE(("enter send_msg_channel_close %p", (void*)channel))
  376|    472|	if (channel->type->closehandler) {
  ------------------
  |  Branch (376:6): [True: 472, False: 0]
  ------------------
  377|    472|		channel->type->closehandler(channel);
  378|    472|	}
  379|       |	
  380|    472|	CHECKCLEARTOWRITE();
  381|       |
  382|    472|	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
  ------------------
  |  |   73|    472|#define SSH_MSG_CHANNEL_CLOSE                   97
  ------------------
  383|    472|	buf_putint(ses.writepayload, channel->remotechan);
  384|       |
  385|    472|	encrypt_packet();
  386|       |
  387|    472|	channel->sent_eof = 1;
  388|    472|	channel->sent_close = 1;
  389|    472|	close_chan_fd(channel, channel->readfd, SHUT_RD);
  390|    472|	close_chan_fd(channel, channel->errfd, SHUT_RDWR);
  391|       |	close_chan_fd(channel, channel->writefd, SHUT_WR);
  392|    472|	TRACE(("leave send_msg_channel_close"))
  393|    472|}
common-channel.c:send_msg_channel_eof:
  396|    257|static void send_msg_channel_eof(struct Channel *channel) {
  397|       |
  398|    257|	TRACE(("enter send_msg_channel_eof"))
  399|    257|	CHECKCLEARTOWRITE();
  400|       |
  401|    257|	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
  ------------------
  |  |   72|    257|#define SSH_MSG_CHANNEL_EOF                     96
  ------------------
  402|    257|	buf_putint(ses.writepayload, channel->remotechan);
  403|       |
  404|    257|	encrypt_packet();
  405|       |
  406|    257|	channel->sent_eof = 1;
  407|       |
  408|    257|	TRACE(("leave send_msg_channel_eof"))
  409|    257|}
common-channel.c:writechannel:
  514|     18|	const unsigned char *moredata, unsigned int *morelen) {
  515|     18|	int ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|     18|#define DROPBEAR_SUCCESS 0
  ------------------
  516|     18|	TRACE(("enter writechannel fd %d", fd))
  517|     18|#ifdef HAVE_WRITEV
  518|     18|	ret = writechannel_writev(channel, fd, cbuf, moredata, morelen);
  519|       |#else
  520|       |	ret = writechannel_fallback(channel, fd, cbuf, moredata, morelen);
  521|       |#endif
  522|       |
  523|       |	/* Window adjust handling */
  524|     18|	if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
  ------------------
  |  |  246|     18|#define RECV_WINDOWEXTEND (opts.recv_window / 3) /* We send a "window extend" every
  ------------------
  |  Branch (524:6): [True: 0, False: 18]
  ------------------
  525|      0|		send_msg_channel_window_adjust(channel, channel->recvdonelen);
  526|      0|		channel->recvwindow += channel->recvdonelen;
  527|      0|		channel->recvdonelen = 0;
  528|      0|	}
  529|       |
  530|     18|	dropbear_assert(channel->recvwindow <= opts.recv_window);
  ------------------
  |  |   84|     18|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 18]
  |  |  |  Branch (84:93): [Folded, False: 18]
  |  |  ------------------
  ------------------
  531|     18|	dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
  ------------------
  |  |   84|     18|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 18]
  |  |  |  Branch (84:93): [Folded, False: 18]
  |  |  ------------------
  ------------------
  532|     18|	dropbear_assert(channel->extrabuf == NULL ||
  ------------------
  |  |   84|     18|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:39): [True: 18, False: 0]
  |  |  |  Branch (84:39): [True: 0, False: 0]
  |  |  |  Branch (84:93): [Folded, False: 18]
  |  |  ------------------
  ------------------
  533|     18|			channel->recvwindow <= cbuf_getavail(channel->extrabuf));
  534|       |	
  535|     18|	TRACE(("leave writechannel"))
  536|     18|	return ret;
  537|     18|}
common-channel.c:writechannel_writev:
  443|     18|	const unsigned char *moredata, unsigned int *morelen) {
  444|       |
  445|     18|	struct iovec iov[3];
  446|     18|	unsigned char *circ_p1, *circ_p2;
  447|     18|	unsigned int circ_len1, circ_len2;
  448|     18|	int io_count = 0;
  449|       |
  450|     18|	ssize_t written;
  451|       |
  452|     18|	cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2);
  453|       |
  454|     18|	if (circ_len1 > 0) {
  ------------------
  |  Branch (454:6): [True: 0, False: 18]
  ------------------
  455|      0|		TRACE(("circ1 %d", circ_len1))
  456|      0|		iov[io_count].iov_base = circ_p1;
  457|      0|		iov[io_count].iov_len = circ_len1;
  458|      0|		io_count++;
  459|      0|	}
  460|       |
  461|     18|	if (circ_len2 > 0) {
  ------------------
  |  Branch (461:6): [True: 0, False: 18]
  ------------------
  462|      0|		TRACE(("circ2 %d", circ_len2))
  463|      0|		iov[io_count].iov_base = circ_p2;
  464|      0|		iov[io_count].iov_len = circ_len2;
  465|      0|		io_count++;
  466|      0|	}
  467|       |
  468|     18|	if (morelen) {
  ------------------
  |  Branch (468:6): [True: 18, False: 0]
  ------------------
  469|     18|		assert(moredata);
  ------------------
  |  Branch (469:3): [True: 0, False: 18]
  |  Branch (469:3): [True: 18, False: 0]
  ------------------
  470|     18|		TRACE(("more %d", *morelen))
  471|     18|		iov[io_count].iov_base = (void*)moredata;
  472|     18|		iov[io_count].iov_len  = *morelen;
  473|     18|		io_count++;
  474|     18|	}
  475|       |
  476|     18|	if (io_count == 0) {
  ------------------
  |  Branch (476:6): [True: 0, False: 18]
  ------------------
  477|       |		/* writechannel may sometimes be called twice in a main loop iteration.
  478|       |		From common_recv_msg_channel_data() then channelio().
  479|       |		The second call may not have any data to write, so we just return. */
  480|      0|		TRACE(("leave writechannel, no data"))
  481|      0|		return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  482|      0|	}
  483|       |
  484|     18|	if (morelen) {
  ------------------
  |  Branch (484:6): [True: 18, False: 0]
  ------------------
  485|       |		/* Default return value, none consumed */
  486|     18|		*morelen = 0;
  487|     18|	}
  488|       |
  489|     18|	written = writev(fd, iov, io_count);
  490|       |
  491|     18|	if (written < 0) {
  ------------------
  |  Branch (491:6): [True: 18, False: 0]
  ------------------
  492|     18|		if (errno != EINTR && errno != EAGAIN) {
  ------------------
  |  Branch (492:7): [True: 18, False: 0]
  |  Branch (492:25): [True: 18, False: 0]
  ------------------
  493|     18|			TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
  494|     18|			close_chan_fd(channel, fd, SHUT_WR);
  495|     18|			return DROPBEAR_FAILURE;
  ------------------
  |  |  112|     18|#define DROPBEAR_FAILURE -1
  ------------------
  496|     18|		}
  497|     18|	} else {
  498|      0|		int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written);
  ------------------
  |  Branch (498:22): [True: 0, False: 0]
  ------------------
  499|      0|		cbuf_incrread(cbuf, cbuf_written);
  500|      0|		if (morelen) {
  ------------------
  |  Branch (500:7): [True: 0, False: 0]
  ------------------
  501|      0|			*morelen = written - cbuf_written;
  502|      0|		}
  503|      0|		channel->recvdonelen += written;
  504|      0|	}
  505|      0|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  506|     18|}
common-channel.c:remove_channel:
  625|  3.87k|static void remove_channel(struct Channel * channel) {
  626|       |
  627|  3.87k|	TRACE(("enter remove_channel"))
  628|  3.87k|	TRACE(("channel index is %d", channel->index))
  629|       |
  630|  3.87k|	cbuf_free(channel->writebuf);
  631|  3.87k|	channel->writebuf = NULL;
  632|       |
  633|  3.87k|	if (channel->extrabuf) {
  ------------------
  |  Branch (633:6): [True: 0, False: 3.87k]
  ------------------
  634|      0|		cbuf_free(channel->extrabuf);
  635|      0|		channel->extrabuf = NULL;
  636|      0|	}
  637|       |
  638|       |
  639|  3.87k|	if (IS_DROPBEAR_SERVER || (channel->writefd != STDOUT_FILENO)) {
  ------------------
  |  |  381|  7.74k|#define IS_DROPBEAR_SERVER (ses.isserver == 1)
  |  |  ------------------
  |  |  |  Branch (381:28): [True: 3.87k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (639:28): [True: 0, False: 0]
  ------------------
  640|       |		/* close the FDs in case they haven't been done
  641|       |		 * yet (they might have been shutdown etc) */
  642|  3.87k|		TRACE(("CLOSE writefd %d", channel->writefd))
  643|  3.87k|		m_close(channel->writefd);
  644|  3.87k|		TRACE(("CLOSE readfd %d", channel->readfd))
  645|  3.87k|		m_close(channel->readfd);
  646|  3.87k|		TRACE(("CLOSE errfd %d", channel->errfd))
  647|  3.87k|		m_close(channel->errfd);
  648|  3.87k|	}
  649|       |
  650|  3.87k|	if (channel->type->cleanup) {
  ------------------
  |  Branch (650:6): [True: 3.42k, False: 449]
  ------------------
  651|  3.42k|		channel->type->cleanup(channel);
  652|  3.42k|	}
  653|       |
  654|  3.87k|	if (channel->conn_pending) {
  ------------------
  |  Branch (654:6): [True: 137, False: 3.73k]
  ------------------
  655|    137|		cancel_connect(channel->conn_pending);
  656|    137|	}
  657|       |
  658|  3.87k|	ses.channels[channel->index] = NULL;
  659|  3.87k|	m_free(channel);
  ------------------
  |  |   24|  3.87k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 3.87k]
  |  |  ------------------
  ------------------
  660|  3.87k|	ses.chancount--;
  661|       |
  662|  3.87k|	update_channel_prio();
  663|       |
  664|  3.87k|	TRACE(("leave remove_channel"))
  665|  3.87k|}
common-channel.c:send_msg_channel_data:
  697|  61.0k|static void send_msg_channel_data(struct Channel *channel, int isextended) {
  698|       |
  699|  61.0k|	int len;
  700|  61.0k|	size_t maxlen, size_pos;
  701|  61.0k|	int fd;
  702|       |
  703|  61.0k|	CHECKCLEARTOWRITE();
  704|       |
  705|  61.0k|	TRACE(("enter send_msg_channel_data"))
  706|  61.0k|	dropbear_assert(!channel->sent_close);
  ------------------
  |  |   84|  61.0k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 4, False: 61.0k]
  |  |  |  Branch (84:93): [Folded, False: 61.0k]
  |  |  ------------------
  ------------------
  707|       |
  708|  61.0k|	if (isextended) {
  ------------------
  |  Branch (708:6): [True: 30.5k, False: 30.4k]
  ------------------
  709|  30.5k|		fd = channel->errfd;
  710|  30.5k|	} else {
  711|  30.4k|		fd = channel->readfd;
  712|  30.4k|	}
  713|  61.0k|	TRACE(("enter send_msg_channel_data isextended %d fd %d", isextended, fd))
  714|  61.0k|	dropbear_assert(fd >= 0);
  ------------------
  |  |   84|  61.0k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 61.0k]
  |  |  |  Branch (84:93): [Folded, False: 61.0k]
  |  |  ------------------
  ------------------
  715|       |
  716|  61.0k|	maxlen = MIN(channel->transwindow, channel->transmaxpacket);
  ------------------
  |  Branch (716:11): [True: 181, False: 60.8k]
  ------------------
  717|       |	/* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 
  718|       |	 * exttype if is extended */
  719|  61.0k|	maxlen = MIN(maxlen, 
  ------------------
  |  Branch (719:11): [True: 30.5k, False: 30.4k]
  |  Branch (719:11): [True: 19.0k, False: 16.9k]
  |  Branch (719:11): [True: 25.0k, False: 35.9k]
  ------------------
  720|  61.0k|			ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
  721|  61.0k|	TRACE(("maxlen %zd", maxlen))
  722|  61.0k|	if (maxlen == 0) {
  ------------------
  |  Branch (722:6): [True: 1.65k, False: 59.3k]
  ------------------
  723|  1.65k|		TRACE(("leave send_msg_channel_data: no window"))
  724|  1.65k|		return;
  725|  1.65k|	}
  726|       |
  727|  59.3k|	buf_putbyte(ses.writepayload, 
  728|  59.3k|			isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
  ------------------
  |  |   71|  29.6k|#define SSH_MSG_CHANNEL_EXTENDED_DATA           95
  ------------------
              			isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
  ------------------
  |  |   70|  89.0k|#define SSH_MSG_CHANNEL_DATA                    94
  ------------------
  |  Branch (728:4): [True: 29.6k, False: 29.6k]
  ------------------
  729|  59.3k|	buf_putint(ses.writepayload, channel->remotechan);
  730|  59.3k|	if (isextended) {
  ------------------
  |  Branch (730:6): [True: 29.6k, False: 29.6k]
  ------------------
  731|  29.6k|		buf_putint(ses.writepayload, SSH_EXTENDED_DATA_STDERR);
  ------------------
  |  |   79|  29.6k|#define SSH_EXTENDED_DATA_STDERR	1
  ------------------
  732|  29.6k|	}
  733|       |	/* a dummy size first ...*/
  734|  59.3k|	size_pos = ses.writepayload->pos;
  735|  59.3k|	buf_putint(ses.writepayload, 0);
  736|       |
  737|       |	/* read the data */
  738|  59.3k|	len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen);
  ------------------
  |  |   55|  59.3k|#define read(fd, buf, count) wrapfd_read(fd, buf, count)
  ------------------
  739|       |
  740|  59.3k|	if (len <= 0) {
  ------------------
  |  Branch (740:6): [True: 173, False: 59.1k]
  ------------------
  741|    173|		if (len == 0 || errno != EINTR) {
  ------------------
  |  Branch (741:7): [True: 0, False: 173]
  |  Branch (741:19): [True: 132, False: 41]
  ------------------
  742|       |			/* This will also get hit in the case of EAGAIN. The only
  743|       |			time we expect to receive EAGAIN is when we're flushing a FD,
  744|       |			in which case it can be treated the same as EOF */
  745|    132|			close_chan_fd(channel, fd, SHUT_RD);
  746|    132|		}
  747|    173|		buf_setpos(ses.writepayload, 0);
  748|    173|		buf_setlen(ses.writepayload, 0);
  749|    173|		TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d", 
  750|    173|					len, errno, fd))
  751|    173|		return;
  752|    173|	}
  753|       |
  754|  59.1k|	if (channel->read_mangler) {
  ------------------
  |  Branch (754:6): [True: 0, False: 59.1k]
  ------------------
  755|      0|		channel->read_mangler(channel, buf_getwriteptr(ses.writepayload, len), &len);
  756|      0|		if (len == 0) {
  ------------------
  |  Branch (756:7): [True: 0, False: 0]
  ------------------
  757|      0|			buf_setpos(ses.writepayload, 0);
  758|      0|			buf_setlen(ses.writepayload, 0);
  759|      0|			return;
  760|      0|		}
  761|      0|	}
  762|       |
  763|  59.1k|	TRACE(("send_msg_channel_data: len %d fd %d", len, fd))
  764|  59.1k|	buf_incrwritepos(ses.writepayload, len);
  765|       |	/* ... real size here */
  766|  59.1k|	buf_setpos(ses.writepayload, size_pos);
  767|  59.1k|	buf_putint(ses.writepayload, len);
  768|       |
  769|  59.1k|	channel->transwindow -= len;
  770|       |
  771|  59.1k|	encrypt_packet();
  772|  59.1k|	TRACE(("leave send_msg_channel_data"))
  773|  59.1k|}
common-channel.c:newchannel:
  108|  3.87k|		unsigned int transwindow, unsigned int transmaxpacket) {
  109|       |
  110|  3.87k|	struct Channel * newchan;
  111|  3.87k|	unsigned int i, j;
  112|       |
  113|  3.87k|	TRACE(("enter newchannel"))
  114|       |	
  115|       |	/* first see if we can use existing channels */
  116|  23.3k|	for (i = 0; i < ses.chansize; i++) {
  ------------------
  |  Branch (116:14): [True: 22.6k, False: 675]
  ------------------
  117|  22.6k|		if (ses.channels[i] == NULL) {
  ------------------
  |  Branch (117:7): [True: 3.19k, False: 19.4k]
  ------------------
  118|  3.19k|			break;
  119|  3.19k|		}
  120|  22.6k|	}
  121|       |
  122|       |	/* otherwise extend the list */
  123|  3.87k|	if (i == ses.chansize) {
  ------------------
  |  Branch (123:6): [True: 675, False: 3.19k]
  ------------------
  124|    675|		if (ses.chansize >= MAX_CHANNELS) {
  ------------------
  |  |  250|    675|#define MAX_CHANNELS 1000 /* simple mem restriction, includes each tcp/x11
  ------------------
  |  Branch (124:7): [True: 0, False: 675]
  ------------------
  125|      0|			TRACE(("leave newchannel: max chans reached"))
  126|      0|			return NULL;
  127|      0|		}
  128|       |
  129|       |		/* extend the channels */
  130|    675|		ses.channels = (struct Channel**)m_realloc(ses.channels,
  131|    675|				(ses.chansize+CHAN_EXTEND_SIZE)*sizeof(struct Channel*));
  ------------------
  |  |   41|    675|#define CHAN_EXTEND_SIZE 3 /* how many extra slots to add when we need more */
  ------------------
  132|       |
  133|    675|		ses.chansize += CHAN_EXTEND_SIZE;
  ------------------
  |  |   41|    675|#define CHAN_EXTEND_SIZE 3 /* how many extra slots to add when we need more */
  ------------------
  134|       |
  135|       |		/* set the new channels to null */
  136|  2.70k|		for (j = i; j < ses.chansize; j++) {
  ------------------
  |  Branch (136:15): [True: 2.02k, False: 675]
  ------------------
  137|  2.02k|			ses.channels[j] = NULL;
  138|  2.02k|		}
  139|       |
  140|    675|	}
  141|       |	
  142|  3.87k|	newchan = (struct Channel*)m_malloc(sizeof(struct Channel));
  143|  3.87k|	newchan->type = type;
  144|  3.87k|	newchan->index = i;
  145|  3.87k|	newchan->sent_close = newchan->recv_close = 0;
  146|  3.87k|	newchan->sent_eof = newchan->recv_eof = 0;
  147|       |
  148|  3.87k|	newchan->remotechan = remotechan;
  149|  3.87k|	newchan->transwindow = transwindow;
  150|  3.87k|	newchan->transmaxpacket = transmaxpacket;
  151|       |	
  152|  3.87k|	newchan->typedata = NULL;
  153|  3.87k|	newchan->writefd = FD_UNINIT;
  ------------------
  |  |   56|  3.87k|#define FD_UNINIT (-2)
  ------------------
  154|  3.87k|	newchan->readfd = FD_UNINIT;
  ------------------
  |  |   56|  3.87k|#define FD_UNINIT (-2)
  ------------------
  155|  3.87k|	newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
  ------------------
  |  |   57|  3.87k|#define FD_CLOSED (-1)
  ------------------
  156|  3.87k|	newchan->await_open = 0;
  157|       |
  158|  3.87k|	newchan->writebuf = cbuf_new(opts.recv_window);
  159|  3.87k|	newchan->recvwindow = opts.recv_window;
  160|       |
  161|  3.87k|	newchan->extrabuf = NULL; /* The user code can set it up */
  162|  3.87k|	newchan->recvdonelen = 0;
  163|  3.87k|	newchan->recvmaxpacket = RECV_MAX_CHANNEL_DATA_LEN;
  ------------------
  |  |   67|  3.87k|#define RECV_MAX_CHANNEL_DATA_LEN (RECV_MAX_PAYLOAD_LEN-(1+4+4))
  |  |  ------------------
  |  |  |  |  555|  3.87k|#define RECV_MAX_PAYLOAD_LEN 32768
  |  |  ------------------
  ------------------
  164|       |
  165|  3.87k|	newchan->prio = DROPBEAR_PRIO_NORMAL;
  166|       |
  167|  3.87k|	ses.channels[i] = newchan;
  168|  3.87k|	ses.chancount++;
  169|       |
  170|  3.87k|	TRACE(("leave newchannel"))
  171|       |
  172|  3.87k|	return newchan;
  173|  3.87k|}
common-channel.c:send_msg_channel_open_failure:
 1017|  1.25k|		int reason, const char *text, const char *lang) {
 1018|       |
 1019|  1.25k|	TRACE(("enter send_msg_channel_open_failure"))
 1020|  1.25k|	CHECKCLEARTOWRITE();
 1021|       |	
 1022|  1.25k|	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE);
  ------------------
  |  |   68|  1.25k|#define SSH_MSG_CHANNEL_OPEN_FAILURE            92
  ------------------
 1023|  1.25k|	buf_putint(ses.writepayload, remotechan);
 1024|  1.25k|	buf_putint(ses.writepayload, reason);
 1025|  1.25k|	buf_putstring(ses.writepayload, text, strlen(text));
 1026|  1.25k|	buf_putstring(ses.writepayload, lang, strlen(lang));
 1027|       |
 1028|  1.25k|	encrypt_packet();
 1029|  1.25k|	TRACE(("leave send_msg_channel_open_failure"))
 1030|  1.25k|}
common-channel.c:send_msg_channel_open_confirmation:
 1036|  3.42k|		unsigned int recvmaxpacket) {
 1037|       |
 1038|  3.42k|	TRACE(("enter send_msg_channel_open_confirmation"))
 1039|  3.42k|	CHECKCLEARTOWRITE();
 1040|       |
 1041|  3.42k|	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
  ------------------
  |  |   67|  3.42k|#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION       91 
  ------------------
 1042|  3.42k|	buf_putint(ses.writepayload, channel->remotechan);
 1043|  3.42k|	buf_putint(ses.writepayload, channel->index);
 1044|  3.42k|	buf_putint(ses.writepayload, recvwindow);
 1045|  3.42k|	buf_putint(ses.writepayload, recvmaxpacket);
 1046|       |
 1047|  3.42k|	encrypt_packet();
 1048|  3.42k|	TRACE(("leave send_msg_channel_open_confirmation"))
 1049|  3.42k|}

send_msg_kexinit:
   51|  7.81k|void send_msg_kexinit() {
   52|       |
   53|  7.81k|	CHECKCLEARTOWRITE();
   54|  7.81k|	buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT);
  ------------------
  |  |   36|  7.81k|#define SSH_MSG_KEXINIT                20
  ------------------
   55|       |
   56|       |	/* cookie */
   57|  7.81k|	genrandom(buf_getwriteptr(ses.writepayload, 16), 16);
   58|  7.81k|	buf_incrwritepos(ses.writepayload, 16);
   59|       |
   60|       |	/* kex algos */
   61|  7.81k|	buf_put_algolist(ses.writepayload, sshkex);
   62|       |
   63|       |	/* server_host_key_algorithms */
   64|  7.81k|	buf_put_algolist(ses.writepayload, sigalgs);
   65|       |
   66|       |	/* encryption_algorithms_client_to_server */
   67|  7.81k|	buf_put_algolist(ses.writepayload, sshciphers);
   68|       |
   69|       |	/* encryption_algorithms_server_to_client */
   70|  7.81k|	buf_put_algolist(ses.writepayload, sshciphers);
   71|       |
   72|       |	/* mac_algorithms_client_to_server */
   73|  7.81k|	buf_put_algolist(ses.writepayload, sshhashes);
   74|       |
   75|       |	/* mac_algorithms_server_to_client */
   76|  7.81k|	buf_put_algolist(ses.writepayload, sshhashes);
   77|       |
   78|       |
   79|       |	/* compression_algorithms_client_to_server */
   80|  7.81k|	buf_put_algolist(ses.writepayload, ses.compress_algos_c2s);
   81|       |
   82|       |	/* compression_algorithms_server_to_client */
   83|  7.81k|	buf_put_algolist(ses.writepayload, ses.compress_algos_s2c);
   84|       |
   85|       |	/* languages_client_to_server */
   86|  7.81k|	buf_putstring(ses.writepayload, "", 0);
   87|       |
   88|       |	/* languages_server_to_client */
   89|  7.81k|	buf_putstring(ses.writepayload, "", 0);
   90|       |
   91|       |	/* first_kex_packet_follows */
   92|  7.81k|	buf_putbyte(ses.writepayload, (ses.send_kex_first_guess != NULL));
   93|       |
   94|       |	/* reserved unit32 */
   95|  7.81k|	buf_putint(ses.writepayload, 0);
   96|       |
   97|       |	/* set up transmitted kex packet buffer for hashing. 
   98|       |	 * This is freed after the end of the kex */
   99|  7.81k|	ses.transkexinit = buf_newcopy(ses.writepayload);
  100|       |
  101|  7.81k|	encrypt_packet();
  102|  7.81k|	ses.dataallowed = 0; /* don't send other packets during kex */
  103|       |
  104|  7.81k|	ses.kexstate.sentkexinit = 1;
  105|       |
  106|  7.81k|	ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
  107|       |
  108|  7.81k|	if (ses.send_kex_first_guess) {
  ------------------
  |  Branch (108:6): [True: 0, False: 7.81k]
  ------------------
  109|      0|		ses.newkeys->algo_kex = first_usable_algo(sshkex)->data;
  110|      0|		ses.newkeys->algo_signature = first_usable_algo(sigalgs)->val;
  111|      0|		ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
  112|      0|		ses.send_kex_first_guess();
  113|      0|	}
  114|       |
  115|  7.81k|	TRACE(("DATAALLOWED=0"))
  116|  7.81k|	TRACE(("-> KEXINIT"))
  117|       |
  118|  7.81k|}
send_msg_newkeys:
  161|  6.45k|void send_msg_newkeys() {
  162|       |
  163|  6.45k|	TRACE(("enter send_msg_newkeys"))
  164|       |
  165|       |	/* generate the kexinit request */
  166|  6.45k|	CHECKCLEARTOWRITE();
  167|  6.45k|	buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS);
  ------------------
  |  |   37|  6.45k|#define SSH_MSG_NEWKEYS                21
  ------------------
  168|  6.45k|	encrypt_packet();
  169|       |
  170|       |	
  171|       |	/* set up our state */
  172|  6.45k|	ses.kexstate.sentnewkeys = 1;
  173|  6.45k|	if (ses.kexstate.donefirstkex) {
  ------------------
  |  Branch (173:6): [True: 3.09k, False: 3.36k]
  ------------------
  174|  3.09k|		ses.kexstate.donesecondkex = 1;
  175|  3.09k|	}
  176|  6.45k|	ses.kexstate.donefirstkex = 1;
  177|  6.45k|	ses.dataallowed = 1; /* we can send other packets again now */
  178|  6.45k|	gen_new_keys();
  179|  6.45k|	switch_keys();
  180|       |
  181|  6.45k|	if (ses.kexstate.strict_kex) {
  ------------------
  |  Branch (181:6): [True: 0, False: 6.45k]
  ------------------
  182|      0|		ses.transseq = 0;
  183|      0|	}
  184|       |
  185|  6.45k|	TRACE(("leave send_msg_newkeys"))
  186|  6.45k|}
recv_msg_newkeys:
  189|  6.22k|void recv_msg_newkeys() {
  190|       |
  191|  6.22k|	TRACE(("enter recv_msg_newkeys"))
  192|       |
  193|  6.22k|	ses.kexstate.recvnewkeys = 1;
  194|  6.22k|	switch_keys();
  195|       |
  196|  6.22k|	if (ses.kexstate.strict_kex) {
  ------------------
  |  Branch (196:6): [True: 0, False: 6.22k]
  ------------------
  197|      0|		ses.recvseq = 0;
  198|      0|	}
  199|  6.22k|	ses.kexstate.recvfirstnewkeys = 1;
  200|       |
  201|  6.22k|	TRACE(("leave recv_msg_newkeys"))
  202|  6.22k|}
kexfirstinitialise:
  230|  4.58k|void kexfirstinitialise() {
  231|  4.58k|	kex_setup_compress();
  232|  4.58k|	kexinitialise();
  233|  4.58k|}
recv_msg_kexinit:
  492|  7.30k|void recv_msg_kexinit() {
  493|       |	
  494|  7.30k|	unsigned int kexhashbuf_len = 0;
  495|  7.30k|	unsigned int remote_ident_len = 0;
  496|  7.30k|	unsigned int local_ident_len = 0;
  497|       |
  498|  7.30k|	TRACE(("<- KEXINIT"))
  499|  7.30k|	TRACE(("enter recv_msg_kexinit"))
  500|       |	
  501|  7.30k|	if (!ses.kexstate.sentkexinit) {
  ------------------
  |  Branch (501:6): [True: 3.23k, False: 4.06k]
  ------------------
  502|       |		/* we need to send a kex packet */
  503|  3.23k|		send_msg_kexinit();
  504|  3.23k|		TRACE(("continue recv_msg_kexinit: sent kexinit"))
  505|  3.23k|	}
  506|       |
  507|       |	/* "Once a party has sent a SSH_MSG_KEXINIT message ...
  508|       |	further SSH_MSG_KEXINIT messages MUST NOT be sent" */
  509|  7.30k|	if (ses.kexstate.recvkexinit) {
  ------------------
  |  Branch (509:6): [True: 0, False: 7.30k]
  ------------------
  510|      0|		dropbear_exit("Unexpected KEXINIT");
  511|      0|	}
  512|       |
  513|       |	/* start the kex hash */
  514|  7.30k|	local_ident_len = strlen(LOCAL_IDENT);
  ------------------
  |  |   14|  7.30k|#define LOCAL_IDENT "SSH-2.0-dropbear" IDENT_VERSION_PART
  |  |  ------------------
  |  |  |  |   12|  7.30k|#define IDENT_VERSION_PART "_" DROPBEAR_VERSION
  |  |  |  |  ------------------
  |  |  |  |  |  |    7|  7.30k|#define DROPBEAR_VERSION "2026.91"
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  515|  7.30k|	remote_ident_len = strlen(ses.remoteident);
  516|       |
  517|  7.30k|	kexhashbuf_len = local_ident_len + remote_ident_len
  518|  7.30k|		+ ses.transkexinit->len + ses.payload->len
  519|  7.30k|		+ KEXHASHBUF_MAX_INTS;
  ------------------
  |  |  290|  7.30k|#define KEXHASHBUF_MAX_INTS (MAX_PUBKEY_SIZE + MAX_KEX_PARTS)
  |  |  ------------------
  |  |  |  |  261|  7.30k|#define MAX_PUBKEY_SIZE 600
  |  |  ------------------
  |  |               #define KEXHASHBUF_MAX_INTS (MAX_PUBKEY_SIZE + MAX_KEX_PARTS)
  |  |  ------------------
  |  |  |  |  274|  7.30k|#define MAX_KEX_PARTS (2*4 + 1184 + 1088 + 32*2 + 68)
  |  |  ------------------
  ------------------
  520|       |
  521|  7.30k|	ses.kexhashbuf = buf_new(kexhashbuf_len);
  522|       |
  523|  7.30k|	if (IS_DROPBEAR_CLIENT) {
  ------------------
  |  |  382|  7.30k|#define IS_DROPBEAR_CLIENT (ses.isserver == 0)
  |  |  ------------------
  |  |  |  Branch (382:28): [True: 0, False: 7.30k]
  |  |  ------------------
  ------------------
  524|       |
  525|       |		/* read the peer's choice of algos */
  526|      0|		read_kex_algos();
  527|       |
  528|       |		/* V_C, the client's version string (CR and NL excluded) */
  529|      0|		buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
  ------------------
  |  |   14|      0|#define LOCAL_IDENT "SSH-2.0-dropbear" IDENT_VERSION_PART
  |  |  ------------------
  |  |  |  |   12|      0|#define IDENT_VERSION_PART "_" DROPBEAR_VERSION
  |  |  |  |  ------------------
  |  |  |  |  |  |    7|      0|#define DROPBEAR_VERSION "2026.91"
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  530|       |		/* V_S, the server's version string (CR and NL excluded) */
  531|      0|		buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
  532|       |
  533|       |		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
  534|      0|		buf_putstring(ses.kexhashbuf,
  535|      0|			(const char*)ses.transkexinit->data, ses.transkexinit->len);
  536|       |		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
  537|      0|		buf_setpos(ses.payload, ses.payload_beginning);
  538|      0|		buf_putstring(ses.kexhashbuf,
  539|      0|			(const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
  540|      0|			ses.payload->len-ses.payload->pos);
  541|      0|		ses.requirenext = SSH_MSG_KEXDH_REPLY;
  ------------------
  |  |   39|      0|#define SSH_MSG_KEXDH_REPLY            31
  ------------------
  542|  7.30k|	} else {
  543|       |		/* SERVER */
  544|       |
  545|       |		/* read the peer's choice of algos */
  546|  7.30k|		read_kex_algos();
  547|       |		/* V_C, the client's version string (CR and NL excluded) */
  548|  7.30k|		buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
  549|       |		/* V_S, the server's version string (CR and NL excluded) */
  550|  7.30k|		buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
  ------------------
  |  |   14|  7.30k|#define LOCAL_IDENT "SSH-2.0-dropbear" IDENT_VERSION_PART
  |  |  ------------------
  |  |  |  |   12|  7.30k|#define IDENT_VERSION_PART "_" DROPBEAR_VERSION
  |  |  |  |  ------------------
  |  |  |  |  |  |    7|  7.30k|#define DROPBEAR_VERSION "2026.91"
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  551|       |
  552|       |		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
  553|  7.30k|		buf_setpos(ses.payload, ses.payload_beginning);
  554|  7.30k|		buf_putstring(ses.kexhashbuf, 
  555|  7.30k|			(const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
  556|  7.30k|			ses.payload->len-ses.payload->pos);
  557|       |
  558|       |		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
  559|  7.30k|		buf_putstring(ses.kexhashbuf,
  560|  7.30k|			(const char*)ses.transkexinit->data, ses.transkexinit->len);
  561|       |
  562|  7.30k|		ses.requirenext = SSH_MSG_KEXDH_INIT;
  ------------------
  |  |   38|  7.30k|#define SSH_MSG_KEXDH_INIT             30
  ------------------
  563|  7.30k|	}
  564|       |
  565|  7.30k|	buf_free(ses.transkexinit);
  566|  7.30k|	ses.transkexinit = NULL;
  567|       |	/* the rest of ses.kexhashbuf will be done after DH exchange */
  568|       |
  569|  7.30k|	ses.kexstate.recvkexinit = 1;
  570|       |
  571|  7.30k|	if (ses.kexstate.strict_kex && !ses.kexstate.donefirstkex && ses.recvseq != 1) {
  ------------------
  |  Branch (571:6): [True: 0, False: 7.30k]
  |  Branch (571:33): [True: 0, False: 0]
  |  Branch (571:63): [True: 0, False: 0]
  ------------------
  572|      0|		dropbear_exit("First packet wasn't kexinit");
  573|      0|	}
  574|       |
  575|  7.30k|	TRACE(("leave recv_msg_kexinit"))
  576|  7.30k|}
finish_kexhashbuf:
  579|  6.45k|void finish_kexhashbuf(void) {
  580|  6.45k|	hash_state hs;
  581|  6.45k|	const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
  582|       |
  583|  6.45k|	hash_desc->init(&hs);
  584|  6.45k|	buf_setpos(ses.kexhashbuf, 0);
  585|  6.45k|	hash_desc->process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
  586|  6.45k|			ses.kexhashbuf->len);
  587|  6.45k|	ses.hash = buf_new(hash_desc->hashsize);
  588|  6.45k|	hash_desc->done(&hs, buf_getwriteptr(ses.hash, hash_desc->hashsize));
  589|  6.45k|	buf_setlen(ses.hash, hash_desc->hashsize);
  590|       |
  591|       |#if defined(DEBUG_KEXHASH) && DEBUG_TRACE
  592|       |	if (!debug_trace) {
  593|       |		printhex("kexhashbuf", ses.kexhashbuf->data, ses.kexhashbuf->len);
  594|       |		printhex("kexhash", ses.hash->data, ses.hash->len);
  595|       |	}
  596|       |#endif
  597|       |
  598|  6.45k|	buf_burn_free(ses.kexhashbuf);
  599|  6.45k|	m_burn(&hs, sizeof(hash_state));
  600|  6.45k|	ses.kexhashbuf = NULL;
  601|       |	
  602|       |	/* first time around, we set the session_id to H */
  603|  6.45k|	if (ses.session_id == NULL) {
  ------------------
  |  Branch (603:6): [True: 3.36k, False: 3.09k]
  ------------------
  604|       |		/* create the session_id, this never needs freeing */
  605|  3.36k|		ses.session_id = buf_newcopy(ses.hash);
  606|  3.36k|	}
  607|  6.45k|}
common-kex.c:switch_keys:
  120|  12.6k|static void switch_keys() {
  121|  12.6k|	TRACE2(("enter switch_keys"))
  122|  12.6k|	if (!(ses.kexstate.sentkexinit && ses.kexstate.recvkexinit)) {
  ------------------
  |  Branch (122:8): [True: 12.6k, False: 10]
  |  Branch (122:36): [True: 12.6k, False: 0]
  ------------------
  123|     10|		dropbear_exit("Unexpected newkeys message");
  124|     10|	}
  125|       |
  126|  12.6k|	if (!ses.keys) {
  ------------------
  |  Branch (126:6): [True: 0, False: 12.6k]
  ------------------
  127|      0|		ses.keys = m_malloc(sizeof(*ses.newkeys));
  128|      0|	}
  129|  12.6k|	if (ses.kexstate.recvnewkeys && ses.newkeys->recv.valid) {
  ------------------
  |  Branch (129:6): [True: 6.21k, False: 6.45k]
  |  Branch (129:34): [True: 6.21k, False: 0]
  ------------------
  130|  6.21k|		TRACE(("switch_keys recv"))
  131|       |#ifndef DISABLE_ZLIB
  132|       |		gen_new_zstream_recv();
  133|       |#endif
  134|  6.21k|		ses.keys->recv = ses.newkeys->recv;
  135|  6.21k|		m_burn(&ses.newkeys->recv, sizeof(ses.newkeys->recv));
  136|  6.21k|		ses.newkeys->recv.valid = 0;
  137|  6.21k|	}
  138|  12.6k|	if (ses.kexstate.sentnewkeys && ses.newkeys->trans.valid) {
  ------------------
  |  Branch (138:6): [True: 12.6k, False: 0]
  |  Branch (138:34): [True: 6.45k, False: 6.21k]
  ------------------
  139|  6.45k|		TRACE(("switch_keys trans"))
  140|       |#ifndef DISABLE_ZLIB
  141|       |		gen_new_zstream_trans();
  142|       |#endif
  143|  6.45k|		ses.keys->trans = ses.newkeys->trans;
  144|  6.45k|		m_burn(&ses.newkeys->trans, sizeof(ses.newkeys->trans));
  145|  6.45k|		ses.newkeys->trans.valid = 0;
  146|  6.45k|	}
  147|  12.6k|	if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys)
  ------------------
  |  Branch (147:6): [True: 12.6k, False: 0]
  |  Branch (147:34): [True: 6.21k, False: 6.45k]
  ------------------
  148|  6.21k|	{
  149|  6.21k|		TRACE(("switch_keys done"))
  150|  6.21k|		ses.keys->algo_kex = ses.newkeys->algo_kex;
  151|  6.21k|		ses.keys->algo_hostkey = ses.newkeys->algo_hostkey;
  152|  6.21k|		ses.keys->algo_signature = ses.newkeys->algo_signature;
  153|  6.21k|		m_free(ses.newkeys);
  ------------------
  |  |   24|  6.21k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 6.21k]
  |  |  ------------------
  ------------------
  154|       |		ses.newkeys = NULL;
  155|  6.21k|		kexinitialise();
  156|  6.21k|	}
  157|  12.6k|	TRACE2(("leave switch_keys"))
  158|  12.6k|}
common-kex.c:kex_setup_compress:
  204|  4.58k|static void kex_setup_compress(void) {
  205|  4.58k|#ifdef DISABLE_ZLIB
  206|  4.58k|	ses.compress_algos_c2s = ssh_nocompress;
  207|  4.58k|	ses.compress_algos_s2c = ssh_nocompress;
  208|       |#else
  209|       |
  210|       |	if (!opts.compression) {
  211|       |		ses.compress_algos_c2s = ssh_nocompress;
  212|       |		ses.compress_algos_s2c = ssh_nocompress;
  213|       |		return;
  214|       |	}
  215|       |
  216|       |	if (IS_DROPBEAR_CLIENT) {
  217|       |		/* TODO: should c2s in dbclient be disabled?
  218|       |		 * Current Dropbear server disables it. Disabling it also
  219|       |		 * lets DROPBEAR_CLI_IMMEDIATE_AUTH work (see comment there) */
  220|       |		ses.compress_algos_c2s = ssh_compress;
  221|       |		ses.compress_algos_s2c = ssh_compress;
  222|       |	} else {
  223|       |		ses.compress_algos_c2s = ssh_nocompress;
  224|       |		ses.compress_algos_s2c = ssh_compress;
  225|       |	}
  226|       |#endif
  227|  4.58k|}
common-kex.c:kexinitialise:
  236|  10.7k|static void kexinitialise() {
  237|       |
  238|  10.7k|	TRACE(("kexinitialise()"))
  239|       |
  240|       |	/* sent/recv'd MSG_KEXINIT */
  241|  10.7k|	ses.kexstate.sentkexinit = 0;
  242|  10.7k|	ses.kexstate.recvkexinit = 0;
  243|       |
  244|       |	/* sent/recv'd MSG_NEWKEYS */
  245|  10.7k|	ses.kexstate.recvnewkeys = 0;
  246|  10.7k|	ses.kexstate.sentnewkeys = 0;
  247|       |
  248|       |	/* first_packet_follows */
  249|  10.7k|	ses.kexstate.them_firstfollows = 0;
  250|       |
  251|  10.7k|	ses.kexstate.datatrans = 0;
  252|  10.7k|	ses.kexstate.datarecv = 0;
  253|       |
  254|  10.7k|	ses.kexstate.our_first_follows_matches = 0;
  255|       |
  256|  10.7k|	ses.kexstate.lastkextime = monotonic_now();
  257|       |
  258|  10.7k|}
common-kex.c:gen_new_keys:
  299|  6.45k|static void gen_new_keys() {
  300|       |
  301|  6.45k|	unsigned char C2S_IV[MAX_IV_LEN];
  302|  6.45k|	unsigned char C2S_key[MAX_KEY_LEN];
  303|  6.45k|	unsigned char S2C_IV[MAX_IV_LEN];
  304|  6.45k|	unsigned char S2C_key[MAX_KEY_LEN];
  305|       |	/* unsigned char key[MAX_KEY_LEN]; */
  306|  6.45k|	unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
  307|       |
  308|  6.45k|	hash_state hs;
  309|  6.45k|	const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
  310|  6.45k|	char mactransletter, macrecvletter; /* Client or server specific */
  311|       |
  312|  6.45k|	TRACE(("enter gen_new_keys"))
  313|       |	/* the dh_K and hash are the start of all hashes, we make use of that */
  314|       |
  315|  6.45k|	hash_desc->init(&hs);
  316|  6.45k|	if (ses.dh_K) {
  ------------------
  |  Branch (316:6): [True: 6.45k, False: 0]
  ------------------
  317|  6.45k|		hash_process_mp(hash_desc, &hs, ses.dh_K);
  318|  6.45k|		mp_clear(ses.dh_K);
  319|  6.45k|		m_free(ses.dh_K);
  ------------------
  |  |   24|  6.45k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 6.45k]
  |  |  ------------------
  ------------------
  320|  6.45k|	}
  321|  6.45k|	if (ses.dh_K_bytes) {
  ------------------
  |  Branch (321:6): [True: 0, False: 6.45k]
  ------------------
  322|      0|	    hash_desc->process(&hs, ses.dh_K_bytes->data, ses.dh_K_bytes->len);
  323|      0|		buf_burn_free(ses.dh_K_bytes);
  324|      0|		ses.dh_K_bytes = NULL;
  325|      0|	}
  326|  6.45k|	hash_desc->process(&hs, ses.hash->data, ses.hash->len);
  327|  6.45k|	buf_burn_free(ses.hash);
  328|  6.45k|	ses.hash = NULL;
  329|       |
  330|  6.45k|	if (IS_DROPBEAR_CLIENT) {
  ------------------
  |  |  382|  6.45k|#define IS_DROPBEAR_CLIENT (ses.isserver == 0)
  |  |  ------------------
  |  |  |  Branch (382:28): [True: 0, False: 6.45k]
  |  |  ------------------
  ------------------
  331|      0|		trans_IV	= C2S_IV;
  332|      0|		recv_IV		= S2C_IV;
  333|      0|		trans_key	= C2S_key;
  334|      0|		recv_key	= S2C_key;
  335|      0|		mactransletter = 'E';
  336|      0|		macrecvletter = 'F';
  337|  6.45k|	} else {
  338|  6.45k|		trans_IV	= S2C_IV;
  339|  6.45k|		recv_IV		= C2S_IV;
  340|  6.45k|		trans_key	= S2C_key;
  341|  6.45k|		recv_key	= C2S_key;
  342|  6.45k|		mactransletter = 'F';
  343|  6.45k|		macrecvletter = 'E';
  344|  6.45k|	}
  345|       |
  346|  6.45k|	hashkeys(C2S_IV, sizeof(C2S_IV), &hs, 'A');
  347|  6.45k|	hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B');
  348|  6.45k|	hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C');
  349|  6.45k|	hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D');
  350|       |
  351|  6.45k|	if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
  ------------------
  |  Branch (351:6): [True: 6.45k, False: 0]
  ------------------
  352|  6.45k|		int recv_cipher = -1;
  353|  6.45k|		if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) {
  ------------------
  |  Branch (353:7): [True: 6.01k, False: 441]
  ------------------
  354|  6.01k|			recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
  355|  6.01k|			if (recv_cipher < 0) {
  ------------------
  |  Branch (355:8): [True: 0, False: 6.01k]
  ------------------
  356|      0|				dropbear_exit("Crypto error");
  357|      0|			}
  358|  6.01k|		}
  359|  6.45k|		if (ses.newkeys->recv.crypt_mode->start(recv_cipher, 
  ------------------
  |  Branch (359:7): [True: 0, False: 6.45k]
  ------------------
  360|  6.45k|				recv_IV, recv_key, 
  361|  6.45k|				ses.newkeys->recv.algo_crypt->keysize, 0, 
  362|  6.45k|				&ses.newkeys->recv.cipher_state) != CRYPT_OK) {
  363|      0|			dropbear_exit("Crypto error");
  364|      0|		}
  365|  6.45k|	}
  366|       |
  367|  6.45k|	if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) {
  ------------------
  |  Branch (367:6): [True: 6.45k, False: 0]
  ------------------
  368|  6.45k|		int trans_cipher = -1;
  369|  6.45k|		if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) {
  ------------------
  |  Branch (369:7): [True: 6.01k, False: 438]
  ------------------
  370|  6.01k|			trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
  371|  6.01k|			if (trans_cipher < 0) {
  ------------------
  |  Branch (371:8): [True: 0, False: 6.01k]
  ------------------
  372|      0|				dropbear_exit("Crypto error");
  373|      0|			}
  374|  6.01k|		}
  375|  6.45k|		if (ses.newkeys->trans.crypt_mode->start(trans_cipher, 
  ------------------
  |  Branch (375:7): [True: 0, False: 6.45k]
  ------------------
  376|  6.45k|				trans_IV, trans_key, 
  377|  6.45k|				ses.newkeys->trans.algo_crypt->keysize, 0, 
  378|  6.45k|				&ses.newkeys->trans.cipher_state) != CRYPT_OK) {
  379|      0|			dropbear_exit("Crypto error");
  380|      0|		}
  381|  6.45k|	}
  382|       |
  383|  6.45k|	if (ses.newkeys->trans.algo_mac->hash_desc != NULL) {
  ------------------
  |  Branch (383:6): [True: 6.01k, False: 438]
  ------------------
  384|  6.01k|		hashkeys(ses.newkeys->trans.mackey, 
  385|  6.01k|				ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
  386|  6.01k|		ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hash_desc->name);
  387|  6.01k|	}
  388|       |
  389|  6.45k|	if (ses.newkeys->recv.algo_mac->hash_desc != NULL) {
  ------------------
  |  Branch (389:6): [True: 0, False: 6.45k]
  ------------------
  390|      0|		hashkeys(ses.newkeys->recv.mackey, 
  391|      0|				ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
  392|      0|		ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hash_desc->name);
  393|      0|	}
  394|       |
  395|       |	/* Ready to switch over */
  396|  6.45k|	ses.newkeys->trans.valid = 1;
  397|  6.45k|	ses.newkeys->recv.valid = 1;
  398|       |
  399|  6.45k|	m_burn(C2S_IV, sizeof(C2S_IV));
  400|  6.45k|	m_burn(C2S_key, sizeof(C2S_key));
  401|  6.45k|	m_burn(S2C_IV, sizeof(S2C_IV));
  402|  6.45k|	m_burn(S2C_key, sizeof(S2C_key));
  403|  6.45k|	m_burn(&hs, sizeof(hash_state));
  404|       |
  405|  6.45k|	TRACE(("leave gen_new_keys"))
  406|  6.45k|}
common-kex.c:hashkeys:
  267|  31.8k|		const hash_state * hs, const unsigned char X) {
  268|       |
  269|  31.8k|	const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
  270|  31.8k|	hash_state hs2;
  271|  31.8k|	unsigned int offset;
  272|  31.8k|	unsigned char tmpout[MAX_HASH_SIZE];
  273|       |
  274|  31.8k|	memcpy(&hs2, hs, sizeof(hash_state));
  275|  31.8k|	hash_desc->process(&hs2, &X, 1);
  276|  31.8k|	hash_desc->process(&hs2, ses.session_id->data, ses.session_id->len);
  277|  31.8k|	hash_desc->done(&hs2, tmpout);
  278|  31.8k|	memcpy(out, tmpout, MIN(hash_desc->hashsize, outlen));
  ------------------
  |  Branch (278:22): [True: 8.32k, False: 23.5k]
  ------------------
  279|  31.8k|	for (offset = hash_desc->hashsize; 
  280|  40.1k|			offset < outlen; 
  ------------------
  |  Branch (280:4): [True: 8.32k, False: 31.8k]
  ------------------
  281|  31.8k|			offset += hash_desc->hashsize)
  282|  8.32k|	{
  283|       |		/* need to extend */
  284|  8.32k|		memcpy(&hs2, hs, sizeof(hash_state));
  285|  8.32k|		hash_desc->process(&hs2, out, offset);
  286|  8.32k|		hash_desc->done(&hs2, tmpout);
  287|       |		memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize));
  ------------------
  |  Branch (287:32): [True: 804, False: 7.52k]
  ------------------
  288|  8.32k|	}
  289|  31.8k|	m_burn(&hs2, sizeof(hash_state));
  290|  31.8k|}
common-kex.c:read_kex_algos:
  611|  7.30k|static void read_kex_algos() {
  612|       |
  613|       |	/* for asymmetry */
  614|  7.30k|	algo_type * c2s_hash_algo = NULL;
  615|  7.30k|	algo_type * s2c_hash_algo = NULL;
  616|  7.30k|	algo_type * c2s_cipher_algo = NULL;
  617|  7.30k|	algo_type * s2c_cipher_algo = NULL;
  618|  7.30k|	algo_type * c2s_comp_algo = NULL;
  619|  7.30k|	algo_type * s2c_comp_algo = NULL;
  620|       |	/* the generic one */
  621|  7.30k|	algo_type * algo = NULL;
  622|       |
  623|       |	/* which algo couldn't match */
  624|  7.30k|	char * erralgo = NULL;
  625|       |
  626|  7.30k|	int goodguess = 0;
  627|  7.30k|	int allgood = 1; /* we AND this with each goodguess and see if its still
  628|       |						true after */
  629|  7.30k|	int kexguess2 = 0;
  630|       |
  631|  7.30k|	buf_incrpos(ses.payload, 16); /* start after the cookie */
  632|       |
  633|  7.30k|	memset(ses.newkeys, 0x0, sizeof(*ses.newkeys));
  634|       |
  635|       |	/* kex_algorithms */
  636|  7.30k|#if DROPBEAR_KEXGUESS2
  637|  7.30k|	if (buf_has_algo(ses.payload, KEXGUESS2_ALGO_NAME) == DROPBEAR_SUCCESS) {
  ------------------
  |  |  137|  7.30k|#define KEXGUESS2_ALGO_NAME "kexguess2@matt.ucc.asn.au"
  ------------------
              	if (buf_has_algo(ses.payload, KEXGUESS2_ALGO_NAME) == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|  7.30k|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (637:6): [True: 8, False: 7.29k]
  ------------------
  638|      8|		kexguess2 = 1;
  639|      8|	}
  640|  7.30k|#endif
  641|       |
  642|  7.30k|#if DROPBEAR_EXT_INFO
  643|       |	/* Determine if SSH_MSG_EXT_INFO messages should be sent.
  644|       |	Should be done for the first key exchange. Only required on server side
  645|       |    for server-sig-algs */
  646|  7.30k|	if (IS_DROPBEAR_SERVER) {
  ------------------
  |  |  381|  7.30k|#define IS_DROPBEAR_SERVER (ses.isserver == 1)
  |  |  ------------------
  |  |  |  Branch (381:28): [True: 7.21k, False: 95]
  |  |  ------------------
  ------------------
  647|  7.21k|		if (!ses.kexstate.donefirstkex) {
  ------------------
  |  Branch (647:7): [True: 3.99k, False: 3.21k]
  ------------------
  648|  3.99k|			if (buf_has_algo(ses.payload, SSH_EXT_INFO_C) == DROPBEAR_SUCCESS) {
  ------------------
  |  |  100|  3.99k|#define SSH_EXT_INFO_C "ext-info-c"
  ------------------
              			if (buf_has_algo(ses.payload, SSH_EXT_INFO_C) == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|  3.99k|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (648:8): [True: 14, False: 3.98k]
  ------------------
  649|     14|				ses.allow_ext_info = 1;
  650|     14|			}
  651|  3.99k|		}
  652|  7.21k|	}
  653|  7.30k|#endif
  654|       |
  655|  7.30k|	if (!ses.kexstate.donefirstkex) {
  ------------------
  |  Branch (655:6): [True: 3.99k, False: 3.31k]
  ------------------
  656|  3.99k|		const char* strict_name;
  657|  3.99k|		if (IS_DROPBEAR_CLIENT) {
  ------------------
  |  |  382|  3.99k|#define IS_DROPBEAR_CLIENT (ses.isserver == 0)
  |  |  ------------------
  |  |  |  Branch (382:28): [True: 0, False: 3.99k]
  |  |  ------------------
  ------------------
  658|      0|			strict_name = SSH_STRICT_KEX_S;
  ------------------
  |  |  104|      0|#define SSH_STRICT_KEX_S "kex-strict-s-v00@openssh.com"
  ------------------
  659|  3.99k|		} else {
  660|  3.99k|			strict_name = SSH_STRICT_KEX_C;
  ------------------
  |  |  105|  3.99k|#define SSH_STRICT_KEX_C "kex-strict-c-v00@openssh.com"
  ------------------
  661|  3.99k|		}
  662|  3.99k|		if (buf_has_algo(ses.payload, strict_name) == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|  3.99k|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (662:7): [True: 2, False: 3.99k]
  ------------------
  663|      2|			ses.kexstate.strict_kex = 1;
  664|      2|		}
  665|  3.99k|	}
  666|       |
  667|  7.30k|	algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
  668|  7.30k|	allgood &= goodguess;
  669|  7.30k|	if (algo == NULL || algo->data == NULL) {
  ------------------
  |  Branch (669:6): [True: 307, False: 6.99k]
  |  Branch (669:22): [True: 6, False: 6.99k]
  ------------------
  670|       |		/* kexguess2, ext-info-c, ext-info-s should not match negotiation */
  671|    218|		erralgo = "kex";
  672|    218|		goto error;
  673|    218|	}
  674|  7.08k|	TRACE(("kexguess2 %d", kexguess2))
  675|  7.08k|	DEBUG3(("kex algo %s", algo->name))
  676|  7.08k|	ses.newkeys->algo_kex = algo->data;
  677|       |
  678|       |	/* server_host_key_algorithms */
  679|  7.08k|	algo = buf_match_algo(ses.payload, sigalgs, kexguess2, &goodguess);
  680|  7.08k|	allgood &= goodguess;
  681|  7.08k|	if (algo == NULL) {
  ------------------
  |  Branch (681:6): [True: 21, False: 7.06k]
  ------------------
  682|     21|		erralgo = "hostkey";
  683|     21|		goto error;
  684|     21|	}
  685|  7.06k|	DEBUG2(("hostkey algo %s", algo->name))
  686|  7.06k|	ses.newkeys->algo_signature = algo->val;
  687|  7.06k|	ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
  688|       |
  689|       |	/* encryption_algorithms_client_to_server */
  690|  7.06k|	c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
  691|  7.06k|	if (c2s_cipher_algo == NULL) {
  ------------------
  |  Branch (691:6): [True: 8, False: 7.05k]
  ------------------
  692|      8|		erralgo = "enc c->s";
  693|      8|		goto error;
  694|      8|	}
  695|  7.05k|	DEBUG2(("enc  c2s is %s", c2s_cipher_algo->name))
  696|       |
  697|       |	/* encryption_algorithms_server_to_client */
  698|  7.05k|	s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
  699|  7.05k|	if (s2c_cipher_algo == NULL) {
  ------------------
  |  Branch (699:6): [True: 8, False: 7.05k]
  ------------------
  700|      8|		erralgo = "enc s->c";
  701|      8|		goto error;
  702|      8|	}
  703|  7.05k|	DEBUG2(("enc  s2c is %s", s2c_cipher_algo->name))
  704|       |
  705|       |	/* mac_algorithms_client_to_server */
  706|  7.05k|	c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
  707|  7.05k|#if DROPBEAR_AEAD_MODE
  708|  7.05k|	if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) {
  ------------------
  |  Branch (708:6): [True: 478, False: 6.57k]
  ------------------
  709|    478|		c2s_hash_algo = NULL;
  710|    478|	} else
  711|  6.57k|#endif
  712|  6.57k|	if (c2s_hash_algo == NULL) {
  ------------------
  |  Branch (712:6): [True: 7, False: 6.56k]
  ------------------
  713|      7|		erralgo = "mac c->s";
  714|      7|		goto error;
  715|      7|	}
  716|  7.04k|	DEBUG2(("hmac c2s is %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>"))
  717|       |
  718|       |	/* mac_algorithms_server_to_client */
  719|  7.04k|	s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
  720|  7.04k|#if DROPBEAR_AEAD_MODE
  721|  7.04k|	if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) {
  ------------------
  |  Branch (721:6): [True: 468, False: 6.57k]
  ------------------
  722|    468|		s2c_hash_algo = NULL;
  723|    468|	} else
  724|  6.57k|#endif
  725|  6.57k|	if (s2c_hash_algo == NULL) {
  ------------------
  |  Branch (725:6): [True: 11, False: 6.56k]
  ------------------
  726|     11|		erralgo = "mac s->c";
  727|     11|		goto error;
  728|     11|	}
  729|  7.03k|	DEBUG2(("hmac s2c is %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>"))
  730|       |
  731|       |	/* compression_algorithms_client_to_server */
  732|  7.03k|	c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos_c2s, 0, NULL);
  733|  7.03k|	if (c2s_comp_algo == NULL) {
  ------------------
  |  Branch (733:6): [True: 5, False: 7.02k]
  ------------------
  734|      5|		erralgo = "comp c->s";
  735|      5|		goto error;
  736|      5|	}
  737|  7.02k|	DEBUG2(("comp c2s is %s", c2s_comp_algo->name))
  738|       |
  739|       |	/* compression_algorithms_server_to_client */
  740|  7.02k|	s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos_s2c, 0, NULL);
  741|  7.02k|	if (s2c_comp_algo == NULL) {
  ------------------
  |  Branch (741:6): [True: 4, False: 7.02k]
  ------------------
  742|      4|		erralgo = "comp s->c";
  743|      4|		goto error;
  744|      4|	}
  745|  7.02k|	DEBUG2(("comp s2c is %s", s2c_comp_algo->name))
  746|       |
  747|       |	/* languages_client_to_server */
  748|  7.02k|	buf_eatstring(ses.payload);
  749|       |
  750|       |	/* languages_server_to_client */
  751|  7.02k|	buf_eatstring(ses.payload);
  752|       |
  753|       |	/* their first_kex_packet_follows */
  754|  7.02k|	if (buf_getbool(ses.payload)) {
  ------------------
  |  Branch (754:6): [True: 110, False: 6.91k]
  ------------------
  755|    110|		TRACE(("them kex firstfollows. allgood %d", allgood))
  756|    110|		ses.kexstate.them_firstfollows = 1;
  757|       |		/* if the guess wasn't good, we ignore the packet sent */
  758|    110|		if (!allgood) {
  ------------------
  |  Branch (758:7): [True: 110, False: 0]
  ------------------
  759|    110|			ses.ignorenext = 1;
  760|    110|		}
  761|    110|	}
  762|       |
  763|       |	/* Handle the asymmetry */
  764|  7.02k|	if (IS_DROPBEAR_CLIENT) {
  ------------------
  |  |  382|  7.02k|#define IS_DROPBEAR_CLIENT (ses.isserver == 0)
  |  |  ------------------
  |  |  |  Branch (382:28): [True: 0, False: 7.02k]
  |  |  ------------------
  ------------------
  765|      0|		ses.newkeys->recv.algo_crypt = 
  766|      0|			(struct dropbear_cipher*)s2c_cipher_algo->data;
  767|      0|		ses.newkeys->trans.algo_crypt = 
  768|      0|			(struct dropbear_cipher*)c2s_cipher_algo->data;
  769|      0|		ses.newkeys->recv.crypt_mode = 
  770|      0|			(struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
  771|      0|		ses.newkeys->trans.crypt_mode =
  772|      0|			(struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
  773|      0|		ses.newkeys->recv.algo_mac = 
  774|      0|#if DROPBEAR_AEAD_MODE
  775|      0|			s2c_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
  ------------------
  |  Branch (775:4): [True: 0, False: 0]
  ------------------
  776|      0|#endif
  777|      0|			(struct dropbear_hash*)s2c_hash_algo->data;
  778|      0|		ses.newkeys->trans.algo_mac = 
  779|      0|#if DROPBEAR_AEAD_MODE
  780|      0|			c2s_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
  ------------------
  |  Branch (780:4): [True: 0, False: 0]
  ------------------
  781|      0|#endif
  782|      0|			(struct dropbear_hash*)c2s_hash_algo->data;
  783|      0|		ses.newkeys->recv.algo_comp = s2c_comp_algo->val;
  784|      0|		ses.newkeys->trans.algo_comp = c2s_comp_algo->val;
  785|  7.02k|	} else {
  786|       |		/* SERVER */
  787|  7.02k|		ses.newkeys->recv.algo_crypt = 
  788|  7.02k|			(struct dropbear_cipher*)c2s_cipher_algo->data;
  789|  7.02k|		ses.newkeys->trans.algo_crypt = 
  790|  7.02k|			(struct dropbear_cipher*)s2c_cipher_algo->data;
  791|  7.02k|		ses.newkeys->recv.crypt_mode =
  792|  7.02k|			(struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
  793|  7.02k|		ses.newkeys->trans.crypt_mode =
  794|  7.02k|			(struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
  795|  7.02k|		ses.newkeys->recv.algo_mac = 
  796|  7.02k|#if DROPBEAR_AEAD_MODE
  797|  7.02k|			c2s_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
  ------------------
  |  Branch (797:4): [True: 466, False: 6.55k]
  ------------------
  798|  7.02k|#endif
  799|  7.02k|			(struct dropbear_hash*)c2s_hash_algo->data;
  800|  7.02k|		ses.newkeys->trans.algo_mac = 
  801|  7.02k|#if DROPBEAR_AEAD_MODE
  802|  7.02k|			s2c_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
  ------------------
  |  Branch (802:4): [True: 461, False: 6.56k]
  ------------------
  803|  7.02k|#endif
  804|  7.02k|			(struct dropbear_hash*)s2c_hash_algo->data;
  805|  7.02k|		ses.newkeys->recv.algo_comp = c2s_comp_algo->val;
  806|  7.02k|		ses.newkeys->trans.algo_comp = s2c_comp_algo->val;
  807|  7.02k|	}
  808|       |
  809|  7.02k|#if DROPBEAR_FUZZ
  810|  7.02k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (810:6): [True: 6.79k, False: 227]
  ------------------
  811|  6.79k|		fuzz_kex_fakealgos();
  812|  6.79k|	}
  813|  7.02k|#endif
  814|       |
  815|       |	/* reserved for future extensions */
  816|  7.02k|	buf_getint(ses.payload);
  817|       |
  818|  7.02k|	if (ses.send_kex_first_guess && allgood) {
  ------------------
  |  Branch (818:6): [True: 0, False: 7.02k]
  |  Branch (818:34): [True: 0, False: 0]
  ------------------
  819|      0|		TRACE(("our_first_follows_matches 1"))
  820|      0|		ses.kexstate.our_first_follows_matches = 1;
  821|      0|	}
  822|  7.02k|	return;
  823|       |
  824|    282|error:
  825|    282|	dropbear_exit("No matching algo %s", erralgo);
  826|  7.02k|}

common_session_init:
   47|  4.58k|void common_session_init(int sock_in, int sock_out) {
   48|  4.58k|	time_t now;
   49|       |
   50|       |#if DEBUG_TRACE
   51|       |	debug_start_net();
   52|       |#endif
   53|       |
   54|  4.58k|	TRACE(("enter session_init"))
   55|       |
   56|  4.58k|	ses.sock_in = sock_in;
   57|  4.58k|	ses.sock_out = sock_out;
   58|  4.58k|	ses.maxfd = MAX(sock_in, sock_out);
  ------------------
  |  Branch (58:14): [True: 0, False: 4.58k]
  ------------------
   59|       |
   60|  4.58k|	if (sock_in >= 0) {
  ------------------
  |  Branch (60:6): [True: 4.58k, False: 0]
  ------------------
   61|  4.58k|		setnonblocking(sock_in);
   62|  4.58k|	}
   63|  4.58k|	if (sock_out >= 0) {
  ------------------
  |  Branch (63:6): [True: 4.58k, False: 0]
  ------------------
   64|  4.58k|		setnonblocking(sock_out);
   65|  4.58k|	}
   66|       |
   67|  4.58k|	ses.socket_prio = DROPBEAR_PRIO_NORMAL;
   68|       |	/* Sets it to lowdelay */
   69|  4.58k|	update_channel_prio();
   70|       |
   71|       |#if !DROPBEAR_SVR_MULTIUSER
   72|       |	/* A sanity check to prevent an accidental configuration option
   73|       |	   leaving multiuser systems exposed */
   74|       |	{
   75|       |		int ret;
   76|       |		errno = 0;
   77|       |		ret = getgroups(0, NULL);
   78|       |		if (!(ret == -1 && errno == ENOSYS)) {
   79|       |			dropbear_exit("Non-multiuser Dropbear requires a non-multiuser kernel");
   80|       |		}
   81|       |	}
   82|       |#endif
   83|       |
   84|  4.58k|	now = monotonic_now();
   85|  4.58k|	ses.connect_time = now;
   86|  4.58k|	ses.last_packet_time_keepalive_recv = now;
   87|  4.58k|	ses.last_packet_time_idle = now;
   88|  4.58k|	ses.last_packet_time_any_sent = 0;
   89|  4.58k|	ses.last_packet_time_keepalive_sent = 0;
   90|       |	
   91|  4.58k|#if DROPBEAR_FUZZ
   92|  4.58k|	if (!fuzz.fuzzing)
  ------------------
  |  Branch (92:6): [True: 0, False: 4.58k]
  ------------------
   93|      0|#endif
   94|      0|	{
   95|      0|	if (pipe(ses.signal_pipe) < 0) {
  ------------------
  |  Branch (95:6): [True: 0, False: 0]
  ------------------
   96|      0|		dropbear_exit("Signal pipe failed");
   97|      0|	}
   98|      0|	setnonblocking(ses.signal_pipe[0]);
   99|      0|	setnonblocking(ses.signal_pipe[1]);
  100|      0|	ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[0]);
  ------------------
  |  Branch (100:14): [True: 0, False: 0]
  ------------------
  101|      0|	ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[1]);
  ------------------
  |  Branch (101:14): [True: 0, False: 0]
  ------------------
  102|      0|	}
  103|       |	
  104|  4.58k|	ses.writepayload = buf_new(TRANS_MAX_PAYLOAD_LEN);
  ------------------
  |  |  560|  4.58k|#define TRANS_MAX_PAYLOAD_LEN 16384
  ------------------
  105|  4.58k|	ses.transseq = 0;
  106|       |
  107|  4.58k|	ses.readbuf = NULL;
  108|  4.58k|	ses.payload = NULL;
  109|  4.58k|	ses.recvseq = 0;
  110|       |
  111|  4.58k|	initqueue(&ses.writequeue);
  112|       |
  113|  4.58k|	ses.requirenext = SSH_MSG_KEXINIT;
  ------------------
  |  |   36|  4.58k|#define SSH_MSG_KEXINIT                20
  ------------------
  114|  4.58k|	ses.dataallowed = 1; /* we can send data until we actually 
  115|       |							send the SSH_MSG_KEXINIT */
  116|  4.58k|	ses.ignorenext = 0;
  117|  4.58k|	ses.lastpacket = 0;
  118|  4.58k|	ses.reply_queue_head = NULL;
  119|  4.58k|	ses.reply_queue_tail = NULL;
  120|       |
  121|       |	/* set all the algos to none */
  122|  4.58k|	ses.keys = (struct key_context*)m_malloc(sizeof(struct key_context));
  123|  4.58k|	ses.newkeys = NULL;
  124|  4.58k|	ses.keys->recv.algo_crypt = &dropbear_nocipher;
  125|  4.58k|	ses.keys->trans.algo_crypt = &dropbear_nocipher;
  126|  4.58k|	ses.keys->recv.crypt_mode = &dropbear_mode_none;
  127|  4.58k|	ses.keys->trans.crypt_mode = &dropbear_mode_none;
  128|       |	
  129|  4.58k|	ses.keys->recv.algo_mac = &dropbear_nohash;
  130|  4.58k|	ses.keys->trans.algo_mac = &dropbear_nohash;
  131|       |
  132|  4.58k|	ses.keys->algo_kex = NULL;
  133|  4.58k|	ses.keys->algo_hostkey = -1;
  134|  4.58k|	ses.keys->recv.algo_comp = DROPBEAR_COMP_NONE;
  135|  4.58k|	ses.keys->trans.algo_comp = DROPBEAR_COMP_NONE;
  136|       |
  137|       |#ifndef DISABLE_ZLIB
  138|       |	ses.keys->recv.zstream = NULL;
  139|       |	ses.keys->trans.zstream = NULL;
  140|       |#endif
  141|       |
  142|       |	/* key exchange buffers */
  143|  4.58k|	ses.session_id = NULL;
  144|  4.58k|	ses.kexhashbuf = NULL;
  145|  4.58k|	ses.transkexinit = NULL;
  146|  4.58k|	ses.dh_K = NULL;
  147|  4.58k|	ses.remoteident = NULL;
  148|       |
  149|  4.58k|	ses.chantypes = NULL;
  150|       |
  151|  4.58k|	ses.allowprivport = 0;
  152|       |
  153|       |#if DROPBEAR_PLUGIN
  154|       |        ses.plugin_session = NULL;
  155|       |#endif
  156|       |
  157|  4.58k|	TRACE(("leave session_init"))
  158|  4.58k|}
session_loop:
  160|  4.58k|void session_loop(void(*loophandler)(void)) {
  161|       |
  162|  4.58k|	fd_set readfd, writefd;
  163|  4.58k|	struct timeval timeout;
  164|  4.58k|	int val;
  165|       |
  166|       |	/* main loop, select()s for all sockets in use */
  167|   302k|	for(;;) {
  168|   302k|		const int writequeue_has_space = (ses.writequeue_len <= 2*TRANS_MAX_PAYLOAD_LEN);
  ------------------
  |  |  560|   302k|#define TRANS_MAX_PAYLOAD_LEN 16384
  ------------------
  169|       |
  170|   302k|		timeout.tv_sec = select_timeout();
  171|   302k|		timeout.tv_usec = 0;
  172|   302k|		DROPBEAR_FD_ZERO(&writefd);
  ------------------
  |  |  106|   302k|#define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds)
  ------------------
  |  Branch (172:3): [Folded, False: 302k]
  ------------------
  173|   302k|		DROPBEAR_FD_ZERO(&readfd);
  ------------------
  |  |  106|   302k|#define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds)
  ------------------
  |  Branch (173:3): [Folded, False: 302k]
  ------------------
  174|       |
  175|   302k|		dropbear_assert(ses.payload == NULL);
  ------------------
  |  |   84|   302k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 302k]
  |  |  |  Branch (84:93): [Folded, False: 302k]
  |  |  ------------------
  ------------------
  176|       |
  177|       |		/* We get woken up when signal handlers write to this pipe.
  178|       |		   SIGCHLD in svr-chansession is the only one currently. */
  179|   302k|#if DROPBEAR_FUZZ
  180|   302k|		if (!fuzz.fuzzing) 
  ------------------
  |  Branch (180:7): [True: 0, False: 302k]
  ------------------
  181|      0|#endif
  182|      0|		{
  183|      0|		FD_SET(ses.signal_pipe[0], &readfd);
  184|      0|		}
  185|       |
  186|       |		/* set up for channels which can be read/written */
  187|   302k|		setchannelfds(&readfd, &writefd, writequeue_has_space);
  188|       |
  189|       |		/* Pending connections to test */
  190|   302k|		set_connect_fds(&writefd);
  191|       |
  192|       |		/* We delay reading from the input socket during initial setup until
  193|       |		after we have written out our initial KEXINIT packet (empty writequeue). 
  194|       |		This means our initial packet can be in-flight while we're doing a blocking
  195|       |		read for the remote ident.
  196|       |		We also avoid reading from the socket if the writequeue is full, that avoids
  197|       |		replies backing up */
  198|   302k|		if (ses.sock_in != -1 
  ------------------
  |  Branch (198:7): [True: 302k, False: 0]
  ------------------
  199|   302k|			&& (ses.remoteident || isempty(&ses.writequeue)) 
  ------------------
  |  Branch (199:8): [True: 288k, False: 13.8k]
  |  Branch (199:27): [True: 4.67k, False: 9.16k]
  ------------------
  200|   293k|			&& writequeue_has_space) {
  ------------------
  |  Branch (200:7): [True: 287k, False: 6.26k]
  ------------------
  201|   287k|			FD_SET(ses.sock_in, &readfd);
  202|   287k|		}
  203|       |
  204|       |		/* Ordering is important, this test must occur after any other function
  205|       |		might have queued packets (such as connection handlers) */
  206|   302k|		if (ses.sock_out != -1 && !isempty(&ses.writequeue)) {
  ------------------
  |  Branch (206:7): [True: 302k, False: 0]
  |  Branch (206:29): [True: 56.6k, False: 245k]
  ------------------
  207|  56.6k|			FD_SET(ses.sock_out, &writefd);
  208|  56.6k|		}
  209|       |
  210|   302k|		val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout);
  ------------------
  |  |   53|   302k|        wrapfd_select(nfds, readfds, writefds, exceptfds, timeout)
  ------------------
  211|       |
  212|   302k|		if (ses.exitflag) {
  ------------------
  |  Branch (212:7): [True: 0, False: 302k]
  ------------------
  213|      0|			dropbear_exit("Terminated by signal");
  214|      0|		}
  215|       |		
  216|   302k|		if (val < 0 && errno != EINTR) {
  ------------------
  |  Branch (216:7): [True: 257, False: 302k]
  |  Branch (216:18): [True: 0, False: 257]
  ------------------
  217|      0|			dropbear_exit("Error in select");
  218|      0|		}
  219|       |
  220|   302k|		if (val <= 0) {
  ------------------
  |  Branch (220:7): [True: 15.6k, False: 287k]
  ------------------
  221|       |			/* If we were interrupted or the select timed out, we still
  222|       |			 * want to iterate over channels etc for reading, to handle
  223|       |			 * server processes exiting etc. 
  224|       |			 * We don't want to read/write FDs. */
  225|  15.6k|			DROPBEAR_FD_ZERO(&writefd);
  ------------------
  |  |  106|  15.6k|#define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds)
  ------------------
  |  Branch (225:4): [Folded, False: 15.6k]
  ------------------
  226|  15.6k|			DROPBEAR_FD_ZERO(&readfd);
  ------------------
  |  |  106|  15.6k|#define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds)
  ------------------
  |  Branch (226:4): [Folded, False: 15.6k]
  ------------------
  227|  15.6k|		}
  228|       |		
  229|       |		/* We'll just empty out the pipe if required. We don't do
  230|       |		any thing with the data, since the pipe's purpose is purely to
  231|       |		wake up the select() above. */
  232|   302k|		ses.channel_signal_pending = 0;
  233|   302k|		if (FD_ISSET(ses.signal_pipe[0], &readfd)) {
  ------------------
  |  Branch (233:7): [True: 0, False: 302k]
  ------------------
  234|      0|			char x;
  235|      0|			TRACE(("signal pipe set"))
  236|      0|			while (read(ses.signal_pipe[0], &x, 1) > 0) {}
  ------------------
  |  |   55|      0|#define read(fd, buf, count) wrapfd_read(fd, buf, count)
  ------------------
  |  Branch (236:11): [True: 0, False: 0]
  ------------------
  237|      0|			ses.channel_signal_pending = 1;
  238|      0|		}
  239|       |
  240|       |		/* check for auth timeout, rekeying required etc */
  241|   302k|		checktimeouts();
  242|       |
  243|       |		/* process session socket's incoming data */
  244|   302k|		if (ses.sock_in != -1) {
  ------------------
  |  Branch (244:7): [True: 302k, False: 0]
  ------------------
  245|   302k|			if (FD_ISSET(ses.sock_in, &readfd)) {
  ------------------
  |  Branch (245:8): [True: 230k, False: 71.7k]
  ------------------
  246|   230k|				if (!ses.remoteident) {
  ------------------
  |  Branch (246:9): [True: 4.58k, False: 226k]
  ------------------
  247|       |					/* blocking read of the version string */
  248|  4.58k|					read_session_identification();
  249|   226k|				} else {
  250|   226k|					read_packet();
  251|   226k|				}
  252|   230k|			}
  253|       |			
  254|       |			/* Process the decrypted packet. After this, the read buffer
  255|       |			 * will be ready for a new packet */
  256|   302k|			if (ses.payload != NULL) {
  ------------------
  |  Branch (256:8): [True: 41.0k, False: 261k]
  ------------------
  257|  41.0k|				process_packet();
  258|  41.0k|			}
  259|   302k|		}
  260|       |
  261|       |		/* if required, flush out any queued reply packets that
  262|       |		were being held up during a KEX */
  263|   302k|		maybe_flush_reply_queue();
  264|       |
  265|   302k|		handle_connect_fds(&writefd);
  266|       |
  267|       |		/* loop handler prior to channelio, in case the server loophandler closes
  268|       |		channels on process exit */
  269|   302k|		loophandler();
  270|       |
  271|       |		/* process pipes etc for the channels, ses.dataallowed == 0
  272|       |		 * during rekeying ) */
  273|   302k|		channelio(&readfd, &writefd);
  274|       |
  275|       |		/* process session socket's outgoing data */
  276|   302k|		if (ses.sock_out != -1) {
  ------------------
  |  Branch (276:7): [True: 298k, False: 4.58k]
  ------------------
  277|   298k|			if (!isempty(&ses.writequeue)) {
  ------------------
  |  Branch (277:8): [True: 91.7k, False: 206k]
  ------------------
  278|  91.7k|				write_packet();
  279|  91.7k|			}
  280|   298k|		}
  281|       |
  282|   302k|	} /* for(;;) */
  283|       |	
  284|       |	/* Not reached */
  285|  4.58k|}
session_cleanup:
  296|  4.58k|void session_cleanup() {
  297|       |	
  298|  4.58k|	TRACE(("enter session_cleanup"))
  299|       |	
  300|       |	/* we can't cleanup if we don't know the session state */
  301|  4.58k|	if (!ses.init_done) {
  ------------------
  |  Branch (301:6): [True: 0, False: 4.58k]
  ------------------
  302|      0|		TRACE(("leave session_cleanup: !ses.init_done"))
  303|      0|		return;
  304|      0|	}
  305|       |
  306|       |	/* BEWARE of changing order of functions here. */
  307|       |
  308|       |	/* Must be before extra_session_cleanup() */
  309|  4.58k|	chancleanup();
  310|       |
  311|  4.58k|	if (ses.extra_session_cleanup) {
  ------------------
  |  Branch (311:6): [True: 4.58k, False: 0]
  ------------------
  312|  4.58k|		ses.extra_session_cleanup();
  313|  4.58k|	}
  314|       |
  315|       |	/* After these are freed most functions will fail */
  316|  4.58k|#if DROPBEAR_CLEANUP
  317|       |	/* listeners call cleanup functions, this should occur before
  318|       |	other session state is freed. */
  319|  4.58k|	remove_all_listeners();
  320|       |
  321|  4.58k|	remove_connect_pending();
  322|       |
  323|  7.24k|	while (!isempty(&ses.writequeue)) {
  ------------------
  |  Branch (323:9): [True: 2.66k, False: 4.58k]
  ------------------
  324|  2.66k|		buf_free(dequeue(&ses.writequeue));
  325|  2.66k|	}
  326|       |
  327|  4.58k|	m_free(ses.newkeys);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  328|       |#ifndef DISABLE_ZLIB
  329|       |	if (ses.keys->recv.zstream != NULL) {
  330|       |		if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) {
  331|       |			dropbear_exit("Crypto error");
  332|       |		}
  333|       |		m_free(ses.keys->recv.zstream);
  334|       |	}
  335|       |	if (ses.keys->trans.zstream != NULL) {
  336|       |		if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) {
  337|       |			dropbear_exit("Crypto error");
  338|       |		}
  339|       |		m_free(ses.keys->trans.zstream);
  340|       |	}
  341|       |#endif
  342|       |
  343|  4.58k|	m_free(ses.remoteident);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  344|  4.58k|	m_free(ses.authstate.pw_dir);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  345|  4.58k|	m_free(ses.authstate.pw_name);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  346|  4.58k|	m_free(ses.authstate.pw_shell);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  347|  4.58k|	m_free(ses.authstate.pw_passwd);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  348|  4.58k|	m_free(ses.authstate.username);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  349|  4.58k|#endif
  350|       |
  351|  4.58k|	cleanup_buf(&ses.session_id);
  352|  4.58k|	cleanup_buf(&ses.hash);
  353|  4.58k|	cleanup_buf(&ses.payload);
  354|  4.58k|	cleanup_buf(&ses.readbuf);
  355|  4.58k|	cleanup_buf(&ses.writepayload);
  356|  4.58k|	cleanup_buf(&ses.kexhashbuf);
  357|  4.58k|	cleanup_buf(&ses.transkexinit);
  358|  4.58k|	if (ses.dh_K) {
  ------------------
  |  Branch (358:6): [True: 0, False: 4.58k]
  ------------------
  359|      0|		mp_clear(ses.dh_K);
  360|      0|	}
  361|  4.58k|	m_free(ses.dh_K);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  362|  4.58k|	if (ses.dh_K_bytes) {
  ------------------
  |  Branch (362:6): [True: 0, False: 4.58k]
  ------------------
  363|      0|		buf_burn_free(ses.dh_K_bytes);
  364|      0|	}
  365|       |
  366|  4.58k|	m_burn(ses.keys, sizeof(struct key_context));
  367|  4.58k|	m_free(ses.keys);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  368|       |
  369|  4.58k|	TRACE(("leave session_cleanup"))
  370|  4.58k|}
send_session_identification:
  372|  4.58k|void send_session_identification() {
  373|  4.58k|	buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1);
  ------------------
  |  |   14|  4.58k|#define LOCAL_IDENT "SSH-2.0-dropbear" IDENT_VERSION_PART
  ------------------
  374|  4.58k|	buf_putbytes(writebuf, (const unsigned char *) LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n"));
  ------------------
  |  |   14|  4.58k|#define LOCAL_IDENT "SSH-2.0-dropbear" IDENT_VERSION_PART
  ------------------
              	buf_putbytes(writebuf, (const unsigned char *) LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n"));
  ------------------
  |  |   14|  4.58k|#define LOCAL_IDENT "SSH-2.0-dropbear" IDENT_VERSION_PART
  ------------------
  375|  4.58k|	writebuf_enqueue(writebuf);
  376|  4.58k|}
ignore_recv_response:
  501|    609|void ignore_recv_response() {
  502|       |	/* Do nothing */
  503|    609|	TRACE(("Ignored msg_request_response"))
  504|    609|}
fill_passwd:
  655|  4.58k|void fill_passwd(const char* username) {
  656|  4.58k|	struct passwd *pw = NULL;
  657|  4.58k|	if (ses.authstate.pw_name)
  ------------------
  |  Branch (657:6): [True: 0, False: 4.58k]
  ------------------
  658|      0|		m_free(ses.authstate.pw_name);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  659|  4.58k|	if (ses.authstate.pw_dir)
  ------------------
  |  Branch (659:6): [True: 0, False: 4.58k]
  ------------------
  660|      0|		m_free(ses.authstate.pw_dir);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  661|  4.58k|	if (ses.authstate.pw_shell)
  ------------------
  |  Branch (661:6): [True: 0, False: 4.58k]
  ------------------
  662|      0|		m_free(ses.authstate.pw_shell);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  663|  4.58k|	if (ses.authstate.pw_passwd)
  ------------------
  |  Branch (663:6): [True: 0, False: 4.58k]
  ------------------
  664|      0|		m_free(ses.authstate.pw_passwd);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  665|       |
  666|  4.58k|	pw = getpwnam(username);
  ------------------
  |  |  108|  4.58k|#define getpwnam(x) fuzz_getpwnam(x)
  ------------------
  667|  4.58k|	if (!pw) {
  ------------------
  |  Branch (667:6): [True: 0, False: 4.58k]
  ------------------
  668|      0|		return;
  669|      0|	}
  670|  4.58k|	ses.authstate.pw_uid = pw->pw_uid;
  671|  4.58k|	ses.authstate.pw_gid = pw->pw_gid;
  672|  4.58k|	ses.authstate.pw_name = m_strdup(pw->pw_name);
  673|  4.58k|	ses.authstate.pw_dir = m_strdup(pw->pw_dir);
  674|  4.58k|	ses.authstate.pw_shell = m_strdup(pw->pw_shell);
  675|  4.58k|	{
  676|  4.58k|		char *passwd_crypt = pw->pw_passwd;
  677|  4.58k|#ifdef HAVE_SHADOW_H
  678|       |		/* "x" for the passwd crypt indicates shadow should be used */
  679|  4.58k|		if (pw->pw_passwd && strcmp(pw->pw_passwd, "x") == 0) {
  ------------------
  |  Branch (679:7): [True: 4.58k, False: 0]
  |  Branch (679:24): [True: 0, False: 4.58k]
  ------------------
  680|       |			/* get the shadow password */
  681|      0|			struct spwd *spasswd = getspnam(ses.authstate.pw_name);
  682|      0|			if (spasswd && spasswd->sp_pwdp) {
  ------------------
  |  Branch (682:8): [True: 0, False: 0]
  |  Branch (682:19): [True: 0, False: 0]
  ------------------
  683|      0|				passwd_crypt = spasswd->sp_pwdp;
  684|      0|			} else {
  685|       |				/* Fail if missing in /etc/shadow */
  686|      0|				passwd_crypt = "!!";
  687|      0|			}
  688|      0|		}
  689|  4.58k|#endif
  690|  4.58k|		if (!passwd_crypt) {
  ------------------
  |  Branch (690:7): [True: 0, False: 4.58k]
  ------------------
  691|       |			/* android supposedly returns NULL */
  692|      0|			passwd_crypt = "!!";
  693|      0|		}
  694|  4.58k|		ses.authstate.pw_passwd = m_strdup(passwd_crypt);
  695|  4.58k|	}
  696|  4.58k|}
update_channel_prio:
  699|  12.9k|void update_channel_prio() {
  700|  12.9k|	enum dropbear_prio new_prio;
  701|  12.9k|	int any = 0;
  702|  12.9k|	unsigned int i;
  703|       |
  704|  12.9k|	TRACE(("update_channel_prio"))
  705|       |
  706|  12.9k|	if (ses.sock_out < 0) {
  ------------------
  |  Branch (706:6): [True: 1.77k, False: 11.1k]
  ------------------
  707|  1.77k|		TRACE(("leave update_channel_prio: no socket"))
  708|  1.77k|		return;
  709|  1.77k|	}
  710|       |
  711|  11.1k|	new_prio = DROPBEAR_PRIO_NORMAL;
  712|  30.7k|	for (i = 0; i < ses.chansize; i++) {
  ------------------
  |  Branch (712:14): [True: 24.5k, False: 6.22k]
  ------------------
  713|  24.5k|		struct Channel *channel = ses.channels[i];
  714|  24.5k|		if (!channel) {
  ------------------
  |  Branch (714:7): [True: 16.2k, False: 8.29k]
  ------------------
  715|  16.2k|			continue;
  716|  16.2k|		}
  717|  8.29k|		any = 1;
  718|  8.29k|		if (channel->prio == DROPBEAR_PRIO_LOWDELAY) {
  ------------------
  |  Branch (718:7): [True: 4.90k, False: 3.38k]
  ------------------
  719|  4.90k|			new_prio = DROPBEAR_PRIO_LOWDELAY;
  720|  4.90k|			break;
  721|  4.90k|		}
  722|  8.29k|	}
  723|       |
  724|  11.1k|	if (any == 0) {
  ------------------
  |  Branch (724:6): [True: 5.40k, False: 5.72k]
  ------------------
  725|       |		/* lowdelay during setup */
  726|  5.40k|		TRACE(("update_channel_prio: not any"))
  727|  5.40k|		new_prio = DROPBEAR_PRIO_LOWDELAY;
  728|  5.40k|	}
  729|       |
  730|  11.1k|	if (new_prio != ses.socket_prio) {
  ------------------
  |  Branch (730:6): [True: 5.69k, False: 5.43k]
  ------------------
  731|  5.69k|		TRACE(("Dropbear priority transitioning %d -> %d", ses.socket_prio, new_prio))
  732|  5.69k|		set_sock_priority(ses.sock_out, new_prio);
  733|  5.69k|		ses.socket_prio = new_prio;
  734|  5.69k|	}
  735|  11.1k|}
common-session.c:cleanup_buf:
  287|  32.0k|static void cleanup_buf(buffer **buf) {
  288|  32.0k|	if (!*buf) {
  ------------------
  |  Branch (288:6): [True: 17.8k, False: 14.2k]
  ------------------
  289|  17.8k|		return;
  290|  17.8k|	}
  291|  14.2k|	buf_burn_free(*buf);
  292|       |	*buf = NULL;
  293|  14.2k|}
common-session.c:read_session_identification:
  378|  4.58k|static void read_session_identification() {
  379|       |	/* max length of 255 chars */
  380|  4.58k|	char linebuf[256];
  381|  4.58k|	int len = 0;
  382|  4.58k|	char done = 0;
  383|  4.58k|	int i;
  384|       |
  385|       |	/* Servers may send other lines of data before sending the
  386|       |	 * version string, client must be able to process such lines.
  387|       |	 * If they send more than 50 lines, something is wrong */
  388|  4.70k|	for (i = IS_DROPBEAR_CLIENT ? 50 : 1; i > 0; i--) {
  ------------------
  |  |  382|  4.58k|#define IS_DROPBEAR_CLIENT (ses.isserver == 0)
  |  |  ------------------
  |  |  |  Branch (382:28): [True: 0, False: 4.58k]
  |  |  ------------------
  ------------------
  |  Branch (388:40): [True: 4.58k, False: 121]
  ------------------
  389|  4.58k|		len = ident_readln(ses.sock_in, linebuf, sizeof(linebuf));
  390|       |
  391|  4.58k|		if (len < 0 && errno != EINTR) {
  ------------------
  |  Branch (391:7): [True: 85, False: 4.49k]
  |  Branch (391:18): [True: 9, False: 76]
  ------------------
  392|       |			/* It failed */
  393|      9|			break;
  394|      9|		}
  395|       |
  396|  4.57k|		if (len >= 4 && memcmp(linebuf, "SSH-", 4) == 0) {
  ------------------
  |  Branch (396:7): [True: 4.49k, False: 82]
  |  Branch (396:19): [True: 4.45k, False: 39]
  ------------------
  397|       |			/* start of line matches */
  398|  4.45k|			done = 1;
  399|  4.45k|			break;
  400|  4.45k|		}
  401|  4.57k|	}
  402|       |
  403|  4.58k|	if (!done) {
  ------------------
  |  Branch (403:6): [True: 130, False: 4.45k]
  ------------------
  404|    130|		TRACE(("error reading remote ident: %s\n", strerror(errno)))
  405|    130|		ses.remoteclosed();
  406|  4.45k|	} else {
  407|       |		/* linebuf is already null terminated */
  408|  4.45k|		ses.remoteident = m_malloc(len);
  409|  4.45k|		memcpy(ses.remoteident, linebuf, len);
  410|  4.45k|	}
  411|       |
  412|       |	/* Shall assume that 2.x will be backwards compatible. */
  413|  4.58k|	if (strncmp(ses.remoteident, "SSH-2.", 6) != 0
  ------------------
  |  Branch (413:6): [True: 60, False: 4.52k]
  ------------------
  414|     60|			&& strncmp(ses.remoteident, "SSH-1.99-", 9) != 0) {
  ------------------
  |  Branch (414:7): [True: 58, False: 2]
  ------------------
  415|     58|		dropbear_exit("Incompatible remote version '%s'", ses.remoteident);
  416|     58|	}
  417|       |
  418|  4.58k|	DEBUG1(("remoteident: %s", ses.remoteident))
  419|       |
  420|  4.58k|}
common-session.c:ident_readln:
  424|  4.58k|static int ident_readln(int fd, char* buf, int count) {
  425|       |	
  426|  4.58k|	char in;
  427|  4.58k|	int pos = 0;
  428|  4.58k|	int num = 0;
  429|  4.58k|	fd_set fds;
  430|  4.58k|	struct timeval timeout;
  431|       |
  432|  4.58k|	TRACE(("enter ident_readln"))
  433|       |
  434|  4.58k|	if (count < 1) {
  ------------------
  |  Branch (434:6): [True: 0, False: 4.58k]
  ------------------
  435|      0|		return -1;
  436|      0|	}
  437|       |
  438|  4.58k|	DROPBEAR_FD_ZERO(&fds);
  ------------------
  |  |  106|  4.58k|#define DROPBEAR_FD_ZERO(fds) FD_ZERO(fds)
  ------------------
  |  Branch (438:2): [Folded, False: 4.58k]
  ------------------
  439|       |
  440|       |	/* select since it's a non-blocking fd */
  441|       |	
  442|       |	/* leave space to null-terminate */
  443|  81.6k|	while (pos < count-1) {
  ------------------
  |  Branch (443:9): [True: 81.6k, False: 1]
  ------------------
  444|       |
  445|  81.6k|		FD_SET(fd, &fds);
  446|       |
  447|  81.6k|		timeout.tv_sec = 1;
  448|  81.6k|		timeout.tv_usec = 0;
  449|  81.6k|		if (select(fd+1, &fds, NULL, NULL, &timeout) < 0) {
  ------------------
  |  |   53|  81.6k|        wrapfd_select(nfds, readfds, writefds, exceptfds, timeout)
  ------------------
  |  Branch (449:7): [True: 79, False: 81.5k]
  ------------------
  450|     79|			if (errno == EINTR) {
  ------------------
  |  Branch (450:8): [True: 79, False: 0]
  ------------------
  451|     79|				continue;
  452|     79|			}
  453|      0|			TRACE(("leave ident_readln: select error"))
  454|      0|			return -1;
  455|     79|		}
  456|       |
  457|  81.5k|		checktimeouts();
  458|       |		
  459|       |		/* Have to go one byte at a time, since we don't want to read past
  460|       |		 * the end, and have to somehow shove bytes back into the normal
  461|       |		 * packet reader */
  462|  81.5k|		if (FD_ISSET(fd, &fds)) {
  ------------------
  |  Branch (462:7): [True: 81.5k, False: 0]
  ------------------
  463|  81.5k|			num = read(fd, &in, 1);
  ------------------
  |  |   55|  81.5k|#define read(fd, buf, count) wrapfd_read(fd, buf, count)
  ------------------
  464|       |			/* a "\n" is a newline, "\r" we want to read in and keep going
  465|       |			 * so that it won't be read as part of the next line */
  466|  81.5k|			if (num < 0) {
  ------------------
  |  Branch (466:8): [True: 108, False: 81.4k]
  ------------------
  467|       |				/* error */
  468|    108|				if (errno == EINTR) {
  ------------------
  |  Branch (468:9): [True: 107, False: 1]
  ------------------
  469|    107|					continue; /* not a real error */
  470|    107|				}
  471|      1|				TRACE(("leave ident_readln: read error"))
  472|      1|				return -1;
  473|    108|			}
  474|  81.4k|			if (num == 0) {
  ------------------
  |  Branch (474:8): [True: 84, False: 81.3k]
  ------------------
  475|       |				/* EOF */
  476|     84|				TRACE(("leave ident_readln: EOF"))
  477|     84|				return -1;
  478|     84|			}
  479|       |
  480|  81.3k|#if DROPBEAR_FUZZ
  481|  81.3k|			fuzz_dump(&in, 1);
  482|  81.3k|#endif
  483|       |
  484|  81.3k|			if (in == '\n') {
  ------------------
  |  Branch (484:8): [True: 4.49k, False: 76.8k]
  ------------------
  485|       |				/* end of ident string */
  486|  4.49k|				break;
  487|  4.49k|			}
  488|       |			/* we don't want to include '\r's */
  489|  76.8k|			if (in != '\r') {
  ------------------
  |  Branch (489:8): [True: 62.9k, False: 13.9k]
  ------------------
  490|  62.9k|				buf[pos] = in;
  491|  62.9k|				pos++;
  492|  62.9k|			}
  493|  76.8k|		}
  494|  81.5k|	}
  495|       |
  496|  4.49k|	buf[pos] = '\0';
  497|  4.49k|	TRACE(("leave ident_readln: return %d", pos+1))
  498|  4.49k|	return pos+1;
  499|  4.58k|}
common-session.c:checktimeouts:
  545|   384k|static void checktimeouts() {
  546|       |
  547|   384k|	time_t now;
  548|   384k|	now = monotonic_now();
  549|       |
  550|   384k|	if (IS_DROPBEAR_SERVER && ses.authstate.authdone != 1
  ------------------
  |  |  381|   768k|#define IS_DROPBEAR_SERVER (ses.isserver == 1)
  |  |  ------------------
  |  |  |  Branch (381:28): [True: 384k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (550:28): [True: 0, False: 384k]
  ------------------
  551|      0|		&& elapsed(now, ses.connect_time) >= AUTH_TIMEOUT) {
  ------------------
  |  |   35|      0|#define AUTH_TIMEOUT 300 /* we choose 5 minutes */
  ------------------
  |  Branch (551:6): [True: 0, False: 0]
  ------------------
  552|      0|			dropbear_close("Timeout before auth");
  553|      0|	}
  554|       |
  555|       |	/* we can't rekey if we haven't done remote ident exchange yet */
  556|   384k|	if (ses.remoteident == NULL) {
  ------------------
  |  Branch (556:6): [True: 95.3k, False: 288k]
  ------------------
  557|  95.3k|		return;
  558|  95.3k|	}
  559|       |
  560|   288k|	if (!ses.kexstate.sentkexinit
  ------------------
  |  Branch (560:6): [True: 173k, False: 115k]
  ------------------
  561|   173k|			&& (elapsed(now, ses.kexstate.lastkextime) >= KEX_REKEY_TIMEOUT
  ------------------
  |  |   28|   346k|#define KEX_REKEY_TIMEOUT (3600 * 8)
  ------------------
  |  Branch (561:8): [True: 0, False: 173k]
  ------------------
  562|   173k|			|| ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA
  ------------------
  |  |   31|   346k|#define KEX_REKEY_DATA (1<<30) /* 2^30 == 1GB, this value must be < INT_MAX */
  ------------------
  |  Branch (562:7): [True: 0, False: 173k]
  ------------------
  563|   173k|			|| ses.kexstate.needrekey)) {
  ------------------
  |  Branch (563:7): [True: 0, False: 173k]
  ------------------
  564|      0|		TRACE(("rekeying after timeout or max data reached"))
  565|      0|		ses.kexstate.needrekey = 0;
  566|      0|		send_msg_kexinit();
  567|      0|	}
  568|       |
  569|   288k|	if (opts.keepalive_secs > 0 && ses.authstate.authdone) {
  ------------------
  |  Branch (569:6): [True: 0, False: 288k]
  |  Branch (569:33): [True: 0, False: 0]
  ------------------
  570|       |		/* Avoid sending keepalives prior to auth - those are
  571|       |		not valid pre-auth packet types */
  572|       |
  573|       |		/* Send keepalives if we've been idle */
  574|      0|		if (elapsed(now, ses.last_packet_time_any_sent) >= opts.keepalive_secs) {
  ------------------
  |  Branch (574:7): [True: 0, False: 0]
  ------------------
  575|      0|			send_msg_keepalive();
  576|      0|		}
  577|       |
  578|       |		/* Also send an explicit keepalive message to trigger a response
  579|       |		if the remote end hasn't sent us anything */
  580|      0|		if (elapsed(now, ses.last_packet_time_keepalive_recv) >= opts.keepalive_secs
  ------------------
  |  Branch (580:7): [True: 0, False: 0]
  ------------------
  581|      0|			&& elapsed(now, ses.last_packet_time_keepalive_sent) >= opts.keepalive_secs) {
  ------------------
  |  Branch (581:7): [True: 0, False: 0]
  ------------------
  582|      0|			send_msg_keepalive();
  583|      0|		}
  584|       |
  585|      0|		if (elapsed(now, ses.last_packet_time_keepalive_recv)
  ------------------
  |  Branch (585:7): [True: 0, False: 0]
  ------------------
  586|      0|			>= opts.keepalive_secs * DEFAULT_KEEPALIVE_LIMIT) {
  ------------------
  |  |  573|      0|#define DEFAULT_KEEPALIVE_LIMIT 3
  ------------------
  587|      0|			dropbear_exit("Keepalive timeout");
  588|      0|		}
  589|      0|	}
  590|       |
  591|   288k|	if (opts.idle_timeout_secs > 0
  ------------------
  |  Branch (591:6): [True: 0, False: 288k]
  ------------------
  592|      0|			&& elapsed(now, ses.last_packet_time_idle) >= opts.idle_timeout_secs) {
  ------------------
  |  Branch (592:7): [True: 0, False: 0]
  ------------------
  593|      0|		dropbear_close("Idle timeout");
  594|      0|	}
  595|       |
  596|   288k|	if (opts.max_duration_secs > 0
  ------------------
  |  Branch (596:6): [True: 0, False: 288k]
  ------------------
  597|      0|			&& elapsed(now, ses.connect_time) >= opts.max_duration_secs) {
  ------------------
  |  Branch (597:7): [True: 0, False: 0]
  ------------------
  598|      0|		dropbear_close("Max duration reached");
  599|      0|	}
  600|   288k|}
common-session.c:elapsed:
  535|   867k|static long elapsed(time_t now, time_t prev) {
  536|   867k|	time_t del = now - prev;
  537|   867k|	if (del > LONG_MAX) {
  ------------------
  |  Branch (537:6): [True: 0, False: 867k]
  ------------------
  538|      0|		return LONG_MAX;
  539|      0|	}
  540|   867k|	return (long)del;
  541|   867k|}
common-session.c:select_timeout:
  613|   302k|static long select_timeout() {
  614|       |	/* determine the minimum timeout that might be required, so
  615|       |	as to avoid waking when unneccessary */
  616|   302k|	long timeout = KEX_REKEY_TIMEOUT;
  ------------------
  |  |   28|   302k|#define KEX_REKEY_TIMEOUT (3600 * 8)
  ------------------
  617|   302k|	time_t now = monotonic_now();
  618|       |
  619|   302k|	if (!ses.kexstate.sentkexinit) {
  ------------------
  |  Branch (619:6): [True: 173k, False: 129k]
  ------------------
  620|   173k|		update_timeout(KEX_REKEY_TIMEOUT, now, ses.kexstate.lastkextime, &timeout);
  ------------------
  |  |   28|   173k|#define KEX_REKEY_TIMEOUT (3600 * 8)
  ------------------
  621|   173k|	}
  622|   302k|	if (ses.kexstate.needrekey) {
  ------------------
  |  Branch (622:6): [True: 0, False: 302k]
  ------------------
  623|      0|		timeout = 0;
  624|      0|	}
  625|       |
  626|   302k|	if (ses.authstate.authdone != 1 && IS_DROPBEAR_SERVER) {
  ------------------
  |  |  381|      0|#define IS_DROPBEAR_SERVER (ses.isserver == 1)
  |  |  ------------------
  |  |  |  Branch (381:28): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (626:6): [True: 0, False: 302k]
  ------------------
  627|       |		/* AUTH_TIMEOUT is only relevant before authdone */
  628|      0|		update_timeout(AUTH_TIMEOUT, now, ses.connect_time, &timeout);
  ------------------
  |  |   35|      0|#define AUTH_TIMEOUT 300 /* we choose 5 minutes */
  ------------------
  629|      0|	}
  630|       |
  631|   302k|	if (ses.authstate.authdone) {
  ------------------
  |  Branch (631:6): [True: 302k, False: 0]
  ------------------
  632|   302k|		update_timeout(opts.keepalive_secs, now,
  633|   302k|			MAX(ses.last_packet_time_keepalive_recv, ses.last_packet_time_keepalive_sent),
  ------------------
  |  Branch (633:4): [True: 302k, False: 0]
  ------------------
  634|   302k|			&timeout);
  635|   302k|	}
  636|       |
  637|   302k|	update_timeout(opts.idle_timeout_secs, now, ses.last_packet_time_idle,
  638|   302k|		&timeout);
  639|       |
  640|   302k|	update_timeout(opts.max_duration_secs, now, ses.connect_time,
  641|   302k|		&timeout);
  642|       |
  643|       |	/* clamp negative timeouts to zero - event has already triggered */
  644|       |	return MAX(timeout, 0);
  ------------------
  |  Branch (644:9): [True: 302k, False: 0]
  ------------------
  645|   302k|}
common-session.c:update_timeout:
  602|  1.08M|static void update_timeout(long limit, time_t now, time_t last_event, long * timeout) {
  603|  1.08M|	TRACE2(("update_timeout limit %ld, now %llu, last %llu, timeout %ld",
  604|  1.08M|		limit,
  605|  1.08M|		(unsigned long long)now,
  606|  1.08M|		(unsigned long long)last_event, *timeout))
  607|  1.08M|	if (last_event > 0 && limit > 0) {
  ------------------
  |  Branch (607:6): [True: 1.08M, False: 0]
  |  Branch (607:24): [True: 173k, False: 908k]
  ------------------
  608|       |		*timeout = MIN(*timeout, MAX(0, limit - elapsed(now, last_event)));
  ------------------
  |  Branch (608:14): [True: 0, False: 173k]
  |  Branch (608:14): [True: 0, False: 173k]
  |  Branch (608:14): [True: 0, False: 173k]
  ------------------
  609|   173k|		TRACE2(("new timeout %ld", *timeout))
  610|   173k|	}
  611|  1.08M|}

strlcpy:
   93|     40|size_t strlcpy(char *dst, const char *src, size_t size) {
   94|       |
   95|     40|	size_t i;
   96|       |
   97|       |	/* this is undefined, though size==0 -> return 0 */
   98|     40|	if (size < 1) {
  ------------------
  |  Branch (98:6): [True: 0, False: 40]
  ------------------
   99|      0|		return 0;
  100|      0|	}
  101|       |
  102|    430|	for (i = 0; i < size-1; i++) {
  ------------------
  |  Branch (102:14): [True: 430, False: 0]
  ------------------
  103|    430|		if (src[i] == '\0') {
  ------------------
  |  Branch (103:7): [True: 40, False: 390]
  ------------------
  104|     40|			break;
  105|    390|		} else {
  106|    390|			dst[i] = src[i];
  107|    390|		}
  108|    430|	}
  109|       |
  110|     40|	dst[i] = '\0';
  111|     40|	return strlen(src);
  112|       |
  113|     40|}

crypto_init:
   21|      1|void crypto_init() {
   22|       |
   23|      1|	const struct ltc_cipher_descriptor *regciphers[] = {
   24|      1|#if DROPBEAR_AES
   25|      1|		&aes_desc,
   26|      1|#endif
   27|       |#if DROPBEAR_3DES
   28|       |		&des3_desc,
   29|       |#endif
   30|      1|		NULL
   31|      1|	};
   32|       |
   33|      1|	const struct ltc_hash_descriptor *reghashes[] = {
   34|       |#if DROPBEAR_SHA1_HMAC
   35|       |		&sha1_desc,
   36|       |#endif
   37|      1|#if DROPBEAR_SHA256
   38|      1|		&sha256_desc,
   39|      1|#endif
   40|      1|#if DROPBEAR_SHA384
   41|      1|		&sha384_desc,
   42|      1|#endif
   43|      1|#if DROPBEAR_SHA512
   44|      1|		&sha512_desc,
   45|      1|#endif
   46|      1|		NULL
   47|      1|	};
   48|      1|	int i;
   49|       |
   50|      2|	for (i = 0; regciphers[i] != NULL; i++) {
  ------------------
  |  Branch (50:14): [True: 1, False: 1]
  ------------------
   51|      1|		if (register_cipher(regciphers[i]) == -1) {
  ------------------
  |  Branch (51:7): [True: 0, False: 1]
  ------------------
   52|      0|			dropbear_exit("Error registering crypto");
   53|      0|		}
   54|      1|	}
   55|       |
   56|      4|	for (i = 0; reghashes[i] != NULL; i++) {
  ------------------
  |  Branch (56:14): [True: 3, False: 1]
  ------------------
   57|      3|		if (register_hash(reghashes[i]) == -1) {
  ------------------
  |  Branch (57:7): [True: 0, False: 3]
  ------------------
   58|      0|			dropbear_exit("Error registering crypto");
   59|      0|		}
   60|      3|	}
   61|       |
   62|      1|#if DROPBEAR_LTC_PRNG
   63|      1|	dropbear_ltc_prng = register_prng(&dropbear_prng_desc);
   64|      1|	if (dropbear_ltc_prng == -1) {
  ------------------
  |  Branch (64:6): [True: 0, False: 1]
  ------------------
   65|      0|		dropbear_exit("Error registering crypto");
   66|      0|	}
   67|      1|#endif
   68|       |
   69|      1|	mp_rand_source(dropbear_rand_source);
   70|       |
   71|      1|#if DROPBEAR_ECC
   72|      1|	ltc_mp = ltm_desc;
   73|      1|	dropbear_ecc_fill_dp();
   74|      1|#endif
   75|      1|}

m_burn:
    5|   272k|void m_burn(void *data, unsigned int len) {
    6|       |
    7|       |#if defined(HAVE_MEMSET_S)
    8|       |	memset_s(data, len, 0x0, len);
    9|       |#elif defined(HAVE_EXPLICIT_BZERO)
   10|       |	explicit_bzero(data, len);
   11|       |#else
   12|       |	/* This must be volatile to avoid compiler optimisation */
   13|       |	volatile void *p = data;
   14|       |	memset((void*)p, 0x0, len);
   15|       |#endif
   16|   272k|}

m_calloc:
    5|  13.1k|void * m_calloc(size_t nmemb, size_t size) {
    6|  13.1k|    if (SIZE_T_MAX / nmemb < size) {
  ------------------
  |  |  175|  13.1k|#define SIZE_T_MAX ULONG_MAX
  ------------------
  |  Branch (6:9): [True: 0, False: 13.1k]
  ------------------
    7|      0|        dropbear_exit("m_calloc failed");
    8|      0|    }
    9|  13.1k|    return m_malloc(nmemb*size);
   10|  13.1k|}
m_strdup:
   12|  37.0k|void * m_strdup(const char * str) {
   13|  37.0k|    char* ret;
   14|  37.0k|    unsigned int len;
   15|  37.0k|    len = strlen(str);
   16|       |
   17|  37.0k|    ret = m_malloc(len+1);
   18|  37.0k|    if (ret == NULL) {
  ------------------
  |  Branch (18:9): [True: 0, False: 37.0k]
  ------------------
   19|      0|        dropbear_exit("m_strdup failed");
   20|      0|    }
   21|  37.0k|    memcpy(ret, str, len+1);
   22|  37.0k|    return ret;
   23|  37.0k|}
m_malloc_set_epoch:
   76|  4.58k|void m_malloc_set_epoch(unsigned int epoch) {
   77|  4.58k|    current_epoch = epoch;
   78|  4.58k|}
m_malloc_free_epoch:
   80|  4.58k|void m_malloc_free_epoch(unsigned int epoch, int dofree) {
   81|  4.58k|    struct dbmalloc_header* header;
   82|  4.58k|    struct dbmalloc_header* nextheader = NULL;
   83|  4.58k|    struct dbmalloc_header* oldstaple = staple;
   84|  4.58k|    staple = NULL;
   85|       |    /* free allocations from this epoch, create a new staple-anchored list from
   86|       |    the remainder */
   87|  4.76M|    for (header = oldstaple; header; header = nextheader)
  ------------------
  |  Branch (87:30): [True: 4.76M, False: 4.58k]
  ------------------
   88|  4.76M|    {
   89|  4.76M|        nextheader = header->next;
   90|  4.76M|        if (header->epoch == epoch) {
  ------------------
  |  Branch (90:13): [True: 389, False: 4.76M]
  ------------------
   91|    389|            if (dofree) {
  ------------------
  |  Branch (91:17): [True: 389, False: 0]
  ------------------
   92|    389|                free(header);
   93|    389|            }
   94|  4.76M|        } else {
   95|  4.76M|            header->prev = NULL;
   96|       |            header->next = NULL;
   97|  4.76M|            put_alloc(header);
   98|  4.76M|        }
   99|  4.76M|    }
  100|  4.58k|}
m_malloc:
  131|   518k|void * m_malloc(size_t size) {
  132|   518k|    char* mem = NULL;
  133|   518k|    struct dbmalloc_header* header = NULL;
  134|       |
  135|   518k|    if (size == 0 || size > 1e9) {
  ------------------
  |  Branch (135:9): [True: 0, False: 518k]
  |  Branch (135:22): [True: 0, False: 518k]
  ------------------
  136|      0|        dropbear_exit("m_malloc failed");
  137|      0|    }
  138|       |
  139|   518k|    size = size + sizeof(struct dbmalloc_header);
  140|       |
  141|   518k|    mem = calloc(1, size);
  142|   518k|    if (mem == NULL) {
  ------------------
  |  Branch (142:9): [True: 0, False: 518k]
  ------------------
  143|      0|        dropbear_exit("m_malloc failed");
  144|      0|    }
  145|   518k|    header = (struct dbmalloc_header*)mem;
  146|   518k|    put_alloc(header);
  147|   518k|    header->epoch = current_epoch;
  148|   518k|    return &mem[sizeof(struct dbmalloc_header)];
  149|   518k|}
m_realloc:
  151|  9.82k|void * m_realloc(void* ptr, size_t size) {
  152|  9.82k|    char* mem = NULL;
  153|  9.82k|    struct dbmalloc_header* header = NULL;
  154|  9.82k|    if (size == 0 || size > 1e9) {
  ------------------
  |  Branch (154:9): [True: 0, False: 9.82k]
  |  Branch (154:22): [True: 0, False: 9.82k]
  ------------------
  155|      0|        dropbear_exit("m_realloc failed");
  156|      0|    }
  157|       |
  158|  9.82k|    header = get_header(ptr);
  159|  9.82k|    remove_alloc(header);
  160|       |
  161|  9.82k|    size = size + sizeof(struct dbmalloc_header);
  162|  9.82k|    mem = realloc(header, size);
  163|  9.82k|    if (mem == NULL) {
  ------------------
  |  Branch (163:9): [True: 0, False: 9.82k]
  ------------------
  164|      0|        dropbear_exit("m_realloc failed");
  165|      0|    }
  166|       |
  167|  9.82k|    header = (struct dbmalloc_header*)mem;
  168|  9.82k|    put_alloc(header);
  169|  9.82k|    return &mem[sizeof(struct dbmalloc_header)];
  170|  9.82k|}
m_free_direct:
  172|   538k|void m_free_direct(void* ptr) {
  173|   538k|    struct dbmalloc_header* header = NULL;
  174|   538k|    if (!ptr) {
  ------------------
  |  Branch (174:9): [True: 22.5k, False: 515k]
  ------------------
  175|  22.5k|        return;
  176|  22.5k|    }
  177|   515k|    header = get_header(ptr);
  178|   515k|    remove_alloc(header);
  179|   515k|    free(header);
  180|   515k|}
m_realloc_ltm:
  184|    572|void * m_realloc_ltm(void* ptr, size_t oldsize, size_t newsize) {
  185|    572|   (void)oldsize;
  186|    572|   return m_realloc(ptr, newsize);
  187|    572|}
m_free_ltm:
  189|  12.9k|void m_free_ltm(void *mem, size_t size) {
  190|  12.9k|   (void)size;
  191|  12.9k|   m_free_direct(mem);
  192|  12.9k|}
dbmalloc.c:put_alloc:
  102|  5.29M|static void put_alloc(struct dbmalloc_header *header) {
  103|  5.29M|    assert(header->next == NULL);
  ------------------
  |  Branch (103:5): [True: 0, False: 5.29M]
  |  Branch (103:5): [True: 5.29M, False: 0]
  ------------------
  104|  5.29M|    assert(header->prev == NULL);
  ------------------
  |  Branch (104:5): [True: 0, False: 5.29M]
  |  Branch (104:5): [True: 5.29M, False: 0]
  ------------------
  105|  5.29M|    if (staple) {
  ------------------
  |  Branch (105:9): [True: 5.28M, False: 4.58k]
  ------------------
  106|  5.28M|        staple->prev = header;
  107|  5.28M|    }
  108|  5.29M|    header->next = staple;
  109|  5.29M|    staple = header;
  110|  5.29M|}
dbmalloc.c:get_header:
  126|   525k|static struct dbmalloc_header* get_header(void* ptr) {
  127|   525k|    char* bptr = ptr;
  128|   525k|    return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)];
  129|   525k|}
dbmalloc.c:remove_alloc:
  112|   525k|static void remove_alloc(struct dbmalloc_header *header) {
  113|   525k|    if (header->prev) {
  ------------------
  |  Branch (113:9): [True: 296k, False: 229k]
  ------------------
  114|   296k|        header->prev->next = header->next;
  115|   296k|    }
  116|   525k|    if (header->next) {
  ------------------
  |  Branch (116:9): [True: 525k, False: 0]
  ------------------
  117|   525k|        header->next->prev = header->prev;
  118|   525k|    }
  119|   525k|    if (staple == header) {
  ------------------
  |  Branch (119:9): [True: 229k, False: 296k]
  ------------------
  120|   229k|        staple = header->next;
  121|   229k|    }
  122|   525k|    header->prev = NULL;
  123|       |    header->next = NULL;
  124|   525k|}

fuzz_seed:
  153|  4.58k|void fuzz_seed(const unsigned char* dat, unsigned int len) {
  154|  4.58k|	hash_state hs;
  155|  4.58k|	sha256_init(&hs);
  156|  4.58k|	sha256_process(&hs, "fuzzfuzzfuzz", strlen("fuzzfuzzfuzz"));
  157|  4.58k|	sha256_process(&hs, dat, len);
  158|  4.58k|	sha256_done(&hs, hashpool);
  159|  4.58k|	counter = 0;
  160|  4.58k|	donerandinit = 1;
  161|  4.58k|}
genrandom:
  313|   102k|void genrandom(unsigned char* buf, unsigned int len) {
  314|       |
  315|   102k|	hash_state hs;
  316|   102k|	unsigned char hash[SHA256_HASH_SIZE];
  317|   102k|	unsigned int copylen;
  318|       |
  319|   102k|	if (!donerandinit) {
  ------------------
  |  Branch (319:6): [True: 0, False: 102k]
  ------------------
  320|      0|		dropbear_exit("seedrandom not done");
  321|      0|	}
  322|       |
  323|   204k|	while (len > 0) {
  ------------------
  |  Branch (323:9): [True: 102k, False: 102k]
  ------------------
  324|   102k|		sha256_init(&hs);
  325|   102k|		sha256_process(&hs, (void*)hashpool, sizeof(hashpool));
  326|   102k|		sha256_process(&hs, (void*)&counter, sizeof(counter));
  327|   102k|		sha256_done(&hs, hash);
  328|       |
  329|   102k|		counter++;
  330|   102k|		if (counter > MAX_COUNTER) {
  ------------------
  |  |   35|   102k|#define MAX_COUNTER (1<<30)
  ------------------
  |  Branch (330:7): [True: 0, False: 102k]
  ------------------
  331|      0|			seedrandom();
  332|      0|		}
  333|       |
  334|       |		copylen = MIN(len, SHA256_HASH_SIZE);
  ------------------
  |  Branch (334:13): [True: 102k, False: 0]
  ------------------
  335|   102k|		memcpy(buf, hash, copylen);
  336|   102k|		len -= copylen;
  337|   102k|		buf += copylen;
  338|   102k|	}
  339|   102k|	m_burn(hash, sizeof(hash));
  340|   102k|}

dropbear_close:
   95|  2.70k|void dropbear_close(const char* format, ...) {
   96|       |
   97|  2.70k|	va_list param;
   98|       |
   99|  2.70k|	va_start(param, format);
  100|  2.70k|	_dropbear_exit(EXIT_SUCCESS, format, param);
  101|  2.70k|	va_end(param);
  102|       |
  103|      0|}
dropbear_exit:
  105|  1.87k|void dropbear_exit(const char* format, ...) {
  106|       |
  107|  1.87k|	va_list param;
  108|       |
  109|  1.87k|	va_start(param, format);
  110|  1.87k|	_dropbear_exit(EXIT_FAILURE, format, param);
  111|  1.87k|	va_end(param);
  112|      0|}
fail_assert:
  132|      4|void fail_assert(const char* expr, const char* file, int line) {
  133|      4|	dropbear_exit("Failed assertion (%s:%d): `%s'", file, line, expr);
  134|      4|}
dropbear_log:
  148|  4.87k|void dropbear_log(int priority, const char* format, ...) {
  149|       |
  150|  4.87k|	va_list param;
  151|       |
  152|  4.87k|	va_start(param, format);
  153|  4.87k|	_dropbear_log(priority, format, param);
  154|       |	va_end(param);
  155|  4.87k|}
spawn_command:
  275|  1.02k|		int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) {
  276|  1.02k|	int infds[2];
  277|  1.02k|	int outfds[2];
  278|  1.02k|	int errfds[2];
  279|  1.02k|	pid_t pid;
  280|       |
  281|  1.02k|	const int FDIN = 0;
  282|  1.02k|	const int FDOUT = 1;
  283|       |
  284|  1.02k|#if DROPBEAR_FUZZ
  285|  1.02k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (285:6): [True: 1.02k, False: 0]
  ------------------
  286|  1.02k|		return fuzz_spawn_command(ret_writefd, ret_readfd, ret_errfd, ret_pid);
  287|  1.02k|	}
  288|      0|#endif
  289|       |
  290|       |	/* redirect stdin/stdout/stderr */
  291|      0|	if (pipe(infds) != 0) {
  ------------------
  |  Branch (291:6): [True: 0, False: 0]
  ------------------
  292|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  293|      0|	}
  294|      0|	if (pipe(outfds) != 0) {
  ------------------
  |  Branch (294:6): [True: 0, False: 0]
  ------------------
  295|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  296|      0|	}
  297|      0|	if (ret_errfd && pipe(errfds) != 0) {
  ------------------
  |  Branch (297:6): [True: 0, False: 0]
  |  Branch (297:19): [True: 0, False: 0]
  ------------------
  298|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  299|      0|	}
  300|       |
  301|       |#if DROPBEAR_VFORK
  302|       |	pid = vfork();
  303|       |#else
  304|      0|	pid = fork();
  305|      0|#endif
  306|       |
  307|      0|	if (pid < 0) {
  ------------------
  |  Branch (307:6): [True: 0, False: 0]
  ------------------
  308|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  309|      0|	}
  310|       |
  311|      0|	if (!pid) {
  ------------------
  |  Branch (311:6): [True: 0, False: 0]
  ------------------
  312|       |		/* child */
  313|       |
  314|      0|		TRACE(("back to normal sigchld"))
  315|       |		/* Revert to normal sigchld handling */
  316|      0|		if (signal(SIGCHLD, SIG_DFL) == SIG_ERR) {
  ------------------
  |  Branch (316:7): [True: 0, False: 0]
  ------------------
  317|      0|			dropbear_exit("signal() error");
  318|      0|		}
  319|       |
  320|       |		/* redirect stdin/stdout */
  321|       |
  322|      0|		if ((dup2(infds[FDIN], STDIN_FILENO) < 0) ||
  ------------------
  |  Branch (322:7): [True: 0, False: 0]
  ------------------
  323|      0|			(dup2(outfds[FDOUT], STDOUT_FILENO) < 0) ||
  ------------------
  |  Branch (323:4): [True: 0, False: 0]
  ------------------
  324|      0|			(ret_errfd && dup2(errfds[FDOUT], STDERR_FILENO) < 0)) {
  ------------------
  |  Branch (324:5): [True: 0, False: 0]
  |  Branch (324:18): [True: 0, False: 0]
  ------------------
  325|      0|			TRACE(("leave noptycommand: error redirecting FDs"))
  326|      0|			dropbear_exit("Child dup2() failure");
  327|      0|		}
  328|       |
  329|      0|		close(infds[FDOUT]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  330|      0|		close(infds[FDIN]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  331|      0|		close(outfds[FDIN]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  332|      0|		close(outfds[FDOUT]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  333|      0|		if (ret_errfd)
  ------------------
  |  Branch (333:7): [True: 0, False: 0]
  ------------------
  334|      0|		{
  335|      0|			close(errfds[FDIN]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  336|      0|			close(errfds[FDOUT]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  337|      0|		}
  338|       |
  339|      0|		exec_fn(exec_data);
  340|       |		/* not reached */
  341|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  342|      0|	} else {
  343|       |		/* parent */
  344|      0|		close(infds[FDIN]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  345|      0|		close(outfds[FDOUT]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  346|       |
  347|      0|		setnonblocking(outfds[FDIN]);
  348|      0|		setnonblocking(infds[FDOUT]);
  349|       |
  350|      0|		if (ret_errfd) {
  ------------------
  |  Branch (350:7): [True: 0, False: 0]
  ------------------
  351|      0|			close(errfds[FDOUT]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  352|      0|			setnonblocking(errfds[FDIN]);
  353|      0|		}
  354|       |
  355|      0|		if (ret_pid) {
  ------------------
  |  Branch (355:7): [True: 0, False: 0]
  ------------------
  356|      0|			*ret_pid = pid;
  357|      0|		}
  358|       |
  359|      0|		*ret_writefd = infds[FDOUT];
  360|      0|		*ret_readfd = outfds[FDIN];
  361|      0|		if (ret_errfd) {
  ------------------
  |  Branch (361:7): [True: 0, False: 0]
  ------------------
  362|      0|			*ret_errfd = errfds[FDIN];
  363|      0|		}
  364|      0|		return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  365|      0|	}
  366|      0|}
m_close:
  565|  25.3k|void m_close(int fd) {
  566|  25.3k|	int val;
  567|       |
  568|  25.3k|	if (fd < 0) {
  ------------------
  |  Branch (568:6): [True: 19.5k, False: 5.76k]
  ------------------
  569|  19.5k|		return;
  570|  19.5k|	}
  571|       |
  572|  5.76k|	do {
  573|  5.76k|		val = close(fd);
  ------------------
  |  |   56|  5.76k|#define close(fd) wrapfd_close(fd)
  ------------------
  574|  5.76k|	} while (val < 0 && errno == EINTR);
  ------------------
  |  Branch (574:11): [True: 0, False: 5.76k]
  |  Branch (574:22): [True: 0, False: 0]
  ------------------
  575|       |
  576|  5.76k|	if (val < 0 && errno != EBADF) {
  ------------------
  |  Branch (576:6): [True: 0, False: 5.76k]
  |  Branch (576:17): [True: 0, False: 0]
  ------------------
  577|       |		/* Linux says EIO can happen */
  578|       |		dropbear_exit("Error closing fd %d, %s", fd, strerror(errno));
  579|      0|	}
  580|  5.76k|}
setnonblocking:
  582|  9.37k|void setnonblocking(int fd) {
  583|       |
  584|  9.37k|	int fl = 0;
  585|  9.37k|	TRACE(("setnonblocking: %d", fd))
  586|       |
  587|  9.37k|#if DROPBEAR_FUZZ
  588|  9.37k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (588:6): [True: 9.37k, False: 0]
  ------------------
  589|  9.37k|		return;
  590|  9.37k|	}
  591|      0|#endif
  592|      0|	fl = fcntl(fd, F_GETFL, 0);
  593|      0|	if (fl == -1) {
  ------------------
  |  Branch (593:6): [True: 0, False: 0]
  ------------------
  594|       |		/* F_GETFL shouldn't fail */
  595|      0|		dropbear_exit("Couldn't set nonblocking");
  596|      0|	}
  597|       |
  598|      0|	if (fcntl(fd, F_SETFL, fl | O_NONBLOCK) == -1) {
  ------------------
  |  Branch (598:6): [True: 0, False: 0]
  ------------------
  599|      0|		if (errno == ENODEV) {
  ------------------
  |  Branch (599:7): [True: 0, False: 0]
  ------------------
  600|       |			/* Some devices (like /dev/null redirected in)
  601|       |			 * can't be set to non-blocking */
  602|      0|			TRACE(("ignoring ENODEV for setnonblocking"))
  603|      0|		} else {
  604|      0|			dropbear_exit("Couldn't set nonblocking");
  605|      0|		}
  606|      0|	}
  607|      0|	TRACE(("leave setnonblocking"))
  608|      0|}
disallow_core:
  610|      1|void disallow_core() {
  611|      1|	struct rlimit lim = {0};
  612|      1|	if (getrlimit(RLIMIT_CORE, &lim) < 0) {
  ------------------
  |  Branch (612:6): [True: 0, False: 1]
  ------------------
  613|      0|		TRACE(("getrlimit(RLIMIT_CORE) failed"));
  614|      0|	}
  615|      1|	lim.rlim_cur = 0;
  616|      1|	if (setrlimit(RLIMIT_CORE, &lim) < 0) {
  ------------------
  |  Branch (616:6): [True: 0, False: 1]
  ------------------
  617|      0|		TRACE(("setrlimit(RLIMIT_CORE) failed"));
  618|      0|	}
  619|      1|}
expand_homedir_path_home:
  647|      3|char * expand_homedir_path_home(const char *inpath, const char *homedir) {
  648|      3|	if (strncmp(inpath, "~/", 2) == 0 && homedir) {
  ------------------
  |  Branch (648:6): [True: 0, False: 3]
  |  Branch (648:39): [True: 0, False: 0]
  ------------------
  649|      0|		size_t len = strlen(inpath)-2 + strlen(homedir) + 2;
  650|      0|		char *buf = m_malloc(len);
  651|      0|		snprintf(buf, len, "%s/%s", homedir, inpath+2);
  652|      0|		return buf;
  653|      0|	}
  654|       |	/* Fallback */
  655|      3|	return m_strdup(inpath);
  656|      3|}
expand_homedir_path:
  660|      3|char * expand_homedir_path(const char *inpath) {
  661|      3|	struct passwd *pw = NULL;
  662|      3|	char *homedir = getenv("HOME");
  663|       |
  664|      3|	if (!homedir) {
  ------------------
  |  Branch (664:6): [True: 0, False: 3]
  ------------------
  665|      0|		pw = getpwuid(getuid());
  ------------------
  |  |  109|      0|#define getpwuid(x) fuzz_getpwuid(x)
  ------------------
  666|      0|		if (pw) {
  ------------------
  |  Branch (666:7): [True: 0, False: 0]
  ------------------
  667|      0|			homedir = pw->pw_dir;
  668|      0|		}
  669|      0|	}
  670|      3|	return expand_homedir_path_home(inpath, homedir);
  671|      3|}
gettime_wrapper:
  686|   833k|void gettime_wrapper(struct timespec *now) {
  687|   833k|	struct timeval tv;
  688|   833k|#if DROPBEAR_FUZZ
  689|   833k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (689:6): [True: 833k, False: 0]
  ------------------
  690|       |		/* time stands still when fuzzing */
  691|   833k|		now->tv_sec = 5;
  692|   833k|		now->tv_nsec = 0;
  693|   833k|	}
  694|   833k|#endif
  695|       |
  696|   833k|#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
  697|       |	/* POSIX monotonic clock. Newer Linux, BSD, MacOSX >10.12 */
  698|   833k|	if (clock_gettime(CLOCK_MONOTONIC, now) == 0) {
  ------------------
  |  Branch (698:6): [True: 833k, False: 0]
  ------------------
  699|   833k|		return;
  700|   833k|	}
  701|      0|#endif
  702|       |
  703|      0|#if defined(__linux__) && defined(SYS_clock_gettime)
  704|      0|	{
  705|       |	/* Old linux toolchain - kernel might support it but not the build headers */
  706|       |	/* Also glibc <2.17 requires -lrt which we neglect to add */
  707|      0|	static int linux_monotonic_failed = 0;
  708|      0|	if (!linux_monotonic_failed) {
  ------------------
  |  Branch (708:6): [True: 0, False: 0]
  ------------------
  709|       |		/* CLOCK_MONOTONIC isn't in some headers */
  710|      0|		int clock_source_monotonic = 1; 
  711|      0|		if (syscall(SYS_clock_gettime, clock_source_monotonic, now) == 0) {
  ------------------
  |  Branch (711:7): [True: 0, False: 0]
  ------------------
  712|      0|			return;
  713|      0|		} else {
  714|       |			/* Don't try again */
  715|      0|			linux_monotonic_failed = 1;
  716|      0|		}
  717|      0|	}
  718|      0|	}
  719|      0|#endif /* linux fallback clock_gettime */
  720|       |
  721|       |#if defined(HAVE_MACH_ABSOLUTE_TIME)
  722|       |	{
  723|       |	/* OS X pre 10.12, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */
  724|       |	static mach_timebase_info_data_t timebase_info;
  725|       |	uint64_t scaled_time;
  726|       |	if (timebase_info.denom == 0) {
  727|       |		mach_timebase_info(&timebase_info);
  728|       |	}
  729|       |	scaled_time = mach_absolute_time() * timebase_info.numer / timebase_info.denom;
  730|       |	now->tv_sec = scaled_time / 1000000000;
  731|       |	now->tv_nsec = scaled_time % 1000000000;
  732|       |	}
  733|       |#endif /* osx mach_absolute_time */
  734|       |
  735|       |	/* Fallback for everything else - this will sometimes go backwards */
  736|      0|	gettimeofday(&tv, NULL);
  737|      0|	now->tv_sec = tv.tv_sec;
  738|      0|	now->tv_nsec = 1000*(long)tv.tv_usec;
  739|      0|}
monotonic_now:
  742|   833k|time_t monotonic_now() {
  743|   833k|	struct timespec ts;
  744|   833k|	gettime_wrapper(&ts);
  745|   833k|	return ts.tv_sec;
  746|   833k|}

buf_get_dss_pub_key:
   46|      1|int buf_get_dss_pub_key(buffer* buf, dropbear_dss_key *key) {
   47|      1|	int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
   48|       |
   49|      1|	TRACE(("enter buf_get_dss_pub_key"))
   50|      1|	dropbear_assert(key != NULL);
  ------------------
  |  |   84|      1|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 1]
  |  |  |  Branch (84:93): [Folded, False: 1]
  |  |  ------------------
  ------------------
   51|      1|	m_mp_alloc_init_multi(&key->p, &key->q, &key->g, &key->y, NULL);
   52|      1|	key->x = NULL;
   53|       |
   54|      1|	buf_incrpos(buf, 4+SSH_SIGNKEY_DSS_LEN); /* int + "ssh-dss" */
  ------------------
  |  |  115|      1|#define SSH_SIGNKEY_DSS_LEN 7
  ------------------
   55|      1|	if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE
  ------------------
  |  |  112|      2|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (55:6): [True: 0, False: 1]
  ------------------
   56|      1|	 || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE
  ------------------
  |  |  112|      2|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (56:6): [True: 0, False: 1]
  ------------------
   57|      1|	 || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE
  ------------------
  |  |  112|      2|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (57:6): [True: 0, False: 1]
  ------------------
   58|      1|	 || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (58:6): [True: 0, False: 1]
  ------------------
   59|      0|		TRACE(("leave buf_get_dss_pub_key: failed reading mpints"))
   60|      0|		ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
   61|      0|		goto out;
   62|      0|	}
   63|       |
   64|      1|	if (mp_count_bits(key->p) != DSS_P_BITS) {
  ------------------
  |  |   44|      1|#define DSS_P_BITS 1024
  ------------------
  |  Branch (64:6): [True: 0, False: 1]
  ------------------
   65|      0|		dropbear_log(LOG_WARNING, "Bad DSS p");
   66|      0|		ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
   67|      0|		goto out;
   68|      0|	}
   69|       |
   70|      1|	if (mp_count_bits(key->q) != DSS_Q_BITS) {
  ------------------
  |  |   45|      1|#define DSS_Q_BITS 160
  ------------------
  |  Branch (70:6): [True: 0, False: 1]
  ------------------
   71|      0|		dropbear_log(LOG_WARNING, "Bad DSS q");
   72|      0|		ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
   73|      0|		goto out;
   74|      0|	}
   75|       |
   76|       |	/* test 1 < g < p */
   77|      1|	if (mp_cmp_d(key->g, 1) != MP_GT) {
  ------------------
  |  |  156|      1|#define MP_GT         1   /* greater than */
  ------------------
  |  Branch (77:6): [True: 0, False: 1]
  ------------------
   78|      0|		dropbear_log(LOG_WARNING, "Bad DSS g");
   79|      0|		ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
   80|      0|		goto out;
   81|      0|	}
   82|      1|	if (mp_cmp(key->g, key->p) != MP_LT) {
  ------------------
  |  |  154|      1|#define MP_LT        -1   /* less than */
  ------------------
  |  Branch (82:6): [True: 0, False: 1]
  ------------------
   83|      0|		dropbear_log(LOG_WARNING, "Bad DSS g");
   84|      0|		ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
   85|      0|		goto out;
   86|      0|	}
   87|       |
   88|      1|	ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      1|#define DROPBEAR_SUCCESS 0
  ------------------
   89|      1|	TRACE(("leave buf_get_dss_pub_key: success"))
   90|      1|out:
   91|      1|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (91:6): [True: 0, False: 1]
  ------------------
   92|       |		m_mp_free_multi(&key->p, &key->q, &key->g, &key->y, NULL);
   93|      0|	}
   94|      1|	return ret;
   95|      1|}
buf_get_dss_priv_key:
  100|      1|int buf_get_dss_priv_key(buffer* buf, dropbear_dss_key *key) {
  101|       |
  102|      1|	int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  103|       |
  104|      1|	dropbear_assert(key != NULL);
  ------------------
  |  |   84|      1|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 1]
  |  |  |  Branch (84:93): [Folded, False: 1]
  |  |  ------------------
  ------------------
  105|       |
  106|      1|	ret = buf_get_dss_pub_key(buf, key);
  107|      1|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (107:6): [True: 0, False: 1]
  ------------------
  108|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  109|      0|	}
  110|       |
  111|      1|	m_mp_alloc_init_multi(&key->x, NULL);
  112|      1|	ret = buf_getmpint(buf, key->x);
  113|      1|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (113:6): [True: 0, False: 1]
  ------------------
  114|      0|		m_mp_free_multi(&key->x, NULL);
  115|      0|	}
  116|       |
  117|      1|	return ret;
  118|      1|}
dss_key_free:
  122|      1|void dss_key_free(dropbear_dss_key *key) {
  123|       |
  124|      1|	TRACE2(("enter dsa_key_free"))
  125|      1|	if (key == NULL) {
  ------------------
  |  Branch (125:6): [True: 1, False: 0]
  ------------------
  126|      1|		TRACE2(("enter dsa_key_free: key == NULL"))
  127|      1|		return;
  128|      1|	}
  129|      0|	m_mp_free_multi(&key->p, &key->q, &key->g, &key->y, &key->x, NULL);
  130|       |	m_free(key);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  131|      0|	TRACE2(("leave dsa_key_free"))
  132|      0|}

dropbear_ecc_fill_dp:
   47|      1|void dropbear_ecc_fill_dp() {
   48|      1|	struct dropbear_ecc_curve **curve;
   49|       |	/* libtomcrypt guarantees they're ordered by size */
   50|      1|	const ltc_ecc_set_type *dp = ltc_ecc_sets;
   51|      4|	for (curve = dropbear_ecc_curves; *curve; curve++) {
  ------------------
  |  Branch (51:36): [True: 3, False: 1]
  ------------------
   52|      5|		for (;dp->size > 0; dp++) {
  ------------------
  |  Branch (52:9): [True: 5, False: 0]
  ------------------
   53|      5|			if (dp->size == (*curve)->ltc_size) {
  ------------------
  |  Branch (53:8): [True: 3, False: 2]
  ------------------
   54|      3|				(*curve)->dp = dp;
   55|      3|				break;
   56|      3|			}
   57|      5|		}
   58|      3|		if (!(*curve)->dp) {
  ------------------
  |  Branch (58:7): [True: 0, False: 3]
  ------------------
   59|      0|			dropbear_exit("Missing ECC params %s", (*curve)->name);
   60|      0|		}
   61|      3|	}
   62|      1|}
new_ecc_key:
   75|      1|ecc_key * new_ecc_key(void) {
   76|      1|	ecc_key *key = m_malloc(sizeof(*key));
   77|      1|	m_mp_alloc_init_multi((mp_int**)&key->pubkey.x, (mp_int**)&key->pubkey.y, 
   78|       |		(mp_int**)&key->pubkey.z, (mp_int**)&key->k, NULL);
   79|      1|	return key;
   80|      1|}
buf_get_ecc_raw_pubkey:
  147|      1|ecc_key * buf_get_ecc_raw_pubkey(buffer *buf, const struct dropbear_ecc_curve *curve) {
  148|      1|	ecc_key *key = NULL;
  149|      1|	int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  150|      1|	const unsigned int size = curve->dp->size;
  151|      1|	unsigned char first;
  152|       |
  153|      1|	TRACE(("enter buf_get_ecc_raw_pubkey"))
  154|       |
  155|      1|	buf_setpos(buf, 0);
  156|      1|	first = buf_getbyte(buf);
  157|      1|	if (first == 2 || first == 3) {
  ------------------
  |  Branch (157:6): [True: 0, False: 1]
  |  Branch (157:20): [True: 0, False: 1]
  ------------------
  158|      0|		dropbear_log(LOG_WARNING, "Dropbear doesn't support ECC point compression");
  159|      0|		return NULL;
  160|      0|	}
  161|      1|	if (first != 4 || buf->len != 1+2*size) {
  ------------------
  |  Branch (161:6): [True: 0, False: 1]
  |  Branch (161:20): [True: 0, False: 1]
  ------------------
  162|      0|		TRACE(("leave, wrong size"))
  163|      0|		return NULL;
  164|      0|	}
  165|       |
  166|      1|	key = new_ecc_key();
  167|      1|	key->dp = curve->dp;
  168|       |
  169|      1|	if (mp_from_ubin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
  ------------------
  |  |  161|      1|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (169:6): [True: 0, False: 1]
  ------------------
  170|      0|		TRACE(("failed to read x"))
  171|      0|		goto out;
  172|      0|	}
  173|      1|	buf_incrpos(buf, size);
  174|       |
  175|      1|	if (mp_from_ubin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
  ------------------
  |  |  161|      1|#define MP_OKAY       0   /* no error */
  ------------------
  |  Branch (175:6): [True: 0, False: 1]
  ------------------
  176|      0|		TRACE(("failed to read y"))
  177|      0|		goto out;
  178|      0|	}
  179|      1|	buf_incrpos(buf, size);
  180|       |
  181|      1|	mp_set(key->pubkey.z, 1);
  182|       |
  183|      1|	if (ecc_is_point(key) != CRYPT_OK) {
  ------------------
  |  Branch (183:6): [True: 0, False: 1]
  ------------------
  184|      0|		TRACE(("failed, not a point"))
  185|      0|		goto out;
  186|      0|	}
  187|       |
  188|       |   /* SEC1 3.2.3.1 Check that Q != 0 */
  189|      1|	if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) {
  ------------------
  |  |   13|      1|#define LTC_MP_EQ    0
  ------------------
  |  Branch (189:6): [True: 0, False: 1]
  ------------------
  190|      0|		TRACE(("failed, x == 0"))
  191|      0|		goto out;
  192|      0|	}
  193|      1|	if (mp_cmp_d(key->pubkey.y, 0) == LTC_MP_EQ) {
  ------------------
  |  |   13|      1|#define LTC_MP_EQ    0
  ------------------
  |  Branch (193:6): [True: 0, False: 1]
  ------------------
  194|      0|		TRACE(("failed, y == 0"))
  195|      0|		goto out;
  196|      0|	}
  197|       |
  198|      1|	ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      1|#define DROPBEAR_SUCCESS 0
  ------------------
  199|       |
  200|      1|	out:
  201|      1|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (201:6): [True: 0, False: 1]
  ------------------
  202|      0|		if (key) {
  ------------------
  |  Branch (202:7): [True: 0, False: 0]
  ------------------
  203|      0|			ecc_free(key);
  204|      0|			m_free(key);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  205|      0|			key = NULL;
  206|      0|		}
  207|      0|	}
  208|       |
  209|      1|	return key;
  210|       |
  211|      1|}
ecc.c:ecc_is_point:
   85|      1|{
   86|      1|	mp_int *prime, *b, *t1, *t2;
   87|      1|	int err;
   88|       |	
   89|      1|	m_mp_alloc_init_multi(&prime, &b, &t1, &t2, NULL);
   90|       |	
   91|       |   /* load prime and b */
   92|      1|	if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK)                          { goto error; }
  ------------------
  |  Branch (92:6): [True: 0, False: 1]
  ------------------
   93|      1|	if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK)                                  { goto error; }
  ------------------
  |  Branch (93:6): [True: 0, False: 1]
  ------------------
   94|       |	
   95|       |   /* compute y^2 */
   96|      1|	if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK)                                         { goto error; }
  ------------------
  |  Branch (96:6): [True: 0, False: 1]
  ------------------
   97|       |	
   98|       |   /* compute x^3 */
   99|      1|	if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK)                                         { goto error; }
  ------------------
  |  Branch (99:6): [True: 0, False: 1]
  ------------------
  100|      1|	if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK)                                             { goto error; }
  ------------------
  |  Branch (100:6): [True: 0, False: 1]
  ------------------
  101|      1|	if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK)                                     { goto error; }
  ------------------
  |  Branch (101:6): [True: 0, False: 1]
  ------------------
  102|       |	
  103|       |   /* compute y^2 - x^3 */
  104|      1|	if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK)                                                { goto error; }
  ------------------
  |  Branch (104:6): [True: 0, False: 1]
  ------------------
  105|       |	
  106|       |   /* compute y^2 - x^3 + 3x */
  107|      1|	if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
  ------------------
  |  Branch (107:6): [True: 0, False: 1]
  ------------------
  108|      1|	if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
  ------------------
  |  Branch (108:6): [True: 0, False: 1]
  ------------------
  109|      1|	if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
  ------------------
  |  Branch (109:6): [True: 0, False: 1]
  ------------------
  110|      1|	if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK)                                             { goto error; }
  ------------------
  |  Branch (110:6): [True: 0, False: 1]
  ------------------
  111|      1|	while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
  ------------------
  |  |   12|      1|#define LTC_MP_LT   -1
  ------------------
  |  Branch (111:9): [True: 0, False: 1]
  ------------------
  112|      0|		if ((err = mp_add(t1, prime, t1)) != CRYPT_OK)                                          { goto error; }
  ------------------
  |  Branch (112:7): [True: 0, False: 0]
  ------------------
  113|      0|	}
  114|      1|	while (mp_cmp(t1, prime) != LTC_MP_LT) {
  ------------------
  |  |   12|      1|#define LTC_MP_LT   -1
  ------------------
  |  Branch (114:9): [True: 0, False: 1]
  ------------------
  115|      0|		if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK)                                          { goto error; }
  ------------------
  |  Branch (115:7): [True: 0, False: 0]
  ------------------
  116|      0|	}
  117|       |	
  118|       |   /* compare to b */
  119|      1|	if (mp_cmp(t1, b) != LTC_MP_EQ) {
  ------------------
  |  |   13|      1|#define LTC_MP_EQ    0
  ------------------
  |  Branch (119:6): [True: 0, False: 1]
  ------------------
  120|      0|		err = CRYPT_INVALID_PACKET;
  121|      1|	} else {
  122|      1|		err = CRYPT_OK;
  123|      1|	}
  124|       |	
  125|      1|	error:
  126|      1|	mp_clear_multi(prime, b, t1, t2, NULL);
  127|      1|	m_free(prime);
  ------------------
  |  |   24|      1|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1]
  |  |  ------------------
  ------------------
  128|      1|	m_free(b);
  ------------------
  |  |   24|      1|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1]
  |  |  ------------------
  ------------------
  129|      1|	m_free(t1);
  ------------------
  |  |   24|      1|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1]
  |  |  ------------------
  ------------------
  130|       |	m_free(t2);
  ------------------
  |  |   24|      1|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1]
  |  |  ------------------
  ------------------
  131|      1|	return err;
  132|      1|}

signkey_is_ecdsa:
   11|      4|{
   12|      4|	return type == DROPBEAR_SIGNKEY_ECDSA_NISTP256
  ------------------
  |  Branch (12:9): [True: 1, False: 3]
  ------------------
   13|      3|		|| type == DROPBEAR_SIGNKEY_ECDSA_NISTP384
  ------------------
  |  Branch (13:6): [True: 0, False: 3]
  ------------------
   14|      3|		|| type == DROPBEAR_SIGNKEY_ECDSA_NISTP521;
  ------------------
  |  Branch (14:6): [True: 0, False: 3]
  ------------------
   15|      4|}
buf_get_ecdsa_pub_key:
   77|      1|ecc_key *buf_get_ecdsa_pub_key(buffer* buf) {
   78|      1|	unsigned char *key_ident = NULL, *identifier = NULL;
   79|      1|	unsigned int key_ident_len, identifier_len;
   80|      1|	buffer *q_buf = NULL;
   81|      1|	struct dropbear_ecc_curve **curve;
   82|      1|	ecc_key *new_key = NULL;
   83|       |
   84|       |	/* string   "ecdsa-sha2-[identifier]" or "sk-ecdsa-sha2-nistp256@openssh.com" */
   85|      1|	key_ident = (unsigned char*)buf_getstring(buf, &key_ident_len);
   86|       |	/* string   "[identifier]" */
   87|      1|	identifier = (unsigned char*)buf_getstring(buf, &identifier_len);
   88|       |
   89|      1|	if (strcmp (key_ident, "sk-ecdsa-sha2-nistp256@openssh.com") == 0) {
  ------------------
  |  Branch (89:6): [True: 0, False: 1]
  ------------------
   90|      0|		if (strcmp (identifier, "nistp256") != 0) {
  ------------------
  |  Branch (90:7): [True: 0, False: 0]
  ------------------
   91|      0|			TRACE(("mismatching identifiers"))
   92|      0|			goto out;
   93|      0|		}
   94|      1|	} else {
   95|      1|		if (key_ident_len != identifier_len + strlen ("ecdsa-sha2-")) {
  ------------------
  |  Branch (95:7): [True: 0, False: 1]
  ------------------
   96|      0|			TRACE(("Bad identifier lengths"))
   97|      0|			goto out;
   98|      0|		}
   99|      1|		if (memcmp(&key_ident[strlen ("ecdsa-sha2-")], identifier, identifier_len) != 0) {
  ------------------
  |  Branch (99:7): [True: 0, False: 1]
  ------------------
  100|      0|			TRACE(("mismatching identifiers"))
  101|      0|			goto out;
  102|      0|		}
  103|      1|	}
  104|       |
  105|      1|	for (curve = dropbear_ecc_curves; *curve; curve++) {
  ------------------
  |  Branch (105:36): [True: 1, False: 0]
  ------------------
  106|      1|		if (memcmp(identifier, (char*)(*curve)->name, strlen((char*)(*curve)->name)) == 0) {
  ------------------
  |  Branch (106:7): [True: 1, False: 0]
  ------------------
  107|      1|			break;
  108|      1|		}
  109|      1|	}
  110|      1|	if (!*curve) {
  ------------------
  |  Branch (110:6): [True: 0, False: 1]
  ------------------
  111|      0|		TRACE(("couldn't match ecc curve"))
  112|      0|		goto out;
  113|      0|	}
  114|       |
  115|       |	/* string Q */
  116|      1|	q_buf = buf_getstringbuf(buf);
  117|      1|	new_key = buf_get_ecc_raw_pubkey(q_buf, *curve);
  118|       |
  119|      1|out:
  120|      1|	m_free(key_ident);
  ------------------
  |  |   24|      1|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1]
  |  |  ------------------
  ------------------
  121|      1|	m_free(identifier);
  ------------------
  |  |   24|      1|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1]
  |  |  ------------------
  ------------------
  122|      1|	if (q_buf) {
  ------------------
  |  Branch (122:6): [True: 1, False: 0]
  ------------------
  123|      1|		buf_free(q_buf);
  124|       |		q_buf = NULL;
  125|      1|	}
  126|      1|	TRACE(("leave buf_get_ecdsa_pub_key"))	
  127|      1|	return new_key;
  128|      1|}
buf_get_ecdsa_priv_key:
  130|      1|ecc_key *buf_get_ecdsa_priv_key(buffer *buf) {
  131|      1|	ecc_key *new_key = NULL;
  132|      1|	TRACE(("enter buf_get_ecdsa_priv_key"))
  133|      1|	new_key = buf_get_ecdsa_pub_key(buf);
  134|      1|	if (!new_key) {
  ------------------
  |  Branch (134:6): [True: 0, False: 1]
  ------------------
  135|      0|		return NULL;
  136|      0|	}
  137|       |
  138|      1|	if (buf_getmpint(buf, new_key->k) != DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|      1|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (138:6): [True: 0, False: 1]
  ------------------
  139|      0|		ecc_free(new_key);
  140|      0|		m_free(new_key);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  141|      0|		return NULL;
  142|      0|	}
  143|       |
  144|      1|	return new_key;
  145|      1|}

buf_get_ed25519_priv_key:
   78|      1|int buf_get_ed25519_priv_key(buffer *buf, dropbear_ed25519_key *key) {
   79|       |
   80|      1|	unsigned int len;
   81|       |
   82|      1|	TRACE(("enter buf_get_ed25519_priv_key"))
   83|      1|	dropbear_assert(key != NULL);
  ------------------
  |  |   84|      1|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 1]
  |  |  |  Branch (84:93): [Folded, False: 1]
  |  |  ------------------
  ------------------
   84|       |
   85|      1|	buf_incrpos(buf, 4+SSH_SIGNKEY_ED25519_LEN); /* int + "ssh-ed25519" */
  ------------------
  |  |  119|      1|#define SSH_SIGNKEY_ED25519_LEN 11
  ------------------
   86|       |
   87|      1|	len = buf_getint(buf);
   88|      1|	if (len != CURVE25519_LEN*2 || buf->len - buf->pos < len) {
  ------------------
  |  |   34|      1|#define CURVE25519_LEN 32
  ------------------
  |  Branch (88:6): [True: 0, False: 1]
  |  Branch (88:33): [True: 0, False: 1]
  ------------------
   89|      0|		TRACE(("leave buf_get_ed25519_priv_key: failure"))
   90|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
   91|      0|	}
   92|       |
   93|      1|	memcpy(key->priv, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
  ------------------
  |  |   34|      1|#define CURVE25519_LEN 32
  ------------------
              	memcpy(key->priv, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
  ------------------
  |  |   34|      1|#define CURVE25519_LEN 32
  ------------------
   94|      1|	buf_incrpos(buf, CURVE25519_LEN);
  ------------------
  |  |   34|      1|#define CURVE25519_LEN 32
  ------------------
   95|      1|	memcpy(key->pub, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
  ------------------
  |  |   34|      1|#define CURVE25519_LEN 32
  ------------------
              	memcpy(key->pub, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
  ------------------
  |  |   34|      1|#define CURVE25519_LEN 32
  ------------------
   96|      1|	buf_incrpos(buf, CURVE25519_LEN);
  ------------------
  |  |   34|      1|#define CURVE25519_LEN 32
  ------------------
   97|       |
   98|      1|	TRACE(("leave buf_get_ed25519_priv_key: success"))
   99|      1|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      1|#define DROPBEAR_SUCCESS 0
  ------------------
  100|      1|}
ed25519_key_free:
  103|      1|void ed25519_key_free(dropbear_ed25519_key *key) {
  104|       |
  105|      1|	TRACE2(("enter ed25519_key_free"))
  106|       |
  107|      1|	if (key == NULL) {
  ------------------
  |  Branch (107:6): [True: 1, False: 0]
  ------------------
  108|      1|		TRACE2(("leave ed25519_key_free: key == NULL"))
  109|      1|		return;
  110|      1|	}
  111|      0|	m_burn(key->priv, CURVE25519_LEN);
  ------------------
  |  |   34|      0|#define CURVE25519_LEN 32
  ------------------
  112|      0|	m_free(key);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  113|       |
  114|      0|	TRACE2(("leave ed25519_key_free"))
  115|      0|}

list_append:
    5|    137|void list_append(m_list *list, void *item) {
    6|    137|	m_list_elem *elem;
    7|       |	
    8|    137|	elem = m_malloc(sizeof(*elem));
    9|    137|	elem->item = item;
   10|    137|	elem->list = list;
   11|    137|	elem->next = NULL;
   12|    137|	if (!list->first) {
  ------------------
  |  Branch (12:6): [True: 137, False: 0]
  ------------------
   13|    137|		list->first = elem;
   14|    137|		elem->prev = NULL;
   15|    137|	} else {
   16|      0|		elem->prev = list->last;
   17|      0|		list->last->next = elem;
   18|      0|	}
   19|    137|	list->last = elem;
   20|    137|}
list_remove:
   28|    137|void * list_remove(m_list_elem *elem) {
   29|    137|	void *item = elem->item;
   30|    137|	m_list *list = elem->list;
   31|    137|	if (list->first == elem)
  ------------------
  |  Branch (31:6): [True: 137, False: 0]
  ------------------
   32|    137|	{
   33|    137|		list->first = elem->next;
   34|    137|	}
   35|    137|	if (list->last == elem)
  ------------------
  |  Branch (35:6): [True: 137, False: 0]
  ------------------
   36|    137|	{
   37|    137|		list->last = elem->prev;
   38|    137|	}
   39|    137|	if (elem->prev)
  ------------------
  |  Branch (39:6): [True: 0, False: 137]
  ------------------
   40|      0|	{
   41|      0|		elem->prev->next = elem->next;
   42|      0|	}
   43|    137|	if (elem->next)
  ------------------
  |  Branch (43:6): [True: 0, False: 137]
  ------------------
   44|      0|	{
   45|      0|		elem->next->prev = elem->prev;
   46|      0|	}
   47|       |	m_free(elem);
  ------------------
  |  |   24|    137|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 137]
  |  |  ------------------
  ------------------
   48|    137|	return item;
   49|    137|}

listeners_initialise:
   30|  4.58k|void listeners_initialise() {
   31|       |
   32|       |	/* just one slot to start with */
   33|  4.58k|	ses.listeners = (struct Listener**)m_malloc(sizeof(struct Listener*));
   34|  4.58k|	ses.listensize = 1;
   35|  4.58k|	ses.listeners[0] = NULL;
   36|       |
   37|  4.58k|}
set_listener_fds:
   39|   302k|void set_listener_fds(fd_set * readfds) {
   40|       |
   41|   302k|	unsigned int i, j;
   42|   302k|	struct Listener *listener;
   43|       |
   44|       |	/* check each in turn */
   45|   615k|	for (i = 0; i < ses.listensize; i++) {
  ------------------
  |  Branch (45:14): [True: 313k, False: 302k]
  ------------------
   46|   313k|		listener = ses.listeners[i];
   47|   313k|		if (listener != NULL) {
  ------------------
  |  Branch (47:7): [True: 19.2k, False: 293k]
  ------------------
   48|  38.5k|			for (j = 0; j < listener->nsocks; j++) {
  ------------------
  |  Branch (48:16): [True: 19.2k, False: 19.2k]
  ------------------
   49|       |				FD_SET(listener->socks[j], readfds);
   50|  19.2k|			}
   51|  19.2k|		}
   52|   313k|	}
   53|   302k|}
handle_listeners:
   56|   298k|void handle_listeners(const fd_set * readfds) {
   57|       |
   58|   298k|	unsigned int i, j;
   59|   298k|	struct Listener *listener;
   60|   298k|	int sock;
   61|       |
   62|       |	/* check each in turn */
   63|   606k|	for (i = 0; i < ses.listensize; i++) {
  ------------------
  |  Branch (63:14): [True: 308k, False: 298k]
  ------------------
   64|   308k|		listener = ses.listeners[i];
   65|   308k|		if (listener != NULL) {
  ------------------
  |  Branch (65:7): [True: 19.2k, False: 289k]
  ------------------
   66|  38.5k|			for (j = 0; j < listener->nsocks; j++) {
  ------------------
  |  Branch (66:16): [True: 19.2k, False: 19.2k]
  ------------------
   67|  19.2k|				sock = listener->socks[j];
   68|  19.2k|				if (FD_ISSET(sock, readfds)) {
  ------------------
  |  Branch (68:9): [True: 8.84k, False: 10.4k]
  ------------------
   69|  8.84k|					listener->acceptor(listener, sock);
   70|  8.84k|				}
   71|  19.2k|			}
   72|  19.2k|		}
   73|   308k|	}
   74|   298k|} /* Woo brace matching */
new_listener:
   82|    216|		void (*cleanup)(const struct Listener*)) {
   83|       |
   84|    216|	unsigned int i, j;
   85|    216|	struct Listener *newlisten = NULL;
   86|       |	/* try get a new structure to hold it */
   87|    361|	for (i = 0; i < ses.listensize; i++) {
  ------------------
  |  Branch (87:14): [True: 329, False: 32]
  ------------------
   88|    329|		if (ses.listeners[i] == NULL) {
  ------------------
  |  Branch (88:7): [True: 184, False: 145]
  ------------------
   89|    184|			break;
   90|    184|		}
   91|    329|	}
   92|       |
   93|       |	/* or create a new one */
   94|    216|	if (i == ses.listensize) {
  ------------------
  |  Branch (94:6): [True: 32, False: 184]
  ------------------
   95|     32|		if (ses.listensize > MAX_LISTENERS) {
  ------------------
  |  |   28|     32|#define MAX_LISTENERS 20
  ------------------
  |  Branch (95:7): [True: 0, False: 32]
  ------------------
   96|      0|			TRACE(("leave newlistener: too many already"))
   97|      0|			for (j = 0; j < nsocks; j++) {
  ------------------
  |  Branch (97:16): [True: 0, False: 0]
  ------------------
   98|      0|				close(socks[j]);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
   99|      0|			}
  100|      0|			return NULL;
  101|      0|		}
  102|       |		
  103|     32|		ses.listeners = (struct Listener**)m_realloc(ses.listeners,
  104|     32|				(ses.listensize+LISTENER_EXTEND_SIZE)
  ------------------
  |  |   29|     32|#define LISTENER_EXTEND_SIZE 1
  ------------------
  105|     32|				*sizeof(struct Listener*));
  106|       |
  107|     32|		ses.listensize += LISTENER_EXTEND_SIZE;
  ------------------
  |  |   29|     32|#define LISTENER_EXTEND_SIZE 1
  ------------------
  108|       |
  109|     64|		for (j = i; j < ses.listensize; j++) {
  ------------------
  |  Branch (109:15): [True: 32, False: 32]
  ------------------
  110|     32|			ses.listeners[j] = NULL;
  111|     32|		}
  112|     32|	}
  113|       |
  114|    432|	for (j = 0; j < nsocks; j++) {
  ------------------
  |  Branch (114:14): [True: 216, False: 216]
  ------------------
  115|    216|		ses.maxfd = MAX(ses.maxfd, socks[j]);
  ------------------
  |  Branch (115:15): [True: 10, False: 206]
  ------------------
  116|    216|	}
  117|       |
  118|    216|	TRACE(("new listener num %d ", i))
  119|       |
  120|    216|	newlisten = (struct Listener*)m_malloc(sizeof(struct Listener));
  121|    216|	newlisten->index = i;
  122|    216|	newlisten->type = type;
  123|    216|	newlisten->typedata = typedata;
  124|    216|	newlisten->nsocks = nsocks;
  125|    216|	memcpy(newlisten->socks, socks, nsocks * sizeof(int));
  126|    216|	newlisten->acceptor = acceptor;
  127|    216|	newlisten->cleanup = cleanup;
  128|       |
  129|    216|	ses.listeners[i] = newlisten;
  130|    216|	return newlisten;
  131|    216|}
get_listener:
  136|    122|		int (*match)(const void*, const void*)) {
  137|       |
  138|    122|	unsigned int i;
  139|       |
  140|    278|	for (i = 0; i < ses.listensize; i++) {
  ------------------
  |  Branch (140:14): [True: 156, False: 122]
  ------------------
  141|    156|		struct Listener* listener = ses.listeners[i];
  142|    156|		if (listener && listener->type == type
  ------------------
  |  Branch (142:7): [True: 78, False: 78]
  |  Branch (142:19): [True: 0, False: 78]
  ------------------
  143|      0|				&& match(typedata, listener->typedata)) {
  ------------------
  |  Branch (143:8): [True: 0, False: 0]
  ------------------
  144|      0|			return listener;
  145|      0|		}
  146|    156|	}
  147|       |
  148|    122|	return NULL;
  149|    122|}
remove_listener:
  151|    216|void remove_listener(struct Listener* listener) {
  152|       |
  153|    216|	unsigned int j;
  154|       |
  155|    216|	if (listener->cleanup) {
  ------------------
  |  Branch (155:6): [True: 0, False: 216]
  ------------------
  156|      0|		listener->cleanup(listener);
  157|      0|	}
  158|       |
  159|    432|	for (j = 0; j < listener->nsocks; j++) {
  ------------------
  |  Branch (159:14): [True: 216, False: 216]
  ------------------
  160|    216|		close(listener->socks[j]);
  ------------------
  |  |   56|    216|#define close(fd) wrapfd_close(fd)
  ------------------
  161|    216|	}
  162|    216|	ses.listeners[listener->index] = NULL;
  163|       |	m_free(listener);
  ------------------
  |  |   24|    216|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 216]
  |  |  ------------------
  ------------------
  164|    216|}
remove_all_listeners:
  166|  4.58k|void remove_all_listeners(void) {
  167|  4.58k|	unsigned int i;
  168|  9.19k|	for (i = 0; i < ses.listensize; i++) {
  ------------------
  |  Branch (168:14): [True: 4.61k, False: 4.58k]
  ------------------
  169|  4.61k|		if (ses.listeners[i]) {
  ------------------
  |  Branch (169:7): [True: 0, False: 4.61k]
  ------------------
  170|      0|			remove_listener(ses.listeners[i]);
  171|      0|		}
  172|  4.61k|	}
  173|       |	m_free(ses.listeners);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  174|  4.58k|}

login_logout:
  211|     10|{
  212|     10|	li->type = LTYPE_LOGOUT;
  ------------------
  |  |  119|     10|#define LTYPE_LOGOUT   8
  ------------------
  213|     10|	login_write(li);
  214|     10|}
login_alloc_entry:
  229|     10|{
  230|     10|	struct logininfo *newli;
  231|       |
  232|     10|	newli = (struct logininfo *) m_malloc (sizeof(*newli));
  233|     10|	(void)login_init_entry(newli, pid, username, hostname, line);
  234|     10|	return newli;
  235|     10|}
login_free_entry:
  241|     10|{
  242|       |	m_free(li);
  ------------------
  |  |   24|     10|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 10]
  |  |  ------------------
  ------------------
  243|     10|}
login_init_entry:
  257|     10|{
  258|     10|	struct passwd *pw;
  259|       |
  260|     10|	memset(li, 0, sizeof(*li));
  261|       |
  262|     10|	li->pid = pid;
  263|       |
  264|       |	/* set the line information */
  265|     10|	if (line)
  ------------------
  |  Branch (265:6): [True: 10, False: 0]
  ------------------
  266|     10|		line_fullname(li->line, line, sizeof(li->line));
  267|       |
  268|     10|	if (username) {
  ------------------
  |  Branch (268:6): [True: 0, False: 10]
  ------------------
  269|      0|		strlcpy(li->username, username, sizeof(li->username));
  270|      0|		pw = getpwnam(li->username);
  ------------------
  |  |  108|      0|#define getpwnam(x) fuzz_getpwnam(x)
  ------------------
  271|      0|		if (pw == NULL)
  ------------------
  |  Branch (271:7): [True: 0, False: 0]
  ------------------
  272|      0|			dropbear_exit("login_init_entry: Cannot find user \"%s\"",
  273|      0|					li->username);
  274|      0|		li->uid = pw->pw_uid;
  275|      0|	}
  276|       |
  277|     10|	if (hostname)
  ------------------
  |  Branch (277:6): [True: 10, False: 0]
  ------------------
  278|     10|		strlcpy(li->hostname, hostname, sizeof(li->hostname));
  279|       |
  280|     10|	return 1;
  281|     10|}
login_set_current_time:
  291|     10|{
  292|     10|	struct timeval tv;
  293|       |
  294|     10|	gettimeofday(&tv, NULL);
  295|       |
  296|     10|	li->tv_sec = tv.tv_sec;
  297|     10|	li->tv_usec = tv.tv_usec;
  298|     10|}
login_write:
  306|     10|{
  307|       |	/* set the timestamp */
  308|     10|	login_set_current_time(li);
  309|     10|#ifdef USE_LOGIN
  310|     10|	syslogin_write_entry(li);
  311|     10|#endif
  312|     10|#ifdef USE_LASTLOG
  313|     10|	if (li->type == LTYPE_LOGIN) {
  ------------------
  |  |  118|     10|#define LTYPE_LOGIN    7
  ------------------
  |  Branch (313:6): [True: 0, False: 10]
  ------------------
  314|      0|		lastlog_write_entry(li);
  315|      0|	}
  316|     10|#endif
  317|       |#ifdef USE_UTMP
  318|       |	utmp_write_entry(li);
  319|       |#endif
  320|       |#ifdef USE_WTMP
  321|       |	wtmp_write_entry(li);
  322|       |#endif
  323|       |#ifdef USE_UTMPX
  324|       |	utmpx_write_entry(li);
  325|       |#endif
  326|       |#ifdef USE_WTMPX
  327|       |	wtmpx_write_entry(li);
  328|       |#endif
  329|     10|}
line_fullname:
  376|     10|{
  377|     10|	memset(dst, '\0', dstsize);
  378|     10|	if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) {
  ------------------
  |  Branch (378:6): [True: 10, False: 0]
  |  Branch (378:41): [True: 0, False: 0]
  ------------------
  379|     10|		strlcpy(dst, src, dstsize);
  380|     10|	} else {
  381|      0|		strlcpy(dst, "/dev/", dstsize);
  382|      0|		strlcat(dst, src, dstsize);
  383|      0|	}
  384|     10|	return dst;
  385|     10|}
line_stripname:
  390|     10|{
  391|     10|	memset(dst, '\0', dstsize);
  392|     10|	if (strncmp(src, "/dev/", 5) == 0)
  ------------------
  |  Branch (392:6): [True: 10, False: 0]
  ------------------
  393|     10|		strlcpy(dst, src + 5, dstsize);
  394|      0|	else
  395|      0|		strlcpy(dst, src, dstsize);
  396|     10|	return dst;
  397|     10|}
syslogin_write_entry:
 1228|     10|{
 1229|     10|	switch (li->type) {
 1230|      0|	case LTYPE_LOGIN:
  ------------------
  |  |  118|      0|#define LTYPE_LOGIN    7
  ------------------
  |  Branch (1230:2): [True: 0, False: 10]
  ------------------
 1231|      0|		return syslogin_perform_login(li);
 1232|     10|	case LTYPE_LOGOUT:
  ------------------
  |  |  119|     10|#define LTYPE_LOGOUT   8
  ------------------
  |  Branch (1232:2): [True: 10, False: 0]
  ------------------
 1233|     10|		return syslogin_perform_logout(li);
 1234|      0|	default:
  ------------------
  |  Branch (1234:2): [True: 0, False: 10]
  ------------------
 1235|       |		dropbear_log(LOG_WARNING, "syslogin_write_entry: Invalid type field");
 1236|      0|		return 0;
 1237|     10|	}
 1238|     10|}
loginrec.c:syslogin_perform_logout:
 1205|     10|{
 1206|     10|# ifdef HAVE_LOGOUT
 1207|     10|	char line[8];
 1208|       |
 1209|     10|	(void)line_stripname(line, li->line, sizeof(line));
 1210|       |
 1211|     10|	if (!logout(line)) {
  ------------------
  |  Branch (1211:6): [True: 10, False: 0]
  ------------------
 1212|     10|		dropbear_log(LOG_WARNING, "syslogin_perform_logout: logout(%s) returned an error: %s", line, strerror(errno));
 1213|     10|#  ifdef HAVE_LOGWTMP
 1214|     10|	} else {
 1215|      0|		logwtmp(line, "", "");
 1216|      0|#  endif
 1217|      0|	}
 1218|       |	/* FIXME: (ATL - if the need arises) What to do if we have
 1219|       |	 * login, but no logout?  what if logout but no logwtmp? All
 1220|       |	 * routines are in libutil so they should all be there,
 1221|       |	 * but... */
 1222|     10|# endif
 1223|     10|	return 1;
 1224|     10|}

cancel_connect:
   57|    137|void cancel_connect(struct dropbear_progress_connection *c) {
   58|    137|	c->cb = cancel_callback;
   59|       |	c->cb_data = NULL;
   60|    137|}
connect_remote:
  191|     89|{
  192|     89|	struct dropbear_progress_connection *c = NULL;
  193|     89|	int err;
  194|     89|	struct addrinfo hints;
  195|       |
  196|     89|	c = m_malloc(sizeof(*c));
  197|     89|	c->remotehost = m_strdup(remotehost);
  198|     89|	c->remoteport = m_strdup(remoteport);
  199|     89|	c->sock = -1;
  200|     89|	c->cb = cb;
  201|     89|	c->cb_data = cb_data;
  202|     89|	c->prio = prio;
  203|       |
  204|     89|	list_append(&ses.conn_pending, c);
  205|       |
  206|     89|#if DROPBEAR_FUZZ
  207|     89|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (207:6): [True: 89, False: 0]
  ------------------
  208|     89|		c->errstring = m_strdup("fuzzing connect_remote always fails");
  209|     89|		return c;
  210|     89|	}
  211|      0|#endif
  212|       |
  213|      0|	memset(&hints, 0, sizeof(hints));
  214|      0|	hints.ai_socktype = SOCK_STREAM;
  215|      0|	hints.ai_family = AF_UNSPEC;
  216|       |
  217|      0|	err = getaddrinfo(remotehost, remoteport, &hints, &c->res);
  218|      0|	if (err) {
  ------------------
  |  Branch (218:6): [True: 0, False: 0]
  ------------------
  219|      0|		int len;
  220|      0|		len = 100 + strlen(gai_strerror(err));
  221|      0|		c->errstring = (char*)m_malloc(len);
  222|      0|		snprintf(c->errstring, len, "Error resolving '%s' port '%s'. %s", 
  223|      0|				remotehost, remoteport, gai_strerror(err));
  224|      0|		TRACE(("Error resolving: %s", gai_strerror(err)))
  225|      0|	} else {
  226|      0|		c->res_iter = c->res;
  227|      0|	}
  228|       |	
  229|      0|	if (bind_address) {
  ------------------
  |  Branch (229:6): [True: 0, False: 0]
  ------------------
  230|      0|		c->bind_address = m_strdup(bind_address);
  231|      0|	}
  232|      0|	if (bind_port) {
  ------------------
  |  Branch (232:6): [True: 0, False: 0]
  ------------------
  233|      0|		c->bind_port = m_strdup(bind_port);
  234|      0|	}
  235|       |
  236|      0|	return c;
  237|     89|}
connect_streamlocal:
  243|     48|{
  244|     48|	struct dropbear_progress_connection *c = NULL;
  245|     48|	struct sockaddr_un *sunaddr;
  246|       |
  247|     48|	c = m_malloc(sizeof(*c));
  248|     48|	c->remotehost = m_strdup(localpath);
  249|     48|	c->remoteport = NULL;
  250|     48|	c->sock = -1;
  251|     48|	c->cb = cb;
  252|     48|	c->cb_data = cb_data;
  253|     48|	c->prio = prio;
  254|       |
  255|     48|	list_append(&ses.conn_pending, c);
  256|       |
  257|     48|#if DROPBEAR_FUZZ
  258|     48|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (258:6): [True: 48, False: 0]
  ------------------
  259|     48|		c->errstring = m_strdup("fuzzing connect_streamlocal always fails");
  260|     48|		return c;
  261|     48|	}
  262|      0|#endif
  263|       |
  264|      0|	if (strlen(localpath) >= sizeof(sunaddr->sun_path)) {
  ------------------
  |  Branch (264:6): [True: 0, False: 0]
  ------------------
  265|      0|		c->errstring = m_strdup("Stream path too long");
  266|      0|		TRACE(("localpath: %s is too long", localpath));
  267|      0|		return c;
  268|      0|	}
  269|       |
  270|       |	/*
  271|       |	 * Fake up a struct addrinfo for AF_UNIX connections.
  272|       |	 * remove_connect() must check ai_family
  273|       |	 * and use m_free() not freeaddirinfo() for AF_UNIX.
  274|       |	 */
  275|      0|	c->res = m_malloc(sizeof(*c->res) + sizeof(*sunaddr));
  276|      0|	c->res->ai_addr = (struct sockaddr *)(c->res + 1);
  277|      0|	c->res->ai_addrlen = sizeof(*sunaddr);
  278|      0|	c->res->ai_family = AF_UNIX;
  279|      0|	c->res->ai_socktype = SOCK_STREAM;
  280|      0|	c->res->ai_protocol = PF_UNSPEC;
  281|      0|	sunaddr = (struct sockaddr_un *)c->res->ai_addr;
  282|      0|	sunaddr->sun_family = AF_UNIX;
  283|      0|	strlcpy(sunaddr->sun_path, localpath, sizeof(sunaddr->sun_path));
  284|       |
  285|       |	/* Copy to target iter */ 
  286|      0|	c->res_iter = c->res;
  287|       |
  288|      0|	return c;
  289|      0|}
remove_connect_pending:
  291|  4.58k|void remove_connect_pending() {
  292|  4.58k|	while (ses.conn_pending.first) {
  ------------------
  |  Branch (292:9): [True: 0, False: 4.58k]
  ------------------
  293|      0|		struct dropbear_progress_connection *c = ses.conn_pending.first->item;
  294|      0|		remove_connect(c, ses.conn_pending.first);
  295|      0|	}
  296|  4.58k|}
set_connect_fds:
  299|   302k|void set_connect_fds(fd_set *writefd) {
  300|   302k|	m_list_elem *iter;
  301|   302k|	iter = ses.conn_pending.first;
  302|   302k|	while (iter) {
  ------------------
  |  Branch (302:9): [True: 137, False: 302k]
  ------------------
  303|    137|		m_list_elem *next_iter = iter->next;
  304|    137|		struct dropbear_progress_connection *c = iter->item;
  305|       |		/* Set one going */
  306|    137|		while (c->res_iter && c->sock < 0) {
  ------------------
  |  Branch (306:10): [True: 0, False: 137]
  |  Branch (306:25): [True: 0, False: 0]
  ------------------
  307|      0|			connect_try_next(c);
  308|      0|		}
  309|    137|		if (c->sock >= 0) {
  ------------------
  |  Branch (309:7): [True: 0, False: 137]
  ------------------
  310|      0|			FD_SET(c->sock, writefd);
  311|    137|		} else {
  312|       |			/* Final failure */
  313|    137|			if (!c->errstring) {
  ------------------
  |  Branch (313:8): [True: 0, False: 137]
  ------------------
  314|      0|				c->errstring = m_strdup("unexpected failure");
  315|      0|			}
  316|    137|			c->cb(DROPBEAR_FAILURE, -1, c->cb_data, c->errstring);
  ------------------
  |  |  112|    137|#define DROPBEAR_FAILURE -1
  ------------------
  317|    137|			remove_connect(c, iter);
  318|    137|		}
  319|    137|		iter = next_iter;
  320|    137|	}
  321|   302k|}
handle_connect_fds:
  323|   298k|void handle_connect_fds(const fd_set *writefd) {
  324|   298k|	m_list_elem *iter;
  325|   298k|	for (iter = ses.conn_pending.first; iter; iter = iter->next) {
  ------------------
  |  Branch (325:38): [True: 137, False: 298k]
  ------------------
  326|    137|		int val;
  327|    137|		socklen_t vallen = sizeof(val);
  328|    137|		struct dropbear_progress_connection *c = iter->item;
  329|       |
  330|    137|		if (c->sock < 0 || !FD_ISSET(c->sock, writefd)) {
  ------------------
  |  Branch (330:7): [True: 137, False: 0]
  |  Branch (330:22): [True: 0, False: 0]
  ------------------
  331|    137|			continue;
  332|    137|		}
  333|       |
  334|      0|		TRACE(("handling %s port %s socket %d", c->remotehost, c->remoteport, c->sock));
  335|       |
  336|      0|		if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &val, &vallen) != 0) {
  ------------------
  |  Branch (336:7): [True: 0, False: 0]
  ------------------
  337|      0|			TRACE(("handle_connect_fds getsockopt(%d) SO_ERROR failed: %s", c->sock, strerror(errno)))
  338|       |			/* This isn't expected to happen - Unix has surprises though, continue gracefully. */
  339|      0|			m_close(c->sock);
  340|      0|			c->sock = -1;
  341|      0|		} else if (val != 0) {
  ------------------
  |  Branch (341:14): [True: 0, False: 0]
  ------------------
  342|       |			/* Connect failed */
  343|      0|			TRACE(("connect to %s port %s failed.", c->remotehost, c->remoteport))
  344|      0|			m_close(c->sock);
  345|      0|			c->sock = -1;
  346|       |
  347|      0|			m_free(c->errstring);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  348|      0|			c->errstring = m_strdup(strerror(val));
  349|      0|		} else {
  350|       |			/* New connection has been established */
  351|      0|			c->cb(DROPBEAR_SUCCESS, c->sock, c->cb_data, NULL);
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  352|      0|			remove_connect(c, iter);
  353|      0|			TRACE(("leave handle_connect_fds - success"))
  354|       |			/* Must return here - remove_connect() invalidates iter */
  355|      0|			return; 
  356|      0|		}
  357|      0|	}
  358|   298k|}
packet_queue_to_iovec:
  364|  91.7k|void packet_queue_to_iovec(const struct Queue *queue, struct iovec *iov, unsigned int *iov_count) {
  365|  91.7k|	struct Link *l;
  366|  91.7k|	unsigned int i;
  367|  91.7k|	int len;
  368|  91.7k|	buffer *writebuf;
  369|       |
  370|       |#ifndef IOV_MAX
  371|       |	#if (defined(__CYGWIN__) || defined(__GNU__)) && !defined(UIO_MAXIOV)
  372|       |		#define IOV_MAX 1024
  373|       |	#elif defined(__sgi)
  374|       |		#define IOV_MAX 512 
  375|       |	#else 
  376|       |		#define IOV_MAX UIO_MAXIOV
  377|       |	#endif
  378|       |#endif
  379|       |
  380|  91.7k|	*iov_count = MIN(MIN(queue->count, IOV_MAX), *iov_count);
  ------------------
  |  Branch (380:15): [True: 91.7k, False: 0]
  |  Branch (380:15): [True: 89.2k, False: 0]
  |  Branch (380:15): [True: 89.2k, False: 2.50k]
  ------------------
  381|       |
  382|   530k|	for (l = queue->head, i = 0; i < *iov_count; l = l->link, i++)
  ------------------
  |  Branch (382:31): [True: 438k, False: 91.7k]
  ------------------
  383|   438k|	{
  384|   438k|		writebuf = (buffer*)l->item;
  385|   438k|		len = writebuf->len - writebuf->pos;
  386|   438k|		dropbear_assert(len > 0);
  ------------------
  |  |   84|   438k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 438k]
  |  |  |  Branch (84:93): [Folded, False: 438k]
  |  |  ------------------
  ------------------
  387|   438k|		TRACE2(("write_packet writev #%d len %d/%d", i,
  388|   438k|				len, writebuf->len))
  389|   438k|		iov[i].iov_base = buf_getptr(writebuf, len);
  390|   438k|		iov[i].iov_len = len;
  391|   438k|	}
  392|  91.7k|}
packet_queue_consume:
  394|  91.7k|void packet_queue_consume(struct Queue *queue, ssize_t written) {
  395|  91.7k|	buffer *writebuf;
  396|  91.7k|	int len;
  397|   183k|	while (written > 0) {
  ------------------
  |  Branch (397:9): [True: 91.7k, False: 91.7k]
  ------------------
  398|  91.7k|		writebuf = (buffer*)examine(queue);
  399|  91.7k|		len = writebuf->len - writebuf->pos;
  400|  91.7k|		if (len > written) {
  ------------------
  |  Branch (400:7): [True: 0, False: 91.7k]
  ------------------
  401|       |			/* partial buffer write */
  402|      0|			buf_incrpos(writebuf, written);
  403|      0|			written = 0;
  404|  91.7k|		} else {
  405|  91.7k|			written -= len;
  406|  91.7k|			dequeue(queue);
  407|  91.7k|			buf_free(writebuf);
  408|  91.7k|		}
  409|  91.7k|	}
  410|  91.7k|}
set_sock_priority:
  430|  5.69k|void set_sock_priority(int sock, enum dropbear_prio prio) {
  431|       |
  432|  5.69k|	int rc;
  433|  5.69k|	int val;
  434|       |
  435|  5.69k|#if DROPBEAR_FUZZ
  436|  5.69k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (436:6): [True: 5.69k, False: 0]
  ------------------
  437|  5.69k|		TRACE(("fuzzing skips set_sock_prio"))
  438|  5.69k|		return;
  439|  5.69k|	}
  440|      0|#endif
  441|       |	/* Don't log ENOTSOCK errors so that this can harmlessly be called
  442|       |	 * on a client '-J' proxy pipe */
  443|       |
  444|      0|	if (opts.disable_ip_tos == 0) {
  ------------------
  |  Branch (444:6): [True: 0, False: 0]
  ------------------
  445|      0|#ifdef IP_TOS
  446|       |	/* Set the DSCP field for outbound IP packet priority.
  447|       |	rfc4594 has some guidance to meanings.
  448|       |
  449|       |	We set AF21 as "Low-Latency" class for interactive (tty session,
  450|       |	also handshake/setup packets). Other traffic is left at the default.
  451|       |
  452|       |	OpenSSH at present uses AF21/CS1, rationale
  453|       |	https://cvsweb.openbsd.org/src/usr.bin/ssh/readconf.c#rev1.284
  454|       |
  455|       |	Old Dropbear/OpenSSH and Debian/Ubuntu OpenSSH (at Jan 2022) use
  456|       |	IPTOS_LOWDELAY/IPTOS_THROUGHPUT
  457|       |
  458|       |	DSCP constants are from Linux headers, applicable to other platforms
  459|       |	such as macos.
  460|       |	*/
  461|      0|	if (prio == DROPBEAR_PRIO_LOWDELAY) {
  ------------------
  |  Branch (461:6): [True: 0, False: 0]
  ------------------
  462|      0|		val = 0x48; /* IPTOS_DSCP_AF21 */
  463|      0|	} else {
  464|      0|		val = 0; /* default */
  465|      0|	}
  466|      0|#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS)
  467|      0|	rc = setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, (void*)&val, sizeof(val));
  468|      0|	if (rc < 0 && errno != ENOTSOCK) {
  ------------------
  |  Branch (468:6): [True: 0, False: 0]
  |  Branch (468:16): [True: 0, False: 0]
  ------------------
  469|      0|		TRACE(("Couldn't set IPV6_TCLASS (%s)", strerror(errno)));
  470|      0|	}
  471|      0|#endif
  472|      0|	rc = setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&val, sizeof(val));
  473|      0|	if (rc < 0 && errno != ENOTSOCK) {
  ------------------
  |  Branch (473:6): [True: 0, False: 0]
  |  Branch (473:16): [True: 0, False: 0]
  ------------------
  474|      0|		TRACE(("Couldn't set IP_TOS (%s)", strerror(errno)));
  475|      0|	}
  476|      0|#endif /* IP_TOS */
  477|      0|	}
  478|       |
  479|      0|#ifdef HAVE_LINUX_PKT_SCHED_H
  480|       |	/* Set scheduling priority within the local Linux network stack */
  481|      0|	if (prio == DROPBEAR_PRIO_LOWDELAY) {
  ------------------
  |  Branch (481:6): [True: 0, False: 0]
  ------------------
  482|      0|		val = TC_PRIO_INTERACTIVE;
  483|      0|	} else {
  484|      0|		val = 0;
  485|      0|	}
  486|       |	/* linux specific, sets QoS class. see tc-prio(8) */
  487|      0|	rc = setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &val, sizeof(val));
  488|      0|	if (rc < 0 && errno != ENOTSOCK) {
  ------------------
  |  Branch (488:6): [True: 0, False: 0]
  |  Branch (488:16): [True: 0, False: 0]
  ------------------
  489|      0|		TRACE(("Couldn't set SO_PRIORITY (%s)", strerror(errno)))
  490|      0|    }
  491|      0|#endif
  492|       |
  493|      0|}
dropbear_listen:
  533|    209|		int *socks, unsigned int sockcount, char **errstring, int *maxfd, const char* interface) {
  534|       |
  535|    209|	struct addrinfo hints, *res = NULL, *res0 = NULL;
  536|    209|	int err;
  537|    209|	unsigned int nsock;
  538|    209|	int val;
  539|    209|	int sock;
  540|    209|	uint16_t *allocated_lport_p = NULL;
  541|    209|	int allocated_lport = 0;
  542|       |	
  543|    209|	TRACE(("enter dropbear_listen"))
  544|       |
  545|    209|#if DROPBEAR_FUZZ
  546|    209|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (546:6): [True: 209, False: 0]
  ------------------
  547|    209|		return fuzz_dropbear_listen(address, port, socks, sockcount, errstring, maxfd);
  548|    209|	}
  549|      0|#endif
  550|       |	
  551|      0|	memset(&hints, 0, sizeof(hints));
  552|      0|	hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */
  553|      0|	hints.ai_socktype = SOCK_STREAM;
  554|       |
  555|       |	/* for calling getaddrinfo:
  556|       |	 address == NULL and !AI_PASSIVE: local loopback
  557|       |	 address == NULL and AI_PASSIVE: all interfaces
  558|       |	 address != NULL: whatever the address says */
  559|      0|	if (!address) {
  ------------------
  |  Branch (559:6): [True: 0, False: 0]
  ------------------
  560|      0|		TRACE(("dropbear_listen: local loopback"))
  561|      0|	} else {
  562|      0|		if (address[0] == '\0') {
  ------------------
  |  Branch (562:7): [True: 0, False: 0]
  ------------------
  563|      0|			if (interface) {
  ------------------
  |  Branch (563:8): [True: 0, False: 0]
  ------------------
  564|      0|				TRACE(("dropbear_listen: %s", interface))
  565|      0|			} else {
  566|      0|				TRACE(("dropbear_listen: all interfaces"))
  567|      0|			}
  568|      0|			address = NULL;
  569|      0|		}
  570|      0|		hints.ai_flags = AI_PASSIVE;
  571|      0|	}
  572|      0|	err = getaddrinfo(address, port, &hints, &res0);
  573|       |
  574|      0|	if (err) {
  ------------------
  |  Branch (574:6): [True: 0, False: 0]
  ------------------
  575|      0|		if (errstring != NULL && *errstring == NULL) {
  ------------------
  |  Branch (575:7): [True: 0, False: 0]
  |  Branch (575:28): [True: 0, False: 0]
  ------------------
  576|      0|			int len;
  577|      0|			len = 20 + strlen(gai_strerror(err));
  578|      0|			*errstring = (char*)m_malloc(len);
  579|      0|			snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err));
  580|      0|		}
  581|      0|		if (res0) {
  ------------------
  |  Branch (581:7): [True: 0, False: 0]
  ------------------
  582|      0|			freeaddrinfo(res0);
  583|      0|			res0 = NULL;
  584|      0|		}
  585|      0|		TRACE(("leave dropbear_listen: failed resolving"))
  586|      0|		return -1;
  587|      0|	}
  588|       |
  589|       |	/* When listening on server-assigned-port 0
  590|       |	 * the assigned ports may differ for address families (v4/v6)
  591|       |	 * causing problems for tcpip-forward.
  592|       |	 * Caller can do a get_socket_address to discover assigned-port
  593|       |	 * hence, use same port for all address families */
  594|      0|	allocated_lport = 0;
  595|      0|	nsock = 0;
  596|      0|	for (res = res0; res != NULL && nsock < sockcount;
  ------------------
  |  Branch (596:19): [True: 0, False: 0]
  |  Branch (596:34): [True: 0, False: 0]
  ------------------
  597|      0|			res = res->ai_next) {
  598|      0|		if (allocated_lport > 0) {
  ------------------
  |  Branch (598:7): [True: 0, False: 0]
  ------------------
  599|      0|			if (AF_INET == res->ai_family) {
  ------------------
  |  Branch (599:8): [True: 0, False: 0]
  ------------------
  600|      0|				allocated_lport_p = &((struct sockaddr_in *)res->ai_addr)->sin_port;
  601|      0|			} else if (AF_INET6 == res->ai_family) {
  ------------------
  |  Branch (601:15): [True: 0, False: 0]
  ------------------
  602|      0|				allocated_lport_p = &((struct sockaddr_in6 *)res->ai_addr)->sin6_port;
  603|      0|			}
  604|      0|			*allocated_lport_p = htons(allocated_lport);
  605|      0|		}
  606|       |
  607|       |		/* Get a socket */
  608|      0|		socks[nsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  609|      0|		sock = socks[nsock]; /* For clarity */
  610|      0|		if (sock < 0) {
  ------------------
  |  Branch (610:7): [True: 0, False: 0]
  ------------------
  611|      0|			err = errno;
  612|      0|			TRACE(("socket() failed"))
  613|      0|			continue;
  614|      0|		}
  615|       |
  616|       |		/* Various useful socket options */
  617|      0|		val = 1;
  618|       |		/* set to reuse, quick timeout */
  619|      0|		setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));
  620|       |
  621|      0|#ifdef SO_BINDTODEVICE
  622|      0|		if(interface && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0) {
  ------------------
  |  Branch (622:6): [True: 0, False: 0]
  |  Branch (622:19): [True: 0, False: 0]
  ------------------
  623|      0|			dropbear_log(LOG_WARNING, "Couldn't set SO_BINDTODEVICE");
  624|      0|			TRACE(("Failed setsockopt with errno failure, %d %s", errno, strerror(errno)))
  625|      0|		}
  626|      0|#endif
  627|       |
  628|      0|#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
  629|      0|		if (res->ai_family == AF_INET6) {
  ------------------
  |  Branch (629:7): [True: 0, False: 0]
  ------------------
  630|      0|			int on = 1;
  631|      0|			if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, 
  ------------------
  |  Branch (631:8): [True: 0, False: 0]
  ------------------
  632|      0|						&on, sizeof(on)) == -1) {
  633|      0|				dropbear_log(LOG_WARNING, "Couldn't set IPV6_V6ONLY");
  634|      0|			}
  635|      0|		}
  636|      0|#endif
  637|      0|		set_sock_nodelay(sock);
  638|       |
  639|      0|		if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
  ------------------
  |  Branch (639:7): [True: 0, False: 0]
  ------------------
  640|      0|			err = errno;
  641|      0|			close(sock);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  642|      0|			TRACE(("bind(%s) failed", port))
  643|      0|			continue;
  644|      0|		}
  645|       |
  646|      0|		if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0) {
  ------------------
  |  |  411|      0|#define DROPBEAR_LISTEN_BACKLOG MAX_CHANNELS
  |  |  ------------------
  |  |  |  |  250|      0|#define MAX_CHANNELS 1000 /* simple mem restriction, includes each tcp/x11
  |  |  ------------------
  ------------------
  |  Branch (646:7): [True: 0, False: 0]
  ------------------
  647|      0|			err = errno;
  648|      0|			close(sock);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  649|      0|			TRACE(("listen() failed"))
  650|      0|			continue;
  651|      0|		}
  652|       |
  653|      0|		if (0 == allocated_lport) {
  ------------------
  |  Branch (653:7): [True: 0, False: 0]
  ------------------
  654|      0|			allocated_lport = get_sock_port(sock);
  655|      0|		}
  656|       |
  657|      0|		*maxfd = MAX(*maxfd, sock);
  ------------------
  |  Branch (657:12): [True: 0, False: 0]
  ------------------
  658|      0|		nsock++;
  659|      0|	}
  660|       |
  661|      0|	if (res0) {
  ------------------
  |  Branch (661:6): [True: 0, False: 0]
  ------------------
  662|      0|		freeaddrinfo(res0);
  663|      0|		res0 = NULL;
  664|      0|	}
  665|       |
  666|      0|	if (nsock == 0) {
  ------------------
  |  Branch (666:6): [True: 0, False: 0]
  ------------------
  667|      0|		if (errstring != NULL && *errstring == NULL) {
  ------------------
  |  Branch (667:7): [True: 0, False: 0]
  |  Branch (667:28): [True: 0, False: 0]
  ------------------
  668|      0|			int len;
  669|      0|			len = 20 + strlen(strerror(err));
  670|      0|			*errstring = (char*)m_malloc(len);
  671|      0|			snprintf(*errstring, len, "Error listening: %s", strerror(err));
  672|      0|		}
  673|      0|		TRACE(("leave dropbear_listen: failure, %s", strerror(err)))
  674|      0|		return -1;
  675|      0|	}
  676|       |
  677|      0|	TRACE(("leave dropbear_listen: success, %d socks bound", nsock))
  678|      0|	return nsock;
  679|      0|}
get_socket_address:
  683|  10.2k|{
  684|  10.2k|	struct sockaddr_storage addr;
  685|  10.2k|	socklen_t addrlen;
  686|       |
  687|  10.2k|#if DROPBEAR_FUZZ
  688|  10.2k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (688:6): [True: 10.2k, False: 0]
  ------------------
  689|  10.2k|		fuzz_get_socket_address(fd, local_host, local_port, remote_host, remote_port, host_lookup);
  690|  10.2k|		return;
  691|  10.2k|	}
  692|      0|#endif
  693|       |	
  694|      0|	if (local_host || local_port) {
  ------------------
  |  Branch (694:6): [True: 0, False: 0]
  |  Branch (694:20): [True: 0, False: 0]
  ------------------
  695|      0|		addrlen = sizeof(addr);
  696|      0|		if (getsockname(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
  ------------------
  |  Branch (696:7): [True: 0, False: 0]
  ------------------
  697|      0|			dropbear_exit("Failed socket address: %s", strerror(errno));
  698|      0|		}
  699|      0|		getaddrstring(&addr, local_host, local_port, host_lookup);		
  700|      0|	}
  701|      0|	if (remote_host || remote_port) {
  ------------------
  |  Branch (701:6): [True: 0, False: 0]
  |  Branch (701:21): [True: 0, False: 0]
  ------------------
  702|      0|		addrlen = sizeof(addr);
  703|      0|		if (getpeername(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
  ------------------
  |  Branch (703:7): [True: 0, False: 0]
  ------------------
  704|      0|			dropbear_exit("Failed socket address: %s", strerror(errno));
  705|      0|		}
  706|      0|		getaddrstring(&addr, remote_host, remote_port, host_lookup);		
  707|      0|	}
  708|      0|}
netio.c:remove_connect:
   29|    137|static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *iter) {
   30|    137|	if (c->res) {
  ------------------
  |  Branch (30:6): [True: 0, False: 137]
  ------------------
   31|       |		/* Only call freeaddrinfo if connection is not AF_UNIX. */
   32|      0|		if (c->res->ai_family != AF_UNIX) {
  ------------------
  |  Branch (32:7): [True: 0, False: 0]
  ------------------
   33|      0|			freeaddrinfo(c->res);
   34|      0|		} else {
   35|      0|			m_free(c->res);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
   36|      0|		}
   37|      0|	}
   38|    137|	m_free(c->remotehost);
  ------------------
  |  |   24|    137|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 137]
  |  |  ------------------
  ------------------
   39|    137|	m_free(c->remoteport);
  ------------------
  |  |   24|    137|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 137]
  |  |  ------------------
  ------------------
   40|    137|	m_free(c->errstring);
  ------------------
  |  |   24|    137|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 137]
  |  |  ------------------
  ------------------
   41|    137|	m_free(c->bind_address);
  ------------------
  |  |   24|    137|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 137]
  |  |  ------------------
  ------------------
   42|    137|	m_free(c->bind_port);
  ------------------
  |  |   24|    137|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 137]
  |  |  ------------------
  ------------------
   43|    137|	m_free(c);
  ------------------
  |  |   24|    137|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 137]
  |  |  ------------------
  ------------------
   44|       |
   45|    137|	if (iter) {
  ------------------
  |  Branch (45:6): [True: 137, False: 0]
  ------------------
   46|    137|		list_remove(iter);
   47|    137|	}
   48|    137|}

write_packet:
   58|  91.7k|void write_packet() {
   59|       |
   60|  91.7k|	ssize_t written;
   61|  91.7k|#if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV))
   62|       |	/* 50 is somewhat arbitrary */
   63|  91.7k|	unsigned int iov_count = 50;
   64|  91.7k|	struct iovec iov[50];
   65|       |#else
   66|       |	int len;
   67|       |	buffer* writebuf;
   68|       |#endif
   69|       |	
   70|  91.7k|	TRACE2(("enter write_packet"))
   71|  91.7k|	dropbear_assert(!isempty(&ses.writequeue));
  ------------------
  |  |   84|  91.7k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 91.7k]
  |  |  |  Branch (84:93): [Folded, False: 91.7k]
  |  |  ------------------
  ------------------
   72|       |
   73|  91.7k|#if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV))
   74|       |
   75|  91.7k|	packet_queue_to_iovec(&ses.writequeue, iov, &iov_count);
   76|       |	/* This may return EAGAIN. The main loop sometimes
   77|       |	calls write_packet() without bothering to test with select() since
   78|       |	it's likely to be necessary */
   79|  91.7k|#if DROPBEAR_FUZZ
   80|  91.7k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (80:6): [True: 91.7k, False: 0]
  ------------------
   81|       |		/* pretend to write one packet at a time */
   82|       |		/* TODO(fuzz): randomise amount written based on the fuzz input */
   83|  91.7k|		written = iov[0].iov_len;
   84|  91.7k|	}
   85|      0|	else
   86|      0|#endif
   87|      0|	{
   88|      0|	written = writev(ses.sock_out, iov, iov_count);
   89|      0|	if (written < 0) {
  ------------------
  |  Branch (89:6): [True: 0, False: 0]
  ------------------
   90|      0|		if (errno == EINTR || errno == EAGAIN) {
  ------------------
  |  Branch (90:7): [True: 0, False: 0]
  |  Branch (90:25): [True: 0, False: 0]
  ------------------
   91|      0|			TRACE2(("leave write_packet: EINTR"))
   92|      0|			return;
   93|      0|		} else {
   94|      0|			dropbear_exit("Error writing: %s", strerror(errno));
   95|      0|		}
   96|      0|	}
   97|      0|	}
   98|       |
   99|  91.7k|	packet_queue_consume(&ses.writequeue, written);
  100|  91.7k|	ses.writequeue_len -= written;
  101|       |
  102|  91.7k|	if (written == 0) {
  ------------------
  |  Branch (102:6): [True: 0, False: 91.7k]
  ------------------
  103|      0|		ses.remoteclosed();
  104|      0|	}
  105|       |
  106|       |#else /* No writev () */
  107|       |#if DROPBEAR_FUZZ
  108|       |	_Static_assert(0, "No fuzzing code for no-writev writes");
  109|       |#endif
  110|       |	/* Get the next buffer in the queue of encrypted packets to write*/
  111|       |	writebuf = (buffer*)examine(&ses.writequeue);
  112|       |
  113|       |	len = writebuf->len - writebuf->pos;
  114|       |	dropbear_assert(len > 0);
  115|       |	/* Try to write as much as possible */
  116|       |	written = write(ses.sock_out, buf_getptr(writebuf, len), len);
  117|       |
  118|       |	if (written < 0) {
  119|       |		if (errno == EINTR || errno == EAGAIN) {
  120|       |			TRACE2(("leave writepacket: EINTR"))
  121|       |			return;
  122|       |		} else {
  123|       |			dropbear_exit("Error writing: %s", strerror(errno));
  124|       |		}
  125|       |	} 
  126|       |
  127|       |	if (written == 0) {
  128|       |		ses.remoteclosed();
  129|       |	}
  130|       |
  131|       |	ses.writequeue_len -= written;
  132|       |
  133|       |	if (written == len) {
  134|       |		/* We've finished with the packet, free it */
  135|       |		dequeue(&ses.writequeue);
  136|       |		buf_free(writebuf);
  137|       |		writebuf = NULL;
  138|       |	} else {
  139|       |		/* More packet left to write, leave it in the queue for later */
  140|       |		buf_incrpos(writebuf, written);
  141|       |	}
  142|       |#endif /* writev */
  143|       |
  144|  91.7k|	TRACE2(("leave write_packet"))
  145|  91.7k|}
read_packet:
  150|   226k|void read_packet() {
  151|       |
  152|   226k|	int len;
  153|   226k|	unsigned int maxlen;
  154|   226k|	unsigned char blocksize;
  155|       |
  156|   226k|	TRACE2(("enter read_packet"))
  157|   226k|	blocksize = ses.keys->recv.algo_crypt->blocksize;
  158|       |	
  159|   226k|	if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
  ------------------
  |  Branch (159:6): [True: 43.9k, False: 182k]
  |  Branch (159:29): [True: 82.7k, False: 99.7k]
  ------------------
  160|   126k|		int ret;
  161|       |		/* In the first blocksize of a packet */
  162|       |
  163|       |		/* Read the first blocksize of the packet, so we can decrypt it and
  164|       |		 * find the length of the whole packet */
  165|   126k|		ret = read_packet_init();
  166|       |
  167|   126k|		if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|   126k|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (167:7): [True: 82.7k, False: 43.9k]
  ------------------
  168|       |			/* didn't read enough to determine the length */
  169|  82.7k|			TRACE2(("leave read_packet: packetinit done"))
  170|  82.7k|			return;
  171|  82.7k|		}
  172|   126k|	}
  173|       |
  174|       |	/* Attempt to read the remainder of the packet, note that there
  175|       |	 * mightn't be any available (EAGAIN) */
  176|   143k|	maxlen = ses.readbuf->len - ses.readbuf->pos;
  177|   143k|	if (maxlen == 0) {
  ------------------
  |  Branch (177:6): [True: 10.1k, False: 133k]
  ------------------
  178|       |		/* Occurs when the packet is only a single block long and has all
  179|       |		 * been read in read_packet_init().  Usually means that MAC is disabled
  180|       |		 */
  181|  10.1k|		len = 0;
  182|   133k|	} else {
  183|   133k|		len = read(ses.sock_in, buf_getptr(ses.readbuf, maxlen), maxlen);
  ------------------
  |  |   55|   133k|#define read(fd, buf, count) wrapfd_read(fd, buf, count)
  ------------------
  184|       |
  185|   133k|		if (len == 0) {
  ------------------
  |  Branch (185:7): [True: 156, False: 133k]
  ------------------
  186|    156|			ses.remoteclosed();
  187|    156|		}
  188|       |
  189|   133k|		if (len < 0) {
  ------------------
  |  Branch (189:7): [True: 74, False: 133k]
  ------------------
  190|     74|			if (errno == EINTR || errno == EAGAIN) {
  ------------------
  |  Branch (190:8): [True: 71, False: 3]
  |  Branch (190:26): [True: 0, False: 3]
  ------------------
  191|     71|				TRACE2(("leave read_packet: EINTR or EAGAIN"))
  192|     71|				return;
  193|     71|			} else {
  194|      3|				dropbear_exit("Error reading: %s", strerror(errno));
  195|      3|			}
  196|     74|		}
  197|       |
  198|   133k|		buf_incrpos(ses.readbuf, len);
  199|   133k|	}
  200|       |
  201|   143k|	if ((unsigned int)len == maxlen) {
  ------------------
  |  Branch (201:6): [True: 41.0k, False: 102k]
  ------------------
  202|       |		/* The whole packet has been read */
  203|  41.0k|		decrypt_packet();
  204|       |		/* The main select() loop process_packet() to
  205|       |		 * handle the packet contents... */
  206|  41.0k|	}
  207|   143k|	TRACE2(("leave read_packet"))
  208|   143k|}
decrypt_packet:
  298|  41.0k|void decrypt_packet() {
  299|       |
  300|  41.0k|	unsigned char blocksize;
  301|  41.0k|	unsigned char macsize;
  302|  41.0k|	unsigned int padlen;
  303|  41.0k|	unsigned int len;
  304|       |
  305|  41.0k|	TRACE2(("enter decrypt_packet"))
  306|  41.0k|	blocksize = ses.keys->recv.algo_crypt->blocksize;
  307|  41.0k|	macsize = ses.keys->recv.algo_mac->hashsize;
  308|       |
  309|  41.0k|	ses.kexstate.datarecv += ses.readbuf->len;
  310|       |
  311|  41.0k|#if DROPBEAR_AEAD_MODE
  312|  41.0k|	if (ses.keys->recv.crypt_mode->aead_crypt) {
  ------------------
  |  Branch (312:6): [True: 0, False: 41.0k]
  ------------------
  313|       |		/* first blocksize is not decrypted yet */
  314|      0|		buf_setpos(ses.readbuf, 0);
  315|       |
  316|       |		/* decrypt it in-place */
  317|      0|		len = ses.readbuf->len - macsize - ses.readbuf->pos;
  318|      0|		if (ses.keys->recv.crypt_mode->aead_crypt(ses.recvseq,
  ------------------
  |  Branch (318:7): [True: 0, False: 0]
  ------------------
  319|      0|					buf_getptr(ses.readbuf, len + macsize),
  320|      0|					buf_getwriteptr(ses.readbuf, len),
  321|      0|					len, macsize,
  322|      0|					&ses.keys->recv.cipher_state, LTC_DECRYPT) != CRYPT_OK) {
  ------------------
  |  |   70|      0|#define LTC_DECRYPT 1
  ------------------
  323|      0|			dropbear_exit("Error decrypting");
  324|      0|		}
  325|      0|		buf_incrpos(ses.readbuf, len);
  326|      0|	} else
  327|  41.0k|#endif
  328|  41.0k|	{
  329|       |		/* we've already decrypted the first blocksize in read_packet_init */
  330|  41.0k|		buf_setpos(ses.readbuf, blocksize);
  331|       |
  332|       |		/* decrypt it in-place */
  333|  41.0k|		len = ses.readbuf->len - macsize - ses.readbuf->pos;
  334|  41.0k|		if (ses.keys->recv.crypt_mode->decrypt(
  ------------------
  |  Branch (334:7): [True: 0, False: 41.0k]
  ------------------
  335|  41.0k|					buf_getptr(ses.readbuf, len), 
  336|  41.0k|					buf_getwriteptr(ses.readbuf, len),
  337|  41.0k|					len,
  338|  41.0k|					&ses.keys->recv.cipher_state) != CRYPT_OK) {
  339|      0|			dropbear_exit("Error decrypting");
  340|      0|		}
  341|  41.0k|		buf_incrpos(ses.readbuf, len);
  342|       |
  343|       |		/* check the hmac */
  344|  41.0k|		if (checkmac() != DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|  41.0k|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (344:7): [True: 0, False: 41.0k]
  ------------------
  345|      0|			dropbear_exit("Integrity error");
  346|      0|		}
  347|       |
  348|  41.0k|	}
  349|       |	
  350|  41.0k|#if DROPBEAR_FUZZ
  351|  41.0k|	fuzz_dump(ses.readbuf->data, ses.readbuf->len);
  352|  41.0k|#endif
  353|       |
  354|       |	/* get padding length */
  355|  41.0k|	buf_setpos(ses.readbuf, PACKET_PADDING_OFF);
  ------------------
  |  |   48|  41.0k|#define PACKET_PADDING_OFF 4
  ------------------
  356|  41.0k|	padlen = buf_getbyte(ses.readbuf);
  357|       |		
  358|       |	/* payload length */
  359|       |	/* - 4 - 1 is for LEN and PADLEN values */
  360|  41.0k|	len = ses.readbuf->len - padlen - 4 - 1 - macsize;
  361|  41.0k|	if ((len > RECV_MAX_PAYLOAD_LEN+ZLIB_COMPRESS_EXPANSION) || (len < 1)) {
  ------------------
  |  |  555|  41.0k|#define RECV_MAX_PAYLOAD_LEN 32768
  ------------------
              	if ((len > RECV_MAX_PAYLOAD_LEN+ZLIB_COMPRESS_EXPANSION) || (len < 1)) {
  ------------------
  |  |   50|  41.0k|#define ZLIB_COMPRESS_EXPANSION (((RECV_MAX_PAYLOAD_LEN/16384)+1)*5 + 6)
  |  |  ------------------
  |  |  |  |  555|  41.0k|#define RECV_MAX_PAYLOAD_LEN 32768
  |  |  ------------------
  ------------------
  |  Branch (361:6): [True: 16, False: 41.0k]
  |  Branch (361:62): [True: 1, False: 41.0k]
  ------------------
  362|     17|		dropbear_exit("Bad packet size %u", len);
  363|     17|	}
  364|       |
  365|  41.0k|	buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF);
  ------------------
  |  |   49|  41.0k|#define PACKET_PAYLOAD_OFF 5
  ------------------
  366|       |
  367|       |#ifndef DISABLE_ZLIB
  368|       |	if (is_compress_recv()) {
  369|       |		/* decompress */
  370|       |		ses.payload = buf_decompress(ses.readbuf, len);
  371|       |		buf_setpos(ses.payload, 0);
  372|       |		ses.payload_beginning = 0;
  373|       |		buf_free(ses.readbuf);
  374|       |	} else 
  375|       |#endif
  376|  41.0k|	{
  377|  41.0k|		ses.payload = ses.readbuf;
  378|  41.0k|		ses.payload_beginning = ses.payload->pos;
  379|  41.0k|		buf_setlen(ses.payload, ses.payload->pos + len);
  380|  41.0k|	}
  381|  41.0k|	ses.readbuf = NULL;
  382|       |
  383|  41.0k|	ses.recvseq++;
  384|       |
  385|  41.0k|	TRACE2(("leave decrypt_packet"))
  386|  41.0k|}
maybe_flush_reply_queue:
  495|   298k|void maybe_flush_reply_queue() {
  496|   298k|	struct packetlist *tmp_item = NULL, *curr_item = NULL;
  497|   298k|	if (!ses.dataallowed)
  ------------------
  |  Branch (497:6): [True: 97.5k, False: 200k]
  ------------------
  498|  97.5k|	{
  499|  97.5k|		TRACE(("maybe_empty_reply_queue - no data allowed"))
  500|  97.5k|		return;
  501|  97.5k|	}
  502|       |		
  503|   200k|	for (curr_item = ses.reply_queue_head; curr_item; ) {
  ------------------
  |  Branch (503:41): [True: 56, False: 200k]
  ------------------
  504|     56|		CHECKCLEARTOWRITE();
  505|     56|		buf_putbytes(ses.writepayload,
  506|     56|			curr_item->payload->data, curr_item->payload->len);
  507|       |			
  508|     56|		buf_free(curr_item->payload);
  509|     56|		tmp_item = curr_item;
  510|     56|		curr_item = curr_item->next;
  511|     56|		m_free(tmp_item);
  ------------------
  |  |   24|     56|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 56]
  |  |  ------------------
  ------------------
  512|     56|		encrypt_packet();
  513|     56|	}
  514|       |	ses.reply_queue_head = ses.reply_queue_tail = NULL;
  515|   200k|}
encrypt_packet:
  519|  89.8k|void encrypt_packet() {
  520|       |
  521|  89.8k|	unsigned char padlen;
  522|  89.8k|	unsigned char blocksize, mac_size;
  523|  89.8k|	buffer * writebuf; /* the packet which will go on the wire. This is 
  524|       |	                      encrypted in-place. */
  525|  89.8k|	unsigned char packet_type;
  526|  89.8k|	unsigned int len, encrypt_buf_size;
  527|  89.8k|	unsigned char mac_bytes[MAX_MAC_LEN];
  528|       |
  529|  89.8k|	time_t now;
  530|       |	
  531|  89.8k|	TRACE2(("enter encrypt_packet()"))
  532|       |
  533|  89.8k|	buf_setpos(ses.writepayload, 0);
  534|  89.8k|	packet_type = buf_getbyte(ses.writepayload);
  535|  89.8k|	buf_setpos(ses.writepayload, 0);
  536|       |
  537|  89.8k|	TRACE2(("encrypt_packet type is %d", packet_type))
  538|       |	
  539|  89.8k|	if ((!ses.dataallowed && !packet_is_okay_kex(packet_type))) {
  ------------------
  |  Branch (539:7): [True: 11.2k, False: 78.6k]
  |  Branch (539:27): [True: 79, False: 11.1k]
  ------------------
  540|       |		/* During key exchange only particular packets are allowed.
  541|       |			Since this packet_type isn't OK we just enqueue it to send 
  542|       |			after the KEX, see maybe_flush_reply_queue */
  543|     79|		enqueue_reply_packet();
  544|     79|		return;
  545|     79|	}
  546|       |		
  547|  89.8k|	blocksize = ses.keys->trans.algo_crypt->blocksize;
  548|  89.8k|	mac_size = ses.keys->trans.algo_mac->hashsize;
  549|       |
  550|       |	/* Encrypted packet len is payload+5. We need to then make sure
  551|       |	 * there is enough space for padding or MIN_PACKET_LEN. 
  552|       |	 * Add extra 3 since we need at least 4 bytes of padding */
  553|  89.8k|	encrypt_buf_size = (ses.writepayload->len+4+1) 
  554|  89.8k|		+ MAX(MIN_PACKET_LEN, blocksize) + 3
  ------------------
  |  Branch (554:5): [True: 40.4k, False: 49.3k]
  ------------------
  555|       |	/* add space for the MAC at the end */
  556|  89.8k|				+ mac_size
  557|       |#ifndef DISABLE_ZLIB
  558|       |	/* some extra in case 'compression' makes it larger */
  559|       |				+ ZLIB_COMPRESS_EXPANSION
  560|       |#endif
  561|       |	/* and an extra cleartext (stripped before transmission) byte for the
  562|       |	 * packet type */
  563|  89.8k|				+ 1;
  564|       |
  565|  89.8k|	writebuf = buf_new(encrypt_buf_size);
  566|  89.8k|	buf_setlen(writebuf, PACKET_PAYLOAD_OFF);
  ------------------
  |  |   49|  89.8k|#define PACKET_PAYLOAD_OFF 5
  ------------------
  567|  89.8k|	buf_setpos(writebuf, PACKET_PAYLOAD_OFF);
  ------------------
  |  |   49|  89.8k|#define PACKET_PAYLOAD_OFF 5
  ------------------
  568|       |
  569|       |#ifndef DISABLE_ZLIB
  570|       |	/* compression */
  571|       |	if (is_compress_trans()) {
  572|       |		buf_compress(writebuf, ses.writepayload, ses.writepayload->len);
  573|       |	} else
  574|       |#endif
  575|  89.8k|	{
  576|  89.8k|		memcpy(buf_getwriteptr(writebuf, ses.writepayload->len),
  577|  89.8k|				buf_getptr(ses.writepayload, ses.writepayload->len),
  578|  89.8k|				ses.writepayload->len);
  579|  89.8k|		buf_incrwritepos(writebuf, ses.writepayload->len);
  580|  89.8k|	}
  581|       |
  582|       |	/* finished with payload */
  583|  89.8k|	buf_setpos(ses.writepayload, 0);
  584|  89.8k|	buf_setlen(ses.writepayload, 0);
  585|       |
  586|       |	/* length of padding - packet length excluding the packetlength uint32
  587|       |	 * field in aead mode must be a multiple of blocksize, with a minimum of
  588|       |	 * 4 bytes of padding */
  589|  89.8k|	len = writebuf->len;
  590|  89.8k|#if DROPBEAR_AEAD_MODE
  591|  89.8k|	if (ses.keys->trans.crypt_mode->aead_crypt) {
  ------------------
  |  Branch (591:6): [True: 27.8k, False: 61.9k]
  ------------------
  592|  27.8k|		len -= 4;
  593|  27.8k|	}
  594|  89.8k|#endif
  595|  89.8k|	padlen = blocksize - len % blocksize;
  596|  89.8k|	if (padlen < 4) {
  ------------------
  |  Branch (596:6): [True: 27.1k, False: 62.6k]
  ------------------
  597|  27.1k|		padlen += blocksize;
  598|  27.1k|	}
  599|       |	/* check for min packet length */
  600|  89.8k|	if (writebuf->len + padlen < MIN_PACKET_LEN) {
  ------------------
  |  |  241|  89.8k|#define MIN_PACKET_LEN 16
  ------------------
  |  Branch (600:6): [True: 215, False: 89.5k]
  ------------------
  601|    215|		padlen += blocksize;
  602|    215|	}
  603|       |
  604|  89.8k|	buf_setpos(writebuf, 0);
  605|       |	/* packet length excluding the packetlength uint32 */
  606|  89.8k|	buf_putint(writebuf, writebuf->len + padlen - 4);
  607|       |
  608|       |	/* padding len */
  609|  89.8k|	buf_putbyte(writebuf, padlen);
  610|       |	/* actual padding */
  611|  89.8k|	buf_setpos(writebuf, writebuf->len);
  612|  89.8k|	buf_incrlen(writebuf, padlen);
  613|  89.8k|	genrandom(buf_getptr(writebuf, padlen), padlen);
  614|       |
  615|  89.8k|#if DROPBEAR_AEAD_MODE
  616|  89.8k|	if (ses.keys->trans.crypt_mode->aead_crypt) {
  ------------------
  |  Branch (616:6): [True: 27.8k, False: 61.9k]
  ------------------
  617|       |		/* do the actual encryption, in-place */
  618|  27.8k|		buf_setpos(writebuf, 0);
  619|       |		/* encrypt it in-place*/
  620|  27.8k|		len = writebuf->len;
  621|  27.8k|		buf_incrlen(writebuf, mac_size);
  622|  27.8k|		if (ses.keys->trans.crypt_mode->aead_crypt(ses.transseq,
  ------------------
  |  Branch (622:7): [True: 0, False: 27.8k]
  ------------------
  623|  27.8k|					buf_getptr(writebuf, len),
  624|  27.8k|					buf_getwriteptr(writebuf, len + mac_size),
  625|  27.8k|					len, mac_size,
  626|  27.8k|					&ses.keys->trans.cipher_state, LTC_ENCRYPT) != CRYPT_OK) {
  ------------------
  |  |   68|  27.8k|#define LTC_ENCRYPT 0
  ------------------
  627|      0|			dropbear_exit("Error encrypting");
  628|      0|		}
  629|  27.8k|		buf_incrpos(writebuf, len + mac_size);
  630|  27.8k|	} else
  631|  61.9k|#endif
  632|  61.9k|	{
  633|  61.9k|		make_mac(ses.transseq, &ses.keys->trans, writebuf, writebuf->len, mac_bytes);
  634|       |
  635|       |		/* do the actual encryption, in-place */
  636|  61.9k|		buf_setpos(writebuf, 0);
  637|       |		/* encrypt it in-place*/
  638|  61.9k|		len = writebuf->len;
  639|  61.9k|		if (ses.keys->trans.crypt_mode->encrypt(
  ------------------
  |  Branch (639:7): [True: 0, False: 61.9k]
  ------------------
  640|  61.9k|					buf_getptr(writebuf, len),
  641|  61.9k|					buf_getwriteptr(writebuf, len),
  642|  61.9k|					len,
  643|  61.9k|					&ses.keys->trans.cipher_state) != CRYPT_OK) {
  644|      0|			dropbear_exit("Error encrypting");
  645|      0|		}
  646|  61.9k|		buf_incrpos(writebuf, len);
  647|       |
  648|       |		/* stick the MAC on it */
  649|  61.9k|		buf_putbytes(writebuf, mac_bytes, mac_size);
  650|  61.9k|	}
  651|       |
  652|       |	/* Update counts */
  653|  89.8k|	ses.kexstate.datatrans += writebuf->len;
  654|       |
  655|  89.8k|	writebuf_enqueue(writebuf);
  656|       |
  657|       |	/* Update counts */
  658|  89.8k|	ses.transseq++;
  659|       |
  660|  89.8k|	now = monotonic_now();
  661|  89.8k|	ses.last_packet_time_any_sent = now;
  662|       |	/* idle timeout shouldn't be affected by responses to keepalives.
  663|       |	send_msg_keepalive() itself also does tricks with 
  664|       |	ses.last_packet_idle_time - read that if modifying this code */
  665|  89.8k|	if (packet_type != SSH_MSG_REQUEST_FAILURE
  ------------------
  |  |   65|   179k|#define SSH_MSG_REQUEST_FAILURE                 82
  ------------------
  |  Branch (665:6): [True: 88.6k, False: 1.12k]
  ------------------
  666|  88.6k|		&& packet_type != SSH_MSG_UNIMPLEMENTED
  ------------------
  |  |   31|   178k|#define SSH_MSG_UNIMPLEMENTED          3
  ------------------
  |  Branch (666:6): [True: 83.3k, False: 5.30k]
  ------------------
  667|  83.3k|		&& packet_type != SSH_MSG_IGNORE) {
  ------------------
  |  |   30|  83.3k|#define SSH_MSG_IGNORE                 2
  ------------------
  |  Branch (667:6): [True: 83.3k, False: 0]
  ------------------
  668|  83.3k|		ses.last_packet_time_idle = now;
  669|       |
  670|  83.3k|	}
  671|       |
  672|  89.8k|	TRACE2(("leave encrypt_packet()"))
  673|  89.8k|}
writebuf_enqueue:
  675|  94.3k|void writebuf_enqueue(buffer * writebuf) {
  676|       |	/* enqueue the packet for sending. It will get freed after transmission. */
  677|  94.3k|	buf_setpos(writebuf, 0);
  678|  94.3k|	enqueue(&ses.writequeue, (void*)writebuf);
  679|  94.3k|	ses.writequeue_len += writebuf->len;
  680|  94.3k|}
packet.c:read_packet_init:
  214|   126k|static int read_packet_init() {
  215|       |
  216|   126k|	unsigned int maxlen;
  217|   126k|	int slen;
  218|   126k|	unsigned int len, plen;
  219|   126k|	unsigned int blocksize;
  220|   126k|	unsigned int macsize;
  221|       |
  222|       |
  223|   126k|	blocksize = ses.keys->recv.algo_crypt->blocksize;
  224|   126k|	macsize = ses.keys->recv.algo_mac->hashsize;
  225|       |
  226|   126k|	if (ses.readbuf == NULL) {
  ------------------
  |  Branch (226:6): [True: 43.9k, False: 82.7k]
  ------------------
  227|       |		/* start of a new packet */
  228|  43.9k|		ses.readbuf = buf_new(INIT_READBUF);
  ------------------
  |  |   51|  43.9k|#define INIT_READBUF 128
  ------------------
  229|  43.9k|	}
  230|       |
  231|   126k|	maxlen = blocksize - ses.readbuf->pos;
  232|       |			
  233|       |	/* read the rest of the packet if possible */
  234|   126k|	slen = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
  ------------------
  |  |   55|   126k|#define read(fd, buf, count) wrapfd_read(fd, buf, count)
  ------------------
  235|   126k|			maxlen);
  236|   126k|	if (slen == 0) {
  ------------------
  |  Branch (236:6): [True: 2.41k, False: 124k]
  ------------------
  237|  2.41k|		ses.remoteclosed();
  238|  2.41k|	}
  239|   126k|	if (slen < 0) {
  ------------------
  |  Branch (239:6): [True: 72, False: 126k]
  ------------------
  240|     72|		if (errno == EINTR || errno == EAGAIN) {
  ------------------
  |  Branch (240:7): [True: 67, False: 5]
  |  Branch (240:25): [True: 0, False: 5]
  ------------------
  241|     67|			TRACE2(("leave read_packet_init: EINTR"))
  242|     67|			return DROPBEAR_FAILURE;
  ------------------
  |  |  112|     67|#define DROPBEAR_FAILURE -1
  ------------------
  243|     67|		}
  244|      5|		dropbear_exit("Error reading: %s", strerror(errno));
  245|     72|	}
  246|       |
  247|   126k|	buf_incrwritepos(ses.readbuf, slen);
  248|       |
  249|   126k|	if ((unsigned int)slen != maxlen) {
  ------------------
  |  Branch (249:6): [True: 82.7k, False: 43.8k]
  ------------------
  250|       |		/* don't have enough bytes to determine length, get next time */
  251|  82.7k|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|  82.7k|#define DROPBEAR_FAILURE -1
  ------------------
  252|  82.7k|	}
  253|       |
  254|       |	/* now we have the first block, need to get packet length, so we decrypt
  255|       |	 * the first block (only need first 4 bytes) */
  256|  43.8k|	buf_setpos(ses.readbuf, 0);
  257|  43.8k|#if DROPBEAR_AEAD_MODE
  258|  43.8k|	if (ses.keys->recv.crypt_mode->aead_crypt) {
  ------------------
  |  Branch (258:6): [True: 0, False: 43.8k]
  ------------------
  259|      0|		if (ses.keys->recv.crypt_mode->aead_getlength(ses.recvseq,
  ------------------
  |  Branch (259:7): [True: 0, False: 0]
  ------------------
  260|      0|					buf_getptr(ses.readbuf, blocksize), &plen,
  261|      0|					blocksize,
  262|      0|					&ses.keys->recv.cipher_state) != CRYPT_OK) {
  263|      0|			dropbear_exit("Error decrypting");
  264|      0|		}
  265|      0|		len = plen + 4 + macsize;
  266|      0|	} else
  267|  43.8k|#endif
  268|  43.8k|	{
  269|  43.8k|		if (ses.keys->recv.crypt_mode->decrypt(buf_getptr(ses.readbuf, blocksize), 
  ------------------
  |  Branch (269:7): [True: 0, False: 43.8k]
  ------------------
  270|  43.8k|					buf_getwriteptr(ses.readbuf, blocksize),
  271|  43.8k|					blocksize,
  272|  43.8k|					&ses.keys->recv.cipher_state) != CRYPT_OK) {
  273|      0|			dropbear_exit("Error decrypting");
  274|      0|		}
  275|  43.8k|		plen = buf_getint(ses.readbuf) + 4;
  276|  43.8k|		len = plen + macsize;
  277|  43.8k|	}
  278|       |
  279|  43.8k|	TRACE2(("packet size is %u, block %u mac %u", len, blocksize, macsize))
  280|       |
  281|       |
  282|       |	/* check packet length */
  283|  43.8k|	if ((len > RECV_MAX_PACKET_LEN) ||
  ------------------
  |  |  243|  43.8k|#define RECV_MAX_PACKET_LEN (MAX(35000, ((RECV_MAX_PAYLOAD_LEN)+100)))
  ------------------
  |  Branch (283:6): [True: 2.47k, False: 41.4k]
  |  Branch (283:13): [True: 41.4k, Folded]
  ------------------
  284|  41.4k|		(plen < blocksize) ||
  ------------------
  |  Branch (284:3): [True: 7, False: 41.4k]
  ------------------
  285|  41.4k|		(plen % blocksize != 0)) {
  ------------------
  |  Branch (285:3): [True: 159, False: 41.2k]
  ------------------
  286|    231|		dropbear_exit("Integrity error (bad packet size %u)", len);
  287|    231|	}
  288|       |
  289|  43.6k|	if (len > ses.readbuf->size) {
  ------------------
  |  Branch (289:6): [True: 8.28k, False: 35.3k]
  ------------------
  290|  8.28k|		ses.readbuf = buf_resize(ses.readbuf, len);		
  291|  8.28k|	}
  292|  43.6k|	buf_setlen(ses.readbuf, len);
  293|  43.6k|	buf_setpos(ses.readbuf, blocksize);
  294|  43.6k|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|  43.6k|#define DROPBEAR_SUCCESS 0
  ------------------
  295|  43.8k|}
packet.c:checkmac:
  390|  41.0k|static int checkmac() {
  391|       |
  392|  41.0k|	unsigned char mac_bytes[MAX_MAC_LEN];
  393|  41.0k|	unsigned int mac_size, contents_len;
  394|       |	
  395|  41.0k|	mac_size = ses.keys->recv.algo_mac->hashsize;
  396|  41.0k|	contents_len = ses.readbuf->len - mac_size;
  397|       |
  398|  41.0k|	buf_setpos(ses.readbuf, 0);
  399|  41.0k|	make_mac(ses.recvseq, &ses.keys->recv, ses.readbuf, contents_len, mac_bytes);
  400|       |
  401|  41.0k|#if DROPBEAR_FUZZ
  402|  41.0k|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (402:6): [True: 41.0k, False: 0]
  ------------------
  403|       |	 	/* fail 1 in 2000 times to test error path. */
  404|  41.0k|		unsigned int value = 0;
  405|  41.0k|		if (mac_size > sizeof(value)) {
  ------------------
  |  Branch (405:7): [True: 0, False: 41.0k]
  ------------------
  406|      0|			memcpy(&value, mac_bytes, sizeof(value));
  407|      0|		}
  408|  41.0k|		if (value % 2000 == 99) {
  ------------------
  |  Branch (408:7): [True: 0, False: 41.0k]
  ------------------
  409|      0|			return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  410|      0|		}
  411|  41.0k|		return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|  41.0k|#define DROPBEAR_SUCCESS 0
  ------------------
  412|  41.0k|	}
  413|      0|#endif
  414|       |
  415|       |	/* compare the hash */
  416|      0|	buf_setpos(ses.readbuf, contents_len);
  417|      0|	if (constant_time_memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
  ------------------
  |  Branch (417:6): [True: 0, False: 0]
  ------------------
  418|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  419|      0|	} else {
  420|      0|		return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  421|      0|	}
  422|      0|}
packet.c:packet_is_okay_kex:
  464|  11.2k|static int packet_is_okay_kex(unsigned char type) {
  465|  11.2k|	if (type >= SSH_MSG_USERAUTH_REQUEST) {
  ------------------
  |  |   42|  11.2k|#define SSH_MSG_USERAUTH_REQUEST            50
  ------------------
  |  Branch (465:6): [True: 79, False: 11.1k]
  ------------------
  466|     79|		return 0;
  467|     79|	}
  468|  11.1k|	if (type == SSH_MSG_SERVICE_REQUEST || type == SSH_MSG_SERVICE_ACCEPT) {
  ------------------
  |  |   33|  22.2k|#define SSH_MSG_SERVICE_REQUEST        5
  ------------------
              	if (type == SSH_MSG_SERVICE_REQUEST || type == SSH_MSG_SERVICE_ACCEPT) {
  ------------------
  |  |   34|  11.1k|#define SSH_MSG_SERVICE_ACCEPT         6
  ------------------
  |  Branch (468:6): [True: 0, False: 11.1k]
  |  Branch (468:41): [True: 0, False: 11.1k]
  ------------------
  469|      0|		return 0;
  470|      0|	}
  471|  11.1k|	if (type == SSH_MSG_KEXINIT) {
  ------------------
  |  |   36|  11.1k|#define SSH_MSG_KEXINIT                20
  ------------------
  |  Branch (471:6): [True: 0, False: 11.1k]
  ------------------
  472|       |		/* XXX should this die horribly if !dataallowed ?? */
  473|      0|		return 0;
  474|      0|	}
  475|  11.1k|	return 1;
  476|  11.1k|}
packet.c:enqueue_reply_packet:
  478|     79|static void enqueue_reply_packet() {
  479|     79|	struct packetlist * new_item = NULL;
  480|     79|	new_item = m_malloc(sizeof(struct packetlist));
  481|     79|	new_item->next = NULL;
  482|       |	
  483|     79|	new_item->payload = buf_newcopy(ses.writepayload);
  484|     79|	buf_setpos(ses.writepayload, 0);
  485|     79|	buf_setlen(ses.writepayload, 0);
  486|       |	
  487|     79|	if (ses.reply_queue_tail) {
  ------------------
  |  Branch (487:6): [True: 32, False: 47]
  ------------------
  488|     32|		ses.reply_queue_tail->next = new_item;
  489|     47|	} else {
  490|     47|		ses.reply_queue_head = new_item;
  491|     47|	}
  492|     79|	ses.reply_queue_tail = new_item;
  493|     79|}
packet.c:make_mac:
  687|   103k|		unsigned char *output_mac) {
  688|   103k|	unsigned char seqbuf[4];
  689|   103k|	unsigned long bufsize;
  690|   103k|	hmac_state hmac;
  691|       |
  692|   103k|	if (key_state->algo_mac->hashsize > 0) {
  ------------------
  |  Branch (692:6): [True: 49.3k, False: 53.6k]
  ------------------
  693|       |		/* calculate the mac */
  694|  49.3k|		if (hmac_init(&hmac, 
  ------------------
  |  Branch (694:7): [True: 0, False: 49.3k]
  ------------------
  695|  49.3k|					key_state->hash_index,
  696|  49.3k|					key_state->mackey,
  697|  49.3k|					key_state->algo_mac->keysize) != CRYPT_OK) {
  698|      0|			dropbear_exit("HMAC error");
  699|      0|		}
  700|       |	
  701|       |		/* sequence number */
  702|  49.3k|		STORE32H(seqno, seqbuf);
  ------------------
  |  |   62|  49.3k|#define STORE32H(x, y)                          \
  |  |   63|  49.3k|do { ulong32 __t = __builtin_bswap32 ((x));     \
  |  |   64|  49.3k|      XMEMCPY ((y), &__t, 4); } while(0)
  |  |  ------------------
  |  |  |  |   39|  49.3k|#define XMEMCPY  memcpy
  |  |  ------------------
  |  |  |  Branch (64:39): [Folded, False: 49.3k]
  |  |  ------------------
  ------------------
  703|  49.3k|		if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
  ------------------
  |  Branch (703:7): [True: 0, False: 49.3k]
  ------------------
  704|      0|			dropbear_exit("HMAC error");
  705|      0|		}
  706|       |	
  707|       |		/* the actual contents */
  708|  49.3k|		buf_setpos(clear_buf, 0);
  709|  49.3k|		if (hmac_process(&hmac, 
  ------------------
  |  Branch (709:7): [True: 0, False: 49.3k]
  ------------------
  710|  49.3k|					buf_getptr(clear_buf, clear_len),
  711|  49.3k|					clear_len) != CRYPT_OK) {
  712|      0|			dropbear_exit("HMAC error");
  713|      0|		}
  714|       |	
  715|  49.3k|		bufsize = MAX_MAC_LEN;
  ------------------
  |  |  147|  49.3k|#define MAX_MAC_LEN 32
  ------------------
  716|  49.3k|		if (hmac_done(&hmac, output_mac, &bufsize) != CRYPT_OK) {
  ------------------
  |  Branch (716:7): [True: 0, False: 49.3k]
  ------------------
  717|      0|			dropbear_exit("HMAC error");
  718|      0|		}
  719|  49.3k|	}
  720|   103k|	TRACE2(("leave writemac"))
  721|   103k|}

process_packet:
   43|  41.0k|void process_packet() {
   44|       |
   45|  41.0k|	unsigned char type;
   46|  41.0k|	unsigned int i;
   47|  41.0k|	unsigned int first_strict_kex = ses.kexstate.strict_kex && !ses.kexstate.recvfirstnewkeys;
  ------------------
  |  Branch (47:34): [True: 0, False: 41.0k]
  |  Branch (47:61): [True: 0, False: 0]
  ------------------
   48|  41.0k|	time_t now;
   49|       |
   50|  41.0k|	TRACE2(("enter process_packet"))
   51|       |
   52|  41.0k|	type = buf_getbyte(ses.payload);
   53|  41.0k|	TRACE(("process_packet: packet type = %d,  len %d", type, ses.payload->len))
   54|       |
   55|  41.0k|	now = monotonic_now();
   56|  41.0k|	ses.last_packet_time_keepalive_recv = now;
   57|       |
   58|       |
   59|  41.0k|	if (type == SSH_MSG_DISCONNECT) {
  ------------------
  |  |   29|  41.0k|#define SSH_MSG_DISCONNECT             1
  ------------------
  |  Branch (59:6): [True: 6, False: 41.0k]
  ------------------
   60|       |		/* Allowed at any time */
   61|      6|		dropbear_close("Disconnect received");
   62|      6|	}
   63|       |
   64|       |	/* These packets may be received at any time,
   65|       |	   except during first kex with strict kex */
   66|  41.0k|	if (!first_strict_kex) {
  ------------------
  |  Branch (66:6): [True: 41.0k, False: 6]
  ------------------
   67|  41.0k|		switch(type) {
  ------------------
  |  Branch (67:10): [True: 853, False: 40.2k]
  ------------------
   68|    344|			case SSH_MSG_IGNORE:
  ------------------
  |  |   30|    344|#define SSH_MSG_IGNORE                 2
  ------------------
  |  Branch (68:4): [True: 344, False: 40.7k]
  ------------------
   69|    344|				goto out;
   70|    415|			case SSH_MSG_DEBUG:
  ------------------
  |  |   32|    415|#define SSH_MSG_DEBUG                  4
  ------------------
  |  Branch (70:4): [True: 415, False: 40.6k]
  ------------------
   71|    415|				goto out;
   72|     94|			case SSH_MSG_UNIMPLEMENTED:
  ------------------
  |  |   31|     94|#define SSH_MSG_UNIMPLEMENTED          3
  ------------------
  |  Branch (72:4): [True: 94, False: 40.9k]
  ------------------
   73|     94|				TRACE(("SSH_MSG_UNIMPLEMENTED"))
   74|     94|				goto out;
   75|  41.0k|		}
   76|  41.0k|	}
   77|       |
   78|       |	/* Ignore these packet types so that keepalives don't interfere with
   79|       |	idle detection. This is slightly incorrect since a tcp forwarded
   80|       |	global request with failure won't trigger the idle timeout,
   81|       |	but that's probably acceptable */
   82|  40.2k|	if (!(type == SSH_MSG_GLOBAL_REQUEST 
  ------------------
  |  |   63|  80.4k|#define SSH_MSG_GLOBAL_REQUEST                  80
  ------------------
  |  Branch (82:8): [True: 1.41k, False: 38.8k]
  ------------------
   83|  38.8k|		|| type == SSH_MSG_REQUEST_FAILURE
  ------------------
  |  |   65|  79.0k|#define SSH_MSG_REQUEST_FAILURE                 82
  ------------------
  |  Branch (83:6): [True: 368, False: 38.4k]
  ------------------
   84|  38.4k|		|| type == SSH_MSG_CHANNEL_FAILURE)) {
  ------------------
  |  |   76|  38.4k|#define SSH_MSG_CHANNEL_FAILURE                 100
  ------------------
  |  Branch (84:6): [True: 227, False: 38.2k]
  ------------------
   85|  38.2k|		ses.last_packet_time_idle = now;
   86|  38.2k|	}
   87|       |
   88|       |	/* This applies for KEX, where the spec says the next packet MUST be
   89|       |	 * NEWKEYS */
   90|  40.2k|	if (ses.requirenext != 0) {
  ------------------
  |  Branch (90:6): [True: 22.0k, False: 18.2k]
  ------------------
   91|  22.0k|		if (ses.requirenext == type)
  ------------------
  |  Branch (91:7): [True: 17.0k, False: 4.95k]
  ------------------
   92|  17.0k|		{
   93|       |			/* Got what we expected */
   94|  17.0k|			TRACE(("got expected packet %d during kexinit", type))
   95|  17.0k|		}
   96|  4.95k|		else
   97|  4.95k|		{
   98|       |			/* RFC4253 7.1 - various messages are allowed at this point.
   99|       |			The only ones we know about have already been handled though,
  100|       |			so just return "unimplemented" */
  101|  4.95k|			if (type >= 1 && type <= 49
  ------------------
  |  Branch (101:8): [True: 4.94k, False: 10]
  |  Branch (101:21): [True: 4.91k, False: 33]
  ------------------
  102|  4.91k|				&& type != SSH_MSG_SERVICE_REQUEST
  ------------------
  |  |   33|  9.86k|#define SSH_MSG_SERVICE_REQUEST        5
  ------------------
  |  Branch (102:8): [True: 4.90k, False: 1]
  ------------------
  103|  4.90k|				&& type != SSH_MSG_SERVICE_ACCEPT
  ------------------
  |  |   34|  9.86k|#define SSH_MSG_SERVICE_ACCEPT         6
  ------------------
  |  Branch (103:8): [True: 4.90k, False: 1]
  ------------------
  104|  4.90k|				&& type != SSH_MSG_KEXINIT
  ------------------
  |  |   36|  9.86k|#define SSH_MSG_KEXINIT                20
  ------------------
  |  Branch (104:8): [True: 4.90k, False: 1]
  ------------------
  105|  4.90k|				&& !first_strict_kex)
  ------------------
  |  Branch (105:8): [True: 4.90k, False: 0]
  ------------------
  106|  4.90k|			{
  107|  4.90k|				TRACE(("unknown allowed packet during kexinit"))
  108|  4.90k|				recv_unimplemented();
  109|  4.90k|				goto out;
  110|  4.90k|			}
  111|     46|			else
  112|     46|			{
  113|     46|				TRACE(("disallowed packet during kexinit"))
  114|     46|				dropbear_exit("Unexpected packet type %d, expected %d", type,
  115|     46|						ses.requirenext);
  116|     46|			}
  117|  4.95k|		}
  118|  22.0k|	}
  119|       |
  120|       |	/* Check if we should ignore this packet. Used currently only for
  121|       |	 * KEX code, with first_kex_packet_follows */
  122|  35.2k|	if (ses.ignorenext) {
  ------------------
  |  Branch (122:6): [True: 90, False: 35.1k]
  ------------------
  123|     90|		TRACE(("Ignoring packet, type = %d", type))
  124|     90|		ses.ignorenext = 0;
  125|     90|		goto out;
  126|     90|	}
  127|       |
  128|       |	/* Only clear the flag after we have checked ignorenext */
  129|  35.1k|	if (ses.requirenext != 0 && ses.requirenext == type)
  ------------------
  |  Branch (129:6): [True: 16.9k, False: 18.2k]
  |  Branch (129:30): [True: 16.9k, False: 0]
  ------------------
  130|  16.9k|	{
  131|  16.9k|		ses.requirenext = 0;
  132|  16.9k|	}
  133|       |
  134|       |
  135|       |	/* Kindly the protocol authors gave all the preauth packets type values
  136|       |	 * less-than-or-equal-to 60 ( == MAX_UNAUTH_PACKET_TYPE ).
  137|       |	 * NOTE: if the protocol changes and new types are added, revisit this 
  138|       |	 * assumption */
  139|  35.1k|	if ( !ses.authstate.authdone && type > MAX_UNAUTH_PACKET_TYPE ) {
  ------------------
  |  |   38|      0|#define MAX_UNAUTH_PACKET_TYPE SSH_MSG_USERAUTH_PK_OK
  |  |  ------------------
  |  |  |  |   52|      0|#define SSH_MSG_USERAUTH_PK_OK				60
  |  |  ------------------
  ------------------
  |  Branch (139:7): [True: 0, False: 35.1k]
  |  Branch (139:34): [True: 0, False: 0]
  ------------------
  140|      0|		dropbear_exit("Received message %d before userauth", type);
  141|      0|	}
  142|       |
  143|   262k|	for (i = 0; ; i++) {
  144|   262k|		if (ses.packettypes[i].type == 0) {
  ------------------
  |  Branch (144:7): [True: 393, False: 261k]
  ------------------
  145|       |			/* end of list */
  146|    393|			break;
  147|    393|		}
  148|       |
  149|   261k|		if (ses.packettypes[i].type == type) {
  ------------------
  |  Branch (149:7): [True: 34.7k, False: 226k]
  ------------------
  150|  34.7k|			ses.packettypes[i].handler();
  151|  34.7k|			goto out;
  152|  34.7k|		}
  153|   261k|	}
  154|       |
  155|       |	
  156|       |	/* TODO do something more here? */
  157|    399|	TRACE(("preauth unknown packet"))
  158|    399|	recv_unimplemented();
  159|       |
  160|  39.5k|out:
  161|  39.5k|	ses.lastpacket = type;
  162|  39.5k|	buf_free(ses.payload);
  163|  39.5k|	ses.payload = NULL;
  164|       |
  165|  39.5k|	TRACE2(("leave process_packet"))
  166|  39.5k|}
process-packet.c:recv_unimplemented:
  174|  5.30k|static void recv_unimplemented() {
  175|       |
  176|  5.30k|	CHECKCLEARTOWRITE();
  177|       |
  178|  5.30k|	buf_putbyte(ses.writepayload, SSH_MSG_UNIMPLEMENTED);
  ------------------
  |  |   31|  5.30k|#define SSH_MSG_UNIMPLEMENTED          3
  ------------------
  179|       |	/* the decryption routine increments the sequence number, we must
  180|       |	 * decrement */
  181|  5.30k|	buf_putint(ses.writepayload, ses.recvseq - 1);
  182|       |
  183|  5.30k|	encrypt_packet();
  184|  5.30k|}

initqueue:
   29|  4.58k|void initqueue(struct Queue* queue) {
   30|       |
   31|  4.58k|	queue->head = NULL;
   32|       |	queue->tail = NULL;
   33|  4.58k|	queue->count = 0;
   34|  4.58k|}
isempty:
   36|   899k|int isempty(const struct Queue* queue) {
   37|       |
   38|       |	return (queue->head == NULL);
   39|   899k|}
dequeue:
   41|  94.3k|void* dequeue(struct Queue* queue) {
   42|       |
   43|  94.3k|	void* ret;
   44|  94.3k|	struct Link* oldhead;
   45|  94.3k|	dropbear_assert(!isempty(queue));
  ------------------
  |  |   84|  94.3k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 94.3k]
  |  |  |  Branch (84:93): [Folded, False: 94.3k]
  |  |  ------------------
  ------------------
   46|       |	
   47|  94.3k|	ret = queue->head->item;
   48|  94.3k|	oldhead = queue->head;
   49|       |	
   50|  94.3k|	if (oldhead->link != NULL) {
  ------------------
  |  Branch (50:6): [True: 54.1k, False: 40.2k]
  ------------------
   51|  54.1k|		queue->head = oldhead->link;
   52|  54.1k|	} else {
   53|  40.2k|		queue->head = NULL;
   54|  40.2k|		queue->tail = NULL;
   55|  40.2k|		TRACE(("empty queue dequeing"))
   56|  40.2k|	}
   57|       |
   58|       |	m_free(oldhead);
  ------------------
  |  |   24|  94.3k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 94.3k]
  |  |  ------------------
  ------------------
   59|  94.3k|	queue->count--;
   60|  94.3k|	return ret;
   61|  94.3k|}
examine:
   63|  91.7k|void *examine(const struct Queue* queue) {
   64|       |
   65|  91.7k|	dropbear_assert(!isempty(queue));
  ------------------
  |  |   84|  91.7k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 91.7k]
  |  |  |  Branch (84:93): [Folded, False: 91.7k]
  |  |  ------------------
  ------------------
   66|  91.7k|	return queue->head->item;
   67|  91.7k|}
enqueue:
   69|  94.3k|void enqueue(struct Queue* queue, void* item) {
   70|       |
   71|  94.3k|	struct Link* newlink;
   72|       |
   73|  94.3k|	newlink = (struct Link*)m_malloc(sizeof(struct Link));
   74|       |
   75|  94.3k|	newlink->item = item;
   76|  94.3k|	newlink->link = NULL;
   77|       |
   78|  94.3k|	if (queue->tail != NULL) {
  ------------------
  |  Branch (78:6): [True: 54.1k, False: 40.2k]
  ------------------
   79|  54.1k|		queue->tail->link = newlink;
   80|  54.1k|	}
   81|  94.3k|	queue->tail = newlink;
   82|       |
   83|  94.3k|	if (queue->head == NULL) {
  ------------------
  |  Branch (83:6): [True: 40.2k, False: 54.1k]
  ------------------
   84|  40.2k|		queue->head = newlink;
   85|  40.2k|	}
   86|  94.3k|	queue->count++;
   87|  94.3k|}

buf_get_rsa_pub_key:
   53|      1|int buf_get_rsa_pub_key(buffer* buf, dropbear_rsa_key *key) {
   54|       |
   55|      1|	int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
   56|      1|	TRACE(("enter buf_get_rsa_pub_key"))
   57|      1|	dropbear_assert(key != NULL);
  ------------------
  |  |   84|      1|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 1]
  |  |  |  Branch (84:93): [Folded, False: 1]
  |  |  ------------------
  ------------------
   58|      1|	m_mp_alloc_init_multi(&key->e, &key->n, NULL);
   59|      1|	key->d = NULL;
   60|      1|	key->p = NULL;
   61|      1|	key->q = NULL;
   62|       |
   63|      1|	buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */
  ------------------
  |  |  117|      1|#define SSH_SIGNKEY_RSA_LEN 7
  ------------------
   64|       |
   65|      1|	if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE
  ------------------
  |  |  112|      2|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (65:6): [True: 0, False: 1]
  ------------------
   66|      1|	 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (66:6): [True: 0, False: 1]
  ------------------
   67|      0|		TRACE(("leave buf_get_rsa_pub_key: failure"))
   68|      0|		goto out;
   69|      0|	}
   70|       |
   71|      1|	if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) {
  ------------------
  |  |   69|      1|#define MIN_RSA_KEYLEN 1024
  ------------------
  |  Branch (71:6): [True: 0, False: 1]
  ------------------
   72|      0|		dropbear_log(LOG_WARNING, "RSA key too short");
   73|      0|		goto out;
   74|      0|	}
   75|       |
   76|       |	/* 64 bit is limit used by openssl, so we won't block any keys in the wild */
   77|      1|	if (mp_count_bits(key->e) > 64) {
  ------------------
  |  Branch (77:6): [True: 0, False: 1]
  ------------------
   78|      0|		dropbear_log(LOG_WARNING, "RSA key bad e");
   79|      0|		goto out;
   80|      0|	}
   81|       |
   82|      1|	TRACE(("leave buf_get_rsa_pub_key: success"))
   83|      1|	ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      1|#define DROPBEAR_SUCCESS 0
  ------------------
   84|      1|out:
   85|      1|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (85:6): [True: 0, False: 1]
  ------------------
   86|       |		m_mp_free_multi(&key->e, &key->n, NULL);
   87|      0|	}
   88|      1|	return ret;
   89|      1|}
buf_get_rsa_priv_key:
   94|      1|int buf_get_rsa_priv_key(buffer* buf, dropbear_rsa_key *key) {
   95|      1|	int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
   96|       |
   97|      1|	TRACE(("enter buf_get_rsa_priv_key"))
   98|      1|	dropbear_assert(key != NULL);
  ------------------
  |  |   84|      1|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 1]
  |  |  |  Branch (84:93): [Folded, False: 1]
  |  |  ------------------
  ------------------
   99|       |
  100|      1|	if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (100:6): [True: 0, False: 1]
  ------------------
  101|      0|		TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE"))
  102|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  103|      0|	}
  104|       |	
  105|      1|	key->d = NULL;
  106|      1|	key->p = NULL;
  107|      1|	key->q = NULL;
  108|       |
  109|      1|	m_mp_alloc_init_multi(&key->d, NULL);
  110|      1|	if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (110:6): [True: 0, False: 1]
  ------------------
  111|      0|		TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE"))
  112|      0|		goto out;
  113|      0|	}
  114|       |
  115|      1|	if (buf->pos == buf->len) {
  ------------------
  |  Branch (115:6): [True: 0, False: 1]
  ------------------
  116|       |		/* Keys without p or q are prior to Dropbear 0.33 from 2003. */
  117|      0|		dropbear_exit("RSA key format is ancient");
  118|      1|	} else {
  119|      1|		m_mp_alloc_init_multi(&key->p, &key->q, NULL);
  120|       |
  121|      1|		if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (121:7): [True: 0, False: 1]
  ------------------
  122|      0|			TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE"))
  123|      0|			goto out;
  124|      0|		}
  125|       |
  126|      1|		if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (126:7): [True: 0, False: 1]
  ------------------
  127|      0|			TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE"))
  128|      0|			goto out;
  129|      0|		}
  130|      1|	}
  131|       |
  132|      1|	ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      1|#define DROPBEAR_SUCCESS 0
  ------------------
  133|      1|out:
  134|      1|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (134:6): [True: 0, False: 1]
  ------------------
  135|       |		m_mp_free_multi(&key->d, &key->p, &key->q, NULL);
  136|      0|	}
  137|      1|	TRACE(("leave buf_get_rsa_priv_key"))
  138|      1|	return ret;
  139|      1|}
rsa_key_free:
  143|      1|void rsa_key_free(dropbear_rsa_key *key) {
  144|       |
  145|      1|	TRACE2(("enter rsa_key_free"))
  146|       |
  147|      1|	if (key == NULL) {
  ------------------
  |  Branch (147:6): [True: 1, False: 0]
  ------------------
  148|      1|		TRACE2(("leave rsa_key_free: key == NULL"))
  149|      1|		return;
  150|      1|	}
  151|      0|	m_mp_free_multi(&key->d, &key->e, &key->p, &key->q, &key->n, NULL);
  152|       |	m_free(key);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  153|      0|	TRACE2(("leave rsa_key_free"))
  154|      0|}

new_sign_key:
   62|      1|sign_key * new_sign_key() {
   63|       |
   64|      1|	sign_key * ret;
   65|       |
   66|      1|	ret = (sign_key*)m_malloc(sizeof(sign_key));
   67|      1|	ret->type = DROPBEAR_SIGNKEY_NONE;
   68|      1|	ret->source = SIGNKEY_SOURCE_INVALID;
   69|      1|	return ret;
   70|      1|}
signkey_type_from_name:
   86|      4|enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen) {
   87|      4|	int i;
   88|     13|	for (i = 0; i < DROPBEAR_SIGNKEY_NUM_NAMED; i++) {
  ------------------
  |  Branch (88:14): [True: 13, False: 0]
  ------------------
   89|     13|		const char *fixed_name = signkey_names[i];
   90|     13|		if (namelen == strlen(fixed_name)
  ------------------
  |  Branch (90:7): [True: 5, False: 8]
  ------------------
   91|      5|			&& memcmp(fixed_name, name, namelen) == 0) {
  ------------------
  |  Branch (91:7): [True: 4, False: 1]
  ------------------
   92|       |
   93|      4|#if DROPBEAR_ECDSA
   94|       |			/* Some of the ECDSA key sizes are defined even if they're not compiled in */
   95|      4|			if (0
  ------------------
  |  Branch (95:8): [Folded, False: 4]
  ------------------
   96|       |#if !DROPBEAR_ECC_256
   97|       |				|| i == DROPBEAR_SIGNKEY_ECDSA_NISTP256
   98|       |#endif
   99|       |#if !DROPBEAR_ECC_384
  100|       |				|| i == DROPBEAR_SIGNKEY_ECDSA_NISTP384
  101|       |#endif
  102|       |#if !DROPBEAR_ECC_521
  103|       |				|| i == DROPBEAR_SIGNKEY_ECDSA_NISTP521
  104|       |#endif
  105|      4|				) {
  106|      0|				TRACE(("attempt to use ecdsa type %d not compiled in", i))
  107|      0|				return DROPBEAR_SIGNKEY_NONE;
  108|      0|			}
  109|      4|#endif
  110|       |
  111|      4|			return (enum signkey_type)i;
  112|      4|		}
  113|     13|	}
  114|       |
  115|      0|	TRACE(("signkey_type_from_name unexpected key type."))
  116|       |
  117|      0|	return DROPBEAR_SIGNKEY_NONE;
  118|      4|}
signkey_type_from_signature:
  173|  6.95k|enum signkey_type signkey_type_from_signature(enum signature_type sigtype) {
  174|  6.95k|#if DROPBEAR_RSA
  175|  6.95k|#if DROPBEAR_RSA_SHA256
  176|  6.95k|	if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) {
  ------------------
  |  Branch (176:6): [True: 2, False: 6.95k]
  ------------------
  177|      2|		return DROPBEAR_SIGNKEY_RSA;
  178|      2|	}
  179|  6.95k|#endif
  180|  6.95k|#if DROPBEAR_RSA_SHA1
  181|  6.95k|	if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA1) {
  ------------------
  |  Branch (181:6): [True: 3, False: 6.95k]
  ------------------
  182|      3|		return DROPBEAR_SIGNKEY_RSA;
  183|      3|	}
  184|  6.95k|#endif
  185|  6.95k|#endif /* DROPBEAR_RSA */
  186|  6.95k|	assert((int)sigtype < (int)DROPBEAR_SIGNKEY_NUM_NAMED);
  ------------------
  |  Branch (186:2): [True: 0, False: 6.95k]
  |  Branch (186:2): [True: 6.95k, False: 0]
  ------------------
  187|  6.95k|	return (enum signkey_type)sigtype;
  188|  6.95k|}
signkey_key_ptr:
  193|      1|signkey_key_ptr(sign_key *key, enum signkey_type type) {
  194|      1|	switch (type) {
  195|      0|#if DROPBEAR_ED25519
  196|      0|		case DROPBEAR_SIGNKEY_ED25519:
  ------------------
  |  Branch (196:3): [True: 0, False: 1]
  ------------------
  197|      0|#if DROPBEAR_SK_ED25519
  198|      0|		case DROPBEAR_SIGNKEY_SK_ED25519:
  ------------------
  |  Branch (198:3): [True: 0, False: 1]
  ------------------
  199|      0|#endif
  200|      0|			return (void**)&key->ed25519key;
  201|      0|#endif
  202|      0|#if DROPBEAR_ECDSA
  203|      0|#if DROPBEAR_ECC_256
  204|      1|		case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
  ------------------
  |  Branch (204:3): [True: 1, False: 0]
  ------------------
  205|      1|#if DROPBEAR_SK_ECDSA
  206|      1|		case DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256:
  ------------------
  |  Branch (206:3): [True: 0, False: 1]
  ------------------
  207|      1|#endif
  208|      1|			return (void**)&key->ecckey256;
  209|      0|#endif
  210|      0|#if DROPBEAR_ECC_384
  211|      0|		case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
  ------------------
  |  Branch (211:3): [True: 0, False: 1]
  ------------------
  212|      0|			return (void**)&key->ecckey384;
  213|      0|#endif
  214|      0|#if DROPBEAR_ECC_521
  215|      0|		case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
  ------------------
  |  Branch (215:3): [True: 0, False: 1]
  ------------------
  216|      0|			return (void**)&key->ecckey521;
  217|      0|#endif
  218|      0|#endif /* DROPBEAR_ECDSA */
  219|      0|#if DROPBEAR_RSA
  220|      0|		case DROPBEAR_SIGNKEY_RSA:
  ------------------
  |  Branch (220:3): [True: 0, False: 1]
  ------------------
  221|      0|			return (void**)&key->rsakey;
  222|      0|#endif
  223|      0|#if DROPBEAR_DSS
  224|      0|		case DROPBEAR_SIGNKEY_DSS:
  ------------------
  |  Branch (224:3): [True: 0, False: 1]
  ------------------
  225|      0|			return (void**)&key->dsskey;
  226|      0|#endif
  227|      0|		default:
  ------------------
  |  Branch (227:3): [True: 0, False: 1]
  ------------------
  228|       |			return NULL;
  229|      1|	}
  230|      1|}
buf_get_priv_key:
  339|      4|int buf_get_priv_key(buffer *buf, sign_key *key, enum signkey_type *type) {
  340|       |
  341|      4|	char *ident;
  342|      4|	unsigned int len;
  343|      4|	enum signkey_type keytype;
  344|      4|	int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|      4|#define DROPBEAR_FAILURE -1
  ------------------
  345|       |
  346|      4|	TRACE2(("enter buf_get_priv_key"))
  347|       |
  348|      4|	ident = buf_getstring(buf, &len);
  349|      4|	keytype = signkey_type_from_name(ident, len);
  350|      4|	m_free(ident);
  ------------------
  |  |   24|      4|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4]
  |  |  ------------------
  ------------------
  351|       |
  352|      4|	if (*type != DROPBEAR_SIGNKEY_ANY && *type != keytype) {
  ------------------
  |  Branch (352:6): [True: 4, False: 0]
  |  Branch (352:39): [True: 0, False: 4]
  ------------------
  353|      0|		TRACE(("wrong key type: %d %d", *type, keytype))
  354|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  355|      0|	}
  356|       |
  357|      4|	*type = keytype;
  358|       |
  359|       |	/* Rewind the buffer back before "ssh-rsa" etc */
  360|      4|	buf_decrpos(buf, len + 4);
  361|       |
  362|      4|#if DROPBEAR_DSS
  363|      4|	if (keytype == DROPBEAR_SIGNKEY_DSS) {
  ------------------
  |  Branch (363:6): [True: 1, False: 3]
  ------------------
  364|      1|		dss_key_free(key->dsskey);
  365|      1|		key->dsskey = m_malloc(sizeof(*key->dsskey));
  366|      1|		ret = buf_get_dss_priv_key(buf, key->dsskey);
  367|      1|		if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (367:7): [True: 0, False: 1]
  ------------------
  368|      0|			dss_key_free(key->dsskey);
  369|      0|			key->dsskey = NULL;
  370|      0|		}
  371|      1|	}
  372|      4|#endif
  373|      4|#if DROPBEAR_RSA
  374|      4|	if (keytype == DROPBEAR_SIGNKEY_RSA) {
  ------------------
  |  Branch (374:6): [True: 1, False: 3]
  ------------------
  375|      1|		rsa_key_free(key->rsakey);
  376|      1|		key->rsakey = m_malloc(sizeof(*key->rsakey));
  377|      1|		ret = buf_get_rsa_priv_key(buf, key->rsakey);
  378|      1|		if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (378:7): [True: 0, False: 1]
  ------------------
  379|      0|			rsa_key_free(key->rsakey);
  380|      0|			key->rsakey = NULL;
  381|      0|		}
  382|      1|	}
  383|      4|#endif
  384|      4|#if DROPBEAR_ECDSA
  385|      4|	if (signkey_is_ecdsa(keytype)) {
  ------------------
  |  Branch (385:6): [True: 1, False: 3]
  ------------------
  386|      1|		ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
  387|      1|		if (eck) {
  ------------------
  |  Branch (387:7): [True: 1, False: 0]
  ------------------
  388|      1|			if (*eck) {
  ------------------
  |  Branch (388:8): [True: 0, False: 1]
  ------------------
  389|      0|				ecc_free(*eck);
  390|      0|				m_free(*eck);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  391|      0|				*eck = NULL;
  392|      0|			}
  393|      1|			*eck = buf_get_ecdsa_priv_key(buf);
  394|      1|			if (*eck) {
  ------------------
  |  Branch (394:8): [True: 1, False: 0]
  ------------------
  395|      1|				ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      1|#define DROPBEAR_SUCCESS 0
  ------------------
  396|      1|			}
  397|      1|		}
  398|      1|	}
  399|      4|#endif
  400|      4|#if DROPBEAR_ED25519
  401|      4|	if (keytype == DROPBEAR_SIGNKEY_ED25519) {
  ------------------
  |  Branch (401:6): [True: 1, False: 3]
  ------------------
  402|      1|		ed25519_key_free(key->ed25519key);
  403|      1|		key->ed25519key = m_malloc(sizeof(*key->ed25519key));
  404|      1|		ret = buf_get_ed25519_priv_key(buf, key->ed25519key);
  405|      1|		if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      1|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (405:7): [True: 0, False: 1]
  ------------------
  406|      0|			m_free(key->ed25519key);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  407|      0|			key->ed25519key = NULL;
  408|      0|		}
  409|      1|	}
  410|      4|#endif
  411|       |
  412|      4|	TRACE2(("leave buf_get_priv_key"))
  413|       |
  414|      4|	return ret;
  415|       |	
  416|      4|}

pty_allocate:
   50|     10|{
   51|     10|#if defined(HAVE_OPENPTY)
   52|       |	/* exists in recent (4.4) BSDs and OSF/1 */
   53|     10|	char *name;
   54|     10|	int i;
   55|       |
   56|     10|	i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
   57|     10|	if (i < 0) {
  ------------------
  |  Branch (57:6): [True: 0, False: 10]
  ------------------
   58|      0|		dropbear_log(LOG_WARNING, 
   59|      0|				"pty_allocate: openpty: %.100s", strerror(errno));
   60|      0|		return 0;
   61|      0|	}
   62|     10|	name = ttyname(*ttyfd);
   63|     10|	if (!name) {
  ------------------
  |  Branch (63:6): [True: 0, False: 10]
  ------------------
   64|      0|		dropbear_exit("ttyname fails for openpty device");
   65|      0|	}
   66|       |
   67|     10|	strlcpy(namebuf, name, namebuflen);	/* possible truncation */
   68|     10|	return 1;
   69|       |#else /* HAVE_OPENPTY */
   70|       |#ifdef HAVE__GETPTY
   71|       |	/*
   72|       |	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
   73|       |	 * pty's automagically when needed
   74|       |	 */
   75|       |	char *slave;
   76|       |
   77|       |	slave = _getpty(ptyfd, O_RDWR, 0622, 0);
   78|       |	if (slave == NULL) {
   79|       |		dropbear_log(LOG_WARNING,
   80|       |				"pty_allocate: _getpty: %.100s", strerror(errno));
   81|       |		return 0;
   82|       |	}
   83|       |	strlcpy(namebuf, slave, namebuflen);
   84|       |	/* Open the slave side. */
   85|       |	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
   86|       |	if (*ttyfd < 0) {
   87|       |		dropbear_log(LOG_WARNING,
   88|       |				"pty_allocate error: ttyftd open error");
   89|       |		close(*ptyfd);
   90|       |		return 0;
   91|       |	}
   92|       |	return 1;
   93|       |#else /* HAVE__GETPTY */
   94|       |#if defined(USE_DEV_PTMX)
   95|       |	/*
   96|       |	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
   97|       |	 * also has bsd-style ptys, but they simply do not work.)
   98|       |	 *
   99|       |	 * Linux systems may have the /dev/ptmx device, but this code won't work.
  100|       |	 */
  101|       |	int ptm;
  102|       |	char *pts;
  103|       |
  104|       |	ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
  105|       |	if (ptm < 0) {
  106|       |		dropbear_log(LOG_WARNING,
  107|       |				"pty_allocate: /dev/ptmx: %.100s", strerror(errno));
  108|       |		return 0;
  109|       |	}
  110|       |	if (grantpt(ptm) < 0) {
  111|       |		dropbear_log(LOG_WARNING,
  112|       |				"grantpt: %.100s", strerror(errno));
  113|       |		return 0;
  114|       |	}
  115|       |	if (unlockpt(ptm) < 0) {
  116|       |		dropbear_log(LOG_WARNING,
  117|       |				"unlockpt: %.100s", strerror(errno));
  118|       |		return 0;
  119|       |	}
  120|       |	pts = ptsname(ptm);
  121|       |	if (pts == NULL) {
  122|       |		dropbear_log(LOG_WARNING,
  123|       |				"Slave pty side name could not be obtained.");
  124|       |	}
  125|       |	strlcpy(namebuf, pts, namebuflen);
  126|       |	*ptyfd = ptm;
  127|       |
  128|       |	/* Open the slave side. */
  129|       |	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
  130|       |	if (*ttyfd < 0) {
  131|       |		dropbear_log(LOG_ERR,
  132|       |			"error opening pts %.100s: %.100s", namebuf, strerror(errno));
  133|       |		close(*ptyfd);
  134|       |		return 0;
  135|       |	}
  136|       |#if !defined(HAVE_CYGWIN) && defined(I_PUSH)
  137|       |	/*
  138|       |	 * Push the appropriate streams modules, as described in Solaris pts(7).
  139|       |	 * HP-UX pts(7) doesn't have ttcompat module.
  140|       |	 */
  141|       |	if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) {
  142|       |		dropbear_log(LOG_WARNING,
  143|       |				"ioctl I_PUSH ptem: %.100s", strerror(errno));
  144|       |	}
  145|       |	if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) {
  146|       |		dropbear_log(LOG_WARNING,
  147|       |			"ioctl I_PUSH ldterm: %.100s", strerror(errno));
  148|       |	}
  149|       |#ifndef __hpux
  150|       |	if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) {
  151|       |		dropbear_log(LOG_WARNING,
  152|       |			"ioctl I_PUSH ttcompat: %.100s", strerror(errno));
  153|       |	}
  154|       |#endif
  155|       |#endif
  156|       |	return 1;
  157|       |#else /* USE_DEV_PTMX */
  158|       |#ifdef HAVE_DEV_PTS_AND_PTC
  159|       |	/* AIX-style pty code. */
  160|       |	const char *name;
  161|       |
  162|       |	*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
  163|       |	if (*ptyfd < 0) {
  164|       |		dropbear_log(LOG_ERR,
  165|       |			"Could not open /dev/ptc: %.100s", strerror(errno));
  166|       |		return 0;
  167|       |	}
  168|       |	name = ttyname(*ptyfd);
  169|       |	if (!name) {
  170|       |		dropbear_exit("ttyname fails for /dev/ptc device");
  171|       |	}
  172|       |	strlcpy(namebuf, name, namebuflen);
  173|       |	*ttyfd = open(name, O_RDWR | O_NOCTTY);
  174|       |	if (*ttyfd < 0) {
  175|       |		dropbear_log(LOG_ERR,
  176|       |			"Could not open pty slave side %.100s: %.100s",
  177|       |		    name, strerror(errno));
  178|       |		close(*ptyfd);
  179|       |		return 0;
  180|       |	}
  181|       |	return 1;
  182|       |#else /* HAVE_DEV_PTS_AND_PTC */
  183|       |
  184|       |	/* BSD-style pty code. */
  185|       |	char buf[64];
  186|       |	int i;
  187|       |	const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
  188|       |	const char *ptyminors = "0123456789abcdef";
  189|       |	int num_minors = strlen(ptyminors);
  190|       |	int num_ptys = strlen(ptymajors) * num_minors;
  191|       |	struct termios tio;
  192|       |
  193|       |	for (i = 0; i < num_ptys; i++) {
  194|       |		snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
  195|       |			 ptyminors[i % num_minors]);
  196|       |		snprintf(namebuf, namebuflen, "/dev/tty%c%c",
  197|       |		    ptymajors[i / num_minors], ptyminors[i % num_minors]);
  198|       |
  199|       |		*ptyfd = open(buf, O_RDWR | O_NOCTTY);
  200|       |		if (*ptyfd < 0) {
  201|       |			/* Try SCO style naming */
  202|       |			snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
  203|       |			snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
  204|       |			*ptyfd = open(buf, O_RDWR | O_NOCTTY);
  205|       |			if (*ptyfd < 0) {
  206|       |				continue;
  207|       |			}
  208|       |		}
  209|       |
  210|       |		/* Open the slave side. */
  211|       |		*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
  212|       |		if (*ttyfd < 0) {
  213|       |			dropbear_log(LOG_ERR,
  214|       |				"pty_allocate: %.100s: %.100s", namebuf, strerror(errno));
  215|       |			close(*ptyfd);
  216|       |			return 0;
  217|       |		}
  218|       |		/* set tty modes to a sane state for broken clients */
  219|       |		if (tcgetattr(*ptyfd, &tio) < 0) {
  220|       |			dropbear_log(LOG_WARNING,
  221|       |				"ptyallocate: tty modes failed: %.100s", strerror(errno));
  222|       |		} else {
  223|       |			tio.c_lflag |= (ECHO | ISIG | ICANON);
  224|       |			tio.c_oflag |= (OPOST | ONLCR);
  225|       |			tio.c_iflag |= ICRNL;
  226|       |
  227|       |			/* Set the new modes for the terminal. */
  228|       |			if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) {
  229|       |				dropbear_log(LOG_WARNING,
  230|       |					"Setting tty modes for pty failed: %.100s",
  231|       |					strerror(errno));
  232|       |			}
  233|       |		}
  234|       |
  235|       |		return 1;
  236|       |	}
  237|       |	dropbear_log(LOG_WARNING, "Failed to open any /dev/pty?? devices");
  238|       |	return 0;
  239|       |#endif /* HAVE_DEV_PTS_AND_PTC */
  240|       |#endif /* USE_DEV_PTMX */
  241|       |#endif /* HAVE__GETPTY */
  242|       |#endif /* HAVE_OPENPTY */
  243|     10|}
pty_release:
  249|     10|{
  250|     10|	if (chown(tty_name, (uid_t) 0, (gid_t) 0) < 0
  ------------------
  |  Branch (250:6): [True: 0, False: 10]
  ------------------
  251|      0|			&& (errno != ENOENT)) {
  ------------------
  |  Branch (251:7): [True: 0, False: 0]
  ------------------
  252|      0|		dropbear_log(LOG_ERR,
  253|      0|				"chown %.100s 0 0 failed: %.100s", tty_name, strerror(errno));
  254|      0|	}
  255|     10|	if (chmod(tty_name, (mode_t) 0666) < 0
  ------------------
  |  Branch (255:6): [True: 0, False: 10]
  ------------------
  256|      0|			&& (errno != ENOENT)) {
  ------------------
  |  Branch (256:7): [True: 0, False: 0]
  ------------------
  257|      0|		dropbear_log(LOG_ERR,
  258|       |			"chmod %.100s 0666 failed: %.100s", tty_name, strerror(errno));
  259|      0|	}
  260|     10|}
pty_change_window_size:
  345|      1|{
  346|      1|	struct winsize w;
  347|       |
  348|      1|	w.ws_row = row;
  349|      1|	w.ws_col = col;
  350|      1|	w.ws_xpixel = xpixel;
  351|      1|	w.ws_ypixel = ypixel;
  352|       |	(void) ioctl(ptyfd, TIOCSWINSZ, &w);
  353|      1|}
pty_setowner:
  357|     10|{
  358|     10|	struct group *grp;
  359|     10|	gid_t gid;
  360|     10|	mode_t mode;
  361|     10|	struct stat st;
  362|       |
  363|       |	/* Determine the group to make the owner of the tty. */
  364|     10|	grp = getgrnam("tty");
  365|     10|	if (grp) {
  ------------------
  |  Branch (365:6): [True: 10, False: 0]
  ------------------
  366|     10|		gid = grp->gr_gid;
  367|     10|		mode = S_IRUSR | S_IWUSR | S_IWGRP;
  368|     10|	} else {
  369|      0|		gid = pw->pw_gid;
  370|      0|		mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
  371|      0|	}
  372|       |
  373|       |	/*
  374|       |	 * Change owner and mode of the tty as required.
  375|       |	 * Warn but continue if filesystem is read-only and the uids match/
  376|       |	 * tty is owned by root.
  377|       |	 */
  378|     10|	if (stat(tty_name, &st)) {
  ------------------
  |  Branch (378:6): [True: 0, False: 10]
  ------------------
  379|      0|		dropbear_exit("pty_setowner: stat(%.101s) failed: %.100s",
  380|      0|				tty_name, strerror(errno));
  381|      0|	}
  382|       |
  383|       |	/* Allow either "tty" gid or user's own gid. On Linux with openpty()
  384|       |	 * this varies depending on the devpts mount options */
  385|     10|	if (st.st_uid != pw->pw_uid || !(st.st_gid == gid || st.st_gid == pw->pw_gid)) {
  ------------------
  |  Branch (385:6): [True: 0, False: 10]
  |  Branch (385:35): [True: 10, False: 0]
  |  Branch (385:55): [True: 0, False: 0]
  ------------------
  386|      0|		if (chown(tty_name, pw->pw_uid, gid) < 0) {
  ------------------
  |  Branch (386:7): [True: 0, False: 0]
  ------------------
  387|      0|			if (errno == EROFS &&
  ------------------
  |  Branch (387:8): [True: 0, False: 0]
  ------------------
  388|      0|			    (st.st_uid == pw->pw_uid || st.st_uid == 0)) {
  ------------------
  |  Branch (388:9): [True: 0, False: 0]
  |  Branch (388:36): [True: 0, False: 0]
  ------------------
  389|      0|				dropbear_log(LOG_ERR,
  390|      0|					"chown(%.100s, %u, %u) failed: %.100s",
  391|      0|						tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
  392|      0|						strerror(errno));
  393|      0|			} else {
  394|      0|				dropbear_exit("chown(%.100s, %u, %u) failed: %.100s",
  395|      0|				    tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
  396|      0|				    strerror(errno));
  397|      0|			}
  398|      0|		}
  399|      0|	}
  400|       |
  401|     10|	if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
  ------------------
  |  Branch (401:6): [True: 0, False: 10]
  ------------------
  402|      0|		if (chmod(tty_name, mode) < 0) {
  ------------------
  |  Branch (402:7): [True: 0, False: 0]
  ------------------
  403|      0|			if (errno == EROFS &&
  ------------------
  |  Branch (403:8): [True: 0, False: 0]
  ------------------
  404|      0|			    (st.st_mode & (S_IRGRP | S_IROTH)) == 0) {
  ------------------
  |  Branch (404:8): [True: 0, False: 0]
  ------------------
  405|      0|				dropbear_log(LOG_ERR,
  406|      0|					"chmod(%.100s, 0%o) failed: %.100s",
  407|      0|					tty_name, mode, strerror(errno));
  408|      0|			} else {
  409|      0|				dropbear_exit("chmod(%.100s, 0%o) failed: %.100s",
  410|       |				    tty_name, mode, strerror(errno));
  411|      0|			}
  412|      0|		}
  413|      0|	}
  414|     10|}

svr_agentreq:
   52|    384|int svr_agentreq(struct ChanSess * chansess) {
   53|    384|	int fd = -1;
   54|       |
   55|    384|	if (!svr_pubkey_allows_agentfwd()) {
  ------------------
  |  Branch (55:6): [True: 0, False: 384]
  ------------------
   56|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
   57|      0|	}
   58|       |
   59|    384|	if (chansess->agentlistener != NULL) {
  ------------------
  |  Branch (59:6): [True: 168, False: 216]
  ------------------
   60|    168|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|    168|#define DROPBEAR_FAILURE -1
  ------------------
   61|    168|	}
   62|       |
   63|    216|#if DROPBEAR_FUZZ
   64|    216|	if (fuzz.fuzzing) {
  ------------------
  |  Branch (64:6): [True: 216, False: 0]
  ------------------
   65|    216|		fd = wrapfd_new_dummy();
   66|    216|	}
   67|      0|	else
   68|      0|#endif
   69|      0|	{
   70|       |		/* create listening socket */
   71|      0|		fd = socket(PF_UNIX, SOCK_STREAM, 0);
   72|      0|		if (fd < 0) {
  ------------------
  |  Branch (72:7): [True: 0, False: 0]
  ------------------
   73|      0|			goto fail;
   74|      0|		}
   75|       |
   76|       |		/* create the unix socket dir and file */
   77|      0|		if (bindagent(fd, chansess) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (77:7): [True: 0, False: 0]
  ------------------
   78|      0|			goto fail;
   79|      0|		}
   80|       |
   81|       |		/* listen */
   82|      0|		if (listen(fd, 20) < 0) {
  ------------------
  |  Branch (82:7): [True: 0, False: 0]
  ------------------
   83|      0|			goto fail;
   84|      0|		}
   85|      0|	}
   86|       |
   87|       |	/* set non-blocking */
   88|    216|	setnonblocking(fd);
   89|       |
   90|       |	/* pass if off to listener */
   91|    216|	chansess->agentlistener = new_listener( &fd, 1,
   92|    216|		LISTENER_TYPE_DEFAULT, chansess,
   93|    216|		agentaccept, NULL);
   94|       |
   95|    216|	if (chansess->agentlistener == NULL) {
  ------------------
  |  Branch (95:6): [True: 0, False: 216]
  ------------------
   96|      0|		goto fail;
   97|      0|	}
   98|       |
   99|    216|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|    216|#define DROPBEAR_SUCCESS 0
  ------------------
  100|       |
  101|      0|fail:
  102|      0|	m_close(fd);
  103|       |	/* cleanup */
  104|      0|	svr_agentcleanup(chansess);
  105|       |
  106|      0|	return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  107|    216|}
svr_agentcleanup:
  149|  3.42k|void svr_agentcleanup(struct ChanSess * chansess) {
  150|       |
  151|  3.42k|	char *path = NULL;
  152|  3.42k|	uid_t uid;
  153|  3.42k|	gid_t gid;
  154|  3.42k|	int len;
  155|       |
  156|  3.42k|	if (chansess->agentlistener != NULL) {
  ------------------
  |  Branch (156:6): [True: 216, False: 3.20k]
  ------------------
  157|    216|		remove_listener(chansess->agentlistener);
  158|    216|		chansess->agentlistener = NULL;
  159|    216|	}
  160|       |
  161|  3.42k|	if (chansess->agentfile != NULL && chansess->agentdir != NULL) {
  ------------------
  |  Branch (161:6): [True: 0, False: 3.42k]
  |  Branch (161:37): [True: 0, False: 0]
  ------------------
  162|       |
  163|       |#if !DROPBEAR_SVR_DROP_PRIVS
  164|       |		/* Remove the dir as the user. That way they can't cause problems except
  165|       |		 * for themselves */
  166|       |		uid = getuid();
  167|       |		gid = getgid();
  168|       |		if ((setegid(ses.authstate.pw_gid)) < 0 ||
  169|       |			(seteuid(ses.authstate.pw_uid)) < 0) {
  170|       |			dropbear_exit("Failed to set euid");
  171|       |		}
  172|       |#else
  173|      0|		(void)uid;
  174|      0|		(void)gid;
  175|      0|#endif
  176|       |
  177|       |		/* 2 for "/" and "\0" */
  178|      0|		len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2;
  179|       |
  180|      0|		path = m_malloc(len);
  181|      0|		snprintf(path, len, "%s/%s", chansess->agentdir, chansess->agentfile);
  182|      0|		unlink(path);
  183|      0|		m_free(path);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  184|       |
  185|      0|		rmdir(chansess->agentdir);
  186|       |
  187|       |#if !DROPBEAR_SVR_DROP_PRIVS
  188|       |		if ((seteuid(uid)) < 0 ||
  189|       |			(setegid(gid)) < 0) {
  190|       |			dropbear_exit("Failed to revert euid");
  191|       |		}
  192|       |#endif
  193|       |
  194|      0|		m_free(chansess->agentfile);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  195|      0|		m_free(chansess->agentdir);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  196|      0|	}
  197|       |
  198|  3.42k|}
svr-agentfwd.c:agentaccept:
  112|  8.84k|static void agentaccept(const struct Listener *UNUSED(listener), int sock) {
  113|       |
  114|  8.84k|	int fd;
  115|       |
  116|  8.84k|	fd = accept(sock, NULL, NULL);
  117|  8.84k|	if (fd < 0) {
  ------------------
  |  Branch (117:6): [True: 8.84k, False: 0]
  ------------------
  118|  8.84k|		TRACE(("accept failed"))
  119|  8.84k|		return;
  120|  8.84k|	}
  121|       |
  122|      0|	if (send_msg_channel_open_agent(fd) != DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (122:6): [True: 0, False: 0]
  ------------------
  123|      0|		close(fd);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  124|      0|	}
  125|       |
  126|      0|}

svr_authinitialise:
   42|  4.58k|void svr_authinitialise() {
   43|  4.58k|	memset(&ses.authstate, 0, sizeof(ses.authstate));
   44|  4.58k|#if DROPBEAR_SVR_PUBKEY_AUTH
   45|  4.58k|	ses.authstate.authtypes |= AUTH_TYPE_PUBKEY;
  ------------------
  |  |  103|  4.58k|#define AUTH_TYPE_PUBKEY    (1 << 1)
  ------------------
   46|  4.58k|#endif
   47|  4.58k|#if DROPBEAR_SVR_PASSWORD_AUTH || DROPBEAR_SVR_PAM_AUTH
   48|  4.58k|	if (!svr_opts.noauthpass) {
  ------------------
  |  Branch (48:6): [True: 4.58k, False: 0]
  ------------------
   49|  4.58k|		ses.authstate.authtypes |= AUTH_TYPE_PASSWORD;
  ------------------
  |  |  104|  4.58k|#define AUTH_TYPE_PASSWORD  (1 << 2)
  ------------------
   50|  4.58k|	}
   51|  4.58k|#endif
   52|  4.58k|}
recv_msg_userauth_request:
   73|     34|void recv_msg_userauth_request() {
   74|       |
   75|     34|	char *username = NULL, *servicename = NULL, *methodname = NULL;
   76|     34|	unsigned int userlen, servicelen, methodlen;
   77|     34|	int valid_user = 0;
   78|       |
   79|     34|	TRACE(("enter recv_msg_userauth_request"))
   80|       |
   81|       |	/* for compensating failure delay */
   82|     34|	gettime_wrapper(&ses.authstate.auth_starttime);
   83|       |
   84|       |	/* ignore packets if auth is already done */
   85|     34|	if (ses.authstate.authdone == 1) {
  ------------------
  |  Branch (85:6): [True: 34, False: 0]
  ------------------
   86|     34|		TRACE(("leave recv_msg_userauth_request: authdone already"))
   87|     34|		return;
   88|     34|	}
   89|       |
   90|       |	/* send the banner if it exists, it will only exist once */
   91|      0|	if (svr_opts.banner) {
  ------------------
  |  Branch (91:6): [True: 0, False: 0]
  ------------------
   92|      0|		send_msg_userauth_banner(svr_opts.banner);
   93|      0|		buf_free(svr_opts.banner);
   94|      0|		svr_opts.banner = NULL;
   95|      0|	}
   96|       |
   97|      0|	username = buf_getstring(ses.payload, &userlen);
   98|      0|	servicename = buf_getstring(ses.payload, &servicelen);
   99|      0|	methodname = buf_getstring(ses.payload, &methodlen);
  100|       |
  101|       |	/* only handle 'ssh-connection' currently */
  102|      0|	if (!(servicelen == SSH_SERVICE_CONNECTION_LEN
  ------------------
  |  |  111|      0|#define SSH_SERVICE_CONNECTION_LEN 14
  ------------------
  |  Branch (102:8): [True: 0, False: 0]
  ------------------
  103|      0|			&& (strncmp(servicename, SSH_SERVICE_CONNECTION,
  ------------------
  |  |  110|      0|#define SSH_SERVICE_CONNECTION "ssh-connection"
  ------------------
  |  Branch (103:7): [True: 0, False: 0]
  ------------------
  104|      0|					SSH_SERVICE_CONNECTION_LEN) == 0))) {
  ------------------
  |  |  111|      0|#define SSH_SERVICE_CONNECTION_LEN 14
  ------------------
  105|      0|		m_free(username);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  106|      0|		m_free(servicename);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  107|      0|		m_free(methodname);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  108|      0|		dropbear_exit("unknown service in auth");
  109|      0|	}
  110|       |
  111|       |	/* check username is good before continuing. 
  112|       |	 * the 'incrfail' varies depending on the auth method to
  113|       |	 * avoid giving away which users exist on the system through
  114|       |	 * the time delay. */
  115|      0|	if (checkusername(username, userlen) == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (115:6): [True: 0, False: 0]
  ------------------
  116|      0|		valid_user = 1;
  117|      0|	}
  118|       |
  119|       |	/* user wants to know what methods are supported */
  120|      0|	if (methodlen == AUTH_METHOD_NONE_LEN &&
  ------------------
  |  |  108|      0|#define AUTH_METHOD_NONE_LEN 4
  ------------------
  |  Branch (120:6): [True: 0, False: 0]
  ------------------
  121|      0|			strncmp(methodname, AUTH_METHOD_NONE,
  ------------------
  |  |  107|      0|#define AUTH_METHOD_NONE "none"
  ------------------
  |  Branch (121:4): [True: 0, False: 0]
  ------------------
  122|      0|				AUTH_METHOD_NONE_LEN) == 0) {
  ------------------
  |  |  108|      0|#define AUTH_METHOD_NONE_LEN 4
  ------------------
  123|      0|		TRACE(("recv_msg_userauth_request: 'none' request"))
  124|      0|		if (valid_user
  ------------------
  |  Branch (124:7): [True: 0, False: 0]
  ------------------
  125|      0|				&& svr_opts.allowblankpass
  ------------------
  |  Branch (125:8): [True: 0, False: 0]
  ------------------
  126|      0|				&& !svr_opts.noauthpass
  ------------------
  |  Branch (126:8): [True: 0, False: 0]
  ------------------
  127|      0|				&& !(svr_opts.norootpass && ses.authstate.pw_uid == 0) 
  ------------------
  |  Branch (127:10): [True: 0, False: 0]
  |  Branch (127:33): [True: 0, False: 0]
  ------------------
  128|      0|				&& ses.authstate.pw_passwd[0] == '\0') 
  ------------------
  |  Branch (128:8): [True: 0, False: 0]
  ------------------
  129|      0|		{
  130|      0|			dropbear_log(LOG_NOTICE, 
  131|      0|					"Auth succeeded with blank password for '%s' from %s",
  132|      0|					ses.authstate.pw_name,
  133|      0|					svr_ses.addrstring);
  134|      0|			send_msg_userauth_success();
  135|      0|			goto out;
  136|      0|		}
  137|      0|		else
  138|      0|		{
  139|       |			/* 'none' has no failure delay */
  140|      0|			send_msg_userauth_failure(0, 0);
  141|      0|			goto out;
  142|      0|		}
  143|      0|	}
  144|       |	
  145|      0|#if DROPBEAR_SVR_PASSWORD_AUTH
  146|      0|	if (!svr_opts.noauthpass &&
  ------------------
  |  Branch (146:6): [True: 0, False: 0]
  ------------------
  147|      0|			!(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) {
  ------------------
  |  Branch (147:6): [True: 0, False: 0]
  |  Branch (147:29): [True: 0, False: 0]
  ------------------
  148|       |		/* user wants to try password auth */
  149|      0|		if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
  ------------------
  |  |  112|      0|#define AUTH_METHOD_PASSWORD_LEN 8
  ------------------
  |  Branch (149:7): [True: 0, False: 0]
  ------------------
  150|      0|				strncmp(methodname, AUTH_METHOD_PASSWORD,
  ------------------
  |  |  111|      0|#define AUTH_METHOD_PASSWORD "password"
  ------------------
  |  Branch (150:5): [True: 0, False: 0]
  ------------------
  151|      0|					AUTH_METHOD_PASSWORD_LEN) == 0) {
  ------------------
  |  |  112|      0|#define AUTH_METHOD_PASSWORD_LEN 8
  ------------------
  152|      0|			svr_auth_password(valid_user);
  153|      0|			goto out;
  154|      0|		}
  155|      0|	}
  156|      0|#endif
  157|       |
  158|       |#if DROPBEAR_SVR_PAM_AUTH
  159|       |	if (!svr_opts.noauthpass &&
  160|       |			!(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) {
  161|       |		/* user wants to try password auth */
  162|       |		if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
  163|       |				strncmp(methodname, AUTH_METHOD_PASSWORD,
  164|       |					AUTH_METHOD_PASSWORD_LEN) == 0) {
  165|       |			svr_auth_pam(valid_user);
  166|       |			goto out;
  167|       |		}
  168|       |	}
  169|       |#endif
  170|       |
  171|      0|#if DROPBEAR_SVR_PUBKEY_AUTH
  172|       |	/* user wants to try pubkey auth */
  173|      0|	if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
  ------------------
  |  |  110|      0|#define AUTH_METHOD_PUBKEY_LEN 9
  ------------------
  |  Branch (173:6): [True: 0, False: 0]
  ------------------
  174|      0|			strncmp(methodname, AUTH_METHOD_PUBKEY,
  ------------------
  |  |  109|      0|#define AUTH_METHOD_PUBKEY "publickey"
  ------------------
  |  Branch (174:4): [True: 0, False: 0]
  ------------------
  175|      0|				AUTH_METHOD_PUBKEY_LEN) == 0) {
  ------------------
  |  |  110|      0|#define AUTH_METHOD_PUBKEY_LEN 9
  ------------------
  176|      0|		svr_auth_pubkey(valid_user);
  177|      0|		goto out;
  178|      0|	}
  179|      0|#endif
  180|       |
  181|       |	/* nothing matched, we just fail with a delay */
  182|      0|	send_msg_userauth_failure(0, 1);
  183|       |
  184|      0|out:
  185|       |
  186|      0|	m_free(username);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  187|      0|	m_free(servicename);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  188|       |	m_free(methodname);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  189|      0|}
svr_raise_gid_utmp:
  548|     10|void svr_raise_gid_utmp(void) {
  549|     10|#if DROPBEAR_SVR_DROP_PRIVS
  550|     10|	if (!svr_ses.have_utmp_gid) {
  ------------------
  |  Branch (550:6): [True: 10, False: 0]
  ------------------
  551|     10|		return;
  552|     10|	}
  553|       |
  554|      0|	if (setegid(svr_ses.utmp_gid) != 0) {
  ------------------
  |  Branch (554:6): [True: 0, False: 0]
  ------------------
  555|       |		dropbear_log(LOG_WARNING, "failed setegid");
  556|      0|	}
  557|      0|#endif
  558|      0|}
svr_restore_gid:
  560|     10|void svr_restore_gid(void) {
  561|     10|#if DROPBEAR_SVR_DROP_PRIVS
  562|     10|	if (!svr_ses.have_utmp_gid) {
  ------------------
  |  Branch (562:6): [True: 10, False: 0]
  ------------------
  563|     10|		return;
  564|     10|	}
  565|       |
  566|      0|	if (setegid(getgid()) != 0) {
  ------------------
  |  Branch (566:6): [True: 0, False: 0]
  ------------------
  567|       |		dropbear_log(LOG_WARNING, "failed setegid");
  568|      0|	}
  569|      0|#endif
  570|      0|}

svr_pubkey_allows_agentfwd:
   55|    384|int svr_pubkey_allows_agentfwd() {
   56|    384|	if (ses.authstate.pubkey_options 
  ------------------
  |  Branch (56:6): [True: 0, False: 384]
  ------------------
   57|      0|		&& ses.authstate.pubkey_options->no_agent_forwarding_flag) {
  ------------------
  |  Branch (57:6): [True: 0, False: 0]
  ------------------
   58|      0|		return 0;
   59|      0|	}
   60|    384|	return 1;
   61|    384|}
svr_pubkey_allows_tcpfwd:
   65|  1.85k|int svr_pubkey_allows_tcpfwd() {
   66|  1.85k|	if (ses.authstate.pubkey_options 
  ------------------
  |  Branch (66:6): [True: 0, False: 1.85k]
  ------------------
   67|      0|		&& ses.authstate.pubkey_options->no_port_forwarding_flag) {
  ------------------
  |  Branch (67:6): [True: 0, False: 0]
  ------------------
   68|      0|		return 0;
   69|      0|	}
   70|  1.85k|	return 1;
   71|  1.85k|}
svr_pubkey_has_forced_command:
   74|  1.08k|int svr_pubkey_has_forced_command(void) {
   75|  1.08k|	return ses.authstate.pubkey_options
  ------------------
  |  Branch (75:9): [True: 0, False: 1.08k]
  ------------------
   76|      0|		&& ses.authstate.pubkey_options->forced_command;
  ------------------
  |  Branch (76:6): [True: 0, False: 0]
  ------------------
   77|  1.08k|}
svr_pubkey_allows_pty:
   90|    108|int svr_pubkey_allows_pty() {
   91|    108|	if (ses.authstate.pubkey_options 
  ------------------
  |  Branch (91:6): [True: 0, False: 108]
  ------------------
   92|      0|		&& ses.authstate.pubkey_options->no_pty_flag) {
  ------------------
  |  Branch (92:6): [True: 0, False: 0]
  ------------------
   93|      0|		return 0;
   94|      0|	}
   95|    108|	return 1;
   96|    108|}
svr_pubkey_allows_local_tcpfwd:
  100|     89|int svr_pubkey_allows_local_tcpfwd(const char *host, unsigned int port) {
  101|     89|	if (ses.authstate.pubkey_options
  ------------------
  |  Branch (101:6): [True: 0, False: 89]
  ------------------
  102|      0|		&& ses.authstate.pubkey_options->permit_open_destinations) {
  ------------------
  |  Branch (102:6): [True: 0, False: 0]
  ------------------
  103|      0|		m_list_elem *iter = ses.authstate.pubkey_options->permit_open_destinations->first;
  104|      0|		while (iter) {
  ------------------
  |  Branch (104:10): [True: 0, False: 0]
  ------------------
  105|      0|			struct PermitTCPFwdEntry *entry = (struct PermitTCPFwdEntry*)iter->item;
  106|      0|			if (strcmp(entry->host, host) == 0) {
  ------------------
  |  Branch (106:8): [True: 0, False: 0]
  ------------------
  107|      0|				if ((entry->port == PUBKEY_OPTIONS_ANY_PORT) || (entry->port == port)) {
  ------------------
  |  |  116|      0|#define PUBKEY_OPTIONS_ANY_PORT UINT_MAX
  ------------------
  |  Branch (107:9): [True: 0, False: 0]
  |  Branch (107:53): [True: 0, False: 0]
  ------------------
  108|      0|					return 1;
  109|      0|				}
  110|      0|			}
  111|       |
  112|      0|			iter = iter->next;
  113|      0|		}
  114|       |
  115|      0|		return 0;
  116|      0|	}
  117|       |
  118|     89|	return 1;
  119|     89|}
svr_pubkey_allows_remote_tcpfwd:
  123|    209|int svr_pubkey_allows_remote_tcpfwd(const char *host, unsigned int port) {
  124|       |	/* no host restrictions */
  125|    209|	(void)host;
  126|       |
  127|    209|	if (ses.authstate.pubkey_options
  ------------------
  |  Branch (127:6): [True: 0, False: 209]
  ------------------
  128|      0|		&& ses.authstate.pubkey_options->permit_listens) {
  ------------------
  |  Branch (128:6): [True: 0, False: 0]
  ------------------
  129|      0|		m_list_elem *iter = ses.authstate.pubkey_options->permit_listens->first;
  130|      0|		while (iter) {
  ------------------
  |  Branch (130:10): [True: 0, False: 0]
  ------------------
  131|      0|			struct PermitTCPFwdEntry *entry = (struct PermitTCPFwdEntry*)iter->item;
  132|      0|			if (entry->port == port) {
  ------------------
  |  Branch (132:8): [True: 0, False: 0]
  ------------------
  133|      0|				return 1;
  134|      0|			}
  135|       |
  136|      0|			iter = iter->next;
  137|      0|		}
  138|       |
  139|      0|		return 0;
  140|      0|	}
  141|       |
  142|    209|	return 1;
  143|    209|}
svr_pubkey_set_forced_command:
  147|  1.09k|void svr_pubkey_set_forced_command(struct ChanSess *chansess) {
  148|  1.09k|	if (ses.authstate.pubkey_options && ses.authstate.pubkey_options->forced_command) {
  ------------------
  |  Branch (148:6): [True: 0, False: 1.09k]
  |  Branch (148:38): [True: 0, False: 0]
  ------------------
  149|      0|		TRACE(("Forced command '%s'", ses.authstate.pubkey_options->forced_command))
  150|      0|		if (chansess->cmd) {
  ------------------
  |  Branch (150:7): [True: 0, False: 0]
  ------------------
  151|       |			/* original_command takes ownership */
  152|      0|			chansess->original_command = chansess->cmd;
  153|      0|			chansess->cmd = NULL;
  154|      0|		} else {
  155|      0|			chansess->original_command = m_strdup("");
  156|      0|		}
  157|      0|		chansess->cmd = m_strdup(ses.authstate.pubkey_options->forced_command);
  158|       |#if LOG_COMMANDS
  159|       |		dropbear_log(LOG_INFO, "Command forced to '%s'", chansess->original_command);
  160|       |#endif
  161|      0|	}
  162|  1.09k|}
svr_pubkey_options_cleanup:
  165|  4.58k|void svr_pubkey_options_cleanup(struct PubKeyOptions *pubkey_options) {
  166|  4.58k|	if (pubkey_options) {
  ------------------
  |  Branch (166:6): [True: 0, False: 4.58k]
  ------------------
  167|      0|		m_free(pubkey_options->forced_command);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  168|      0|		if (pubkey_options->permit_open_destinations) {
  ------------------
  |  Branch (168:7): [True: 0, False: 0]
  ------------------
  169|      0|			m_list_elem *iter = pubkey_options->permit_open_destinations->first;
  170|      0|			while (iter) {
  ------------------
  |  Branch (170:11): [True: 0, False: 0]
  ------------------
  171|      0|				struct PermitTCPFwdEntry *entry = (struct PermitTCPFwdEntry*)list_remove(iter);
  172|      0|				m_free(entry->host);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  173|      0|				m_free(entry);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  174|      0|				iter = pubkey_options->permit_open_destinations->first;
  175|      0|			}
  176|      0|			m_free(pubkey_options->permit_open_destinations);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  177|      0|		}
  178|      0|		if (pubkey_options->permit_listens) {
  ------------------
  |  Branch (178:7): [True: 0, False: 0]
  ------------------
  179|      0|			m_list_elem *iter = pubkey_options->permit_listens->first;
  180|      0|			while (iter) {
  ------------------
  |  Branch (180:11): [True: 0, False: 0]
  ------------------
  181|      0|				struct PermitTCPFwdEntry *entry = (struct PermitTCPFwdEntry*)list_remove(iter);
  182|      0|				m_free(entry->host);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  183|      0|				m_free(entry);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  184|      0|				iter = pubkey_options->permit_listens->first;
  185|      0|			}
  186|      0|			m_free(pubkey_options->permit_listens);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  187|      0|		}
  188|      0|		m_free(pubkey_options->info_env);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  189|       |		m_free(pubkey_options);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  190|      0|	}
  191|  4.58k|}

svr_chansess_checksignal:
   95|   298k|void svr_chansess_checksignal(void) {
   96|   298k|	int status;
   97|   298k|	pid_t pid;
   98|       |
   99|   298k|	if (!ses.channel_signal_pending) {
  ------------------
  |  Branch (99:6): [True: 298k, False: 0]
  ------------------
  100|   298k|		return;
  101|   298k|	}
  102|       |
  103|      0|	while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
  ------------------
  |  Branch (103:9): [True: 0, False: 0]
  ------------------
  104|      0|		unsigned int i;
  105|      0|		struct exitinfo *ex = NULL;
  106|      0|		TRACE(("svr_chansess_checksignal : pid %d", pid))
  107|       |
  108|      0|		ex = NULL;
  109|       |		/* find the corresponding chansess */
  110|      0|		for (i = 0; i < svr_ses.childpidsize; i++) {
  ------------------
  |  Branch (110:15): [True: 0, False: 0]
  ------------------
  111|      0|			if (svr_ses.childpids[i].pid == pid) {
  ------------------
  |  Branch (111:8): [True: 0, False: 0]
  ------------------
  112|      0|				TRACE(("found match session"));
  113|      0|				ex = &svr_ses.childpids[i].chansess->exit;
  114|      0|				break;
  115|      0|			}
  116|      0|		}
  117|       |
  118|       |		/* If the pid wasn't matched, then we might have hit the race mentioned
  119|       |		 * above. So we just store the info for the parent to deal with */
  120|      0|		if (ex == NULL) {
  ------------------
  |  Branch (120:7): [True: 0, False: 0]
  ------------------
  121|      0|			TRACE(("using lastexit"));
  122|      0|			ex = &svr_ses.lastexit;
  123|      0|		}
  124|       |
  125|      0|		ex->exitpid = pid;
  126|      0|		if (WIFEXITED(status)) {
  ------------------
  |  Branch (126:7): [True: 0, False: 0]
  ------------------
  127|      0|			ex->exitstatus = WEXITSTATUS(status);
  128|      0|		}
  129|      0|		if (WIFSIGNALED(status)) {
  ------------------
  |  Branch (129:7): [True: 0, False: 0]
  ------------------
  130|      0|			ex->exitsignal = WTERMSIG(status);
  131|      0|#if !defined(AIX) && defined(WCOREDUMP)
  132|      0|			ex->exitcore = WCOREDUMP(status);
  133|       |#else
  134|       |			ex->exitcore = 0;
  135|       |#endif
  136|      0|		} else {
  137|       |			/* we use this to determine how pid exited */
  138|      0|			ex->exitsignal = -1;
  139|      0|		}
  140|      0|	}
  141|      0|}
svr_chansessinitialise:
 1073|  4.58k|void svr_chansessinitialise() {
 1074|       |
 1075|  4.58k|	struct sigaction sa_chld;
 1076|       |
 1077|       |	/* single child process intially */
 1078|  4.58k|	svr_ses.childpids = (struct ChildPid*)m_malloc(sizeof(struct ChildPid));
 1079|  4.58k|	svr_ses.childpids[0].pid = -1; /* unused */
 1080|  4.58k|	svr_ses.childpids[0].chansess = NULL;
 1081|  4.58k|	svr_ses.childpidsize = 1;
 1082|  4.58k|	svr_ses.lastexit.exitpid = -1; /* Nothing has exited yet */
 1083|  4.58k|	sa_chld.sa_handler = sesssigchild_handler;
 1084|  4.58k|	sa_chld.sa_flags = SA_NOCLDSTOP;
 1085|  4.58k|	sigemptyset(&sa_chld.sa_mask);
 1086|  4.58k|	if (sigaction(SIGCHLD, &sa_chld, NULL) < 0) {
  ------------------
  |  Branch (1086:6): [True: 0, False: 4.58k]
  ------------------
 1087|      0|		dropbear_exit("signal() error");
 1088|      0|	}
 1089|       |	
 1090|  4.58k|}
svr-chansession.c:sesscheckclose:
   77|  55.0k|static int sesscheckclose(struct Channel *channel) {
   78|  55.0k|	struct ChanSess *chansess = (struct ChanSess*)channel->typedata;
   79|  55.0k|	TRACE(("sesscheckclose, pid %d, exitpid %d", chansess->pid, chansess->exit.exitpid))
   80|       |
   81|  55.0k|	if (chansess->exit.exitpid != -1) {
  ------------------
  |  Branch (81:6): [True: 0, False: 55.0k]
  ------------------
   82|      0|		channel->flushing = 1;
   83|      0|	}
   84|  55.0k|	return chansess->pid == 0 || chansess->exit.exitpid != -1;
  ------------------
  |  Branch (84:9): [True: 472, False: 54.6k]
  |  Branch (84:31): [True: 0, False: 54.6k]
  ------------------
   85|  55.0k|}
svr-chansession.c:newchansess:
  238|  3.42k|static int newchansess(struct Channel *channel) {
  239|       |
  240|  3.42k|	struct ChanSess *chansess;
  241|       |
  242|  3.42k|	TRACE(("new chansess %p", (void*)channel))
  243|       |
  244|  3.42k|	dropbear_assert(channel->typedata == NULL);
  ------------------
  |  |   84|  3.42k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 3.42k]
  |  |  |  Branch (84:93): [Folded, False: 3.42k]
  |  |  ------------------
  ------------------
  245|       |
  246|  3.42k|	chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess));
  247|  3.42k|	chansess->cmd = NULL;
  248|  3.42k|	chansess->connection_string = NULL;
  249|  3.42k|	chansess->client_string = NULL;
  250|  3.42k|	chansess->pid = 0;
  251|       |
  252|       |	/* pty details */
  253|  3.42k|	chansess->master = -1;
  254|  3.42k|	chansess->slave = -1;
  255|  3.42k|	chansess->tty = NULL;
  256|  3.42k|	chansess->term = NULL;
  257|       |
  258|  3.42k|	chansess->exit.exitpid = -1;
  259|       |
  260|  3.42k|	channel->typedata = chansess;
  261|       |
  262|       |#if DROPBEAR_X11FWD
  263|       |	chansess->x11listener = NULL;
  264|       |	chansess->x11authprot = NULL;
  265|       |	chansess->x11authcookie = NULL;
  266|       |#endif
  267|       |
  268|  3.42k|#if DROPBEAR_SVR_AGENTFWD
  269|  3.42k|	chansess->agentlistener = NULL;
  270|  3.42k|	chansess->agentfile = NULL;
  271|  3.42k|	chansess->agentdir = NULL;
  272|  3.42k|#endif
  273|       |
  274|       |	/* Will drop to DROPBEAR_PRIO_NORMAL if a non-tty command starts */
  275|  3.42k|	channel->prio = DROPBEAR_PRIO_LOWDELAY;
  276|       |
  277|  3.42k|	return 0;
  278|       |
  279|  3.42k|}
svr-chansession.c:closechansess:
  290|    472|static void closechansess(const struct Channel *channel) {
  291|    472|	struct ChanSess *chansess;
  292|       |
  293|    472|	TRACE(("enter closechansess"))
  294|       |
  295|    472|	chansess = (struct ChanSess*)channel->typedata;
  296|       |
  297|    472|	if (chansess == NULL) {
  ------------------
  |  Branch (297:6): [True: 0, False: 472]
  ------------------
  298|      0|		TRACE(("leave closechansess: chansess == NULL"))
  299|      0|		return;
  300|      0|	}
  301|       |
  302|    472|	send_exitsignalstatus(channel);
  303|    472|	TRACE(("leave closechansess"))
  304|    472|}
svr-chansession.c:send_exitsignalstatus:
  167|    472|static void send_exitsignalstatus(const struct Channel *channel) {
  168|       |
  169|    472|	struct ChanSess *chansess = (struct ChanSess*)channel->typedata;
  170|       |
  171|    472|	if (chansess->exit.exitpid >= 0) {
  ------------------
  |  Branch (171:6): [True: 0, False: 472]
  ------------------
  172|      0|		if (chansess->exit.exitsignal > 0) {
  ------------------
  |  Branch (172:7): [True: 0, False: 0]
  ------------------
  173|      0|			send_msg_chansess_exitsignal(channel, chansess);
  174|      0|		} else {
  175|      0|			send_msg_chansess_exitstatus(channel, chansess);
  176|      0|		}
  177|      0|	}
  178|    472|}
svr-chansession.c:cleanupchansess:
  307|  3.42k|static void cleanupchansess(const struct Channel *channel) {
  308|       |
  309|  3.42k|	struct ChanSess *chansess;
  310|  3.42k|	unsigned int i;
  311|  3.42k|	struct logininfo *li;
  312|       |
  313|  3.42k|	TRACE(("enter closechansess"))
  314|       |
  315|  3.42k|	chansess = (struct ChanSess*)channel->typedata;
  316|       |
  317|  3.42k|	if (chansess == NULL) {
  ------------------
  |  Branch (317:6): [True: 0, False: 3.42k]
  ------------------
  318|      0|		TRACE(("leave closechansess: chansess == NULL"))
  319|      0|		return;
  320|      0|	}
  321|       |
  322|  3.42k|	m_free(chansess->cmd);
  ------------------
  |  |   24|  3.42k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 3.42k]
  |  |  ------------------
  ------------------
  323|  3.42k|	m_free(chansess->term);
  ------------------
  |  |   24|  3.42k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 3.42k]
  |  |  ------------------
  ------------------
  324|  3.42k|	m_free(chansess->original_command);
  ------------------
  |  |   24|  3.42k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 3.42k]
  |  |  ------------------
  ------------------
  325|       |
  326|  3.42k|	if (chansess->tty) {
  ------------------
  |  Branch (326:6): [True: 10, False: 3.41k]
  ------------------
  327|       |		/* write the utmp/wtmp login record */
  328|     10|		li = chansess_login_alloc(chansess);
  329|       |
  330|     10|		svr_raise_gid_utmp();
  331|     10|		login_logout(li);
  332|     10|		svr_restore_gid();
  333|       |
  334|     10|		login_free_entry(li);
  335|       |
  336|     10|		pty_release(chansess->tty);
  337|     10|		m_free(chansess->tty);
  ------------------
  |  |   24|     10|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 10]
  |  |  ------------------
  ------------------
  338|     10|	}
  339|       |
  340|       |#if DROPBEAR_X11FWD
  341|       |	x11cleanup(chansess);
  342|       |#endif
  343|       |
  344|  3.42k|#if DROPBEAR_SVR_AGENTFWD
  345|  3.42k|	svr_agentcleanup(chansess);
  346|  3.42k|#endif
  347|       |
  348|       |	/* clear child pid entries */
  349|  8.96k|	for (i = 0; i < svr_ses.childpidsize; i++) {
  ------------------
  |  Branch (349:14): [True: 5.54k, False: 3.42k]
  ------------------
  350|  5.54k|		if (svr_ses.childpids[i].chansess == chansess) {
  ------------------
  |  Branch (350:7): [True: 1.02k, False: 4.52k]
  ------------------
  351|  1.02k|			dropbear_assert(svr_ses.childpids[i].pid > 0);
  ------------------
  |  |   84|  1.02k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 1.02k]
  |  |  |  Branch (84:93): [Folded, False: 1.02k]
  |  |  ------------------
  ------------------
  352|  1.02k|			TRACE(("closing pid %d", svr_ses.childpids[i].pid))
  353|  1.02k|			TRACE(("exitpid is %d", chansess->exit.exitpid))
  354|  1.02k|			svr_ses.childpids[i].pid = -1;
  355|  1.02k|			svr_ses.childpids[i].chansess = NULL;
  356|  1.02k|		}
  357|  5.54k|	}
  358|       |				
  359|  3.42k|	m_free(chansess);
  ------------------
  |  |   24|  3.42k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 3.42k]
  |  |  ------------------
  ------------------
  360|       |
  361|  3.42k|	TRACE(("leave closechansess"))
  362|  3.42k|}
svr-chansession.c:chansess_login_alloc:
  282|     10|chansess_login_alloc(const struct ChanSess *chansess) {
  283|     10|	struct logininfo * li;
  284|     10|	li = login_alloc_entry(chansess->pid, ses.authstate.username,
  285|     10|			svr_ses.remotehost, chansess->tty);
  286|     10|	return li;
  287|     10|}
svr-chansession.c:chansessionrequest:
  366|  4.72k|static void chansessionrequest(struct Channel *channel) {
  367|       |
  368|  4.72k|	char * type = NULL;
  369|  4.72k|	unsigned int typelen;
  370|  4.72k|	unsigned char wantreply;
  371|  4.72k|	int ret = 1;
  372|  4.72k|	struct ChanSess *chansess;
  373|       |
  374|  4.72k|	TRACE(("enter chansessionrequest"))
  375|       |
  376|  4.72k|	type = buf_getstring(ses.payload, &typelen);
  377|  4.72k|	wantreply = buf_getbool(ses.payload);
  378|       |
  379|  4.72k|	if (typelen > MAX_NAME_LEN) {
  ------------------
  |  |  233|  4.72k|#define MAX_NAME_LEN 64 /* maximum length of a protocol name, isn't
  ------------------
  |  Branch (379:6): [True: 26, False: 4.70k]
  ------------------
  380|     26|		TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/
  381|     26|		goto out;
  382|     26|	}
  383|       |
  384|  4.70k|	chansess = (struct ChanSess*)channel->typedata;
  385|  4.70k|	dropbear_assert(chansess != NULL);
  ------------------
  |  |   84|  4.70k|#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
  |  |  ------------------
  |  |  |  Branch (84:37): [True: 0, False: 4.70k]
  |  |  |  Branch (84:93): [Folded, False: 4.70k]
  |  |  ------------------
  ------------------
  386|  4.70k|	TRACE(("type is %s", type))
  387|       |
  388|  4.70k|	if (strcmp(type, "window-change") == 0) {
  ------------------
  |  Branch (388:6): [True: 249, False: 4.45k]
  ------------------
  389|    249|		ret = sessionwinchange(chansess);
  390|  4.45k|	} else if (strcmp(type, "shell") == 0) {
  ------------------
  |  Branch (390:13): [True: 945, False: 3.50k]
  ------------------
  391|    945|		ret = sessioncommand(channel, chansess, 0, 0);
  392|  3.50k|	} else if (strcmp(type, "pty-req") == 0) {
  ------------------
  |  Branch (392:13): [True: 108, False: 3.40k]
  ------------------
  393|    108|		ret = sessionpty(chansess);
  394|  3.40k|	} else if (strcmp(type, "exec") == 0) {
  ------------------
  |  Branch (394:13): [True: 767, False: 2.63k]
  ------------------
  395|    767|		ret = sessioncommand(channel, chansess, 1, 0);
  396|  2.63k|	} else if (strcmp(type, "subsystem") == 0) {
  ------------------
  |  Branch (396:13): [True: 144, False: 2.48k]
  ------------------
  397|    144|		ret = sessioncommand(channel, chansess, 1, 1);
  398|       |#if DROPBEAR_X11FWD
  399|       |	} else if (strcmp(type, "x11-req") == 0) {
  400|       |		ret = x11req(chansess);
  401|       |#endif
  402|    144|#if DROPBEAR_SVR_AGENTFWD
  403|  2.48k|	} else if (strcmp(type, "auth-agent-req@openssh.com") == 0) {
  ------------------
  |  Branch (403:13): [True: 384, False: 2.10k]
  ------------------
  404|    384|		ret = svr_agentreq(chansess);
  405|    384|#endif
  406|  2.10k|	} else if (strcmp(type, "signal") == 0) {
  ------------------
  |  Branch (406:13): [True: 1.15k, False: 948]
  ------------------
  407|  1.15k|		ret = sessionsignal(chansess);
  408|  1.15k|	} else {
  409|       |		/* etc, todo "env", "subsystem" */
  410|    948|	}
  411|       |
  412|  4.70k|out:
  413|       |
  414|  4.70k|	if (wantreply) {
  ------------------
  |  Branch (414:6): [True: 4.08k, False: 619]
  ------------------
  415|  4.08k|		if (ret == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|  4.08k|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (415:7): [True: 1.32k, False: 2.76k]
  ------------------
  416|  1.32k|			send_msg_channel_success(channel);
  417|  2.76k|		} else {
  418|  2.76k|			send_msg_channel_failure(channel);
  419|  2.76k|		}
  420|  4.08k|	}
  421|       |
  422|       |	m_free(type);
  ------------------
  |  |   24|  4.70k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.70k]
  |  |  ------------------
  ------------------
  423|  4.70k|	TRACE(("leave chansessionrequest"))
  424|  4.70k|}
svr-chansession.c:sessionwinchange:
  478|    259|static int sessionwinchange(const struct ChanSess *chansess) {
  479|       |
  480|    259|	int termc, termr, termw, termh;
  481|       |
  482|    259|	if (chansess->master < 0) {
  ------------------
  |  Branch (482:6): [True: 249, False: 10]
  ------------------
  483|       |		/* haven't got a pty yet */
  484|    249|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|    249|#define DROPBEAR_FAILURE -1
  ------------------
  485|    249|	}
  486|       |			
  487|     10|	termc = buf_getint(ses.payload);
  488|     10|	termr = buf_getint(ses.payload);
  489|     10|	termw = buf_getint(ses.payload);
  490|     10|	termh = buf_getint(ses.payload);
  491|       |	
  492|     10|	pty_change_window_size(chansess->master, termr, termc, termw, termh);
  493|       |
  494|     10|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|     10|#define DROPBEAR_SUCCESS 0
  ------------------
  495|    259|}
svr-chansession.c:sessioncommand:
  669|  1.85k|		int iscmd, int issubsys) {
  670|       |
  671|  1.85k|	unsigned int cmdlen = 0;
  672|  1.85k|	int ret;
  673|       |
  674|  1.85k|	TRACE(("enter sessioncommand %d", channel->index))
  675|       |
  676|  1.85k|	if (chansess->pid != 0) {
  ------------------
  |  Branch (676:6): [True: 618, False: 1.23k]
  ------------------
  677|       |		/* Note that only one command can _succeed_. The client might try
  678|       |		 * one command (which fails), then try another. Ie fallback
  679|       |		 * from sftp to scp */
  680|    618|		TRACE(("leave sessioncommand, already have a command"))
  681|    618|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|    618|#define DROPBEAR_FAILURE -1
  ------------------
  682|    618|	}
  683|       |
  684|  1.23k|	if (iscmd) {
  ------------------
  |  Branch (684:6): [True: 692, False: 546]
  ------------------
  685|       |		/* "exec" */
  686|    692|		if (chansess->cmd == NULL) {
  ------------------
  |  Branch (686:7): [True: 692, False: 0]
  ------------------
  687|    692|			chansess->cmd = buf_getstring(ses.payload, &cmdlen);
  688|       |
  689|    692|			if (cmdlen > MAX_CMD_LEN) {
  ------------------
  |  |   84|    692|#define MAX_CMD_LEN 9000 /* max length of a command */
  ------------------
  |  Branch (689:8): [True: 0, False: 692]
  ------------------
  690|      0|				m_free(chansess->cmd);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  691|       |				/* TODO - send error - too long ? */
  692|      0|				TRACE(("leave sessioncommand, command too long %d", cmdlen))
  693|      0|				return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  694|      0|			}
  695|    692|		}
  696|    692|		if (issubsys) {
  ------------------
  |  Branch (696:7): [True: 144, False: 548]
  ------------------
  697|    144|#if DROPBEAR_SFTPSERVER
  698|    144|			if ((cmdlen == 4) && strncmp(chansess->cmd, "sftp", 4) == 0) {
  ------------------
  |  Branch (698:8): [True: 103, False: 41]
  |  Branch (698:25): [True: 2, False: 101]
  ------------------
  699|      2|				char *expand_path = expand_homedir_path(SFTPSERVER_PATH);
  ------------------
  |  |  526|      2|#define SFTPSERVER_PATH "/usr/libexec/sftp-server"
  ------------------
  700|      2|				m_free(chansess->cmd);
  ------------------
  |  |   24|      2|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 2]
  |  |  ------------------
  ------------------
  701|      2|				chansess->cmd = m_strdup(expand_path);
  702|      2|				m_free(expand_path);
  ------------------
  |  |   24|      2|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 2]
  |  |  ------------------
  ------------------
  703|      2|			} else 
  704|    142|#endif
  705|    142|			{
  706|    142|				m_free(chansess->cmd);
  ------------------
  |  |   24|    142|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 142]
  |  |  ------------------
  ------------------
  707|    142|				TRACE(("leave sessioncommand, unknown subsystem"))
  708|    142|				return DROPBEAR_FAILURE;
  ------------------
  |  |  112|    142|#define DROPBEAR_FAILURE -1
  ------------------
  709|    142|			}
  710|    144|		}
  711|    692|	}
  712|       |	
  713|       |
  714|       |	/* take global command into account */
  715|  1.09k|	if (svr_opts.forced_command) {
  ------------------
  |  Branch (715:6): [True: 0, False: 1.09k]
  ------------------
  716|      0|		if (chansess->cmd) {
  ------------------
  |  Branch (716:7): [True: 0, False: 0]
  ------------------
  717|      0|			chansess->original_command = chansess->cmd;
  718|      0|		} else {
  719|      0|			chansess->original_command = m_strdup("");
  720|      0|		}
  721|      0|		chansess->cmd = m_strdup(svr_opts.forced_command);
  722|  1.09k|	} else {
  723|       |		/* take public key option 'command' into account */
  724|  1.09k|		svr_pubkey_set_forced_command(chansess);
  725|  1.09k|	}
  726|       |
  727|       |
  728|       |#if LOG_COMMANDS
  729|       |	if (chansess->cmd) {
  730|       |		dropbear_log(LOG_INFO, "User %s executing '%s'", 
  731|       |						ses.authstate.pw_name, chansess->cmd);
  732|       |	} else {
  733|       |		dropbear_log(LOG_INFO, "User %s executing login shell", 
  734|       |						ses.authstate.pw_name);
  735|       |	}
  736|       |#endif
  737|       |
  738|       |	/* uClinux will vfork(), so there'll be a race as 
  739|       |	connection_string is freed below. */
  740|  1.09k|#if !DROPBEAR_VFORK
  741|  1.09k|	make_connection_string(chansess);
  742|  1.09k|#endif
  743|       |
  744|  1.09k|	if (chansess->term == NULL) {
  ------------------
  |  Branch (744:6): [True: 1.02k, False: 72]
  ------------------
  745|       |		/* no pty */
  746|  1.02k|		ret = noptycommand(channel, chansess);
  747|  1.02k|		if (ret == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|  1.02k|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (747:7): [True: 1.02k, False: 0]
  ------------------
  748|  1.02k|			channel->prio = DROPBEAR_PRIO_NORMAL;
  749|  1.02k|			update_channel_prio();
  750|  1.02k|		}
  751|  1.02k|	} else {
  752|       |		/* want pty */
  753|     72|		ret = ptycommand(channel, chansess);
  754|     72|	}
  755|       |
  756|  1.09k|#if !DROPBEAR_VFORK
  757|  1.09k|	m_free(chansess->connection_string);
  ------------------
  |  |   24|  1.09k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1.09k]
  |  |  ------------------
  ------------------
  758|  1.09k|	m_free(chansess->client_string);
  ------------------
  |  |   24|  1.09k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1.09k]
  |  |  ------------------
  ------------------
  759|  1.09k|#endif
  760|       |
  761|  1.09k|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|  1.09k|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (761:6): [True: 72, False: 1.02k]
  ------------------
  762|       |		m_free(chansess->cmd);
  ------------------
  |  |   24|     72|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 72]
  |  |  ------------------
  ------------------
  763|     72|	}
  764|  1.09k|	TRACE(("leave sessioncommand, ret %d", ret))
  765|  1.09k|	return ret;
  766|  1.23k|}
svr-chansession.c:make_connection_string:
  641|  1.09k|static void make_connection_string(struct ChanSess *chansess) {
  642|  1.09k|	char *local_ip, *local_port, *remote_ip, *remote_port;
  643|  1.09k|	size_t len;
  644|  1.09k|	get_socket_address(ses.sock_in, &local_ip, &local_port, &remote_ip, &remote_port, 0);
  645|       |
  646|       |	/* "remoteip remoteport localip localport" */
  647|  1.09k|	len = strlen(local_ip) + strlen(remote_ip) + 20;
  648|  1.09k|	chansess->connection_string = m_malloc(len);
  649|  1.09k|	snprintf(chansess->connection_string, len, "%s %s %s %s", remote_ip, remote_port, local_ip, local_port);
  650|       |
  651|       |	/* deprecated but bash only loads .bashrc if SSH_CLIENT is set */ 
  652|       |	/* "remoteip remoteport localport" */
  653|  1.09k|	len = strlen(remote_ip) + 20;
  654|  1.09k|	chansess->client_string = m_malloc(len);
  655|  1.09k|	snprintf(chansess->client_string, len, "%s %s %s", remote_ip, remote_port, local_port);
  656|       |
  657|  1.09k|	m_free(local_ip);
  ------------------
  |  |   24|  1.09k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1.09k]
  |  |  ------------------
  ------------------
  658|  1.09k|	m_free(local_port);
  ------------------
  |  |   24|  1.09k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1.09k]
  |  |  ------------------
  ------------------
  659|  1.09k|	m_free(remote_ip);
  ------------------
  |  |   24|  1.09k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1.09k]
  |  |  ------------------
  ------------------
  660|       |	m_free(remote_port);
  ------------------
  |  |   24|  1.09k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1.09k]
  |  |  ------------------
  ------------------
  661|  1.09k|}
svr-chansession.c:noptycommand:
  771|  1.02k|static int noptycommand(struct Channel *channel, struct ChanSess *chansess) {
  772|  1.02k|	int ret;
  773|       |
  774|  1.02k|	TRACE(("enter noptycommand"))
  775|  1.02k|	ret = spawn_command(execchild, chansess, 
  776|  1.02k|			&channel->writefd, &channel->readfd, &channel->errfd,
  777|  1.02k|			&chansess->pid);
  778|       |
  779|  1.02k|	if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|  1.02k|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (779:6): [True: 0, False: 1.02k]
  ------------------
  780|      0|		return ret;
  781|      0|	}
  782|       |
  783|  1.02k|	ses.maxfd = MAX(ses.maxfd, channel->writefd);
  ------------------
  |  Branch (783:14): [True: 173, False: 851]
  ------------------
  784|  1.02k|	ses.maxfd = MAX(ses.maxfd, channel->readfd);
  ------------------
  |  Branch (784:14): [True: 166, False: 858]
  ------------------
  785|  1.02k|	ses.maxfd = MAX(ses.maxfd, channel->errfd);
  ------------------
  |  Branch (785:14): [True: 75, False: 949]
  ------------------
  786|  1.02k|	channel->bidir_fd = 0;
  787|       |
  788|  1.02k|	addchildpid(chansess, chansess->pid);
  789|       |
  790|  1.02k|	if (svr_ses.lastexit.exitpid != -1) {
  ------------------
  |  Branch (790:6): [True: 0, False: 1.02k]
  ------------------
  791|      0|		unsigned int i;
  792|      0|		TRACE(("parent side: lastexitpid is %d", svr_ses.lastexit.exitpid))
  793|       |		/* The child probably exited and the signal handler triggered
  794|       |		 * possibly before we got around to adding the childpid. So we fill
  795|       |		 * out its data manually */
  796|      0|		for (i = 0; i < svr_ses.childpidsize; i++) {
  ------------------
  |  Branch (796:15): [True: 0, False: 0]
  ------------------
  797|      0|			if (svr_ses.childpids[i].pid == svr_ses.lastexit.exitpid) {
  ------------------
  |  Branch (797:8): [True: 0, False: 0]
  ------------------
  798|      0|				TRACE(("found match for lastexitpid"))
  799|      0|				svr_ses.childpids[i].chansess->exit = svr_ses.lastexit;
  800|      0|				svr_ses.lastexit.exitpid = -1;
  801|      0|				break;
  802|      0|			}
  803|      0|		}
  804|      0|	}
  805|       |
  806|  1.02k|	TRACE(("leave noptycommand"))
  807|  1.02k|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|  1.02k|#define DROPBEAR_SUCCESS 0
  ------------------
  808|  1.02k|}
svr-chansession.c:addchildpid:
  941|  1.02k|static void addchildpid(struct ChanSess *chansess, pid_t pid) {
  942|       |
  943|  1.02k|	unsigned int i;
  944|  1.48k|	for (i = 0; i < svr_ses.childpidsize; i++) {
  ------------------
  |  Branch (944:14): [True: 1.22k, False: 259]
  ------------------
  945|  1.22k|		if (svr_ses.childpids[i].pid == -1) {
  ------------------
  |  Branch (945:7): [True: 765, False: 462]
  ------------------
  946|    765|			break;
  947|    765|		}
  948|  1.22k|	}
  949|       |
  950|       |	/* need to increase size */
  951|  1.02k|	if (i == svr_ses.childpidsize) {
  ------------------
  |  Branch (951:6): [True: 259, False: 765]
  ------------------
  952|    259|		svr_ses.childpids = (struct ChildPid*)m_realloc(svr_ses.childpids,
  953|    259|				sizeof(struct ChildPid) * (svr_ses.childpidsize+1));
  954|    259|		svr_ses.childpidsize++;
  955|    259|	}
  956|       |	
  957|  1.02k|	TRACE(("addchildpid %d pid %d for chansess %p", i, pid, chansess))
  958|  1.02k|	svr_ses.childpids[i].pid = pid;
  959|  1.02k|	svr_ses.childpids[i].chansess = chansess;
  960|       |
  961|  1.02k|}
svr-chansession.c:ptycommand:
  813|     72|static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
  814|       |
  815|     72|	pid_t pid;
  816|     72|	struct logininfo *li = NULL;
  817|     72|#if DO_MOTD
  818|     72|	buffer * motdbuf = NULL;
  819|     72|	int len;
  820|     72|	struct stat sb;
  821|     72|	char *hushpath = NULL;
  822|     72|#endif
  823|       |
  824|     72|	TRACE(("enter ptycommand"))
  825|       |
  826|       |	/* we need to have a pty allocated */
  827|     72|	if (chansess->master == -1 || chansess->tty == NULL) {
  ------------------
  |  Branch (827:6): [True: 72, False: 0]
  |  Branch (827:32): [True: 0, False: 0]
  ------------------
  828|     72|		dropbear_log(LOG_WARNING, "No pty was allocated, couldn't execute");
  829|     72|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|     72|#define DROPBEAR_FAILURE -1
  ------------------
  830|     72|	}
  831|       |	
  832|       |#if DROPBEAR_VFORK
  833|       |	pid = vfork();
  834|       |#else
  835|      0|	pid = fork();
  836|      0|#endif
  837|      0|	if (pid < 0)
  ------------------
  |  Branch (837:6): [True: 0, False: 0]
  ------------------
  838|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  839|       |
  840|      0|	if (pid == 0) {
  ------------------
  |  Branch (840:6): [True: 0, False: 0]
  ------------------
  841|       |		/* child */
  842|       |		
  843|      0|		TRACE(("back to normal sigchld"))
  844|       |		/* Revert to normal sigchld handling */
  845|      0|		if (signal(SIGCHLD, SIG_DFL) == SIG_ERR) {
  ------------------
  |  Branch (845:7): [True: 0, False: 0]
  ------------------
  846|      0|			dropbear_exit("signal() error");
  847|      0|		}
  848|       |		
  849|       |		/* redirect stdin/stdout/stderr */
  850|      0|		close(chansess->master);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  851|       |
  852|      0|		pty_make_controlling_tty(&chansess->slave, chansess->tty);
  853|       |		
  854|      0|		if ((dup2(chansess->slave, STDIN_FILENO) < 0) ||
  ------------------
  |  Branch (854:7): [True: 0, False: 0]
  ------------------
  855|      0|			(dup2(chansess->slave, STDOUT_FILENO) < 0)) {
  ------------------
  |  Branch (855:4): [True: 0, False: 0]
  ------------------
  856|      0|			TRACE(("leave ptycommand: error redirecting filedesc"))
  857|      0|			return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  858|      0|			}
  859|       |
  860|       |		/* write the utmp/wtmp login record - must be after changing the
  861|       |		 * terminal used for stdout with the dup2 above, otherwise
  862|       |		 * the wtmp login will not be recorded */
  863|      0|		li = chansess_login_alloc(chansess);
  864|       |
  865|      0|		svr_raise_gid_utmp();
  866|      0|		login_login(li);
  867|      0|		svr_restore_gid();
  868|       |
  869|      0|		login_free_entry(li);
  870|       |
  871|       |		/* Can now dup2 stderr. Messages from login_login() have gone
  872|       |		to the parent stderr */
  873|      0|		if (dup2(chansess->slave, STDERR_FILENO) < 0) {
  ------------------
  |  Branch (873:7): [True: 0, False: 0]
  ------------------
  874|      0|			TRACE(("leave ptycommand: error redirecting filedesc"))
  875|      0|			return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  876|      0|		}
  877|       |
  878|      0|		close(chansess->slave);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  879|       |
  880|      0|#if DO_MOTD
  881|      0|		if (svr_opts.domotd && !chansess->cmd) {
  ------------------
  |  Branch (881:7): [True: 0, False: 0]
  |  Branch (881:26): [True: 0, False: 0]
  ------------------
  882|       |			/* don't show the motd if ~/.hushlogin exists */
  883|       |
  884|       |			/* 12 == strlen("/.hushlogin\0") */
  885|      0|			len = strlen(ses.authstate.pw_dir) + 12; 
  886|       |
  887|      0|			hushpath = m_malloc(len);
  888|      0|			snprintf(hushpath, len, "%s/.hushlogin", ses.authstate.pw_dir);
  889|       |
  890|      0|			if (stat(hushpath, &sb) < 0) {
  ------------------
  |  Branch (890:8): [True: 0, False: 0]
  ------------------
  891|      0|				char *expand_path = NULL;
  892|       |				/* more than a screenful is stupid IMHO */
  893|      0|				motdbuf = buf_new(MOTD_MAXSIZE);
  ------------------
  |  |  358|      0|#define MOTD_MAXSIZE 2000
  ------------------
  894|      0|				expand_path = expand_homedir_path(MOTD_FILENAME);
  ------------------
  |  |  355|      0|#define MOTD_FILENAME "/etc/motd"
  ------------------
  895|      0|				if (buf_readfile(motdbuf, expand_path) == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (895:9): [True: 0, False: 0]
  ------------------
  896|       |					/* incase it is full size, add LF at last position */
  897|      0|					if (motdbuf->len == motdbuf->size) motdbuf->data[motdbuf->len - 1]=10;
  ------------------
  |  Branch (897:10): [True: 0, False: 0]
  ------------------
  898|      0|					buf_setpos(motdbuf, 0);
  899|      0|					while (motdbuf->pos != motdbuf->len) {
  ------------------
  |  Branch (899:13): [True: 0, False: 0]
  ------------------
  900|      0|						len = motdbuf->len - motdbuf->pos;
  901|      0|						len = write(STDOUT_FILENO, 
  ------------------
  |  |   54|      0|#define write(fd, buf, count) wrapfd_write(fd, buf, count)
  ------------------
  902|      0|								buf_getptr(motdbuf, len), len);
  903|      0|						buf_incrpos(motdbuf, len);
  904|      0|					}
  905|      0|				}
  906|      0|				m_free(expand_path);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  907|      0|				buf_free(motdbuf);
  908|       |
  909|      0|			}
  910|      0|			m_free(hushpath);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  911|      0|		}
  912|      0|#endif /* DO_MOTD */
  913|       |
  914|      0|		execchild(chansess);
  915|       |		/* not reached */
  916|       |
  917|      0|	} else {
  918|       |		/* parent */
  919|      0|		TRACE(("continue ptycommand: parent"))
  920|      0|		chansess->pid = pid;
  921|       |
  922|       |		/* add a child pid */
  923|      0|		addchildpid(chansess, pid);
  924|       |
  925|      0|		close(chansess->slave);
  ------------------
  |  |   56|      0|#define close(fd) wrapfd_close(fd)
  ------------------
  926|      0|		channel->writefd = chansess->master;
  927|      0|		channel->readfd = chansess->master;
  928|       |		/* don't need to set stderr here */
  929|      0|		ses.maxfd = MAX(ses.maxfd, chansess->master);
  ------------------
  |  Branch (929:15): [True: 0, False: 0]
  ------------------
  930|      0|		channel->bidir_fd = 0;
  931|       |
  932|      0|		setnonblocking(chansess->master);
  933|       |
  934|      0|	}
  935|       |
  936|      0|	TRACE(("leave ptycommand"))
  937|      0|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  938|      0|}
svr-chansession.c:sessionpty:
  591|    108|static int sessionpty(struct ChanSess * chansess) {
  592|       |
  593|    108|	unsigned int termlen;
  594|    108|	char namebuf[65];
  595|    108|	struct passwd * pw = NULL;
  596|       |
  597|    108|	TRACE(("enter sessionpty"))
  598|       |
  599|    108|	if (!svr_pubkey_allows_pty()) {
  ------------------
  |  Branch (599:6): [True: 0, False: 108]
  ------------------
  600|      0|		TRACE(("leave sessionpty : pty forbidden by public key option"))
  601|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  602|      0|	}
  603|       |
  604|    108|	chansess->term = buf_getstring(ses.payload, &termlen);
  605|    108|	if (termlen > MAX_TERM_LEN) {
  ------------------
  |  |   85|    108|#define MAX_TERM_LEN 200 /* max length of TERM name */
  ------------------
  |  Branch (605:6): [True: 94, False: 14]
  ------------------
  606|       |		/* TODO send disconnect ? */
  607|     94|		TRACE(("leave sessionpty: term len too long"))
  608|     94|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|     94|#define DROPBEAR_FAILURE -1
  ------------------
  609|     94|	}
  610|       |
  611|       |	/* allocate the pty */
  612|     14|	if (chansess->master != -1) {
  ------------------
  |  Branch (612:6): [True: 0, False: 14]
  ------------------
  613|      0|		dropbear_exit("Multiple pty requests");
  614|      0|	}
  615|     14|	if (pty_allocate(&chansess->master, &chansess->slave, namebuf, 64) == 0) {
  ------------------
  |  Branch (615:6): [True: 0, False: 14]
  ------------------
  616|      0|		TRACE(("leave sessionpty: failed to allocate pty"))
  617|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  618|      0|	}
  619|       |	
  620|     14|	chansess->tty = m_strdup(namebuf);
  621|     14|	if (!chansess->tty) {
  ------------------
  |  Branch (621:6): [True: 0, False: 14]
  ------------------
  622|      0|		dropbear_exit("Out of memory"); /* TODO disconnect */
  623|      0|	}
  624|       |
  625|     14|	pw = getpwnam(ses.authstate.pw_name);
  ------------------
  |  |  108|     14|#define getpwnam(x) fuzz_getpwnam(x)
  ------------------
  626|     14|	if (!pw)
  ------------------
  |  Branch (626:6): [True: 0, False: 14]
  ------------------
  627|      0|		dropbear_exit("getpwnam failed after succeeding previously");
  628|     14|	pty_setowner(pw, chansess->tty);
  629|       |
  630|       |	/* Set up the rows/col counts */
  631|     14|	sessionwinchange(chansess);
  632|       |
  633|       |	/* Read the terminal modes */
  634|     14|	get_termmodes(chansess);
  635|       |
  636|     14|	TRACE(("leave sessionpty"))
  637|     14|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|     14|#define DROPBEAR_SUCCESS 0
  ------------------
  638|     14|}
svr-chansession.c:get_termmodes:
  497|      1|static void get_termmodes(const struct ChanSess *chansess) {
  498|       |
  499|      1|	struct termios termio;
  500|      1|	unsigned char opcode;
  501|      1|	unsigned int value;
  502|      1|	const struct TermCode * termcode;
  503|      1|	unsigned int len;
  504|       |
  505|      1|	TRACE(("enter get_termmodes"))
  506|       |
  507|       |	/* Term modes */
  508|       |	/* We'll ignore errors and continue if we can't set modes.
  509|       |	 * We're ignoring baud rates since they seem evil */
  510|      1|	if (tcgetattr(chansess->master, &termio) == -1) {
  ------------------
  |  Branch (510:6): [True: 0, False: 1]
  ------------------
  511|      0|		return;
  512|      0|	}
  513|       |
  514|      1|	len = buf_getint(ses.payload);
  515|      1|	TRACE(("term mode str %d p->l %d p->p %d", 
  516|      1|				len, ses.payload->len , ses.payload->pos));
  517|      1|	if (len != ses.payload->len - ses.payload->pos) {
  ------------------
  |  Branch (517:6): [True: 1, False: 0]
  ------------------
  518|      1|		dropbear_exit("Bad term mode string");
  519|      1|	}
  520|       |
  521|      0|	if (len == 0) {
  ------------------
  |  Branch (521:6): [True: 0, False: 0]
  ------------------
  522|      0|		TRACE(("leave get_termmodes: empty terminal modes string"))
  523|      0|		return;
  524|      0|	}
  525|       |
  526|      0|	while (((opcode = buf_getbyte(ses.payload)) != 0x00) && opcode <= 159) {
  ------------------
  |  Branch (526:9): [True: 0, False: 0]
  |  Branch (526:58): [True: 0, False: 0]
  ------------------
  527|       |
  528|       |		/* must be before checking type, so that value is consumed even if
  529|       |		 * we don't use it */
  530|      0|		value = buf_getint(ses.payload);
  531|       |
  532|       |		/* handle types of code */
  533|      0|		if (opcode > MAX_TERMCODE) {
  ------------------
  |  |   35|      0|#define MAX_TERMCODE 93
  ------------------
  |  Branch (533:7): [True: 0, False: 0]
  ------------------
  534|      0|			continue;
  535|      0|		}
  536|      0|		termcode = &termcodes[(unsigned int)opcode];
  537|       |		
  538|       |
  539|      0|		switch (termcode->type) {
  ------------------
  |  Branch (539:11): [True: 0, False: 0]
  ------------------
  540|       |
  541|      0|			case TERMCODE_NONE:
  ------------------
  |  |   28|      0|#define TERMCODE_NONE 0
  ------------------
  |  Branch (541:4): [True: 0, False: 0]
  ------------------
  542|      0|				break;
  543|       |
  544|      0|			case TERMCODE_CONTROLCHAR:
  ------------------
  |  |   33|      0|#define TERMCODE_CONTROLCHAR 5
  ------------------
  |  Branch (544:4): [True: 0, False: 0]
  ------------------
  545|      0|				termio.c_cc[termcode->mapcode] = value;
  546|      0|				break;
  547|       |
  548|      0|			case TERMCODE_INPUT:
  ------------------
  |  |   30|      0|#define TERMCODE_INPUT 2
  ------------------
  |  Branch (548:4): [True: 0, False: 0]
  ------------------
  549|      0|				if (value) {
  ------------------
  |  Branch (549:9): [True: 0, False: 0]
  ------------------
  550|      0|					termio.c_iflag |= termcode->mapcode;
  551|      0|				} else {
  552|      0|					termio.c_iflag &= ~(termcode->mapcode);
  553|      0|				}
  554|      0|				break;
  555|       |
  556|      0|			case TERMCODE_OUTPUT:
  ------------------
  |  |   31|      0|#define TERMCODE_OUTPUT 3
  ------------------
  |  Branch (556:4): [True: 0, False: 0]
  ------------------
  557|      0|				if (value) {
  ------------------
  |  Branch (557:9): [True: 0, False: 0]
  ------------------
  558|      0|					termio.c_oflag |= termcode->mapcode;
  559|      0|				} else {
  560|      0|					termio.c_oflag &= ~(termcode->mapcode);
  561|      0|				}
  562|      0|				break;
  563|       |
  564|      0|			case TERMCODE_LOCAL:
  ------------------
  |  |   32|      0|#define TERMCODE_LOCAL 4
  ------------------
  |  Branch (564:4): [True: 0, False: 0]
  ------------------
  565|      0|				if (value) {
  ------------------
  |  Branch (565:9): [True: 0, False: 0]
  ------------------
  566|      0|					termio.c_lflag |= termcode->mapcode;
  567|      0|				} else {
  568|      0|					termio.c_lflag &= ~(termcode->mapcode);
  569|      0|				}
  570|      0|				break;
  571|       |
  572|      0|			case TERMCODE_CONTROL:
  ------------------
  |  |   29|      0|#define TERMCODE_CONTROL 1
  ------------------
  |  Branch (572:4): [True: 0, False: 0]
  ------------------
  573|      0|				if (value) {
  ------------------
  |  Branch (573:9): [True: 0, False: 0]
  ------------------
  574|      0|					termio.c_cflag |= termcode->mapcode;
  575|      0|				} else {
  576|      0|					termio.c_cflag &= ~(termcode->mapcode);
  577|      0|				}
  578|      0|				break;
  579|       |				
  580|      0|		}
  581|      0|	}
  582|      0|	if (tcsetattr(chansess->master, TCSANOW, &termio) < 0) {
  ------------------
  |  Branch (582:6): [True: 0, False: 0]
  ------------------
  583|       |		dropbear_log(LOG_INFO, "Error setting terminal attributes");
  584|      0|	}
  585|      0|	TRACE(("leave get_termmodes"))
  586|      0|}
svr-chansession.c:sessionsignal:
  428|  1.15k|static int sessionsignal(const struct ChanSess *chansess) {
  429|  1.15k|	TRACE(("sessionsignal"))
  430|       |
  431|  1.15k|	int sig = 0;
  432|  1.15k|	char* signame = NULL;
  433|  1.15k|	int i;
  434|       |
  435|  1.15k|	if (chansess->pid == 0) {
  ------------------
  |  Branch (435:6): [True: 219, False: 938]
  ------------------
  436|    219|		TRACE(("sessionsignal: done no pid"))
  437|       |		/* haven't got a process pid yet */
  438|    219|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|    219|#define DROPBEAR_FAILURE -1
  ------------------
  439|    219|	}
  440|       |
  441|    938|	if (svr_opts.forced_command || svr_pubkey_has_forced_command()) {
  ------------------
  |  Branch (441:6): [True: 0, False: 938]
  |  Branch (441:33): [True: 0, False: 938]
  ------------------
  442|      0|		TRACE(("disallowed signal for forced_command"));
  443|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  444|      0|	}
  445|       |
  446|    938|	if (DROPBEAR_SVR_MULTIUSER && !DROPBEAR_SVR_DROP_PRIVS) {
  ------------------
  |  |  393|  1.87k|#define DROPBEAR_SVR_MULTIUSER 1
  |  |  ------------------
  |  |  |  Branch (393:32): [True: 0, Folded]
  |  |  ------------------
  ------------------
              	if (DROPBEAR_SVR_MULTIUSER && !DROPBEAR_SVR_DROP_PRIVS) {
  ------------------
  |  |  490|      0|#define DROPBEAR_SVR_DROP_PRIVS DROPBEAR_SVR_MULTIUSER
  |  |  ------------------
  |  |  |  |  393|      0|#define DROPBEAR_SVR_MULTIUSER 1
  |  |  ------------------
  ------------------
  |  Branch (446:32): [Folded, False: 0]
  ------------------
  447|      0|		TRACE(("disallow signal without drop privs"));
  448|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  449|      0|	}
  450|       |
  451|    938|	signame = buf_getstring(ses.payload, NULL);
  452|       |
  453|  11.6k|	for (i = 0; signames[i].name != NULL; i++) {
  ------------------
  |  Branch (453:14): [True: 10.9k, False: 663]
  ------------------
  454|  10.9k|		if (strcmp(signames[i].name, signame) == 0) {
  ------------------
  |  Branch (454:7): [True: 275, False: 10.7k]
  ------------------
  455|    275|			sig = signames[i].signal;
  456|    275|			break;
  457|    275|		}
  458|  10.9k|	}
  459|       |
  460|    938|	m_free(signame);
  ------------------
  |  |   24|    938|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 938]
  |  |  ------------------
  ------------------
  461|       |
  462|    938|	TRACE(("sessionsignal: pid %d signal %d", (int)chansess->pid, sig))
  463|    938|	if (sig == 0) {
  ------------------
  |  Branch (463:6): [True: 662, False: 276]
  ------------------
  464|       |		/* failed */
  465|    662|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|    662|#define DROPBEAR_FAILURE -1
  ------------------
  466|    662|	}
  467|       |			
  468|    276|	if (kill(chansess->pid, sig) < 0) {
  ------------------
  |  |   57|    276|#define kill(pid, sig) fuzz_kill(pid, sig)
  ------------------
  |  Branch (468:6): [True: 0, False: 276]
  ------------------
  469|      0|		TRACE(("sessionsignal: kill() errored"))
  470|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  471|      0|	} 
  472|       |
  473|    276|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|    276|#define DROPBEAR_SUCCESS 0
  ------------------
  474|    276|}

svr_recv_msg_global_request:
   37|  1.40k|void svr_recv_msg_global_request(void) {
   38|       |
   39|  1.40k|    char* reqname = NULL;
   40|  1.40k|    unsigned int namelen;
   41|  1.40k|    unsigned int wantreply = 0;
   42|  1.40k|    int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|  1.40k|#define DROPBEAR_FAILURE -1
  ------------------
   43|       |
   44|  1.40k|    TRACE(("enter recv_msg_global_request_remote"))
   45|       |
   46|  1.40k|    reqname = buf_getstring(ses.payload, &namelen);
   47|  1.40k|    wantreply = buf_getbool(ses.payload);
   48|       |
   49|  1.40k|#if DROPBEAR_SVR_REMOTEANYFWD
   50|  1.40k|    if (svr_opts.noremotefwd || !svr_pubkey_allows_tcpfwd()) {
  ------------------
  |  Branch (50:9): [True: 1, False: 1.40k]
  |  Branch (50:33): [True: 0, False: 1.40k]
  ------------------
   51|      0|        TRACE(("remote forwarding is disabled"));
   52|      0|        goto out;
   53|      0|    }
   54|       |#else
   55|       |    /* No request handlers */
   56|       |    goto out;
   57|       |#endif
   58|       |
   59|  1.40k|    if (namelen > MAX_NAME_LEN) {
  ------------------
  |  |  233|  1.40k|#define MAX_NAME_LEN 64 /* maximum length of a protocol name, isn't
  ------------------
  |  Branch (59:9): [True: 75, False: 1.33k]
  ------------------
   60|     75|        TRACE(("name len is wrong: %d", namelen))
   61|     75|        goto out;
   62|     75|    }
   63|       |
   64|  1.33k|    if (0) {}
  ------------------
  |  Branch (64:9): [Folded, False: 1.33k]
  ------------------
   65|  1.33k|#if DROPBEAR_SVR_REMOTETCPFWD
   66|  1.33k|    else if (strcmp("tcpip-forward", reqname) == 0) {
  ------------------
  |  Branch (66:14): [True: 372, False: 959]
  ------------------
   67|    372|        ret = svr_remotetcpreq(wantreply);
   68|       |        /* svr_remotetcpreq sends its on reply if needed,
   69|       |         * don't send another in out: below */
   70|    372|        wantreply = 0;
   71|    959|    } else if (strcmp("cancel-tcpip-forward", reqname) == 0) {
  ------------------
  |  Branch (71:16): [True: 196, False: 763]
  ------------------
   72|    196|        ret = svr_cancelremotetcp();
   73|    196|    }
   74|    763|#endif
   75|    763|#if DROPBEAR_SVR_REMOTESTREAMFWD
   76|    763|    else if (strcmp("streamlocal-forward@openssh.com", reqname) == 0) {
  ------------------
  |  Branch (76:14): [True: 0, False: 763]
  ------------------
   77|      0|        ret = svr_remotestreamlocalreq();
   78|    763|    } else if (strcmp("cancel-streamlocal-forward@openssh.com", reqname) == 0) {
  ------------------
  |  Branch (78:16): [True: 0, False: 763]
  ------------------
   79|      0|        ret = svr_cancelremotestreamlocal();
   80|      0|    }
   81|    763|#endif
   82|    763|    else {
   83|    763|        TRACE(("unhandled request '%s'", reqname))
   84|    763|    }
   85|       |
   86|  1.39k|out:
   87|  1.39k|    if (wantreply) {
  ------------------
  |  Branch (87:9): [True: 798, False: 595]
  ------------------
   88|    798|        if (ret == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|    798|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (88:13): [True: 0, False: 798]
  ------------------
   89|      0|            send_msg_request_success();
   90|    798|        } else {
   91|    798|            send_msg_request_failure();
   92|    798|        }
   93|    798|    }
   94|       |
   95|  1.39k|    m_free(reqname);
  ------------------
  |  |   24|  1.39k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 1.39k]
  |  |  ------------------
  ------------------
   96|       |
   97|  1.39k|    TRACE(("leave recv_msg_global_request"))
   98|  1.39k|}

recv_msg_kexdh_init:
   49|  6.69k|void recv_msg_kexdh_init() {
   50|  6.69k|	DEF_MP_INT(dh_e);
  ------------------
  |  |   81|  6.69k|#define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
  ------------------
   51|  6.69k|	buffer *q_c = NULL;
   52|       |
   53|  6.69k|	TRACE(("enter recv_msg_kexdh_init"))
   54|  6.69k|	if (!ses.kexstate.recvkexinit) {
  ------------------
  |  Branch (54:6): [True: 7, False: 6.68k]
  ------------------
   55|      7|		dropbear_exit("Premature kexdh_init message received");
   56|      7|	}
   57|       |
   58|  6.68k|	switch (ses.newkeys->algo_kex->mode) {
  ------------------
  |  Branch (58:10): [True: 6.68k, False: 0]
  ------------------
   59|      0|#if DROPBEAR_NORMAL_DH
   60|    199|		case DROPBEAR_KEX_NORMAL_DH:
  ------------------
  |  Branch (60:3): [True: 199, False: 6.48k]
  ------------------
   61|    199|			m_mp_init(&dh_e);
   62|    199|			if (buf_getmpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|    199|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (62:8): [True: 63, False: 136]
  ------------------
   63|     63|				dropbear_exit("Bad kex value");
   64|     63|			}
   65|    136|			break;
   66|    136|#endif
   67|    136|#if DROPBEAR_ECDH
   68|  2.67k|		case DROPBEAR_KEX_ECDH:
  ------------------
  |  Branch (68:3): [True: 2.67k, False: 4.00k]
  ------------------
   69|  2.67k|#endif
   70|  2.67k|#if DROPBEAR_CURVE25519
   71|  6.46k|		case DROPBEAR_KEX_CURVE25519:
  ------------------
  |  Branch (71:3): [True: 3.78k, False: 2.89k]
  ------------------
   72|  6.46k|#endif
   73|  6.46k|#if DROPBEAR_PQHYBRID
   74|  6.48k|		case DROPBEAR_KEX_PQHYBRID:
  ------------------
  |  Branch (74:3): [True: 23, False: 6.66k]
  ------------------
   75|  6.48k|#endif
   76|  6.48k|#if DROPBEAR_ECDH || DROPBEAR_CURVE25519 || DROPBEAR_PQHYBRID
   77|  6.48k|			q_c = buf_getstringbuf(ses.payload);
   78|  6.48k|			break;
   79|  6.68k|#endif
   80|  6.68k|	}
   81|  6.52k|	if (ses.payload->pos != ses.payload->len) {
  ------------------
  |  Branch (81:6): [True: 74, False: 6.45k]
  ------------------
   82|     74|		dropbear_exit("Bad kex value");
   83|     74|	}
   84|       |
   85|  6.45k|	send_msg_kexdh_reply(&dh_e, q_c);
   86|       |
   87|  6.45k|	mp_clear(&dh_e);
   88|  6.45k|	if (q_c) {
  ------------------
  |  Branch (88:6): [True: 6.39k, False: 62]
  ------------------
   89|  6.39k|		buf_free(q_c);
   90|  6.39k|		q_c = NULL;
   91|  6.39k|	}
   92|       |
   93|  6.45k|	send_msg_newkeys();
   94|       |
   95|  6.45k|#if DROPBEAR_EXT_INFO
   96|       |	/* Only send it following the first newkeys */
   97|  6.45k|	if (!ses.kexstate.donesecondkex && ses.allow_ext_info) {
  ------------------
  |  Branch (97:6): [True: 3.36k, False: 3.09k]
  |  Branch (97:37): [True: 9, False: 3.35k]
  ------------------
   98|      9|		send_msg_ext_info();
   99|      9|	}
  100|  6.45k|#endif
  101|       |
  102|  6.45k|	if (!ses.kexstate.donesecondkex) {
  ------------------
  |  Branch (102:6): [True: 3.36k, False: 3.09k]
  ------------------
  103|       |		/* Disable other signature types.
  104|       |		 * During future rekeying, privileges may have been dropped
  105|       |		 * so other keys won't be loadable.
  106|       |		 * This must occur after send_msg_ext_info() which uses the hostkey list */
  107|  3.36k|		disable_sig_except(ses.newkeys->algo_signature);
  108|  3.36k|	}
  109|       |
  110|  6.45k|	ses.requirenext = SSH_MSG_NEWKEYS;
  ------------------
  |  |   37|  6.45k|#define SSH_MSG_NEWKEYS                21
  ------------------
  111|  6.45k|	TRACE(("leave recv_msg_kexdh_init"))
  112|  6.45k|}
svr-kex.c:send_msg_kexdh_reply:
  200|  6.45k|static void send_msg_kexdh_reply(mp_int *dh_e, buffer *q_c) {
  201|  6.45k|	TRACE(("enter send_msg_kexdh_reply"))
  202|       |
  203|       |	/* we can start creating the kexdh_reply packet */
  204|  6.45k|	CHECKCLEARTOWRITE();
  205|       |
  206|  6.45k|#if DROPBEAR_DELAY_HOSTKEY
  207|  6.45k|	if (svr_opts.delay_hostkey)
  ------------------
  |  Branch (207:6): [True: 0, False: 6.45k]
  ------------------
  208|      0|	{
  209|      0|		svr_ensure_hostkey();
  210|      0|	}
  211|  6.45k|#endif
  212|       |
  213|  6.45k|#if DROPBEAR_FUZZ
  214|  6.45k|	if (fuzz.fuzzing && fuzz.skip_kexmaths) {
  ------------------
  |  Branch (214:6): [True: 6.45k, False: 0]
  |  Branch (214:22): [True: 6.45k, False: 0]
  ------------------
  215|  6.45k|		fuzz_fake_send_kexdh_reply();
  216|  6.45k|		return;
  217|  6.45k|	}
  218|      0|#endif
  219|       |
  220|      0|	buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY);
  ------------------
  |  |   39|      0|#define SSH_MSG_KEXDH_REPLY            31
  ------------------
  221|      0|	buf_put_pub_key(ses.writepayload, svr_opts.hostkey,
  222|      0|			ses.newkeys->algo_hostkey);
  223|       |
  224|      0|	switch (ses.newkeys->algo_kex->mode) {
  ------------------
  |  Branch (224:10): [True: 0, False: 0]
  ------------------
  225|      0|#if DROPBEAR_NORMAL_DH
  226|      0|		case DROPBEAR_KEX_NORMAL_DH:
  ------------------
  |  Branch (226:3): [True: 0, False: 0]
  ------------------
  227|      0|			{
  228|      0|			struct kex_dh_param * dh_param = gen_kexdh_param();
  229|      0|			kexdh_comb_key(dh_param, dh_e, svr_opts.hostkey);
  230|       |
  231|       |			/* put f */
  232|      0|			buf_putmpint(ses.writepayload, &dh_param->pub);
  233|      0|			free_kexdh_param(dh_param);
  234|      0|			}
  235|      0|			break;
  236|      0|#endif
  237|      0|#if DROPBEAR_ECDH
  238|      0|		case DROPBEAR_KEX_ECDH:
  ------------------
  |  Branch (238:3): [True: 0, False: 0]
  ------------------
  239|      0|			{
  240|      0|			struct kex_ecdh_param *ecdh_param = gen_kexecdh_param();
  241|      0|			kexecdh_comb_key(ecdh_param, q_c, svr_opts.hostkey);
  242|       |
  243|      0|			buf_put_ecc_raw_pubkey_string(ses.writepayload, &ecdh_param->key);
  244|      0|			free_kexecdh_param(ecdh_param);
  245|      0|			}
  246|      0|			break;
  247|      0|#endif
  248|      0|#if DROPBEAR_CURVE25519
  249|      0|		case DROPBEAR_KEX_CURVE25519:
  ------------------
  |  Branch (249:3): [True: 0, False: 0]
  ------------------
  250|      0|			{
  251|      0|			struct kex_curve25519_param *param = gen_kexcurve25519_param();
  252|      0|			kexcurve25519_comb_key(param, q_c, svr_opts.hostkey);
  253|       |
  254|      0|			buf_putstring(ses.writepayload, param->pub, CURVE25519_LEN);
  ------------------
  |  |  122|      0|#define CURVE25519_LEN 32
  ------------------
  255|      0|			free_kexcurve25519_param(param);
  256|      0|			}
  257|      0|			break;
  258|      0|#endif
  259|      0|#if DROPBEAR_PQHYBRID
  260|      0|		case DROPBEAR_KEX_PQHYBRID:
  ------------------
  |  Branch (260:3): [True: 0, False: 0]
  ------------------
  261|      0|			{
  262|      0|			struct kex_pqhybrid_param *param = gen_kexpqhybrid_param();
  263|      0|			kexpqhybrid_comb_key(param, q_c, svr_opts.hostkey);
  264|       |
  265|      0|			buf_putbufstring(ses.writepayload, param->concat_public);
  266|      0|			free_kexpqhybrid_param(param);
  267|      0|			}
  268|      0|			break;
  269|      0|#endif
  270|      0|	}
  271|       |
  272|       |	/* calc the signature */
  273|      0|	buf_put_sign(ses.writepayload, svr_opts.hostkey, 
  274|      0|			ses.newkeys->algo_signature, ses.hash);
  275|       |
  276|       |	/* the SSH_MSG_KEXDH_REPLY is done */
  277|      0|	encrypt_packet();
  278|       |
  279|      0|	TRACE(("leave send_msg_kexdh_reply"))
  280|      0|}
svr-kex.c:send_msg_ext_info:
  284|      9|static void send_msg_ext_info(void) {
  285|      9|	TRACE(("enter send_msg_ext_info"))
  286|       |
  287|      9|	buf_putbyte(ses.writepayload, SSH_MSG_EXT_INFO);
  ------------------
  |  |   35|      9|#define SSH_MSG_EXT_INFO               7
  ------------------
  288|       |	/* nr-extensions */
  289|      9|	buf_putint(ses.writepayload, 1);
  290|       |
  291|      9|	buf_putstring(ses.writepayload, SSH_SERVER_SIG_ALGS, strlen(SSH_SERVER_SIG_ALGS));
  ------------------
  |  |  101|      9|#define SSH_SERVER_SIG_ALGS "server-sig-algs"
  ------------------
              	buf_putstring(ses.writepayload, SSH_SERVER_SIG_ALGS, strlen(SSH_SERVER_SIG_ALGS));
  ------------------
  |  |  101|      9|#define SSH_SERVER_SIG_ALGS "server-sig-algs"
  ------------------
  292|      9|	buf_put_algolist_all(ses.writepayload, sigalgs, 1);
  293|       |	
  294|      9|	encrypt_packet();
  295|       |
  296|      9|	TRACE(("leave send_msg_ext_info"))
  297|      9|}

svr_getopts:
  147|      1|void svr_getopts(int argc, char ** argv) {
  148|       |
  149|      1|	unsigned int i, j;
  150|      1|	char ** next = NULL;
  151|      1|	int nextisport = 0;
  152|      1|	char* recv_window_arg = NULL;
  153|      1|	char* keepalive_arg = NULL;
  154|      1|	char* idle_timeout_arg = NULL;
  155|      1|	char* max_duration_arg = NULL;
  156|      1|	char* maxauthtries_arg = NULL;
  157|      1|	char* reexec_fd_arg = NULL;
  158|      1|	char* keyfile = NULL;
  159|      1|	char *algo_print_arg = NULL;
  160|      1|	char c;
  161|       |#if DROPBEAR_PLUGIN
  162|       |        char* pubkey_plugin = NULL;
  163|       |#endif
  164|       |
  165|       |
  166|       |	/* see printhelp() for options */
  167|      1|	svr_opts.bannerfile = NULL;
  168|      1|	svr_opts.banner = NULL;
  169|      1|	svr_opts.forced_command = NULL;
  170|      1|	svr_opts.forkbg = 1;
  171|      1|	svr_opts.norootlogin = 0;
  172|      1|#ifdef HAVE_GETGROUPLIST
  173|      1|	svr_opts.restrict_group = NULL;
  174|      1|	svr_opts.restrict_group_gid = 0;
  175|      1|#endif
  176|      1|	svr_opts.noauthpass = 0;
  177|      1|	svr_opts.norootpass = 0;
  178|      1|	svr_opts.allowblankpass = 0;
  179|      1|	svr_opts.multiauthmethod = 0;
  180|      1|	svr_opts.maxauthtries = MAX_AUTH_TRIES;
  ------------------
  |  |  463|      1|#define MAX_AUTH_TRIES 10
  ------------------
  181|      1|	svr_opts.inetdmode = 0;
  182|      1|	svr_opts.portcount = 0;
  183|      1|	svr_opts.hostkey = NULL;
  184|      1|	svr_opts.delay_hostkey = 0;
  185|      1|	svr_opts.pidfile = expand_homedir_path(DROPBEAR_PIDFILE);
  ------------------
  |  |  507|      1|#define DROPBEAR_PIDFILE "/var/run/dropbear.pid"
  ------------------
  186|      1|	svr_opts.authorized_keys_dir = "~/.ssh";
  187|      1|#if DROPBEAR_SVR_LOCALANYFWD
  188|      1|	svr_opts.nolocaltcp = 0;
  189|      1|#endif
  190|      1|#if DROPBEAR_SVR_REMOTEANYFWD
  191|      1|	svr_opts.noremotefwd = 0;
  192|      1|#endif
  193|       |#if DROPBEAR_PLUGIN
  194|       |        svr_opts.pubkey_plugin = NULL;
  195|       |        svr_opts.pubkey_plugin_options = NULL;
  196|       |#endif
  197|      1|	svr_opts.pass_on_env = 0;
  198|      1|	svr_opts.reexec_childpipe = -1;
  199|       |
  200|       |#ifndef DISABLE_ZLIB
  201|       |	opts.compression = 1;
  202|       |#endif 
  203|       |
  204|       |	/* not yet
  205|       |	opts.ipv4 = 1;
  206|       |	opts.ipv6 = 1;
  207|       |	*/
  208|      1|#if DO_MOTD
  209|      1|	svr_opts.domotd = 1;
  210|      1|#endif
  211|      1|#ifndef DISABLE_SYSLOG
  212|      1|	opts.usingsyslog = 1;
  213|      1|#endif
  214|      1|	opts.recv_window = DEFAULT_RECV_WINDOW;
  ------------------
  |  |  550|      1|#define DEFAULT_RECV_WINDOW 24576
  ------------------
  215|      1|	opts.keepalive_secs = DEFAULT_KEEPALIVE;
  ------------------
  |  |  566|      1|#define DEFAULT_KEEPALIVE 0
  ------------------
  216|      1|	opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT;
  ------------------
  |  |  579|      1|#define DEFAULT_IDLE_TIMEOUT 0
  ------------------
  217|      1|	opts.max_duration_secs = DEFAULT_MAX_DURATION;
  ------------------
  |  |  585|      1|#define DEFAULT_MAX_DURATION 0
  ------------------
  218|       |
  219|      1|#if DROPBEAR_SVR_REMOTETCPFWD
  220|      1|	opts.listen_fwd_all = 0;
  221|      1|#endif
  222|      1|	opts.disable_ip_tos = 0;
  223|       |
  224|      2|	for (i = 1; i < (unsigned int)argc; i++) {
  ------------------
  |  Branch (224:14): [True: 1, False: 1]
  ------------------
  225|      1|		if (argv[i][0] != '-' || argv[i][1] == '\0')
  ------------------
  |  Branch (225:7): [True: 0, False: 1]
  |  Branch (225:28): [True: 0, False: 1]
  ------------------
  226|      0|			dropbear_exit("Invalid argument: %s", argv[i]);
  227|       |
  228|      2|		for (j = 1; (c = argv[i][j]) != '\0' && !next && !nextisport; j++) {
  ------------------
  |  Branch (228:15): [True: 1, False: 1]
  |  Branch (228:43): [True: 1, False: 0]
  |  Branch (228:52): [True: 1, False: 0]
  ------------------
  229|      1|			switch (c) {
  230|      0|				case 'b':
  ------------------
  |  Branch (230:5): [True: 0, False: 1]
  ------------------
  231|      0|					next = &svr_opts.bannerfile;
  232|      0|					break;
  233|      0|				case 'c':
  ------------------
  |  Branch (233:5): [True: 0, False: 1]
  ------------------
  234|      0|					next = &svr_opts.forced_command;
  235|      0|					break;
  236|      0|				case 'd':
  ------------------
  |  Branch (236:5): [True: 0, False: 1]
  ------------------
  237|      0|				case 'r':
  ------------------
  |  Branch (237:5): [True: 0, False: 1]
  ------------------
  238|      0|					next = &keyfile;
  239|      0|					break;
  240|      0|#if DROPBEAR_SVR_PUBKEY_AUTH
  241|      0|				case 'D':
  ------------------
  |  Branch (241:5): [True: 0, False: 1]
  ------------------
  242|      0|					next = &svr_opts.authorized_keys_dir;
  243|      0|					break;
  244|      0|#endif
  245|      0|				case 'R':
  ------------------
  |  Branch (245:5): [True: 0, False: 1]
  ------------------
  246|      0|					svr_opts.delay_hostkey = 1;
  247|      0|					break;
  248|      0|				case 'F':
  ------------------
  |  Branch (248:5): [True: 0, False: 1]
  ------------------
  249|      0|					svr_opts.forkbg = 0;
  250|      0|					break;
  251|      0|#ifndef DISABLE_SYSLOG
  252|      1|				case 'E':
  ------------------
  |  Branch (252:5): [True: 1, False: 0]
  ------------------
  253|      1|					opts.usingsyslog = 0;
  254|      1|					break;
  255|      0|#endif
  256|      0|				case 'e':
  ------------------
  |  Branch (256:5): [True: 0, False: 1]
  ------------------
  257|      0|					svr_opts.pass_on_env = 1;
  258|      0|					break;
  259|       |
  260|      0|#if DROPBEAR_SVR_LOCALANYFWD
  261|      0|				case 'j':
  ------------------
  |  Branch (261:5): [True: 0, False: 1]
  ------------------
  262|      0|					svr_opts.nolocaltcp = 1;
  263|      0|					break;
  264|       |#else
  265|       |				case 'j':
  266|       |					/* Ignore the flag */
  267|       |					break;
  268|       |#endif
  269|      0|#if DROPBEAR_SVR_REMOTEANYFWD
  270|      0|				case 'k':
  ------------------
  |  Branch (270:5): [True: 0, False: 1]
  ------------------
  271|      0|					svr_opts.noremotefwd = 1;
  272|      0|					break;
  273|       |#else
  274|       |				case 'k':
  275|       |					/* Ignore the flag */
  276|       |					break;
  277|       |#endif
  278|      0|#if DROPBEAR_SVR_REMOTETCPFWD
  279|      0|				case 'a':
  ------------------
  |  Branch (279:5): [True: 0, False: 1]
  ------------------
  280|      0|					opts.listen_fwd_all = 1;
  281|      0|					break;
  282|      0|#endif
  283|      0|#if INETD_MODE
  284|      0|				case 'i':
  ------------------
  |  Branch (284:5): [True: 0, False: 1]
  ------------------
  285|      0|					svr_opts.inetdmode = 1;
  286|      0|					break;
  287|      0|#endif
  288|      0|#if DROPBEAR_DO_REEXEC && NON_INETD_MODE
  289|       |				/* For internal use by re-exec */
  290|      0|				case '2':
  ------------------
  |  Branch (290:5): [True: 0, False: 1]
  ------------------
  291|      0|					next = &reexec_fd_arg;
  292|      0|					break;
  293|      0|#endif
  294|      0|				case 'p':
  ------------------
  |  Branch (294:5): [True: 0, False: 1]
  ------------------
  295|      0|					nextisport = 1;
  296|      0|					break;
  297|      0|				case 'P':
  ------------------
  |  Branch (297:5): [True: 0, False: 1]
  ------------------
  298|      0|					next = &svr_opts.pidfile;
  299|      0|					break;
  300|      0|#ifdef SO_BINDTODEVICE
  301|      0|				case 'l':
  ------------------
  |  Branch (301:5): [True: 0, False: 1]
  ------------------
  302|      0|					next = &svr_opts.interface;
  303|      0|					break;
  304|      0|#endif
  305|      0|#if DO_MOTD
  306|       |				/* motd is displayed by default, -m turns it off */
  307|      0|				case 'm':
  ------------------
  |  Branch (307:5): [True: 0, False: 1]
  ------------------
  308|      0|					svr_opts.domotd = 0;
  309|      0|					break;
  310|       |#else
  311|       |				case 'm':
  312|       |					break;
  313|       |#endif
  314|      0|				case 'w':
  ------------------
  |  Branch (314:5): [True: 0, False: 1]
  ------------------
  315|      0|					svr_opts.norootlogin = 1;
  316|      0|					break;
  317|      0|#ifdef HAVE_GETGROUPLIST
  318|      0|				case 'G':
  ------------------
  |  Branch (318:5): [True: 0, False: 1]
  ------------------
  319|      0|					next = &svr_opts.restrict_group;
  320|      0|					break;
  321|      0|#endif
  322|      0|				case 'W':
  ------------------
  |  Branch (322:5): [True: 0, False: 1]
  ------------------
  323|      0|					next = &recv_window_arg;
  324|      0|					break;
  325|      0|				case 'K':
  ------------------
  |  Branch (325:5): [True: 0, False: 1]
  ------------------
  326|      0|					next = &keepalive_arg;
  327|      0|					break;
  328|      0|				case 'I':
  ------------------
  |  Branch (328:5): [True: 0, False: 1]
  ------------------
  329|      0|					next = &idle_timeout_arg;
  330|      0|					break;
  331|      0|				case 'M':
  ------------------
  |  Branch (331:5): [True: 0, False: 1]
  ------------------
  332|      0|					next = &max_duration_arg;
  333|      0|					break;
  334|      0|				case 'T':
  ------------------
  |  Branch (334:5): [True: 0, False: 1]
  ------------------
  335|      0|					next = &maxauthtries_arg;
  336|      0|					break;
  337|      0|#if DROPBEAR_SVR_PASSWORD_AUTH || DROPBEAR_SVR_PAM_AUTH
  338|      0|				case 's':
  ------------------
  |  Branch (338:5): [True: 0, False: 1]
  ------------------
  339|      0|					svr_opts.noauthpass = 1;
  340|      0|					break;
  341|      0|				case 'g':
  ------------------
  |  Branch (341:5): [True: 0, False: 1]
  ------------------
  342|      0|					svr_opts.norootpass = 1;
  343|      0|					break;
  344|      0|				case 'B':
  ------------------
  |  Branch (344:5): [True: 0, False: 1]
  ------------------
  345|      0|					svr_opts.allowblankpass = 1;
  346|      0|					break;
  347|      0|				case 't':
  ------------------
  |  Branch (347:5): [True: 0, False: 1]
  ------------------
  348|      0|					svr_opts.multiauthmethod = 1;
  349|      0|					break;
  350|       |#else
  351|       |				case 's':
  352|       |				case 'g':
  353|       |					break;
  354|       |#endif
  355|      0|				case 'Q':
  ------------------
  |  Branch (355:5): [True: 0, False: 1]
  ------------------
  356|      0|					next = &algo_print_arg;
  357|      0|					break;
  358|      0|				case 'h':
  ------------------
  |  Branch (358:5): [True: 0, False: 1]
  ------------------
  359|      0|					printhelp(argv[0]);
  360|      0|					exit(EXIT_SUCCESS);
  361|      0|					break;
  362|      0|				case 'u':
  ------------------
  |  Branch (362:5): [True: 0, False: 1]
  ------------------
  363|       |					/* backwards compatibility with old urandom option */
  364|      0|					break;
  365|       |#if DROPBEAR_PLUGIN
  366|       |                                case 'A':
  367|       |                                        next = &pubkey_plugin;
  368|       |                                        break;
  369|       |#endif
  370|       |#if DEBUG_TRACE
  371|       |				case 'v':
  372|       |					debug_trace++;
  373|       |					break;
  374|       |#endif
  375|      0|				case 'V':
  ------------------
  |  Branch (375:5): [True: 0, False: 1]
  ------------------
  376|      0|					print_version();
  377|      0|					exit(EXIT_SUCCESS);
  378|      0|					break;
  379|      0|				case 'z':
  ------------------
  |  Branch (379:5): [True: 0, False: 1]
  ------------------
  380|      0|					opts.disable_ip_tos = 1;
  381|      0|					break;
  382|      0|				default:
  ------------------
  |  Branch (382:5): [True: 0, False: 1]
  ------------------
  383|      0|					fprintf(stderr, "Invalid option -%c\n", c);
  ------------------
  |  |  100|      0|#define stderr (fuzz.fake_stderr)
  ------------------
  384|      0|					printhelp(argv[0]);
  385|      0|					exit(EXIT_FAILURE);
  386|      0|					break;
  387|      1|			}
  388|      1|		}
  389|       |
  390|      1|		if (!next && !nextisport)
  ------------------
  |  Branch (390:7): [True: 1, False: 0]
  |  Branch (390:16): [True: 1, False: 0]
  ------------------
  391|      1|			continue;
  392|       |
  393|      0|		if (c == '\0') {
  ------------------
  |  Branch (393:7): [True: 0, False: 0]
  ------------------
  394|      0|			i++;
  395|      0|			j = 0;
  396|      0|			if (!argv[i]) {
  ------------------
  |  Branch (396:8): [True: 0, False: 0]
  ------------------
  397|      0|				dropbear_exit("Missing argument");
  398|      0|			}
  399|      0|		}
  400|       |
  401|      0|		if (nextisport) {
  ------------------
  |  Branch (401:7): [True: 0, False: 0]
  ------------------
  402|      0|			addportandaddress(&argv[i][j]);
  403|      0|			nextisport = 0;
  404|      0|		} else if (next) {
  ------------------
  |  Branch (404:14): [True: 0, False: 0]
  ------------------
  405|      0|			*next = &argv[i][j];
  406|      0|			if (*next == NULL) {
  ------------------
  |  Branch (406:8): [True: 0, False: 0]
  ------------------
  407|      0|				dropbear_exit("Invalid null argument");
  408|      0|			}
  409|      0|			next = NULL;
  410|       |
  411|      0|			if (keyfile) {
  ------------------
  |  Branch (411:8): [True: 0, False: 0]
  ------------------
  412|      0|				addhostkey(keyfile);
  413|      0|				keyfile = NULL;
  414|      0|			}
  415|      0|		}
  416|      0|	}
  417|       |
  418|       |	/* Set up listening ports */
  419|      1|	if (svr_opts.portcount == 0) {
  ------------------
  |  Branch (419:6): [True: 1, False: 0]
  ------------------
  420|      1|		svr_opts.ports[0] = m_strdup(DROPBEAR_DEFPORT);
  ------------------
  |  |   25|      1|#define DROPBEAR_DEFPORT "22"
  ------------------
  421|      1|		svr_opts.addresses[0] = m_strdup(DROPBEAR_DEFADDRESS);
  ------------------
  |  |   30|      1|#define DROPBEAR_DEFADDRESS ""
  ------------------
  422|      1|		svr_opts.portcount = 1;
  423|      1|	}
  424|       |
  425|      1|	if (svr_opts.bannerfile) {
  ------------------
  |  Branch (425:6): [True: 0, False: 1]
  ------------------
  426|      0|		load_banner();
  427|      0|	}
  428|       |
  429|      1|#ifdef HAVE_GETGROUPLIST
  430|      1|	if (svr_opts.restrict_group) {
  ------------------
  |  Branch (430:6): [True: 0, False: 1]
  ------------------
  431|      0|		struct group *restrictedgroup = getgrnam(svr_opts.restrict_group);
  432|       |
  433|      0|		if (restrictedgroup){
  ------------------
  |  Branch (433:7): [True: 0, False: 0]
  ------------------
  434|      0|			svr_opts.restrict_group_gid = restrictedgroup->gr_gid;
  435|      0|		} else {
  436|      0|			dropbear_exit("Cannot restrict logins to group '%s' as the group does not exist", svr_opts.restrict_group);
  437|      0|		}
  438|      0|	}
  439|      1|#endif
  440|       |
  441|      1|	if (recv_window_arg) {
  ------------------
  |  Branch (441:6): [True: 0, False: 1]
  ------------------
  442|      0|		parse_recv_window(recv_window_arg);
  443|      0|	}
  444|       |
  445|      1|	if (maxauthtries_arg) {
  ------------------
  |  Branch (445:6): [True: 0, False: 1]
  ------------------
  446|      0|		unsigned int val = 0;
  447|      0|		if (m_str_to_uint(maxauthtries_arg, &val) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (447:7): [True: 0, False: 0]
  ------------------
  448|      0|			dropbear_exit("Bad maxauthtries '%s'", maxauthtries_arg);
  449|      0|		}
  450|      0|		svr_opts.maxauthtries = val;
  451|      0|	}
  452|       |
  453|       |
  454|      1|	if (keepalive_arg) {
  ------------------
  |  Branch (454:6): [True: 0, False: 1]
  ------------------
  455|      0|		unsigned int val;
  456|      0|		if (m_str_to_uint(keepalive_arg, &val) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (456:7): [True: 0, False: 0]
  ------------------
  457|      0|			dropbear_exit("Bad keepalive '%s'", keepalive_arg);
  458|      0|		}
  459|      0|		opts.keepalive_secs = val;
  460|      0|	}
  461|       |
  462|      1|	if (idle_timeout_arg) {
  ------------------
  |  Branch (462:6): [True: 0, False: 1]
  ------------------
  463|      0|		unsigned int val;
  464|      0|		if (m_str_to_uint(idle_timeout_arg, &val) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (464:7): [True: 0, False: 0]
  ------------------
  465|      0|			dropbear_exit("Bad idle_timeout '%s'", idle_timeout_arg);
  466|      0|		}
  467|      0|		opts.idle_timeout_secs = val;
  468|      0|	}
  469|       |
  470|      1|	if (max_duration_arg) {
  ------------------
  |  Branch (470:6): [True: 0, False: 1]
  ------------------
  471|      0|		unsigned int val;
  472|      0|		if (m_str_to_uint(max_duration_arg, &val) == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (472:7): [True: 0, False: 0]
  ------------------
  473|      0|			dropbear_exit("Bad max_duration '%s'", max_duration_arg);
  474|      0|		}
  475|      0|		opts.max_duration_secs = val;
  476|      0|	}
  477|       |
  478|      1|	if (svr_opts.forced_command) {
  ------------------
  |  Branch (478:6): [True: 0, False: 1]
  ------------------
  479|      0|		dropbear_log(LOG_INFO, "Forced command set to '%s'", svr_opts.forced_command);
  480|      0|	}
  481|       |
  482|      1|	if (svr_opts.interface) {
  ------------------
  |  Branch (482:6): [True: 0, False: 1]
  ------------------
  483|      0|		dropbear_log(LOG_INFO, "Binding to interface '%s'", svr_opts.interface);
  484|      0|	}
  485|       |
  486|      1|	if (reexec_fd_arg) {
  ------------------
  |  Branch (486:6): [True: 0, False: 1]
  ------------------
  487|      0|		if (m_str_to_uint(reexec_fd_arg, &svr_opts.reexec_childpipe) == DROPBEAR_FAILURE
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (487:7): [True: 0, False: 0]
  ------------------
  488|      0|			|| svr_opts.reexec_childpipe < 0) {
  ------------------
  |  Branch (488:7): [True: 0, False: 0]
  ------------------
  489|      0|			dropbear_exit("Bad -2");
  490|      0|		}
  491|      0|	}
  492|       |
  493|      1|	if (svr_opts.multiauthmethod && svr_opts.noauthpass) {
  ------------------
  |  Branch (493:6): [True: 0, False: 1]
  |  Branch (493:34): [True: 0, False: 0]
  ------------------
  494|      0|		dropbear_exit("-t and -s are incompatible");
  495|      0|	}
  496|       |
  497|      1|	if (strlen(svr_opts.authorized_keys_dir) == 0) {
  ------------------
  |  Branch (497:6): [True: 0, False: 1]
  ------------------
  498|      0|		dropbear_exit("Bad -D");
  499|      0|	}
  500|       |
  501|       |#if DROPBEAR_PLUGIN
  502|       |	if (pubkey_plugin) {
  503|       |		svr_opts.pubkey_plugin = m_strdup(pubkey_plugin);
  504|       |		char *args = strchr(svr_opts.pubkey_plugin, ',');
  505|       |		if (args) {
  506|       |			*args='\0';
  507|       |			++args;
  508|       |		}
  509|       |		svr_opts.pubkey_plugin_options = args;
  510|       |	}
  511|       |#endif
  512|      1|	if (algo_print_arg) {
  ------------------
  |  Branch (512:6): [True: 0, False: 1]
  ------------------
  513|      0|		print_algos(algo_print_arg);
  514|       |		/* No return */
  515|      0|	}
  516|      1|}
disable_sig_except:
  560|  3.36k|void disable_sig_except(enum signature_type allow_type) {
  561|  3.36k|	int i;
  562|  3.36k|	TRACE(("Disabling other sigs except %d", allow_type));
  563|  33.6k|	for (i = 0; sigalgs[i].name != NULL; i++) {
  ------------------
  |  Branch (563:14): [True: 30.2k, False: 3.36k]
  ------------------
  564|  30.2k|		enum signature_type sig_type = sigalgs[i].val;
  565|  30.2k|		if (sig_type != allow_type) {
  ------------------
  |  Branch (565:7): [True: 26.8k, False: 3.36k]
  ------------------
  566|  26.8k|			sigalgs[i].usable = 0;
  567|  26.8k|		}
  568|  30.2k|	}
  569|  3.36k|}

recv_msg_service_request:
   37|    860|void recv_msg_service_request() {
   38|       |
   39|    860|	char * name;
   40|    860|	unsigned int len;
   41|       |
   42|    860|	TRACE(("enter recv_msg_service_request"))
   43|       |
   44|    860|	name = buf_getstring(ses.payload, &len);
   45|       |
   46|       |	/* ssh-userauth */
   47|    860|	if (len == SSH_SERVICE_USERAUTH_LEN && 
  ------------------
  |  |  109|  1.72k|#define SSH_SERVICE_USERAUTH_LEN 12
  ------------------
  |  Branch (47:6): [True: 190, False: 670]
  ------------------
   48|    190|			strncmp(SSH_SERVICE_USERAUTH, name, len) == 0) {
  ------------------
  |  |  108|    190|#define SSH_SERVICE_USERAUTH "ssh-userauth"
  ------------------
  |  Branch (48:4): [True: 84, False: 106]
  ------------------
   49|       |
   50|     84|		send_msg_service_accept(name, len);
   51|     84|		m_free(name);
  ------------------
  |  |   24|     84|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 84]
  |  |  ------------------
  ------------------
   52|     84|		TRACE(("leave recv_msg_service_request: done ssh-userauth"))
   53|     84|		return;
   54|     84|	}
   55|       |
   56|       |	/* ssh-connection */
   57|    776|	if (len == SSH_SERVICE_CONNECTION_LEN &&
  ------------------
  |  |  111|  1.55k|#define SSH_SERVICE_CONNECTION_LEN 14
  ------------------
  |  Branch (57:6): [True: 650, False: 126]
  ------------------
   58|    650|			(strncmp(SSH_SERVICE_CONNECTION, name, len) == 0)) {
  ------------------
  |  |  110|    650|#define SSH_SERVICE_CONNECTION "ssh-connection"
  ------------------
  |  Branch (58:4): [True: 537, False: 113]
  ------------------
   59|    537|		if (ses.authstate.authdone != 1) {
  ------------------
  |  Branch (59:7): [True: 0, False: 537]
  ------------------
   60|      0|			dropbear_exit("Request for connection before auth");
   61|      0|		}
   62|       |
   63|    537|		send_msg_service_accept(name, len);
   64|    537|		m_free(name);
  ------------------
  |  |   24|    537|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 537]
  |  |  ------------------
  ------------------
   65|    537|		TRACE(("leave recv_msg_service_request: done ssh-connection"))
   66|    537|		return;
   67|    537|	}
   68|       |
   69|    239|	m_free(name);
  ------------------
  |  |   24|    239|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 239]
  |  |  ------------------
  ------------------
   70|       |	/* TODO this should be a MSG_DISCONNECT */
   71|    239|	dropbear_exit("Unrecognised SSH_MSG_SERVICE_REQUEST");
   72|       |
   73|       |
   74|    776|}
svr-service.c:send_msg_service_accept:
   76|    621|static void send_msg_service_accept(const char *name, int len) {
   77|       |
   78|    621|	TRACE(("accepting service %s", name))
   79|       |
   80|    621|	CHECKCLEARTOWRITE();
   81|       |
   82|    621|	buf_putbyte(ses.writepayload, SSH_MSG_SERVICE_ACCEPT);
  ------------------
  |  |   34|    621|#define SSH_MSG_SERVICE_ACCEPT         6
  ------------------
   83|    621|	buf_putstring(ses.writepayload, name, len);
   84|       |
   85|    621|	encrypt_packet();
   86|       |
   87|    621|}

svr_session:
  108|  4.58k|void svr_session(int sock, int childpipe) {
  109|  4.58k|	char *host, *port;
  110|  4.58k|	size_t len;
  111|       |
  112|  4.58k|	common_session_init(sock, sock);
  113|       |
  114|       |	/* Initialise server specific parts of the session */
  115|  4.58k|	svr_ses.childpipe = childpipe;
  116|       |#if DROPBEAR_VFORK
  117|       |	svr_ses.server_pid = getpid();
  118|       |#endif
  119|       |
  120|       |	/* for logging the remote address */
  121|  4.58k|	get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0);
  122|  4.58k|	len = strlen(host) + strlen(port) + 2;
  123|  4.58k|	svr_ses.addrstring = m_malloc(len);
  124|  4.58k|	snprintf(svr_ses.addrstring, len, "%s:%s", host, port);
  125|  4.58k|	m_free(host);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  126|  4.58k|	m_free(port);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
  127|       |
  128|       |#if DROPBEAR_PLUGIN
  129|       |        /* Initializes the PLUGIN Plugin */
  130|       |        svr_ses.plugin_handle = NULL;
  131|       |        svr_ses.plugin_instance = NULL;
  132|       |        if (svr_opts.pubkey_plugin) {
  133|       |#if DEBUG_TRACE
  134|       |            const int verbose = debug_trace;
  135|       |#else
  136|       |            const int verbose = 0;
  137|       |#endif
  138|       |            PubkeyExtPlugin_newFn  pluginConstructor;
  139|       |
  140|       |            /* RTLD_NOW: fails if not all the symbols are resolved now. Better fail now than at run-time */
  141|       |            svr_ses.plugin_handle = dlopen(svr_opts.pubkey_plugin, RTLD_NOW);
  142|       |            if (svr_ses.plugin_handle == NULL) {
  143|       |                dropbear_exit("failed to load external pubkey plugin '%s': %s", svr_opts.pubkey_plugin, dlerror());
  144|       |            }
  145|       |            pluginConstructor = (PubkeyExtPlugin_newFn)dlsym(svr_ses.plugin_handle, DROPBEAR_PUBKEY_PLUGIN_FNNAME_NEW);
  146|       |            if (!pluginConstructor) {
  147|       |                dropbear_exit("plugin constructor method not found in external pubkey plugin");
  148|       |            }
  149|       |
  150|       |            /* Create an instance of the plugin */
  151|       |            svr_ses.plugin_instance = pluginConstructor(verbose, svr_opts.pubkey_plugin_options, svr_ses.addrstring);
  152|       |            if (svr_ses.plugin_instance == NULL) {
  153|       |                dropbear_exit("external plugin initialization failed");
  154|       |            }
  155|       |            /* Check if the plugin is compatible */
  156|       |            if ( (svr_ses.plugin_instance->api_version[0] != DROPBEAR_PLUGIN_VERSION_MAJOR) ||
  157|       |                 (svr_ses.plugin_instance->api_version[1] < DROPBEAR_PLUGIN_VERSION_MINOR) ) {
  158|       |                dropbear_exit("plugin version check failed: "
  159|       |                              "Dropbear=%d.%d, plugin=%d.%d",
  160|       |                        DROPBEAR_PLUGIN_VERSION_MAJOR, DROPBEAR_PLUGIN_VERSION_MINOR,
  161|       |                        svr_ses.plugin_instance->api_version[0], svr_ses.plugin_instance->api_version[1]);
  162|       |            }
  163|       |            if (svr_ses.plugin_instance->api_version[1] > DROPBEAR_PLUGIN_VERSION_MINOR) {
  164|       |                dropbear_log(LOG_WARNING, "plugin API newer than dropbear API: "
  165|       |                              "Dropbear=%d.%d, plugin=%d.%d",
  166|       |                        DROPBEAR_PLUGIN_VERSION_MAJOR, DROPBEAR_PLUGIN_VERSION_MINOR,
  167|       |                        svr_ses.plugin_instance->api_version[0], svr_ses.plugin_instance->api_version[1]);
  168|       |            }
  169|       |            dropbear_log(LOG_INFO, "successfully loaded and initialized pubkey plugin '%s'", svr_opts.pubkey_plugin);
  170|       |        }
  171|       |#endif
  172|       |
  173|  4.58k|	svr_authinitialise();
  174|  4.58k|	chaninitialise(svr_chantypes);
  175|  4.58k|	svr_chansessinitialise();
  176|  4.58k|	svr_algos_initialise();
  177|       |
  178|  4.58k|	get_socket_address(ses.sock_in, NULL, NULL, 
  179|  4.58k|			&svr_ses.remotehost, NULL, 1);
  180|       |
  181|       |	/* set up messages etc */
  182|  4.58k|	ses.remoteclosed = svr_remoteclosed;
  183|  4.58k|	ses.extra_session_cleanup = svr_session_cleanup;
  184|       |
  185|       |	/* packet handlers */
  186|  4.58k|	ses.packettypes = svr_packettypes;
  187|       |
  188|  4.58k|	ses.isserver = 1;
  189|       |
  190|       |	/* We're ready to go now */
  191|  4.58k|	ses.init_done = 1;
  192|       |
  193|       |	/* exchange identification, version etc */
  194|  4.58k|	send_session_identification();
  195|       |	
  196|  4.58k|	kexfirstinitialise(); /* initialise the kex state */
  197|       |
  198|       |	/* start off with key exchange */
  199|  4.58k|	send_msg_kexinit();
  200|       |
  201|  4.58k|#if DROPBEAR_FUZZ
  202|  4.58k|    if (fuzz.fuzzing) {
  ------------------
  |  Branch (202:9): [True: 4.58k, False: 0]
  ------------------
  203|  4.58k|        fuzz_svr_hook_preloop();
  204|  4.58k|    }
  205|  4.58k|#endif
  206|       |
  207|       |	/* Run the main for-loop. */
  208|  4.58k|	session_loop(svr_chansess_checksignal);
  209|       |
  210|       |	/* Not reached */
  211|       |
  212|  4.58k|}
svr_dropbear_exit:
  215|  4.58k|void svr_dropbear_exit(int exitcode, const char* format, va_list param) {
  216|  4.58k|	char exitmsg[150];
  217|  4.58k|	char fullmsg[300];
  218|  4.58k|	char fromaddr[60];
  219|  4.58k|	int i;
  220|  4.58k|	int add_delay = 0;
  221|       |
  222|       |#if DROPBEAR_PLUGIN
  223|       |	if ((ses.plugin_session != NULL)) {
  224|       |		svr_ses.plugin_instance->delete_session(ses.plugin_session);
  225|       |	}
  226|       |	ses.plugin_session = NULL;
  227|       |	svr_opts.pubkey_plugin_options = NULL;
  228|       |	m_free(svr_opts.pubkey_plugin);
  229|       |#endif
  230|       |
  231|       |	/* Render the formatted exit message */
  232|  4.58k|	vsnprintf(exitmsg, sizeof(exitmsg), format, param);
  233|       |
  234|       |	/* svr_ses.addrstring may not be set for some early exits, or for
  235|       |	the listener process */
  236|  4.58k|	fromaddr[0] = '\0';
  237|  4.58k|	if (svr_ses.addrstring) {
  ------------------
  |  Branch (237:6): [True: 4.58k, False: 0]
  ------------------
  238|  4.58k|	    snprintf(fromaddr, sizeof(fromaddr), " from <%s>", svr_ses.addrstring);
  239|  4.58k|    }
  240|       |
  241|       |	/* Add the prefix depending on session/auth state */
  242|  4.58k|	if (!ses.init_done) {
  ------------------
  |  Branch (242:6): [True: 0, False: 4.58k]
  ------------------
  243|       |		/* before session init */
  244|      0|		snprintf(fullmsg, sizeof(fullmsg), "Early exit%s: %s", fromaddr, exitmsg);
  245|  4.58k|	} else if (ses.authstate.authdone) {
  ------------------
  |  Branch (245:13): [True: 4.58k, False: 0]
  ------------------
  246|       |		/* user has authenticated */
  247|  4.58k|		snprintf(fullmsg, sizeof(fullmsg),
  248|  4.58k|				"Exit (%s)%s: %s", 
  249|  4.58k|				ses.authstate.pw_name, fromaddr, exitmsg);
  250|  4.58k|	} else if (ses.authstate.pw_name) {
  ------------------
  |  Branch (250:13): [True: 0, False: 0]
  ------------------
  251|       |		/* we have a potential user */
  252|      0|		snprintf(fullmsg, sizeof(fullmsg), 
  253|      0|				"Exit before auth%s: (user '%s', %u fails): %s",
  254|      0|				fromaddr, ses.authstate.pw_name, ses.authstate.failcount, exitmsg);
  255|      0|		add_delay = 1;
  256|      0|	} else {
  257|       |		/* before userauth */
  258|      0|		snprintf(fullmsg, sizeof(fullmsg), "Exit before auth%s: %s", fromaddr, exitmsg);
  259|      0|		add_delay = 1;
  260|      0|	}
  261|       |
  262|  4.58k|	dropbear_log(LOG_INFO, "%s", fullmsg);
  263|       |
  264|       |	/* To make it harder for attackers, introduce a delay to keep an
  265|       |	 * unauthenticated session open a bit longer, thus blocking a connection
  266|       |	 * slot until after the delay. Without this, while there is a limit on
  267|       |	 * the amount of attempts an attacker can make at the same time
  268|       |	 * (MAX_UNAUTH_PER_IP), the time taken by dropbear to handle one attempt
  269|       |	 * is still short and thus for each of the allowed parallel attempts
  270|       |	 * many attempts can be chained one after the other. The attempt rate is
  271|       |	 * then:
  272|       |	 *     "MAX_UNAUTH_PER_IP / <process time of one attempt>".
  273|       |	 * With the delay, this rate becomes:
  274|       |	 *     "MAX_UNAUTH_PER_IP / UNAUTH_CLOSE_DELAY".
  275|       |	 */
  276|  4.58k|	if ((add_delay != 0) && (UNAUTH_CLOSE_DELAY > 0)) {
  ------------------
  |  |  499|      0|#define UNAUTH_CLOSE_DELAY 0
  ------------------
  |  Branch (276:6): [True: 0, False: 4.58k]
  |  Branch (276:26): [Folded, False: 0]
  ------------------
  277|      0|		TRACE(("svr_dropbear_exit: start delay of %d seconds", UNAUTH_CLOSE_DELAY));
  278|      0|		sleep(UNAUTH_CLOSE_DELAY);
  ------------------
  |  |  499|      0|#define UNAUTH_CLOSE_DELAY 0
  ------------------
  279|      0|		TRACE(("svr_dropbear_exit: end delay of %d seconds", UNAUTH_CLOSE_DELAY));
  280|      0|	}
  281|       |
  282|       |#if DROPBEAR_VFORK
  283|       |	/* For uclinux only the main server process should cleanup - we don't want
  284|       |	 * forked children doing that */
  285|       |	if (svr_ses.server_pid == getpid())
  286|       |#endif
  287|  4.58k|	{
  288|       |		/* must be after we've done with username etc */
  289|  4.58k|		session_cleanup();
  290|  4.58k|	}
  291|       |
  292|  4.58k|#if DROPBEAR_FUZZ
  293|       |	/* longjmp before cleaning up svr_opts */
  294|  4.58k|    if (fuzz.do_jmp) {
  ------------------
  |  Branch (294:9): [True: 4.58k, False: 0]
  ------------------
  295|  4.58k|        longjmp(fuzz.jmp, 1);
  296|  4.58k|    }
  297|      0|#endif
  298|       |
  299|      0|	if (svr_opts.hostkey) {
  ------------------
  |  Branch (299:6): [True: 0, False: 0]
  ------------------
  300|      0|		sign_key_free(svr_opts.hostkey);
  301|      0|		svr_opts.hostkey = NULL;
  302|      0|	}
  303|      0|	for (i = 0; i < DROPBEAR_MAX_PORTS; i++) {
  ------------------
  |  |   89|      0|#define DROPBEAR_MAX_PORTS 10 /* max number of ports which can be specified,
  ------------------
  |  Branch (303:14): [True: 0, False: 0]
  ------------------
  304|      0|		m_free(svr_opts.addresses[i]);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  305|      0|		m_free(svr_opts.ports[i]);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  306|      0|	}
  307|       |
  308|       |    
  309|      0|	exit(exitcode);
  310|       |
  311|  4.58k|}
svr-session.c:svr_session_cleanup:
   86|  4.58k|svr_session_cleanup(void) {
   87|  4.58k|	svr_pubkey_options_cleanup(ses.authstate.pubkey_options);
   88|  4.58k|	ses.authstate.pubkey_options = NULL;
   89|       |
   90|  4.58k|	m_free(svr_ses.addrstring);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
   91|  4.58k|	m_free(svr_ses.remotehost);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
   92|  4.58k|	m_free(svr_ses.childpids);
  ------------------
  |  |   24|  4.58k|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 4.58k]
  |  |  ------------------
  ------------------
   93|  4.58k|	svr_ses.childpidsize = 0;
   94|       |
   95|       |#if DROPBEAR_PLUGIN
   96|       |        if (svr_ses.plugin_handle != NULL) {
   97|       |            if (svr_ses.plugin_instance) {
   98|       |                svr_ses.plugin_instance->delete_plugin(svr_ses.plugin_instance);
   99|       |                svr_ses.plugin_instance = NULL;
  100|       |            }
  101|       |
  102|       |            dlclose(svr_ses.plugin_handle);
  103|       |            svr_ses.plugin_handle = NULL;
  104|       |        }
  105|       |#endif
  106|  4.58k|}
svr-session.c:svr_remoteclosed:
  351|  2.69k|static void svr_remoteclosed() {
  352|       |
  353|  2.69k|	m_close(ses.sock_in);
  354|  2.69k|	if (ses.sock_in != ses.sock_out) {
  ------------------
  |  Branch (354:6): [True: 0, False: 2.69k]
  ------------------
  355|      0|		m_close(ses.sock_out);
  356|      0|	}
  357|  2.69k|	ses.sock_in = -1;
  358|  2.69k|	ses.sock_out = -1;
  359|  2.69k|	dropbear_close("Exited normally");
  360|       |
  361|  2.69k|}
svr-session.c:svr_algos_initialise:
  363|  4.58k|static void svr_algos_initialise(void) {
  364|  4.58k|	algo_type *algo;
  365|  64.1k|	for (algo = sshkex; algo->name; algo++) {
  ------------------
  |  Branch (365:22): [True: 59.5k, False: 4.58k]
  ------------------
  366|       |#if DROPBEAR_DH_GROUP1 && DROPBEAR_DH_GROUP1_CLIENTONLY
  367|       |		if (strcmp(algo->name, "diffie-hellman-group1-sha1") == 0) {
  368|       |			algo->usable = 0;
  369|       |		}
  370|       |#endif
  371|  59.5k|#if DROPBEAR_EXT_INFO
  372|  59.5k|		if (strcmp(algo->name, SSH_EXT_INFO_C) == 0) {
  ------------------
  |  |  100|  59.5k|#define SSH_EXT_INFO_C "ext-info-c"
  ------------------
  |  Branch (372:7): [True: 4.58k, False: 54.9k]
  ------------------
  373|  4.58k|			algo->usable = 0;
  374|  4.58k|		}
  375|  59.5k|#endif
  376|  59.5k|		if (strcmp(algo->name, SSH_STRICT_KEX_C) == 0) {
  ------------------
  |  |  105|  59.5k|#define SSH_STRICT_KEX_C "kex-strict-c-v00@openssh.com"
  ------------------
  |  Branch (376:7): [True: 4.58k, False: 54.9k]
  ------------------
  377|  4.58k|			algo->usable = 0;
  378|  4.58k|		}
  379|  59.5k|	}
  380|  4.58k|}

svr-streamfwd.c:newstreamlocal:
  266|    147|static int newstreamlocal(struct Channel * channel) {
  267|       |
  268|       |    /*
  269|       |    https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL#rev1.30
  270|       |
  271|       |    byte        SSH_MSG_CHANNEL_OPEN
  272|       |    string      "direct-streamlocal@openssh.com"
  273|       |    uint32      sender channel
  274|       |    uint32      initial window size
  275|       |    uint32      maximum packet size
  276|       |    string      socket path
  277|       |    string      reserved
  278|       |    uint32      reserved
  279|       |    */
  280|       |
  281|    147|    char* destsocket = NULL;
  282|    147|    unsigned int len;
  283|    147|    int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
  ------------------
  |  |   33|    147|#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED    1
  ------------------
  284|       |
  285|    147|    TRACE(("streamlocal channel %d", channel->index))
  286|       |
  287|    147|    if (svr_opts.forced_command || svr_pubkey_has_forced_command()) {
  ------------------
  |  Branch (287:9): [True: 0, False: 147]
  |  Branch (287:36): [True: 0, False: 147]
  ------------------
  288|      0|        TRACE(("leave newstreamlocal: no unix forwarding for forced command"))
  289|      0|        goto out;
  290|      0|    }
  291|       |
  292|    147|    if (svr_opts.nolocaltcp || !svr_pubkey_allows_tcpfwd()) {
  ------------------
  |  Branch (292:9): [True: 0, False: 147]
  |  Branch (292:32): [True: 0, False: 147]
  ------------------
  293|      0|        TRACE(("leave newstreamlocal: local unix forwarding disabled"))
  294|      0|        goto out;
  295|      0|    }
  296|       |
  297|    147|    destsocket = buf_getstring(ses.payload, &len);
  298|    147|    if (len > MAX_HOST_LEN) {
  ------------------
  |  |   87|    147|#define MAX_HOST_LEN 254 /* max hostname len for tcp fwding */
  ------------------
  |  Branch (298:9): [True: 97, False: 50]
  ------------------
  299|     97|        TRACE(("leave streamlocal: destsocket too long"))
  300|     97|        goto out;
  301|     97|    }
  302|       |
  303|     50|    channel->conn_pending = connect_streamlocal(destsocket, channel_connect_done,
  304|     50|        channel, DROPBEAR_PRIO_NORMAL);
  305|       |
  306|     50|    err = SSH_OPEN_IN_PROGRESS;
  ------------------
  |  |   39|     50|#define SSH_OPEN_IN_PROGRESS					99
  ------------------
  307|       |
  308|    145|out:
  309|       |    m_free(destsocket);
  ------------------
  |  |   24|    145|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 145]
  |  |  ------------------
  ------------------
  310|    145|    TRACE(("leave streamlocal: err %d", err))
  311|    145|    return err;
  312|     50|}

svr_cancelremotetcp:
   33|    196|int svr_cancelremotetcp(void) {
   34|       |
   35|    196|    int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|    196|#define DROPBEAR_FAILURE -1
  ------------------
   36|    196|    char * request_addr = NULL;
   37|    196|    unsigned int addrlen;
   38|    196|    unsigned int port;
   39|    196|    struct Listener * listener = NULL;
   40|    196|    struct FwdListener tcpinfo;
   41|       |
   42|    196|    TRACE(("enter cancelremotetcp"))
   43|       |
   44|    196|    request_addr = buf_getstring(ses.payload, &addrlen);
   45|    196|    if (addrlen > MAX_HOST_LEN) {
  ------------------
  |  |   87|    196|#define MAX_HOST_LEN 254 /* max hostname len for tcp fwding */
  ------------------
  |  Branch (45:9): [True: 71, False: 125]
  ------------------
   46|     71|        TRACE(("addr len too long: %d", addrlen))
   47|     71|        goto out;
   48|     71|    }
   49|       |
   50|    125|    port = buf_getint(ses.payload);
   51|       |
   52|    125|    memset(&tcpinfo, 0x0, sizeof(tcpinfo));
   53|    125|    tcpinfo.request_listenaddr = request_addr;
   54|    125|    tcpinfo.listenport = port;
   55|    125|    listener = get_listener(LISTENER_TYPE_TCPFORWARDED, &tcpinfo, matchtcp);
   56|    125|    if (listener) {
  ------------------
  |  Branch (56:9): [True: 0, False: 125]
  ------------------
   57|      0|        remove_listener(listener);
   58|      0|        ret = DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
   59|      0|    }
   60|       |
   61|    193|out:
   62|       |    m_free(request_addr);
  ------------------
  |  |   24|    193|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 193]
  |  |  ------------------
  ------------------
   63|    193|    TRACE(("leave cancelremotetcp"))
   64|    193|    return ret;
   65|    125|}
svr_remotetcpreq:
   68|    372|int svr_remotetcpreq(int wantreply) {
   69|       |
   70|    372|    int ret = DROPBEAR_FAILURE;
  ------------------
  |  |  112|    372|#define DROPBEAR_FAILURE -1
  ------------------
   71|    372|    char * request_addr = NULL;
   72|    372|    unsigned int addrlen;
   73|    372|    struct FwdListener *tcpinfo = NULL;
   74|    372|    unsigned int port;
   75|    372|    struct Listener *listener = NULL;
   76|       |
   77|    372|    TRACE(("enter remotetcpreq"))
   78|       |
   79|    372|    request_addr = buf_getstring(ses.payload, &addrlen);
   80|    372|    if (addrlen > MAX_HOST_LEN) {
  ------------------
  |  |   87|    372|#define MAX_HOST_LEN 254 /* max hostname len for tcp fwding */
  ------------------
  |  Branch (80:9): [True: 21, False: 351]
  ------------------
   81|     21|        TRACE(("addr len too long: %d", addrlen))
   82|     21|        goto out;
   83|     21|    }
   84|       |
   85|    351|    port = buf_getint(ses.payload);
   86|       |
   87|    351|    if (port != 0) {
  ------------------
  |  Branch (87:9): [True: 234, False: 117]
  ------------------
   88|    234|        if (port < 1 || port > 65535) {
  ------------------
  |  Branch (88:13): [True: 0, False: 234]
  |  Branch (88:25): [True: 104, False: 130]
  ------------------
   89|    104|            TRACE(("invalid port: %d", port))
   90|    104|            goto out;
   91|    104|        }
   92|       |
   93|    130|        if (!ses.allowprivport && port < IPPORT_RESERVED) {
  ------------------
  |  Branch (93:13): [True: 130, False: 0]
  |  Branch (93:35): [True: 29, False: 101]
  ------------------
   94|     29|            TRACE(("can't assign port < 1024 for non-root"))
   95|     29|            goto out;
   96|     29|        }
   97|    130|    }
   98|       |
   99|    218|    if (!svr_pubkey_allows_remote_tcpfwd(request_addr, port)) {
  ------------------
  |  Branch (99:9): [True: 0, False: 218]
  ------------------
  100|      0|        TRACE(("remote tcp forwarding listen address not permitted"));
  101|      0|        goto out;
  102|      0|    }
  103|       |
  104|    218|    tcpinfo = (struct FwdListener*)m_malloc(sizeof(struct FwdListener));
  105|    218|    tcpinfo->sendaddr = NULL;
  106|    218|    tcpinfo->sendport = 0;
  107|    218|    tcpinfo->listenport = port;
  108|    218|    tcpinfo->chantype = &svr_chan_tcpremote;
  109|    218|    tcpinfo->fwd_type = forwarded;
  110|    218|    tcpinfo->interface = svr_opts.interface;
  111|       |
  112|    218|    tcpinfo->request_listenaddr = request_addr;
  113|    218|    if (!opts.listen_fwd_all || (strcmp(request_addr, "localhost") == 0) ) {
  ------------------
  |  Branch (113:9): [True: 218, False: 0]
  |  Branch (113:33): [True: 0, False: 0]
  ------------------
  114|       |        /* NULL means "localhost only" */
  115|    209|        tcpinfo->listenaddr = NULL;
  116|    209|    }
  117|      9|    else
  118|      9|    {
  119|      9|        tcpinfo->listenaddr = m_strdup(request_addr);
  120|      9|    }
  121|       |
  122|    218|    ret = listen_tcpfwd(tcpinfo, &listener);
  123|    218|    if (DROPBEAR_SUCCESS == ret) {
  ------------------
  |  |  111|    218|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (123:9): [True: 0, False: 218]
  ------------------
  124|      0|        tcpinfo->listenport = get_sock_port(listener->socks[0]);
  125|      0|    }
  126|       |
  127|    363|out:
  128|       |    /* Send a reply if needed */
  129|    363|    if (wantreply) {
  ------------------
  |  Branch (129:9): [True: 330, False: 33]
  ------------------
  130|    330|        CHECKCLEARTOWRITE();
  131|    330|        if (ret == DROPBEAR_SUCCESS) {
  ------------------
  |  |  111|    330|#define DROPBEAR_SUCCESS 0
  ------------------
  |  Branch (131:13): [True: 0, False: 330]
  ------------------
  132|      0|            buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_SUCCESS);
  ------------------
  |  |   64|      0|#define SSH_MSG_REQUEST_SUCCESS                 81
  ------------------
  133|      0|            if (port == 0) {
  ------------------
  |  Branch (133:17): [True: 0, False: 0]
  ------------------
  134|       |                /* port is only included if allocated */
  135|      0|                buf_putint(ses.writepayload, tcpinfo->listenport);
  136|      0|            }
  137|    330|        } else {
  138|    330|            buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_FAILURE);
  ------------------
  |  |   65|    330|#define SSH_MSG_REQUEST_FAILURE                 82
  ------------------
  139|    330|        }
  140|    330|        encrypt_packet();
  141|    330|    }
  142|       |
  143|    363|    if (ret == DROPBEAR_FAILURE) {
  ------------------
  |  |  112|    363|#define DROPBEAR_FAILURE -1
  ------------------
  |  Branch (143:9): [True: 363, False: 0]
  ------------------
  144|       |        /* we only free it if a listener wasn't created, since the listener
  145|       |         * has to remember it if it's to be cancelled */
  146|    363|        m_free(request_addr);
  ------------------
  |  |   24|    363|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 363]
  |  |  ------------------
  ------------------
  147|    363|        m_free(tcpinfo);
  ------------------
  |  |   24|    363|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 363]
  |  |  ------------------
  ------------------
  148|    363|    }
  149|       |
  150|    363|    TRACE(("leave remotetcpreq"))
  151|       |
  152|    363|    return ret;
  153|    218|}
svr-tcpfwd.c:newtcpdirect:
  163|    302|static int newtcpdirect(struct Channel * channel) {
  164|       |
  165|    302|    char* desthost = NULL;
  166|    302|    unsigned int destport;
  167|    302|    char* orighost = NULL;
  168|    302|    unsigned int origport;
  169|    302|    char portstring[NI_MAXSERV];
  170|    302|    unsigned int len;
  171|    302|    int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
  ------------------
  |  |   33|    302|#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED    1
  ------------------
  172|       |
  173|    302|    TRACE(("newtcpdirect channel %d", channel->index))
  174|       |
  175|    302|    if (svr_opts.nolocaltcp || !svr_pubkey_allows_tcpfwd()) {
  ------------------
  |  Branch (175:9): [True: 0, False: 302]
  |  Branch (175:32): [True: 0, False: 302]
  ------------------
  176|      0|        TRACE(("leave newtcpdirect: local tcp forwarding disabled"))
  177|      0|        goto out;
  178|      0|    }
  179|       |
  180|    302|    desthost = buf_getstring(ses.payload, &len);
  181|    302|    if (len > MAX_HOST_LEN) {
  ------------------
  |  |   87|    302|#define MAX_HOST_LEN 254 /* max hostname len for tcp fwding */
  ------------------
  |  Branch (181:9): [True: 36, False: 266]
  ------------------
  182|     36|        TRACE(("leave newtcpdirect: desthost too long"))
  183|     36|        goto out;
  184|     36|    }
  185|       |
  186|    266|    destport = buf_getint(ses.payload);
  187|       |    
  188|    266|    orighost = buf_getstring(ses.payload, &len);
  189|    266|    if (len > MAX_HOST_LEN) {
  ------------------
  |  |   87|    266|#define MAX_HOST_LEN 254 /* max hostname len for tcp fwding */
  ------------------
  |  Branch (189:9): [True: 18, False: 248]
  ------------------
  190|     18|        TRACE(("leave newtcpdirect: orighost too long"))
  191|     18|        goto out;
  192|     18|    }
  193|       |
  194|    248|    origport = buf_getint(ses.payload);
  195|       |
  196|       |    /* best be sure */
  197|    248|    if (origport > 65535 || destport > 65535) {
  ------------------
  |  Branch (197:9): [True: 95, False: 153]
  |  Branch (197:29): [True: 64, False: 89]
  ------------------
  198|    141|        TRACE(("leave newtcpdirect: port > 65535"))
  199|    141|        goto out;
  200|    141|    }
  201|       |
  202|    107|    if (!svr_pubkey_allows_local_tcpfwd(desthost, destport)) {
  ------------------
  |  Branch (202:9): [True: 0, False: 107]
  ------------------
  203|      0|        TRACE(("leave newtcpdirect: local tcp forwarding not permitted to requested destination"));
  204|      0|        goto out;
  205|      0|    }
  206|       |
  207|    107|    snprintf(portstring, sizeof(portstring), "%u", destport);
  208|    107|    channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done,
  209|    107|        channel, NULL, NULL, DROPBEAR_PRIO_NORMAL);
  210|       |
  211|    107|    err = SSH_OPEN_IN_PROGRESS;
  ------------------
  |  |   39|    107|#define SSH_OPEN_IN_PROGRESS					99
  ------------------
  212|       |
  213|    284|out:
  214|    284|    m_free(desthost);
  ------------------
  |  |   24|    284|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 284]
  |  |  ------------------
  ------------------
  215|       |    m_free(orighost);
  ------------------
  |  |   24|    284|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 284]
  |  |  ------------------
  ------------------
  216|    284|    TRACE(("leave newtcpdirect: err %d", err))
  217|    284|    return err;
  218|    107|}

listen_tcpfwd:
  106|    209|int listen_tcpfwd(struct FwdListener* tcpinfo, struct Listener **ret_listener) {
  107|       |
  108|    209|	char portstring[NI_MAXSERV];
  109|    209|	int socks[DROPBEAR_MAX_SOCKS];
  110|    209|	int nsocks;
  111|    209|	struct Listener *listener;
  112|    209|	char* errstring = NULL;
  113|       |
  114|    209|	TRACE(("enter listen_tcpfwd"))
  115|       |
  116|       |	/* first we try to bind, so don't need to do so much cleanup on failure */
  117|    209|	snprintf(portstring, sizeof(portstring), "%u", tcpinfo->listenport);
  118|       |
  119|    209|	nsocks = dropbear_listen(tcpinfo->listenaddr, portstring, socks, 
  120|    209|			DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd, tcpinfo->interface);
  ------------------
  |  |  292|    209|#define DROPBEAR_MAX_SOCKS 2 /* IPv4, IPv6 are all we'll get for now. Revisit
  ------------------
  121|    209|	if (nsocks < 0) {
  ------------------
  |  Branch (121:6): [True: 209, False: 0]
  ------------------
  122|    209|		dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring);
  123|    209|		m_free(errstring);
  ------------------
  |  |   24|    209|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 209]
  |  |  ------------------
  ------------------
  124|    209|		TRACE(("leave listen_tcpfwd: dropbear_listen failed"))
  125|    209|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|    209|#define DROPBEAR_FAILURE -1
  ------------------
  126|    209|	}
  127|      0|	m_free(errstring);
  ------------------
  |  |   24|      0|#define m_free(X) do {m_free_direct(X); (X) = NULL;} while (0)
  |  |  ------------------
  |  |  |  Branch (24:61): [Folded, False: 0]
  |  |  ------------------
  ------------------
  128|       |	
  129|       |	/* new_listener will close the socks if it fails */
  130|      0|	listener = new_listener(socks, nsocks, LISTENER_TYPE_TCPFORWARDED, tcpinfo,
  131|      0|			tcp_acceptor, cleanup_tcp);
  132|       |
  133|      0|	if (listener == NULL) {
  ------------------
  |  Branch (133:6): [True: 0, False: 0]
  ------------------
  134|      0|		TRACE(("leave listen_tcpfwd: listener failed"))
  135|      0|		return DROPBEAR_FAILURE;
  ------------------
  |  |  112|      0|#define DROPBEAR_FAILURE -1
  ------------------
  136|      0|	}
  137|       |
  138|      0|	if (ret_listener) {
  ------------------
  |  Branch (138:6): [True: 0, False: 0]
  ------------------
  139|      0|		*ret_listener = listener;
  140|      0|	}
  141|       |
  142|      0|	TRACE(("leave listen_tcpfwd: success"))
  143|      0|	return DROPBEAR_SUCCESS;
  ------------------
  |  |  111|      0|#define DROPBEAR_SUCCESS 0
  ------------------
  144|      0|}

