1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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 */
}
|