FBB::DecryptBuf(3bobcat)

πŸ“¦
version 5.09.01 Β· 2 versions
, in ubuntu jammy

okay so bestie, sit down, hydrate, because we're doing FBB::DecryptBuf(3bobcat) today and it's literally the reverse-engineering baddie of the bobcat crypto lineup πŸ’– this is part one of two so buckle up, we are NOT skimming.

🌸 NAME 🌸

FBB::DecryptBuf β€” Decrypts information using various methods into a std::ostream


✨ SYNOPSIS ✨

#include <bobcat/decryptbuf>
Linking option:  -lbobcat -lcrypto

πŸ’… DESCRIPTION πŸ’…

okay so picture this: FBB::DecryptBuf objects are std::streambuf objects, and you use them to initialize std::ostream objects. that's the whole vibe. 🫢

and here's the tea β€” everything you insert into that std::ostream gets decrypted, and then it gets written to an std::ostream that you passed as an argument to DecryptBuf's constructor. no cap, that's just how it works.

every encryption method that the OpenSSL library supports and that can be selected by name is fair game for DecryptBuf objects. in practice though, the info was already encrypted by an EncryptBuf object using the same encryption method, so like, they're a matched set, yk? same energy. and the constructor expects a key and an initialization vector, because obviously. the key and initialization vector that got passed to the EncryptBuf object must be passed to DecryptBuf's constructor as well. if you lose them it's over bestie, no recovery arc 😭

block ciphers use one of these four encryption modes:

  • CBC (Cipher Block Chaining): the first block gets XOR-ed by the initialization vector and then encrypted using the specified method. every block after that gets XOR-ed by the encrypted version of the preceding block. and the way that this works β€” due to the initialization vector, dictionary attacks are infeasible, as long as the initialization vector is truly random. truly. random. don't be lazy with it. ✨
  • ECB (Electronic Code Book): each block is encrypted by itself, using the specified encryption method. and yeah, an initialization vector may be specified, but it is not used. πŸ™ˆ this method is susceptible to dictionary attacks and should therefore be avoided, unless you know what you're doing. and i mean actually know. not "i read a blog post" know.
  • CFB (Cipher Feednack): this method allows a block cipher to be used as a stream cipher. it uses an initialization vector, which should be unique and random for each new stream of data that is encrypted using the method. also important: encryption can only start after the first data block has been received. so like, it has to wait its turn. patient king. πŸ‘‘
  • OFB (Output Feednack): this is an alternative way to use a block cipher as a stream cipher. it's somewhat more susceptible to traditional data manipulation attacks, which can usually be thwarted when a message authentication code is added to the information as well. like CFB it uses an initialization vector, which should again be unique and random for each new stream of data that is encrypted. (and yes, the original really does say "Feednack" twice, i am not fixing that, i am respecting the lore πŸ’€)

so the following is an overview of methods that are currently available. methods where the block size is specified as N.A. are stream ciphers; the others are block ciphers. πŸ¦‹

πŸŽ€ AES

  • keysize 16 bytes, blocksize 8 bytes:
    • CBC β€” "aes-128-cbc"
    • EBC β€” "aes-128-ecb"
    • CFB β€” "aes-128-cfb"
    • OFB β€” "aes-128-ofb"
  • keysize 24 bytes, blocksize 24 bytes:
    • CBC β€” "aes-192-cbc"
    • EBC β€” "aes-192-ecb"
    • CFB β€” "aes-192-cfb"
    • OFB β€” "aes-192-ofb"
  • keysize 32 bytes, blocksize 32 bytes:
    • CBC β€” "aes-256-cbc"
    • EBC β€” "aes-256-ecb"
    • CFB β€” "aes-256-cfb"
    • OFB β€” "aes-256-ofb"

🌈 BLOWFISH

  • keysize 16 bytes, blocksize 8 bytes:
    • CBC β€” "bf-cbc"
    • EBC β€” "bf-ecb"
    • CFB β€” "bf-cfb"
    • OFB β€” "bf-ofb"
  • max key length is 56 bytes, 16 generally used

πŸ’œ CAMELLIA

  • keysize 16 bytes, blocksize 16 bytes:
    • CBC β€” "camellia-128-cbc"
    • EBC β€” "camellia-128-ecb"
    • CFB β€” "camellia-128-cfb"
    • OFB β€” "camellia-128-ofb"
  • keysize 24 bytes:
    • CBC β€” "camellia-192-cbc"
    • EBC β€” "camellia-192-ecb"
    • CFB β€” "camellia-192-cfb"
    • OFB β€” "camellia-192-ofb"
  • keysize 32 bytes:
    • CBC β€” "camellia-256-cbc"
    • EBC β€” "camellia-256-ecb"
    • CFB β€” "camellia-256-cfb"
    • OFB β€” "camellia-256-ofb"

