(**************************************************************************)
(*                                                                        *)
(*  Encryption library                                                    *)
(*  Copyright (C) 2018   Peter Moylan                                     *)
(*                                                                        *)
(*  This program is free software: you can redistribute it and/or modify  *)
(*  it under the terms of the GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 3 of the License, or     *)
(*  (at your option) any later version.                                   *)
(*                                                                        *)
(*  This program is distributed in the hope that it will be useful,       *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
(*  GNU General Public License for more details.                          *)
(*                                                                        *)
(*  You should have received a copy of the GNU General Public License     *)
(*  along with this program.  If not, see <http://www.gnu.org/licenses/>. *)
(*                                                                        *)
(*  To contact author:   http://www.pmoylan.org   peter@pmoylan.org       *)
(*                                                                        *)
(**************************************************************************)


DEFINITION MODULE DES;

        (****************************************************************)
        (*                                                              *)
        (*               DES: Data encryption standard                  *)
        (*                                                              *)
        (*                 as specified in FIPS.46-3                    *)
        (*                                                              *)
        (*  Programmer:         P. Moylan                               *)
        (*  Started:            23 April 2018                           *)
        (*  Last edited:        24 January 2021                         *)
        (*  Status:             DES and 3DES both working               *)
        (*                      CBC mode also working                   *)
        (*                                                              *)
        (*  This module implements both DES and 3DES (the latter also   *)
        (*  called DES3 or triple-DES).  The decision as to which to    *)
        (*  use is based on the supplied key length.  At present we     *)
        (*  support only the ECB versions of these, but block chaining  *)
        (*  will be added if I find a need for it.                      *)
        (*                                                              *)
        (****************************************************************)


FROM SYSTEM IMPORT CARD8;

TYPE DEScontext;            (* is private *)


PROCEDURE DESopen (decrypt, fullpadding: BOOLEAN;  N: CARDINAL;
                                        key: ARRAY OF CARD8): DEScontext;

    (* Starts a new DES session.  The decrypt parameter is FALSE if we  *)
    (* are opening the session to do encryption, and TRUE for           *)
    (* decryption.  N is the length in bytes of the key.                *)
    (*                                                                  *)
    (* 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 8.                      *)
    (*                                                                  *)
    (* 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.           *)
    (*                                                                  *)
    (* Slightly unconventionally, we do not have separate calls for     *)
    (* DES and DES3.  Instead, we choose which one to use based on the  *)
    (* key length N.  DES3 permits three variants:                      *)
    (*  - if the key is 24 bytes long (N=24) then we have the full DES3 *)
    (*    implementation with three independent 8-byte keys.            *)
    (*  - if the key is 16 bytes long (N=16) then we set the third      *)
    (*    8-byte key  equal to the first.                               *)
    (*  - if the supplied key is 8 bytes long (N=8) then we use DES     *)
    (*    instead of DES3.                                              *)
    (* It is easy to see that DES3 with three identical keys would      *)
    (* produce the same result as if we had used DES, so we have not    *)
    (* lost anything by dropping back to DES for this case.             *)

PROCEDURE DES_CBCopen (decrypt, fullpadding: BOOLEAN;  N: CARDINAL;
                                    key, IV: ARRAY OF CARD8): DEScontext;

    (* Like DESopen, but enables the Cipher Block Chaining (CBC) mode   *)
    (* of DES.  The extra parameter IV is the initialisation vector,    *)
    (* which is 8 bytes long.                                           *)

PROCEDURE DumpKeySchedule (ctx: DEScontext);

    (* For testing: writes the key schedule to standard output. *)

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

    (* DES-ECB or DES-CBC encryption/decryption.  The same procedure    *)
    (* is used for both encryption and decryption; the difference lies  *)
    (* in what was specified when opening the session.  Output is added *)
    (* starting at output[outpos], and outpos is updated to be ready    *)
    (* for the next call to this procedure.                             *)

PROCEDURE DESfinal (VAR (*INOUT*) ctx: DEScontext;
                            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 DESopen. *)

END DES.

