github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/c-deps/libroach/ccl/crypto_utils.cc (about)

     1  // Copyright 2017 The Cockroach Authors.
     2  //
     3  // Licensed as a CockroachDB Enterprise file under the Cockroach Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //     https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt
     8  
     9  #include "crypto_utils.h"
    10  #include <cryptopp/filters.h>
    11  #include <cryptopp/hex.h>
    12  #include <cryptopp/osrng.h>
    13  #include <cryptopp/sha.h>
    14  #include "../fmt.h"
    15  
    16  #ifndef _WIN32
    17  #include <sys/resource.h>
    18  #include <sys/time.h>
    19  #include <sys/types.h>
    20  #endif
    21  
    22  std::string HexString(const std::string& s) {
    23    std::string value;
    24  
    25    CryptoPP::StringSource ss(
    26        s, true /* PumpAll */,
    27        new CryptoPP::HexEncoder(new CryptoPP::StringSink(value), false /* uppercase */));
    28  
    29    return value;
    30  }
    31  
    32  std::string RandomBytes(size_t length) {
    33    CryptoPP::SecByteBlock data(length);
    34    CryptoPP::OS_GenerateRandomBlock(false /* blocking */, data, length);
    35    return std::string(reinterpret_cast<const char*>(data.data()), data.size());
    36  }
    37  
    38  class AESEncryptCipher : public rocksdb_utils::BlockCipher {
    39   public:
    40    // The key must have a valid length (16/24/32 bytes) or CryptoPP will fail.
    41    AESEncryptCipher(const std::string& key) : enc_((byte*)key.data(), key.size()) {}
    42  
    43    ~AESEncryptCipher() {}
    44  
    45    // Blocksize is fixed for AES.
    46    size_t BlockSize() { return CryptoPP::AES::BLOCKSIZE; }
    47  
    48    // Encrypt a block of data.
    49    // Length of data is equal to BlockSize().
    50    rocksdb::Status Encrypt(char* data) {
    51      enc_.ProcessBlock((byte*)data);
    52      return rocksdb::Status::OK();
    53    }
    54  
    55    // Decrypt a block of data.
    56    // Length of data is equal to BlockSize().
    57    // NOT IMPLEMENTED: this is not needed for CTR mode so remains unimplemented.
    58    rocksdb::Status Decrypt(char* data) {
    59      return rocksdb::Status::NotSupported("this is an encrypt-only cipher");
    60    }
    61  
    62   private:
    63    CryptoPP::AES::Encryption enc_;
    64  };
    65  
    66  rocksdb_utils::BlockCipher* NewAESEncryptCipher(const enginepbccl::SecretKey* key) {
    67    return new AESEncryptCipher(key->key());
    68  }
    69  
    70  bool UsesAESNI() { return CryptoPP::UsesAESNI(); }
    71  
    72  rocksdb::Status DisableCoreFile() {
    73  #ifdef _WIN32
    74    return rocksdb::Status::NotSupported("preventing crash reports is not supported on Windows");
    75  #else
    76    // We can't use prlimit on OSX. Use setrlimit and getrlimit instead.
    77    rlimit lim;
    78    int ret = getrlimit(RLIMIT_CORE, &lim);
    79    if (ret != 0) {
    80      return rocksdb::Status::NotSupported(
    81          fmt::StringPrintf("failed to get core size rlimit: %s", strerror(errno)));
    82    }
    83  
    84    if (lim.rlim_cur == 0 && lim.rlim_max == 0) {
    85      return rocksdb::Status::OK();
    86    }
    87  
    88    rlimit new_lim = {0, 0};
    89    ret = setrlimit(RLIMIT_CORE, &new_lim);
    90    if (ret != 0) {
    91      return rocksdb::Status::NotSupported(
    92          fmt::StringPrintf("failed to set core size rlimit: %s", strerror(errno)));
    93    }
    94  
    95    return rocksdb::Status::OK();
    96  #endif
    97  }