diff --git a/src/XrdCrypto/XrdCryptoCipher.cc b/src/XrdCrypto/XrdCryptoCipher.cc index bf7858a7745..a09ef750bd4 100644 --- a/src/XrdCrypto/XrdCryptoCipher.cc +++ b/src/XrdCrypto/XrdCryptoCipher.cc @@ -145,35 +145,65 @@ bool XrdCryptoCipher::IsDefaultLength() const } //____________________________________________________________________________ -int XrdCryptoCipher::Encrypt(XrdSutBucket &bck) +int XrdCryptoCipher::MaxIVLength() const +{ + // Return the max cipher IV length + + ABSTRACTMETHOD("XrdCryptoCipher::MaxIVLength"); + return 0; +} + +//____________________________________________________________________________ +int XrdCryptoCipher::Encrypt(XrdSutBucket &bck, bool useiv) { // Encrypt bucket bck with local cipher // Return size of encoded bucket or -1 in case of error int snew = -1; - int sz = EncOutLength(bck.size); + int liv = 0; + char *iv = 0; + if (useiv) { + iv = RefreshIV(liv); + if (!iv) return snew; + } + + int sz = EncOutLength(bck.size) + liv; char *newbck = new char[sz]; if (newbck) { memset(newbck, 0, sz); - snew = Encrypt(bck.buffer,bck.size,newbck); + if (liv > 0) memcpy(newbck, iv, liv); + snew = Encrypt(bck.buffer,bck.size,newbck+liv); if (snew > -1) - bck.Update(newbck,snew); + bck.Update(newbck,snew + liv); } return snew; } //____________________________________________________________________________ -int XrdCryptoCipher::Decrypt(XrdSutBucket &bck) +int XrdCryptoCipher::Decrypt(XrdSutBucket &bck, bool useiv) { // Decrypt bucket bck with local cipher // Return size of encoded bucket or -1 in case of error int snew = -1; - int sz = DecOutLength(bck.size); + int liv = (useiv) ? MaxIVLength() : 0; + + int sz = DecOutLength(bck.size - liv); char *newbck = new char[sz]; if (newbck) { + + if (useiv) { + char *iv = new char[liv]; + if (iv) { + memcpy(iv,bck.buffer,liv); + SetIV(liv, iv); + delete[] iv; + } else { + return snew; + } + } memset(newbck, 0, sz); - snew = Decrypt(bck.buffer,bck.size,newbck); + snew = Decrypt(bck.buffer + liv, bck.size - liv, newbck); if (snew > -1) bck.Update(newbck,snew); } diff --git a/src/XrdCrypto/XrdCryptoCipher.hh b/src/XrdCrypto/XrdCryptoCipher.hh index 7b15dea9ff6..16b7f9b3ec5 100644 --- a/src/XrdCrypto/XrdCryptoCipher.hh +++ b/src/XrdCrypto/XrdCryptoCipher.hh @@ -67,6 +67,7 @@ public: virtual char *IV(int &l) const; virtual bool IsDefaultLength() const; virtual char *Public(int &lpub); + virtual int MaxIVLength() const; // Additional setters virtual void SetIV(int l, const char *iv); @@ -74,8 +75,8 @@ public: // Additional methods virtual int Encrypt(const char *in, int lin, char *out); virtual int Decrypt(const char *in, int lin, char *out); - int Encrypt(XrdSutBucket &buck); - int Decrypt(XrdSutBucket &buck); + int Encrypt(XrdSutBucket &buck, bool useiv = true); + int Decrypt(XrdSutBucket &buck, bool useiv = true); virtual char *RefreshIV(int &l); }; diff --git a/src/XrdCrypto/XrdCryptosslCipher.cc b/src/XrdCrypto/XrdCryptosslCipher.cc index f265d4260a5..406a5554ce8 100644 --- a/src/XrdCrypto/XrdCryptosslCipher.cc +++ b/src/XrdCrypto/XrdCryptosslCipher.cc @@ -1005,8 +1005,8 @@ void XrdCryptosslCipher::GenerateIV() lIV = 0; } - // Generate a new one - fIV = XrdSutRndm::GetBuffer(EVP_MAX_IV_LENGTH); + // Generate a new one, using crypt-like chars + fIV = XrdSutRndm::GetBuffer(EVP_MAX_IV_LENGTH, 3); if (fIV) lIV = EVP_MAX_IV_LENGTH; } @@ -1044,6 +1044,8 @@ int XrdCryptosslCipher::EncDec(int enc, const char *in, int lin, char *out) int lout = 0; + const char *action = (enc == 1) ? "encrypting" : "decrypting"; + // Check inputs if (!in || lin <= 0 || !out) { DEBUG("wrong inputs arguments"); @@ -1088,7 +1090,7 @@ int XrdCryptosslCipher::EncDec(int enc, const char *in, int lin, char *out) int ltmp = 0; if (!EVP_CipherUpdate(ctx, (unsigned char *)&out[0], <mp, (unsigned char *)in, lin)) { - DEBUG("error encrypting"); + DEBUG("error " << action); return 0; } lout = ltmp; @@ -1119,3 +1121,11 @@ int XrdCryptosslCipher::DecOutLength(int l) lout = (lout <= 0) ? l : lout; return lout; } + +//____________________________________________________________________________ +int XrdCryptosslCipher::MaxIVLength() const +{ + // Return the max cipher IV length + + return EVP_MAX_IV_LENGTH; +} diff --git a/src/XrdCrypto/XrdCryptosslCipher.hh b/src/XrdCrypto/XrdCryptosslCipher.hh index d87264959fd..6473ef82995 100644 --- a/src/XrdCrypto/XrdCryptosslCipher.hh +++ b/src/XrdCrypto/XrdCryptosslCipher.hh @@ -90,6 +90,7 @@ public: XrdSutBucket *AsBucket(); char *IV(int &l) const { l = lIV; return fIV; } bool IsDefaultLength() const { return deflength; } + int MaxIVLength() const; // Additional setter void SetIV(int l, const char *iv);