| 176 | } |
| 177 | |
| 178 | size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const |
| 179 | { |
| 180 | CRYPTOPP_ASSERT(inBlocks); |
| 181 | CRYPTOPP_ASSERT(outBlocks); |
| 182 | CRYPTOPP_ASSERT(length); |
| 183 | |
| 184 | size_t blockSize = BlockSize(); |
| 185 | size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; |
| 186 | size_t xorIncrement = xorBlocks ? blockSize : 0; |
| 187 | size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; |
| 188 | |
| 189 | if (flags & BT_ReverseDirection) |
| 190 | { |
| 191 | CRYPTOPP_ASSERT(length % blockSize == 0); |
| 192 | inBlocks += length - blockSize; |
| 193 | xorBlocks += length - blockSize; |
| 194 | outBlocks += length - blockSize; |
| 195 | inIncrement = 0-inIncrement; |
| 196 | xorIncrement = 0-xorIncrement; |
| 197 | outIncrement = 0-outIncrement; |
| 198 | } |
| 199 | |
| 200 | while (length >= blockSize) |
| 201 | { |
| 202 | if (flags & BT_XorInput) |
| 203 | { |
| 204 | // Coverity finding. However, xorBlocks is never NULL if BT_XorInput. |
| 205 | CRYPTOPP_ASSERT(xorBlocks); |
| 206 | #if defined(__COVERITY__) |
| 207 | if (xorBlocks) |
| 208 | #endif |
| 209 | xorbuf(outBlocks, xorBlocks, inBlocks, blockSize); |
| 210 | ProcessBlock(outBlocks); |
| 211 | } |
| 212 | else |
| 213 | { |
| 214 | // xorBlocks can be NULL. See, for example, ECB_OneWay::ProcessData. |
| 215 | ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); |
| 216 | } |
| 217 | |
| 218 | if (flags & BT_InBlockIsCounter) |
| 219 | const_cast<byte *>(inBlocks)[blockSize-1]++; |
| 220 | inBlocks += inIncrement; |
| 221 | outBlocks += outIncrement; |
| 222 | xorBlocks += xorIncrement; |
| 223 | length -= blockSize; |
| 224 | } |
| 225 | |
| 226 | return length; |
| 227 | } |
| 228 | |
| 229 | unsigned int BlockTransformation::OptimalDataAlignment() const |
| 230 | { |
no test coverage detected