Botan  1.11.15
Functions
Botan::CryptoBox Namespace Reference

Functions

std::string decrypt (const byte input[], size_t input_len, const std::string &passphrase)
std::string decrypt (const std::string &input, const std::string &passphrase)
std::string encrypt (const byte input[], size_t input_len, const std::string &passphrase, RandomNumberGenerator &rng)

Detailed Description

This namespace holds various high-level crypto functions


Function Documentation

BOTAN_DLL std::string Botan::CryptoBox::decrypt ( const byte  input[],
size_t  input_len,
const std::string &  passphrase 
)

Decrypt a message encrypted with CryptoBox::encrypt

Parameters:
inputthe input data
input_lenthe length of input in bytes
passphrasethe passphrase used to encrypt the message

Definition at line 99 of file cryptobox.cpp.

References Botan::OctetString::begin(), Botan::PEM_Code::decode_check_label(), Botan::DECRYPTION, Botan::PBKDF::derive_key(), Botan::get_byte(), Botan::get_cipher(), Botan::Pipe::process_msg(), Botan::Pipe::read(), Botan::Pipe::read_all_as_string(), and Botan::same_mem().

Referenced by decrypt().

   {
   DataSource_Memory input_src(input, input_len);
   secure_vector<byte> ciphertext =
      PEM_Code::decode_check_label(input_src,
                                   "BOTAN CRYPTOBOX MESSAGE");

   if(ciphertext.size() < (VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN))
      throw Decoding_Error("Invalid CryptoBox input");

   for(size_t i = 0; i != VERSION_CODE_LEN; ++i)
      if(ciphertext[i] != get_byte(i, CRYPTOBOX_VERSION_CODE))
         throw Decoding_Error("Bad CryptoBox version");

   const byte* pbkdf_salt = &ciphertext[VERSION_CODE_LEN];

   PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512));

   OctetString master_key = pbkdf.derive_key(
      PBKDF_OUTPUT_LEN,
      passphrase,
      pbkdf_salt,
      PBKDF_SALT_LEN,
      PBKDF_ITERATIONS);

   const byte* mk = master_key.begin();

   SymmetricKey cipher_key(&mk[0], CIPHER_KEY_LEN);
   SymmetricKey mac_key(&mk[CIPHER_KEY_LEN], MAC_KEY_LEN);
   InitializationVector iv(&mk[CIPHER_KEY_LEN + MAC_KEY_LEN], CIPHER_IV_LEN);

   Pipe pipe(new Fork(
                get_cipher("Serpent/CTR-BE", cipher_key, iv, DECRYPTION),
                new MAC_Filter(new HMAC(new SHA_512),
                               mac_key, MAC_OUTPUT_LEN)));

   const size_t ciphertext_offset =
      VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN;

   pipe.process_msg(&ciphertext[ciphertext_offset],
                    ciphertext.size() - ciphertext_offset);

   byte computed_mac[MAC_OUTPUT_LEN];
   pipe.read(computed_mac, MAC_OUTPUT_LEN, 1);

   if(!same_mem(computed_mac,
                &ciphertext[VERSION_CODE_LEN + PBKDF_SALT_LEN],
                MAC_OUTPUT_LEN))
      throw Decoding_Error("CryptoBox integrity failure");

   return pipe.read_all_as_string(0);
   }
BOTAN_DLL std::string Botan::CryptoBox::decrypt ( const std::string &  input,
const std::string &  passphrase 
)

Decrypt a message encrypted with CryptoBox::encrypt

Parameters:
inputthe input data
passphrasethe passphrase used to encrypt the message

Definition at line 153 of file cryptobox.cpp.

References decrypt().

   {
   return decrypt(reinterpret_cast<const byte*>(&input[0]),
                  input.size(),
                  passphrase);
   }
BOTAN_DLL std::string Botan::CryptoBox::encrypt ( const byte  input[],
size_t  input_len,
const std::string &  passphrase,
RandomNumberGenerator &  rng 
)

Encrypt a message using a passphrase

Parameters:
inputthe input data
input_lenthe length of input in bytes
passphrasethe passphrase used to encrypt the message
rnga ref to a random number generator, such as AutoSeeded_RNG

Definition at line 43 of file cryptobox.cpp.

References Botan::OctetString::begin(), Botan::copy_mem(), Botan::PBKDF::derive_key(), Botan::PEM_Code::encode(), Botan::ENCRYPTION, Botan::get_byte(), Botan::get_cipher(), Botan::Pipe::process_msg(), Botan::RandomNumberGenerator::randomize(), Botan::Pipe::read(), and Botan::Pipe::remaining().

   {
   secure_vector<byte> pbkdf_salt(PBKDF_SALT_LEN);
   rng.randomize(&pbkdf_salt[0], pbkdf_salt.size());

   PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512));

   OctetString master_key = pbkdf.derive_key(
      PBKDF_OUTPUT_LEN,
      passphrase,
      &pbkdf_salt[0],
      pbkdf_salt.size(),
      PBKDF_ITERATIONS);

   const byte* mk = master_key.begin();

   SymmetricKey cipher_key(&mk[0], CIPHER_KEY_LEN);
   SymmetricKey mac_key(&mk[CIPHER_KEY_LEN], MAC_KEY_LEN);
   InitializationVector iv(&mk[CIPHER_KEY_LEN + MAC_KEY_LEN], CIPHER_IV_LEN);

   Pipe pipe(get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION),
             new Fork(
                nullptr,
                new MAC_Filter(new HMAC(new SHA_512),
                               mac_key, MAC_OUTPUT_LEN)));

   pipe.process_msg(input, input_len);

   /*
   Output format is:
      version # (4 bytes)
      salt (10 bytes)
      mac (20 bytes)
      ciphertext
   */
   const size_t ciphertext_len = pipe.remaining(0);

   std::vector<byte> out_buf(VERSION_CODE_LEN +
                             PBKDF_SALT_LEN +
                             MAC_OUTPUT_LEN +
                             ciphertext_len);

   for(size_t i = 0; i != VERSION_CODE_LEN; ++i)
     out_buf[i] = get_byte(i, CRYPTOBOX_VERSION_CODE);

   copy_mem(&out_buf[VERSION_CODE_LEN], &pbkdf_salt[0],  PBKDF_SALT_LEN);

   pipe.read(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN], MAC_OUTPUT_LEN, 1);
   pipe.read(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN],
             ciphertext_len, 0);

   return PEM_Code::encode(out_buf, "BOTAN CRYPTOBOX MESSAGE");
   }