Răsfoiți Sursa

Merge branch 'aes-updates'

* aes-updates:
  * Update String decrypt_string_cbc() to directly call AES_cbc_encrypt()
  * Update String encrypt_string_cbc() to directly call AES_cbc_encrypt()
  * Encode the length of the text into the ciphertext's padding using PKCS[1] style padding
  * Fix AES CBC functions not properly resizing
  * Move AES String crypt functions to aes_util.c
Bryan Drewery 16 ani în urmă
părinte
comite
e952944b99
5 a modificat fișierele cu 112 adăugiri și 110 ștergeri
  1. 5 10
      src/EncryptedStream.c
  2. 0 81
      src/crypt.c
  3. 0 11
      src/crypt.h
  4. 99 8
      src/crypto/aes_util.c
  5. 8 0
      src/crypto/aes_util.h

+ 5 - 10
src/EncryptedStream.c

@@ -64,11 +64,9 @@ int EncryptedStream::loadFile (const int fd) {
 }
 
 void EncryptedStream::apply_filters(bd::String& buf, const bd::String& IV) const {
-  if (enc_flags & ENC_AES_256_CBC) {
-    unsigned char* iv = (unsigned char*) IV.dup();
-    buf = encrypt_string_cbc(key, buf, iv);
-    delete[] iv;
-  } else if (enc_flags & ENC_AES_256_ECB)
+  if (enc_flags & ENC_AES_256_CBC)
+    buf = encrypt_string_cbc(key, buf, IV);
+  else if (enc_flags & ENC_AES_256_ECB)
     buf = encrypt_string(key, buf);
 
   if (enc_flags & ENC_BASE64_BROKEN)
@@ -83,11 +81,8 @@ void EncryptedStream::unapply_filters(bd::String& buf, const bd::String& IV) con
   if (enc_flags & ENC_BASE64)
     buf = bd::base64Decode(buf);
 
-  if (enc_flags & ENC_AES_256_CBC) {
-    unsigned char* iv = (unsigned char*) IV.dup();
-    buf = decrypt_string_cbc(key, buf, iv);
-    delete[] iv;
-  }
+  if (enc_flags & ENC_AES_256_CBC)
+    buf = decrypt_string_cbc(key, buf, IV);
   else if (enc_flags & ENC_AES_256_ECB)
     buf = decrypt_string(key, buf);
 }

+ 0 - 81
src/crypt.c

@@ -35,54 +35,6 @@ char *encrypt_string(const char *keydata, char *in)
   }
 }
 
-/**
- * @brief Encrypt a string with AES 256 ECB
- * @param key The key to encrypt with
- * @param data The string to encrypt
- * @return A new, encrypted string
- */
-bd::String encrypt_string(const bd::String& key, const bd::String& data) {
-  if (!key) return data;
-  size_t len = data.length();
-  char *bdata = (char*) aes_encrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
-  bd::String encrypted(bdata, len);
-  free(bdata);
-  return encrypted;
-}
-
-#ifdef not_needed
-/**
- * @brief Encrypt a string with Blowfish ECB
- * @param key The key to encrypt with
- * @param data The string to encrypt
- * @return A new, encrypted string
- */
-bd::String encrypt_string_bf(const bd::String& key, const bd::String& data) {
-  if (!key) return data;
-  size_t len = data.length();
-  char *bdata = (char*) bf_encrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
-  bd::String encrypted(bdata, len);
-  free(bdata);
-  return encrypted;
-}
-#endif
-
-/**
- * @brief Encrypt a string with AES 256 CBC
- * @param key The key to encrypt with
- * @param data The string to encrypt
- * @param IV The IV to use (WARNING: This is modified inplace)
- * @return A new, encrypted string
- */
-bd::String encrypt_string_cbc(const bd::String& key, const bd::String& data, unsigned char* IV) {
-  if (!key) return data;
-  size_t len = data.length();
-  char *bdata = (char*) aes_encrypt_cbc_binary(key.c_str(), (unsigned char*) data.c_str(), &len, IV);
-  bd::String encrypted(bdata, len);
-  free(bdata);
-  return encrypted;
-}
-
 char *decrypt_string(const char *keydata, char *in)
 {
   size_t len = strlen(in);
@@ -101,39 +53,6 @@ char *decrypt_string(const char *keydata, char *in)
   }
 }
 
