/*
 * SHA-256 (FIPS 180-4) and HMAC-SHA-256 (RFC 2104).
 *
 * Written for LanMan98; placed in the public domain.  The interface
 * deliberately matches md5.h, which is what the rest of this module
 * already uses, so the two can be swapped by name.
 *
 * SMB2 signs with HMAC-SHA-256 over the whole message.  Nothing else
 * here needs a SHA, so this is the smallest implementation that is
 * still readable rather than the fastest one.
 *   Portions Copyright RISC OS Developments 2019+, credited to the RISC OS One Project.
 */

#ifndef __SHA256_H
#define __SHA256_H

#include <stdlib.h>

#define SHA256_RESULTLEN (256/8)
#define SHA256_BLOCKLEN  (64)

typedef unsigned int sha256_uint32;

struct sha256_context
{
    sha256_uint32 state[8];
    sha256_uint32 lo, hi;           /* message length in bits, two halves */
    unsigned char buffer[SHA256_BLOCKLEN];
    unsigned int  used;             /* bytes currently in buffer */
};

void sha256_init(struct sha256_context *ctx);
void sha256_update(struct sha256_context *ctx, const void *data, size_t size);
void sha256_final(struct sha256_context *ctx,
                  unsigned char result[SHA256_RESULTLEN]);

void sha256_get_digest(const void *data, size_t size,
                       unsigned char result[SHA256_RESULTLEN]);

void hmac_sha256(const unsigned char *key, size_t key_len,
                 const void *data, size_t size,
                 unsigned char result[SHA256_RESULTLEN]);

/*
    The same, over two pieces without joining them first.  A signature is
    taken over a header and a body that are already adjacent in the packet
    buffer, but the key schedule is worth not repeating.
*/
void hmac_sha256_2(const unsigned char *key, size_t key_len,
                   const void *d1, size_t n1,
                   const void *d2, size_t n2,
                   unsigned char result[SHA256_RESULTLEN]);

#endif
