KWallet

cbc.cc
1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2001 George Staikos <staikos@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "cbc.h"
9#include "kwalletbackend_debug.h"
10#include <string.h>
11
12CipherBlockChain::CipherBlockChain(BlockCipher *cipher, bool useECBforReading) :
13 _cipher(cipher)
14 , _useECBforReading(useECBforReading)
15{
16 _next = nullptr;
17 _register = nullptr;
18 _len = -1;
19 _reader = _writer = 0L;
20 if (cipher) {
21 _blksz = cipher->blockSize();
22 }
23}
24
25CipherBlockChain::~CipherBlockChain()
26{
27 delete[](char *)_register;
28 _register = nullptr;
29 delete[](char *)_next;
30 _next = nullptr;
31}
32
33bool CipherBlockChain::setKey(void *key, int bitlength)
34{
35 if (_cipher) {
36 return _cipher->setKey(key, bitlength);
37 }
38 return false;
39}
40
41int CipherBlockChain::keyLen() const
42{
43 if (_cipher) {
44 return _cipher->keyLen();
45 }
46 return -1;
47}
48
49bool CipherBlockChain::variableKeyLen() const
50{
51 if (_cipher) {
52 return _cipher->variableKeyLen();
53 }
54 return false;
55}
56
57bool CipherBlockChain::readyToGo() const
58{
59 if (_cipher) {
60 return _cipher->readyToGo();
61 }
62 return false;
63}
64
65void CipherBlockChain::initRegister() {
66 if (_register == nullptr) {
67 size_t registerLen = _cipher->blockSize();
68 _register = new unsigned char[registerLen];
69 _len = registerLen;
70 }
71 memset(_register, 0, _len);
72}
73
74int CipherBlockChain::encrypt(void *block, int len)
75{
76 if (_cipher && !_reader) {
77 int rc;
78
79 _writer |= 1;
80
81 initRegister();
82
83 if ((len % _len) >0) {
84 qCDebug(KWALLETBACKEND_LOG) << "Block length given encrypt (" << len << ") is not a multiple of " << _len;
85 return -1;
86 }
87
88 char *elemBlock = static_cast<char*>(block);
89 for (int b = 0; b < len/_len; b++) {
90
91 // This might be optimizable
92 char *tb = static_cast<char*>(elemBlock);
93 for (int i = 0; i < _len; i++) {
94 *tb++ ^= ((char *)_register)[i];
95 }
96
97 rc = _cipher->encrypt(elemBlock, _len);
98
99 if (rc != -1) {
100 memcpy(_register, elemBlock, _len);
101 }
102 elemBlock += _len;
103 }
104
105 return rc;
106 }
107 return -1;
108}
109
110// This is the old decrypt method, that was decrypting using ECB
111// instead of CBC
112int CipherBlockChain::decryptECB(void *block, int len) {
113 if (_cipher && !_writer) {
114 int rc;
115
116 _reader |= 1;
117
118 if (!_register) {
119 _register = new unsigned char[len];
120 _len = len;
121 memset(_register, 0, len);
122 } else if (len > _len) {
123 return -1;
124 }
125
126 if (!_next) {
127 _next = new unsigned char[_len];
128 }
129 memcpy(_next, block, _len);
130
131 rc = _cipher->decrypt(block, len);
132
133 if (rc != -1) {
134 // This might be optimizable
135 char *tb = (char *)block;
136 for (int i = 0; i < len; i++) {
137 tb[i] ^= ((char *)_register)[i];
138 }
139 }
140
141 void *temp;
142 temp = _next;
143 _next = _register;
144 _register = temp;
145
146 return rc;
147 }
148 return -1;
149}
150
151int CipherBlockChain::decrypt(void *block, int len)
152{
153 if (_useECBforReading) {
154 qCDebug(KWALLETBACKEND_LOG) << "decrypting using ECB!";
155 return decryptECB(block, len);
156 }
157
158 if (_cipher && !_writer) {
159 int rc = 0;
160
161 _reader |= 1;
162
163 initRegister();
164
165 if ((len % _len) >0) {
166 qCDebug(KWALLETBACKEND_LOG) << "Block length given for decrypt (" << len << ") is not a multiple of " << _len;
167 return -1;
168 }
169
170 char *elemBlock = static_cast<char*>(block);
171 for (int b = 0; b < len/_len; b++) {
172 if (_next == nullptr) {
173 _next = new unsigned char[_len];
174 }
175 memcpy(_next, elemBlock, _len);
176
177 int bytesDecrypted = _cipher->decrypt(elemBlock, _len);
178
179 if (bytesDecrypted != -1) {
180 rc += bytesDecrypted;
181 // This might be optimizable
182 char *tb = (char *)elemBlock;
183 for (int i = 0; i < _len; i++) {
184 *tb++ ^= ((char *)_register)[i];
185 }
186 }
187
188 void *temp;
189 temp = _next;
190 _next = _register;
191 _register = temp;
192
193 elemBlock += _len;
194 }
195
196 return rc;
197 }
198 return -1;
199}
200
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 10 2024 11:47:59 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.