Subject: Albrecht/Paterson/Watson's attack

From: Mouse <[email-masked]>
Date: Mon, 5 May 2014 15:39:23 -0400 (EDT)

Perhaps it wasn't mentioned here, or perhaps I'd just missed it, but a
note elselist prompted me to read
http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf.

Any thoughts?  Besides the obvious suggestions made in the paper
(basically "don't use CBC bulk ciphers"), it occurs to me that there is
another defense: make it hard to identify packet boundaries by,
whenever the connection would otherwise go idle, generating an IGNORE
packet and sending only part of it, holding the rest until something
more is available to be sent on that connection.

It wouldn't completely prevent the attack, since the attacker can
simply guess how much BPP-level packet remains at the network-level
packet boundary, but it would be another factor against success - and
it would require not just injecting data, but intercepting and
modifying the first wire packet after idle time.  It would also render
connections attackable only during the first packet after idle time,
rather than at any time when idle.  It seems to me this would increase
the difficulty of an attack, perhaps significantly.  While admittedly
this particular attack is easy enough to defeat by just not using CBC
modes, it seems likely to me that some other attack based on
recognizing and exploiting BPP-layer packet boundaries will come along.

Thoughts?

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		[email-masked]
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

---

From: "Mark D. Baushke" <[email-masked]>
Date: Mon, 5 May 2014 15:09:26 -0700

Mouse <[email-masked]> writes:

