diff options
Diffstat (limited to 'src/hash/libwebidoidc-hash.c')
-rw-r--r-- | src/hash/libwebidoidc-hash.c | 64 |
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 */ +} |