summaryrefslogtreecommitdiff
path: root/src/hash/libwebidoidc-hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hash/libwebidoidc-hash.c')
-rw-r--r--src/hash/libwebidoidc-hash.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/hash/libwebidoidc-hash.c b/src/hash/libwebidoidc-hash.c
new file mode 100644
index 0000000..75d7da9
--- /dev/null
+++ b/src/hash/libwebidoidc-hash.c
@@ -0,0 +1,64 @@
+#include <utilities.h>
+#include <nettle/sha2.h>
+
+#define _(s) dgettext (PACKAGE, s)
+
+SCM_SYMBOL (sha256, "SHA-256");
+SCM_SYMBOL (sha384, "SHA-384");
+SCM_SYMBOL (sha512, "SHA-512");
+
+SCM_SYMBOL (unsupported_alg, "unsupported-alg");
+
+SCM_DEFINE (webidoidc_hash_g, "hash", 2, 0, 0, (SCM alg, SCM payload),
+ "Hash something with @var{alg}, which must be @code{'SHA-256}, @code{'SHA-384} or @code{'SHA-512}.")
+{
+ size_t payload_size;
+ uint8_t *c_payload;
+ if (scm_is_string (payload))
+ {
+ return webidoidc_hash_g (alg, scm_string_to_utf8 (payload));
+ }
+ payload_size = scm_c_bytevector_length (payload);
+ c_payload = scm_gc_malloc_pointerless (payload_size, "To hash");
+ memcpy (c_payload, SCM_BYTEVECTOR_CONTENTS (payload), payload_size);
+ if (scm_is_eq (alg, sha256))
+ {
+ struct sha256_ctx hash;
+ uint8_t digest[SHA256_DIGEST_SIZE];
+ sha256_init (&hash);
+ sha256_update (&hash, payload_size, c_payload);
+ sha256_digest (&hash, SHA256_DIGEST_SIZE, digest);
+ return wrap_bytevector (SHA256_DIGEST_SIZE, digest);
+ }
+ else if (scm_is_eq (alg, sha384))
+ {
+ struct sha384_ctx hash;
+ uint8_t digest[SHA384_DIGEST_SIZE];
+ sha384_init (&hash);
+ sha384_update (&hash, payload_size, c_payload);
+ sha384_digest (&hash, SHA384_DIGEST_SIZE, digest);
+ return wrap_bytevector (SHA384_DIGEST_SIZE, digest);
+ }
+ else if (scm_is_eq (alg, sha512))
+ {
+ struct sha512_ctx hash;
+ uint8_t digest[SHA512_DIGEST_SIZE];
+ sha512_init (&hash);
+ sha512_update (&hash, payload_size, c_payload);
+ sha512_digest (&hash, SHA512_DIGEST_SIZE, digest);
+ return wrap_bytevector (SHA512_DIGEST_SIZE, digest);
+ }
+ else
+ {
+ scm_throw (unsupported_alg, scm_list_1 (alg));
+ }
+ return SCM_UNDEFINED;
+}
+
+void
+init_webidoidc_hash (void)
+{
+#ifndef SCM_MAGIC_SNARFER
+#include "libwebidoidc-hash.x"
+#endif /* not SCM_MAGIC_SNARFER */
+}