/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: CBC.cpp Date: 2022-10-08 Author: Reece ***/ #include #include "../Crypto.hpp" #include "CBC.hpp" namespace Aurora::Crypto::CBC { bool CBCContext::Initialize(const Memory::MemoryViewRead &key, const Memory::MemoryViewRead &iv) { if (iv.length > 32) { SysPushErrorArg(); return false; } if (!iv.ptr) { SysPushErrorArg(); return false; } if (!key.ptr) { SysPushErrorArg(); return false; } if (key.length > AuArraySize(this->streamKey_)) { SysPushErrorArg(); return false; } AuMemcpy(this->cbc_.IV, iv.ptr, iv.length); this->iIVLength = iv.length; this->iKeyLength = key.length; AuMemcpy(this->streamKey_, key.ptr, key.length); return true; } bool CBCContext::GetIV(const Memory::MemoryViewWrite &writeView) { if (!writeView.ptr) { SysPushErrorArg(); return false; } if (writeView.length != this->cbc_.blocklen) { return {}; } AuMemcpy(writeView.ptr, this->cbc_.IV, this->cbc_.blocklen); return true; } bool CBCContext::SetIV(const Memory::MemoryViewRead &readView) { if (!readView.ptr) { SysPushErrorArg(); return false; } if (readView.length != this->cbc_.blocklen) { return {}; } AuMemcpy(this->cbc_.IV, readView.ptr, this->cbc_.blocklen); return true; } bool CBCContext::TryInit(int iCipher) { char iv[32]; int iRet {}; if (this->iLastCipher_ != -1) { return this->iLastCipher_ == iCipher; } AuMemcpy(iv, this->cbc_.IV, 32); iRet = ::cbc_start(iCipher, AuReinterpretCast(iv), AuReinterpretCast(this->streamKey_), this->iKeyLength, 0, &this->cbc_); if (iRet != CRYPT_OK) { SysPushErrorCrypt("{}", iRet); return {}; } this->iLastCipher_ = iCipher; return true; } bool CBCContext::Decrypt(int iCipher, const Memory::MemoryViewWrite &memoryView) { int iRet {}; if (!TryInit(iCipher)) { return false; } iRet = ::cbc_decrypt(AuReinterpretCast(memoryView.ptr), AuReinterpretCast(memoryView.ptr), memoryView.length, &this->cbc_); if (iRet != CRYPT_OK) { SysPushErrorCrypt("{}", iRet); return false; } return true; } bool CBCContext::Encrypt(int iCipher, const Memory::MemoryViewWrite &memoryView) { int iRet {}; if (!TryInit(iCipher)) { return false; } iRet = ::cbc_encrypt(AuReinterpretCast(memoryView.ptr), AuReinterpretCast(memoryView.ptr), memoryView.length, &this->cbc_); if (iRet != CRYPT_OK) { SysPushErrorCrypt("{}", iRet); return false; } return true; } AUKN_SYM ICBCContext *NewContextNew() { return _new CBCContext(); } AUKN_SYM void NewContextRelease(ICBCContext *pContext) { AuSafeDelete(pContext); } }