diff options
author | Jack Lloyd <[email protected]> | 2018-07-13 11:59:53 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-07-13 11:59:53 -0400 |
commit | d145ad41b3ffca7756db843e3df6e167a2959049 (patch) | |
tree | 309df9cf49305507dc4bf89ab1caeaf06078b60a /src | |
parent | 1cf1682035fd56e7f997e6570bd9755b6eb42eef (diff) |
Add FPE1 to C API
GH #1612
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/ffi/ffi.h | 22 | ||||
-rw-r--r-- | src/lib/ffi/ffi_fpe.cpp | 90 | ||||
-rw-r--r-- | src/lib/misc/fpe_fe1/fpe_fe1.cpp | 3 | ||||
-rw-r--r-- | src/tests/test_ffi.cpp | 41 |
4 files changed, 155 insertions, 1 deletions
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index d2e924eb6..f62fe17d2 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -1202,6 +1202,28 @@ int botan_key_unwrap3394(const uint8_t wrapped_key[], size_t wrapped_key_len, const uint8_t kek[], size_t kek_len, uint8_t key[], size_t *key_len); +/** +* Format Preserving Encryption +*/ + +typedef struct botan_fpe_struct* botan_fpe_t; + +#define BOTAN_FPE_FLAG_FE1_COMPAT_MODE 1 + +BOTAN_PUBLIC_API(2,8) +int botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n, + const uint8_t key[], size_t key_len, + size_t rounds, uint32_t flags); + +BOTAN_PUBLIC_API(2,8) +int botan_fpe_destroy(botan_fpe_t fpe); + +BOTAN_PUBLIC_API(2,8) +int botan_fpe_encrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len); + +BOTAN_PUBLIC_API(2,8) +int botan_fpe_decrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len); + /* * TLS (WIP) */ diff --git a/src/lib/ffi/ffi_fpe.cpp b/src/lib/ffi/ffi_fpe.cpp new file mode 100644 index 000000000..82c612f8d --- /dev/null +++ b/src/lib/ffi/ffi_fpe.cpp @@ -0,0 +1,90 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/ffi.h> +#include <botan/internal/ffi_util.h> +#include <botan/internal/ffi_mp.h> +#include <memory> + +#if defined(BOTAN_HAS_FPE_FE1) + #include <botan/fpe_fe1.h> +#endif + +extern "C" { + +using namespace Botan_FFI; + +BOTAN_FFI_DECLARE_STRUCT(botan_fpe_struct, Botan::FPE_FE1, 0xD49FB820); + +int botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n, + const uint8_t key[], size_t key_len, + size_t rounds, uint32_t flags) + { +#if defined(BOTAN_HAS_FPE_FE1) + + return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() { + + if(fpe == nullptr || key == nullptr) + return BOTAN_FFI_ERROR_NULL_POINTER; + + *fpe = nullptr; + + if(flags != 0 && flags != BOTAN_FPE_FLAG_FE1_COMPAT_MODE) + return BOTAN_FFI_ERROR_BAD_FLAG; + + const bool compat_mode = (flags & BOTAN_FPE_FLAG_FE1_COMPAT_MODE); + + std::unique_ptr<Botan::FPE_FE1> fpe_obj( + new Botan::FPE_FE1(safe_get(n), rounds, compat_mode)); + + fpe_obj->set_key(key, key_len); + + *fpe = new botan_fpe_struct(fpe_obj.release()); + return BOTAN_FFI_SUCCESS; + }); +#else + *fpe = nullptr; + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +int botan_fpe_destroy(botan_fpe_t fpe) + { +#if defined(BOTAN_HAS_FPE_FE1) + return BOTAN_FFI_CHECKED_DELETE(fpe); +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +int botan_fpe_encrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len) + { +#if defined(BOTAN_HAS_FPE_FE1) + return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() { + Botan::BigInt r = safe_get(fpe).encrypt(safe_get(x), tweak, tweak_len); + safe_get(x) = r; + return BOTAN_FFI_SUCCESS; + }); +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +int botan_fpe_decrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], size_t tweak_len) + { +#if defined(BOTAN_HAS_FPE_FE1) + return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() { + Botan::BigInt r = safe_get(fpe).decrypt(safe_get(x), tweak, tweak_len); + safe_get(x) = r; + return BOTAN_FFI_SUCCESS; + }); + +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + +} diff --git a/src/lib/misc/fpe_fe1/fpe_fe1.cpp b/src/lib/misc/fpe_fe1/fpe_fe1.cpp index 8cd79401c..680967ea9 100644 --- a/src/lib/misc/fpe_fe1/fpe_fe1.cpp +++ b/src/lib/misc/fpe_fe1/fpe_fe1.cpp @@ -134,7 +134,8 @@ secure_vector<uint8_t> FPE_FE1::compute_tweak_mac(const uint8_t tweak[], size_t m_mac->update(m_n_bytes.data(), m_n_bytes.size()); m_mac->update_be(static_cast<uint32_t>(tweak_len)); - m_mac->update(tweak, tweak_len); + if(tweak_len > 0) + m_mac->update(tweak, tweak_len); return m_mac->final(); } diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index 45a5f0139..e0828f588 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -79,6 +79,10 @@ class FFI_Unit_Tests final : public Test results.push_back(ffi_test_stream_ciphers()); results.push_back(ffi_test_pkcs_hash_id()); +#if defined(BOTAN_HAS_FPE_FE1) + results.push_back(ffi_test_fpe()); +#endif + #if defined(BOTAN_HAS_RFC3394_KEYWRAP) results.push_back(ffi_test_keywrap()); #endif @@ -1204,6 +1208,43 @@ class FFI_Unit_Tests final : public Test TEST_FFI_OK(botan_pubkey_fingerprint, (pub, "SHA-512", fingerprint.data(), &fingerprint_len)); } + Test::Result ffi_test_fpe() + { + Test::Result result("FFI FPE"); + + const uint8_t key[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + botan_mp_t n, x; + botan_fpe_t fpe; + + botan_mp_init(&n); + botan_mp_set_from_str(n, "1000000000"); + + botan_mp_init(&x); + botan_mp_set_from_str(x, "178051120"); + + TEST_FFI_OK(botan_fpe_fe1_init, (&fpe, n, key, sizeof(key), 5, 0)); + + TEST_FFI_OK(botan_fpe_encrypt, (fpe, x, nullptr, 0)); + + uint32_t xval = 0; + TEST_FFI_OK(botan_mp_to_uint32, (x, &xval)); + result.test_eq("Expected FPE ciphertext", xval, size_t(605648666)); + + TEST_FFI_OK(botan_fpe_encrypt, (fpe, x, nullptr, 0)); + TEST_FFI_OK(botan_fpe_decrypt, (fpe, x, nullptr, 0)); + TEST_FFI_OK(botan_fpe_decrypt, (fpe, x, nullptr, 0)); + + TEST_FFI_OK(botan_mp_to_uint32, (x, &xval)); + result.test_eq("FPE round trip", xval, size_t(178051120)); + + TEST_FFI_OK(botan_fpe_destroy, (fpe)); + TEST_FFI_OK(botan_mp_destroy, (x)); + TEST_FFI_OK(botan_mp_destroy, (n)); + + return result; + } + Test::Result ffi_test_keywrap() { Test::Result result("FFI keywrap"); |