XRootD
Loading...
Searching...
No Matches
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
47#endif
48#if OPENSSL_VERSION_NUMBER >= 0x30000000L
49#include <openssl/provider.h>
50#endif
51
52#include "XrdOuc/XrdOucCRC.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
59class XrdCryptoLite_bf32 : public XrdCryptoLite
60{
61public:
62
63virtual 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
70virtual 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
85int 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
129int 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()