> Besides the obvious suggestions made in the paper (basically "don't
> use CBC bulk ciphers"), it occurs to me that there is another defense:
> make it hard to identify packet boundaries by, whenever the connection
> would otherwise go idle, generating an IGNORE packet and sending only
> part of it, holding the rest until something more is available to be
> sent on that connection.

Another alternative is to use an encrypt-then-mac approach.

http://tools.ietf.org/html/draft-gutmann-tls-encrypt-then-mac-05

which has a normative reference to:

    Krawczyk, H., "The Order of Encryption and Authentication
    for Protecting Communications (or: How Secure Is SSL?)",
    Springer-Verlag LNCS 2139, August 2001.

fwiw: I believe that OpenSSL extensions to KEX_DEFAULT_MAC do this:

	"[email-masked]," \
	"[email-masked]," \
	"[email-masked]," \
	"[email-masked]," \
	"[email-masked]," \
	"[email-masked]," \
	"[email-masked]," \
	"[email-masked]," \
	"[email-masked]," \

which seems to work for them. I don't know if we want to try to make the
-etm alternatives available as a part of the SSHv2 defined set of MACs.

	-- Mark

---

From: "denis bider \(Bitvise\)" <[email-masked]>
Date: Mon, 5 May 2014 18:15:39 -0600

Our implementation in Bitvise SSH Server (versions of the last several years 
that use our FlowSsh library) makes this class of attack difficult by:

- Implementing precise checks about whether the received packet length is 
valid.

- If the received packet length is invalid, generating a random valid packet 
length, and continuing execution as if that length was received.

This way, the attacker is denied knowledge of whether their attempt to 
infiltrate the first CBC block succeeded or not.

I know of no way the attacker can distinguish one successful infiltration 
attempt from hundreds of thousands of unsuccessful attempts. Even if the 
attacker knows some property of the plaintext, e.g. that it is ASCII, many 
of the unsuccessful "plaintexts" can seem valid.

denis

-----Original Message----- 
From: Mouse
Sent: Monday, May 5, 2014 13:39
To: [email-masked]
Subject: Albrecht/Paterson/Watson's attack

Thoughts?

/~\ The ASCII   Mouse
\ / Ribbon Campaign

---

From: [email-masked] (Niels Möller)
Date: Tue, 06 May 2014 08:51:23 +0200

Mouse <[email-masked]> writes:

> make it hard to identify packet boundaries by,

I think that's a good idea in general, also to make traffic analysis a
bit more difficult.

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.

---

From: [email-masked] (Niels Möller)
Date: Tue, 06 May 2014 08:57:11 +0200

> -etm alternatives available as a part of the SSHv2 defined set of MACs.

I think that would be good.

Back when the ssh protocols were designed, applying the MAC to the
cleartext was uncontroversial. I think Schneier's Applied Cryptography
recommended it, with the motivation that message authentication ought to
be applied to the data that has meaning to the receiver. A possible
attack was that the enemy might tamper with the encryption key used; this
clearly changes the cleartext message, but if the MAC is applied to the
cryptotext, that type of change isn't detected.

The somewhat counter intuitive advice that the MAC should be applied to
the cryptotext is more recent, and if it's not too painful to
incorporate that in ssh in general, that would be a good thing.

Regards,
/Niels

---

From: Peter Gutmann <[email-masked]>
Date: Tue, 06 May 2014 22:00:54 +1200

>I think that would be good.

+1 (conflict-of-interest disclaimer: I'm the author of the TLS EtM draft). 

One thing that SSH would then need to do is to stop encrypting the header
(that is, the length information) so you can run the MAC over the packet
without having to pick apart bits of it via decryption first, which is what
helps the Paterson et al attack work.  The TLS draft explicitly tells
implementers to read the length, read that many bytes from the network, run
the MAC, and discard the packet immediately if the MAC fails to verify.  If
you still need to run crypto ops before you can verify the MAC you're not
actually doing EtM, or at least not getting the security benefits that it
provides.

Peter.

---

From: Simon Tatham <[email-masked]>
Date: Tue, 06 May 2014 11:25:06 +0100

In article <[email-masked]> you write:
> helps the Paterson et al attack work.

I think this idea has historically been unpopular in SSH circles
because the cleartext packet length fields were critical to attacks
against SSH-1. Of course, those were _particularly bad_ cleartext
packet length fields, but even so, it's unsurprising that people have
a reflexive aversion as a result...

Personally, if I were redesigning the SSH-2 binary packet protocol,
I'd be inclined to split it into two entirely separate layers, by
removing the coupling between semantic SSH protocol messages and
chunks of data encrypted/MACed as a whole. There's no actual reason
that the two should coincide.

So you'd start with a BPP designed solely for security, which would
consist of a series of (length, encrypted data, MAC) chunks stuck
end-to-end. The MAC would apply to the ciphertext, and the length
would be the full length of the ciphertext (or perhaps ciphertext+MAC)
in clear.

Once those chunks were MACed and decrypted, the decrypted ciphertexts
would be concatenated, and the resulting byte stream would be divided
into semantic SSH-2 messages according to a (length, type, data)
format about as simple as the one in SFTP (though you might also want
to provide a convenient way of including small numbers of bytes of
padding between messages, without having to construct an entire
SSH_MSG_IGNORE).

And the two notions of 'chunk' and 'message' have no particular need
to match up. So if you wanted to send lots of SSH-2 messages in one
go, you could combine them into a single chunk, and then the atomic
MAC covering the whole chunk would make it impossible for an attacker
to determine the boundaries between those messages (so, e.g., hiding
password length by combining the password with an SSH_MSG_IGNORE is
now clearly not defeatable by proxying the TCP stream and dribbling
out bytes one by one until you see a response). Conversely, a very
large message could be split across multiple chunks if you felt like
it, or an SSH_MSG_IGNORE could start at the end of one chunk and
finish in the start of the next.

Hence, the cleartext length field on the _chunk_ doesn't necessarily
tell you anything about the length of any _message_ within that chunk.
Indeed, it doesn't even tell you anything you couldn't deduce from
the TCP segment boundaries, which is my rationale for it not being an
unreasonable exposure of information. (In particular, the cleartext
length field would always be a multiple of the cipher block size.)

I suppose, on the other hand, that if people still disliked having
message lengths in clear, then you could tweak this concept using the
suggestion from the paper referenced upthread of having a MAC covering
just the length field or just the first cipher block or some such, so
you'd get a chunk consisting of (encrypted length, MAC of encrypted
length, encrypted rest-of-data, MAC of encrypted rest-of-data).
-- 
Simon Tatham         "A cynic is a person who smells flowers and
<[email-masked]>    immediately looks around for a coffin."

---

From: [email-masked] (Niels Möller)
Date: Tue, 06 May 2014 13:24:10 +0200

> length, encrypted rest-of-data, MAC of encrypted rest-of-data).

