DEFINITION MODULE HMAC;

        (********************************************************)
        (*                                                      *)
        (*    HMAC: Keyed hashing for message authentication    *)
        (*                                                      *)
        (*     Implementation of HMAC as defined in RFC2104     *)
        (*                                                      *)
        (*     This module implements the variants HMAC-MD5,    *)
        (*     HMAC-SHA1, HMAC-SHA256, HMAC-SHA384, and         *)
        (*     HMAC-SHA512.  It could easily be extended to     *)
        (*     other variants if desired.                       *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            18 February 2005                *)
        (*  Last edited:        29 October 2024                 *)
        (*  Status:             OK                              *)
        (*                                                      *)
        (*  Revised June 2021 to make each result a bigendian   *)
        (*  string of CARD8, rather than an array of numbers    *)
        (*  whose endianness was ambiguous.                     *)
        (*                                                      *)
        (********************************************************)


FROM SYSTEM IMPORT LOC, CARD8;

PROCEDURE HMAC_MD5 (key: ARRAY OF CARD8;  keylength: CARDINAL;
                     VAR (*IN*) text: ARRAY OF CARD8;  textlength: CARDINAL;
                     VAR (*OUT*) Digest: ARRAY OF CARD8);

    (* Performs the HMAC-MD5 hashing method, with Digest as the result. *)

PROCEDURE HMAC_SHA1 (key: ARRAY OF CARD8;  keylength: CARDINAL;
                     VAR (*IN*) text: ARRAY OF CARD8;  textlength: CARDINAL;
                     VAR (*OUT*) Digest: ARRAY OF CARD8);

    (* Performs the HMAC-SHA1 hashing method, with Digest as the result. *)

PROCEDURE HMAC_SHA256 (key: ARRAY OF CARD8;  keylength: CARDINAL;
                     VAR (*IN*) text: ARRAY OF CARD8;  textlength: CARDINAL;
                     VAR (*OUT*) Digest: ARRAY OF CARD8);

    (* Performs the HMAC-SHA256 hashing method, with Digest as the result. *)

PROCEDURE HMAC_SHA384 (key: ARRAY OF CARD8;  keylength: CARDINAL;
                     VAR (*IN*) text: ARRAY OF CARD8;  textlength: CARDINAL;
                     VAR (*OUT*) Digest: ARRAY OF CARD8);

    (* Performs the HMAC-SHA384 hashing method, with Digest as the result. *)

PROCEDURE HMAC_SHA512 (key: ARRAY OF CARD8;  keylength: CARDINAL;
                     VAR (*IN*) text: ARRAY OF CARD8;  textlength: CARDINAL;
                     VAR (*OUT*) Digest: ARRAY OF CARD8);

    (* Performs the HMAC-SHA512 hashing method, with Digest as the result. *)

(************************************************************************)
(*  The following procedures implement a new approach. Working.         *)
(************************************************************************)

TYPE HMAC_SHA256_context;       (* is private *)

PROCEDURE HMAC_SHA256_Init (key: ARRAY OF LOC;
                                keylength: CARDINAL): HMAC_SHA256_context;

    (* Performs the first step of the HMAC-SHA256 hashing method. *)

PROCEDURE HMAC_SHA256_Update (ctx: HMAC_SHA256_context;
                     VAR (*IN*) text: ARRAY OF LOC;  textlength: CARDINAL);

    (* Supplies the input to be hashed.                         *)
    (* This can be called multiple times, to add more input.    *)

PROCEDURE HMAC_SHA256_Final (ctx: HMAC_SHA256_context;
                                    VAR (*OUT*) Digest: ARRAY OF CARD8);

    (* Performs the final step of the HMAC-SHA256 hashing method,   *)
    (* with Digest as the result.                                   *)

END HMAC.

