(********************************************************************) (* *) (* cipher.s7i Generic support for TLS bulk cipher algorithms. *) (* Copyright (C) 2013 Thomas Mertes *) (* *) (* This file is part of the Seed7 Runtime Library. *) (* *) (* The Seed7 Runtime Library is free software; you can *) (* redistribute it and/or modify it under the terms of the GNU *) (* Lesser General Public License as published by the Free Software *) (* Foundation; either version 2.1 of the License, or (at your *) (* option) any later version. *) (* *) (* The Seed7 Runtime Library 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 Lesser General Public License for more *) (* details. *) (* *) (* You should have received a copy of the GNU Lesser General *) (* Public License along with this program; if not, write to the *) (* Free Software Foundation, Inc., 51 Franklin Street, *) (* Fifth Floor, Boston, MA 02110-1301, USA. *) (* *) (********************************************************************) (** * Enumeration of cipher algorithms. * Currently the ciphers NO_CIPHER, RC4, DES, TDES, BLOWFISH, AES and * AES_GCM are supported. *) const type: cipherAlgorithm is new enum NO_CIPHER, RC4, DES, TDES, BLOWFISH, AES, AES_GCM end enum; (** * Interface type for the internal state of a cipher. * The cipherState interface is implemented with [[arc4]], [[des]], [[tdes]], * [[blowfish]], [[aes]], [[aes_gcm]] and [[#noCipherState|noCipher]] (no encryption). *) const type: cipherState is sub object interface; (** * Block size used by the given [[cipher#cipherAlgorithm|cipherAlgorithm]]. * Stream ciphers have a block size of 0. * @return the block size used by the ''cipherAlgorithm''. *) const func integer: blockSize (in cipherAlgorithm: cipherAlg) is DYNAMIC; (** * Set key and initialization vector for the given [[cipher#cipherAlgorithm|cipherAlgorithm]]. * @param cipherAlg The [[cipher#cipherAlgorithm|cipherAlgorithm]] to be used. * @return the ''cipherState'' of the ''cipherAlgorithm''. *) const func cipherState: setCipherKey (in cipherAlgorithm: cipherAlg, in string: cipherKey, in string: initializationVector) is DYNAMIC; (** * Initialize the authenticated encryption with associated data (AEAD). * For all other cipher algorithms this function does nothing. *) const proc: initAead (inout cipherState: state, in string: recordTypeAndVersion, in integer: sequenceNumber) is DYNAMIC; (** * Obtain the computed MAC of data that has been decrypted with an AEAD cipher. * For all other cipher algorithms this function raises an exception. * After a successful decryption with an AEAD cipher getComputedMac and getMac * should return the same value. *) const func string: getComputedMac (in cipherState: state) is DYNAMIC; (** * Obtain the MAC that is appended to the encrypted data of an AEAD cipher. * For all other cipher algorithms this function raises an exception. * After a successful decryption with an AEAD cipher getComputedMac and getMac * should return the same value. *) const func string: getMac (in cipherState: state) is DYNAMIC; (** * Encode a string with the ''state'' of the selected cipher algorithm. * @return the encoded string. *) const func string: encode (inout cipherState: state, in string: plaintext) is DYNAMIC; (** * Decode a string with the ''state'' of the selected cipher algorithm. * @return the decoded string. *) const func string: decode (inout cipherState: state, in string: encoded) is DYNAMIC; (* NO_CIPHER *) (** * [[cipher|cipherState]] implementation type describing the state if no cipher is used. * The data remains unencrypted if NO_CIPHER is used. *) const type: noCipherState is new struct end struct; type_implements_interface(noCipherState, cipherState); const cipherState: (attr cipherState) . value is noCipherState.value; const func integer: blockSize (NO_CIPHER) is 0; const func cipherState: setCipherKey (NO_CIPHER, in string: cipherKey, in string: initializationVector) is func result var cipherState: state is cipherState.value; local var noCipherState: new_state is noCipherState.value; begin state := toInterface(new_state); end func; const proc: initAead (inout noCipherState: state, in string: recordTypeAndVersion, in integer: sequenceNumber) is noop; const func string: encode (inout noCipherState: state, in string: plaintext) is return plaintext; const func string: decode (inout noCipherState: state, in string: encoded) is return encoded;