Files
handleaiuinew/env/LMI/include/kApi/Crypto/kCipherStream.cpp
T

179 lines
4.8 KiB
C++
Raw Normal View History

2024-05-18 23:53:26 +08:00
/**
* @file kCipherStream.cpp
*
* @internal
* Copyright (C) 2016-2021 by LMI Technologies Inc.
* Licensed under the MIT License.
* Redistributed files must retain the above copyright notice.
*/
#include <kApi/Crypto/kCipherStream.h>
#include <kApi/Crypto/kCipher.h>
#include <kApi/Data/kArray1.h>
kBeginClassEx(k, kCipherStream)
kAddPrivateVMethod(kCipherStream, kObject, VRelease)
kAddPrivateVMethod(kCipherStream, kStream, VReadSomeImpl)
kAddPrivateVMethod(kCipherStream, kStream, VWriteImpl)
kAddPrivateVMethod(kCipherStream, kStream, VFlush)
kEndClassEx()
kFx(kStatus) kCipherStream_Construct(kCipherStream *cipherStream, kStream stream, kCipher cipher, kAlloc allocator)
{
kAlloc alloc = kAlloc_Fallback(allocator);
kStatus status;
kCheck(kAlloc_GetObject(alloc, kTypeOf(kCipherStream), cipherStream));
if (!kSuccess(status = xkCipherStream_Init(*cipherStream, kTypeOf(kCipherStream), stream, cipher, alloc)))
{
kAlloc_FreeRef(alloc, cipherStream);
}
return status;
}
kFx(kStatus) xkCipherStream_Init(kCipherStream cipherStream, kType type, kStream stream, kCipher cipher, kAlloc alloc)
{
kObjR(kCipherStream, cipherStream);
kStatus status = kOK;
kCheck(kStream_Init(cipherStream, type, alloc));
obj->writeBuffer = kNULL;
obj->readBuffer = kNULL;
obj->bufferSize = kCipher_Blocksize(cipher);
obj->writeBufferUsed = 0;
obj->readBufferUsed = 0;
obj->encryptArray = kNULL;
obj->decryptArray = kNULL;
obj->stream = stream;
obj->cipher = cipher;
kTry
{
kTest(kObject_GetMem(cipherStream, obj->bufferSize, &obj->writeBuffer));
kTest(kObject_GetMem(cipherStream, obj->bufferSize, &obj->readBuffer));
kTest(kArray1_Construct(&obj->encryptArray, kTypeOf(kByte), 0, kObject_Alloc(cipherStream)));
kTest(kArray1_Construct(&obj->decryptArray, kTypeOf(kByte), 0, kObject_Alloc(cipherStream)));
}
kCatch(&status)
{
xkCipherStream_VRelease(cipherStream);
kEndCatch(status);
}
return kOK;
}
kFx(kStatus) xkCipherStream_VRelease(kCipherStream cipherStream)
{
kObj(kCipherStream, cipherStream);
kCheck(kCipherStream_FlushFinal(cipherStream));
kDestroyRef(&obj->encryptArray);
kDestroyRef(&obj->decryptArray);
kCheck(kObject_FreeMemRef(cipherStream, &obj->writeBuffer));
kCheck(kObject_FreeMemRef(cipherStream, &obj->readBuffer));
kCheck(kObject_VRelease(cipherStream));
return kOK;
}
kFx(kStatus) xkCipherStream_VFlush(kCipherStream cipherStream)
{
kObj(kCipherStream, cipherStream);
return kStream_Flush(obj->stream);
}
kFx(kStatus) kCipherStream_FlushFinal(kCipherStream cipherStream)
{
kObj(kCipherStream, cipherStream);
kTry
{
if (obj->writeBufferUsed != 0)
{
kTest(kCipher_Encrypt(obj->cipher, obj->writeBuffer, obj->writeBufferUsed, obj->encryptArray));
kTest(kStream_Write(obj->stream, kArray1_Data(obj->encryptArray), kArray1_Length(obj->encryptArray)));
}
kTest(kStream_Flush(obj->stream));
}
kFinally
{
kEndFinally();
}
return kOK;
}
kFx(kStatus) xkCipherStream_VReadSomeImpl(kCipherStream cipherStream, void* buffer, kSize minCount, kSize maxCount, kSize* bytesRead)
{
kObj(kCipherStream, cipherStream);
kSize i;
kByte* writer = (kByte*) buffer;
kTry
{
for (i = 0; i < minCount; i++)
{
if (obj->readBufferUsed == 0)
{
kTest(kStream_Read(obj->stream, obj->readBuffer, obj->bufferSize));
kTest(kCipher_Decrypt(obj->cipher, obj->readBuffer, obj->bufferSize, obj->decryptArray));
kMemCopy(obj->readBuffer, kArray1_Data(obj->decryptArray), obj->bufferSize);
obj->readBufferUsed = obj->bufferSize;
}
writer[i] = obj->readBuffer[obj->bufferSize - obj->readBufferUsed--];
}
}
kFinally
{
kEndFinally();
}
if (!kIsNull(bytesRead))
{
*bytesRead = minCount;
}
return kOK;
}
kFx(kStatus) xkCipherStream_VWriteImpl(kCipherStream cipherStream, const void* buffer, kSize size)
{
kObj(kCipherStream, cipherStream);
const kByte* reader = (const kByte*) buffer;
kSize i;
kTry
{
for (i = 0; i < size; i++)
{
obj->writeBuffer[obj->writeBufferUsed++] = reader[i];
if (obj->writeBufferUsed == obj->bufferSize)
{
kTest(kCipher_Encrypt(obj->cipher, obj->writeBuffer, obj->bufferSize, obj->encryptArray));
kTest(kStream_Write(obj->stream, kArray1_Data(obj->encryptArray), kArray1_Length(obj->encryptArray)));
obj->writeBufferUsed = 0;
}
}
}
kFinally
{
kEndFinally();
}
return kOK;
}