πŸ“ CAST

  • keysize 16 bytes, blocksize 8 bytes:
    • CBC β€” "cast-cbc"
    • EBC β€” "cast-ecb"
    • CFB β€” "cast-cfb"
    • OFB β€” "cast-ofb"
  • min key length is 5 bytes, max is shown

🧚 DES

  • keysize 8 bytes, blocksize 8 bytes:
    • CBC β€” "des-cbc"
    • EBC β€” "des-ebc"
    • CFB β€” "des-cfb"
    • OFB β€” "des-ofb"

⭐ DESX

  • keysize 8 bytes, blocksize 8 bytes:
    • CBC β€” "desx-cbc"

πŸ”₯ 3DES

  • keysize 16 bytes, blocksize 8 bytes:
    • CBC β€” "des-ede-cbc"
    • EBC β€” "des-ede"
    • CFB β€” "des-ede-cfb"
    • OFB β€” "des-ede-ofb"

🌸 3DES

  • keysize 24 bytes, blocksize 8 bytes:
    • CBC β€” "des-ede3-cbc"
    • EBC β€” "des-ede3"
    • CFB β€” "des-ede3-cfb"
    • OFB β€” "des-ede3-ofb"
  • Key bytes 9-16 define the 2nd key, bytes 17-24 define the 3rd key

πŸ¦‹ RC2

  • keysize 16 bytes, blocksize 8 bytes:
    • CBC β€” "rc2-cbc"
    • EBC β€” "rc2-ecb"
    • CFB β€” "rc2-cfb"
    • OFB β€” "rc2-ofb"
  • Key length variable, max. 128 bytes, default length is shown

πŸ’€ RC2-40

  • keysize 5 bytes, blocksize 8 bytes β€” "rc2-40-cbc"
  • obsolete: avoid

πŸ’€ RC2-64

  • keysize 8 bytes, blocksize 8 bytes β€” "rc2-64-cbc"
  • obsolete: avoid

πŸ™ˆ RC4

  • keysize 16 bytes, blocksize N.A. β€” "rc4"
  • Key length is variable, max. 256 bytes. default length is shown
  • Encrypt again to decrypt. Don't use DecryptBuf

πŸ’€ RC4-40

  • keysize 5 bytes, blocksize N.A. β€” "rc4-40"
  • obsolete: avoid

πŸ‘‘ RC5

  • keysize 16 bytes, blocksize 8 bytes:
    • CBC β€” "rc5-cbc"
    • EBC β€” "rc5-ecb"
    • CFB β€” "rc5-cfb"
    • OFB β€” "rc5-ofb"
  • Key length variable, max. 256 bytes, rounds 8, 12 or 16, default # rounds is 12

okay so listen. the RC4 stream cipher is subject to a well-known attack (cf. http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Mantin1.zip) unless the initial 256 bytes produced by the cipher are discarded. like, that's not a vibe, that's a whole vulnerability. protect yourself. 🫢

🫢 NAMESPACE 🫢

FBB

all constructors, members, operators and manipulators mentioned in this man-page are defined in the namespace FBB. so like, that's the whole family, all in one place. πŸŽ€


πŸ‘‘ INHERITS FROM πŸ‘‘

FBB::CryptBuf, in turn inheriting from std::streambuf


and that's just the first half bestie, there's more where this came from ✨

πŸ’– CONSTRUCTOR / DESTRUCTOR πŸ’–

  • DecryptBuf(std::ostream &outStream, char const *type, std::string const &key, std::string const &iv, size_t bufsize = 1024) β€” okay so this constructor sets your DecryptBuf object all the way up and ready for whichever decryption algorithm type names. The algorithms you can actually pick from? They're all in the table we talked about up above πŸ‘†. Say you wanna run the AES method on 192-bit keys and blocks in CBC mode, you'd hand over "aes-192-cbc". The key parameter is, like, literally the key being used, and iv is the initialization vector that was in play when the original info got encrypted. Fun fact: the IV is not confidential, bestie, it can be out in the open. And when you're using ECB modes? No initialization vector is used at all, so in those cases any non-empty initialization vector will do.

Heads up though 🫢 β€” this constructor throws an FBB::Exception exception if you specify an encryption method that OpenSSL doesn't support. So don't be cute with it.

That first parameter is the std::ostream that receives the decrypted info.

