Git development
 help / color / mirror / Atom feed
From: "brian m. carlson" <sandals@crustytoothpaste.net>
To: Jeff King <peff@peff.net>
Cc: Junio C Hamano <gitster@pobox.com>,
	git@vger.kernel.org, Patrick Steinhardt <ps@pks.im>
Subject: Re: [PATCH 4/7] hash: make git_hash_discard() idempotent
Date: Tue, 7 Jul 2026 21:41:00 +0000	[thread overview]
Message-ID: <ak1yazHtP_OazDaO@fruit.crustytoothpaste.net> (raw)
In-Reply-To: <20260707201808.GD11780@coredump.intra.peff.net>

[-- Attachment #1: Type: text/plain, Size: 2291 bytes --]

On 2026-07-07 at 20:18:08, Jeff King wrote:
> On Tue, Jul 07, 2026 at 09:22:04AM -0700, Junio C Hamano wrote:
> > But the change nevertheless looks mostly good except for one "hmph".
> > When _init() is called, active gets turned on automatically, and
> > either _discard() or _final() turns it off.  Only _discard() is
> > protected from getting called multiple times.  Is this because
> > it is already a no-op to call _final() multiple times?
> 
> No, it's a bug to call _final() multiple times. See my response
> elsewhere in the thread.

This is almost always the case in hash function libraries.  Let me
explain why.

A context for SHA-256 contains the 8 32-bit words in the state, a bit or
byte counter (as a 64-bit quantity or two 32-bit quantities), and a
64-byte buffer for unprocessed bytes—and that's it.  When finalizing a
hash, you must always pad with a 0x80 byte and then optionally some zero
bytes, plus a 64-bit counter of bits in the message.  That may result in
one or two iterations of the hash to process the remaining bytes and the
padding, and that almost always updates the state words in the context
in place.  (SHA-1 functions identically but for the state size.)

So if you call the final function multiple times, you're not computing
the final value the second time, but instead trying to re-pad and
re-compute the final hash value, which results in a _different_,
incorrect value.  In SHA-256, this is a valid hash value for a different
message (which is the original message with the padding and length
tacked on and is effectively a length-extension attack), but in hashes
that don't allow length-extension attacks, such as SHA-3 and BLAKE2,
what you get is simply corrupt data.

So most hash function libraries that allocate memory are going to free
it in the final function because you can't really call final multiple
times and get a sensible response.  If you want to do that, then you
need to clone the context and call final on each context once.

Our Rust code makes calling final a second time impossible because
finalization takes `self`, not `&mut self`, so the object is _moved_
into the final method and you no longer have access to it after that.
-- 
brian m. carlson (they/them)
Toronto, Ontario, CA

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 325 bytes --]

  reply	other threads:[~2026-07-07 21:41 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-07  4:55 [PATCH 0/7] git_hash_*() quality-of-life improvements Jeff King
2026-07-07  5:01 ` [PATCH 1/7] hash: use git_hash_init() consistently Jeff King
2026-07-07 14:39   ` Junio C Hamano
2026-07-07 20:13     ` Jeff King
2026-07-07 20:17       ` Junio C Hamano
2026-07-07 20:25         ` Jeff King
2026-07-07 21:25   ` brian m. carlson
2026-07-08  3:54     ` Jeff King
2026-07-07  5:04 ` [PATCH 2/7] hash: convert remaining direct function calls Jeff King
2026-07-07 16:15   ` Junio C Hamano
2026-07-07  5:05 ` [PATCH 3/7] hash: document function pointers and wrappers Jeff King
2026-07-07 14:26   ` Patrick Steinhardt
2026-07-07 20:05     ` Jeff King
2026-07-07  5:07 ` [PATCH 4/7] hash: make git_hash_discard() idempotent Jeff King
2026-07-07 16:22   ` Junio C Hamano
2026-07-07 20:18     ` Jeff King
2026-07-07 21:41       ` brian m. carlson [this message]
2026-07-07 22:25         ` Junio C Hamano
2026-07-07  5:07 ` [PATCH 5/7] csum-file: use idempotent git_hash_discard() Jeff King
2026-07-07  5:08 ` [PATCH 6/7] http: " Jeff King
2026-07-07 16:25   ` Junio C Hamano
2026-07-07  5:09 ` [PATCH 7/7] hash: check ctx->active flag in all wrapper functions Jeff King
2026-07-07 14:26   ` Patrick Steinhardt
2026-07-07 16:33   ` Junio C Hamano
2026-07-07 20:10     ` Jeff King
2026-07-07 14:26 ` [PATCH 0/7] git_hash_*() quality-of-life improvements Patrick Steinhardt
2026-07-08  3:52 ` [PATCH v2 " Jeff King
2026-07-08  3:52   ` [PATCH v2 1/7] hash: use git_hash_init() consistently Jeff King
2026-07-08  3:52   ` [PATCH v2 2/7] hash: convert remaining direct function calls Jeff King
2026-07-08  3:52   ` [PATCH v2 3/7] hash: document function pointers and wrappers Jeff King
2026-07-08  3:52   ` [PATCH v2 4/7] hash: make git_hash_discard() idempotent Jeff King
2026-07-08  3:53   ` [PATCH v2 5/7] csum-file: use idempotent git_hash_discard() Jeff King
2026-07-08  3:53   ` [PATCH v2 6/7] http: " Jeff King
2026-07-08  3:53   ` [PATCH v2 7/7] hash: check ctx->active flag in all wrapper functions Jeff King
2026-07-08  8:05   ` [PATCH v2 0/7] git_hash_*() quality-of-life improvements Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ak1yazHtP_OazDaO@fruit.crustytoothpaste.net \
    --to=sandals@crustytoothpaste.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox