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 #include <cerrno>
35 #include <cstdlib>
36 #include <cstring>
37 #include <sys/types.h>
38 #include <netinet/in.h>
39 #include <cinttypes>
40 
41 #include <openssl/evp.h>
42 #include <openssl/opensslv.h>
43 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
44 #include <openssl/provider.h>
45 #endif
46 
47 #include "XrdOuc/XrdOucCRC.hh"
48 #include "XrdSys/XrdSysHeaders.hh"
49 
50 /******************************************************************************/
51 /* C l a s s X r d C r y p t o L i t e _ b f 3 2 */
52 /******************************************************************************/
53 
55 {
56 public:
57 
58 virtual int Decrypt(const char *key, // Decryption key
59  int keyLen, // Decryption key byte length
60  const char *src, // Buffer to be decrypted
61  int srcLen, // Bytes length of src buffer
62  char *dst, // Buffer to hold decrypted result
63  int dstLen); // Bytes length of dst buffer
64 
65 virtual int Encrypt(const char *key, // Encryption key
66  int keyLen, // Encryption key byte length
67  const char *src, // Buffer to be encrypted
68  int srcLen, // Bytes length of src buffer
69  char *dst, // Buffer to hold encrypted result
70  int dstLen); // Bytes length of dst buffer
71 
72  XrdCryptoLite_bf32(const char deType) : XrdCryptoLite(deType, 4) {}
74 };
75 
76 /******************************************************************************/
77 /* D e c r y p t */
78 /******************************************************************************/
79 
80 int XrdCryptoLite_bf32::Decrypt(const char *key,
81  int keyLen,
82  const char *src,
83  int srcLen,
84  char *dst,
85  int dstLen)
86 {
87  unsigned char ivec[8] = {0,0,0,0,0,0,0,0};
88  unsigned int crc32;
89  int wLen;
90  int dLen = srcLen - sizeof(crc32);
91 
92 // Make sure we have data
93 //
94  if (dstLen <= (int)sizeof(crc32) || dstLen < srcLen) return -EINVAL;
95 
96 // Decrypt
97 //
98  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
99  EVP_DecryptInit_ex(ctx, EVP_bf_cfb64(), NULL, NULL, NULL);
100  EVP_CIPHER_CTX_set_padding(ctx, 0);
101  EVP_CIPHER_CTX_set_key_length(ctx, keyLen);
102  EVP_DecryptInit_ex(ctx, NULL, NULL, (unsigned char *)key, ivec);
103  EVP_DecryptUpdate(ctx, (unsigned char *)dst, &wLen,
104  (unsigned char *)src, srcLen);
105  EVP_DecryptFinal_ex(ctx, (unsigned char *)dst, &wLen);
106  EVP_CIPHER_CTX_free(ctx);
107 
108 // Perform the CRC check to verify we have valid data here
109 //
110  memcpy(&crc32, dst+dLen, sizeof(crc32));
111  crc32 = ntohl(crc32);
112  if (crc32 != XrdOucCRC::CRC32((const unsigned char *)dst, dLen))
113  return -EPROTO;
114 
115 // Return success
116 //
117  return dLen;
118 }
119 
120 /******************************************************************************/
121 /* E n c r y p t */
122 /******************************************************************************/
123 
124 int XrdCryptoLite_bf32::Encrypt(const char *key,
125  int keyLen,
126  const char *src,
127  int srcLen,
128  char *dst,
129  int dstLen)
130 {
131  unsigned char buff[4096], *bP, *mP = 0, ivec[8] = {0,0,0,0,0,0,0,0};
132  unsigned int crc32;
133  int wLen;
134  int dLen = srcLen + sizeof(crc32);
135 
136 // Make sure that the destination if at least 4 bytes larger and we have data
137 //
138  if (dstLen-srcLen < (int)sizeof(crc32) || srcLen <= 0) return -EINVAL;
139 
140 // Normally, the msg is 4k or less but if more, get a new buffer
141 //
142  if (dLen <= (int)sizeof(buff)) bP = buff;
143  else {if (!(mP = (unsigned char *)malloc(dLen))) return -ENOMEM;
144  else bP = mP;
145  }
146 
147 // Append a crc
148 //
149  memcpy(bP, src, srcLen);
150  crc32 = XrdOucCRC::CRC32(bP, srcLen);
151  crc32 = htonl(crc32);
152  memcpy((bP+srcLen), &crc32, sizeof(crc32));
153 
154 // Encrypt
155 //
156  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
157  EVP_EncryptInit_ex(ctx, EVP_bf_cfb64(), NULL, NULL, NULL);
158  EVP_CIPHER_CTX_set_padding(ctx, 0);
159  EVP_CIPHER_CTX_set_key_length(ctx, keyLen);
160  EVP_EncryptInit_ex(ctx, NULL, NULL, (unsigned char *)key, ivec);
161  EVP_EncryptUpdate(ctx, (unsigned char *)dst, &wLen, bP, dLen);
162  EVP_EncryptFinal_ex(ctx, (unsigned char *)dst, &wLen);
163  EVP_CIPHER_CTX_free(ctx);
164 
165 // Free temp buffer and return success
166 //
167  if (mP) free(mP);
168  return dLen;
169 }
170 
171 /******************************************************************************/
172 /* X r d C r y p t o L i t e _ N e w _ b f 3 2 */
173 /******************************************************************************/
174 
176 {
177 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
178  // With openssl v3 the blowfish cipher is only available via the "legacy"
179  // provider. Legacy is typically not enabled by default (but can be via
180  // openssl.cnf) so it is loaded here. Explicitly loading a provider will
181  // disable the automatic loading of the "default" one. The default might
182  // not have already been loaded, or standard algorithms might be available
183  // via another configured provider, such as FIPS. So an attempt is made to
184  // fetch a common default algorithm, possibly automaticlly loading the
185  // default provider. Afterwards the legacy provider is loaded.
186  static struct loadProviders {
187  loadProviders() {
188  EVP_MD *mdp = EVP_MD_fetch(NULL, "SHA2-256", NULL);
189  if (mdp) EVP_MD_free(mdp);
190  // Load legacy provider into the default (NULL) library context
191  (void) OSSL_PROVIDER_load(NULL, "legacy");
192  }
193  } lp;
194 #endif
195  return (XrdCryptoLite *)(new XrdCryptoLite_bf32(Type));
196 }
XrdCryptoLite * XrdCryptoLite_New_bf32(const char Type)
virtual int Decrypt(const char *key, int keyLen, const char *src, int srcLen, char *dst, int dstLen)
virtual int Encrypt(const char *key, int keyLen, const char *src, int srcLen, char *dst, int dstLen)
XrdCryptoLite_bf32(const char deType)
static uint32_t CRC32(const unsigned char *data, int count)
Definition: XrdOucCRC.cc:171