cryptmodes_64.mli 7.52 KB
Newer Older
gerd's avatar
gerd committed
1
(* $Id: cryptmodes_64.mli,v 1.2 2001/03/10 16:43:21 gerd Exp $
gerd's avatar
gerd committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
 * ----------------------------------------------------------------------
 * This module is part of the cryptgps package by Gerd Stolpmann.
 *)

(* OVERVIEW:
 *
 * A block cipher encrypts or decrypts a fixed amount of bits on every
 * invocation. Here, we assume that the underlying cipher handles 64 bit
 * blocks as elementary units.
 * If you have a message which is a multiple of 64 bits, you could encrypt
 * every block independently. IT IS STRONGLY RECOMMENDED NOT TO USE THIS
 * SIMPLE APPROACH. This method, often called ECB ("electronic code book"),
 * is vulnerable by plaintext attacks, even if a strong cipher is used.
 * This module implements the following, much better alternatives.
 *
 * ---------------------
 * CIPHER BLOCK CHAINING
 * ---------------------
 *
 * USAGE, LIMITATIONS:
 *
 * - buffer size: the buffer to be en/decrypted must be a multiple of 64 bits.
 * - initialization vector: the ivec used for encryption must be same as the
 *   ivec for decryption. The ivec is not secret, it can be transmitted along
 *   with the ciphertext. It is recommended to use the timestamp as ivec,
 *   or some random bits.
 *
 * SECURITY:
 *
 * - good: 
 *   plaintext patterns (i.e. text structure in the plaintext) is hidden in
 *   the ciphertext 
 * - bad: some manipulations in the ciphertext at the end of the message
 *   are possible. To avoid this, compute an MD5 hash of the message, and
 *   PREPEND the hash value to the message.
 *
 * FAULT-TOLERANCE:
 * 
 * - a bit error in the ciphertext affects the corresponding plaintext and
 *   the following block
 * - no recovery from synchronisation errors possible (missing or extra bits)
 *
 * --------------------
 * CIPHER-FEEDBACK MODE
 * --------------------
 *
 * USAGE, LIMITATIONS:
 *
 * - buffer size: no restrictions
 * - initialization vector: the ivec used for encryption must be same as the
 *   ivec for decryption. The ivec is not secret, it can be transmitted along
 *   with the ciphertext. A different ivec must be used for every transmitted
 *   message, e.g. MD5(timestamp + serial number).
 *
 * SECURITY:
 *
 * - good: 
 *   plaintext patterns (i.e. text structure in the plaintext) is hidden in
 *   the ciphertext 
 * - bad: some manipulations in the ciphertext at the end of the message
 *   are possible. To avoid this, compute an MD5 hash of the message, and
 *   PREPEND the hash value to the message.
 * 
 * FAULT TOLERANCE:
 *
 * - a bit error in the ciphertext affects the corresponding plaintext and
 *   the following block
 * - n-bit CFB can recover from missing n or extra n bits.
 *
 * --------------------
 * OUTPUT-FEEDBACK MODE
 * --------------------
 *
 * USAGE, LIMITATIONS:
 *
 * - buffer size: no restrictions
 * - initialization vector: the ivec used for encryption must be same as the
 *   ivec for decryption. The ivec is not secret, it can be transmitted along
 *   with the ciphertext. A different ivec must be used for every transmitted
 *   message, e.g. MD5(timestamp + serial number).
 *
 * SECURITY:
 *
 * - good: 
 *   plaintext patterns (i.e. text structure in the plaintext) is hidden in
 *   the ciphertext 
 * - bad:
 *   manipulation of bits in the ciphertext directly affects the corresponding
 *   bits in the plaintext
 * 
 * FAULT TOLERANCE:
 *
 * - a bit error in the ciphertext affects only corresponding plaintext bit
 * - n-bit CFB cannot recover from missing or extra bits.
 *
 * --------------
 * RECOMMENDATION
 * --------------
 *
 * - If the encrypted messages are transmitted on a serial line, use CFB-8.
 *   This is the only mode which can recover from synchronization errors on
 *   byte level.
 * - If your message is a multiple of 64 bits, use CBC. If possible, pad
 *   the message to fill up to the next 64 bit multiple, and send the length
 *   of the message, too. 
 * - Otherwise, use CFB-64.
 *)


