diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-07-04 07:28:18 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-07-04 07:28:18 -0700 |
commit | c7b508747347e8a17546140da64e5170b01e075e (patch) | |
tree | 857bb702a1171282afff5ae00d1a51b316fceea0 /chksum.c | |
parent | f47ad62b88bcff263c3f14b3107968efffd8378a (diff) | |
download | txr-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.
Diffstat (limited to 'chksum.c')
-rw-r--r-- | chksum.c | 51 |
1 files changed, 38 insertions, 13 deletions
@@ -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)); } |