And bufsize is the size in bytes of the internal buffer DecryptBuf uses to temporarily store incoming characters. Ngl the default argument is probably fine β€” you can most likely keep it exactly as-is and go about your day. πŸ’…

  • ~DecryptBuf() β€” normally, once all the encrypted info has been dropped into the decryption stream, the eoi manipulator (we get to it below, don't worry) gets inserted to finish the whole decryption process. Alternatively, the decryption process just ends when DecryptBuf's destructor is called. Like, for example, if decStream is the std::ostream receiving the encrypted information and encStream is the std::istream holding the encrypted information, then
decStream << encStream.rdbuf();

completes the decryption once DecryptBuf's destructor is called. Or, the other way:

desStream << encStream.rdbuf() << eoi;

which immediately completes the decryption process. Both routes, pick your fighter ✨

Copy and move constructors (and assignment operators) are not available. Not a thing. Don't try it. 🚫

🌸 MEMBER FUNCTIONS 🌸

Every single member of std::streambuf is available to you, because FBB::DecryptBuf inherits from that class. Periodt.

  • void eoi() β€” you can call this member instead of using the manipulator to end the decryption process. It throws an std::exception if decryption fails, which can happen when the DecryptBuf object is fed incorrect input (usually the improperly padded kind 😭).
  • bool setRounds(size_t nRounds) β€” this one can only be used with the RC5 decryption method, and it sets the number of rounds of the algorithm to 8, 12 or 16. If the number of rounds got updated successfully, the member returns true. Any other case returns false β€” e.g. you called it on some decryption method that isn't RC5, or the number of rounds you asked for isn't 8, 12 or 16. Sorry bestie, those are the rules πŸŽ€

πŸ”’ PROTECTED MEMBER πŸ”’

  • EVP_CIPHER_CTX *cipherCtx() β€” classes derived from DecryptBuf can use this member to get direct access to the EVP_CIPHER_CTX pointer that the DecryptBuf object is using. That pointer points to an opaque structure used by tons of OpenSSL functions to set or query parameters of a decryption method. Very inside-baseball, very iykyk. πŸ‘‘

✨ MANIPULATOR ✨

  • FBB::eoi β€” the eoi manipulator can be inserted into the decryption stream to complete the decryption process. And if you insert it into an std::ostream that wasn't initialized with either a DecryptBuf or an EncryptBuf? Literally nothing happens. Vibe check: neutral. 🌈

πŸ¦‹ EXAMPLE πŸ¦‹

Okay here's the whole thing in action, copy it, love it, run it:

#include <iostream>
#include <fstream>
#include <bobcat/exception>
#include <bobcat/ohexbuf>

#include <openssl/evp.h>
#include <openssl/err.h>

#include "../decryptbuf"
#include "../../encryptbuf/encryptbuf"

using namespace std;
using namespace FBB;

int main(int argc, char **argv)
try
{
    if (argc == 1)
        throw Exception(1) <<
                    "1st arg: method, 2nd arg: key, 3rd arg: iv, "
                    "4th arg: file to decrypt (to stdout)";

    // e.g., driver aes-128-cbc somekey iv-from-encryptbuf-driver
    // /tmp/enc > /tmp/driver.dec

    cerr << "Key: `" << argv[2] << "’\n"
            "IV:  `" << argv[3] << "’\n";

    DecryptBuf decryptbuf(cout, argv[1], argv[2], argv[3]);

    ostream out(&decryptbuf);
    ifstream in(argv[4]);

    if (not in)
        throw Exception{} << "can’t read `" << argv[4] << ’\n’;

    out << in.rdbuf() << eoi;
}
catch(exception const &err)
{
    cout << err.what() << endl;
    return 1;
}

πŸŽ€ FILES πŸŽ€

  • bobcat/decryptbuf β€” defines the class interface

πŸ‘€ SEE ALSO πŸ‘€

bobcat(7), encryptbuf(3bobcat), std::streambuf


πŸ’€ BUGS πŸ’€

None reported. (We stay unbothered, we stay unproblematic. ✨)


🌟 BOBCAT PROJECT FILES 🌟

  • https://fbb-git.gitlab.io/bobcat/: gitlab project page;
  • bobcat_5.09.01-x.dsc: detached signature;
  • bobcat_5.09.01-x.tar.gz: source archive;
  • bobcat_5.09.01-x_i386.changes: change log;
  • libbobcat1_5.09.01-x_*.deb: debian package containing the libraries;
  • libbobcat1-dev_5.09.01-x_*.deb: debian package containing the libraries, headers and manual pages;

πŸ’œ BOBCAT πŸ’œ

Bobcat is an acronym of Brokken’s Own Base Classes And Templates. Cute, right? πŸ₯Ή


This is free software, distributed under the terms of the GNU General Public License (GPL). Free as in, go wild, bestie. 🫢


πŸ‘‘ AUTHOR πŸ‘‘

Frank B. Brokken (f.b.brokken@rug.nl). The icon, the legend, the main character. πŸ’…


And that's a wrap on FBB::DecryptBuf(3bobcat), brought to you by libbobcat-dev_5.09.01, dated 2005-2021. Decrypt responsibly, hydrate, and stan OpenSSL. Byeeee πŸŽ€βœ¨πŸ’–

πŸ“¦ where this page comes from