I'm pretty sure I'm missing something subtle here. We first get a packet
length, and then we read an encrypted message of that length from the
network, check the mac and decrypt it (assuming we have configured some
-etm mode of operation). To communicate that packet length, we
have a couple of different options:

1. Cleartext packet length, no crypto, no mac.

2. Encrypted packet length, no mac.

3. Encrypted packet length, with a separate mac.

You seem to be saying that (1) is secure (except that the exposed
lengths are unfortunately meaningful also above the ssh transport layer)
and that (3) is secure, but that (2) is a problem.

Is there any easy explanation for that? I realize that the first
decrypted block includes both length and a prefix of the cleartext
message, which possibly is the source of the problem, but if everything
but the length part is ignored until after successful verification of
the mac, it's not clear why that's a problem.

Regards,
/Niels

---

From: Simon Tatham <[email-masked]>
Date: Tue, 06 May 2014 12:42:33 +0100

> and that (3) is secure, but that (2) is a problem.

Sorry to have been unclear! I may well not have thought it through
adequately myself. But what I was getting at here is two separate
attacks:

 (a) the subject of the whole paper, i.e. an attack on the encryption
     which involves substituting an initial cipher block and inferring
     from the subsequent failure mode some information about the
     length field to which it decrypted. Putting the length field in
     cleartext rather than in the first cipher block defeats this
     attack.

 (b) the DoS attack which the paper mentions in passing as being
     potentially opened up by having the length field in cleartext: an
     active attacker replaces the length field with a very large one
     and sends a big pile of data, causing the receiver to buffer it
     all and use up a lot of memory. The paper admits that this may
     not be something you particularly care about.

The option you list as (1), i.e. a cleartext unMACed packet length,
defeats attack (a), but it struck me that people might still dislike
cleartext packet lengths for some other reason(s), possibly including
attack (b).

Option (2), putting the packet length back into the encrypted data
without a separate MAC, risks reintroducing forms of attack (a), i.e.
decryption oracles based on the fact that the decrypted packet length
affects the receiver's behaviour before the MAC on it is checked.

Option (3), encrypting the packet length and MACing it separately,
defeats both types of attack as far as I can see.

(And I don't think it matters whether the packet length lives on its
own in a separate cipher block or whether it's combined with the first
n-4 bytes of the payload. As long as a fixed number of cipher blocks
are covered by the first MAC, and that MAC is verified before taking
any action based on the length field, I think it should be OK either
way.)
-- 
Simon Tatham         "Happiness is having a large, warm, loving,
<[email-masked]>    caring, close-knit family in another city."

---

From: [email-masked] (Niels Möller)
Date: Tue, 06 May 2014 14:50:17 +0200

>      cleartext rather than in the first cipher block defeats this

If you said that the attacker can infer information about the initial
cleartext, *after* the length field, then a cleartext length field might
be an improvement. I imagine that attacks like that might be possible
with CBC mode, but is seems highly unlikely if using something like
aes-ctr or salsa20.

But if the problem is leaking information about the length field itself,
a change to instead send that information totally in the clear cannot be
an improvement.

To adress leaking of length info to active attackers, one would need a
redesign where information about the length never reveals anything
sensitive, a bit like what you sketched.

I guess I ought to read the paper myself, but I don't have the time to
do that right away.

> defeats both types of attack as far as I can see.

Given the close connection between ssh transport packets and packets for
the userauth and connection protocols, I think it's desirable to encrypt
the length (and in general, try to hide message boundaries).

