/*
webid-oidc, implementation of the Solid specification
Copyright (C) 2020, 2021 Vivien Kraus
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
#include
#include
#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 */
}