diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-08-23 23:06:09 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-08-23 23:06:09 -0700 |
commit | 8a10829e5e35e5b0721260e0a7b31554ec21d766 (patch) | |
tree | 037c9464dc75ff36bbfadd0c2f1117fa60b28d75 /chksum.c | |
parent | 27a722e96f281974e9f49887e9470422dcb1da91 (diff) | |
download | txr-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.c | 112 |
1 files changed, 112 insertions, 0 deletions
@@ -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)); } |