Packages

libdecaf NIF for ECDH (X25519, X448), EdDSA (Ed25519, Ed25519ctx, Ed25519ph, Ed448, Ed448ph), curve25519, curve448, spongerng

Current section

Files

Jump to
libdecaf c_src nif impl sha512.c.h
Raw

c_src/nif/impl/sha512.c.h

// -*- mode: c; tab-width: 4; indent-tabs-mode: nil; st-rulers: [132] -*-
// vim: ts=4 sw=4 ft=c et
#include <decaf/sha512.h>
/*
* Erlang NIF functions
*/
/* libdecaf_nif:sha2_512/2 */
static int libdecaf_nif_sha2_512_2_work(ErlNifEnv *env, xnif_slice_t *slice, int *phasep, size_t *offsetp, size_t reductions);
static ERL_NIF_TERM libdecaf_nif_sha2_512_2_done(ErlNifEnv *env, xnif_slice_t *slice);
static xnif_slice_func_t libdecaf_nif_sha2_512_2_func = {
libdecaf_nif_sha2_512_2_work,
libdecaf_nif_sha2_512_2_done,
NULL,
NULL,
};
static ERL_NIF_TERM
libdecaf_nif_sha2_512_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
struct decaf_sha512_ctx_s ctxbuf;
struct decaf_sha512_ctx_s *ctx = &ctxbuf;
ErlNifBinary input;
unsigned long outlen;
unsigned char *outbuf = NULL;
ERL_NIF_TERM out_term;
if (argc != 2 || !enif_inspect_iolist_as_binary(env, argv[0], &input) || !enif_get_ulong(env, argv[1], &outlen) ||
outlen > 64) {
return enif_make_badarg(env);
}
(void)decaf_sha512_init(ctx);
if (input.size <= XNIF_SLICE_MAX_PER_SLICE) {
outbuf = enif_make_new_binary(env, outlen, &out_term);
(void)decaf_sha512_update(ctx, input.data, input.size);
(void)decaf_sha512_final(ctx, outbuf, outlen);
(void)decaf_sha512_destroy(ctx);
return out_term;
}
ctx = libdecaf_nif_alloc_sha2_512_ctx(env);
if (ctx == NULL) {
return enif_make_badarg(env);
}
(void)memcpy(ctx, &ctxbuf, sizeof(struct decaf_sha512_ctx_s));
xnif_slice_t *slice = xnif_slice_create(env, "sha2_512", &libdecaf_nif_sha2_512_2_func, 0, input.size);
if (slice == NULL) {
(void)enif_release_resource((void *)ctx);
return enif_make_badarg(env);
}
ERL_NIF_TERM newargv[3];
newargv[0] = enif_make_resource(env, (void *)ctx);
newargv[1] = argv[0];
newargv[2] = argv[1];
(void)enif_release_resource((void *)ctx);
return xnif_slice_schedule(env, slice, 3, newargv);
}
static int
libdecaf_nif_sha2_512_2_work(ErlNifEnv *env, xnif_slice_t *slice, int *phasep, size_t *offsetp, size_t reductions)
{
struct decaf_sha512_ctx_s *ctx = NULL;
size_t offset = *offsetp;
ErlNifBinary input;
if (slice->argc != 3 || !libdecaf_nif_get_sha2_512_ctx(env, slice->argv[0], &ctx) ||
!enif_inspect_iolist_as_binary(env, slice->argv[1], &input)) {
return -1;
}
(void)decaf_sha512_update(ctx, (const uint8_t *)input.data + offset, reductions);
*offsetp = offset + reductions;
return 0;
}
static ERL_NIF_TERM
libdecaf_nif_sha2_512_2_done(ErlNifEnv *env, xnif_slice_t *slice)
{
struct decaf_sha512_ctx_s *ctx = NULL;
unsigned long outlen;
unsigned char *outbuf = NULL;
ERL_NIF_TERM out_term;
if (slice->argc != 3 || !libdecaf_nif_get_sha2_512_ctx(env, slice->argv[0], &ctx) ||
!enif_get_ulong(env, slice->argv[2], &outlen) || outlen > 64) {
return enif_make_badarg(env);
}
outbuf = enif_make_new_binary(env, outlen, &out_term);
(void)decaf_sha512_final(ctx, outbuf, outlen);
(void)decaf_sha512_destroy(ctx);
return out_term;
}
/* libdecaf_nif:sha2_512_init/0 */
static ERL_NIF_TERM
libdecaf_nif_sha2_512_init_0(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
struct decaf_sha512_ctx_s ctxbuf;
struct decaf_sha512_ctx_s *ctx = &ctxbuf;
ERL_NIF_TERM out_term;
if (argc != 0) {
return enif_make_badarg(env);
}
(void)decaf_sha512_init(ctx);
ctx = libdecaf_nif_alloc_sha2_512_ctx(env);
if (ctx == NULL) {
return enif_make_badarg(env);
}
(void)memcpy(ctx, &ctxbuf, sizeof(struct decaf_sha512_ctx_s));
out_term = enif_make_resource(env, (void *)ctx);
(void)enif_release_resource((void *)ctx);
return out_term;
}
/* libdecaf_nif:sha2_512_update/2 */
static int libdecaf_nif_sha2_512_update_2_work(ErlNifEnv *env, xnif_slice_t *slice, int *phasep, size_t *offsetp,
size_t reductions);
static ERL_NIF_TERM libdecaf_nif_sha2_512_update_2_done(ErlNifEnv *env, xnif_slice_t *slice);
static xnif_slice_func_t libdecaf_nif_sha2_512_update_2_func = {
libdecaf_nif_sha2_512_update_2_work,
libdecaf_nif_sha2_512_update_2_done,
NULL,
NULL,
};
static ERL_NIF_TERM
libdecaf_nif_sha2_512_update_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
struct decaf_sha512_ctx_s *old_ctx = NULL;
struct decaf_sha512_ctx_s *new_ctx = NULL;
ErlNifBinary input;
ERL_NIF_TERM out_term;
if (argc != 2 || !libdecaf_nif_get_sha2_512_ctx(env, argv[0], &old_ctx) ||
!enif_inspect_iolist_as_binary(env, argv[1], &input)) {
return enif_make_badarg(env);
}
new_ctx = libdecaf_nif_alloc_sha2_512_ctx(env);
if (new_ctx == NULL) {
return enif_make_badarg(env);
}
(void)memcpy(new_ctx, old_ctx, sizeof(struct decaf_sha512_ctx_s));
if (input.size <= XNIF_SLICE_MAX_PER_SLICE) {
(void)decaf_sha512_update(new_ctx, input.data, input.size);
out_term = enif_make_resource(env, (void *)new_ctx);
(void)enif_release_resource((void *)new_ctx);
return out_term;
}
xnif_slice_t *slice = xnif_slice_create(env, "sha2_512_update", &libdecaf_nif_sha2_512_update_2_func, 0, input.size);
if (slice == NULL) {
(void)enif_release_resource((void *)new_ctx);
return enif_make_badarg(env);
}
ERL_NIF_TERM newargv[2];
newargv[0] = enif_make_resource(env, (void *)new_ctx);
newargv[1] = argv[1];
(void)enif_release_resource((void *)new_ctx);
return xnif_slice_schedule(env, slice, 2, newargv);
}
static int
libdecaf_nif_sha2_512_update_2_work(ErlNifEnv *env, xnif_slice_t *slice, int *phasep, size_t *offsetp, size_t reductions)
{
struct decaf_sha512_ctx_s *ctx = NULL;
size_t offset = *offsetp;
ErlNifBinary input;
if (slice->argc != 2 || !libdecaf_nif_get_sha2_512_ctx(env, slice->argv[0], &ctx) ||
!enif_inspect_iolist_as_binary(env, slice->argv[1], &input)) {
return -1;
}
(void)decaf_sha512_update(ctx, (const uint8_t *)input.data + offset, reductions);
*offsetp = offset + reductions;
return 0;
}
static ERL_NIF_TERM
libdecaf_nif_sha2_512_update_2_done(ErlNifEnv *env, xnif_slice_t *slice)
{
struct decaf_sha512_ctx_s *ctx = NULL;
if (slice->argc != 2 || !libdecaf_nif_get_sha2_512_ctx(env, slice->argv[0], &ctx)) {
return enif_make_badarg(env);
}
return slice->argv[0];
}
/* libdecaf_nif:sha2_512_final/2 */
static ERL_NIF_TERM
libdecaf_nif_sha2_512_final_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
struct decaf_sha512_ctx_s *old_ctx = NULL;
struct decaf_sha512_ctx_s new_ctxbuf;
struct decaf_sha512_ctx_s *new_ctx = &new_ctxbuf;
unsigned long outlen;
unsigned char *outbuf = NULL;
ERL_NIF_TERM out_term;
if (argc != 2 || !libdecaf_nif_get_sha2_512_ctx(env, argv[0], &old_ctx) || !enif_get_ulong(env, argv[1], &outlen) ||
outlen > 64) {
return enif_make_badarg(env);
}
(void)memcpy(new_ctx, old_ctx, sizeof(struct decaf_sha512_ctx_s));
outbuf = enif_make_new_binary(env, outlen, &out_term);
(void)decaf_sha512_final(new_ctx, outbuf, outlen);
(void)decaf_sha512_destroy(new_ctx);
return out_term;
}