Insecurity of wire encryption and using same key (and nonce) for both sides

25 views
Skip to first unread message

Mark Rotteveel

unread,
May 21, 2023, 7:51:34 AM5/21/23
to firebir...@googlegroups.com
Currently, the wire encryption plugins use the same key (Arc4, ChaCha,
ChaCha64) and nonce (ChaCha and ChaCha64) for both directions of
communication. I'm far from an encryption expert, but this is a
vulnerability or avenue for decryption attacks, because - at least for
the ChaCha-family (not sure about Arc4) - the XOR of both streams will
then be the XOR of the plaintexts, and if (part of) one of the
plaintexts is known, you can then obtain (part of) the other plaintext.

I'm not sure how this should be addressed, but I think we need to use
some key-derivation function which takes in the session key and
something to represent the specific stream direction (maybe fixed, maybe
generated per connection) to generate a stream specific key.

Similarly, the nonce sent for ChaCha and ChaCha64 would need to be per
direction and not shared. For communication with the client, maybe the
nonce sent with TAG_PLUGIN_SPECIFIC should be doubled in size, so it can
be split in two.

But as I said, I'm not an expert on encryption, so maybe those ideas
don't make much sense, but I do think this needs to be addressed in some
way, or maybe we should bite the bullet and just switch to using TLS
instead of trying to reinvent the wheel.

Mark
--
Mark Rotteveel

Alex Peshkoff

unread,
May 22, 2023, 1:17:43 PM5/22/23
to firebir...@googlegroups.com
On 5/21/23 14:51, Mark Rotteveel wrote:
> Currently, the wire encryption plugins use the same key (Arc4, ChaCha,
> ChaCha64) and nonce (ChaCha and ChaCha64) for both directions of
> communication. I'm far from an encryption expert, but this is a
> vulnerability or avenue for decryption attacks, because - at least for
> the ChaCha-family (not sure about Arc4) - the XOR of both streams will
> then be the XOR of the plaintexts, and if (part of) one of the
> plaintexts is known, you can then obtain (part of) the other plaintext.
>
> I'm not sure how this should be addressed, but I think we need to use
> some key-derivation function which takes in the session key and
> something to represent the specific stream direction (maybe fixed,
> maybe generated per connection) to generate a stream specific key.
>

For chacha it's enough to change starting counter from 0 to 1 in one of
directions.
For Arc4 problem is solved with different salt for directions.

> Similarly, the nonce sent for ChaCha and ChaCha64 would need to be per
> direction and not shared. For communication with the client, maybe the
> nonce sent with TAG_PLUGIN_SPECIFIC should be doubled in size, so it
> can be split in two.

Yes, nonce can also used for it.

>
> But as I said, I'm not an expert on encryption, so maybe those ideas
> don't make much sense, but I do think this needs to be addressed in
> some way, or maybe we should bite the bullet and just switch to using
> TLS instead of trying to reinvent the wheel.
>

May be TLS plugin for wire encryption is really best solution.


Mark Rotteveel

unread,
May 22, 2023, 1:48:18 PM5/22/23
to firebir...@googlegroups.com
On 22-05-2023 19:17, 'Alex Peshkoff' via firebird-devel wrote:
> On 5/21/23 14:51, Mark Rotteveel wrote:
>> Currently, the wire encryption plugins use the same key (Arc4, ChaCha,
>> ChaCha64) and nonce (ChaCha and ChaCha64) for both directions of
>> communication. I'm far from an encryption expert, but this is a
>> vulnerability or avenue for decryption attacks, because - at least for
>> the ChaCha-family (not sure about Arc4) - the XOR of both streams will
>> then be the XOR of the plaintexts, and if (part of) one of the
>> plaintexts is known, you can then obtain (part of) the other plaintext.
>>
>> I'm not sure how this should be addressed, but I think we need to use
>> some key-derivation function which takes in the session key and
>> something to represent the specific stream direction (maybe fixed,
>> maybe generated per connection) to generate a stream specific key.
>>
>
> For chacha it's enough to change starting counter from 0 to 1 in one of
> directions.

I don't think so. As I understand it, that will just shift the keystream
by 64 bytes. So, if you XOR one stream with a 64 bit offset compared to
the other, you still have the XOR of both plaintexts.

> For Arc4 problem is solved with different salt for directions.

Arc4 just has a key, no salt, so I guess you mean something similar to
what I suggested.

> May be TLS plugin for wire encryption is really best solution.

Yes, I think so.

Mark
--
Mark Rotteveel

Mark Rotteveel

unread,
May 22, 2023, 1:49:46 PM5/22/23
to firebir...@googlegroups.com
On 22-05-2023 19:48, Mark Rotteveel wrote:
> I don't think so. As I understand it, that will just shift the keystream
> by 64 bytes. So, if you XOR one stream with a 64 bit offset compared to
> the other, you still have the XOR of both plaintexts.

That should have read "64 byte offset compared to the other"...

--
Mark Rotteveel

Jim Starkey

unread,
May 23, 2023, 10:30:23 AM5/23/23
to firebir...@googlegroups.com
TLS is designed to authenticate a server to a client and is certificate
based.  A database protocol needs to be designed to authenticate a
client to a server.  TLS also requires more round trips than, say, an
SRP handshake, but the requirement for a certificate is major PITA,
particularly on AWS.

In the early days of Amorphous, I coded up a ChaCha20 implementation,
which lost big time to AES on a processor with the crypto instruction
set (which, to the best of my knowledge, is just about everything except
Raspberry Pis).

