⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cryputil.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 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 + -