But an additional MAC gives a significant additional overhead. Maybe one
could get away with a short MAC for the first block (including the
length), provided that the MAC at the end of the cryptotext covers the
complete message?

Regards,
/Niels

---

From: Mouse <[email-masked]>
Date: Thu, 8 May 2014 17:44:40 -0400 (EDT)

> One thing that SSH would then need to do is to stop encrypting the
> header (that is, the length information) so you can run the MAC over
> the packet without having to pick apart bits of it via decryption
> first,

This is actually not quite true.  It would need to do so to implement
EtM as outlined in the descriptions I've found, but I see no particular
reason to slavishly follow them.  There's no reason you can't encrypt
the whole thing, including the length, but then MAC the resulting
ciphertext.  You have to decrypt a little before you can tell how much
to run the MAC over, but that's hardly a big deal.

Personally, if I were worried about such things, I would probably MAC
the cleartext, MAC the ciphertext, and append both MACs to the
encrypted packet.  I might even encrypt the cleartext's MAC along with
the payload before running the ciphertext MAC.

> If you still need to run crypto ops before you can verify the MAC
> you're not actually doing EtM, or at least not getting the security
> benefits that it provides.

What benefits _does_ it provide?  Why do they outweigh exposing packet
sizes?

It seems to me that the Bellare/Namprempre paper has a number of
weaknesses for our purposes[%], mostly amounting to mismatches between
its assumptions and the world of SSH.  In particular, the only
arguments I see against E&M, such as SSH uses, are based on the MAC
leaking information about its input.

It would be nice to use a construct that has some kind of proof of its
security - other things being equal.  Here, they are not; using their
EtM construction demands exposing information the current paradigm does
not expose.  Furthermore, the only flaws I see described in the current
construction are based on assuming weaknesses in the underlying
algorithms.

But I recognize your name enough to know you're not stupid.  This leads
me to expect I'm missing something important.

What?

/~\ The ASCII				  Mouse
\ / Ribbon Campaign

[%] For example, it appears to assume that message lengths are
    unprotected in all variants; as I understand it, that's one of the
    main arguments against EtM for SSH.  The paper also does not
    consider different types of brokenness different, such as
    implementation bugs that can break an algorithm in some ways but
    not others - an example is the "what if the key is corrupted"
    spectre which has been invoked as justification for choosing E&M.
    (Any paper whose results depend on implementations being bug-free
    needs a very careful read-over before it can be considered to apply
    to real software.)  It also considers possibilities such as a MAC
    leaking information about the data it is applied to.

---

From: Mouse <[email-masked]>
Date: Sat, 10 May 2014 02:37:14 -0400 (EDT)

[me]
>> http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf

[denis]
> Our implementation in Bitvise SSH Server (versions of the last
> several years that use our FlowSsh library) makes this class of
> attack difficult by: [turning corrupt packet lengths into random
> valid packet lengths]

I've now implemented this defense in moussh.  I don't quite do it as
described above, because, if done that simply, there is a (small)
chance the MAC will pass and feed corrupted data into the session.
When generating a random valid packet length, I also switch the
connection to using a dummy MAC algorithm which is basically just like
the "none" algorithm except that checks always fail (for "none" they
always succeed).  Thus, when/if the randomized packet length is
exhausted, it will exhibit the behaviour corresponding to a MAC failure
with probability 1, rather than 1-(2^-160) (or whatever, depending on
the MAC in use).

[me]
>> make it hard to identify packet boundaries by, whenever the
>> connection would otherwise go idle, generating an IGNORE packet and
>> sending only part of it, holding the rest until something more is
>> available to be sent on that connection.
> I think that's a good idea in general, also to make traffic analysis
> a bit more difficult.

