in sdk/src/encryption/CryptoStreamBuf.cc [57:126]
std::streamsize CryptoStreamBuf::xsgetn(char * _Ptr, std::streamsize _Count)
{
const std::streamsize startCount = _Count;
std::streamsize readCnt;
unsigned char block[BLK_SIZE];
//update iv base the pos
if (!initEncrypt) {
auto currPos = StreamBufProxy::seekoff(std::streamoff(0), std::ios_base::cur, std::ios_base::in);
currPos -= StartPosForIV_;
auto blkOff = currPos / BLK_SIZE;
auto blkIdx = currPos % BLK_SIZE;
auto iv = SymmetricCipher::IncCTRCounter(iv_, blkOff);
cipher_->EncryptInit(key_, iv);
encBufferCnt_ = 0;
encBufferOff_ = 0;
if (blkIdx > 0) {
StreamBufProxy::seekpos(blkOff * BLK_SIZE, std::ios_base::in);
readCnt = StreamBufProxy::xsgetn(reinterpret_cast<char *>(block), BLK_SIZE);
auto ret = cipher_->Encrypt(encBuffer_, static_cast<int>(readCnt), block, static_cast<int>(readCnt));
if (ret < 0) {
return -1;
}
encBufferCnt_ = ret - blkIdx;
encBufferOff_ = blkIdx;
}
initEncrypt = true;
}
//read from inner encBuffer_ first
readCnt = read_from_encrypted_buffer(_Ptr, _Count);
if (readCnt > 0) {
_Count -= readCnt;
_Ptr += readCnt;
}
//read from streambuf by BLK_SIZE
while (_Count > 0) {
readCnt = StreamBufProxy::xsgetn(reinterpret_cast<char *>(block), BLK_SIZE);
if (readCnt <= 0)
break;
if (_Count < readCnt) {
auto ret = cipher_->Encrypt(encBuffer_, static_cast<int>(readCnt), block, static_cast<int>(readCnt));
if (ret < 0) {
return -1;
}
encBufferCnt_ = ret;
encBufferOff_ = 0;
break;
}
else {
auto ret = cipher_->Encrypt(reinterpret_cast<unsigned char *>(_Ptr), static_cast<int>(readCnt), block, static_cast<int>(readCnt));
if (ret < 0) {
return -1;
}
_Count -= ret;
_Ptr += ret;
}
}
//read from inner encBuffer_ again
readCnt = read_from_encrypted_buffer(_Ptr, _Count);
if (readCnt > 0) {
_Count -= readCnt;
_Ptr += readCnt;
}
return startCount - _Count;
}