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#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"
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{
56public:
57
58virtual 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
65virtual 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
80int 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
124int 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)
XrdCryptoLite(char deType, int ovhd=8)
static uint32_t CRC32(const unsigned char *data, int count)
Definition XrdOucCRC.cc:171