summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-07-04 07:28:18 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-07-04 07:28:18 -0700
commitc7b508747347e8a17546140da64e5170b01e075e (patch)
tree857bb702a1171282afff5ae00d1a51b316fceea0
parentf47ad62b88bcff263c3f14b3107968efffd8378a (diff)
downloadtxr-c7b508747347e8a17546140da64e5170b01e075e.tar.gz
txr-c7b508747347e8a17546140da64e5170b01e075e.tar.bz2
txr-c7b508747347e8a17546140da64e5170b01e075e.zip
sha256: allow application to specify digest buffer.
* chksum.c (sha256_stream_impl): New static function, formed out of bulk of sha256_stream. Takes a pointer to a buffer where the digest is stored. (sha256_ensure_buf): New static function. (sha256_stream): Take buf argument; use sha256_ensure_buf to allocate a buffer if necessary, and to obtain the low-level buffer pointer. Implementation moved into sha256_stream_impl. (sha256_buf, sha256_str): Take pointer to digest buffer; don't allocate a buf object, don't return anything. (sha256): Take buf argument; use sha256_ensure_buf to allocate a buffer if necessary, and to obtain the low-level buffer pointer, which is passed to sha256_buf and sha256_str. (chksum_init): Update registrations of intrinsics with new optional parameters. * chksum.h (sha256_stream, sha256): Declarations updated. * txr.1: Updated.
-rw-r--r--chksum.c51
-rw-r--r--chksum.h4
-rw-r--r--txr.120
3 files changed, 56 insertions, 19 deletions
diff --git a/chksum.c b/chksum.c
index 1863ba47..0400593b 100644
--- a/chksum.c
+++ b/chksum.c
@@ -47,10 +47,9 @@
#include "chksums/crc32.h"
#include "chksum.h"
-val sha256_stream(val stream, val nbytes)
+static void sha256_stream_impl(val stream, val nbytes, unsigned char *hash)
{
SHA256_t s256;
- unsigned char *hash = chk_malloc(SHA256_DIGEST_LENGTH);
val buf = iobuf_get();
val bfsz = length_buf(buf);
SHA256_init(&s256);
@@ -89,13 +88,36 @@ val sha256_stream(val stream, val nbytes)
SHA256_final(&s256, hash);
iobuf_put(buf);
- return make_borrowed_buf(num_fast(SHA256_DIGEST_LENGTH), hash);
}
-static val sha256_buf(val buf, val self)
+static val sha256_ensure_buf(val self, val buf_in, unsigned char **phash)
+{
+ const cnum sdl = SHA256_DIGEST_LENGTH;
+
+ if (null_or_missing_p(buf_in)) {
+ *phash = chk_malloc(sdl);
+ return make_borrowed_buf(num_fast(sdl), *phash);
+ } else {
+ *phash = buf_get(buf_in, self);
+ if (lt(length_buf(buf_in), num_fast(sdl)))
+ uw_throwf(error_s, lit("~s: buffer ~s too small for SHA-256 hash"),
+ self, buf_in, nao);
+ return buf_in;
+ }
+}
+
+val sha256_stream(val stream, val nbytes, val buf_in)
+{
+ val self = lit("sha256-stream");
+ unsigned char *hash;
+ val buf = sha256_ensure_buf(self, buf_in, &hash);
+ sha256_stream_impl(stream, nbytes, hash);
+ return buf;
+}
+
+static void sha256_buf(val buf, unsigned char *hash)
{
SHA256_t s256;
- unsigned char *hash = chk_malloc(SHA256_DIGEST_LENGTH);
SHA256_init(&s256);
ucnum len = c_unum(buf->b.len);
mem_t *data = buf->b.data;
@@ -111,26 +133,29 @@ static val sha256_buf(val buf, val self)
SHA256_update(&s256, data, len);
SHA256_final(&s256, hash);
- return make_borrowed_buf(num_fast(SHA256_DIGEST_LENGTH), hash);
}
-static val sha256_str(val str, val self)
+static void sha256_str(val str, unsigned char *hash)
{
val s = make_byte_input_stream(str);
- return sha256_stream(s, nil);
+ sha256_stream_impl(s, nil, hash);
}
-val sha256(val obj)
+val sha256(val obj, val buf_in)
{
val self = lit("sha256");
+ unsigned char *hash;
+ val buf = sha256_ensure_buf(self, buf_in, &hash);
switch (type(obj)) {
case STR:
case LSTR:
case LIT:
- return sha256_str(obj, self);
+ sha256_str(obj, hash);
+ return buf;
case BUF:
- return sha256_buf(obj, self);
+ sha256_buf(obj, hash);
+ return buf;
default:
uw_throwf(error_s, lit("~a: cannot hash ~s, only buffer and strings"),
self, obj, nao);
@@ -223,8 +248,8 @@ val crc32(val obj)
void chksum_init(void)
{
- reg_fun(intern(lit("sha256-stream"), user_package), func_n2o(sha256_stream, 1));
- reg_fun(intern(lit("sha256"), user_package), func_n1(sha256));
+ reg_fun(intern(lit("sha256-stream"), user_package), func_n3o(sha256_stream, 1));
+ reg_fun(intern(lit("sha256"), user_package), func_n2o(sha256, 1));
reg_fun(intern(lit("crc32-stream"), user_package), func_n2o(crc32_stream, 1));
reg_fun(intern(lit("crc32"), user_package), func_n1(crc32));
}
diff --git a/chksum.h b/chksum.h
index e3516f57..6eb68588 100644
--- a/chksum.h
+++ b/chksum.h
@@ -25,8 +25,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-val sha256_stream(val stream, val nbytes);
-val sha256(val obj);
+val sha256_stream(val stream, val nbytes, val buf);
+val sha256(val obj, val buf);
val crc32_stream(val stream, val nbytes);
val crc32(val obj);
void chksum_init(void);
diff --git a/txr.1 b/txr.1
index 5bc1622c..b6844b4a 100644
--- a/txr.1
+++ b/txr.1
@@ -51969,7 +51969,7 @@ The CRC-32 is returned as a non-negative integer.
.coNP Function @ sha256-stream
.synb
-.mets (sha256-stream < stream <> [ nbytes ])
+.mets (sha256-stream < stream >> [ nbytes <> [ buf ]])
.syne
.desc
The
@@ -51985,11 +51985,17 @@ integer. It gives the number of bytes which should be read
and included in the digest. If the argument is omitted, then bytes are read
until the end of the stream.
-The 256 bit digest value is returned as a buffer containing 32 bytes.
+If the
+.meta buf
+argument is omitted, the 256 bit digest value is returned as a new,
+32-byte-long buffer object. If the
+.meta buf
+argument is specified, it must be a buffer that is at least 32 bytes long.
+The hash is placed into that buffer, which is then returned.
.coNP Function @ sha256
.synb
-.mets (sha256 << obj )
+.mets (sha256 < obj <> [ buf ])
.syne
.desc
The
@@ -52008,7 +52014,13 @@ If
is a character string, then the digest is calculated over the bytes
which constitute its UTF-8 representation.
-The 256 bit digest value is returned as a buffer containing 32 bytes.
+If the
+.meta buf
+argument is omitted, the 256 bit digest value is returned as a new,
+32-byte-long buffer object. If the
+.meta buf
+argument is specified, it must be a buffer that is at least 32 bytes long.
+The hash is placed into that buffer, which is then returned.
.SS* The Awk Utility