moussh does not yet include this defense; I found it remarkably
difficult to do.  I will need to think about how to implement this.  It
may call for improving the APIs to my crypto libraries, since it's hard
to do this without either (a) generating a lot of unnecessary IGNOREs
or (b) having support for encrypting something and then rolling back, a
way to encrypt the IGNORE and then, if it turns out it doesn't get
written, reset the crypto's state to pretend it wasn't encrypted after
all.  (Doing it in another write() would be easy, but risks introducing
a TCP packet boundary at the BPP packet boundary whose concealment is
the whole point of this.  TCP doesn't promise that write() boundaries
will produce TCP segment boundaries, but it actually does so relatively
often anyway.)

/~\ The ASCII				  Mouse
\ / Ribbon Campaign

---

From: [email-masked] (Niels Möller)
Date: Sat, 10 May 2014 09:10:24 +0200

Mouse <[email-masked]> writes:

> difficult to do.

I have some code to do this (not yet in any relased version, though, I don't get much
time for lsh hacking these days). I have a "push" flag for the functions
to encrypt and send of an ssh package. Packets without this flag is
buffered. When the buffered data exceeds a reasonable packet size, I
send the packet out with no extra ignore message.

If the push flag is set, the packet is sent regardless of the amount of
buffered data, and an extra ignore message is appended to the buffer.

See
http://git.lysator.liu.se/lsh/lsh/blobs/master/src/transport_write.c

Regards,
/Niels

---

From: Peter Gutmann <[email-masked]>
Date: Sat, 10 May 2014 22:01:31 +1200

Mouse <[email-masked]> writes:

>What benefits _does_ it provide?  Why do they outweigh exposing packet sizes?

It eliminates about a decade's worth of assorted oracle attacks on encryption
algorithms, implementations, packet-handling code, and so on.

The "not exposing packet sizes" is rather overrated in any case, unless you go
to extraordinary lengths in your implementation all an attacker has to do is
look at the TCP traffic to see where one packet stops and the next one starts.
In any case apart from sensitive packets like ones containing password info
(e.g. the userauth messages), which one would hope are padded to a fixed size,
what real, actual benefit (not gedanken-experiment hypothesis) does an
attacker gain from knowing the packet length?  My guess is that most (all?)
SSH implementations have been exposing packet lengths (at the TCP level) for
more than a decade without anyone being able to exploit it.

Peter.

---

From: Peter Gutmann <[email-masked]>
Date: Sat, 10 May 2014 22:06:09 +1200

Simon Tatham <[email-masked]> writes:

>The MAC would apply to the ciphertext, and the length would be the full
>length of the ciphertext (or perhaps ciphertext+MAC) in clear.

That's what I'd like to see too.  My code, and presumably everyone else's as
well, currently contains a large pile of ad-hockery to kludge around all the
different side-channel attacks you have to worry about with the current way
packet data is handled.  Being able to do:

  read length;
  read that many bytes;
  run MAC and accept/reject;

would cut out all of this.  The only thing you need to worry about is not
using memcmp() for the MAC check.

Peter.

---

From: Mouse <[email-masked]>
Date: Sat, 10 May 2014 13:08:59 -0400 (EDT)

>> moussh does not yet include this defense [partial IGNORE packets]; I
>> found it remarkably difficult to do.

> I have some code to do this [...].  I have a "push" flag for the
> functions to encrypt and send of an ssh package.  Packets without
> this flag is buffered.  When the buffered data exceeds a reasonable
> packet size, I send the packet out with no extra ignore message.

> If the push flag is set, the packet is sent regardless of the amount
> of buffered data, and an extra ignore message is appended to the
> buffer.

