aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-07-13 11:59:53 -0400
committerJack Lloyd <[email protected]>2018-07-13 11:59:53 -0400
commitd145ad41b3ffca7756db843e3df6e167a2959049 (patch)
tree309df9cf49305507dc4bf89ab1caeaf06078b60a /src/lib
parent1cf1682035fd56e7f997e6570bd9755b6eb42eef (diff)
Add FPE1 to C API
GH #1612
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ffi/ffi.h22
-rw-r--r--src/lib/ffi/ffi_fpe.cpp90
-rw-r--r--src/lib/misc/fpe_fe1/fpe_fe1.cpp3
3 files changed, 114 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();
}