Amorphous uses an XML based SRP handshake followed by AES-128 with
cyberblock chaining and ciphertext stealing for C++ clients and RC4 for
Java clients ('cause I'm lazy).
--
Jim Starkey, AmorphousDB, LLC

Dimitry Sibiryakov

unread,
May 23, 2023, 10:43:40 AM5/23/23
to firebir...@googlegroups.com
>> I'm not sure how this should be addressed, but I think we need to use some key-derivation function which takes in the session key and something to represent the specific stream direction (maybe fixed, maybe generated per connection) to generate a stream specific key.

>> Similarly, the nonce sent for ChaCha and ChaCha64 would need to be per
>> direction and not shared. For communication with the client, maybe the nonce
>> sent with TAG_PLUGIN_SPECIFIC should be doubled in size, so it can be split in
>> two.
>
> Yes, nonce can also used for it.

With Srp client and server have a strong secure shared secret S (or its hash
H). Server can use higher bits of it as a session key while client - lower one
so both sides have other's key without exposing any of its part over the wire.

--
WBR, SD.

Alex Peshkoff

unread,
May 23, 2023, 12:26:09 PM5/23/23
to firebir...@googlegroups.com
Is not it enough to add to hash before shared secret S known to everyone
but different for directions salt before calculating hash H of S?


Dimitry Sibiryakov

unread,
May 23, 2023, 12:36:01 PM5/23/23
to firebir...@googlegroups.com
'Alex Peshkoff' via firebird-devel wrote 23.05.2023 18:26:
>>   With Srp client and server have a strong secure shared secret S (or its hash
>> H). Server can use higher bits of it as a session key while client - lower one
>> so both sides have other's key without exposing any of its part over the wire.
>
> Is not it enough to add to hash before shared secret S known to everyone but
> different for directions salt before calculating hash H of S?

At first glance it can work if done in wire crypt plugin. Otherwise it would
break backward compatibility.
At second glance it is pointless because a well-known part of pre-image don't
increase security which is set by unknown bits only.

--
WBR, SD.

Alex Peshkoff

unread,
May 24, 2023, 2:00:54 AM5/24/23
to firebir...@googlegroups.com
But we talk here about very specific attack - XOR of 2 data streams
between client and server. Security is provided by bits from shared
secret, well-known part of pre-image makes them not correlated. What do
I miss?


Mark Rotteveel

unread,
May 24, 2023, 3:56:51 AM5/24/23
to firebir...@googlegroups.com
Yes, it doesn't increase the entropy of the key as such, but using a
fixed or session-specific "salt" per direction, and hashing it together
with the session key to generate a stream-specific key will prevent that
type of XOR attack.

Same for doubling the nonce for ChaCha / ChaCha64, so the nonce can be
split in two (one per stream direction).

However, both client and server need to be aware **and** agree that they
need to do this, otherwise older clients cannot connect to newer servers
nor can newer clients connect to older servers.

The current wire crypt exchange doesn't really allow for this: the
server can send additional info to the client, but the client cannot
send additional information to the server (i.e. to confirm it used the
new key-generation). So this requires either a new protocol version
(either to allow more info to be sent by client to server as part of
op_crypt, or the new key-generation is selected based on the protocol
version), or it requires introducing another wire crypt plugin name or
key type, where the newer key types are listed before the older key types.

Defining a new key type might be the simplest way forward. For example,
with `WireCryptPlugin = ChaCha64, ChaCha, Arc4` configured in
firebird.conf, the server sends Symmetric2 (ChaCha64, ChaCha, Arc4),
Symmetric (ChaCha64, ChaCha, Arc4), so new clients can select the new
Symmetric2 variant, while older clients can select the Symmetric variant.

The Symmetric2 variant will then define:

1) How to derive a stream specific key (e.g. use
SHA256(<stream-specific-part>,<session-key>); As far as I know, Arc4
will work with 256-bit keys, but otherwise we could use
SHA1(<stream-specific-part>,<session-key>) for Arc4 to keep the key 160
bits like now)
2) What <stream-specific-part> is, e.g. fixed data like the strings
"firebird-server-to-client", "firebird-client-to-server", or maybe
something session-specific sent in op_cond_accept or op_accept_data in
the server keys buffer (say TAG_SERVER_STREAM_ID for server-to-client,
TAG_CLIENT_STREAM_ID for client-to-server, both with, say, 128-bits of
random data).
3) For ChaCha and ChaCha64, it doubles the "plugin specific data" size,
so it can be split in two, so the nonce is different per direction, and
which part of the plugin specific data is for which direction.

However, I don't know if and how the existing wire crypt plugin API
allows for them to register with multiple key types, so I don't know if
this is a feasible approach in that regard.

Mark
--
Mark Rotteveel

Alex Peshkoff

unread,
May 24, 2023, 4:03:25 AM5/24/23
to firebir...@googlegroups.com
Yes, it does by design. But telling true poorly tested.


Dimitry Sibiryakov

unread,
May 24, 2023, 5:24:11 AM5/24/23
to firebir...@googlegroups.com
'Alex Peshkoff' via firebird-devel wrote 24.05.2023 8:00:
> But we talk here about very specific attack - XOR of 2 data streams between
> client and server. Security is provided by bits from shared secret, well-known
> part of pre-image makes them not correlated. What do I miss?

Nothing. I missed the point that size of unknown part is not reduced in your
suggestion.

--
WBR, SD.
Reply all
Reply to author
Forward
0 new messages