diff options
author | Jack Lloyd <[email protected]> | 2017-06-21 14:43:52 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-06-29 12:38:37 -0400 |
commit | 6ac870e6d81d98420a102661a27ad9b521da86f5 (patch) | |
tree | 0341a30bbf1003614e81e54f98b0a08105b6d9d1 /src/tests/test_ffi.cpp | |
parent | 8b0986310ae9fdf7fa93e28e2820d818cc954cdd (diff) |
Add SM2 signature scheme
From https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
This is a contribution from Ribose Inc (@riboseinc).
Diffstat (limited to 'src/tests/test_ffi.cpp')
-rw-r--r-- | src/tests/test_ffi.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index e9d9b6e20..bf5fc0e9c 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -383,6 +383,10 @@ class FFI_Unit_Tests : public Test results.push_back(ffi_test_ecdh(rng)); #endif +#if defined(BOTAN_HAS_SM2) + results.push_back(ffi_test_sm2(rng)); +#endif + #if defined(BOTAN_HAS_MCELIECE) results.push_back(ffi_test_mceliece(rng)); #endif @@ -1280,6 +1284,94 @@ class FFI_Unit_Tests : public Test return result; } + Test::Result ffi_test_sm2(botan_rng_t rng) + { + Test::Result result("FFI SM2"); + static const char* kCurve = "sm2p256v1"; + const std::string sm2_ident = "SM2 Ident Field"; + botan_privkey_t priv; + botan_pubkey_t pub; + botan_privkey_t loaded_privkey; + botan_pubkey_t loaded_pubkey; + + REQUIRE_FFI_OK(botan_privkey_create, (&priv, "SM2_Sig", kCurve, rng)); + TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv)); + ffi_test_pubkey_export(result, pub, priv, rng); + + // Check key load functions + botan_mp_t private_scalar, public_x, public_y; + botan_mp_init(&private_scalar); + botan_mp_init(&public_x); + botan_mp_init(&public_y); + + TEST_FFI_OK(botan_privkey_get_field, (private_scalar, priv, "x")); + TEST_FFI_OK(botan_pubkey_get_field, (public_x, pub, "public_x")); + TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub, "public_y")); + TEST_FFI_OK(botan_privkey_load_sm2, (&loaded_privkey, private_scalar, kCurve)); + TEST_FFI_OK(botan_pubkey_load_sm2, (&loaded_pubkey, public_x, public_y, kCurve)); + TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0)); + TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0)); + + char namebuf[32] = { 0 }; + size_t name_len = sizeof(namebuf); + + TEST_FFI_OK(botan_pubkey_algo_name, (pub, &namebuf[0], &name_len)); + result.test_eq(namebuf, namebuf, "SM2_Sig"); + + std::vector<uint8_t> message(1280), signature; + TEST_FFI_OK(botan_rng_get, (rng, message.data(), message.size())); + botan_pk_op_sign_t signer; + if(TEST_FFI_OK(botan_pk_op_sign_create, (&signer, loaded_privkey, sm2_ident.c_str(), 0))) + { + // TODO: break input into multiple calls to update + TEST_FFI_OK(botan_pk_op_sign_update, (signer, message.data(), message.size())); + + signature.resize(96); // TODO: no way to derive this from API + size_t sig_len = signature.size(); + TEST_FFI_OK(botan_pk_op_sign_finish, (signer, rng, signature.data(), &sig_len)); + signature.resize(sig_len); + + TEST_FFI_OK(botan_pk_op_sign_destroy, (signer)); + } + + botan_pk_op_verify_t verifier; + + if(signature.size() > 0 && TEST_FFI_OK(botan_pk_op_verify_create, (&verifier, pub, sm2_ident.c_str(), 0))) + { + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + // TODO: randomize this + signature[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + message[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + signature[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_FAIL("bad signature", botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + message[0] ^= 1; + TEST_FFI_OK(botan_pk_op_verify_update, (verifier, message.data(), message.size())); + TEST_FFI_OK(botan_pk_op_verify_finish, (verifier, signature.data(), signature.size())); + + TEST_FFI_OK(botan_pk_op_verify_destroy, (verifier)); + } + + TEST_FFI_OK(botan_mp_destroy, (private_scalar)); + TEST_FFI_OK(botan_mp_destroy, (public_x)); + TEST_FFI_OK(botan_mp_destroy, (public_y)); + TEST_FFI_OK(botan_pubkey_destroy, (pub)); + TEST_FFI_OK(botan_privkey_destroy, (priv)); + TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey)); + TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey)); + + return result; + } + Test::Result ffi_test_ecdh(botan_rng_t rng) { Test::Result result("FFI ECDH"); |