~ubuntu-branches/ubuntu/quantal/ceph/quantal

« back to all changes in this revision

Viewing changes to src/auth/Crypto.cc

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum, Clint Byrum, Micah Gersten
  • Date: 2011-02-12 22:50:26 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110212225026-yyyw4tk0msgql3ul
Tags: 0.24.2-0ubuntu1
[ Clint Byrum <clint@ubuntu.com> ]
* New upstream release. (LP: #658670, LP: #684011)
* debian/patches/fix-mkcephfs.patch: dropped (applied upstream)
* Removed .la files from libceph1-dev, libcrush1-dev and 
  librados1-dev (per Debian policy v3.9.1 10.2).
* debian/control: adding pkg-config as a build dependency
* debian/control: depend on libcrypto++-dev instead of libssl-dev
* debian/watch: added watch file

[ Micah Gersten <micahg@ubuntu.com> ]
* debian/control: add Homepage

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 */
13
13
 
14
14
#include "Crypto.h"
15
 
 
16
 
#include "openssl/evp.h"
17
 
#include "openssl/aes.h"
 
15
#include <cryptopp/modes.h>
 
16
#include <cryptopp/aes.h>
 
17
#include <cryptopp/filters.h>
18
18
 
19
19
#include "include/ceph_fs.h"
20
20
#include "config.h"
22
22
 
23
23
#include <errno.h>
24
24
 
 
25
using namespace CryptoPP;
 
26
 
25
27
int get_random_bytes(char *buf, int len)
26
28
{
27
29
  char *t = buf;
94
96
 
95
97
 
96
98
// ---------------------------------------------------
97
 
 
98
 
#define AES_KEY_LEN     AES_BLOCK_SIZE
 
99
#define AES_KEY_LEN     ((size_t)AES::DEFAULT_KEYLENGTH)
 
100
#define AES_BLOCK_LEN   ((size_t)AES::BLOCKSIZE)
99
101
 
100
102
class CryptoAES : public CryptoHandler {
101
103
public:
107
109
  int decrypt(bufferptr& secret, const bufferlist& in, bufferlist& out);
108
110
};
109
111
 
110
 
static const unsigned char *aes_iv = (const unsigned char *)"cephsageyudagreg";
 
112
static const unsigned char *aes_iv = (const unsigned char *)CEPH_AES_IV;
111
113
 
112
114
int CryptoAES::create(bufferptr& secret)
113
115
{
121
123
 
122
124
int CryptoAES::validate_secret(bufferptr& secret)
123
125
{
124
 
  if (secret.length() < AES_KEY_LEN) {
 
126
  if (secret.length() < (size_t)AES_KEY_LEN) {
125
127
    dout(0) << "key is too short" << dendl;
126
128
    return -EINVAL;
127
129
  }
132
134
int CryptoAES::encrypt(bufferptr& secret, const bufferlist& in, bufferlist& out)
133
135
{
134
136
  const unsigned char *key = (const unsigned char *)secret.c_str();
135
 
  int in_len = in.length();
136
137
  const unsigned char *in_buf;
137
 
  int max_out = (in_len + AES_BLOCK_SIZE) & ~(AES_BLOCK_SIZE -1);
138
 
  int total_out = 0;
139
 
  int outlen;
140
 
#define OUT_BUF_EXTRA 128
141
 
  unsigned char outbuf[max_out + OUT_BUF_EXTRA];
142
138
 
143
139
  if (secret.length() < AES_KEY_LEN) {
144
140
    derr(0) << "key is too short" << dendl;
145
141
    return false;
146
142
  }
147
 
 
148
 
  EVP_CIPHER_CTX ctx;
149
 
  EVP_CIPHER_CTX_init(&ctx);
150
 
  EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, aes_iv);
151
 
 
152
 
  bool ret = false;
 
143
  string ciphertext;
 
144
  CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
 
145
  CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, aes_iv );
 
146
  CryptoPP::StringSink *sink = new CryptoPP::StringSink(ciphertext);
 
147
  if (!sink)
 
148
    return false;
 
149
  CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, sink);
 
150
 
153
151
  for (std::list<bufferptr>::const_iterator it = in.buffers().begin(); 
154
152
       it != in.buffers().end(); it++) {
155
 
    outlen = max_out - total_out;
156
153
    in_buf = (const unsigned char *)it->c_str();
157
 
    if (!EVP_EncryptUpdate(&ctx, &outbuf[total_out], &outlen, in_buf, it->length()))
158
 
      goto out;
159
 
    total_out += outlen;
160
 
  }
161
 
  if (!EVP_EncryptFinal_ex(&ctx, outbuf + total_out, &outlen))
162
 
    goto out;
163
 
  total_out += outlen;
164
 
 
165
 
  out.append((const char *)outbuf, total_out);
166
 
  ret = true;
167
 
 out:
168
 
  EVP_CIPHER_CTX_cleanup(&ctx);
169
 
  return ret;
 
154
 
 
155
    stfEncryptor.Put(in_buf, it->length());
 
156
  }
 
157
  try {
 
158
    stfEncryptor.MessageEnd();
 
159
  } catch (CryptoPP::Exception& e) {
 
160
    dout(0) << "encryptor.MessageEnd::Exception: " << e.GetWhat() << dendl;
 
161
    return false;
 
162
  }
 
163
  out.append((const char *)ciphertext.c_str(), ciphertext.length());
 
164
 
 
165
  return true;
170
166
}
171
167
 
172
168
int CryptoAES::decrypt(bufferptr& secret, const bufferlist& in, bufferlist& out)
173
169
{
174
170
  const unsigned char *key = (const unsigned char *)secret.c_str();
175
171
 
176
 
  int in_len = in.length();
177
 
  int dec_len = 0;
178
 
  int total_dec_len = 0;
179
 
 
180
 
  unsigned char dec_data[in_len];
181
 
  int result = 0;
182
 
 
183
 
  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
184
 
  EVP_CIPHER_CTX_init(ctx);
185
 
 
186
 
  int res = EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, aes_iv);
187
 
  if (res == 1) {
188
 
    for (std::list<bufferptr>::const_iterator it = in.buffers().begin(); 
 
172
  CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
 
173
  CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, aes_iv );
 
174
 
 
175
  string decryptedtext;
 
176
  CryptoPP::StringSink *sink = new CryptoPP::StringSink(decryptedtext);
 
177
  if (!sink)
 
178
    return -ENOMEM;
 
179
  CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, sink);
 
180
  for (std::list<bufferptr>::const_iterator it = in.buffers().begin(); 
189
181
       it != in.buffers().end(); it++) {
190
182
      const unsigned char *in_buf = (const unsigned char *)it->c_str();
191
 
      res = EVP_DecryptUpdate(ctx, &dec_data[total_dec_len],
192
 
            &dec_len, in_buf, it->length());
193
 
      total_dec_len += dec_len;
194
 
 
195
 
      if (res != 1) {
196
 
        dout(0) << "EVP_DecryptUpdate error" << dendl;
197
 
        result = -1;
198
 
      }
199
 
    }
200
 
  } else {
201
 
    dout(0) << "EVP_DecryptInit_ex error" << dendl;
202
 
    result = -1;
203
 
  }
204
 
 
205
 
  if (!result) {
206
 
    EVP_DecryptFinal_ex(ctx,
207
 
              &dec_data[total_dec_len],
208
 
              &dec_len);
209
 
 
210
 
    total_dec_len += dec_len;
211
 
    out.append((const char *)dec_data, total_dec_len);
212
 
  }
213
 
 
214
 
  EVP_CIPHER_CTX_free(ctx);
215
 
  return result;
 
183
      stfDecryptor.Put(in_buf, it->length());
 
184
  }
 
185
 
 
186
  try {
 
187
    stfDecryptor.MessageEnd();
 
188
  } catch (CryptoPP::Exception& e) {
 
189
    dout(0) << "decryptor.MessageEnd::Exception: " << e.GetWhat() << dendl;
 
190
    return -EINVAL;
 
191
  }
 
192
 
 
193
  out.append((const char *)decryptedtext.c_str(), decryptedtext.length());
 
194
  return decryptedtext.length();
216
195
}
217
196
 
218
197