diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/botan/src/cli/cc_enc.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/botan/src/cli/cc_enc.cpp')
-rw-r--r-- | comm/third_party/botan/src/cli/cc_enc.cpp | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/cli/cc_enc.cpp b/comm/third_party/botan/src/cli/cc_enc.cpp new file mode 100644 index 0000000000..509b996012 --- /dev/null +++ b/comm/third_party/botan/src/cli/cc_enc.cpp @@ -0,0 +1,189 @@ +/* +* (C) 2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "cli.h" +#include <botan/hex.h> + +#if defined(BOTAN_HAS_FPE_FE1) && defined(BOTAN_HAS_PBKDF) + +#include <botan/fpe_fe1.h> +#include <botan/pbkdf.h> + +namespace Botan_CLI { + +namespace { + +uint8_t luhn_checksum(uint64_t cc_number) + { + uint8_t sum = 0; + + bool alt = false; + while(cc_number) + { + uint8_t digit = cc_number % 10; + if(alt) + { + digit *= 2; + if(digit > 9) + { + digit -= 9; + } + } + + sum += digit; + + cc_number /= 10; + alt = !alt; + } + + return (sum % 10); + } + +bool luhn_check(uint64_t cc_number) + { + return (luhn_checksum(cc_number) == 0); + } + +uint64_t cc_rank(uint64_t cc_number) + { + // Remove Luhn checksum + return cc_number / 10; + } + +uint64_t cc_derank(uint64_t cc_number) + { + for(size_t i = 0; i != 10; ++i) + { + if(luhn_check(cc_number * 10 + i)) + { + return (cc_number * 10 + i); + } + } + + return 0; + } + +uint64_t encrypt_cc_number(uint64_t cc_number, + const Botan::secure_vector<uint8_t>& key, + const std::vector<uint8_t>& tweak) + { + const Botan::BigInt n = 1000000000000000; + + const uint64_t cc_ranked = cc_rank(cc_number); + + const Botan::BigInt c = Botan::FPE::fe1_encrypt(n, cc_ranked, key, tweak); + + if(c.bits() > 50) + { + throw Botan::Internal_Error("FPE produced a number too large"); + } + + uint64_t enc_cc = 0; + for(size_t i = 0; i != 7; ++i) + { + enc_cc = (enc_cc << 8) | c.byte_at(6 - i); + } + return cc_derank(enc_cc); + } + +uint64_t decrypt_cc_number(uint64_t enc_cc, + const Botan::secure_vector<uint8_t>& key, + const std::vector<uint8_t>& tweak) + { + const Botan::BigInt n = 1000000000000000; + + const uint64_t cc_ranked = cc_rank(enc_cc); + + const Botan::BigInt c = Botan::FPE::fe1_decrypt(n, cc_ranked, key, tweak); + + if(c.bits() > 50) + { + throw CLI_Error("FPE produced a number too large"); + } + + uint64_t dec_cc = 0; + for(size_t i = 0; i != 7; ++i) + { + dec_cc = (dec_cc << 8) | c.byte_at(6 - i); + } + return cc_derank(dec_cc); + } + +} + +class CC_Encrypt final : public Command + { + public: + CC_Encrypt() : Command("cc_encrypt CC passphrase --tweak=") {} + + std::string group() const override + { + return "misc"; + } + + std::string description() const override + { + return "Encrypt the passed valid credit card number using FPE encryption"; + } + + void go() override + { + const uint64_t cc_number = std::stoull(get_arg("CC")); + const std::vector<uint8_t> tweak = Botan::hex_decode(get_arg("tweak")); + const std::string pass = get_arg("passphrase"); + + std::unique_ptr<Botan::PBKDF> pbkdf(Botan::PBKDF::create("PBKDF2(SHA-256)")); + if(!pbkdf) + { + throw CLI_Error_Unsupported("PBKDF", "PBKDF2(SHA-256)"); + } + + Botan::secure_vector<uint8_t> key = pbkdf->pbkdf_iterations(32, pass, tweak.data(), tweak.size(), 100000); + + output() << encrypt_cc_number(cc_number, key, tweak) << "\n"; + } + }; + +BOTAN_REGISTER_COMMAND("cc_encrypt", CC_Encrypt); + +class CC_Decrypt final : public Command + { + public: + CC_Decrypt() : Command("cc_decrypt CC passphrase --tweak=") {} + + std::string group() const override + { + return "misc"; + } + + std::string description() const override + { + return "Decrypt the passed valid ciphertext credit card number using FPE decryption"; + } + + void go() override + { + const uint64_t cc_number = std::stoull(get_arg("CC")); + const std::vector<uint8_t> tweak = Botan::hex_decode(get_arg("tweak")); + const std::string pass = get_arg("passphrase"); + + std::unique_ptr<Botan::PBKDF> pbkdf(Botan::PBKDF::create("PBKDF2(SHA-256)")); + if(!pbkdf) + { + throw CLI_Error_Unsupported("PBKDF", "PBKDF2(SHA-256)"); + } + + Botan::secure_vector<uint8_t> key = pbkdf->pbkdf_iterations(32, pass, tweak.data(), tweak.size(), 100000); + + output() << decrypt_cc_number(cc_number, key, tweak) << "\n"; + } + }; + +BOTAN_REGISTER_COMMAND("cc_decrypt", CC_Decrypt); + +} + +#endif // FPE && PBKDF |