XRootD
XrdCryptoLite_bf32.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C r y p t o L i t e _ b f 3 2 . c c */
4 /* */
5 /* */
6 /* (c) 2008 by the Board of Trustees of the Leland Stanford, Jr., University */
7 /* All Rights Reserved */
8 /* Produced by Andrew Hanushevsky for Stanford University under contract */
9 /* DE-AC02-76-SFO0515 with the Department of Energy */
10 /* */
11 /* This file is part of the XRootD software suite. */
12 /* */
13 /* XRootD is free software: you can redistribute it and/or modify it under */
14 /* the terms of the GNU Lesser General Public License as published by the */
15 /* Free Software Foundation, either version 3 of the License, or (at your */
16 /* option) any later version. */
17 /* */
18 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21 /* License for more details. */
22 /* */
23 /* You should have received a copy of the GNU Lesser General Public License */
24 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26 /* */
27 /* The copyright holder's institutional names and contributor's names may not */
28 /* be used to endorse or promote products derived from this software without */
29 /* specific prior written permission of the institution or contributor. */
30 /******************************************************************************/
31 
33 
34 #ifdef HAVE_SSL
35 
36 #include <cerrno>
37 #include <cstdlib>
38 #include <cstring>
39 #include <sys/types.h>
40 #include <netinet/in.h>
41 #include <cinttypes>
42 
43 #include <openssl/evp.h>
44 #include <openssl/opensslv.h>
45 #if OPENSSL_VERSION_NUMBER < 0x10100000L
46 #include "XrdTls/XrdTlsContext.hh"
47 #endif
48 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
49 #include <openssl/provider.h>
50 #endif
51 
52 #include "XrdOuc/XrdOucCRC.hh"
53 #include "XrdSys/XrdSysHeaders.hh"
54 
55 /******************************************************************************/
56 /* C l a s s X r d C r y p t o L i t e _ b f 3 2 */
57 /******************************************************************************/
58 
59 class XrdCryptoLite_bf32 : public XrdCryptoLite
60 {
61 public:
62 
63 virtual int Decrypt(const char *key, // Decryption key
64  int keyLen, // Decryption key byte length
65  const char *src, // Buffer to be decrypted
66  int srcLen, // Bytes length of src buffer
67  char *dst, // Buffer to hold decrypted result
68  int dstLen); // Bytes length of dst buffer
69 
70 virtual int Encrypt(const char *key, // Encryption key
71  int keyLen, // Encryption key byte length
72  const char *src, // Buffer to be encrypted
73  int srcLen, // Bytes length of src buffer
74  char *dst, // Buffer to hold encrypted result
75  int dstLen); // Bytes length of dst buffer
76 
77  XrdCryptoLite_bf32(const char deType) : XrdCryptoLite(deType, 4) {}
78  ~XrdCryptoLite_bf32() {}
79 };
80 
81 /******************************************************************************/
82 /* D e c r y p t */
83 /******************************************************************************/
84 
85 int XrdCryptoLite_bf32::Decrypt(const char *key,
86  int keyLen,
87  const char *src,
88  int srcLen,
89  char *dst,
90  int dstLen)
91 {
92  unsigned char ivec[8] = {0,0,0,0,0,0,0,0};
93  unsigned int crc32;
94  int wLen;
95  int dLen = srcLen - sizeof(crc32);
96 
97 // Make sure we have data
98 //
99  if (dstLen <= (int)sizeof(crc32) || dstLen < srcLen) return -EINVAL;
100 
101 // Decrypt
102 //
103  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
104  EVP_DecryptInit_ex(ctx, EVP_bf_cfb64(), NULL, NULL, NULL);
105  EVP_CIPHER_CTX_set_padding(ctx, 0);
106  EVP_CIPHER_CTX_set_key_length(ctx, keyLen);
107  EVP_DecryptInit_ex(ctx, NULL, NULL, (unsigned char *)key, ivec);
108  EVP_DecryptUpdate(ctx, (unsigned char *)dst, &wLen,
109  (unsigned char *)src, srcLen);
110  EVP_DecryptFinal_ex(ctx, (unsigned char *)dst, &wLen);
111  EVP_CIPHER_CTX_free(ctx);
112 
113 // Perform the CRC check to verify we have valid data here
114 //
115  memcpy(&crc32, dst+dLen, sizeof(crc32));
116  crc32 = ntohl(crc32);
117  if (crc32 != XrdOucCRC::CRC32((const unsigned char *)dst, dLen))
118  return -EPROTO;
119 
120 // Return success
121 //
122  return dLen;
123 }
124 
125 /******************************************************************************/
126 /* E n c r y p t */
127 /******************************************************************************/
128 
129 int XrdCryptoLite_bf32::Encrypt(const char *key,
130  int keyLen,
131  const char *src,
132  int srcLen,
133  char *dst,
134  int dstLen)
135 {
136  unsigned char buff[4096], *bP, *mP = 0, ivec[8] = {0,0,0,0,0,0,0,0};
137  unsigned int crc32;
138  int wLen;
139  int dLen = srcLen + sizeof(crc32);
140 
141 // Make sure that the destination if at least 4 bytes larger and we have data
142 //
143  if (dstLen-srcLen < (int)sizeof(crc32) || srcLen <= 0) return -EINVAL;
144 
145 // Normally, the msg is 4k or less but if more, get a new buffer
146 //
147  if (dLen <= (int)sizeof(buff)) bP = buff;
148  else {if (!(mP = (unsigned char *)malloc(dLen))) return -ENOMEM;
149  else bP = mP;
150  }
151 
152 // Append a crc
153 //
154  memcpy(bP, src, srcLen);
155  crc32 = XrdOucCRC::CRC32(bP, srcLen);
156  crc32 = htonl(crc32);
157  memcpy((bP+srcLen), &crc32, sizeof(crc32));
158 
159 // Encrypt
160 //
161  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
162  EVP_EncryptInit_ex(ctx, EVP_bf_cfb64(), NULL, NULL, NULL);
163  EVP_CIPHER_CTX_set_padding(ctx, 0);
164  EVP_CIPHER_CTX_set_key_length(ctx, keyLen);
165  EVP_EncryptInit_ex(ctx, NULL, NULL, (unsigned char *)key, ivec);
166  EVP_EncryptUpdate(ctx, (unsigned char *)dst, &wLen, bP, dLen);
167  EVP_EncryptFinal_ex(ctx, (unsigned char *)dst, &wLen);
168  EVP_CIPHER_CTX_free(ctx);
169 
170 // Free temp buffer and return success
171 //
172  if (mP) free(mP);
173  return dLen;
174 }
175 #endif
176 
177 /******************************************************************************/
178 /* X r d C r y p t o L i t e _ N e w _ b f 3 2 */
179 /******************************************************************************/
180 
182 {
183 #ifdef HAVE_SSL
184 #if OPENSSL_VERSION_NUMBER < 0x10100000L
185  // In case nothing has yet configured a libcrypto thread-id callback
186  // function we provide one via the XrdTlsContext Init method. Compared
187  // to the default the aim is to provide better properies when libcrypto
188  // uses the thread-id as hash-table keys for the per-thread error state.
189  static struct configThreadid {
190  configThreadid() {eText = XrdTlsContext::Init();}
191  const char *eText;
192  } ctid;
193  // Make sure all went well
194  //
195  if (ctid.eText) return (XrdCryptoLite *)0;
196 #endif
197 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
198  // With openssl v3 the blowfish cipher is only available via the "legacy"
199  // provider. Legacy is typically not enabled by default (but can be via
200  // openssl.cnf) so it is loaded here. Explicitly loading a provider will
201  // disable the automatic loading of the "default" one. The default might
202  // not have already been loaded, or standard algorithms might be available
203  // via another configured provider, such as FIPS. So an attempt is made to
204  // fetch a common default algorithm, possibly automaticlly loading the
205  // default provider. Afterwards the legacy provider is loaded.
206  static struct loadProviders {
207  loadProviders() {
208  EVP_MD *mdp = EVP_MD_fetch(NULL, "SHA2-256", NULL);
209  if (mdp) EVP_MD_free(mdp);
210  // Load legacy provider into the default (NULL) library context
211  (void) OSSL_PROVIDER_load(NULL, "legacy");
212  }
213  } lp;
214 #endif
215  return (XrdCryptoLite *)(new XrdCryptoLite_bf32(Type));
216 #else
217  return (XrdCryptoLite *)0;
218 #endif
219 }
XrdCryptoLite * XrdCryptoLite_New_bf32(const char Type)
virtual int Encrypt(const char *key, int keyLen, const char *src, int srcLen, char *dst, int dstLen)=0
virtual int Decrypt(const char *key, int keyLen, const char *src, int srcLen, char *dst, int dstLen)=0
static uint32_t CRC32(const unsigned char *data, int count)
Definition: XrdOucCRC.cc:171
static const char * Init()