summaryrefslogtreecommitdiff
path: root/src/common/crypto.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-01-24 12:33:13 -0500
committerNick Mathewson <nickm@torproject.org>2018-01-25 13:59:55 -0500
commit91c63aae8497bc9de6533daae8f927ca09f96fd2 (patch)
treeb85f7133597089046353ef5a94ce3d5fd2051c23 /src/common/crypto.c
parent7a74b3663fdaa40fc84e48990d15953a8f46a2bf (diff)
downloadtor-91c63aae8497bc9de6533daae8f927ca09f96fd2.tar.gz
tor-91c63aae8497bc9de6533daae8f927ca09f96fd2.zip
In relay_digest_matches(), use stack instead of heap.
We'd been using crypto_digest_dup() and crypto_digest_assign() here, but they aren't necessary. Instead we can just use the stack to store the previous state of the SHA_CTX and avoid a malloc/free pair. Closes ticket 24914.
Diffstat (limited to 'src/common/crypto.c')
-rw-r--r--src/common/crypto.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 107b53ad29..880f92b4d2 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1822,6 +1822,7 @@ crypto_digest_alloc_bytes(digest_algorithm_t alg)
/* Gives the length of crypto_digest_t through the end of the field 'd' */
#define END_OF_FIELD(f) (offsetof(crypto_digest_t, f) + \
STRUCT_FIELD_SIZE(crypto_digest_t, f))
+
switch (alg) {
case DIGEST_SHA1:
return END_OF_FIELD(d.sha1);
@@ -2007,6 +2008,33 @@ crypto_digest_dup(const crypto_digest_t *digest)
return tor_memdup(digest, alloc_bytes);
}
+/** Temporarily save the state of <b>digest</b> in <b>checkpoint</b>.
+ * Asserts that <b>digest</b> is a SHA1 digest object.
+ */
+void
+crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint,
+ const crypto_digest_t *digest)
+{
+ tor_assert(digest->algorithm == DIGEST_SHA1);
+ /* The optimizer should turn this into a constant... */
+ const size_t bytes = crypto_digest_alloc_bytes(DIGEST_SHA1);
+ /* ... and remove this assertion entirely. */
+ tor_assert(bytes <= sizeof(checkpoint->mem));
+ memcpy(checkpoint->mem, digest, bytes);
+}
+
+/** Restore the state of <b>digest</b> from <b>checkpoint</b>.
+ * Asserts that <b>digest</b> is a SHA1 digest object. Requires that the
+ * state was previously stored with crypto_digest_checkpoint() */
+void
+crypto_digest_restore(crypto_digest_t *digest,
+ const crypto_digest_checkpoint_t *checkpoint)
+{
+ tor_assert(digest->algorithm == DIGEST_SHA1);
+ const size_t bytes = crypto_digest_alloc_bytes(DIGEST_SHA1);
+ memcpy(digest, checkpoint->mem, bytes);
+}
+
/** Replace the state of the digest object <b>into</b> with the state
* of the digest object <b>from</b>. Requires that 'into' and 'from'
* have the same digest type.