Skip to content

proto_crypt: clear the remaining stack buffers - #437

Open
woahwhattheheck wants to merge 1 commit into
Tarsnap:masterfrom
woahwhattheheck:proto-crypt-clear-stack
Open

proto_crypt: clear the remaining stack buffers#437
woahwhattheheck wants to merge 1 commit into
Tarsnap:masterfrom
woahwhattheheck:proto-crypt-clear-stack

Conversation

@woahwhattheheck

@woahwhattheheck woahwhattheheck commented Sep 6, 2026

Copy link
Copy Markdown

Disclosure, per this repository's AGENTS.md: I am an LLM (Claude), submitting on behalf of the account owner. I am available to discuss this change and to revise it in response to review feedback.

Fixes #436.

#426 wiped dk_2 and nonce_y in proto_crypt_mkkeys(). Two buffers holding
key material in the same file were not covered by it:

  • proto_crypt_secret() reads the key file into buf[BUFSIZ] and never zeroes
    it, on either the success path or the read-error path at err2. That buffer
    is the pre-image of the shared secret — the whole key file, for a key file of
    BUFSIZ bytes or less. The function already wipes the SHA-256 context two
    lines above, and proto_crypt_secret_free() zeroes the derived secret; the
    buffer it was derived from was the gap. Both spiped and spipe call this
    once at startup and then run for the lifetime of the process.
  • proto_crypt_dhmac() leaves dk_1, the derived diffie-hellman MAC keys, in
    the frame when it returns. Called once per connection.

Three insecure_memzero() calls, using the idiom from #426.

Deliberately not covered

  • ctx in proto_crypt_enc() and proto_crypt_dec() — it is a copy of
    k->ctx_init, which stays in the key structure for the whole connection, so
    wiping the copy buys nothing; and both functions run once per 1024-byte
    packet, which is not somewhere to add work for no gain.
  • nonce_CS in proto_crypt_dhmac() — the nonces are sent over the wire in
    the clear.

Happy to add either if you would rather have the file uniformly wiped.

Testing

No behaviour change: the writes happen after the last read of each buffer in
every path, and neither buffer is read again. insecure_memzero.h is already
included by this file.

426 wiped dk_2 and nonce_y in proto_crypt_mkkeys().  Two buffers holding
key material in the same file were not covered by it.

proto_crypt_secret() reads the key file into buf[BUFSIZ] and never zeroes
it, on the success path or on the read-error path at err2.  That buffer
holds the pre-image of the shared secret, and for a key file of BUFSIZ
bytes or less it holds all of it.  The function already wipes the SHA-256
context two lines above, and proto_crypt_secret_free() zeroes the derived
secret; the buffer it was derived from was the gap.  Both spiped and
spipe call this once at startup and then run for the lifetime of the
process.

proto_crypt_dhmac() leaves dk_1, the derived diffie-hellman MAC keys, in
the frame when it returns.

ctx in proto_crypt_enc() and proto_crypt_dec() is left alone: it is a
copy of k->ctx_init, which stays in the key structure for the whole
connection, and those run once per packet.  nonce_CS is left alone
because the nonces go over the wire in the clear.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

[bug bounty] Key file contents and dhmac keys are left on the stack in proto_crypt.c

2 participants