Vastly different internal architecture.  My code sends packets by
encrypting them and appending to an output queue.  There's a separate
work procedure (a little like a thread without a stack) that writes
from the output queue.  In this paradigm, the connection going idle
amounts to the output queue draining completely.  But, in order for
something to be written in the same writev() as the output queue, it
has to be ready to be written.  But that means running it through the
crypto, consuming key material.  Since I have no way of telling how
much is writable at any given moment (even postulating a call that asks
that could fail because the answer could change between query and
writev), I can't tell whether the writev() will drain the queue (and I
thus want a partial IGNORE packet there) or not (in which case I
don't).  So I'd have to always append it - but then, to avoid a zillion
unnecesasry IGNOREs, I'd need the ability to retract it if no part of
it actually gets written.  That's where it gets interesting.

I could extend the output queue to store a possible IGNORE separately,
but that wouldn't help because it has to be encrypted in sequence with
the packets on either side of it, which would change (potentially) each
time around.  I could store it in the clear, but I have no way to tell
whether I need to encrypt it; there's no way for writev() to tell me
whether it wants more data in a way that lets me compute before
providing it.

Of course, the output queue draining in userland is not the same as the
TCP output queue draining.  I'd rather drive it off the latter, but
there's no easy way to do that; for most purposes, the userland queue
draining is a good enough approximation.

I might be able to add something like your `push' flag, but it's not
clear to me when I should set it.  It sounds to me as though your
paradigm will insert IGNOREs at certain points in the output stream
even if the connectino _isn't_ going idle - correct?

I need to think about this more.  I may need a redesign, or I may come
up with a clean way to do the crypto rollback, or who knows....

/~\ The ASCII				  Mouse
\ / Ribbon Campaign

---

From: Mouse <[email-masked]>
Date: Sat, 10 May 2014 13:37:21 -0400 (EDT)

>> What benefits _does_ [EtM] provide?  Why do they outweigh exposing
>> packet sizes?
> It eliminates about a decade's worth of assorted oracle attacks on
> encryption algorithms, implementations, packet-handling code, and so
> on.

...replacing them with something with an unknown set of issues, because
it hasn't had a decade-plus of burning in.

> The "not exposing packet sizes" is rather overrated in any case,

Perhaps.  I'm not convinced either way on that.

> unless you go to extraordinary lengths in your implementation all an
> attacker has to do is look at the TCP traffic to see where one packet
> stops and the next one starts.

Even to the extent that the TCP in use reflects write() boundaries as
segment boundaries (which in my limited experience is mostly true under
low load with small writes and usually not under high load or with
large writes), that will give the attacker only some packet boundaries.
That is, segment boundaries will be packet boundaries, but packet
boundaries may not be segment boundaries.

I haven't seen an analysis of the risks of exposing such metadata.  I'm
not competent to do that myself; until someone does do such an
analysis, I'm not going to take it on myself to decide that the
exposure is ignorable.

> In any case apart from sensitive packets like ones containing
> password info (e.g. the userauth messages), which one would hope are
> padded to a fixed size,

They are not, in general - see section 8 of 4252; it does not specify,
nor even recommend, any padding.  Since there is no easy way to set a
maximum on password length on a remote system, it's hard (even aside
from possible internal architecture issues) to pd them to a fixed size.
Implementations certainly could pad if they felt like it; have you
looked to see whether any of the ones you have access to do?  moussh
does not pad password-carrying packets except as required by section 6
of 4253 (which applies to all packets, not just password-carrying
ones).  Indeed, I would be inclined to worry that padding password
packets specially might make them more identifiable on the wire.

> what real, actual benefit (not gedanken-experiment hypothesis) does
> an attacker gain from knowing the packet length?

I don't know; I'm not an attacker.  I do know that I'm not about to
meddle with a crypto protocol without reasonable assurance that it
won't cause trouble, and "a dilettante cryptographer [me] couldn't
describe an exploitable problem with the new protocol offhand" is not
good enough assurance.

> My guess is that most (all?) SSH implementations have been exposing
> packet lengths (at the TCP level) for more than a decade without
> anyone being able to exploit it.

Er, not quite.  "without anyone exploiting it" != "without anyone being
able to exploit it".  (Furthermore, "without anyone exploiting it" !=
"without your hearing of anyone exploiting it", but since I don't know
how well-placed you might be to hear of such things, I'm willing to
plead nolo contendere on that point.)  Also, as I outlined above, I'm
far from convinced that exposing TCP packet boundaries is equivalent to
exposing packet lengths.

Also, "more than a decade"?  The SSH RFCs are dated January 2006, so
presumably you are including SSHv1 - what are the differences at these
levels of its protocol?  I've never seen documentation on its protocol
other than the code, and I've never been motivated enough to
reverse-engineer the protocol documentation from the code.

/~\ The ASCII				  Mouse
\ / Ribbon Campaign

---

From: [email-masked] (Niels Möller)
Date: Sat, 10 May 2014 21:09:58 +0200

Mouse <[email-masked]> writes:

> encrypting them and appending to an output queue.

If you do it similarly to what I do, you'd need to add a (short) queue
of unencrypted packets before the output buffer. I think that's more
sane than a "crypto rollback".

> even if the connectino _isn't_ going idle - correct?

I might add some unnecessary ignores, but the intention is not to never
add them if output queue already is larger than a tcp segment.

I think the push flag will be set for most messages, except when you
know that additional messages will be generated shortly. E.g., when
reading data for a tcp forward, if you check with FIONREAD that there's
more data coming (and there's more window space), you can pass a false
push flag for the corresponding SSH_MSG_CHANNEL_DATA message.

Regards,
/Niels

---

From: Mouse <[email-masked]>
Date: Mon, 12 May 2014 10:08:06 -0400 (EDT)

> If you do it similarly to what I do, you'd need to add a (short)
> queue of unencrypted packets before the output buffer.  I think
> that's more sane than a "crypto rollback".

I don't see how that would help.  I'd still need to either encrypt the
possibly-desired IGNORE or do the write without it and risk a BPP-level
packet boundary appearing as a TCP segment boundary via being a write
boundary.

> I might add some unnecessary ignores, but the intention is not to
> never add them if output queue already is larger than a tcp segment.

How do you tell how large TCP segments are?

> know that additional messages will be generated shortly.

Sounds to me as though you'll end up sprinkling IGNOREs all through
most traffic.  That's one of the effects I'd like to avoid.

/~\ The ASCII				  Mouse
\ / Ribbon Campaign

---

From: [email-masked] (Niels Möller)
Date: Mon, 12 May 2014 17:02:07 +0200

> packet boundary appearing as a TCP segment boundary via being a write

The idea is that you collect a queue of cleartext packets. Then one of
two events can get you to encrypt messages, filling the output buffer
with encrypted data.

1. When you have collected enough data to generate a tcp packet of the
   desired size. Encrypt messages one at a time until you have enough
   data in the output buffer. Do a single write of the desired size.

2. Otherwise, if you get a message with the push flag set, generate a
   large enough ignore message, then go to step 1. My code appends the
   ignore message.

>From this discussion I've understood that it would in some ways be
better to insert the ignore message somewhere *before* the message
needing push. E.g, SSH_MSG_IGNORE | SSH_MSG_USERAUTH provides better
hiding than SSH_MSG_USERAUTH | SSH_MSG_IGNORE, but I haven't digested
the implications of that.

> How do you tell how large TCP segments are?

I don't, I'm just thinking that if all my writes are of a fixed size,
say 1300 bytes, the tcp stack can split that into segments anyway it
likes, segment boundaries ought to be independent of the ssh message
boundaries regardless.

And then in practice, I don't use a *single* large packet size, but a
small number of allowed packet sizes, in order to not bloat an
interactive terminal session too much, where I typically collect only a
few keystrokes per message (using VMIN = 3, VTIME = 2 for the tty).

> most traffic.  That's one of the effects I'd like to avoid.

They will be omitted whenever the output buffer starts to fill up. But
otherwise, the intention is that a typical tcp segment will consist of

   | ...end of SSH_MSG_IGNORE | SSH_MSG_other | start of SSH_MSG_IGNORE... |

Regards,
/Niels