DEFINITION MODULE AES;

        (********************************************************)
        (*                                                      *)
        (*    AES: Keyed hashing for message authentication     *)
        (*                                                      *)
        (*  Implementation of AES as defined in NIST.FIPS.197   *)
        (*  We support the versions AES-128, AES-192, AES-256   *)
        (*  and also the CBC and CTR modes of these three.      *)
        (*                                                      *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            12 October 2017                 *)
        (*  Last edited:        28 September 2021               *)
        (*  Status:             Working                         *)
        (*                                                      *)
        (********************************************************)


FROM SYSTEM IMPORT CARD8;

TYPE AEScontext;         (* is private *)

PROCEDURE AESopen (decrypt, fullpadding: BOOLEAN;  variant: CARDINAL;
                                        key: ARRAY OF CARD8): AEScontext;

    (* Begins one ciphering operation.  The returned value can then be  *)
    (* used in encryption and decryption operations using this key.     *)
    (* We recognise three versions of the algorithm:                    *)
    (*        variant     key length (bytes)      key length (bits)     *)
    (*          128             16                      128             *)
    (*          192             24                      192             *)
    (*          256             32                      256             *)
    (*                                                                  *)
    (* The two Boolean parameters are:                                  *)
    (*                                                                  *)
    (*      decrypt     FALSE for encryption, TRUE for decryption       *)
    (*                                                                  *)
    (*      fullpadding TRUE if you want the padding style specified    *)
    (*                  in PKCS #7 (a repeated extra byte count).       *)
    (*                  If you set this to FALSE then the only padding  *)
    (*                  is Nul bytes added to a final partial block,    *)
    (*                  and there is no padding at all if the input     *)
    (*                  length is a multiple of 16.                     *)
    (*                                                                  *)
    (* During decryption, the padding is stripped if the fullpadding    *)
    (* option is specified.  This does mean that the output is one      *)
    (* block behind the input in that case, because we need to know     *)
    (* which block is the last block before removing padding.  If you   *)
    (* want to keep the output in synchronism with the input, set       *)
    (* fullpadding to FALSE.                                            *)

PROCEDURE AES_CBCopen (decrypt, fullpadding: BOOLEAN;  variant: CARDINAL;
                                    key, IV: ARRAY OF CARD8): AEScontext;

    (* Like AESopen, but enables the Cipher Block Chaining (CBC) mode   *)
    (* of AES.  The extra parameter IV is the initialisation vector.    *)

PROCEDURE AES_CTRopen (variant: CARDINAL;  key: ARRAY OF CARD8;
                        nonce: CARDINAL;  IV: ARRAY OF CARD8): AEScontext;

    (* Like AESopen, but enables the Counter (CTR) mode of AES.  The    *)
    (* nonce (32 bits) and IV (64 bits) are assumed to be already in    *)
    (* bigendian order.                                                 *)

PROCEDURE AES_SDCTRopen (variant: CARDINAL;  key: ARRAY OF CARD8;
                                    IV: ARRAY OF CARD8): AEScontext;

    (* Similar to AES_CTRopen, but in this case the counter is a full   *)
    (* 16 bytes long, and IV, assumed to be in bigendian order,  is the *)
    (* initial counter value.                                           *)

PROCEDURE AESprocess (ctx: AEScontext;  inputlength: CARDINAL;
                             VAR (*IN*) input: ARRAY OF CARD8;
                             VAR (*OUT*) output: ARRAY OF CARD8;
                             VAR (*INOUT*) outpos: CARDINAL);

    (* Encrypts or decrypts the input array, depending on what was      *)
    (* specified in AESopen.  The result is stored beginning at         *)
    (* output[outpos], and outpos is updated.  It is legal to call this *)
    (* multiple times before the AESfinal call that terminates the      *)
    (* operation.                                                       *)

PROCEDURE AESfinal (VAR (*INOUT*) ctx: AEScontext;
                            VAR (*OUT*) output: ARRAY OF CARD8;
                             VAR (*INOUT*) outpos: CARDINAL);

    (* Processes any remaining unsent data, adds or removes padding as  *)
    (* needed, then terminates the use of the key specified in AESopen. *)

END AES.

