Skip to content

Commit

Permalink
allow loading raw FrodoKEM keys in FFI
Browse files Browse the repository at this point in the history
  • Loading branch information
reneme committed Oct 14, 2024
1 parent 24d24a1 commit df60ea1
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/lib/ffi/ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,16 @@ int botan_privkey_view_kyber_raw_key(botan_privkey_t key, botan_view_ctx ctx, bo
BOTAN_FFI_EXPORT(3, 1)
int botan_pubkey_view_kyber_raw_key(botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view);

/**
* Algorithm specific key operation: FrodoKEM
*/

BOTAN_FFI_EXPORT(3, 6)
int botan_privkey_load_frodokem(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* frodo_mode);

BOTAN_FFI_EXPORT(3, 6)
int botan_pubkey_load_frodokem(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* frodo_mode);

/*
* Algorithm specific key operations: ECDSA and ECDH
*/
Expand Down
57 changes: 57 additions & 0 deletions src/lib/ffi/ffi_pkey_algs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
#include <botan/kyber.h>
#endif

#if defined(BOTAN_HAS_FRODOKEM)
#include <botan/frodokem.h>
#include <botan/internal/frodo_constants.h>
#endif

namespace {

#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
Expand Down Expand Up @@ -1027,6 +1032,58 @@ int botan_pubkey_view_kyber_raw_key(botan_pubkey_t key, botan_view_ctx ctx, bota
#endif
}

/*
* Algorithm specific key operations: FrodoKEM
*/

int botan_privkey_load_frodokem(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* frodo_mode) {
#if defined(BOTAN_HAS_FRODOKEM)
if(key == nullptr || privkey == nullptr || frodo_mode == nullptr) {
return BOTAN_FFI_ERROR_NULL_POINTER;
}

*key = nullptr;

return ffi_guard_thunk(__func__, [=]() -> int {
auto mode = Botan::FrodoKEMConstants(Botan::FrodoKEMMode(frodo_mode));
if(key_len != mode.len_private_key_bytes()) {
return BOTAN_FFI_ERROR_INVALID_KEY_LENGTH;
}

auto frodo_key = std::make_unique<Botan::FrodoKEM_PrivateKey>(std::span{privkey, key_len}, mode.mode());
*key = new botan_privkey_struct(std::move(frodo_key));
return BOTAN_FFI_SUCCESS;
});
#else
BOTAN_UNUSED(key, privkey, key_len, frodo_mode);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
}

int botan_pubkey_load_frodokem(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* frodo_mode) {
#if defined(BOTAN_HAS_FRODOKEM)
if(key == nullptr || pubkey == nullptr || frodo_mode == nullptr) {
return BOTAN_FFI_ERROR_NULL_POINTER;
}

*key = nullptr;

return ffi_guard_thunk(__func__, [=]() -> int {
auto mode = Botan::FrodoKEMConstants(Botan::FrodoKEMMode(frodo_mode));
if(key_len != mode.len_public_key_bytes()) {
return BOTAN_FFI_ERROR_INVALID_KEY_LENGTH;
}

auto frodo_key = std::make_unique<Botan::FrodoKEM_PublicKey>(std::span{pubkey, key_len}, mode.mode());
*key = new botan_pubkey_struct(std::move(frodo_key));
return BOTAN_FFI_SUCCESS;
});
#else
BOTAN_UNUSED(key, privkey, key_len, frodo_mode);
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
}

int botan_pubkey_view_ec_public_point(const botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view) {
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
Expand Down
30 changes: 30 additions & 0 deletions src/tests/test_ffi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3603,6 +3603,35 @@ class FFI_Kyber1024_Test final : public FFI_Test {
}
};

class FFI_FrodoKEM_Test final : public FFI_KEM_Roundtrip_Test {
public:
std::string name() const override { return "FFI FrodoKEM"; }

protected:
const char* algo() const override { return "FrodoKEM"; }

privkey_loader_fn_t private_key_load_function() const override { return botan_privkey_load_frodokem; }

pubkey_loader_fn_t public_key_load_function() const override { return botan_pubkey_load_frodokem; }

std::vector<const char*> modes() const override {
return std::vector{
"FrodoKEM-640-SHAKE",
"FrodoKEM-976-SHAKE",
"FrodoKEM-1344-SHAKE",
"eFrodoKEM-640-SHAKE",
"eFrodoKEM-976-SHAKE",
"eFrodoKEM-1344-SHAKE",
"FrodoKEM-640-AES",
"FrodoKEM-976-AES",
"FrodoKEM-1344-AES",
"eFrodoKEM-640-AES",
"eFrodoKEM-976-AES",
"eFrodoKEM-1344-AES",
};
}
};

class FFI_ElGamal_Test final : public FFI_Test {
public:
std::string name() const override { return "FFI ElGamal"; }
Expand Down Expand Up @@ -3845,6 +3874,7 @@ BOTAN_REGISTER_TEST("ffi", "ffi_x448", FFI_X448_Test);
BOTAN_REGISTER_TEST("ffi", "ffi_kyber512", FFI_Kyber512_Test);
BOTAN_REGISTER_TEST("ffi", "ffi_kyber768", FFI_Kyber768_Test);
BOTAN_REGISTER_TEST("ffi", "ffi_kyber1024", FFI_Kyber1024_Test);
BOTAN_REGISTER_TEST("ffi", "ffi_frodokem", FFI_FrodoKEM_Test);
BOTAN_REGISTER_TEST("ffi", "ffi_elgamal", FFI_ElGamal_Test);
BOTAN_REGISTER_TEST("ffi", "ffi_dh", FFI_DH_Test);

Expand Down

0 comments on commit df60ea1

Please sign in to comment.