-/**
- * @brief Decrypt an AES 256 ECB ciphered string
- * @param key The key to decrypt with
- * @param data The string to decrypt
- * @return A new, decrypted string
- */
-bd::String decrypt_string(const bd::String& key, const bd::String& data) {
-  if (!key) return data;
-  size_t len = data.length();
-  char *bdata = (char*) aes_decrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
-  bd::String decrypted(bdata, len);
-  OPENSSL_cleanse(bdata, len);
-  free(bdata);
-  return decrypted;
-}
-
-/**
- * @brief Decrypt anAES 256 CBC ciphered string
- * @param key The key to decrypt with
- * @param data The string to decrypt
- * @param IV The IV to use (WARNING: This is modified inplace)
- * @return A new, decrypted string
- */
-bd::String decrypt_string_cbc(const bd::String& key, const bd::String& data, unsigned char* IV) {
-  if (!key) return data;
-  size_t len = data.length();
-  char *bdata = (char*) aes_decrypt_cbc_binary(key.c_str(), (unsigned char*) data.c_str(), &len, IV);
-  bd::String decrypted(bdata, len);
-  OPENSSL_cleanse(bdata, len);
-  free(bdata);
-  return decrypted;
-}
-
 int salted_sha1cmp(const char *salted_hash, const char *string) {
   char* cmp = salted_sha1(string, &salted_hash[1]); //Pass in the salt from the given hash
   int n = strcmp(salted_hash, cmp);

+ 0 - 11
src/crypt.h

@@ -11,10 +11,6 @@
 #include "src/crypto/crypto.h"
 #include "users.h"
 
-namespace bd {
-  class String;
-};
-
 #define SHA_HASH_LENGTH (SHA_DIGEST_LENGTH << 1)
 #define SHA256_HASH_LENGTH (SHA256_DIGEST_LENGTH << 1)
 #define MD5_HASH_LENGTH (MD5_DIGEST_LENGTH << 1)
@@ -30,16 +26,9 @@ char *SHA256(const char *);
 int sha256cmp(const char *, const char*);
 
 char *encrypt_string(const char *, char *);
-bd::String encrypt_string(const bd::String&, const bd::String&);
-#ifdef not_needed
-bd::String encrypt_string_bf(const bd::String&, const bd::String&);
-#endif
-bd::String encrypt_string_cbc(const bd::String&, const bd::String&, unsigned char *);
 char *decrypt_string(const char *, char *);
 char *salted_sha1(const char *, const char* = NULL);
 int salted_sha1cmp(const char *, const char*);
-bd::String decrypt_string(const bd::String&, const bd::String&);
-bd::String decrypt_string_cbc(const bd::String&, const bd::String&, unsigned char *);
 char *cryptit (char *);
 char *decryptit (char *);
 void Encrypt_File(char *, char *);

+ 99 - 8
src/crypto/aes_util.c

@@ -4,6 +4,7 @@
 
 #include "crypto.h"
 #include "src/compat/compat.h"
+#include <bdlib/src/String.h>
 
 #define CRYPT_BLOCKSIZE AES_BLOCK_SIZE
 #define CRYPT_KEYBITS 256
@@ -11,6 +12,86 @@
 
 AES_KEY e_key, d_key;
 
+/**
+ * @brief Encrypt a string with AES 256 ECB
+ * @param key The key to encrypt with
+ * @param data The string to encrypt
+ * @return A new, encrypted string
+ */
+bd::String encrypt_string(const bd::String& key, const bd::String& data) {
+  if (!key) return data;
+  size_t len = data.length();
+  char *bdata = (char*) aes_encrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
+  bd::String encrypted(bdata, len);
+  free(bdata);
+  return encrypted;
+}
+
+/**
+ * @brief Encrypt a string with AES 256 CBC
+ * @param key The key to encrypt with
+ * @param data The string to encrypt
+ * @param IV The IV to use (WARNING: This is modified inplace)
+ * @return A new, encrypted string
+ */
+bd::String encrypt_string_cbc(const bd::String& key, bd::String data, bd::String IV) {
+  if (!key) return data;
+
+  // Add padding
+  size_t padding = CRYPT_BLOCKSIZE;
+  if (data.length() % CRYPT_BLOCKSIZE)
+    padding = (CRYPT_BLOCKSIZE - (data.length() % CRYPT_BLOCKSIZE));
+  // Pad with padding bytes of padding
+  data.resize(data.length() + padding, padding);
+
+  AES_set_encrypt_key((const unsigned char *) key.c_str(), CRYPT_KEYBITS, &e_key);
+  AES_cbc_encrypt((const unsigned char*)data.data(), (unsigned char*)data.mdata(), data.length(), &e_key, (unsigned char*)IV.mdata(), AES_ENCRYPT);
+  OPENSSL_cleanse(&e_key, sizeof(e_key));
+
+  return data;
+}
+
+/**
+ * @brief Decrypt an AES 256 ECB ciphered string
+ * @param key The key to decrypt with
+ * @param data The string to decrypt
+ * @return A new, decrypted string
+ */
+bd::String decrypt_string(const bd::String& key, const bd::String& data) {
+  if (!key) return data;
+  size_t len = data.length();
+  char *bdata = (char*) aes_decrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
+  bd::String decrypted(bdata, len);
+  OPENSSL_cleanse(bdata, len);
+  free(bdata);
+  return decrypted;
+}
+
+/**
+ * @brief Decrypt anAES 256 CBC ciphered string
+ * @param key The key to decrypt with
+ * @param data The string to decrypt
+ * @param IV The IV to use (WARNING: This is modified inplace)
+ * @return A new, decrypted string
+ */
+bd::String decrypt_string_cbc(const bd::String& key, bd::String data, bd::String IV) {
+  if (!key) return data;
+
+  data.resize(data.length() - (data.length() % CRYPT_BLOCKSIZE));
+  AES_set_decrypt_key((const unsigned char *) key.c_str(), CRYPT_KEYBITS, &d_key);
+  AES_cbc_encrypt((const unsigned char*)data.data(), (unsigned char*)data.mdata(), data.length(), &d_key, (unsigned char*)IV.mdata(), AES_DECRYPT);
+  OPENSSL_cleanse(&d_key, sizeof(d_key));
+
+  // How much padding?
+  size_t padding = data[data.length() - 1];
+
+  if (!padding || padding > 16)
+    data.resize(strlen((char*) data.c_str()));
+  else
+    data.resize(data.length() - padding);
+  return data;
+}
+
 unsigned char *
 aes_encrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *inlen)
 {
@@ -84,10 +165,14 @@ aes_encrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *inlen, un
   unsigned char *out = NULL;
 
   /* First pad indata to CRYPT_BLOCKSIZE multiple */
-  if (len % CRYPT_BLOCKSIZE)             /* more than 1 block? */
-    len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
+  size_t padding = 16;
+  if (len % CRYPT_BLOCKSIZE)              /* more than 1 block? */
+    padding = (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
+  len += padding;
 
-  out = (unsigned char *) my_calloc(1, len + 1);
+  out = (unsigned char *) my_calloc(1, len);
+  memset(out + *inlen, padding, padding);
+  memcpy(out, in, *inlen);
   *inlen = len;
 
   if (!keydata || !*keydata) {
@@ -98,11 +183,10 @@ aes_encrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *inlen, un
 
     strlcpy(key, keydata, sizeof(key));
     AES_set_encrypt_key((const unsigned char *) key, CRYPT_KEYBITS, &e_key);
-    AES_cbc_encrypt(in, out, len, &e_key, ivec, AES_ENCRYPT);
+    AES_cbc_encrypt(out, out, len, &e_key, ivec, AES_ENCRYPT);
     OPENSSL_cleanse(key, sizeof(key));
     OPENSSL_cleanse(&e_key, sizeof(e_key));
   }
-  out[len] = 0;
   return out;
 }
 
@@ -113,6 +197,7 @@ aes_decrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *len, unsi
 
   *len -= *len % CRYPT_BLOCKSIZE;
   out = (unsigned char *) my_calloc(1, *len + 1);
+  memcpy(out, in, *len);
 
   if (!keydata || !*keydata) {
     /* No key, no decryption */
@@ -122,12 +207,18 @@ aes_decrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *len, unsi
 
     strlcpy(key, keydata, sizeof(key));
     AES_set_decrypt_key((const unsigned char *) key, CRYPT_KEYBITS, &d_key);
-    AES_cbc_encrypt(in, out, *len, &d_key, ivec, AES_DECRYPT);
+    AES_cbc_encrypt(out, out, *len, &d_key, ivec, AES_DECRYPT);
     OPENSSL_cleanse(key, sizeof(key));
     OPENSSL_cleanse(&d_key, sizeof(d_key));
   }
 
-  *len = strlen((char*) out);
-  out[*len] = 0;
+  // How much padding?
+  size_t padding = out[*len - 1];
+
+  if (!padding)
+    *len = strlen((char*) out);
+  else
+    *len -= padding;
+
   return out;
 }

+ 8 - 0
src/crypto/aes_util.h

@@ -7,8 +7,16 @@
 
 #include <sys/types.h>
 
+namespace bd {
+  class String;
+};
+
 unsigned char *aes_encrypt_ecb_binary(const char *, unsigned char *, size_t *);
 unsigned char *aes_decrypt_ecb_binary(const char *, unsigned char *, size_t *);
 unsigned char *aes_encrypt_cbc_binary(const char *, unsigned char *, size_t *, unsigned char *);
 unsigned char *aes_decrypt_cbc_binary(const char *, unsigned char *, size_t *, unsigned char *);
+bd::String encrypt_string(const bd::String&, const bd::String&);
+bd::String encrypt_string_cbc(const bd::String&, bd::String, bd::String);
+bd::String decrypt_string(const bd::String&, const bd::String&);
+bd::String decrypt_string_cbc(const bd::String&, bd::String, bd::String);
 #endif