version 1.230, 2016/03/07 19:02:43 |
version 1.231, 2016/07/08 03:44:42 |
|
|
{ |
{ |
struct session_state *state = ssh->state; |
struct session_state *state = ssh->state; |
u_int padlen, need; |
u_int padlen, need; |
u_char *cp, macbuf[SSH_DIGEST_MAX_LENGTH]; |
u_char *cp; |
u_int maclen, aadlen = 0, authlen = 0, block_size; |
u_int maclen, aadlen = 0, authlen = 0, block_size; |
struct sshenc *enc = NULL; |
struct sshenc *enc = NULL; |
struct sshmac *mac = NULL; |
struct sshmac *mac = NULL; |
|
|
* 'maclen' bytes of message authentication code. |
* 'maclen' bytes of message authentication code. |
*/ |
*/ |
if (sshbuf_len(state->input) < aadlen + need + authlen + maclen) |
if (sshbuf_len(state->input) < aadlen + need + authlen + maclen) |
return 0; |
return 0; /* packet is incomplete */ |
#ifdef PACKET_DEBUG |
#ifdef PACKET_DEBUG |
fprintf(stderr, "read_poll enc/full: "); |
fprintf(stderr, "read_poll enc/full: "); |
sshbuf_dump(state->input, stderr); |
sshbuf_dump(state->input, stderr); |
#endif |
#endif |
/* EtM: compute mac over encrypted input */ |
/* EtM: check mac over encrypted input */ |
if (mac && mac->enabled && mac->etm) { |
if (mac && mac->enabled && mac->etm) { |
if ((r = mac_compute(mac, state->p_read.seqnr, |
if ((r = mac_check(mac, state->p_read.seqnr, |
sshbuf_ptr(state->input), aadlen + need, |
sshbuf_ptr(state->input), aadlen + need, |
macbuf, sizeof(macbuf))) != 0) |
sshbuf_ptr(state->input) + aadlen + need + authlen, |
|
maclen)) != 0) { |
|
if (r == SSH_ERR_MAC_INVALID) |
|
logit("Corrupted MAC on input."); |
goto out; |
goto out; |
|
} |
} |
} |
if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need, |
if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need, |
&cp)) != 0) |
&cp)) != 0) |
|
|
goto out; |
goto out; |
if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0) |
if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0) |
goto out; |
goto out; |
/* |
|
* compute MAC over seqnr and packet, |
|
* increment sequence number for incoming packet |
|
*/ |
|
if (mac && mac->enabled) { |
if (mac && mac->enabled) { |
if (!mac->etm) |
/* Not EtM: check MAC over cleartext */ |
if ((r = mac_compute(mac, state->p_read.seqnr, |
if (!mac->etm && (r = mac_check(mac, state->p_read.seqnr, |
sshbuf_ptr(state->incoming_packet), |
sshbuf_ptr(state->incoming_packet), |
sshbuf_len(state->incoming_packet), |
sshbuf_len(state->incoming_packet), |
macbuf, sizeof(macbuf))) != 0) |
sshbuf_ptr(state->input), maclen)) != 0) { |
|
if (r != SSH_ERR_MAC_INVALID) |
goto out; |
goto out; |
if (timingsafe_bcmp(macbuf, sshbuf_ptr(state->input), |
|
mac->mac_len) != 0) { |
|
logit("Corrupted MAC on input."); |
logit("Corrupted MAC on input."); |
if (need > PACKET_MAX_SIZE) |
if (need > PACKET_MAX_SIZE) |
return SSH_ERR_INTERNAL_ERROR; |
return SSH_ERR_INTERNAL_ERROR; |
return ssh_packet_start_discard(ssh, enc, mac, |
return ssh_packet_start_discard(ssh, enc, mac, |
state->packlen, PACKET_MAX_SIZE - need); |
state->packlen, PACKET_MAX_SIZE - need); |
} |
} |
|
/* Remove MAC from input buffer */ |
DBG(debug("MAC #%d ok", state->p_read.seqnr)); |
DBG(debug("MAC #%d ok", state->p_read.seqnr)); |
if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) |
if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) |
goto out; |
goto out; |