diff options
-rw-r--r-- | src/lib/ffi/ffi.cpp | 12 | ||||
-rw-r--r-- | src/lib/ffi/ffi.h | 14 | ||||
-rw-r--r-- | src/lib/ffi/ffi_block.cpp | 15 | ||||
-rw-r--r-- | src/lib/ffi/ffi_util.h | 13 | ||||
-rw-r--r-- | src/tests/test_ffi.cpp | 10 |
5 files changed, 59 insertions, 5 deletions
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index b540a9b8e..74c576631 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -14,10 +14,10 @@ namespace Botan_FFI { -int ffi_error_exception_thrown(const char* func_name, const char* exn) +int ffi_error_exception_thrown(const char* func_name, const char* exn, int rc) { - fprintf(stderr, "in %s exception %s\n", func_name, exn); - return BOTAN_FFI_ERROR_EXCEPTION_THROWN; + fprintf(stderr, "in %s exception '%s' returning %d\n", func_name, exn, rc); + return rc; } } @@ -48,6 +48,9 @@ const char* botan_error_description(int err) case BOTAN_FFI_ERROR_EXCEPTION_THROWN: return "Exception thrown"; + case BOTAN_FFI_ERROR_OUT_OF_MEMORY: + return "Out of memory"; + case BOTAN_FFI_ERROR_BAD_FLAG: return "Bad flag"; @@ -57,6 +60,9 @@ const char* botan_error_description(int err) case BOTAN_FFI_ERROR_BAD_PARAMETER: return "Bad parameter"; + case BOTAN_FFI_ERROR_KEY_NOT_SET: + return "Key not set on object"; + case BOTAN_FFI_ERROR_NOT_IMPLEMENTED: return "Not implemented"; diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index 676a451f1..9deefffb5 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -73,9 +73,11 @@ enum BOTAN_FFI_ERROR { BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE = -10, BOTAN_FFI_ERROR_EXCEPTION_THROWN = -20, + BOTAN_FFI_ERROR_OUT_OF_MEMORY = -21, BOTAN_FFI_ERROR_BAD_FLAG = -30, BOTAN_FFI_ERROR_NULL_POINTER = -31, BOTAN_FFI_ERROR_BAD_PARAMETER = -32, + BOTAN_FFI_ERROR_KEY_NOT_SET = -33, BOTAN_FFI_ERROR_NOT_IMPLEMENTED = -40, BOTAN_FFI_ERROR_INVALID_OBJECT = -50, @@ -563,6 +565,18 @@ BOTAN_PUBLIC_API(2,8) int botan_block_cipher_name(botan_block_cipher_t cipher, char* name, size_t* name_len); +/** +* Get the key length limits of this block cipher +* @param cipher the object to read +* @param out_minimum_keylength if non-NULL, will be set to minimum keylength of cipher +* @param out_maximum_keylength if non-NULL, will be set to maximum keylength of cipher +* @param out_keylength_modulo if non-NULL will be set to byte multiple of valid keys +*/ +BOTAN_PUBLIC_API(2,8) int botan_block_cipher_query_keylen(botan_block_cipher_t, + size_t* out_minimum_keylength, + size_t* out_maximum_keylength, + size_t* out_keylength_modulo); + /* * Multiple precision integers */ diff --git a/src/lib/ffi/ffi_block.cpp b/src/lib/ffi/ffi_block.cpp index fad492fd4..e19747d2b 100644 --- a/src/lib/ffi/ffi_block.cpp +++ b/src/lib/ffi/ffi_block.cpp @@ -85,4 +85,19 @@ int botan_block_cipher_name(botan_block_cipher_t cipher, char* name, size_t* nam return write_str_output(name, name_len, bc.name()); }); } +int botan_block_cipher_query_keylen(botan_block_cipher_t cipher, + size_t* out_minimum_keylength, + size_t* out_maximum_keylength, + size_t* out_keylength_modulo) + { + return BOTAN_FFI_DO(Botan::BlockCipher, cipher, bc, { + if(out_minimum_keylength) + *out_minimum_keylength = bc.minimum_keylength(); + if(out_maximum_keylength) + *out_maximum_keylength = bc.maximum_keylength(); + if(out_keylength_modulo) + *out_keylength_modulo = bc.key_spec().keylength_multiple(); + }); + } + } diff --git a/src/lib/ffi/ffi_util.h b/src/lib/ffi/ffi_util.h index 9ff1b0e2f..afd359dbb 100644 --- a/src/lib/ffi/ffi_util.h +++ b/src/lib/ffi/ffi_util.h @@ -43,7 +43,8 @@ struct botan_struct struct NAME final : public Botan_FFI::botan_struct<TYPE, MAGIC> { explicit NAME(TYPE* x) : botan_struct(x) {} } // Declared in ffi.cpp -int ffi_error_exception_thrown(const char* func_name, const char* exn); +int ffi_error_exception_thrown(const char* func_name, const char* exn, + int rc = BOTAN_FFI_ERROR_EXCEPTION_THROWN); template<typename T, uint32_t M> T& safe_get(botan_struct<T,M>* p) @@ -69,7 +70,15 @@ int ffi_guard_thunk(const char* func_name, Thunk thunk) } catch(std::bad_alloc&) { - return ffi_error_exception_thrown(func_name, "bad_alloc"); + return ffi_error_exception_thrown(func_name, "bad_alloc", BOTAN_FFI_ERROR_OUT_OF_MEMORY); + } + catch(Botan::Key_Not_Set& e) + { + return ffi_error_exception_thrown(func_name, e.what(), BOTAN_FFI_ERROR_KEY_NOT_SET); + } + catch(Botan::Invalid_Argument& e) + { + return ffi_error_exception_thrown(func_name, e.what(), BOTAN_FFI_ERROR_BAD_PARAMETER); } catch(std::exception& e) { diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index c0afd9ac2..5940a1009 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -860,6 +860,16 @@ class FFI_Unit_Tests final : public Test TEST_FFI_RC(16, botan_block_cipher_block_size, (cipher)); + size_t min_keylen = 0, max_keylen = 0, mod_keylen = 0; + TEST_FFI_RC(0, botan_block_cipher_query_keylen, (cipher, nullptr, nullptr, nullptr)); + TEST_FFI_RC(0, botan_block_cipher_query_keylen, (cipher, &min_keylen, nullptr, nullptr)); + TEST_FFI_RC(0, botan_block_cipher_query_keylen, (cipher, nullptr, &max_keylen, nullptr)); + TEST_FFI_RC(0, botan_block_cipher_query_keylen, (cipher, nullptr, nullptr, &mod_keylen)); + + result.test_eq("Expected min keylen", min_keylen, 16); + result.test_eq("Expected max keylen", max_keylen, 16); + result.test_eq("Expected mod keylen", mod_keylen, 1); + TEST_FFI_OK(botan_block_cipher_set_key, (cipher, zero16.data(), zero16.size())); TEST_FFI_OK(botan_block_cipher_encrypt_blocks, (cipher, block.data(), block.data(), 1)); |