mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-07 18:50:27 +09:00
packet: Prepare counters to handle rekeying limits
Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Daiki Ueno <dueno@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
92e978f2f3
commit
a61368a06a
15
src/packet.c
15
src/packet.c
@@ -1151,6 +1151,13 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
||||
#endif /* WITH_ZLIB */
|
||||
payloadsize = ssh_buffer_get_len(session->in_buffer);
|
||||
session->recv_seq++;
|
||||
if (session->current_crypto != NULL) {
|
||||
struct ssh_cipher_struct *cipher = NULL;
|
||||
|
||||
cipher = session->current_crypto->in_cipher;
|
||||
cipher->packets++;
|
||||
cipher->blocks += payloadsize / cipher->blocksize;
|
||||
}
|
||||
if (session->raw_counter != NULL) {
|
||||
session->raw_counter->in_bytes += payloadsize;
|
||||
session->raw_counter->in_packets++;
|
||||
@@ -1486,6 +1493,13 @@ static int packet_send2(ssh_session session)
|
||||
|
||||
rc = ssh_packet_write(session);
|
||||
session->send_seq++;
|
||||
if (session->current_crypto != NULL) {
|
||||
struct ssh_cipher_struct *cipher = NULL;
|
||||
|
||||
cipher = session->current_crypto->out_cipher;
|
||||
cipher->packets++;
|
||||
cipher->blocks += payloadsize / cipher->blocksize;
|
||||
}
|
||||
if (session->raw_counter != NULL) {
|
||||
session->raw_counter->out_bytes += payloadsize;
|
||||
session->raw_counter->out_packets++;
|
||||
@@ -1504,7 +1518,6 @@ error:
|
||||
return rc; /* SSH_OK, AGAIN or ERROR */
|
||||
}
|
||||
|
||||
|
||||
int ssh_packet_send(ssh_session session) {
|
||||
return packet_send2(session);
|
||||
}
|
||||
|
||||
@@ -136,6 +136,33 @@ error:
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_init_rekey_state(struct ssh_session_struct *session,
|
||||
struct ssh_cipher_struct *cipher)
|
||||
{
|
||||
/* Reset the counters: should be NOOP */
|
||||
cipher->packets = 0;
|
||||
cipher->blocks = 0;
|
||||
|
||||
/* Default rekey limits for ciphers as specified in RFC4344, Section 3.2 */
|
||||
if (cipher->blocksize >= 16) {
|
||||
/* For larger block size (L bits) use maximum of 2**(L/4) blocks */
|
||||
cipher->max_blocks = (uint64_t)1 << (cipher->blocksize*2);
|
||||
} else {
|
||||
/* For smaller blocks use limit of 1 GB as recommended in RFC4253 */
|
||||
cipher->max_blocks = ((uint64_t)1 << 30) / cipher->blocksize;
|
||||
}
|
||||
/* If we have limit provided by user, use the smaller one */
|
||||
if (session->opts.rekey_data != 0) {
|
||||
cipher->max_blocks = MIN(cipher->max_blocks,
|
||||
session->opts.rekey_data / cipher->blocksize);
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"Set rekey after %" PRIu64 " blocks",
|
||||
cipher->max_blocks);
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_newkeys){
|
||||
ssh_string sig_blob = NULL;
|
||||
ssh_signature sig = NULL;
|
||||
@@ -234,6 +261,17 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
|
||||
/* FIXME later, include a function to change keys */
|
||||
session->current_crypto = session->next_crypto;
|
||||
|
||||
/* Initialize rekeying states */
|
||||
ssh_init_rekey_state(session,
|
||||
session->current_crypto->out_cipher);
|
||||
ssh_init_rekey_state(session,
|
||||
session->current_crypto->in_cipher);
|
||||
if (session->opts.rekey_time != 0) {
|
||||
ssh_timestamp_init(&session->last_rekey_time);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Set rekey after %" PRIu32 " seconds",
|
||||
session->opts.rekey_time/1000);
|
||||
}
|
||||
|
||||
session->next_crypto = crypto_new();
|
||||
if (session->next_crypto == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
|
||||
Reference in New Issue
Block a user