module type T =
    sig
      
      type key

      (* CIPHER BLOCK CHAINING MODE *)

      val encrypt_cbc :
	  key -> (int * int * int * int) -> string -> 
	    ((int * int * int * int) * string)
	(* Encrypts the string whose length MUST be a multiple of 8 bytes
	 * with the given key and initialization vector, resulting in the
	 * output vector (for the next CBC cascade) and the encrypted string.
	 * The size of the string remains unchanged when it is encrypted.
	 *)

      val decrypt_cbc :
	  key -> (int * int * int * int) -> string -> 
	    ((int * int * int * int) * string)
	(* Decrypts the string whose length MUST be a multiple of 8 bytes
	 * with the given key and initialization vector, resulting in the
	 * output vector (for the next CBC cascade) and the decrypted string.
	 *)

      (* 8 BIT CIPHER-FEEDBACK MODE *)

	      (* This is 8 times slower than CBC *)

      val encrypt_cfb8 :
	  key -> (int * int * int * int) -> string -> 
	    ((int * int * int * int) * string)
	(* Encrypts the string (with arbitraty length) with the given key
	 * and initialization vector, resulting in the output vector (for
	 * the next CFB cascade) and the encrypted string (of the same
	 * length).
	 *)

      val decrypt_cfb8 :
	  key -> (int * int * int * int) -> string -> 
	    ((int * int * int * int) * string)
	(* Decrypts the string (with arbitraty length) with the given key
	 * and initialization vector, resulting in the output vector (for
	 * the next CFB cascade) and the decrypted string (of the same
	 * length).
	 *)

      (* 64 BIT CIPHER-FEEDBACK MODE *)

      val encrypt_cfb64 :
	  key -> (int * int * int * int) -> int -> string -> 
	    ((int * int * int * int) * int * string)
	(* Encrypts the string (with arbitraty length) with the given key
	 * and initialization vector, resulting in the output vector (for
	 * the next CFB cascade) and the encrypted string (of the same
	 * length).
	 * Compared with cfb8, there is an additional int that it passed
	 * to and from this function. It is always in the range 0..7 and
	 * indicates which byte of the 64 bit block comes next. In doubt,
         * pass a 0 as this int.
	 *)

      val decrypt_cfb64 :
	  key -> (int * int * int * int) -> int -> string -> 
	    ((int * int * int * int) * int * string)
	(* Decrypts the string (with arbitraty length) with the given key
	 * and initialization vector, resulting in the output vector (for
	 * the next CFB cascade) and the decrypted string (of the same
	 * length).
	 *)

      (* OUTPUT-FEEDBACK MODE (64 bit) *)

      val crypt_ofb :
	  key -> (int * int * int * int) -> int -> string -> 
	    ((int * int * int * int) * int * string)
	(* Encrypts/Decrypts the string 
	 * with the given key and initialization vector, resulting in the
	 * output vector (for the next OFB cascade) and the encrypted string.
	 * The size of the string remains unchanged when it is encrypted.
	 *)
    end
;;


gerd's avatar
gerd committed
195 196 197 198 199 200 201 202 203 204 205
(* Derives the other modes from the basic ECB mode:
 * 
 * Make_modes: This version is efficient for cryptsystems based on
 *   encrypt_ecb
 * Make_modes_int32: This version is efficient for cryptsystems based on
 *   encrypt_ecb_int32
 *
 * Both functors behave in an equivalent way; the only difference is that
 * Make_modes is fast if M.encrypt_ecb is fast, and that Make_modes_int32
 * is fast if M.encrypt_ecb_int32 is fast.
 *)
gerd's avatar
gerd committed
206 207 208 209 210

module Make_modes (M : Cryptsystem_64.T) : T with type key = M.key
;;


gerd's avatar
gerd committed
211 212 213 214
module Make_modes_int32 (M : Cryptsystem_64.T) : T with type key = M.key
;;


gerd's avatar
gerd committed
215 216 217 218 219

(* ======================================================================
 * History:
 * 
 * $Log: cryptmodes_64.mli,v $
gerd's avatar
gerd committed
220 221 222
 * Revision 1.2  2001/03/10 16:43:21  gerd
 * 	int32 experiments
 *
gerd's avatar
gerd committed
223 224 225 226 227
 * Revision 1.1  1999/06/04 20:42:01  gerd
 * 	Initial revision.
 *
 * 
 *)