summaryrefslogtreecommitdiffstats
path: root/chksum.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-08-23 23:06:09 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-08-23 23:06:09 -0700
commit8a10829e5e35e5b0721260e0a7b31554ec21d766 (patch)
tree037c9464dc75ff36bbfadd0c2f1117fa60b28d75 /chksum.c
parent27a722e96f281974e9f49887e9470422dcb1da91 (diff)
downloadtxr-8a10829e5e35e5b0721260e0a7b31554ec21d766.tar.gz
txr-8a10829e5e35e5b0721260e0a7b31554ec21d766.tar.bz2
txr-8a10829e5e35e5b0721260e0a7b31554ec21d766.zip
New state-object-based sha256 and md5 digesting.
* chksum.c (sha256_ctx_s, md5_ctx_s): New symbol variables. (sha256_ops, md5_ops): New static structs. (sha256_begin, sha256_hash, sha256_end, md5_begin, md5_hash, md5_end): New functions. (chksum_init): New symbol variables initialized; sha256-begin, sha256-hash, sha256-end, md5-begin, md5-hash, md5-end intrinsics registered. * chksum.h (sha256_begin, sha256_hash, sha256_end, md5_begin, md5_hash, md5_end): Declared. * txr.1: Documented.
Diffstat (limited to 'chksum.c')
-rw-r--r--chksum.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/chksum.c b/chksum.c
index 6d65a203..776fe3d1 100644
--- a/chksum.c
+++ b/chksum.c
@@ -48,6 +48,8 @@
#include "chksums/md5.h"
#include "chksum.h"
+static val sha256_ctx_s, md5_ctx_s;
+
static void sha256_stream_impl(val stream, val nbytes, unsigned char *hash)
{
SHA256_t s256;
@@ -165,6 +167,57 @@ val sha256(val obj, val buf_in)
}
}
+static struct cobj_ops sha256_ops = cobj_ops_init(cobj_equal_handle_op,
+ cobj_print_op,
+ cobj_destroy_free_op,
+ cobj_mark_op,
+ cobj_handle_hash_op);
+val sha256_begin(void)
+{
+ SHA256_t *ps256 = coerce(SHA256_t *, chk_malloc(sizeof *ps256));
+ SHA256_init(ps256);
+ return cobj(coerce(mem_t *, ps256), sha256_ctx_s, &sha256_ops);
+}
+
+val sha256_hash(val ctx, val obj)
+{
+ val self = lit("sha256-hash");
+ SHA256_t *ps256 = coerce(SHA256_t *, cobj_handle(self, ctx, sha256_ctx_s));
+
+ switch (type(obj)) {
+ case STR:
+ case LSTR:
+ case LIT:
+ {
+ char *str = utf8_dup_to(c_str(obj));
+ SHA256_update(ps256, coerce(const unsigned char *, str), strlen(str));
+ free(str);
+ }
+ break;
+ case BUF:
+ SHA256_update(ps256, obj->b.data, c_unum(obj->b.len));
+ break;
+ default:
+ uw_throwf(error_s, lit("~a: cannot hash ~s, only buffer and strings"),
+ self, obj, nao);
+ }
+
+ return obj;
+}
+
+val sha256_end(val ctx, val buf_in)
+{
+ val self = lit("sha256-end");
+ unsigned char *hash;
+ SHA256_t *ps256 = coerce(SHA256_t *, cobj_handle(self, ctx, sha256_ctx_s));
+ val buf = chksum_ensure_buf(self, buf_in, num_fast(SHA256_DIGEST_LENGTH),
+ &hash, lit("SHA-256"));
+
+ SHA256_final(ps256, hash);
+ SHA256_init(ps256);
+ return buf;
+}
+
val crc32_stream(val stream, val nbytes)
{
u32_t crc = 0;
@@ -351,12 +404,71 @@ val md5(val obj, val buf_in)
}
}
+static struct cobj_ops md5_ops = cobj_ops_init(cobj_equal_handle_op,
+ cobj_print_op,
+ cobj_destroy_free_op,
+ cobj_mark_op,
+ cobj_handle_hash_op);
+val md5_begin(void)
+{
+ MD5_t *pmd5 = coerce(MD5_t *, chk_malloc(sizeof *pmd5));
+ MD5_init(pmd5);
+ return cobj(coerce(mem_t *, pmd5), md5_ctx_s, &md5_ops);
+}
+
+val md5_hash(val ctx, val obj)
+{
+ val self = lit("md5-hash");
+ MD5_t *pmd5 = coerce(MD5_t *, cobj_handle(self, ctx, md5_ctx_s));
+
+ switch (type(obj)) {
+ case STR:
+ case LSTR:
+ case LIT:
+ {
+ char *str = utf8_dup_to(c_str(obj));
+ MD5_update(pmd5, coerce(const unsigned char *, str), strlen(str));
+ free(str);
+ }
+ break;
+ case BUF:
+ MD5_update(pmd5, obj->b.data, c_unum(obj->b.len));
+ break;
+ default:
+ uw_throwf(error_s, lit("~a: cannot hash ~s, only buffer and strings"),
+ self, obj, nao);
+ }
+
+ return obj;
+}
+
+val md5_end(val ctx, val buf_in)
+{
+ val self = lit("md5-end");
+ unsigned char *hash;
+ MD5_t *pmd5 = coerce(MD5_t *, cobj_handle(self, ctx, md5_ctx_s));
+ val buf = chksum_ensure_buf(self, buf_in, num_fast(MD5_DIGEST_LENGTH),
+ &hash, lit("SHA-256"));
+
+ MD5_final(pmd5, hash);
+ MD5_init(pmd5);
+ return buf;
+}
+
void chksum_init(void)
{
+ sha256_ctx_s = intern(lit("sha256-ctx"), user_package);
+ md5_ctx_s = intern(lit("md5-ctx"), user_package);
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("sha256-begin"), user_package), func_n0(sha256_begin));
+ reg_fun(intern(lit("sha256-hash"), user_package), func_n2(sha256_hash));
+ reg_fun(intern(lit("sha256-end"), user_package), func_n2o(sha256_end, 1));
reg_fun(intern(lit("crc32-stream"), user_package), func_n2o(crc32_stream, 1));
reg_fun(intern(lit("crc32"), user_package), func_n1(crc32));
reg_fun(intern(lit("md5-stream"), user_package), func_n3o(md5_stream, 1));
reg_fun(intern(lit("md5"), user_package), func_n2o(md5, 1));
+ reg_fun(intern(lit("md5-begin"), user_package), func_n0(md5_begin));
+ reg_fun(intern(lit("md5-hash"), user_package), func_n2(md5_hash));
+ reg_fun(intern(lit("md5-end"), user_package), func_n2o(md5_end, 1));
}