📄 cryputil.cpp
字号:
// cryputil.cc// code for cryputil.h// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#include "cryputil.h" // this module#include "datablok.h" // DataBlock#include "security.h" // xassert, xSecurity#include "selgamal.h" // ElGamal*#include "sdsa.h" // DSA*#include "globrand.h" // GlobalRandomPool#include "blokutil.h" // removeNBO32#include "warn.h" // warning#include <limits.h> // INT_MAXvoid checkNBO32(DataBlock &data, long expected, char const *message){ // I don't know why removeNBO32 sign-extends its result (it's a todo to // figure out why), but it does. but 'exptected' (at least sometimes) // isn't. since I know, right here, we're only comparing 32 bits, lets // just mask off the rest. long found = removeNBO32(data) & 0xffffffff; expected = expected & 0xffffffff; if (found != expected) { xsecurity(message); }}// -------------- EncryptBlockTrans ------------------int EncryptBlockTrans::minInputSize() const{ return 0;}int EncryptBlockTrans::maxInputSize() const{ return INT_MAX;}int EncryptBlockTrans::minOutputSize(int inputSize) const{ // 1-byte pad-length, plus actual padding int bsize = blockTrans.BlockSize(); return div_up(inputSize, bsize) * bsize + 1;}int EncryptBlockTrans::maxOutputSize(int inputSize) const{ // always the same size return minOutputSize(inputSize);}void EncryptBlockTrans::trans(DataBlock &block){ // compute some initial variables int srclen = block.getDataLen(); int bsize = blockTrans.BlockSize(); int nblocks = div_up(srclen, bsize); int blocksum = nblocks * bsize; int padding = blocksum - srclen; xassert(0 <= padding && padding < bsize); // ensure the block has enough space allocated block.ensureAtLeast(blocksum + 1); // compute ptr to where length field goes byte *data = block.getData(); // verify alignment that BlockTransformation expects xassert( ((int)data) % 4 == 0 ); // encrypt the data, one block at a time for (; nblocks > 0; nblocks--, data += bsize) { blockTrans.ProcessBlock(data); } // write the padding info xassert(0 <= padding && padding <= 0xFF); *data = (byte)padding; // store the new length in 'block' block.setDataLen(blocksum + 1); if (block.getDataLen() > maxOutputSize(srclen)) { xfailure(stringb( "block.getDataLen() = " << block.getDataLen() << " > maxOutputSize(srclen) = " << maxOutputSize(srclen))); }}// ----------------- DecryptBlockTrans ------------------int DecryptBlockTrans::minInputSize() const{ // always at least 1 byte of padding information return 1;}int DecryptBlockTrans::maxInputSize() const{ return INT_MAX;}int DecryptBlockTrans::minOutputSize(int inputSize) const{ // up to blockSize bytes are wasted (blockSize-1 for // fragmentation, then 1 for padding) return mymax(inputSize - blockTrans.BlockSize(), 0);}int DecryptBlockTrans::maxOutputSize(int inputSize) const{ // there is a minimum of 1 byte wasted return inputSize - 1;}void DecryptBlockTrans::trans(DataBlock &block){ // no need to call block.ensureAtLeast, the plaintext // is always smaller than the ciphertext, due to // fragmentation and padding // preliminaries int srclen = block.getDataLen(); byte *data = block.getData(); int bsize = blockTrans.BlockSize(); // verify alignment that BlockTransformation expects xassert( ((int)data) % 4 == 0 ); // see how many blocks there are int blocksum = srclen-1; xassert(blocksum % bsize == 0); int nblocks = blocksum / bsize; // read the padding int padding = data[blocksum]; xassert(0 <= padding && padding < bsize); // decode the data for (; nblocks > 0; nblocks--, data += bsize) { blockTrans.ProcessBlock(data); } // set the actual data length in 'block' block.setDataLen(blocksum - padding); xassert(block.getDataLen() <= maxOutputSize(srclen));}// -------------- CBC3DESEncTrans ------------------------CBC3DESEncTrans::CBC3DESEncTrans(DataBlock const &key, DataBlock const &IV) : EncryptBlockTrans(cbc), tdes(key.getDataC()), cbc(tdes, IV.getDataC()){ xassert(key.getDataLen() == tdes.KEYLENGTH && IV.getDataLen() == (int)cbc.BlockSize());}// -------------- CBC3DESDecTrans ------------------------CBC3DESDecTrans::CBC3DESDecTrans(DataBlock const &key, DataBlock const &IV) : DecryptBlockTrans(cbc), tdes(key.getDataC()), cbc(tdes, IV.getDataC()){ xassert(key.getDataLen() == tdes.KEYLENGTH && IV.getDataLen() == (int)cbc.BlockSize());}// ------------------ SHA1HMAC --------------------SHA *SHA1HMAC::initSha(){ sha = new SHA; return sha;}SHA1HMAC::SHA1HMAC(DataBlock const &key) : HMAC(*initSha(), key.getDataC(), key.getDataLen()){ if (key.getDataLen() < 16) { warning((WarnLevel)(WARN_SECURITY | WARN_DEBUG), "The SHA1HMAC key is probably too short " "to be effective."); }}SHA1HMAC::~SHA1HMAC(){ delete sha;}// ------------ HMAC computation, verification ----------------------void appendDigest(DataBlock &data, HashModule &hash){ //diagDataBlock2(data); hash.CalculateDigest( data.getData() + data.getDataLen(), // dest data.getDataC(), data.getDataLen()); // src //diagDataBlock2(DataBlock(data.getDataC() + data.getDataLen(), // hash.DigestSize())); data.changeDataLen(+hash.DigestSize());}void checkDigest(DataBlock &data, MessageAuthenticationCode &mac, char const *message){ data.changeDataLen(-(signed)(mac.DigestSize())); //diagDataBlock2(data); //diagDataBlock2(DataBlock(data.getDataC() + data.getDataLen(), // mac.DigestSize())); bool ver = mac.VerifyMAC( data.getDataC() + data.getDataLen(), // mac data.getDataC(), data.getDataLen()); // data if (!ver) { xSecurity x(message); THROW(x); }}#if 0// moved to ssha.cpp (see cryputil.h)// -------------------- generic hash --------------------------DataBlock hashDataBlock(DataBlock const &data, HashModule &hash){ // prepare a buffer; query 'hash' to get digest size DataBlock ret(hash.DigestSize()); // compute the digest hash.CalculateDigest(ret.getData(), data.getDataC(), data.getDataLen()); ret.setDataLen(hash.DigestSize()); // return the digest return ret;}DataBlock Sha1(DataBlock const &data){ SHA sha; return hashDataBlock(data, sha);}#endif // 0// ---------------------- DSA -----------------------------void dsaSign(DataBlock const &privKey, DataBlock &data){ DataBlock temp(privKey); GlobalRandomPool grp; DSASigner signer(temp, grp.pool()); signer.trans(data);}void dsaVerify(DataBlock const &pubKey, DataBlock &data, char const *message){ try { DataBlock temp(pubKey); DSAVerifier verifier(temp); verifier.trans(data); } catch (xSecurity &x) { // augment the message and re-throw xsecurity(stringb(x.why() << ": " << message)); }}// ------------------ ElGamal --------------------------DataBlock elGamalEncrypt(DataBlock const &pubKey, DataBlock const &src){ // make encryptor DataBlock temp(pubKey); GlobalRandomPool grp; ElGamalEncryptor enc(temp, grp.pool()); // copy data DataBlock ret(src); // encrypt it enc.trans(ret); return ret;}DataBlock elGamalDecrypt(DataBlock const &privKey, DataBlock const &src){ // make decryptor DataBlock temp(privKey); ElGamalDecryptor dec(temp); // copy data DataBlock ret(src); // decrypt it dec.trans(ret); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -