File indexing completed on 2024-06-16 03:53:04
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2001 George Staikos <staikos@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "cbc.h" 0009 #include <string.h> 0010 0011 CipherBlockChain::CipherBlockChain(BlockCipher *cipher) : _cipher(cipher) 0012 { 0013 _next = 0L; 0014 _register = 0L; 0015 _len = -1; 0016 _reader = _writer = 0L; 0017 if (cipher) { 0018 _blksz = cipher->blockSize(); 0019 } 0020 } 0021 0022 CipherBlockChain::~CipherBlockChain() 0023 { 0024 delete[](char *)_register; 0025 _register = 0L; 0026 delete[](char *)_next; 0027 _next = 0L; 0028 } 0029 0030 bool CipherBlockChain::setKey(void *key, int bitlength) 0031 { 0032 if (_cipher) { 0033 return _cipher->setKey(key, bitlength); 0034 } 0035 return false; 0036 } 0037 0038 int CipherBlockChain::keyLen() const 0039 { 0040 if (_cipher) { 0041 return _cipher->keyLen(); 0042 } 0043 return -1; 0044 } 0045 0046 bool CipherBlockChain::variableKeyLen() const 0047 { 0048 if (_cipher) { 0049 return _cipher->variableKeyLen(); 0050 } 0051 return false; 0052 } 0053 0054 bool CipherBlockChain::readyToGo() const 0055 { 0056 if (_cipher) { 0057 return _cipher->readyToGo(); 0058 } 0059 return false; 0060 } 0061 0062 int CipherBlockChain::encrypt(void *block, int len) 0063 { 0064 if (_cipher && !_reader) { 0065 int rc; 0066 0067 _writer |= 1; 0068 0069 if (!_register) { 0070 _register = new unsigned char[len]; 0071 _len = len; 0072 memset(_register, 0, len); 0073 } else if (len > _len) { 0074 return -1; 0075 } 0076 0077 // This might be optimizable 0078 char *tb = (char *)block; 0079 for (int i = 0; i < len; i++) { 0080 tb[i] ^= ((char *)_register)[i]; 0081 } 0082 0083 rc = _cipher->encrypt(block, len); 0084 0085 if (rc != -1) { 0086 memcpy(_register, block, len); 0087 } 0088 0089 return rc; 0090 } 0091 return -1; 0092 } 0093 0094 int CipherBlockChain::decrypt(void *block, int len) 0095 { 0096 if (_cipher && !_writer) { 0097 int rc; 0098 0099 _reader |= 1; 0100 0101 if (!_register) { 0102 _register = new unsigned char[len]; 0103 _len = len; 0104 memset(_register, 0, len); 0105 } else if (len > _len) { 0106 return -1; 0107 } 0108 0109 if (!_next) { 0110 _next = new unsigned char[_len]; 0111 } 0112 memcpy(_next, block, _len); 0113 0114 rc = _cipher->decrypt(block, len); 0115 0116 if (rc != -1) { 0117 // This might be optimizable 0118 char *tb = (char *)block; 0119 for (int i = 0; i < len; i++) { 0120 tb[i] ^= ((char *)_register)[i]; 0121 } 0122 } 0123 0124 void *temp; 0125 temp = _next; 0126 _next = _register; 0127 _register = temp; 0128 0129 return rc; 0130 } 0131 return -1; 0132 } 0133